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 03:10:21 2016 +0000
Revision:
42:be4b9ee3a615
Parent:
40:aec4d09fde23
Child:
43:6821a9c78c4b
Re-did debug output.; Added poll of Cellular connectivity of WNC before every command.; Eliminated calling hardware init unless the initial and subsequent software init fails.; Added one-shot to commands that the WNC seems sensitive too.

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 30:33be8e2992f3 138 // Clean slate:
fkellermavnet 30:33be8e2992f3 139 sockData->erase();
fkellermavnet 30:33be8e2992f3 140
fkellermavnet 10:df54436ecd38 141 if (socketOpen == 1)
fkellermavnet 10:df54436ecd38 142 {
JMF 2:0e2ef866af95 143 do
JMF 2:0e2ef866af95 144 {
JMF 2:0e2ef866af95 145 WNC_MDM_ERR = WNC_OK;
fkellermavnet 30:33be8e2992f3 146 n = at_sockread_wnc(sockData, len, retries);
JMF 2:0e2ef866af95 147 if (WNC_MDM_ERR == WNC_NO_RESPONSE)
JMF 2:0e2ef866af95 148 {
fkellermavnet 30:33be8e2992f3 149 if (n == 0)
fkellermavnet 30:33be8e2992f3 150 software_init_mdm();
fkellermavnet 30:33be8e2992f3 151 else
fkellermavnet 30:33be8e2992f3 152 puts("Sock read partial data!!!\r\n");
JMF 2:0e2ef866af95 153 }
JMF 2:0e2ef866af95 154 else if (WNC_MDM_ERR == WNC_CMD_ERR)
JMF 2:0e2ef866af95 155 puts("Sock read fail!!!!\r\n");
fkellermavnet 30:33be8e2992f3 156 } while (WNC_MDM_ERR == WNC_NO_RESPONSE);
fkellermavnet 10:df54436ecd38 157 }
fkellermavnet 10:df54436ecd38 158 else
fkellermavnet 10:df54436ecd38 159 puts("Socket is closed for read\r\n");
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 42:be4b9ee3a615 224 string * pRespStr;
fkellermavnet 42:be4b9ee3a615 225 size_t pos;
fkellermavnet 42:be4b9ee3a615 226 int regSts;
fkellermavnet 42:be4b9ee3a615 227
fkellermavnet 42:be4b9ee3a615 228 pc.puts("<-------- Begin Cell Status ------------\r\n");
fkellermavnet 42:be4b9ee3a615 229
fkellermavnet 42:be4b9ee3a615 230 at_send_wnc_cmd("AT+CSQ", &pRespStr, WNC_TIMEOUT_MS); // Check RSSI,BER
fkellermavnet 42:be4b9ee3a615 231 at_send_wnc_cmd("AT+CPIN?", &pRespStr, WNC_TIMEOUT_MS); // Check if SIM locked
fkellermavnet 42:be4b9ee3a615 232
fkellermavnet 42:be4b9ee3a615 233 // If SIM Card not ready don't bother with commands!
fkellermavnet 42:be4b9ee3a615 234 if (pRespStr->find("CPIN: READY") == string::npos)
fkellermavnet 42:be4b9ee3a615 235 {
fkellermavnet 42:be4b9ee3a615 236 pc.puts("------------ WNC SIM Problem! --------->\r\n");
fkellermavnet 42:be4b9ee3a615 237 return (-1);
fkellermavnet 42:be4b9ee3a615 238 }
fkellermavnet 42:be4b9ee3a615 239
fkellermavnet 42:be4b9ee3a615 240 // SIM card OK, now check for signal and cellular network registration
fkellermavnet 42:be4b9ee3a615 241 // do
fkellermavnet 42:be4b9ee3a615 242 // {
fkellermavnet 42:be4b9ee3a615 243 at_send_wnc_cmd("AT+CREG?", &pRespStr, WNC_TIMEOUT_MS); // Check if registered on network
fkellermavnet 42:be4b9ee3a615 244 pos = pRespStr->find("CREG: ");
fkellermavnet 42:be4b9ee3a615 245 if (pos != string::npos)
fkellermavnet 42:be4b9ee3a615 246 {
fkellermavnet 42:be4b9ee3a615 247 // The registration is the 2nd arg in the comma separated list
fkellermavnet 42:be4b9ee3a615 248 *pRespStr = pRespStr->substr(pos+8, 1);
fkellermavnet 42:be4b9ee3a615 249 regSts = atoi(pRespStr->c_str());
fkellermavnet 42:be4b9ee3a615 250 // 1 - registered home, 5 - registered roaming
fkellermavnet 42:be4b9ee3a615 251 if ((regSts != 1) && (regSts != 5))
fkellermavnet 42:be4b9ee3a615 252 {
fkellermavnet 42:be4b9ee3a615 253 pc.puts("------------ WNC Cell Link Down! ------>\r\n");
fkellermavnet 42:be4b9ee3a615 254 return (-2);
fkellermavnet 42:be4b9ee3a615 255 }
fkellermavnet 42:be4b9ee3a615 256 }
fkellermavnet 42:be4b9ee3a615 257 // } while ((regSts != 1) && (regSts !=5));
fkellermavnet 42:be4b9ee3a615 258 pc.puts("------------ WNC Ready ---------------->\r\n");
fkellermavnet 42:be4b9ee3a615 259
fkellermavnet 42:be4b9ee3a615 260 return (0);
fkellermavnet 42:be4b9ee3a615 261 }
fkellermavnet 42:be4b9ee3a615 262
JMF 2:0e2ef866af95 263 // Sets a global with failure or success, assumes 1 thread all the time
JMF 2:0e2ef866af95 264 int send_wnc_cmd(const char * s, string ** r, int ms_timeout)
JMF 2:0e2ef866af95 265 {
fkellermavnet 42:be4b9ee3a615 266 if (check_wnc_ready() < 0)
fkellermavnet 42:be4b9ee3a615 267 {
fkellermavnet 42:be4b9ee3a615 268 string truncStr(s, 50);
fkellermavnet 42:be4b9ee3a615 269 pc.puts("FAIL send cmd: ");
fkellermavnet 42:be4b9ee3a615 270 pc.puts(truncStr.c_str());
fkellermavnet 42:be4b9ee3a615 271 pc.puts("\r\n");
fkellermavnet 42:be4b9ee3a615 272 WNC_MDM_ERR = WNC_NO_RESPONSE;
fkellermavnet 42:be4b9ee3a615 273 return (-2);
fkellermavnet 42:be4b9ee3a615 274 }
fkellermavnet 42:be4b9ee3a615 275
fkellermavnet 42:be4b9ee3a615 276 // If WNC ready, send user command
fkellermavnet 42:be4b9ee3a615 277 return (at_send_wnc_cmd(s, r, ms_timeout));
fkellermavnet 42:be4b9ee3a615 278 }
fkellermavnet 42:be4b9ee3a615 279
fkellermavnet 42:be4b9ee3a615 280 int at_send_wnc_cmd(const char * s, string ** r, int ms_timeout)
fkellermavnet 42:be4b9ee3a615 281 {
JMF 2:0e2ef866af95 282 static const char * rsp_lst[] = { "OK", "ERROR", NULL };
JMF 2:0e2ef866af95 283 int len;
fkellermavnet 42:be4b9ee3a615 284 if (strlen(s) > 60)
fkellermavnet 42:be4b9ee3a615 285 {
fkellermavnet 42:be4b9ee3a615 286 string truncStr(s,57);
fkellermavnet 42:be4b9ee3a615 287 truncStr += "...";
fkellermavnet 42:be4b9ee3a615 288 pc.printf("Send: <<%s>>\r\n",truncStr.c_str());
fkellermavnet 42:be4b9ee3a615 289 }
fkellermavnet 42:be4b9ee3a615 290 else
fkellermavnet 42:be4b9ee3a615 291 pc.printf("Send: <<%s>>\r\n",s);
fkellermavnet 42:be4b9ee3a615 292
JMF 2:0e2ef866af95 293 int res = mdm_sendAtCmdRsp(s, rsp_lst, ms_timeout, &wncStr, &len);
JMF 2:0e2ef866af95 294 *r = &wncStr; // Return a pointer to the static string
JMF 2:0e2ef866af95 295
JMF 2:0e2ef866af95 296 if (res >= 0)
fkellermavnet 42:be4b9ee3a615 297 {
JMF 2:0e2ef866af95 298 pc.puts("[");
fkellermavnet 42:be4b9ee3a615 299 if (wncStr.size() < 51)
fkellermavnet 42:be4b9ee3a615 300 pc.puts(wncStr.c_str());
fkellermavnet 42:be4b9ee3a615 301 else
fkellermavnet 42:be4b9ee3a615 302 {
fkellermavnet 42:be4b9ee3a615 303 string truncStr = wncStr.substr(0,50) + "...";
fkellermavnet 42:be4b9ee3a615 304 pc.puts(truncStr.c_str());
fkellermavnet 42:be4b9ee3a615 305 }
JMF 2:0e2ef866af95 306 pc.puts("]\n\r");
fkellermavnet 42:be4b9ee3a615 307
JMF 2:0e2ef866af95 308 if (res > 0)
JMF 2:0e2ef866af95 309 {
JMF 2:0e2ef866af95 310 if (WNC_MDM_ERR != WNC_NO_RESPONSE)
JMF 2:0e2ef866af95 311 WNC_MDM_ERR = WNC_CMD_ERR;
JMF 2:0e2ef866af95 312 return -1;
JMF 2:0e2ef866af95 313 }
JMF 2:0e2ef866af95 314 else
JMF 2:0e2ef866af95 315 return 0;
JMF 2:0e2ef866af95 316 }
JMF 2:0e2ef866af95 317 else
JMF 2:0e2ef866af95 318 {
JMF 2:0e2ef866af95 319 WNC_MDM_ERR = WNC_NO_RESPONSE;
JMF 2:0e2ef866af95 320 pc.puts("No response from WNC!\n\r");
JMF 2:0e2ef866af95 321 return -2;
JMF 2:0e2ef866af95 322 }
JMF 2:0e2ef866af95 323 }
JMF 2:0e2ef866af95 324
fkellermavnet 42:be4b9ee3a615 325
fkellermavnet 19:f89baed3bd6f 326 void at_at_wnc(void)
fkellermavnet 19:f89baed3bd6f 327 {
fkellermavnet 19:f89baed3bd6f 328 string * pRespStr;
fkellermavnet 19:f89baed3bd6f 329 send_wnc_cmd("AT", &pRespStr, WNC_TIMEOUT_MS); // Heartbeat?
fkellermavnet 19:f89baed3bd6f 330 }
fkellermavnet 19:f89baed3bd6f 331
fkellermavnet 42:be4b9ee3a615 332 void at_init_wnc(bool hardReset)
JMF 2:0e2ef866af95 333 {
fkellermavnet 36:d4782eabff43 334 static bool pdnSet = false;
fkellermavnet 42:be4b9ee3a615 335 static bool intSet = false;
fkellermavnet 42:be4b9ee3a615 336 static bool sockDialSet = false;
fkellermavnet 42:be4b9ee3a615 337 string * pRespStr;
fkellermavnet 36:d4782eabff43 338
fkellermavnet 42:be4b9ee3a615 339 if (hardReset == true)
fkellermavnet 42:be4b9ee3a615 340 {
fkellermavnet 42:be4b9ee3a615 341 pdnSet = false;
fkellermavnet 42:be4b9ee3a615 342 intSet = false;
fkellermavnet 42:be4b9ee3a615 343 sockDialSet = false;
fkellermavnet 42:be4b9ee3a615 344 }
fkellermavnet 42:be4b9ee3a615 345
fkellermavnet 36:d4782eabff43 346 pc.puts("Start AT init of WNC:\r\n");
fkellermavnet 36:d4782eabff43 347 send_wnc_cmd("AT", &pRespStr, WNC_TIMEOUT_MS); // Heartbeat?
fkellermavnet 42:be4b9ee3a615 348 send_wnc_cmd("ATE0", &pRespStr, WNC_TIMEOUT_MS); // Echo Off
fkellermavnet 36:d4782eabff43 349 send_wnc_cmd("AT+CMEE=2", &pRespStr, WNC_TIMEOUT_MS); // 2 - verbose error, 1 - numeric error, 0 - just ERROR
fkellermavnet 42:be4b9ee3a615 350
fkellermavnet 42:be4b9ee3a615 351 if ((WNC_MDM_ERR == WNC_OK) && (intSet == false))
fkellermavnet 42:be4b9ee3a615 352 send_wnc_cmd("AT@INTERNET=1", &pRespStr, WNC_TIMEOUT_MS);
fkellermavnet 42:be4b9ee3a615 353
fkellermavnet 42:be4b9ee3a615 354 if (WNC_MDM_ERR == WNC_OK)
fkellermavnet 42:be4b9ee3a615 355 intSet = true;
fkellermavnet 42:be4b9ee3a615 356 else
fkellermavnet 42:be4b9ee3a615 357 return ;
fkellermavnet 42:be4b9ee3a615 358
fkellermavnet 36:d4782eabff43 359 if (pdnSet == false)
fkellermavnet 36:d4782eabff43 360 {
fkellermavnet 36:d4782eabff43 361 string cmd_str("AT%PDNSET=1,");
fkellermavnet 36:d4782eabff43 362 cmd_str += MY_APN_STR;
fkellermavnet 36:d4782eabff43 363 cmd_str += ",IP";
fkellermavnet 36:d4782eabff43 364 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 365 }
fkellermavnet 42:be4b9ee3a615 366
fkellermavnet 42:be4b9ee3a615 367 if (WNC_MDM_ERR == WNC_OK)
fkellermavnet 42:be4b9ee3a615 368 pdnSet = true;
fkellermavnet 42:be4b9ee3a615 369 else
fkellermavnet 42:be4b9ee3a615 370 return ;
fkellermavnet 42:be4b9ee3a615 371
fkellermavnet 42:be4b9ee3a615 372 if (sockDialSet == false)
fkellermavnet 36:d4782eabff43 373 send_wnc_cmd("AT@SOCKDIAL=1", &pRespStr, WNC_TIMEOUT_MS);
fkellermavnet 42:be4b9ee3a615 374
fkellermavnet 42:be4b9ee3a615 375 if (WNC_MDM_ERR == WNC_OK)
fkellermavnet 42:be4b9ee3a615 376 sockDialSet = true;
fkellermavnet 42:be4b9ee3a615 377 else
fkellermavnet 42:be4b9ee3a615 378 return ;
fkellermavnet 42:be4b9ee3a615 379
fkellermavnet 42:be4b9ee3a615 380 pc.puts("SUCCESS: AT init of WNC!\r\n");
JMF 2:0e2ef866af95 381 }
JMF 2:0e2ef866af95 382
JMF 2:0e2ef866af95 383 void at_sockopen_wnc(const string & ipStr, const char * port )
JMF 2:0e2ef866af95 384 {
JMF 2:0e2ef866af95 385 string * pRespStr;
JMF 2:0e2ef866af95 386 send_wnc_cmd("AT@SOCKCREAT=1", &pRespStr, WNC_TIMEOUT_MS);
JMF 2:0e2ef866af95 387 string cmd_str("AT@SOCKCONN=1,\"");
JMF 2:0e2ef866af95 388 cmd_str += ipStr;
JMF 2:0e2ef866af95 389 cmd_str += "\",";
JMF 2:0e2ef866af95 390 cmd_str += port;
fkellermavnet 38:564b312a719f 391 cmd_str += ",30";
fkellermavnet 39:1996eaec02d6 392 send_wnc_cmd(cmd_str.c_str(), &pRespStr, 31000);
JMF 2:0e2ef866af95 393 }
JMF 2:0e2ef866af95 394
JMF 2:0e2ef866af95 395 void at_sockclose_wnc(void)
JMF 2:0e2ef866af95 396 {
JMF 2:0e2ef866af95 397 string * pRespStr;
JMF 2:0e2ef866af95 398 send_wnc_cmd("AT@SOCKCLOSE=1", &pRespStr, WNC_TIMEOUT_MS);
JMF 2:0e2ef866af95 399 }
JMF 2:0e2ef866af95 400
JMF 2:0e2ef866af95 401 int at_dnsresolve_wnc(const char * s, string * ipStr)
JMF 2:0e2ef866af95 402 {
JMF 2:0e2ef866af95 403 string * pRespStr;
JMF 2:0e2ef866af95 404 string str(s);
JMF 2:0e2ef866af95 405 str = "AT@DNSRESVDON=\"" + str;
JMF 2:0e2ef866af95 406 str += "\"\r\n";
fkellermavnet 30:33be8e2992f3 407 if (send_wnc_cmd(str.c_str(), &pRespStr, WNC_TIMEOUT_MS) == 0)
JMF 2:0e2ef866af95 408 {
JMF 2:0e2ef866af95 409 size_t pos_start = pRespStr->find(":\"") + 2;
JMF 2:0e2ef866af95 410 if (pos_start != string::npos)
JMF 2:0e2ef866af95 411 {
JMF 2:0e2ef866af95 412 size_t pos_end = pRespStr->rfind("\"") - 1;
JMF 2:0e2ef866af95 413 if (pos_end != string::npos)
JMF 2:0e2ef866af95 414 {
JMF 2:0e2ef866af95 415 if (pos_end > pos_start)
JMF 2:0e2ef866af95 416 {
JMF 2:0e2ef866af95 417 // Make a copy for use later (the source string is re-used)
JMF 2:0e2ef866af95 418 *ipStr = pRespStr->substr(pos_start, pos_end - pos_start + 1);
JMF 2:0e2ef866af95 419 return 1;
JMF 2:0e2ef866af95 420 }
JMF 2:0e2ef866af95 421 else
JMF 2:0e2ef866af95 422 pc.puts("URL Resolve fail, substr Err\r\n");
JMF 2:0e2ef866af95 423 }
JMF 2:0e2ef866af95 424 else
JMF 2:0e2ef866af95 425 pc.puts("URL Resolve fail, no 2nd quote\r\n");
JMF 2:0e2ef866af95 426 }
JMF 2:0e2ef866af95 427 else
JMF 2:0e2ef866af95 428 pc.puts("URL Resolve fail, no quotes\r\n");
JMF 2:0e2ef866af95 429 }
JMF 2:0e2ef866af95 430 else
JMF 2:0e2ef866af95 431 pc.puts("URL Resolve fail, WNC cmd fail\r\n");
JMF 2:0e2ef866af95 432
JMF 2:0e2ef866af95 433 return -1;
JMF 2:0e2ef866af95 434 }
JMF 2:0e2ef866af95 435
JMF 2:0e2ef866af95 436 void at_sockwrite_wnc(const char * s)
JMF 2:0e2ef866af95 437 {
JMF 2:0e2ef866af95 438 string * pRespStr;
JMF 2:0e2ef866af95 439 char num2str[6];
JMF 2:0e2ef866af95 440 size_t sLen = strlen(s);
fkellermavnet 39:1996eaec02d6 441 if (sLen <= 1500)
JMF 2:0e2ef866af95 442 {
JMF 2:0e2ef866af95 443 string cmd_str("AT@SOCKWRITE=1,");
JMF 2:0e2ef866af95 444 itoa(sLen, num2str, 10);
JMF 2:0e2ef866af95 445 cmd_str += num2str;
JMF 2:0e2ef866af95 446 cmd_str += ",\"";
JMF 2:0e2ef866af95 447 while(*s != '\0')
JMF 2:0e2ef866af95 448 {
JMF 2:0e2ef866af95 449 itoa((int)*s++, num2str, 16);
JMF 2:0e2ef866af95 450 // Always 2-digit ascii hex:
JMF 2:0e2ef866af95 451 if (strlen(num2str) == 1)
JMF 2:0e2ef866af95 452 {
JMF 2:0e2ef866af95 453 num2str[2] = '\0';
JMF 2:0e2ef866af95 454 num2str[1] = num2str[0];
JMF 2:0e2ef866af95 455 num2str[0] = '0';
JMF 2:0e2ef866af95 456 }
JMF 2:0e2ef866af95 457 cmd_str += num2str;
JMF 2:0e2ef866af95 458 }
JMF 2:0e2ef866af95 459 cmd_str += "\"";
fkellermavnet 42:be4b9ee3a615 460 send_wnc_cmd(cmd_str.c_str(), &pRespStr, 120000);
JMF 2:0e2ef866af95 461 }
JMF 2:0e2ef866af95 462 else
JMF 2:0e2ef866af95 463 pc.puts("sockwrite Err, string to long\r\n");
JMF 2:0e2ef866af95 464 }
JMF 2:0e2ef866af95 465
JMF 2:0e2ef866af95 466 unsigned at_sockread_wnc(string * pS, unsigned n, unsigned retries = 0)
JMF 2:0e2ef866af95 467 {
fkellermavnet 34:1a4498e3580e 468 unsigned i, numBytes = 0;
JMF 2:0e2ef866af95 469 string * pRespStr;
JMF 2:0e2ef866af95 470 string cmd_str("AT@SOCKREAD=1,");
fkellermavnet 30:33be8e2992f3 471
JMF 2:0e2ef866af95 472 if (n <= 1500)
JMF 2:0e2ef866af95 473 {
JMF 2:0e2ef866af95 474 char num2str[6];
fkellermavnet 22:41e6c417ace1 475
JMF 2:0e2ef866af95 476 itoa(n, num2str, 10);
JMF 2:0e2ef866af95 477 cmd_str += num2str;
JMF 2:0e2ef866af95 478 retries += 1;
JMF 2:0e2ef866af95 479 while (retries--)
JMF 2:0e2ef866af95 480 {
fkellermavnet 22:41e6c417ace1 481 // Assuming someone is sending then calling this to receive response, invoke
fkellermavnet 22:41e6c417ace1 482 // a pause to give the response some time to come back and then also
fkellermavnet 22:41e6c417ace1 483 // between each retry.
fkellermavnet 22:41e6c417ace1 484 wait_ms(10);
fkellermavnet 22:41e6c417ace1 485
fkellermavnet 30:33be8e2992f3 486 send_wnc_cmd(cmd_str.c_str(), &pRespStr, WNC_TIMEOUT_MS);
JMF 2:0e2ef866af95 487 size_t pos_start = pRespStr->find("\"") + 1;
JMF 2:0e2ef866af95 488 size_t pos_end = pRespStr->rfind("\"") - 1;
fkellermavnet 34:1a4498e3580e 489 i = (pos_end - pos_start + 1); // Num hex chars, 2 per byte
JMF 2:0e2ef866af95 490 if (i > 0)
JMF 2:0e2ef866af95 491 {
fkellermavnet 34:1a4498e3580e 492 retries = 1; // If any data found retry 1 more time to catch data that might be in another
fkellermavnet 34:1a4498e3580e 493 // WNC payload
JMF 2:0e2ef866af95 494 string byte;
JMF 2:0e2ef866af95 495 while (pos_start < pos_end)
JMF 2:0e2ef866af95 496 {
JMF 2:0e2ef866af95 497 byte = pRespStr->substr(pos_start, 2);
fkellermavnet 30:33be8e2992f3 498 *pS += (char)strtol(byte.c_str(), NULL, 16);
JMF 2:0e2ef866af95 499 pos_start += 2;
JMF 2:0e2ef866af95 500 }
fkellermavnet 34:1a4498e3580e 501 numBytes += i/2;
JMF 2:0e2ef866af95 502 }
JMF 2:0e2ef866af95 503 }
fkellermavnet 34:1a4498e3580e 504 return numBytes;
JMF 2:0e2ef866af95 505 }
JMF 2:0e2ef866af95 506 else
JMF 2:0e2ef866af95 507 pc.puts("sockread Err, to many to read\r\n");
JMF 2:0e2ef866af95 508
JMF 2:0e2ef866af95 509 return 0;
JMF 2:0e2ef866af95 510 }