Mobile Life IoT project using the AT&T IoT Starter Kit Software and files for my device to monitor the status or our Airstream travel trailer RV. A full description of the project is at Hackster.IO here as part of the Realtime AT&T IoT Starter Kit Challenge: https://www.hackster.io/Anubus/mobile-life-iot-9c10be

Dependencies:   FXOS8700CQ MODSERIAL mbed

Committer:
Anubus
Date:
Sun Apr 02 12:28:21 2017 +0000
Revision:
0:bd276b1f1249
public version commit

Who changed what in which revision?

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