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 19:31:22 2016 +0000
Revision:
62:73c564e883e9
Parent:
53:dcccf2881fa0
Child:
63:90d7c69993cd
Modified wnccontrol.cpp to use the serial port definitions in hardware.h instead of those locally declared.

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