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 17:45:30 2016 +0000
Revision:
44:c95a85b5cf92
Parent:
43:6821a9c78c4b
Child:
45:a836eecd5d12
Part 2 fix for exception after no response from WNC sockread.

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