The Hiking Pal tracking device firmware. See full description on the detail page: https://www.hackster.io/bowenfeng/hiking-pal-v1-07c02d

Dependencies:   FXOS8700CQ MODSERIAL mbed

Fork of Avnet_ATT_Cellular_IOT by Avnet

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 }