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:
stefanrousseau
Date:
Mon Aug 01 23:32:55 2016 +0000
Revision:
64:09004cd610df
Parent:
63:90d7c69993cd
Child:
66:b2425419b0cc
Replaced all printf's with PRINTF=pc.printf; moved to latest mbed library

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