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:
Thu Aug 11 00:03:09 2016 +0000
Revision:
68:6e311c747045
Parent:
67:11db02bb93e1
Child:
73:da723fedfdd2
Child:
74:3e3ee15584e5
Added Avnet copyright headers on all source files.

Who changed what in which revision?

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