Pubnub demo for AT&T IoT Starter Kit. Functionally similar to the Flow demo.

Dependencies:   FXOS8700CQ MODSERIAL mbed

http://pubnub.github.io/slides/workshop/pictures/broadcast.png

Pubnub demo for AT&T IoT Starter Kit

This demo is functionally similar to the Flow demo, so you can find general information here: https://developer.mbed.org/users/JMF/code/Avnet_ATT_Cellular_IOT/.

The only difference is that we use Pubnub to publish the measurements and subscribe to receiving the instructions to set the LED.

Settings

Pubnub related settings are:

Pubnub settings in `config_me.h`

PUBNUB_SUBSCRIBE_KEY
PUBNUB_PUBLISH_KEY
PUBNUB_CHANNEL

All are documented in their respective comments.

Pubnub context class

Similar to Pubnub SDKs, we provide a Pubnub context class. It is defined in pubnub.h header file and implemented in pubnub.cpp.

It provides only the fundamental "publish" and "subscribe" methods. They are documented in the header file.

This class is reusable in other code (it is not specific to this demo), it has a very narrow interface to the AT&T IoT cellular modem code. For example of use, you can look at the main() (in main.c).

Sample of published data

Published message w/measurement data

{"serial":"vstarterkit001","temp":89.61,"humidity":35,"accelX":0.97,"accelY":0.013,"accelZ":-0.038}

Don't worry, nobody got burnt, the temperature is in degrees Fahrenheit. :)

Publish a message (from, say, the Pubnub console http://pubnub.com/console) of the form {"LED":<name-of-the-color>} on the channel that this demo listens to (default is hello_world) to turn the LED to that color on the Starter Kit:

Turn LED to red

{"LED":"Red"}

Turn LED to green

{"LED":"Green"}

Turn LED to blue

{"LED":"Blue"}
Committer:
fkellermavnet
Date:
Sun Jul 24 19:33:23 2016 +0000
Revision:
46:da9d788f5d5a
Parent:
45:a836eecd5d12
Child:
53:dcccf2881fa0
Exception was not WNC issue or parsing.  Being caused by bad conversion from string to char array.  FIXED!

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JMF 2:0e2ef866af95 1 #include "mbed.h"
JMF 2:0e2ef866af95 2 #include <cctype>
JMF 2:0e2ef866af95 3 #include <string>
JMF 2:0e2ef866af95 4 #include "config_me.h"
JMF 2:0e2ef866af95 5 #include "SerialBuffered.h"
JMF 2:0e2ef866af95 6 #include "wnc_control.h"
JMF 2:0e2ef866af95 7
JMF 2:0e2ef866af95 8 extern Serial pc;
JMF 2:0e2ef866af95 9 extern Serial mdm;
JMF 2:0e2ef866af95 10 extern string MyServerIpAddress;
JMF 2:0e2ef866af95 11 extern string MySocketData;
JMF 2:0e2ef866af95 12
JMF 2:0e2ef866af95 13 int reinitialize_mdm(void);
JMF 2:0e2ef866af95 14
JMF 2:0e2ef866af95 15 enum WNC_ERR_e {
JMF 2:0e2ef866af95 16 WNC_OK =0,
JMF 2:0e2ef866af95 17 WNC_CMD_ERR = -1,
fkellermavnet 46:da9d788f5d5a 18 WNC_NO_RESPONSE = -2,
fkellermavnet 46:da9d788f5d5a 19 WNC_CELL_LINK_DOWN = -3
JMF 2:0e2ef866af95 20 };
JMF 2:0e2ef866af95 21
JMF 2:0e2ef866af95 22 // Contains result of last call to send_wnc_cmd(..)
JMF 2:0e2ef866af95 23 WNC_ERR_e WNC_MDM_ERR = WNC_OK;
JMF 2:0e2ef866af95 24
JMF 2:0e2ef866af95 25 // Contains the RAW WNC UART responses
JMF 2:0e2ef866af95 26 static string wncStr;
fkellermavnet 10:df54436ecd38 27 static int socketOpen = 0;
JMF 2:0e2ef866af95 28
JMF 2:0e2ef866af95 29 void software_init_mdm(void)
JMF 2:0e2ef866af95 30 {
fkellermavnet 42:be4b9ee3a615 31 static bool reportStatus = true;
JMF 2:0e2ef866af95 32 do
JMF 2:0e2ef866af95 33 {
fkellermavnet 42:be4b9ee3a615 34 if (check_wnc_ready() == 0)
fkellermavnet 42:be4b9ee3a615 35 {
fkellermavnet 42:be4b9ee3a615 36 if (reportStatus == false)
fkellermavnet 42:be4b9ee3a615 37 {
fkellermavnet 42:be4b9ee3a615 38 puts("Re-connected to cellular network!\n\r");
fkellermavnet 42:be4b9ee3a615 39 reportStatus = true;
fkellermavnet 42:be4b9ee3a615 40 }
fkellermavnet 42:be4b9ee3a615 41
fkellermavnet 42:be4b9ee3a615 42 // WNC has SIM and registered on network
fkellermavnet 42:be4b9ee3a615 43 do
fkellermavnet 42:be4b9ee3a615 44 {
fkellermavnet 42:be4b9ee3a615 45 WNC_MDM_ERR = WNC_OK;
fkellermavnet 42:be4b9ee3a615 46 at_init_wnc();
fkellermavnet 42:be4b9ee3a615 47 if (WNC_MDM_ERR == WNC_NO_RESPONSE)
fkellermavnet 42:be4b9ee3a615 48 {
fkellermavnet 42:be4b9ee3a615 49 reinitialize_mdm();
fkellermavnet 42:be4b9ee3a615 50 at_init_wnc(true); // Hard reset occurred so make it go through the software init();
fkellermavnet 42:be4b9ee3a615 51 }
fkellermavnet 42:be4b9ee3a615 52 } while (WNC_MDM_ERR != WNC_OK);
fkellermavnet 42:be4b9ee3a615 53 }
fkellermavnet 42:be4b9ee3a615 54 else
fkellermavnet 42:be4b9ee3a615 55 {
fkellermavnet 42:be4b9ee3a615 56 if (reportStatus == true)
fkellermavnet 42:be4b9ee3a615 57 {
fkellermavnet 42:be4b9ee3a615 58 puts("Not connected to cellular network!\n\r");
fkellermavnet 42:be4b9ee3a615 59 reportStatus = false;
fkellermavnet 42:be4b9ee3a615 60 }
fkellermavnet 42:be4b9ee3a615 61 // Atempt to re-register
fkellermavnet 42:be4b9ee3a615 62 // string * pRespStr;
fkellermavnet 42:be4b9ee3a615 63 // pc.puts("Force re-register!\r\n");
fkellermavnet 42:be4b9ee3a615 64 // at_send_wnc_cmd("AT+CFUN=0,0", &pRespStr, WNC_TIMEOUT_MS);
fkellermavnet 42:be4b9ee3a615 65 // wait_ms(31000);
fkellermavnet 42:be4b9ee3a615 66 // at_send_wnc_cmd("AT+CFUN=1,0", &pRespStr, WNC_TIMEOUT_MS);
fkellermavnet 42:be4b9ee3a615 67 // wait_ms(31000);
fkellermavnet 46:da9d788f5d5a 68 WNC_MDM_ERR = WNC_CELL_LINK_DOWN;
fkellermavnet 42:be4b9ee3a615 69 }
fkellermavnet 42:be4b9ee3a615 70 } while (WNC_MDM_ERR != WNC_OK);
JMF 2:0e2ef866af95 71 }
JMF 2:0e2ef866af95 72
JMF 2:0e2ef866af95 73 void resolve_mdm(void)
JMF 2:0e2ef866af95 74 {
JMF 2:0e2ef866af95 75 do
JMF 2:0e2ef866af95 76 {
JMF 2:0e2ef866af95 77 WNC_MDM_ERR = WNC_OK;
JMF 2:0e2ef866af95 78 at_dnsresolve_wnc(MY_SERVER_URL, &MyServerIpAddress);
JMF 2:0e2ef866af95 79 if (WNC_MDM_ERR == WNC_NO_RESPONSE)
JMF 2:0e2ef866af95 80 {
JMF 2:0e2ef866af95 81 software_init_mdm();
JMF 2:0e2ef866af95 82 }
JMF 2:0e2ef866af95 83 else if (WNC_MDM_ERR == WNC_CMD_ERR)
JMF 2:0e2ef866af95 84 {
JMF 2:0e2ef866af95 85 pc.puts("Bad URL!!!!!!\r\n");
JMF 2:0e2ef866af95 86 }
JMF 2:0e2ef866af95 87 } while (WNC_MDM_ERR != WNC_OK);
JMF 2:0e2ef866af95 88
fkellermavnet 30:33be8e2992f3 89 pc.printf("My Server IP: %s\r\n", MyServerIpAddress.c_str());
JMF 2:0e2ef866af95 90 }
JMF 2:0e2ef866af95 91
JMF 2:0e2ef866af95 92 void sockopen_mdm(void)
JMF 2:0e2ef866af95 93 {
JMF 2:0e2ef866af95 94 do
JMF 2:0e2ef866af95 95 {
JMF 2:0e2ef866af95 96 WNC_MDM_ERR = WNC_OK;
JMF 2:0e2ef866af95 97 at_sockopen_wnc(MyServerIpAddress, MY_PORT_STR);
JMF 2:0e2ef866af95 98 if (WNC_MDM_ERR == WNC_NO_RESPONSE)
JMF 2:0e2ef866af95 99 {
JMF 2:0e2ef866af95 100 software_init_mdm();
JMF 2:0e2ef866af95 101 }
JMF 2:0e2ef866af95 102 else if (WNC_MDM_ERR == WNC_CMD_ERR)
JMF 2:0e2ef866af95 103 pc.puts("Socket open fail!!!!\r\n");
fkellermavnet 10:df54436ecd38 104 else
fkellermavnet 10:df54436ecd38 105 socketOpen = 1;
JMF 2:0e2ef866af95 106 } while (WNC_MDM_ERR != WNC_OK);
JMF 2:0e2ef866af95 107 }
JMF 2:0e2ef866af95 108
JMF 2:0e2ef866af95 109 void sockwrite_mdm(const char * s)
JMF 2:0e2ef866af95 110 {
fkellermavnet 10:df54436ecd38 111 if (socketOpen == 1)
fkellermavnet 10:df54436ecd38 112 {
JMF 2:0e2ef866af95 113 do
JMF 2:0e2ef866af95 114 {
JMF 2:0e2ef866af95 115 WNC_MDM_ERR = WNC_OK;
JMF 2:0e2ef866af95 116 at_sockwrite_wnc(s);
JMF 2:0e2ef866af95 117 if (WNC_MDM_ERR == WNC_NO_RESPONSE)
JMF 2:0e2ef866af95 118 {
fkellermavnet 42:be4b9ee3a615 119 pc.puts("Sock write no response!\r\n");
JMF 2:0e2ef866af95 120 software_init_mdm();
JMF 2:0e2ef866af95 121 }
JMF 2:0e2ef866af95 122 else if (WNC_MDM_ERR == WNC_CMD_ERR)
JMF 2:0e2ef866af95 123 {
JMF 2:0e2ef866af95 124 pc.puts("Socket Write fail!!!\r\n");
JMF 2:0e2ef866af95 125 software_init_mdm();
JMF 2:0e2ef866af95 126 }
JMF 2:0e2ef866af95 127 } while (WNC_MDM_ERR != WNC_OK);
fkellermavnet 10:df54436ecd38 128 }
fkellermavnet 10:df54436ecd38 129 else
fkellermavnet 10:df54436ecd38 130 puts("Socket is closed for write!\r\n");
JMF 2:0e2ef866af95 131 }
JMF 2:0e2ef866af95 132
fkellermavnet 30:33be8e2992f3 133 unsigned sockread_mdm(string * sockData, int len, int retries)
JMF 2:0e2ef866af95 134 {
fkellermavnet 30:33be8e2992f3 135 unsigned n = 0;
fkellermavnet 30:33be8e2992f3 136
fkellermavnet 10:df54436ecd38 137 if (socketOpen == 1)
fkellermavnet 10:df54436ecd38 138 {
JMF 2:0e2ef866af95 139 do
JMF 2:0e2ef866af95 140 {
JMF 2:0e2ef866af95 141 WNC_MDM_ERR = WNC_OK;
fkellermavnet 30:33be8e2992f3 142 n = at_sockread_wnc(sockData, len, retries);
JMF 2:0e2ef866af95 143 if (WNC_MDM_ERR == WNC_NO_RESPONSE)
JMF 2:0e2ef866af95 144 {
fkellermavnet 30:33be8e2992f3 145 if (n == 0)
fkellermavnet 30:33be8e2992f3 146 software_init_mdm();
fkellermavnet 30:33be8e2992f3 147 else
fkellermavnet 30:33be8e2992f3 148 puts("Sock read partial data!!!\r\n");
JMF 2:0e2ef866af95 149 }
JMF 2:0e2ef866af95 150 else if (WNC_MDM_ERR == WNC_CMD_ERR)
JMF 2:0e2ef866af95 151 puts("Sock read fail!!!!\r\n");
fkellermavnet 30:33be8e2992f3 152 } while (WNC_MDM_ERR == WNC_NO_RESPONSE);
fkellermavnet 10:df54436ecd38 153 }
fkellermavnet 10:df54436ecd38 154 else
fkellermavnet 44:c95a85b5cf92 155 {
fkellermavnet 10:df54436ecd38 156 puts("Socket is closed for read\r\n");
fkellermavnet 44:c95a85b5cf92 157 sockData->erase();
fkellermavnet 44:c95a85b5cf92 158 }
fkellermavnet 30:33be8e2992f3 159
fkellermavnet 30:33be8e2992f3 160 return (n);
JMF 2:0e2ef866af95 161 }
JMF 2:0e2ef866af95 162
JMF 2:0e2ef866af95 163 void sockclose_mdm(void)
JMF 2:0e2ef866af95 164 {
JMF 2:0e2ef866af95 165 do
JMF 2:0e2ef866af95 166 {
JMF 2:0e2ef866af95 167 WNC_MDM_ERR = WNC_OK;
JMF 2:0e2ef866af95 168 at_sockclose_wnc();
fkellermavnet 10:df54436ecd38 169 // Assume close happened even if it went bad
fkellermavnet 10:df54436ecd38 170 // going bad will result in a re-init anyways and if close
fkellermavnet 10:df54436ecd38 171 // fails we're pretty much in bad state and not much can do
fkellermavnet 10:df54436ecd38 172 socketOpen = 0;
JMF 2:0e2ef866af95 173 if (WNC_MDM_ERR == WNC_NO_RESPONSE)
JMF 2:0e2ef866af95 174 {
JMF 2:0e2ef866af95 175 software_init_mdm();
JMF 2:0e2ef866af95 176 }
JMF 2:0e2ef866af95 177 else if (WNC_MDM_ERR == WNC_CMD_ERR)
JMF 2:0e2ef866af95 178 puts("Sock close fail!!!\r\n");
JMF 2:0e2ef866af95 179 } while (WNC_MDM_ERR != WNC_OK);
JMF 2:0e2ef866af95 180 }
JMF 2:0e2ef866af95 181
JMF 2:0e2ef866af95 182 /**
JMF 2:0e2ef866af95 183 * C++ version 0.4 char* style "itoa":
JMF 2:0e2ef866af95 184 * Written by Lukás Chmela
JMF 2:0e2ef866af95 185 * Released under GPLv3.
JMF 2:0e2ef866af95 186 */
JMF 2:0e2ef866af95 187
JMF 2:0e2ef866af95 188 char* itoa(int value, char* result, int base)
JMF 2:0e2ef866af95 189 {
JMF 2:0e2ef866af95 190 // check that the base if valid
JMF 2:0e2ef866af95 191 if ( base < 2 || base > 36 ) {
JMF 2:0e2ef866af95 192 *result = '\0';
JMF 2:0e2ef866af95 193 return result;
JMF 2:0e2ef866af95 194 }
JMF 2:0e2ef866af95 195
JMF 2:0e2ef866af95 196 char* ptr = result, *ptr1 = result, tmp_char;
JMF 2:0e2ef866af95 197 int tmp_value;
JMF 2:0e2ef866af95 198
JMF 2:0e2ef866af95 199 do {
JMF 2:0e2ef866af95 200 tmp_value = value;
JMF 2:0e2ef866af95 201 value /= base;
JMF 2:0e2ef866af95 202 *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - value * base)];
JMF 2:0e2ef866af95 203 } while ( value );
JMF 2:0e2ef866af95 204
JMF 2:0e2ef866af95 205 // Apply negative sign
JMF 2:0e2ef866af95 206 if ( tmp_value < 0 )
JMF 2:0e2ef866af95 207 *ptr++ = '-';
JMF 2:0e2ef866af95 208 *ptr-- = '\0';
JMF 2:0e2ef866af95 209
JMF 2:0e2ef866af95 210 while ( ptr1 < ptr ) {
JMF 2:0e2ef866af95 211 tmp_char = *ptr;
JMF 2:0e2ef866af95 212 *ptr-- = *ptr1;
JMF 2:0e2ef866af95 213 *ptr1++ = tmp_char;
JMF 2:0e2ef866af95 214 }
JMF 2:0e2ef866af95 215
JMF 2:0e2ef866af95 216 return result;
JMF 2:0e2ef866af95 217 }
JMF 2:0e2ef866af95 218
JMF 2:0e2ef866af95 219 extern int mdm_sendAtCmdRsp(const char *cmd, const char **rsp_list, int timeout_ms, string * rsp, int * len);
JMF 2:0e2ef866af95 220
fkellermavnet 42:be4b9ee3a615 221 int check_wnc_ready(void)
fkellermavnet 42:be4b9ee3a615 222 {
fkellermavnet 43:6821a9c78c4b 223 string * pRespStr;
fkellermavnet 43:6821a9c78c4b 224 size_t pos;
fkellermavnet 43:6821a9c78c4b 225 int regSts;
fkellermavnet 46:da9d788f5d5a 226 int cmdRes1, cmdRes2;
fkellermavnet 42:be4b9ee3a615 227
fkellermavnet 43:6821a9c78c4b 228 pc.puts("<-------- Begin Cell Status ------------\r\n");
fkellermavnet 46:da9d788f5d5a 229
fkellermavnet 46:da9d788f5d5a 230 cmdRes1 = at_send_wnc_cmd("AT+CSQ", &pRespStr, WNC_TIMEOUT_MS); // Check RSSI,BER
fkellermavnet 46:da9d788f5d5a 231 cmdRes2 = at_send_wnc_cmd("AT+CPIN?", &pRespStr, WNC_TIMEOUT_MS); // Check if SIM locked
fkellermavnet 46:da9d788f5d5a 232
fkellermavnet 46:da9d788f5d5a 233 if ((cmdRes1 != 0) && (cmdRes2 != 0))
fkellermavnet 43:6821a9c78c4b 234 {
fkellermavnet 43:6821a9c78c4b 235 pc.puts("------------ WNC No Response! --------->\r\n");
fkellermavnet 43:6821a9c78c4b 236 return (-2);
fkellermavnet 43:6821a9c78c4b 237 }
fkellermavnet 42:be4b9ee3a615 238
fkellermavnet 43:6821a9c78c4b 239 // If SIM Card not ready don't bother with commands!
fkellermavnet 43:6821a9c78c4b 240 if (pRespStr->find("CPIN: READY") == string::npos)
fkellermavnet 43:6821a9c78c4b 241 {
fkellermavnet 43:6821a9c78c4b 242 pc.puts("------------ WNC SIM Problem! --------->\r\n");
fkellermavnet 43:6821a9c78c4b 243 return (-1);
fkellermavnet 43:6821a9c78c4b 244 }
fkellermavnet 43:6821a9c78c4b 245
fkellermavnet 43:6821a9c78c4b 246 // SIM card OK, now check for signal and cellular network registration
fkellermavnet 46:da9d788f5d5a 247 cmdRes1 = at_send_wnc_cmd("AT+CREG?", &pRespStr, WNC_TIMEOUT_MS); // Check if registered on network
fkellermavnet 42:be4b9ee3a615 248 pos = pRespStr->find("CREG: ");
fkellermavnet 42:be4b9ee3a615 249 if (pos != string::npos)
fkellermavnet 42:be4b9ee3a615 250 {
fkellermavnet 43:6821a9c78c4b 251 // The registration is the 2nd arg in the comma separated list
fkellermavnet 43:6821a9c78c4b 252 *pRespStr = pRespStr->substr(pos+8, 1);
fkellermavnet 43:6821a9c78c4b 253 regSts = atoi(pRespStr->c_str());
fkellermavnet 43:6821a9c78c4b 254 // 1 - registered home, 5 - registered roaming
fkellermavnet 43:6821a9c78c4b 255 if ((regSts != 1) && (regSts != 5))
fkellermavnet 43:6821a9c78c4b 256 {
fkellermavnet 43:6821a9c78c4b 257 pc.puts("------------ WNC Cell Link Down! ------>\r\n");
fkellermavnet 43:6821a9c78c4b 258 return (-2);
fkellermavnet 43:6821a9c78c4b 259 }
fkellermavnet 42:be4b9ee3a615 260 }
fkellermavnet 43:6821a9c78c4b 261
fkellermavnet 43:6821a9c78c4b 262 pc.puts("------------ WNC Ready ---------------->\r\n");
fkellermavnet 42:be4b9ee3a615 263
fkellermavnet 43:6821a9c78c4b 264 return (0);
fkellermavnet 42:be4b9ee3a615 265 }
fkellermavnet 42:be4b9ee3a615 266
JMF 2:0e2ef866af95 267 // Sets a global with failure or success, assumes 1 thread all the time
JMF 2:0e2ef866af95 268 int send_wnc_cmd(const char * s, string ** r, int ms_timeout)
JMF 2:0e2ef866af95 269 {
fkellermavnet 46:da9d788f5d5a 270 int cmdRes;
fkellermavnet 46:da9d788f5d5a 271
fkellermavnet 42:be4b9ee3a615 272 if (check_wnc_ready() < 0)
fkellermavnet 42:be4b9ee3a615 273 {
fkellermavnet 45:a836eecd5d12 274 static string noRespStr;
fkellermavnet 42:be4b9ee3a615 275 string truncStr(s, 50);
fkellermavnet 42:be4b9ee3a615 276 pc.puts("FAIL send cmd: ");
fkellermavnet 42:be4b9ee3a615 277 pc.puts(truncStr.c_str());
fkellermavnet 42:be4b9ee3a615 278 pc.puts("\r\n");
fkellermavnet 46:da9d788f5d5a 279 WNC_MDM_ERR = WNC_CELL_LINK_DOWN;
fkellermavnet 45:a836eecd5d12 280 noRespStr.erase();
fkellermavnet 44:c95a85b5cf92 281 *r = &noRespStr;
fkellermavnet 46:da9d788f5d5a 282 return (-3);
fkellermavnet 42:be4b9ee3a615 283 }
fkellermavnet 42:be4b9ee3a615 284
fkellermavnet 42:be4b9ee3a615 285 // If WNC ready, send user command
fkellermavnet 46:da9d788f5d5a 286 cmdRes = at_send_wnc_cmd(s, r, ms_timeout);
fkellermavnet 46:da9d788f5d5a 287
fkellermavnet 46:da9d788f5d5a 288 if (cmdRes == -1)
fkellermavnet 46:da9d788f5d5a 289 WNC_MDM_ERR = WNC_CMD_ERR;
fkellermavnet 46:da9d788f5d5a 290
fkellermavnet 46:da9d788f5d5a 291 if (cmdRes == -2)
fkellermavnet 46:da9d788f5d5a 292 WNC_MDM_ERR = WNC_NO_RESPONSE;
fkellermavnet 46:da9d788f5d5a 293
fkellermavnet 46:da9d788f5d5a 294 if (cmdRes == 0)
fkellermavnet 46:da9d788f5d5a 295 WNC_MDM_ERR = WNC_OK;
fkellermavnet 46:da9d788f5d5a 296
fkellermavnet 46:da9d788f5d5a 297 return (cmdRes);
fkellermavnet 42:be4b9ee3a615 298 }
fkellermavnet 42:be4b9ee3a615 299
fkellermavnet 42:be4b9ee3a615 300 int at_send_wnc_cmd(const char * s, string ** r, int ms_timeout)
fkellermavnet 42:be4b9ee3a615 301 {
JMF 2:0e2ef866af95 302 static const char * rsp_lst[] = { "OK", "ERROR", NULL };
JMF 2:0e2ef866af95 303 int len;
fkellermavnet 42:be4b9ee3a615 304 if (strlen(s) > 60)
fkellermavnet 42:be4b9ee3a615 305 {
fkellermavnet 42:be4b9ee3a615 306 string truncStr(s,57);
fkellermavnet 42:be4b9ee3a615 307 truncStr += "...";
fkellermavnet 42:be4b9ee3a615 308 pc.printf("Send: <<%s>>\r\n",truncStr.c_str());
fkellermavnet 42:be4b9ee3a615 309 }
fkellermavnet 42:be4b9ee3a615 310 else
fkellermavnet 42:be4b9ee3a615 311 pc.printf("Send: <<%s>>\r\n",s);
fkellermavnet 42:be4b9ee3a615 312
JMF 2:0e2ef866af95 313 int res = mdm_sendAtCmdRsp(s, rsp_lst, ms_timeout, &wncStr, &len);
JMF 2:0e2ef866af95 314 *r = &wncStr; // Return a pointer to the static string
JMF 2:0e2ef866af95 315
JMF 2:0e2ef866af95 316 if (res >= 0)
fkellermavnet 42:be4b9ee3a615 317 {
JMF 2:0e2ef866af95 318 pc.puts("[");
fkellermavnet 42:be4b9ee3a615 319 if (wncStr.size() < 51)
fkellermavnet 42:be4b9ee3a615 320 pc.puts(wncStr.c_str());
fkellermavnet 42:be4b9ee3a615 321 else
fkellermavnet 42:be4b9ee3a615 322 {
fkellermavnet 42:be4b9ee3a615 323 string truncStr = wncStr.substr(0,50) + "...";
fkellermavnet 42:be4b9ee3a615 324 pc.puts(truncStr.c_str());
fkellermavnet 42:be4b9ee3a615 325 }
JMF 2:0e2ef866af95 326 pc.puts("]\n\r");
fkellermavnet 42:be4b9ee3a615 327
JMF 2:0e2ef866af95 328 if (res > 0)
JMF 2:0e2ef866af95 329 return -1;
JMF 2:0e2ef866af95 330 else
JMF 2:0e2ef866af95 331 return 0;
JMF 2:0e2ef866af95 332 }
JMF 2:0e2ef866af95 333 else
JMF 2:0e2ef866af95 334 {
JMF 2:0e2ef866af95 335 pc.puts("No response from WNC!\n\r");
JMF 2:0e2ef866af95 336 return -2;
JMF 2:0e2ef866af95 337 }
JMF 2:0e2ef866af95 338 }
JMF 2:0e2ef866af95 339
fkellermavnet 42:be4b9ee3a615 340
fkellermavnet 19:f89baed3bd6f 341 void at_at_wnc(void)
fkellermavnet 19:f89baed3bd6f 342 {
fkellermavnet 19:f89baed3bd6f 343 string * pRespStr;
fkellermavnet 19:f89baed3bd6f 344 send_wnc_cmd("AT", &pRespStr, WNC_TIMEOUT_MS); // Heartbeat?
fkellermavnet 19:f89baed3bd6f 345 }
fkellermavnet 19:f89baed3bd6f 346
fkellermavnet 42:be4b9ee3a615 347 void at_init_wnc(bool hardReset)
JMF 2:0e2ef866af95 348 {
fkellermavnet 36:d4782eabff43 349 static bool pdnSet = false;
fkellermavnet 42:be4b9ee3a615 350 static bool intSet = false;
fkellermavnet 42:be4b9ee3a615 351 static bool sockDialSet = false;
fkellermavnet 42:be4b9ee3a615 352 string * pRespStr;
fkellermavnet 46:da9d788f5d5a 353 int cmdRes;
fkellermavnet 36:d4782eabff43 354
fkellermavnet 42:be4b9ee3a615 355 if (hardReset == true)
fkellermavnet 42:be4b9ee3a615 356 {
fkellermavnet 43:6821a9c78c4b 357 pc.puts("Hard Reset!\r\n");
fkellermavnet 42:be4b9ee3a615 358 pdnSet = false;
fkellermavnet 42:be4b9ee3a615 359 intSet = false;
fkellermavnet 42:be4b9ee3a615 360 sockDialSet = false;
fkellermavnet 42:be4b9ee3a615 361 }
fkellermavnet 42:be4b9ee3a615 362
fkellermavnet 36:d4782eabff43 363 pc.puts("Start AT init of WNC:\r\n");
fkellermavnet 43:6821a9c78c4b 364 // Quick commands below do not need to check cellular connectivity
fkellermavnet 46:da9d788f5d5a 365 cmdRes = at_send_wnc_cmd("AT", &pRespStr, WNC_TIMEOUT_MS); // Heartbeat?
fkellermavnet 46:da9d788f5d5a 366 cmdRes += at_send_wnc_cmd("ATE0", &pRespStr, WNC_TIMEOUT_MS); // Echo Off
fkellermavnet 46:da9d788f5d5a 367 cmdRes += at_send_wnc_cmd("AT+CMEE=2", &pRespStr, WNC_TIMEOUT_MS); // 2 - verbose error, 1 - numeric error, 0 - just ERROR
fkellermavnet 43:6821a9c78c4b 368
fkellermavnet 43:6821a9c78c4b 369 // If the simple commands are not working no chance of more complex.
fkellermavnet 43:6821a9c78c4b 370 // I have seen re-trying commands make it worse.
fkellermavnet 46:da9d788f5d5a 371 if (cmdRes < 0)
fkellermavnet 46:da9d788f5d5a 372 {
fkellermavnet 46:da9d788f5d5a 373 // Since I used the at_send_wnc_cmd I am setting the error state based upon
fkellermavnet 46:da9d788f5d5a 374 // the responses. And since these are simple commands, even if the WNC
fkellermavnet 46:da9d788f5d5a 375 // is saying ERROR, treat it like a no response.
fkellermavnet 46:da9d788f5d5a 376 WNC_MDM_ERR = WNC_NO_RESPONSE;
fkellermavnet 43:6821a9c78c4b 377 return ;
fkellermavnet 46:da9d788f5d5a 378 }
fkellermavnet 42:be4b9ee3a615 379
fkellermavnet 46:da9d788f5d5a 380 if (intSet == false)
fkellermavnet 46:da9d788f5d5a 381 cmdRes = send_wnc_cmd("AT@INTERNET=1", &pRespStr, WNC_TIMEOUT_MS);
fkellermavnet 42:be4b9ee3a615 382
fkellermavnet 46:da9d788f5d5a 383 if (cmdRes == 0)
fkellermavnet 42:be4b9ee3a615 384 intSet = true;
fkellermavnet 42:be4b9ee3a615 385 else
fkellermavnet 42:be4b9ee3a615 386 return ;
fkellermavnet 42:be4b9ee3a615 387
fkellermavnet 36:d4782eabff43 388 if (pdnSet == false)
fkellermavnet 36:d4782eabff43 389 {
fkellermavnet 36:d4782eabff43 390 string cmd_str("AT%PDNSET=1,");
fkellermavnet 36:d4782eabff43 391 cmd_str += MY_APN_STR;
fkellermavnet 36:d4782eabff43 392 cmd_str += ",IP";
fkellermavnet 46:da9d788f5d5a 393 cmdRes = send_wnc_cmd(cmd_str.c_str(), &pRespStr, 4*WNC_TIMEOUT_MS); // Set APN, cmd seems to take a little longer sometimes
fkellermavnet 42:be4b9ee3a615 394 }
fkellermavnet 42:be4b9ee3a615 395
fkellermavnet 46:da9d788f5d5a 396 if (cmdRes == 0)
fkellermavnet 42:be4b9ee3a615 397 pdnSet = true;
fkellermavnet 42:be4b9ee3a615 398 else
fkellermavnet 42:be4b9ee3a615 399 return ;
fkellermavnet 42:be4b9ee3a615 400
fkellermavnet 42:be4b9ee3a615 401 if (sockDialSet == false)
fkellermavnet 46:da9d788f5d5a 402 cmdRes = send_wnc_cmd("AT@SOCKDIAL=1", &pRespStr, WNC_TIMEOUT_MS);
fkellermavnet 42:be4b9ee3a615 403
fkellermavnet 46:da9d788f5d5a 404 if (cmdRes == 0)
fkellermavnet 42:be4b9ee3a615 405 sockDialSet = true;
fkellermavnet 42:be4b9ee3a615 406 else
fkellermavnet 42:be4b9ee3a615 407 return ;
fkellermavnet 42:be4b9ee3a615 408
fkellermavnet 42:be4b9ee3a615 409 pc.puts("SUCCESS: AT init of WNC!\r\n");
JMF 2:0e2ef866af95 410 }
JMF 2:0e2ef866af95 411
JMF 2:0e2ef866af95 412 void at_sockopen_wnc(const string & ipStr, const char * port )
JMF 2:0e2ef866af95 413 {
JMF 2:0e2ef866af95 414 string * pRespStr;
JMF 2:0e2ef866af95 415 send_wnc_cmd("AT@SOCKCREAT=1", &pRespStr, WNC_TIMEOUT_MS);
JMF 2:0e2ef866af95 416 string cmd_str("AT@SOCKCONN=1,\"");
JMF 2:0e2ef866af95 417 cmd_str += ipStr;
JMF 2:0e2ef866af95 418 cmd_str += "\",";
JMF 2:0e2ef866af95 419 cmd_str += port;
fkellermavnet 38:564b312a719f 420 cmd_str += ",30";
fkellermavnet 39:1996eaec02d6 421 send_wnc_cmd(cmd_str.c_str(), &pRespStr, 31000);
JMF 2:0e2ef866af95 422 }
JMF 2:0e2ef866af95 423
JMF 2:0e2ef866af95 424 void at_sockclose_wnc(void)
JMF 2:0e2ef866af95 425 {
JMF 2:0e2ef866af95 426 string * pRespStr;
JMF 2:0e2ef866af95 427 send_wnc_cmd("AT@SOCKCLOSE=1", &pRespStr, WNC_TIMEOUT_MS);
JMF 2:0e2ef866af95 428 }
JMF 2:0e2ef866af95 429
JMF 2:0e2ef866af95 430 int at_dnsresolve_wnc(const char * s, string * ipStr)
JMF 2:0e2ef866af95 431 {
JMF 2:0e2ef866af95 432 string * pRespStr;
JMF 2:0e2ef866af95 433 string str(s);
fkellermavnet 43:6821a9c78c4b 434 str = "AT@DNSRESVDON=\"" + str + "\"";
fkellermavnet 46:da9d788f5d5a 435 if (send_wnc_cmd(str.c_str(), &pRespStr, 15000) == 0)
JMF 2:0e2ef866af95 436 {
JMF 2:0e2ef866af95 437 size_t pos_start = pRespStr->find(":\"") + 2;
fkellermavnet 43:6821a9c78c4b 438 size_t pos_end = pRespStr->rfind("\"") - 1;
fkellermavnet 43:6821a9c78c4b 439 if ((pos_start != string::npos) && (pos_end != string::npos))
JMF 2:0e2ef866af95 440 {
JMF 2:0e2ef866af95 441 if (pos_end > pos_start)
JMF 2:0e2ef866af95 442 {
JMF 2:0e2ef866af95 443 // Make a copy for use later (the source string is re-used)
JMF 2:0e2ef866af95 444 *ipStr = pRespStr->substr(pos_start, pos_end - pos_start + 1);
JMF 2:0e2ef866af95 445 return 1;
JMF 2:0e2ef866af95 446 }
JMF 2:0e2ef866af95 447 else
JMF 2:0e2ef866af95 448 pc.puts("URL Resolve fail, substr Err\r\n");
JMF 2:0e2ef866af95 449 }
JMF 2:0e2ef866af95 450 else
JMF 2:0e2ef866af95 451 pc.puts("URL Resolve fail, no quotes\r\n");
JMF 2:0e2ef866af95 452 }
JMF 2:0e2ef866af95 453 else
JMF 2:0e2ef866af95 454 pc.puts("URL Resolve fail, WNC cmd fail\r\n");
JMF 2:0e2ef866af95 455
fkellermavnet 43:6821a9c78c4b 456 *ipStr = "192.168.0.1";
fkellermavnet 43:6821a9c78c4b 457
JMF 2:0e2ef866af95 458 return -1;
JMF 2:0e2ef866af95 459 }
JMF 2:0e2ef866af95 460
JMF 2:0e2ef866af95 461 void at_sockwrite_wnc(const char * s)
JMF 2:0e2ef866af95 462 {
JMF 2:0e2ef866af95 463 string * pRespStr;
JMF 2:0e2ef866af95 464 char num2str[6];
JMF 2:0e2ef866af95 465 size_t sLen = strlen(s);
fkellermavnet 39:1996eaec02d6 466 if (sLen <= 1500)
JMF 2:0e2ef866af95 467 {
JMF 2:0e2ef866af95 468 string cmd_str("AT@SOCKWRITE=1,");
JMF 2:0e2ef866af95 469 itoa(sLen, num2str, 10);
JMF 2:0e2ef866af95 470 cmd_str += num2str;
JMF 2:0e2ef866af95 471 cmd_str += ",\"";
JMF 2:0e2ef866af95 472 while(*s != '\0')
JMF 2:0e2ef866af95 473 {
JMF 2:0e2ef866af95 474 itoa((int)*s++, num2str, 16);
JMF 2:0e2ef866af95 475 // Always 2-digit ascii hex:
JMF 2:0e2ef866af95 476 if (strlen(num2str) == 1)
JMF 2:0e2ef866af95 477 {
JMF 2:0e2ef866af95 478 num2str[2] = '\0';
JMF 2:0e2ef866af95 479 num2str[1] = num2str[0];
JMF 2:0e2ef866af95 480 num2str[0] = '0';
JMF 2:0e2ef866af95 481 }
JMF 2:0e2ef866af95 482 cmd_str += num2str;
JMF 2:0e2ef866af95 483 }
JMF 2:0e2ef866af95 484 cmd_str += "\"";
fkellermavnet 42:be4b9ee3a615 485 send_wnc_cmd(cmd_str.c_str(), &pRespStr, 120000);
JMF 2:0e2ef866af95 486 }
JMF 2:0e2ef866af95 487 else
JMF 2:0e2ef866af95 488 pc.puts("sockwrite Err, string to long\r\n");
JMF 2:0e2ef866af95 489 }
JMF 2:0e2ef866af95 490
JMF 2:0e2ef866af95 491 unsigned at_sockread_wnc(string * pS, unsigned n, unsigned retries = 0)
JMF 2:0e2ef866af95 492 {
fkellermavnet 34:1a4498e3580e 493 unsigned i, numBytes = 0;
JMF 2:0e2ef866af95 494 string * pRespStr;
JMF 2:0e2ef866af95 495 string cmd_str("AT@SOCKREAD=1,");
fkellermavnet 30:33be8e2992f3 496
fkellermavnet 44:c95a85b5cf92 497 // Clean slate
fkellermavnet 44:c95a85b5cf92 498 pS->erase();
fkellermavnet 44:c95a85b5cf92 499
JMF 2:0e2ef866af95 500 if (n <= 1500)
JMF 2:0e2ef866af95 501 {
JMF 2:0e2ef866af95 502 char num2str[6];
fkellermavnet 22:41e6c417ace1 503
JMF 2:0e2ef866af95 504 itoa(n, num2str, 10);
JMF 2:0e2ef866af95 505 cmd_str += num2str;
JMF 2:0e2ef866af95 506 retries += 1;
JMF 2:0e2ef866af95 507 while (retries--)
JMF 2:0e2ef866af95 508 {
fkellermavnet 22:41e6c417ace1 509 // Assuming someone is sending then calling this to receive response, invoke
fkellermavnet 22:41e6c417ace1 510 // a pause to give the response some time to come back and then also
fkellermavnet 22:41e6c417ace1 511 // between each retry.
fkellermavnet 22:41e6c417ace1 512 wait_ms(10);
fkellermavnet 22:41e6c417ace1 513
fkellermavnet 30:33be8e2992f3 514 send_wnc_cmd(cmd_str.c_str(), &pRespStr, WNC_TIMEOUT_MS);
fkellermavnet 43:6821a9c78c4b 515
JMF 2:0e2ef866af95 516 size_t pos_start = pRespStr->find("\"") + 1;
JMF 2:0e2ef866af95 517 size_t pos_end = pRespStr->rfind("\"") - 1;
fkellermavnet 43:6821a9c78c4b 518
fkellermavnet 43:6821a9c78c4b 519 // Make sure search finds what it's looking for!
fkellermavnet 43:6821a9c78c4b 520 if (pos_start != string::npos && pos_end != string::npos)
fkellermavnet 43:6821a9c78c4b 521 i = (pos_end - pos_start + 1); // Num hex chars, 2 per byte
fkellermavnet 43:6821a9c78c4b 522 else
fkellermavnet 43:6821a9c78c4b 523 i = 0;
fkellermavnet 43:6821a9c78c4b 524
JMF 2:0e2ef866af95 525 if (i > 0)
JMF 2:0e2ef866af95 526 {
fkellermavnet 34:1a4498e3580e 527 retries = 1; // If any data found retry 1 more time to catch data that might be in another
fkellermavnet 34:1a4498e3580e 528 // WNC payload
JMF 2:0e2ef866af95 529 string byte;
JMF 2:0e2ef866af95 530 while (pos_start < pos_end)
JMF 2:0e2ef866af95 531 {
JMF 2:0e2ef866af95 532 byte = pRespStr->substr(pos_start, 2);
fkellermavnet 30:33be8e2992f3 533 *pS += (char)strtol(byte.c_str(), NULL, 16);
JMF 2:0e2ef866af95 534 pos_start += 2;
JMF 2:0e2ef866af95 535 }
fkellermavnet 34:1a4498e3580e 536 numBytes += i/2;
JMF 2:0e2ef866af95 537 }
JMF 2:0e2ef866af95 538 }
JMF 2:0e2ef866af95 539 }
JMF 2:0e2ef866af95 540 else
JMF 2:0e2ef866af95 541 pc.puts("sockread Err, to many to read\r\n");
JMF 2:0e2ef866af95 542
fkellermavnet 43:6821a9c78c4b 543 return (numBytes);
JMF 2:0e2ef866af95 544 }