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:50:42 2016 +0000
Revision:
45:a836eecd5d12
Parent:
44:c95a85b5cf92
Child:
46:da9d788f5d5a
Setup no response string for when WNC is down.  Now erases string in case user manipulated it between calls.

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 45:a836eecd5d12 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 45:a836eecd5d12 278 noRespStr.erase();
fkellermavnet 44:c95a85b5cf92 279 *r = &noRespStr;
fkellermavnet 42:be4b9ee3a615 280 return (-2);
fkellermavnet 42:be4b9ee3a615 281 }
fkellermavnet 42:be4b9ee3a615 282
fkellermavnet 42:be4b9ee3a615 283 // If WNC ready, send user command
fkellermavnet 42:be4b9ee3a615 284 return (at_send_wnc_cmd(s, r, ms_timeout));
fkellermavnet 42:be4b9ee3a615 285 }
fkellermavnet 42:be4b9ee3a615 286
fkellermavnet 42:be4b9ee3a615 287 int at_send_wnc_cmd(const char * s, string ** r, int ms_timeout)
fkellermavnet 42:be4b9ee3a615 288 {
JMF 2:0e2ef866af95 289 static const char * rsp_lst[] = { "OK", "ERROR", NULL };
JMF 2:0e2ef866af95 290 int len;
fkellermavnet 42:be4b9ee3a615 291 if (strlen(s) > 60)
fkellermavnet 42:be4b9ee3a615 292 {
fkellermavnet 42:be4b9ee3a615 293 string truncStr(s,57);
fkellermavnet 42:be4b9ee3a615 294 truncStr += "...";
fkellermavnet 42:be4b9ee3a615 295 pc.printf("Send: <<%s>>\r\n",truncStr.c_str());
fkellermavnet 42:be4b9ee3a615 296 }
fkellermavnet 42:be4b9ee3a615 297 else
fkellermavnet 42:be4b9ee3a615 298 pc.printf("Send: <<%s>>\r\n",s);
fkellermavnet 42:be4b9ee3a615 299
JMF 2:0e2ef866af95 300 int res = mdm_sendAtCmdRsp(s, rsp_lst, ms_timeout, &wncStr, &len);
JMF 2:0e2ef866af95 301 *r = &wncStr; // Return a pointer to the static string
JMF 2:0e2ef866af95 302
JMF 2:0e2ef866af95 303 if (res >= 0)
fkellermavnet 42:be4b9ee3a615 304 {
JMF 2:0e2ef866af95 305 pc.puts("[");
fkellermavnet 42:be4b9ee3a615 306 if (wncStr.size() < 51)
fkellermavnet 42:be4b9ee3a615 307 pc.puts(wncStr.c_str());
fkellermavnet 42:be4b9ee3a615 308 else
fkellermavnet 42:be4b9ee3a615 309 {
fkellermavnet 42:be4b9ee3a615 310 string truncStr = wncStr.substr(0,50) + "...";
fkellermavnet 42:be4b9ee3a615 311 pc.puts(truncStr.c_str());
fkellermavnet 42:be4b9ee3a615 312 }
JMF 2:0e2ef866af95 313 pc.puts("]\n\r");
fkellermavnet 42:be4b9ee3a615 314
JMF 2:0e2ef866af95 315 if (res > 0)
JMF 2:0e2ef866af95 316 {
JMF 2:0e2ef866af95 317 if (WNC_MDM_ERR != WNC_NO_RESPONSE)
JMF 2:0e2ef866af95 318 WNC_MDM_ERR = WNC_CMD_ERR;
JMF 2:0e2ef866af95 319 return -1;
JMF 2:0e2ef866af95 320 }
JMF 2:0e2ef866af95 321 else
JMF 2:0e2ef866af95 322 return 0;
JMF 2:0e2ef866af95 323 }
JMF 2:0e2ef866af95 324 else
JMF 2:0e2ef866af95 325 {
JMF 2:0e2ef866af95 326 WNC_MDM_ERR = WNC_NO_RESPONSE;
JMF 2:0e2ef866af95 327 pc.puts("No response from WNC!\n\r");
JMF 2:0e2ef866af95 328 return -2;
JMF 2:0e2ef866af95 329 }
JMF 2:0e2ef866af95 330 }
JMF 2:0e2ef866af95 331
fkellermavnet 42:be4b9ee3a615 332
fkellermavnet 19:f89baed3bd6f 333 void at_at_wnc(void)
fkellermavnet 19:f89baed3bd6f 334 {
fkellermavnet 19:f89baed3bd6f 335 string * pRespStr;
fkellermavnet 19:f89baed3bd6f 336 send_wnc_cmd("AT", &pRespStr, WNC_TIMEOUT_MS); // Heartbeat?
fkellermavnet 19:f89baed3bd6f 337 }
fkellermavnet 19:f89baed3bd6f 338
fkellermavnet 42:be4b9ee3a615 339 void at_init_wnc(bool hardReset)
JMF 2:0e2ef866af95 340 {
fkellermavnet 36:d4782eabff43 341 static bool pdnSet = false;
fkellermavnet 42:be4b9ee3a615 342 static bool intSet = false;
fkellermavnet 42:be4b9ee3a615 343 static bool sockDialSet = false;
fkellermavnet 42:be4b9ee3a615 344 string * pRespStr;
fkellermavnet 36:d4782eabff43 345
fkellermavnet 42:be4b9ee3a615 346 if (hardReset == true)
fkellermavnet 42:be4b9ee3a615 347 {
fkellermavnet 43:6821a9c78c4b 348 pc.puts("Hard Reset!\r\n");
fkellermavnet 42:be4b9ee3a615 349 pdnSet = false;
fkellermavnet 42:be4b9ee3a615 350 intSet = false;
fkellermavnet 42:be4b9ee3a615 351 sockDialSet = false;
fkellermavnet 42:be4b9ee3a615 352 }
fkellermavnet 42:be4b9ee3a615 353
fkellermavnet 43:6821a9c78c4b 354 WNC_MDM_ERR = WNC_OK; // Below commands will re-establish error state
fkellermavnet 36:d4782eabff43 355 pc.puts("Start AT init of WNC:\r\n");
fkellermavnet 43:6821a9c78c4b 356 // Quick commands below do not need to check cellular connectivity
fkellermavnet 43:6821a9c78c4b 357 at_send_wnc_cmd("AT", &pRespStr, WNC_TIMEOUT_MS); // Heartbeat?
fkellermavnet 43:6821a9c78c4b 358 at_send_wnc_cmd("ATE0", &pRespStr, WNC_TIMEOUT_MS); // Echo Off
fkellermavnet 43:6821a9c78c4b 359 at_send_wnc_cmd("AT+CMEE=2", &pRespStr, WNC_TIMEOUT_MS); // 2 - verbose error, 1 - numeric error, 0 - just ERROR
fkellermavnet 43:6821a9c78c4b 360
fkellermavnet 43:6821a9c78c4b 361 // If the simple commands are not working no chance of more complex.
fkellermavnet 43:6821a9c78c4b 362 // I have seen re-trying commands make it worse.
fkellermavnet 43:6821a9c78c4b 363 if (WNC_MDM_ERR != WNC_OK)
fkellermavnet 43:6821a9c78c4b 364 return ;
fkellermavnet 42:be4b9ee3a615 365
fkellermavnet 42:be4b9ee3a615 366 if ((WNC_MDM_ERR == WNC_OK) && (intSet == false))
fkellermavnet 42:be4b9ee3a615 367 send_wnc_cmd("AT@INTERNET=1", &pRespStr, WNC_TIMEOUT_MS);
fkellermavnet 42:be4b9ee3a615 368
fkellermavnet 42:be4b9ee3a615 369 if (WNC_MDM_ERR == WNC_OK)
fkellermavnet 42:be4b9ee3a615 370 intSet = true;
fkellermavnet 42:be4b9ee3a615 371 else
fkellermavnet 42:be4b9ee3a615 372 return ;
fkellermavnet 42:be4b9ee3a615 373
fkellermavnet 36:d4782eabff43 374 if (pdnSet == false)
fkellermavnet 36:d4782eabff43 375 {
fkellermavnet 36:d4782eabff43 376 string cmd_str("AT%PDNSET=1,");
fkellermavnet 36:d4782eabff43 377 cmd_str += MY_APN_STR;
fkellermavnet 36:d4782eabff43 378 cmd_str += ",IP";
fkellermavnet 36:d4782eabff43 379 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 380 }
fkellermavnet 42:be4b9ee3a615 381
fkellermavnet 42:be4b9ee3a615 382 if (WNC_MDM_ERR == WNC_OK)
fkellermavnet 42:be4b9ee3a615 383 pdnSet = true;
fkellermavnet 42:be4b9ee3a615 384 else
fkellermavnet 42:be4b9ee3a615 385 return ;
fkellermavnet 42:be4b9ee3a615 386
fkellermavnet 42:be4b9ee3a615 387 if (sockDialSet == false)
fkellermavnet 36:d4782eabff43 388 send_wnc_cmd("AT@SOCKDIAL=1", &pRespStr, WNC_TIMEOUT_MS);
fkellermavnet 42:be4b9ee3a615 389
fkellermavnet 42:be4b9ee3a615 390 if (WNC_MDM_ERR == WNC_OK)
fkellermavnet 42:be4b9ee3a615 391 sockDialSet = true;
fkellermavnet 42:be4b9ee3a615 392 else
fkellermavnet 42:be4b9ee3a615 393 return ;
fkellermavnet 42:be4b9ee3a615 394
fkellermavnet 42:be4b9ee3a615 395 pc.puts("SUCCESS: AT init of WNC!\r\n");
JMF 2:0e2ef866af95 396 }
JMF 2:0e2ef866af95 397
JMF 2:0e2ef866af95 398 void at_sockopen_wnc(const string & ipStr, const char * port )
JMF 2:0e2ef866af95 399 {
JMF 2:0e2ef866af95 400 string * pRespStr;
JMF 2:0e2ef866af95 401 send_wnc_cmd("AT@SOCKCREAT=1", &pRespStr, WNC_TIMEOUT_MS);
JMF 2:0e2ef866af95 402 string cmd_str("AT@SOCKCONN=1,\"");
JMF 2:0e2ef866af95 403 cmd_str += ipStr;
JMF 2:0e2ef866af95 404 cmd_str += "\",";
JMF 2:0e2ef866af95 405 cmd_str += port;
fkellermavnet 38:564b312a719f 406 cmd_str += ",30";
fkellermavnet 39:1996eaec02d6 407 send_wnc_cmd(cmd_str.c_str(), &pRespStr, 31000);
JMF 2:0e2ef866af95 408 }
JMF 2:0e2ef866af95 409
JMF 2:0e2ef866af95 410 void at_sockclose_wnc(void)
JMF 2:0e2ef866af95 411 {
JMF 2:0e2ef866af95 412 string * pRespStr;
JMF 2:0e2ef866af95 413 send_wnc_cmd("AT@SOCKCLOSE=1", &pRespStr, WNC_TIMEOUT_MS);
JMF 2:0e2ef866af95 414 }
JMF 2:0e2ef866af95 415
JMF 2:0e2ef866af95 416 int at_dnsresolve_wnc(const char * s, string * ipStr)
JMF 2:0e2ef866af95 417 {
JMF 2:0e2ef866af95 418 string * pRespStr;
JMF 2:0e2ef866af95 419 string str(s);
fkellermavnet 43:6821a9c78c4b 420 str = "AT@DNSRESVDON=\"" + str + "\"";
fkellermavnet 30:33be8e2992f3 421 if (send_wnc_cmd(str.c_str(), &pRespStr, WNC_TIMEOUT_MS) == 0)
JMF 2:0e2ef866af95 422 {
JMF 2:0e2ef866af95 423 size_t pos_start = pRespStr->find(":\"") + 2;
fkellermavnet 43:6821a9c78c4b 424 size_t pos_end = pRespStr->rfind("\"") - 1;
fkellermavnet 43:6821a9c78c4b 425 if ((pos_start != string::npos) && (pos_end != string::npos))
JMF 2:0e2ef866af95 426 {
JMF 2:0e2ef866af95 427 if (pos_end > pos_start)
JMF 2:0e2ef866af95 428 {
JMF 2:0e2ef866af95 429 // Make a copy for use later (the source string is re-used)
JMF 2:0e2ef866af95 430 *ipStr = pRespStr->substr(pos_start, pos_end - pos_start + 1);
JMF 2:0e2ef866af95 431 return 1;
JMF 2:0e2ef866af95 432 }
JMF 2:0e2ef866af95 433 else
JMF 2:0e2ef866af95 434 pc.puts("URL Resolve fail, substr Err\r\n");
JMF 2:0e2ef866af95 435 }
JMF 2:0e2ef866af95 436 else
JMF 2:0e2ef866af95 437 pc.puts("URL Resolve fail, no quotes\r\n");
JMF 2:0e2ef866af95 438 }
JMF 2:0e2ef866af95 439 else
JMF 2:0e2ef866af95 440 pc.puts("URL Resolve fail, WNC cmd fail\r\n");
JMF 2:0e2ef866af95 441
fkellermavnet 43:6821a9c78c4b 442 *ipStr = "192.168.0.1";
fkellermavnet 43:6821a9c78c4b 443
JMF 2:0e2ef866af95 444 return -1;
JMF 2:0e2ef866af95 445 }
JMF 2:0e2ef866af95 446
JMF 2:0e2ef866af95 447 void at_sockwrite_wnc(const char * s)
JMF 2:0e2ef866af95 448 {
JMF 2:0e2ef866af95 449 string * pRespStr;
JMF 2:0e2ef866af95 450 char num2str[6];
JMF 2:0e2ef866af95 451 size_t sLen = strlen(s);
fkellermavnet 39:1996eaec02d6 452 if (sLen <= 1500)
JMF 2:0e2ef866af95 453 {
JMF 2:0e2ef866af95 454 string cmd_str("AT@SOCKWRITE=1,");
JMF 2:0e2ef866af95 455 itoa(sLen, num2str, 10);
JMF 2:0e2ef866af95 456 cmd_str += num2str;
JMF 2:0e2ef866af95 457 cmd_str += ",\"";
JMF 2:0e2ef866af95 458 while(*s != '\0')
JMF 2:0e2ef866af95 459 {
JMF 2:0e2ef866af95 460 itoa((int)*s++, num2str, 16);
JMF 2:0e2ef866af95 461 // Always 2-digit ascii hex:
JMF 2:0e2ef866af95 462 if (strlen(num2str) == 1)
JMF 2:0e2ef866af95 463 {
JMF 2:0e2ef866af95 464 num2str[2] = '\0';
JMF 2:0e2ef866af95 465 num2str[1] = num2str[0];
JMF 2:0e2ef866af95 466 num2str[0] = '0';
JMF 2:0e2ef866af95 467 }
JMF 2:0e2ef866af95 468 cmd_str += num2str;
JMF 2:0e2ef866af95 469 }
JMF 2:0e2ef866af95 470 cmd_str += "\"";
fkellermavnet 42:be4b9ee3a615 471 send_wnc_cmd(cmd_str.c_str(), &pRespStr, 120000);
JMF 2:0e2ef866af95 472 }
JMF 2:0e2ef866af95 473 else
JMF 2:0e2ef866af95 474 pc.puts("sockwrite Err, string to long\r\n");
JMF 2:0e2ef866af95 475 }
JMF 2:0e2ef866af95 476
JMF 2:0e2ef866af95 477 unsigned at_sockread_wnc(string * pS, unsigned n, unsigned retries = 0)
JMF 2:0e2ef866af95 478 {
fkellermavnet 34:1a4498e3580e 479 unsigned i, numBytes = 0;
JMF 2:0e2ef866af95 480 string * pRespStr;
JMF 2:0e2ef866af95 481 string cmd_str("AT@SOCKREAD=1,");
fkellermavnet 30:33be8e2992f3 482
fkellermavnet 44:c95a85b5cf92 483 // Clean slate
fkellermavnet 44:c95a85b5cf92 484 pS->erase();
fkellermavnet 44:c95a85b5cf92 485
JMF 2:0e2ef866af95 486 if (n <= 1500)
JMF 2:0e2ef866af95 487 {
JMF 2:0e2ef866af95 488 char num2str[6];
fkellermavnet 22:41e6c417ace1 489
JMF 2:0e2ef866af95 490 itoa(n, num2str, 10);
JMF 2:0e2ef866af95 491 cmd_str += num2str;
JMF 2:0e2ef866af95 492 retries += 1;
JMF 2:0e2ef866af95 493 while (retries--)
JMF 2:0e2ef866af95 494 {
fkellermavnet 22:41e6c417ace1 495 // Assuming someone is sending then calling this to receive response, invoke
fkellermavnet 22:41e6c417ace1 496 // a pause to give the response some time to come back and then also
fkellermavnet 22:41e6c417ace1 497 // between each retry.
fkellermavnet 22:41e6c417ace1 498 wait_ms(10);
fkellermavnet 22:41e6c417ace1 499
fkellermavnet 30:33be8e2992f3 500 send_wnc_cmd(cmd_str.c_str(), &pRespStr, WNC_TIMEOUT_MS);
fkellermavnet 43:6821a9c78c4b 501
JMF 2:0e2ef866af95 502 size_t pos_start = pRespStr->find("\"") + 1;
JMF 2:0e2ef866af95 503 size_t pos_end = pRespStr->rfind("\"") - 1;
fkellermavnet 43:6821a9c78c4b 504
fkellermavnet 43:6821a9c78c4b 505 // Make sure search finds what it's looking for!
fkellermavnet 43:6821a9c78c4b 506 if (pos_start != string::npos && pos_end != string::npos)
fkellermavnet 43:6821a9c78c4b 507 i = (pos_end - pos_start + 1); // Num hex chars, 2 per byte
fkellermavnet 43:6821a9c78c4b 508 else
fkellermavnet 43:6821a9c78c4b 509 i = 0;
fkellermavnet 43:6821a9c78c4b 510
JMF 2:0e2ef866af95 511 if (i > 0)
JMF 2:0e2ef866af95 512 {
fkellermavnet 34:1a4498e3580e 513 retries = 1; // If any data found retry 1 more time to catch data that might be in another
fkellermavnet 34:1a4498e3580e 514 // WNC payload
JMF 2:0e2ef866af95 515 string byte;
JMF 2:0e2ef866af95 516 while (pos_start < pos_end)
JMF 2:0e2ef866af95 517 {
JMF 2:0e2ef866af95 518 byte = pRespStr->substr(pos_start, 2);
fkellermavnet 30:33be8e2992f3 519 *pS += (char)strtol(byte.c_str(), NULL, 16);
JMF 2:0e2ef866af95 520 pos_start += 2;
JMF 2:0e2ef866af95 521 }
fkellermavnet 34:1a4498e3580e 522 numBytes += i/2;
JMF 2:0e2ef866af95 523 }
JMF 2:0e2ef866af95 524 }
JMF 2:0e2ef866af95 525 }
JMF 2:0e2ef866af95 526 else
JMF 2:0e2ef866af95 527 pc.puts("sockread Err, to many to read\r\n");
JMF 2:0e2ef866af95 528
fkellermavnet 43:6821a9c78c4b 529 return (numBytes);
JMF 2:0e2ef866af95 530 }