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:
JMF
Date:
Thu Aug 04 16:24:13 2016 +0000
Revision:
67:11db02bb93e1
Parent:
66:b2425419b0cc
Child:
68:6e311c747045
changed 'puts' calls to PUTS and defined them in hardware.h along with PRINTF so we can set them all to pc.puts

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