Pubnub demo for AT&T IoT Starter Kit. Functionally similar to the Flow demo.

Dependencies:   FXOS8700CQ MODSERIAL mbed

http://pubnub.github.io/slides/workshop/pictures/broadcast.png

Pubnub demo for AT&T IoT Starter Kit

This demo is functionally similar to the Flow demo, so you can find general information here: https://developer.mbed.org/users/JMF/code/Avnet_ATT_Cellular_IOT/.

The only difference is that we use Pubnub to publish the measurements and subscribe to receiving the instructions to set the LED.

Settings

Pubnub related settings are:

Pubnub settings in `config_me.h`

PUBNUB_SUBSCRIBE_KEY
PUBNUB_PUBLISH_KEY
PUBNUB_CHANNEL

All are documented in their respective comments.

Pubnub context class

Similar to Pubnub SDKs, we provide a Pubnub context class. It is defined in pubnub.h header file and implemented in pubnub.cpp.

It provides only the fundamental "publish" and "subscribe" methods. They are documented in the header file.

This class is reusable in other code (it is not specific to this demo), it has a very narrow interface to the AT&T IoT cellular modem code. For example of use, you can look at the main() (in main.c).

Sample of published data

Published message w/measurement data

{"serial":"vstarterkit001","temp":89.61,"humidity":35,"accelX":0.97,"accelY":0.013,"accelZ":-0.038}

Don't worry, nobody got burnt, the temperature is in degrees Fahrenheit. :)

Publish a message (from, say, the Pubnub console http://pubnub.com/console) of the form {"LED":<name-of-the-color>} on the channel that this demo listens to (default is hello_world) to turn the LED to that color on the Starter Kit:

Turn LED to red

{"LED":"Red"}

Turn LED to green

{"LED":"Green"}

Turn LED to blue

{"LED":"Blue"}
Committer:
fkellermavnet
Date:
Tue Jul 26 20:32:00 2016 +0000
Revision:
53:dcccf2881fa0
Parent:
46:da9d788f5d5a
Child:
62:73c564e883e9
Added conditional debug.; Removed printf("D %s\r\n") which I never should have checked in this past weekend.; Left code with intermediate level of debug turned on.

Who changed what in which revision?

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