modified to get more signal info

Fork of WncControllerLibrary by Fred Kellerman

Committer:
tdMBED
Date:
Sat Nov 25 21:50:17 2017 +0000
Revision:
38:9a1a6f211eb4
Parent:
36:d1a98d5f2bbd
modified to get more signal info

Who changed what in which revision?

UserRevisionLine numberNew contents of line
jmf 36:d1a98d5f2bbd 1 /*
jmf 36:d1a98d5f2bbd 2 Copyright (c) 2016 Fred Kellerman
jmf 36:d1a98d5f2bbd 3
jmf 36:d1a98d5f2bbd 4 Permission is hereby granted, free of charge, to any person obtaining a copy
jmf 36:d1a98d5f2bbd 5 of this software and associated documentation files (the "Software"), to deal
jmf 36:d1a98d5f2bbd 6 in the Software without restriction, including without limitation the rights
jmf 36:d1a98d5f2bbd 7 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
jmf 36:d1a98d5f2bbd 8 copies of the Software, and to permit persons to whom the Software is
jmf 36:d1a98d5f2bbd 9 furnished to do so, subject to the following conditions:
jmf 36:d1a98d5f2bbd 10
jmf 36:d1a98d5f2bbd 11 The above copyright notice and this permission notice shall be included in
jmf 36:d1a98d5f2bbd 12 all copies or substantial portions of the Software.
jmf 36:d1a98d5f2bbd 13
jmf 36:d1a98d5f2bbd 14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
jmf 36:d1a98d5f2bbd 15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
jmf 36:d1a98d5f2bbd 16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
jmf 36:d1a98d5f2bbd 17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
jmf 36:d1a98d5f2bbd 18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
jmf 36:d1a98d5f2bbd 19 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
jmf 36:d1a98d5f2bbd 20 THE SOFTWARE.
jmf 36:d1a98d5f2bbd 21
jmf 36:d1a98d5f2bbd 22 @file WncController.cpp
jmf 36:d1a98d5f2bbd 23 @purpose Controls WNC 14A2A Cellular Modem
jmf 36:d1a98d5f2bbd 24 @version 1.0
jmf 36:d1a98d5f2bbd 25 @date July 2016
jmf 36:d1a98d5f2bbd 26 @author Fred Kellerman
jmf 36:d1a98d5f2bbd 27
jmf 36:d1a98d5f2bbd 28
jmf 36:d1a98d5f2bbd 29 An Example of usage:
jmf 36:d1a98d5f2bbd 30
jmf 36:d1a98d5f2bbd 31 WncControllerK64F mdm(&wncPinList, &mdmUart, &debugUart);
jmf 36:d1a98d5f2bbd 32
jmf 36:d1a98d5f2bbd 33 mdm.enableDebug(true, true);
jmf 36:d1a98d5f2bbd 34
jmf 36:d1a98d5f2bbd 35 if (false == mdm.powerWncOn("m2m.com.attz", 60)) {
jmf 36:d1a98d5f2bbd 36 while(1);
jmf 36:d1a98d5f2bbd 37 }
jmf 36:d1a98d5f2bbd 38
jmf 36:d1a98d5f2bbd 39 // ICCID and MSISDN
jmf 36:d1a98d5f2bbd 40 string iccid; string msisdn;
jmf 36:d1a98d5f2bbd 41 if (mdm.getICCID(&iccid) == true) {
jmf 36:d1a98d5f2bbd 42 if (mdm.convertICCIDtoMSISDN(iccid, &msisdn) == true) {
jmf 36:d1a98d5f2bbd 43 // Send an SMS message (must use 15-digit MISDN number!)
jmf 36:d1a98d5f2bbd 44 mdm.sendSMSText(msisdn.c_str(), "Hello from WNC Kit -> from WNC");
jmf 36:d1a98d5f2bbd 45 }
jmf 36:d1a98d5f2bbd 46 }
jmf 36:d1a98d5f2bbd 47
jmf 36:d1a98d5f2bbd 48 // Get an IP address setup for the socket #1 (0 indexed))
jmf 36:d1a98d5f2bbd 49 if (true == mdm.resolveUrl(0, "www.att.com"))
jmf 36:d1a98d5f2bbd 50 {
jmf 36:d1a98d5f2bbd 51 // Report server IP
jmf 36:d1a98d5f2bbd 52 if (true == mdm.getIpAddr(0, ipAddrStr)) {
jmf 36:d1a98d5f2bbd 53 debugUart.puts("Server IP: ");
jmf 36:d1a98d5f2bbd 54 debugUart.puts(ipAddrStr);
jmf 36:d1a98d5f2bbd 55 debugUart.puts("\r\n");
jmf 36:d1a98d5f2bbd 56 }
jmf 36:d1a98d5f2bbd 57
jmf 36:d1a98d5f2bbd 58 // Open Socket #1, TCP=true resolved IP on port 80:
jmf 36:d1a98d5f2bbd 59 if (true == mdm.openSocket(0, 80, true)) {
jmf 36:d1a98d5f2bbd 60 // Write some data
jmf 36:d1a98d5f2bbd 61 const uint8_t * dataStr = "GET /index.html HTTP/1.0\r\nFrom: someuser@someuser.com\r\nUser-Agent: HTTPTool/1.0\r\n\r\n";
jmf 36:d1a98d5f2bbd 62 if (true == mdm.write(0, dataStr, strlen((const char *)dataStr)))
jmf 36:d1a98d5f2bbd 63 {
jmf 36:d1a98d5f2bbd 64 const uint8_t * myBuf;
jmf 36:d1a98d5f2bbd 65 mdm.setReadRetries(0, 20);
jmf 36:d1a98d5f2bbd 66 uint32_t n = mdm.read(0, &myBuf);
jmf 36:d1a98d5f2bbd 67 if (n > 0)
jmf 36:d1a98d5f2bbd 68 debugUart.printf("Read %d chars: %s\r\n", n, myBuf);
jmf 36:d1a98d5f2bbd 69 else
jmf 36:d1a98d5f2bbd 70 debugUart.puts("No read data!\r\n");
jmf 36:d1a98d5f2bbd 71 }
jmf 36:d1a98d5f2bbd 72 }
jmf 36:d1a98d5f2bbd 73 }
jmf 36:d1a98d5f2bbd 74
jmf 36:d1a98d5f2bbd 75 */
jmf 36:d1a98d5f2bbd 76
jmf 36:d1a98d5f2bbd 77
jmf 36:d1a98d5f2bbd 78 #include <cstdlib>
jmf 36:d1a98d5f2bbd 79 #include <cctype>
jmf 36:d1a98d5f2bbd 80 #include <string.h>
jmf 36:d1a98d5f2bbd 81 #include "WncController.h"
jmf 36:d1a98d5f2bbd 82
jmf 36:d1a98d5f2bbd 83 namespace WncController_fk {
jmf 36:d1a98d5f2bbd 84
jmf 36:d1a98d5f2bbd 85 /////////////////////////////////////////////////////
jmf 36:d1a98d5f2bbd 86 // Static initializers
jmf 36:d1a98d5f2bbd 87 /////////////////////////////////////////////////////
jmf 36:d1a98d5f2bbd 88 WncController::WncSocketInfo_s WncController::m_sSock[MAX_NUM_WNC_SOCKETS];
jmf 36:d1a98d5f2bbd 89 const WncController::WncSocketInfo_s WncController::defaultSockStruct = { 0, false, "192.168.0.1", 80, 0, 25, true, 30 };
jmf 36:d1a98d5f2bbd 90
jmf 36:d1a98d5f2bbd 91 WncController::WncState_e WncController::m_sState = WNC_OFF;
jmf 36:d1a98d5f2bbd 92 uint16_t WncController::m_sCmdTimeoutMs = WNC_CMD_TIMEOUT_MS;
jmf 36:d1a98d5f2bbd 93 string WncController::m_sApnStr = "NULL";
jmf 36:d1a98d5f2bbd 94 string WncController::m_sWncStr;
jmf 36:d1a98d5f2bbd 95 uint8_t WncController::m_sPowerUpTimeoutSecs = MAX_POWERUP_TIMEOUT;
jmf 36:d1a98d5f2bbd 96 bool WncController::m_sDebugEnabled = false;
jmf 36:d1a98d5f2bbd 97 bool WncController::m_sMoreDebugEnabled = false;
jmf 36:d1a98d5f2bbd 98 bool WncController::m_sCheckNetStatus = false; // Turn on internet status check between every command
jmf 36:d1a98d5f2bbd 99 const char * const WncController::INVALID_IP_STR = "";
jmf 36:d1a98d5f2bbd 100 bool WncController::m_sReadyForSMS = false;
jmf 36:d1a98d5f2bbd 101
jmf 36:d1a98d5f2bbd 102
jmf 36:d1a98d5f2bbd 103 /**
jmf 36:d1a98d5f2bbd 104 * C++ version 0.4 char* style "itoa":
jmf 36:d1a98d5f2bbd 105 * Written by Lukás Chmela
jmf 36:d1a98d5f2bbd 106 * Released under GPLv3.
jmf 36:d1a98d5f2bbd 107 */
jmf 36:d1a98d5f2bbd 108 static char* itoa(int64_t value, char* result, int base)
jmf 36:d1a98d5f2bbd 109 {
jmf 36:d1a98d5f2bbd 110 // check that the base is valid
jmf 36:d1a98d5f2bbd 111 if ( base < 2 || base > 36 ) {
jmf 36:d1a98d5f2bbd 112 *result = '\0';
jmf 36:d1a98d5f2bbd 113 return result;
jmf 36:d1a98d5f2bbd 114 }
jmf 36:d1a98d5f2bbd 115
jmf 36:d1a98d5f2bbd 116 char* ptr = result, *ptr1 = result, tmp_char;
jmf 36:d1a98d5f2bbd 117 int64_t tmp_value;
jmf 36:d1a98d5f2bbd 118
jmf 36:d1a98d5f2bbd 119 do {
jmf 36:d1a98d5f2bbd 120 tmp_value = value;
jmf 36:d1a98d5f2bbd 121 value /= base;
jmf 36:d1a98d5f2bbd 122 *ptr++ = "zyxwvutsrqponmlkjihgfedcba9876543210123456789abcdefghijklmnopqrstuvwxyz"[35 + (tmp_value - value * base)];
jmf 36:d1a98d5f2bbd 123 } while ( value );
jmf 36:d1a98d5f2bbd 124
jmf 36:d1a98d5f2bbd 125 // Apply negative sign
jmf 36:d1a98d5f2bbd 126 if ( tmp_value < 0 )
jmf 36:d1a98d5f2bbd 127 *ptr++ = '-';
jmf 36:d1a98d5f2bbd 128
jmf 36:d1a98d5f2bbd 129 *ptr-- = '\0';
jmf 36:d1a98d5f2bbd 130
jmf 36:d1a98d5f2bbd 131 while ( ptr1 < ptr ) {
jmf 36:d1a98d5f2bbd 132 tmp_char = *ptr;
jmf 36:d1a98d5f2bbd 133 *ptr-- = *ptr1;
jmf 36:d1a98d5f2bbd 134 *ptr1++ = tmp_char;
jmf 36:d1a98d5f2bbd 135 }
jmf 36:d1a98d5f2bbd 136
jmf 36:d1a98d5f2bbd 137 return result;
jmf 36:d1a98d5f2bbd 138 }
jmf 36:d1a98d5f2bbd 139
jmf 36:d1a98d5f2bbd 140 const char * WncController::_to_string(int64_t value)
jmf 36:d1a98d5f2bbd 141 {
jmf 36:d1a98d5f2bbd 142 static char str[21]; // room for signed 64-bit + null
jmf 36:d1a98d5f2bbd 143 itoa(value, str, 10);
jmf 36:d1a98d5f2bbd 144 return (str);
jmf 36:d1a98d5f2bbd 145 }
jmf 36:d1a98d5f2bbd 146
jmf 36:d1a98d5f2bbd 147 const char * WncController::_to_hex_string(uint8_t value)
jmf 36:d1a98d5f2bbd 148 {
jmf 36:d1a98d5f2bbd 149 static char str[3]; // room for 8-bit + null
jmf 36:d1a98d5f2bbd 150 itoa(value, str, 16);
jmf 36:d1a98d5f2bbd 151 return (str);
jmf 36:d1a98d5f2bbd 152 }
jmf 36:d1a98d5f2bbd 153
jmf 36:d1a98d5f2bbd 154 WncController::WncController(void)
jmf 36:d1a98d5f2bbd 155 {
jmf 36:d1a98d5f2bbd 156 for(unsigned i; i<MAX_NUM_WNC_SOCKETS; i++)
jmf 36:d1a98d5f2bbd 157 m_sSock[i] = defaultSockStruct;
jmf 36:d1a98d5f2bbd 158 }
jmf 36:d1a98d5f2bbd 159
jmf 36:d1a98d5f2bbd 160 void WncController::enableDebug(bool on, bool moreDebugOn)
jmf 36:d1a98d5f2bbd 161 {
jmf 36:d1a98d5f2bbd 162 m_sDebugEnabled = on;
jmf 36:d1a98d5f2bbd 163 m_sMoreDebugEnabled = moreDebugOn;
jmf 36:d1a98d5f2bbd 164 }
jmf 36:d1a98d5f2bbd 165
jmf 36:d1a98d5f2bbd 166 WncController::WncState_e WncController::getWncStatus(void)
jmf 36:d1a98d5f2bbd 167 {
jmf 36:d1a98d5f2bbd 168 return (m_sState);
jmf 36:d1a98d5f2bbd 169 }
jmf 36:d1a98d5f2bbd 170
jmf 36:d1a98d5f2bbd 171 int16_t WncController::getDbmRssi(void)
jmf 36:d1a98d5f2bbd 172 {
jmf 36:d1a98d5f2bbd 173 int16_t rssi, ber;
jmf 36:d1a98d5f2bbd 174 if (at_getrssiber_wnc(&rssi, &ber) == true)
jmf 36:d1a98d5f2bbd 175 return (rssi);
jmf 36:d1a98d5f2bbd 176 else
jmf 36:d1a98d5f2bbd 177 return (99);
jmf 36:d1a98d5f2bbd 178 }
jmf 36:d1a98d5f2bbd 179
jmf 36:d1a98d5f2bbd 180 int16_t WncController::get3gBer(void)
jmf 36:d1a98d5f2bbd 181 {
jmf 36:d1a98d5f2bbd 182 int16_t rssi, ber;
jmf 36:d1a98d5f2bbd 183 if (at_getrssiber_wnc(&rssi, &ber) == true)
jmf 36:d1a98d5f2bbd 184 return (ber);
jmf 36:d1a98d5f2bbd 185 else
jmf 36:d1a98d5f2bbd 186 return (99);
jmf 36:d1a98d5f2bbd 187 }
jmf 36:d1a98d5f2bbd 188
jmf 36:d1a98d5f2bbd 189 bool WncController::powerWncOn(const char * const apn, uint8_t powerUpTimeoutSecs)
jmf 36:d1a98d5f2bbd 190 {
jmf 36:d1a98d5f2bbd 191 dbgPuts("Waiting for WNC to Initialize...");
jmf 36:d1a98d5f2bbd 192 m_sPowerUpTimeoutSecs = powerUpTimeoutSecs;
jmf 36:d1a98d5f2bbd 193 m_sState = WNC_ON_NO_CELL_LINK; // Turn soft on to allow "AT" for init to be sent!
jmf 36:d1a98d5f2bbd 194 if (initWncModem(powerUpTimeoutSecs) == true) {
jmf 36:d1a98d5f2bbd 195 // Set the Apn
jmf 36:d1a98d5f2bbd 196 setApnName(apn);
jmf 36:d1a98d5f2bbd 197 if (false == softwareInitMdm()) {
jmf 36:d1a98d5f2bbd 198 dbgPuts("Software init failed!");
jmf 36:d1a98d5f2bbd 199 m_sState = WNC_OFF;
jmf 36:d1a98d5f2bbd 200 }
jmf 36:d1a98d5f2bbd 201 }
jmf 36:d1a98d5f2bbd 202 else {
jmf 36:d1a98d5f2bbd 203 dbgPuts("Power up failed!");
jmf 36:d1a98d5f2bbd 204 m_sState = WNC_OFF;
jmf 36:d1a98d5f2bbd 205 }
jmf 36:d1a98d5f2bbd 206
jmf 36:d1a98d5f2bbd 207 return ((m_sState == WNC_ON) || (m_sState == WNC_ON_NO_CELL_LINK));
jmf 36:d1a98d5f2bbd 208 }
jmf 36:d1a98d5f2bbd 209
jmf 36:d1a98d5f2bbd 210 size_t WncController::sendCustomCmd(const char * cmd, char * resp, size_t sizeRespBuf, int ms_timeout)
jmf 36:d1a98d5f2bbd 211 {
jmf 36:d1a98d5f2bbd 212 string * respStr;
jmf 36:d1a98d5f2bbd 213
jmf 36:d1a98d5f2bbd 214 if (sizeRespBuf > 0) {
jmf 36:d1a98d5f2bbd 215 AtCmdErr_e r = at_send_wnc_cmd(cmd, &respStr, ms_timeout);
jmf 36:d1a98d5f2bbd 216 strncpy(resp, respStr->c_str(), sizeRespBuf);
jmf 36:d1a98d5f2bbd 217 if (respStr->size() > sizeRespBuf)
jmf 36:d1a98d5f2bbd 218 dbgPuts("sendCustomCmd truncated!");
jmf 36:d1a98d5f2bbd 219
jmf 36:d1a98d5f2bbd 220 return (respStr->size());
jmf 36:d1a98d5f2bbd 221 }
jmf 36:d1a98d5f2bbd 222
jmf 36:d1a98d5f2bbd 223 dbgPuts("sendCustomCmd: would have overrun!");
jmf 36:d1a98d5f2bbd 224
jmf 36:d1a98d5f2bbd 225 return (0);
jmf 36:d1a98d5f2bbd 226 }
jmf 36:d1a98d5f2bbd 227
jmf 36:d1a98d5f2bbd 228 bool WncController::pingUrl(const char * url)
jmf 36:d1a98d5f2bbd 229 {
jmf 36:d1a98d5f2bbd 230 string ipAddr;
jmf 36:d1a98d5f2bbd 231
jmf 36:d1a98d5f2bbd 232 if (true == at_dnsresolve_wnc(url, &ipAddr))
jmf 36:d1a98d5f2bbd 233 return (pingIp(ipAddr.c_str()));
jmf 36:d1a98d5f2bbd 234 else
jmf 36:d1a98d5f2bbd 235 dbgPuts("pingUrl DNS resolve: failed!");
jmf 36:d1a98d5f2bbd 236
jmf 36:d1a98d5f2bbd 237 return (false);
jmf 36:d1a98d5f2bbd 238 }
jmf 36:d1a98d5f2bbd 239
jmf 36:d1a98d5f2bbd 240 bool WncController::pingIp(const char * ip)
jmf 36:d1a98d5f2bbd 241 {
jmf 36:d1a98d5f2bbd 242 if (true == at_ping_wnc(ip))
jmf 36:d1a98d5f2bbd 243 return (true);
jmf 36:d1a98d5f2bbd 244 else
jmf 36:d1a98d5f2bbd 245 dbgPuts("pingIp: failed!");
jmf 36:d1a98d5f2bbd 246
jmf 36:d1a98d5f2bbd 247 return (false);
jmf 36:d1a98d5f2bbd 248 }
jmf 36:d1a98d5f2bbd 249
jmf 36:d1a98d5f2bbd 250 bool WncController::getWncNetworkingStats(WncIpStats * s)
jmf 36:d1a98d5f2bbd 251 {
jmf 36:d1a98d5f2bbd 252 return (at_get_wnc_net_stats(s));
jmf 36:d1a98d5f2bbd 253 }
jmf 36:d1a98d5f2bbd 254
jmf 36:d1a98d5f2bbd 255 bool WncController::getIpAddr(uint16_t numSock, char myIpAddr[MAX_LEN_IP_STR])
jmf 36:d1a98d5f2bbd 256 {
jmf 36:d1a98d5f2bbd 257 if (numSock < MAX_NUM_WNC_SOCKETS) {
jmf 36:d1a98d5f2bbd 258 strncpy(myIpAddr, m_sSock[numSock].myIpAddressStr.c_str(), MAX_LEN_IP_STR);
jmf 36:d1a98d5f2bbd 259 myIpAddr[MAX_LEN_IP_STR - 1] = '\0';
jmf 36:d1a98d5f2bbd 260 return (true);
jmf 36:d1a98d5f2bbd 261 }
jmf 36:d1a98d5f2bbd 262 else {
jmf 36:d1a98d5f2bbd 263 myIpAddr[0] = '\0';
jmf 36:d1a98d5f2bbd 264 return (false);
jmf 36:d1a98d5f2bbd 265 }
jmf 36:d1a98d5f2bbd 266 }
jmf 36:d1a98d5f2bbd 267
jmf 36:d1a98d5f2bbd 268 bool WncController::setApnName(const char * const apnStr)
jmf 36:d1a98d5f2bbd 269 {
jmf 36:d1a98d5f2bbd 270 if (at_setapn_wnc(apnStr) == true)
jmf 36:d1a98d5f2bbd 271 {
jmf 36:d1a98d5f2bbd 272 m_sApnStr = apnStr;
jmf 36:d1a98d5f2bbd 273 return (true);
jmf 36:d1a98d5f2bbd 274 }
jmf 36:d1a98d5f2bbd 275 else
jmf 36:d1a98d5f2bbd 276 return (false);
jmf 36:d1a98d5f2bbd 277 }
jmf 36:d1a98d5f2bbd 278
jmf 36:d1a98d5f2bbd 279 bool WncController::resolveUrl(uint16_t numSock, const char * url)
jmf 36:d1a98d5f2bbd 280 {
jmf 36:d1a98d5f2bbd 281 bool cmdRes;
jmf 36:d1a98d5f2bbd 282
jmf 36:d1a98d5f2bbd 283 if (numSock < MAX_NUM_WNC_SOCKETS) {
jmf 36:d1a98d5f2bbd 284 if (strlen(url) > 0) {
jmf 36:d1a98d5f2bbd 285 cmdRes = at_dnsresolve_wnc(url, &m_sSock[numSock].myIpAddressStr);
jmf 36:d1a98d5f2bbd 286 if (cmdRes == false)
jmf 36:d1a98d5f2bbd 287 dbgPuts("Cannot resolve URL!");
jmf 36:d1a98d5f2bbd 288 return (cmdRes);
jmf 36:d1a98d5f2bbd 289 }
jmf 36:d1a98d5f2bbd 290 else
jmf 36:d1a98d5f2bbd 291 dbgPuts("Invalid URL");
jmf 36:d1a98d5f2bbd 292 }
jmf 36:d1a98d5f2bbd 293 else
jmf 36:d1a98d5f2bbd 294 dbgPuts("Invalid Sock num!");
jmf 36:d1a98d5f2bbd 295
jmf 36:d1a98d5f2bbd 296 return (false);
jmf 36:d1a98d5f2bbd 297 }
jmf 36:d1a98d5f2bbd 298
jmf 36:d1a98d5f2bbd 299 bool WncController::setIpAddr(uint16_t numSock, const char * ipStr)
jmf 36:d1a98d5f2bbd 300 {
jmf 36:d1a98d5f2bbd 301 if (numSock < MAX_NUM_WNC_SOCKETS) {
jmf 36:d1a98d5f2bbd 302 m_sSock[numSock].myIpAddressStr = ipStr;
jmf 36:d1a98d5f2bbd 303 return (true);
jmf 36:d1a98d5f2bbd 304 }
jmf 36:d1a98d5f2bbd 305 else {
jmf 36:d1a98d5f2bbd 306 dbgPuts("Bad socket num!");
jmf 36:d1a98d5f2bbd 307 return (false);
jmf 36:d1a98d5f2bbd 308 }
jmf 36:d1a98d5f2bbd 309 }
jmf 36:d1a98d5f2bbd 310
jmf 36:d1a98d5f2bbd 311 void WncController::setWncCmdTimeout(uint16_t toMs)
jmf 36:d1a98d5f2bbd 312 {
jmf 36:d1a98d5f2bbd 313 m_sCmdTimeoutMs = toMs;
jmf 36:d1a98d5f2bbd 314 }
jmf 36:d1a98d5f2bbd 315
jmf 36:d1a98d5f2bbd 316 bool WncController::openSocketUrl(uint16_t numSock, const char * url, uint16_t port, bool tcp, uint16_t timeOutSec)
jmf 36:d1a98d5f2bbd 317 {
jmf 36:d1a98d5f2bbd 318 if (resolveUrl(numSock, url) == true)
jmf 36:d1a98d5f2bbd 319 return (openSocket(numSock, port, tcp, timeOutSec));
jmf 36:d1a98d5f2bbd 320
jmf 36:d1a98d5f2bbd 321 return (false);
jmf 36:d1a98d5f2bbd 322 }
jmf 36:d1a98d5f2bbd 323
jmf 36:d1a98d5f2bbd 324 bool WncController::openSocketIpAddr(uint16_t numSock, const char * ipAddr, uint16_t port, bool tcp, uint16_t timeOutSec)
jmf 36:d1a98d5f2bbd 325 {
jmf 36:d1a98d5f2bbd 326 if (setIpAddr(numSock, ipAddr) == true)
jmf 36:d1a98d5f2bbd 327 return (openSocket(numSock, port, tcp, timeOutSec));
jmf 36:d1a98d5f2bbd 328
jmf 36:d1a98d5f2bbd 329 return (false);
jmf 36:d1a98d5f2bbd 330 }
jmf 36:d1a98d5f2bbd 331
jmf 36:d1a98d5f2bbd 332 bool WncController::openSocket(uint16_t numSock, uint16_t port, bool tcp, uint16_t timeOutSec)
jmf 36:d1a98d5f2bbd 333 {
jmf 36:d1a98d5f2bbd 334 if (numSock < MAX_NUM_WNC_SOCKETS) {
jmf 36:d1a98d5f2bbd 335 // IPV4 ip addr sanity check!
jmf 36:d1a98d5f2bbd 336 size_t lenIpStr = m_sSock[numSock].myIpAddressStr.size();
jmf 36:d1a98d5f2bbd 337 if (lenIpStr < 7 || lenIpStr > 15) {
jmf 36:d1a98d5f2bbd 338 dbgPuts("Invalid IP Address!");
jmf 36:d1a98d5f2bbd 339 return (false);
jmf 36:d1a98d5f2bbd 340 }
jmf 36:d1a98d5f2bbd 341
jmf 36:d1a98d5f2bbd 342 // Already open ? Must close if want to re-open with new settings.
jmf 36:d1a98d5f2bbd 343 if (m_sSock[numSock].open == true) {
jmf 36:d1a98d5f2bbd 344 dbgPuts("Socket already open, close then re-open!");
jmf 36:d1a98d5f2bbd 345 if (true == at_sockclose_wnc(m_sSock[numSock].numWncSock))
jmf 36:d1a98d5f2bbd 346 m_sSock[numSock].open = false;
jmf 36:d1a98d5f2bbd 347 else
jmf 36:d1a98d5f2bbd 348 return (false);
jmf 36:d1a98d5f2bbd 349 }
jmf 36:d1a98d5f2bbd 350
jmf 36:d1a98d5f2bbd 351 m_sSock[numSock].myPort = port;
jmf 36:d1a98d5f2bbd 352 m_sSock[numSock].isTcp = tcp;
jmf 36:d1a98d5f2bbd 353 m_sSock[numSock].timeOutSec = timeOutSec;
jmf 36:d1a98d5f2bbd 354
jmf 36:d1a98d5f2bbd 355 int16_t numWncSock = at_sockopen_wnc(m_sSock[numSock].myIpAddressStr.c_str(), port, numSock, tcp, timeOutSec);
jmf 36:d1a98d5f2bbd 356 m_sSock[numSock].numWncSock = numWncSock;
jmf 36:d1a98d5f2bbd 357 if (numWncSock > 0 && numWncSock <= MAX_NUM_WNC_SOCKETS)
jmf 36:d1a98d5f2bbd 358 m_sSock[numSock].open = true;
jmf 36:d1a98d5f2bbd 359 else {
jmf 36:d1a98d5f2bbd 360 m_sSock[numSock].open = false;
jmf 36:d1a98d5f2bbd 361 dbgPuts("Socket open fail!!!!");
jmf 36:d1a98d5f2bbd 362
jmf 36:d1a98d5f2bbd 363 // If the modem is not responding don't bother it.
jmf 36:d1a98d5f2bbd 364 if (WNC_NO_RESPONSE != getWncStatus()) {
jmf 36:d1a98d5f2bbd 365 // Work-around. If the sock open fails it needs to be told
jmf 36:d1a98d5f2bbd 366 // to close. If 6 sock opens happen with a fail, it further
jmf 36:d1a98d5f2bbd 367 // crashes the WNC. Not sure why the sock won't open.
jmf 36:d1a98d5f2bbd 368 at_sockclose_wnc(m_sSock[numSock].numWncSock);
jmf 36:d1a98d5f2bbd 369 }
jmf 36:d1a98d5f2bbd 370 }
jmf 36:d1a98d5f2bbd 371 }
jmf 36:d1a98d5f2bbd 372 else {
jmf 36:d1a98d5f2bbd 373 dbgPuts("Bad socket num or IP!");
jmf 36:d1a98d5f2bbd 374 return (false);
jmf 36:d1a98d5f2bbd 375 }
jmf 36:d1a98d5f2bbd 376
jmf 36:d1a98d5f2bbd 377 return (m_sSock[numSock].open);
jmf 36:d1a98d5f2bbd 378 }
jmf 36:d1a98d5f2bbd 379
jmf 36:d1a98d5f2bbd 380 bool WncController::sockWrite(const uint8_t * const s, uint16_t n, uint16_t numSock, bool isTcp)
jmf 36:d1a98d5f2bbd 381 {
jmf 36:d1a98d5f2bbd 382 bool result = true;
jmf 36:d1a98d5f2bbd 383
jmf 36:d1a98d5f2bbd 384 AtCmdErr_e cmdRes = at_sockwrite_wnc(s, n, m_sSock[numSock].numWncSock, isTcp);
jmf 36:d1a98d5f2bbd 385 if (cmdRes != WNC_AT_CMD_OK) {
jmf 36:d1a98d5f2bbd 386 if ((cmdRes == WNC_AT_CMD_ERREXT) || (cmdRes == WNC_AT_CMD_ERRCME))
jmf 36:d1a98d5f2bbd 387 {
jmf 36:d1a98d5f2bbd 388 // This may throw away any data that hasn't been written out of the WNC
jmf 36:d1a98d5f2bbd 389 // but at this point with the way the WNC currently works we have
jmf 36:d1a98d5f2bbd 390 // no choice.
jmf 36:d1a98d5f2bbd 391 closeOpenSocket(numSock);
jmf 36:d1a98d5f2bbd 392 }
jmf 36:d1a98d5f2bbd 393 result = false;
jmf 36:d1a98d5f2bbd 394 }
jmf 36:d1a98d5f2bbd 395
jmf 36:d1a98d5f2bbd 396 return (result);
jmf 36:d1a98d5f2bbd 397 }
jmf 36:d1a98d5f2bbd 398
jmf 36:d1a98d5f2bbd 399 bool WncController::write(uint16_t numSock, const uint8_t * s, uint32_t n)
jmf 36:d1a98d5f2bbd 400 {
jmf 36:d1a98d5f2bbd 401 bool result;
jmf 36:d1a98d5f2bbd 402
jmf 36:d1a98d5f2bbd 403 if (numSock < MAX_NUM_WNC_SOCKETS) {
jmf 36:d1a98d5f2bbd 404 if (m_sSock[numSock].open == true) {
jmf 36:d1a98d5f2bbd 405 if (n <= MAX_WNC_WRITE_BYTES) {
jmf 36:d1a98d5f2bbd 406 result = sockWrite(s, n, numSock, m_sSock[numSock].isTcp);
jmf 36:d1a98d5f2bbd 407 }
jmf 36:d1a98d5f2bbd 408 else {
jmf 36:d1a98d5f2bbd 409 uint16_t rem = n % MAX_WNC_WRITE_BYTES;
jmf 36:d1a98d5f2bbd 410 while (n >= MAX_WNC_WRITE_BYTES) {
jmf 36:d1a98d5f2bbd 411 n -= MAX_WNC_WRITE_BYTES;
jmf 36:d1a98d5f2bbd 412 result = sockWrite(s, MAX_WNC_WRITE_BYTES, numSock, m_sSock[numSock].isTcp);
jmf 36:d1a98d5f2bbd 413 if (result == false) {
jmf 36:d1a98d5f2bbd 414 n = 0;
jmf 36:d1a98d5f2bbd 415 rem = 0;
jmf 36:d1a98d5f2bbd 416 dbgPuts("Sock write fail!");
jmf 36:d1a98d5f2bbd 417 }
jmf 36:d1a98d5f2bbd 418 else
jmf 36:d1a98d5f2bbd 419 s += MAX_WNC_WRITE_BYTES;
jmf 36:d1a98d5f2bbd 420 }
jmf 36:d1a98d5f2bbd 421 if (rem > 0)
jmf 36:d1a98d5f2bbd 422 result = sockWrite(s, rem, numSock, m_sSock[numSock].isTcp);
jmf 36:d1a98d5f2bbd 423 }
jmf 36:d1a98d5f2bbd 424 }
jmf 36:d1a98d5f2bbd 425 else {
jmf 36:d1a98d5f2bbd 426 dbgPuts("Socket is closed for write!");
jmf 36:d1a98d5f2bbd 427 result = false;
jmf 36:d1a98d5f2bbd 428 }
jmf 36:d1a98d5f2bbd 429 }
jmf 36:d1a98d5f2bbd 430 else {
jmf 36:d1a98d5f2bbd 431 dbgPuts("Bad socket num!");
jmf 36:d1a98d5f2bbd 432 result = false;
jmf 36:d1a98d5f2bbd 433 }
jmf 36:d1a98d5f2bbd 434
jmf 36:d1a98d5f2bbd 435 return (result);
jmf 36:d1a98d5f2bbd 436 }
jmf 36:d1a98d5f2bbd 437
jmf 36:d1a98d5f2bbd 438 size_t WncController::read(uint16_t numSock, const uint8_t ** readBuf)
jmf 36:d1a98d5f2bbd 439 {
jmf 36:d1a98d5f2bbd 440 static string theBuf;
jmf 36:d1a98d5f2bbd 441 string readStr;
jmf 36:d1a98d5f2bbd 442
jmf 36:d1a98d5f2bbd 443 theBuf.erase(); // Clean-up from last time
jmf 36:d1a98d5f2bbd 444
jmf 36:d1a98d5f2bbd 445 if (numSock < MAX_NUM_WNC_SOCKETS) {
jmf 36:d1a98d5f2bbd 446 if (m_sSock[numSock].open == true) {
jmf 36:d1a98d5f2bbd 447 uint8_t i = m_sSock[numSock].readRetries;
jmf 36:d1a98d5f2bbd 448 uint16_t to = m_sSock[numSock].readRetryWaitMs;
jmf 36:d1a98d5f2bbd 449 bool foundData = false;
jmf 36:d1a98d5f2bbd 450 do {
jmf 36:d1a98d5f2bbd 451 AtCmdErr_e cmdRes;
jmf 36:d1a98d5f2bbd 452 cmdRes = at_sockread_wnc(&readStr, m_sSock[numSock].numWncSock, m_sSock[numSock].isTcp);
jmf 36:d1a98d5f2bbd 453 if (WNC_AT_CMD_OK == cmdRes) {
jmf 36:d1a98d5f2bbd 454 // This will let this loop read until the socket data is
jmf 36:d1a98d5f2bbd 455 // empty. If no data, then wait the retry amount of time.
jmf 36:d1a98d5f2bbd 456 if (readStr.size() > 0) {
jmf 36:d1a98d5f2bbd 457 theBuf += readStr;
jmf 36:d1a98d5f2bbd 458 foundData = true;
jmf 36:d1a98d5f2bbd 459 i = 1;
jmf 36:d1a98d5f2bbd 460 }
jmf 36:d1a98d5f2bbd 461 else {
jmf 36:d1a98d5f2bbd 462 // Once data is found start returning it asap
jmf 36:d1a98d5f2bbd 463 if (foundData == false)
jmf 36:d1a98d5f2bbd 464 waitMs(to);
jmf 36:d1a98d5f2bbd 465 }
jmf 36:d1a98d5f2bbd 466 }
jmf 36:d1a98d5f2bbd 467 else {
jmf 36:d1a98d5f2bbd 468 theBuf += readStr; // Append what if any we got before it errored.
jmf 36:d1a98d5f2bbd 469 dbgPuts("Sockread failed!");
jmf 36:d1a98d5f2bbd 470 if (WNC_NO_RESPONSE == getWncStatus()) {
jmf 36:d1a98d5f2bbd 471 i = 0;
jmf 36:d1a98d5f2bbd 472 }
jmf 36:d1a98d5f2bbd 473 else if ((cmdRes == WNC_AT_CMD_ERREXT) || (cmdRes == WNC_AT_CMD_ERRCME))
jmf 36:d1a98d5f2bbd 474 {
jmf 36:d1a98d5f2bbd 475 // This may throw away any data that hasn't been read out of the WNC
jmf 36:d1a98d5f2bbd 476 // but at this point with the way the WNC currently works we have
jmf 36:d1a98d5f2bbd 477 // no choice.
jmf 36:d1a98d5f2bbd 478 closeOpenSocket(numSock);
jmf 36:d1a98d5f2bbd 479 i = 0;
jmf 36:d1a98d5f2bbd 480 }
jmf 36:d1a98d5f2bbd 481 else
jmf 36:d1a98d5f2bbd 482 waitMs(to);
jmf 36:d1a98d5f2bbd 483 }
jmf 36:d1a98d5f2bbd 484 } while (i-- > 0);
jmf 36:d1a98d5f2bbd 485 }
jmf 36:d1a98d5f2bbd 486 else {
jmf 36:d1a98d5f2bbd 487 dbgPuts("Socket is closed for read");
jmf 36:d1a98d5f2bbd 488 }
jmf 36:d1a98d5f2bbd 489 }
jmf 36:d1a98d5f2bbd 490 else {
jmf 36:d1a98d5f2bbd 491 dbgPuts("Bad socket num!");
jmf 36:d1a98d5f2bbd 492 }
jmf 36:d1a98d5f2bbd 493
jmf 36:d1a98d5f2bbd 494 *readBuf = (const uint8_t *)theBuf.c_str();
jmf 36:d1a98d5f2bbd 495
jmf 36:d1a98d5f2bbd 496 return (theBuf.size());
jmf 36:d1a98d5f2bbd 497 }
jmf 36:d1a98d5f2bbd 498
jmf 36:d1a98d5f2bbd 499 size_t WncController::read(uint16_t numSock, uint8_t * readBuf, uint32_t maxReadBufLen)
jmf 36:d1a98d5f2bbd 500 {
jmf 36:d1a98d5f2bbd 501 uint32_t numCopied = 0;
jmf 36:d1a98d5f2bbd 502
jmf 36:d1a98d5f2bbd 503 if (numSock < MAX_NUM_WNC_SOCKETS) {
jmf 36:d1a98d5f2bbd 504 if (m_sSock[numSock].open == true) {
jmf 36:d1a98d5f2bbd 505 uint8_t i = m_sSock[numSock].readRetries;
jmf 36:d1a98d5f2bbd 506 uint16_t to = m_sSock[numSock].readRetryWaitMs;
jmf 36:d1a98d5f2bbd 507 bool foundData = false;
jmf 36:d1a98d5f2bbd 508 uint16_t numRead;
jmf 36:d1a98d5f2bbd 509 do {
jmf 36:d1a98d5f2bbd 510 AtCmdErr_e cmdRes;
jmf 36:d1a98d5f2bbd 511 if (maxReadBufLen < MAX_WNC_READ_BYTES)
jmf 36:d1a98d5f2bbd 512 cmdRes = at_sockread_wnc(readBuf, &numRead, maxReadBufLen, m_sSock[numSock].numWncSock, m_sSock[numSock].isTcp);
jmf 36:d1a98d5f2bbd 513 else
jmf 36:d1a98d5f2bbd 514 cmdRes = at_sockread_wnc(readBuf, &numRead, MAX_WNC_READ_BYTES, m_sSock[numSock].numWncSock, m_sSock[numSock].isTcp);
jmf 36:d1a98d5f2bbd 515
jmf 36:d1a98d5f2bbd 516 if (WNC_AT_CMD_OK == cmdRes) {
jmf 36:d1a98d5f2bbd 517 // This will let this loop read until the socket data is
jmf 36:d1a98d5f2bbd 518 // empty. If no data, then wait the retry amount of time.
jmf 36:d1a98d5f2bbd 519 if (numRead > 0) {
jmf 36:d1a98d5f2bbd 520 foundData = true;
jmf 36:d1a98d5f2bbd 521 i = 1;
jmf 36:d1a98d5f2bbd 522 if (numRead <= maxReadBufLen) {
jmf 36:d1a98d5f2bbd 523 maxReadBufLen -= numRead;
jmf 36:d1a98d5f2bbd 524 numCopied += numRead;
jmf 36:d1a98d5f2bbd 525 readBuf += numRead;
jmf 36:d1a98d5f2bbd 526 }
jmf 36:d1a98d5f2bbd 527 else {
jmf 36:d1a98d5f2bbd 528 i = 0; // No more room for data!
jmf 36:d1a98d5f2bbd 529 dbgPutsNoTime("No more room for read data!");
jmf 36:d1a98d5f2bbd 530 }
jmf 36:d1a98d5f2bbd 531 }
jmf 36:d1a98d5f2bbd 532 else {
jmf 36:d1a98d5f2bbd 533 // Once data is found start returning it asap
jmf 36:d1a98d5f2bbd 534 if (foundData == false)
jmf 36:d1a98d5f2bbd 535 waitMs(to);
jmf 36:d1a98d5f2bbd 536 }
jmf 36:d1a98d5f2bbd 537 }
jmf 36:d1a98d5f2bbd 538 else {
jmf 36:d1a98d5f2bbd 539 dbgPuts("Sockread failed!");
jmf 36:d1a98d5f2bbd 540 if (WNC_NO_RESPONSE == getWncStatus()) {
jmf 36:d1a98d5f2bbd 541 i = 0;
jmf 36:d1a98d5f2bbd 542 }
jmf 36:d1a98d5f2bbd 543 else if ((cmdRes == WNC_AT_CMD_ERREXT) || (cmdRes == WNC_AT_CMD_ERRCME))
jmf 36:d1a98d5f2bbd 544 {
jmf 36:d1a98d5f2bbd 545 // This may throw away any data that hasn't been read out of the WNC
jmf 36:d1a98d5f2bbd 546 // but at this point with the way the WNC currently works we have
jmf 36:d1a98d5f2bbd 547 // no choice.
jmf 36:d1a98d5f2bbd 548 closeOpenSocket(numSock);
jmf 36:d1a98d5f2bbd 549 i = 0;
jmf 36:d1a98d5f2bbd 550 }
jmf 36:d1a98d5f2bbd 551 else
jmf 36:d1a98d5f2bbd 552 waitMs(to);
jmf 36:d1a98d5f2bbd 553 }
jmf 36:d1a98d5f2bbd 554 } while ((i-- > 0) && (maxReadBufLen > 0));
jmf 36:d1a98d5f2bbd 555 }
jmf 36:d1a98d5f2bbd 556 else {
jmf 36:d1a98d5f2bbd 557 dbgPuts("Socket is closed for read");
jmf 36:d1a98d5f2bbd 558 }
jmf 36:d1a98d5f2bbd 559 }
jmf 36:d1a98d5f2bbd 560 else {
jmf 36:d1a98d5f2bbd 561 dbgPuts("Bad socket num!");
jmf 36:d1a98d5f2bbd 562 }
jmf 36:d1a98d5f2bbd 563
jmf 36:d1a98d5f2bbd 564 return (numCopied);
jmf 36:d1a98d5f2bbd 565 }
jmf 36:d1a98d5f2bbd 566
jmf 36:d1a98d5f2bbd 567 void WncController::setReadRetries(uint16_t numSock, uint16_t retries)
jmf 36:d1a98d5f2bbd 568 {
jmf 36:d1a98d5f2bbd 569 if (numSock < MAX_NUM_WNC_SOCKETS)
jmf 36:d1a98d5f2bbd 570 m_sSock[numSock].readRetries = retries;
jmf 36:d1a98d5f2bbd 571 else
jmf 36:d1a98d5f2bbd 572 dbgPuts("Bad socket num!");
jmf 36:d1a98d5f2bbd 573 }
jmf 36:d1a98d5f2bbd 574
jmf 36:d1a98d5f2bbd 575 void WncController::setReadRetryWait(uint16_t numSock, uint16_t readRetryWaitMs)
jmf 36:d1a98d5f2bbd 576 {
jmf 36:d1a98d5f2bbd 577 if (numSock < MAX_NUM_WNC_SOCKETS)
jmf 36:d1a98d5f2bbd 578 m_sSock[numSock].readRetryWaitMs = readRetryWaitMs;
jmf 36:d1a98d5f2bbd 579 else
jmf 36:d1a98d5f2bbd 580 dbgPuts("Bad socket num!");
jmf 36:d1a98d5f2bbd 581 }
jmf 36:d1a98d5f2bbd 582
jmf 36:d1a98d5f2bbd 583 bool WncController::closeSocket(uint16_t numSock)
jmf 36:d1a98d5f2bbd 584 {
jmf 36:d1a98d5f2bbd 585 if (numSock < MAX_NUM_WNC_SOCKETS) {
jmf 36:d1a98d5f2bbd 586
jmf 36:d1a98d5f2bbd 587 if (false == at_sockclose_wnc(m_sSock[numSock].numWncSock))
jmf 36:d1a98d5f2bbd 588 dbgPuts("Sock close may not have closed!");
jmf 36:d1a98d5f2bbd 589
jmf 36:d1a98d5f2bbd 590 // Even with an error the socket could have closed,
jmf 36:d1a98d5f2bbd 591 // can't tell for sure so just soft close it for now.
jmf 36:d1a98d5f2bbd 592 m_sSock[numSock].open = false;
jmf 36:d1a98d5f2bbd 593 }
jmf 36:d1a98d5f2bbd 594 else {
jmf 36:d1a98d5f2bbd 595 dbgPuts("Bad socket num!");
jmf 36:d1a98d5f2bbd 596 }
jmf 36:d1a98d5f2bbd 597
jmf 36:d1a98d5f2bbd 598 return (m_sSock[numSock].open == false);
jmf 36:d1a98d5f2bbd 599 }
jmf 36:d1a98d5f2bbd 600
jmf 36:d1a98d5f2bbd 601 size_t WncController::mdmGetline(string * buff, int timeout_ms)
jmf 36:d1a98d5f2bbd 602 {
jmf 36:d1a98d5f2bbd 603 char chin = '\0';
jmf 36:d1a98d5f2bbd 604 char chin_last;
jmf 36:d1a98d5f2bbd 605 size_t len = 0;
jmf 36:d1a98d5f2bbd 606
jmf 36:d1a98d5f2bbd 607 startTimerB();
jmf 36:d1a98d5f2bbd 608 while ((len <= MAX_LEN_WNC_CMD_RESPONSE) && (getTimerTicksB_mS() < timeout_ms)) {
jmf 36:d1a98d5f2bbd 609 if (charReady()) {
jmf 36:d1a98d5f2bbd 610 chin_last = chin;
jmf 36:d1a98d5f2bbd 611 chin = getc();
jmf 36:d1a98d5f2bbd 612 if (isprint(chin)) {
jmf 36:d1a98d5f2bbd 613 *buff += chin;
jmf 36:d1a98d5f2bbd 614 len++; // Bound the copy length to something reaonable just in case
jmf 36:d1a98d5f2bbd 615 continue;
jmf 36:d1a98d5f2bbd 616 }
jmf 36:d1a98d5f2bbd 617 else if ((('\r' == chin_last) && ('\n' == chin)) || (('\n' == chin_last) && ('\r' == chin))) {
jmf 36:d1a98d5f2bbd 618 break;
jmf 36:d1a98d5f2bbd 619 }
jmf 36:d1a98d5f2bbd 620 }
jmf 36:d1a98d5f2bbd 621 }
jmf 36:d1a98d5f2bbd 622 stopTimerB();
jmf 36:d1a98d5f2bbd 623
jmf 36:d1a98d5f2bbd 624 if (len > MAX_LEN_WNC_CMD_RESPONSE)
jmf 36:d1a98d5f2bbd 625 dbgPuts("Max cmd length reply exceeded!");
jmf 36:d1a98d5f2bbd 626
jmf 36:d1a98d5f2bbd 627 return (len);
jmf 36:d1a98d5f2bbd 628 }
jmf 36:d1a98d5f2bbd 629
jmf 36:d1a98d5f2bbd 630 bool WncController::softwareInitMdm(void)
jmf 36:d1a98d5f2bbd 631 {
jmf 36:d1a98d5f2bbd 632 static bool reportStatus = true;
jmf 36:d1a98d5f2bbd 633 unsigned i;
jmf 36:d1a98d5f2bbd 634
jmf 36:d1a98d5f2bbd 635 if (checkCellLink() == true) {
jmf 36:d1a98d5f2bbd 636 if (reportStatus == false) {
jmf 36:d1a98d5f2bbd 637 dbgPuts("Re-connected to cellular network!");
jmf 36:d1a98d5f2bbd 638 reportStatus = true;
jmf 36:d1a98d5f2bbd 639 }
jmf 36:d1a98d5f2bbd 640
jmf 36:d1a98d5f2bbd 641 // WNC has SIM and registered on network so
jmf 36:d1a98d5f2bbd 642 // soft initialize the WNC.
jmf 36:d1a98d5f2bbd 643 for (i = 0; i < WNC_SOFT_INIT_RETRY_COUNT; i++)
jmf 36:d1a98d5f2bbd 644 if (at_init_wnc() == true)
jmf 36:d1a98d5f2bbd 645 break;
jmf 36:d1a98d5f2bbd 646
jmf 36:d1a98d5f2bbd 647 // If it did not respond try a hardware init
jmf 36:d1a98d5f2bbd 648 if (i == WNC_SOFT_INIT_RETRY_COUNT)
jmf 36:d1a98d5f2bbd 649 {
jmf 36:d1a98d5f2bbd 650 at_reinitialize_mdm();
jmf 36:d1a98d5f2bbd 651 return (at_init_wnc(true)); // Hard reset occurred so make it go through the software init();
jmf 36:d1a98d5f2bbd 652 }
jmf 36:d1a98d5f2bbd 653 else
jmf 36:d1a98d5f2bbd 654 return (true);
jmf 36:d1a98d5f2bbd 655 }
jmf 36:d1a98d5f2bbd 656 else
jmf 36:d1a98d5f2bbd 657 {
jmf 36:d1a98d5f2bbd 658 if (reportStatus == true) {
jmf 36:d1a98d5f2bbd 659 dbgPuts("Not connected to cellular network!");
jmf 36:d1a98d5f2bbd 660 reportStatus = false;
jmf 36:d1a98d5f2bbd 661 }
jmf 36:d1a98d5f2bbd 662 return (false);
jmf 36:d1a98d5f2bbd 663 }
jmf 36:d1a98d5f2bbd 664 }
jmf 36:d1a98d5f2bbd 665
jmf 36:d1a98d5f2bbd 666 WncController::AtCmdErr_e WncController::sendWncCmd(const char * const s, string ** r, int ms_timeout)
jmf 36:d1a98d5f2bbd 667 {
jmf 36:d1a98d5f2bbd 668 if (checkCellLink() == false) {
jmf 36:d1a98d5f2bbd 669 static string noRespStr;
jmf 36:d1a98d5f2bbd 670
jmf 36:d1a98d5f2bbd 671 // Save some run-time!
jmf 36:d1a98d5f2bbd 672 if (m_sDebugEnabled)
jmf 36:d1a98d5f2bbd 673 {
jmf 36:d1a98d5f2bbd 674 dbgPuts("FAIL send cmd: ", false);
jmf 36:d1a98d5f2bbd 675 if (m_sMoreDebugEnabled && m_sDebugEnabled) {
jmf 36:d1a98d5f2bbd 676 dbgPutsNoTime(s);
jmf 36:d1a98d5f2bbd 677 }
jmf 36:d1a98d5f2bbd 678 else {
jmf 36:d1a98d5f2bbd 679 size_t n = strlen(s);
jmf 36:d1a98d5f2bbd 680 if (n <= WNC_TRUNC_DEBUG_LENGTH) {
jmf 36:d1a98d5f2bbd 681 dbgPutsNoTime(s);
jmf 36:d1a98d5f2bbd 682 }
jmf 36:d1a98d5f2bbd 683 else {
jmf 36:d1a98d5f2bbd 684 string truncStr(s,WNC_TRUNC_DEBUG_LENGTH/2);
jmf 36:d1a98d5f2bbd 685 truncStr += "..";
jmf 36:d1a98d5f2bbd 686 truncStr += &s[n-(WNC_TRUNC_DEBUG_LENGTH/2)];
jmf 36:d1a98d5f2bbd 687 dbgPutsNoTime(truncStr.c_str());
jmf 36:d1a98d5f2bbd 688 }
jmf 36:d1a98d5f2bbd 689 }
jmf 36:d1a98d5f2bbd 690 }
jmf 36:d1a98d5f2bbd 691
jmf 36:d1a98d5f2bbd 692 noRespStr.erase();
jmf 36:d1a98d5f2bbd 693 *r = &noRespStr;
jmf 36:d1a98d5f2bbd 694
jmf 36:d1a98d5f2bbd 695 return (WNC_AT_CMD_NO_CELL_LINK);
jmf 36:d1a98d5f2bbd 696 }
jmf 36:d1a98d5f2bbd 697
jmf 36:d1a98d5f2bbd 698 if (m_sCheckNetStatus)
jmf 36:d1a98d5f2bbd 699 {
jmf 36:d1a98d5f2bbd 700 if (m_sMoreDebugEnabled)
jmf 36:d1a98d5f2bbd 701 dbgPuts("[---------- Network Status -------------");
jmf 36:d1a98d5f2bbd 702 string * pRespStr;
jmf 36:d1a98d5f2bbd 703 at_send_wnc_cmd("AT@SOCKDIAL?", &pRespStr, m_sCmdTimeoutMs);
jmf 36:d1a98d5f2bbd 704 if (m_sMoreDebugEnabled)
jmf 36:d1a98d5f2bbd 705 dbgPuts("---------------------------------------]");
jmf 36:d1a98d5f2bbd 706 }
jmf 36:d1a98d5f2bbd 707
jmf 36:d1a98d5f2bbd 708 // If WNC ready, send user command
jmf 36:d1a98d5f2bbd 709 return (at_send_wnc_cmd(s, r, ms_timeout));
jmf 36:d1a98d5f2bbd 710 }
jmf 36:d1a98d5f2bbd 711
jmf 36:d1a98d5f2bbd 712 WncController::AtCmdErr_e WncController::at_send_wnc_cmd(const char * s, string ** r, int ms_timeout)
jmf 36:d1a98d5f2bbd 713 {
jmf 36:d1a98d5f2bbd 714 // Save some run-time!
jmf 36:d1a98d5f2bbd 715 if (m_sDebugEnabled)
jmf 36:d1a98d5f2bbd 716 {
jmf 36:d1a98d5f2bbd 717 if (m_sMoreDebugEnabled) {
jmf 36:d1a98d5f2bbd 718 dbgPuts("TX: ", false); dbgPutsNoTime(s);
jmf 36:d1a98d5f2bbd 719 }
jmf 36:d1a98d5f2bbd 720 else {
jmf 36:d1a98d5f2bbd 721 if (m_sDebugEnabled) { // Save some run-time!
jmf 36:d1a98d5f2bbd 722 size_t n = strlen(s);
jmf 36:d1a98d5f2bbd 723 if (n <= WNC_TRUNC_DEBUG_LENGTH) {
jmf 36:d1a98d5f2bbd 724 dbgPuts("TX: ", false); dbgPutsNoTime(s);
jmf 36:d1a98d5f2bbd 725 }
jmf 36:d1a98d5f2bbd 726 else {
jmf 36:d1a98d5f2bbd 727 string truncStr(s,WNC_TRUNC_DEBUG_LENGTH/2);
jmf 36:d1a98d5f2bbd 728 truncStr += "..";
jmf 36:d1a98d5f2bbd 729 truncStr += &s[n - (WNC_TRUNC_DEBUG_LENGTH/2)];
jmf 36:d1a98d5f2bbd 730 dbgPuts("TX: ", false); dbgPutsNoTime(truncStr.c_str());
jmf 36:d1a98d5f2bbd 731 }
jmf 36:d1a98d5f2bbd 732 }
jmf 36:d1a98d5f2bbd 733 }
jmf 36:d1a98d5f2bbd 734 }
jmf 36:d1a98d5f2bbd 735
jmf 36:d1a98d5f2bbd 736 AtCmdErr_e atResult = mdmSendAtCmdRsp(s, ms_timeout, &m_sWncStr);
jmf 36:d1a98d5f2bbd 737 *r = &m_sWncStr; // Return a pointer to the static string
jmf 36:d1a98d5f2bbd 738
jmf 36:d1a98d5f2bbd 739 if (atResult != WNC_AT_CMD_TIMEOUT) {
jmf 36:d1a98d5f2bbd 740 // If a prior command timed out but a new one works then
jmf 36:d1a98d5f2bbd 741 // change the state back to ON. We don't know here in this
jmf 36:d1a98d5f2bbd 742 // method if the Cell Link is good so assume it is. When a command
jmf 36:d1a98d5f2bbd 743 // that depends on the cell link is made it will update the state.
jmf 36:d1a98d5f2bbd 744 if (m_sState == WNC_NO_RESPONSE)
jmf 36:d1a98d5f2bbd 745 m_sState = WNC_ON;
jmf 36:d1a98d5f2bbd 746
jmf 36:d1a98d5f2bbd 747 // Save some run-time!
jmf 36:d1a98d5f2bbd 748 if (m_sDebugEnabled)
jmf 36:d1a98d5f2bbd 749 {
jmf 36:d1a98d5f2bbd 750 dbgPuts("RX: ", false);
jmf 36:d1a98d5f2bbd 751 if (m_sMoreDebugEnabled) {
jmf 36:d1a98d5f2bbd 752 dbgPutsNoTime(m_sWncStr.c_str());
jmf 36:d1a98d5f2bbd 753 }
jmf 36:d1a98d5f2bbd 754 else {
jmf 36:d1a98d5f2bbd 755 if (m_sWncStr.size() <= WNC_TRUNC_DEBUG_LENGTH) {
jmf 36:d1a98d5f2bbd 756 dbgPutsNoTime(m_sWncStr.c_str());
jmf 36:d1a98d5f2bbd 757 }
jmf 36:d1a98d5f2bbd 758 else {
jmf 36:d1a98d5f2bbd 759 string truncStr = m_sWncStr.substr(0,WNC_TRUNC_DEBUG_LENGTH/2) + "..";
jmf 36:d1a98d5f2bbd 760 truncStr += m_sWncStr.substr(m_sWncStr.size() - (WNC_TRUNC_DEBUG_LENGTH/2), WNC_TRUNC_DEBUG_LENGTH/2);
jmf 36:d1a98d5f2bbd 761 dbgPutsNoTime(truncStr.c_str());
jmf 36:d1a98d5f2bbd 762 }
jmf 36:d1a98d5f2bbd 763 }
jmf 36:d1a98d5f2bbd 764 }
jmf 36:d1a98d5f2bbd 765 }
jmf 36:d1a98d5f2bbd 766 else {
jmf 36:d1a98d5f2bbd 767 m_sState = WNC_NO_RESPONSE;
jmf 36:d1a98d5f2bbd 768 dbgPuts("AT Cmd TIMEOUT!");
jmf 36:d1a98d5f2bbd 769 dbgPuts("RX: ", false); dbgPutsNoTime(m_sWncStr.c_str());
jmf 36:d1a98d5f2bbd 770 }
jmf 36:d1a98d5f2bbd 771
jmf 36:d1a98d5f2bbd 772 return (atResult);
jmf 36:d1a98d5f2bbd 773 }
jmf 36:d1a98d5f2bbd 774
jmf 36:d1a98d5f2bbd 775 void WncController::closeOpenSocket(uint16_t numSock)
jmf 36:d1a98d5f2bbd 776 {
jmf 36:d1a98d5f2bbd 777 // Try to open and close the socket
jmf 36:d1a98d5f2bbd 778 do {
jmf 36:d1a98d5f2bbd 779 dbgPuts("Try to close and re-open socket");
jmf 36:d1a98d5f2bbd 780 if (false == at_sockclose_wnc(m_sSock[numSock].numWncSock)) {
jmf 36:d1a98d5f2bbd 781 if (WNC_NO_RESPONSE == getWncStatus()) {
jmf 36:d1a98d5f2bbd 782 dbgPuts("No response for closeOpenSocket1");
jmf 36:d1a98d5f2bbd 783 return ;
jmf 36:d1a98d5f2bbd 784 }
jmf 36:d1a98d5f2bbd 785 }
jmf 36:d1a98d5f2bbd 786
jmf 36:d1a98d5f2bbd 787 int numWncSock = at_sockopen_wnc(m_sSock[numSock].myIpAddressStr.c_str(), m_sSock[numSock].myPort, numSock, m_sSock[numSock].isTcp, m_sSock[numSock].timeOutSec);
jmf 36:d1a98d5f2bbd 788 m_sSock[numSock].numWncSock = numWncSock;
jmf 36:d1a98d5f2bbd 789 if (numWncSock > 0 && numWncSock <= MAX_NUM_WNC_SOCKETS)
jmf 36:d1a98d5f2bbd 790 m_sSock[numSock].open = true;
jmf 36:d1a98d5f2bbd 791 else {
jmf 36:d1a98d5f2bbd 792 m_sSock[numSock].open = false;
jmf 36:d1a98d5f2bbd 793 dbgPuts("Failed to re-open socket!");
jmf 36:d1a98d5f2bbd 794 }
jmf 36:d1a98d5f2bbd 795
jmf 36:d1a98d5f2bbd 796 if (WNC_NO_RESPONSE == getWncStatus()) {
jmf 36:d1a98d5f2bbd 797 dbgPuts("No response for closeOpenSocket2");
jmf 36:d1a98d5f2bbd 798 return ;
jmf 36:d1a98d5f2bbd 799 }
jmf 36:d1a98d5f2bbd 800 } while (m_sSock[numSock].open == false);
jmf 36:d1a98d5f2bbd 801 }
jmf 36:d1a98d5f2bbd 802
jmf 36:d1a98d5f2bbd 803 bool WncController::getICCID(string * iccid)
jmf 36:d1a98d5f2bbd 804 {
jmf 36:d1a98d5f2bbd 805 if (at_geticcid_wnc(iccid) == false) {
jmf 36:d1a98d5f2bbd 806 dbgPuts("getICCID error!");
jmf 36:d1a98d5f2bbd 807 return (false);
jmf 36:d1a98d5f2bbd 808 }
jmf 36:d1a98d5f2bbd 809
jmf 36:d1a98d5f2bbd 810 return (true);
jmf 36:d1a98d5f2bbd 811 }
jmf 36:d1a98d5f2bbd 812
jmf 36:d1a98d5f2bbd 813 bool WncController::at_geticcid_wnc(string * iccid)
jmf 36:d1a98d5f2bbd 814 {
jmf 36:d1a98d5f2bbd 815 string * respStr;
jmf 36:d1a98d5f2bbd 816
jmf 36:d1a98d5f2bbd 817 iccid->erase();
jmf 36:d1a98d5f2bbd 818
jmf 36:d1a98d5f2bbd 819 AtCmdErr_e r = at_send_wnc_cmd("AT%CCID", &respStr, m_sCmdTimeoutMs);
jmf 36:d1a98d5f2bbd 820
jmf 36:d1a98d5f2bbd 821 if (r != WNC_AT_CMD_OK || respStr->size() == 0)
jmf 36:d1a98d5f2bbd 822 return (false);
jmf 36:d1a98d5f2bbd 823
jmf 36:d1a98d5f2bbd 824 size_t pos = respStr->find("AT%CCID");
jmf 36:d1a98d5f2bbd 825 if (pos == string::npos)
jmf 36:d1a98d5f2bbd 826 return (false);
jmf 36:d1a98d5f2bbd 827
jmf 36:d1a98d5f2bbd 828 size_t posOK = respStr->rfind("OK");
jmf 36:d1a98d5f2bbd 829 if (posOK == string::npos)
jmf 36:d1a98d5f2bbd 830 return (false);
jmf 36:d1a98d5f2bbd 831
jmf 36:d1a98d5f2bbd 832 pos += 7; // Advanced to the number
jmf 36:d1a98d5f2bbd 833 *iccid = respStr->substr(pos, posOK - pos);
jmf 36:d1a98d5f2bbd 834
jmf 36:d1a98d5f2bbd 835 return (true);
jmf 36:d1a98d5f2bbd 836 }
jmf 36:d1a98d5f2bbd 837
jmf 36:d1a98d5f2bbd 838 bool WncController::convertICCIDtoMSISDN(const string & iccid, string * msisdn)
jmf 36:d1a98d5f2bbd 839 {
jmf 36:d1a98d5f2bbd 840 msisdn->erase();
jmf 36:d1a98d5f2bbd 841
jmf 36:d1a98d5f2bbd 842 if (iccid.size() != 20 && iccid.size() != 19) {
jmf 36:d1a98d5f2bbd 843 dbgPuts("Invalid ICCID length!");
jmf 36:d1a98d5f2bbd 844 return (false);
jmf 36:d1a98d5f2bbd 845 }
jmf 36:d1a98d5f2bbd 846
jmf 36:d1a98d5f2bbd 847 *msisdn = "882350";
jmf 36:d1a98d5f2bbd 848
jmf 36:d1a98d5f2bbd 849 if (iccid.size() == 20)
jmf 36:d1a98d5f2bbd 850 *msisdn += iccid.substr(10,iccid.size() - 11);
jmf 36:d1a98d5f2bbd 851 else
jmf 36:d1a98d5f2bbd 852 *msisdn += iccid.substr(10,iccid.size() - 10);
jmf 36:d1a98d5f2bbd 853
jmf 36:d1a98d5f2bbd 854 return (true);
jmf 36:d1a98d5f2bbd 855 }
jmf 36:d1a98d5f2bbd 856
jmf 36:d1a98d5f2bbd 857 bool WncController::sendSMSText(const char * const phoneNum, const char * const text)
jmf 36:d1a98d5f2bbd 858 {
jmf 36:d1a98d5f2bbd 859 if (at_sendSMStext_wnc(phoneNum, text) == true)
jmf 36:d1a98d5f2bbd 860 return (true);
jmf 36:d1a98d5f2bbd 861 else {
jmf 36:d1a98d5f2bbd 862 dbgPuts("sendSMSText: Failed!");
jmf 36:d1a98d5f2bbd 863 return (false);
jmf 36:d1a98d5f2bbd 864 }
jmf 36:d1a98d5f2bbd 865 }
jmf 36:d1a98d5f2bbd 866
jmf 36:d1a98d5f2bbd 867 bool WncController::readSMSLog(struct WncSmsList * log)
jmf 36:d1a98d5f2bbd 868 {
jmf 36:d1a98d5f2bbd 869 string * logStr;
jmf 36:d1a98d5f2bbd 870 uint16_t i;
jmf 36:d1a98d5f2bbd 871
jmf 36:d1a98d5f2bbd 872 if (at_readSMSlog_wnc(&logStr) == false) {
jmf 36:d1a98d5f2bbd 873 dbgPuts("readSMSLog: Failed!");
jmf 36:d1a98d5f2bbd 874 return (false);
jmf 36:d1a98d5f2bbd 875 }
jmf 36:d1a98d5f2bbd 876
jmf 36:d1a98d5f2bbd 877 // Clean slate
jmf 36:d1a98d5f2bbd 878 log->msgCount = 0;
jmf 36:d1a98d5f2bbd 879
jmf 36:d1a98d5f2bbd 880 if (logStr->size() == 0)
jmf 36:d1a98d5f2bbd 881 return (false);
jmf 36:d1a98d5f2bbd 882
jmf 36:d1a98d5f2bbd 883 // Pick out the stuff from the string and convert to struct
jmf 36:d1a98d5f2bbd 884 string s;
jmf 36:d1a98d5f2bbd 885 size_t pos2;
jmf 36:d1a98d5f2bbd 886 size_t pos = logStr->find("+CMGL:");
jmf 36:d1a98d5f2bbd 887
jmf 36:d1a98d5f2bbd 888 for(i=0; i<MAX_WNC_SMS_MSG_SLOTS; i++) {
jmf 36:d1a98d5f2bbd 889 // Start with a clean slate, let parsing fill out later.
jmf 36:d1a98d5f2bbd 890 log->e[i].unread = false;
jmf 36:d1a98d5f2bbd 891 log->e[i].incoming = false;
jmf 36:d1a98d5f2bbd 892 log->e[i].unsent = false;
jmf 36:d1a98d5f2bbd 893 log->e[i].pduMode = false;
jmf 36:d1a98d5f2bbd 894 log->e[i].msgReceipt = false;
jmf 36:d1a98d5f2bbd 895
jmf 36:d1a98d5f2bbd 896 log->e[i].idx = logStr->at(pos + 7);
jmf 36:d1a98d5f2bbd 897 if (pos == string::npos)
jmf 36:d1a98d5f2bbd 898 return (false);
jmf 36:d1a98d5f2bbd 899 pos2 = logStr->find(",\"", pos);
jmf 36:d1a98d5f2bbd 900 if (pos2 == string::npos) {
jmf 36:d1a98d5f2bbd 901 // If the WNC acts wrong and receives a PDU mode
jmf 36:d1a98d5f2bbd 902 // SMS there will not be any quotes in the response,
jmf 36:d1a98d5f2bbd 903 // just take the whole reply and make it the message body for
jmf 36:d1a98d5f2bbd 904 // now, mark it as an unread message, set the pdu flag!
jmf 36:d1a98d5f2bbd 905 log->e[log->msgCount].unread = true;
jmf 36:d1a98d5f2bbd 906 log->e[log->msgCount].pduMode = true;
jmf 36:d1a98d5f2bbd 907 log->msgCount++;
jmf 36:d1a98d5f2bbd 908
jmf 36:d1a98d5f2bbd 909 pos2 = logStr->find("+CMGL", pos + 5);
jmf 36:d1a98d5f2bbd 910 if (pos2 == string::npos) {
jmf 36:d1a98d5f2bbd 911 pos2 = logStr->find("OK", pos + 5);
jmf 36:d1a98d5f2bbd 912 if (pos2 == string::npos) {
jmf 36:d1a98d5f2bbd 913 dbgPuts("Strange SMS Log Ending!");
jmf 36:d1a98d5f2bbd 914 return (false);
jmf 36:d1a98d5f2bbd 915 }
jmf 36:d1a98d5f2bbd 916 i = MAX_WNC_SMS_MSG_SLOTS;
jmf 36:d1a98d5f2bbd 917 }
jmf 36:d1a98d5f2bbd 918 log->e[log->msgCount].msg = logStr->substr(0, pos2 - pos);
jmf 36:d1a98d5f2bbd 919 pos = pos2; // for loop starts off expecting pos to point to next log msg
jmf 36:d1a98d5f2bbd 920 continue;
jmf 36:d1a98d5f2bbd 921 }
jmf 36:d1a98d5f2bbd 922 pos += 2; // Advance to the text we want
jmf 36:d1a98d5f2bbd 923 pos2 = logStr->find("\",", pos);
jmf 36:d1a98d5f2bbd 924 if ((pos2 == string::npos) || (pos >= pos2))
jmf 36:d1a98d5f2bbd 925 return (false);
jmf 36:d1a98d5f2bbd 926
jmf 36:d1a98d5f2bbd 927 // Setup attributes
jmf 36:d1a98d5f2bbd 928 s = logStr->substr(pos, pos2 - pos);
jmf 36:d1a98d5f2bbd 929 if (s.find("REC READ") != string::npos)
jmf 36:d1a98d5f2bbd 930 log->e[i].incoming = true;
jmf 36:d1a98d5f2bbd 931 if (s.find("REC UNREAD") != string::npos) {
jmf 36:d1a98d5f2bbd 932 log->e[i].unread = true;
jmf 36:d1a98d5f2bbd 933 log->e[i].incoming = true;
jmf 36:d1a98d5f2bbd 934 }
jmf 36:d1a98d5f2bbd 935 if (s.find("STO UNSENT") != string::npos)
jmf 36:d1a98d5f2bbd 936 log->e[i].unsent = true;
jmf 36:d1a98d5f2bbd 937 if (logStr->find(",,") == string::npos)
jmf 36:d1a98d5f2bbd 938 log->e[i].msgReceipt = true;
jmf 36:d1a98d5f2bbd 939
jmf 36:d1a98d5f2bbd 940 // Tele number
jmf 36:d1a98d5f2bbd 941 pos2 = logStr->find(",\"", pos2);
jmf 36:d1a98d5f2bbd 942 if (pos2 == string::npos)
jmf 36:d1a98d5f2bbd 943 return (false);
jmf 36:d1a98d5f2bbd 944 pos2 += 2; // Advance to next field
jmf 36:d1a98d5f2bbd 945 pos = logStr->find("\",", pos2);
jmf 36:d1a98d5f2bbd 946 if ((pos == string::npos) || (pos2 > pos))
jmf 36:d1a98d5f2bbd 947 return (false);
jmf 36:d1a98d5f2bbd 948 if (pos == pos2)
jmf 36:d1a98d5f2bbd 949 log->e[i].number.erase();
jmf 36:d1a98d5f2bbd 950 else
jmf 36:d1a98d5f2bbd 951 log->e[i].number = logStr->substr(pos2, pos - pos2);
jmf 36:d1a98d5f2bbd 952
jmf 36:d1a98d5f2bbd 953 // Date
jmf 36:d1a98d5f2bbd 954 pos = logStr->find(",\"", pos);
jmf 36:d1a98d5f2bbd 955 if (pos == string::npos)
jmf 36:d1a98d5f2bbd 956 return (false);
jmf 36:d1a98d5f2bbd 957 pos += 2; // Beginning of date field
jmf 36:d1a98d5f2bbd 958 pos2 = logStr->find(",", pos); // End of timestamp field
jmf 36:d1a98d5f2bbd 959 if ((pos2 == string::npos) || (pos > pos2))
jmf 36:d1a98d5f2bbd 960 return (false);
jmf 36:d1a98d5f2bbd 961 if (pos == pos2)
jmf 36:d1a98d5f2bbd 962 log->e[i].date.erase();
jmf 36:d1a98d5f2bbd 963 else
jmf 36:d1a98d5f2bbd 964 log->e[i].date = logStr->substr(pos, pos2 - pos);
jmf 36:d1a98d5f2bbd 965
jmf 36:d1a98d5f2bbd 966 // Timestamp
jmf 36:d1a98d5f2bbd 967 pos = logStr->find("\",", pos2); // End of timestamp
jmf 36:d1a98d5f2bbd 968 if (pos == string::npos)
jmf 36:d1a98d5f2bbd 969 return (false);
jmf 36:d1a98d5f2bbd 970 pos2 += 1; // Beginning of time field
jmf 36:d1a98d5f2bbd 971 if (pos < pos2)
jmf 36:d1a98d5f2bbd 972 return (false);
jmf 36:d1a98d5f2bbd 973 if (pos == pos2)
jmf 36:d1a98d5f2bbd 974 log->e[i].time.erase();
jmf 36:d1a98d5f2bbd 975 else
jmf 36:d1a98d5f2bbd 976 log->e[i].time = logStr->substr(pos2, pos - pos2);
jmf 36:d1a98d5f2bbd 977
jmf 36:d1a98d5f2bbd 978 // Message field
jmf 36:d1a98d5f2bbd 979
jmf 36:d1a98d5f2bbd 980 // We don't know how many messages we have so the next search
jmf 36:d1a98d5f2bbd 981 // could end with +CMGL or OK.
jmf 36:d1a98d5f2bbd 982 pos += 2; // Advanced to message text
jmf 36:d1a98d5f2bbd 983 pos2 = logStr->find("+CMGL", pos);
jmf 36:d1a98d5f2bbd 984 if (pos2 == string::npos) {
jmf 36:d1a98d5f2bbd 985 pos2 = logStr->find("OK", pos);
jmf 36:d1a98d5f2bbd 986 if (pos2 == string::npos) {
jmf 36:d1a98d5f2bbd 987 dbgPuts("Strange SMS Log Ending!");
jmf 36:d1a98d5f2bbd 988 return (false);
jmf 36:d1a98d5f2bbd 989 }
jmf 36:d1a98d5f2bbd 990 i = MAX_WNC_SMS_MSG_SLOTS; // break
jmf 36:d1a98d5f2bbd 991 }
jmf 36:d1a98d5f2bbd 992 if (pos > pos2)
jmf 36:d1a98d5f2bbd 993 return (false);
jmf 36:d1a98d5f2bbd 994 if (pos == pos2)
jmf 36:d1a98d5f2bbd 995 log->e[log->msgCount].msg.erase();
jmf 36:d1a98d5f2bbd 996 else
jmf 36:d1a98d5f2bbd 997 log->e[log->msgCount].msg = logStr->substr(pos, pos2 - pos);
jmf 36:d1a98d5f2bbd 998
jmf 36:d1a98d5f2bbd 999 log->msgCount++; // Message complete
jmf 36:d1a98d5f2bbd 1000 }
jmf 36:d1a98d5f2bbd 1001
jmf 36:d1a98d5f2bbd 1002 return (true);
jmf 36:d1a98d5f2bbd 1003 }
jmf 36:d1a98d5f2bbd 1004
jmf 36:d1a98d5f2bbd 1005 bool WncController::readUnreadSMSText(struct WncSmsList * w, bool deleteRead)
jmf 36:d1a98d5f2bbd 1006 {
jmf 36:d1a98d5f2bbd 1007 struct WncController::WncSmsList tmp;
jmf 36:d1a98d5f2bbd 1008
jmf 36:d1a98d5f2bbd 1009 if (readSMSLog(&tmp) == false)
jmf 36:d1a98d5f2bbd 1010 return (false);
jmf 36:d1a98d5f2bbd 1011
jmf 36:d1a98d5f2bbd 1012 w->msgCount = 0;
jmf 36:d1a98d5f2bbd 1013 for(uint16_t i = 0; i < tmp.msgCount; i++) {
jmf 36:d1a98d5f2bbd 1014 if (tmp.e[i].unread == true) {
jmf 36:d1a98d5f2bbd 1015 w->e[w->msgCount] = tmp.e[i];
jmf 36:d1a98d5f2bbd 1016 w->msgCount++;
jmf 36:d1a98d5f2bbd 1017 if (deleteRead == true) {
jmf 36:d1a98d5f2bbd 1018 // Clean up message that was copied out and read
jmf 36:d1a98d5f2bbd 1019 deleteSMSTextFromMem(w->e[i].idx);
jmf 36:d1a98d5f2bbd 1020 }
jmf 36:d1a98d5f2bbd 1021 }
jmf 36:d1a98d5f2bbd 1022 }
jmf 36:d1a98d5f2bbd 1023
jmf 36:d1a98d5f2bbd 1024 return (w->msgCount > 0);
jmf 36:d1a98d5f2bbd 1025 }
jmf 36:d1a98d5f2bbd 1026
jmf 36:d1a98d5f2bbd 1027 size_t WncController::getSignalQuality(const char ** log)
jmf 36:d1a98d5f2bbd 1028 {
jmf 36:d1a98d5f2bbd 1029 size_t n;
jmf 36:d1a98d5f2bbd 1030
jmf 36:d1a98d5f2bbd 1031 n = at_getSignalQuality_wnc(log);
jmf 36:d1a98d5f2bbd 1032 if (n == 0)
jmf 36:d1a98d5f2bbd 1033 dbgPuts("readSMSText: Failed!");
jmf 36:d1a98d5f2bbd 1034
jmf 36:d1a98d5f2bbd 1035 return (n);
jmf 36:d1a98d5f2bbd 1036 }
jmf 36:d1a98d5f2bbd 1037
jmf 36:d1a98d5f2bbd 1038 size_t WncController::at_getSignalQuality_wnc(const char ** log)
jmf 36:d1a98d5f2bbd 1039 {
jmf 36:d1a98d5f2bbd 1040 string * pRespStr;
jmf 36:d1a98d5f2bbd 1041 static string logStr;
jmf 36:d1a98d5f2bbd 1042
jmf 36:d1a98d5f2bbd 1043 logStr.erase();
jmf 36:d1a98d5f2bbd 1044
jmf 36:d1a98d5f2bbd 1045 if (at_send_wnc_cmd("AT%MEAS=\"0\"", &pRespStr, m_sCmdTimeoutMs) == WNC_AT_CMD_OK) {
jmf 36:d1a98d5f2bbd 1046 logStr = *pRespStr;
jmf 36:d1a98d5f2bbd 1047 logStr += "\r\n";
jmf 36:d1a98d5f2bbd 1048 }
jmf 36:d1a98d5f2bbd 1049 else
jmf 36:d1a98d5f2bbd 1050 dbgPuts("AT%MEAS=0: failed!");
jmf 36:d1a98d5f2bbd 1051
jmf 36:d1a98d5f2bbd 1052 if (at_send_wnc_cmd("AT%MEAS=\"1\"", &pRespStr, m_sCmdTimeoutMs) == WNC_AT_CMD_OK) {
jmf 36:d1a98d5f2bbd 1053 logStr += *pRespStr;
jmf 36:d1a98d5f2bbd 1054 logStr += "\r\n";
jmf 36:d1a98d5f2bbd 1055 }
jmf 36:d1a98d5f2bbd 1056 else
jmf 36:d1a98d5f2bbd 1057 dbgPuts("AT%MEAS=1: failed!");
jmf 36:d1a98d5f2bbd 1058
jmf 36:d1a98d5f2bbd 1059 if (at_send_wnc_cmd("AT%MEAS=\"2\"", &pRespStr, m_sCmdTimeoutMs) == WNC_AT_CMD_OK) {
jmf 36:d1a98d5f2bbd 1060 logStr += *pRespStr;
jmf 36:d1a98d5f2bbd 1061 logStr += "\r\n";
jmf 36:d1a98d5f2bbd 1062 }
jmf 36:d1a98d5f2bbd 1063 else
jmf 36:d1a98d5f2bbd 1064 dbgPuts("AT%MEAS=2: failed!");
jmf 36:d1a98d5f2bbd 1065
jmf 36:d1a98d5f2bbd 1066 if (at_send_wnc_cmd("AT%MEAS=\"3\"", &pRespStr, m_sCmdTimeoutMs) == WNC_AT_CMD_OK) {
jmf 36:d1a98d5f2bbd 1067 logStr += *pRespStr;
jmf 36:d1a98d5f2bbd 1068 logStr += "\r\n";
jmf 36:d1a98d5f2bbd 1069 }
jmf 36:d1a98d5f2bbd 1070 else
jmf 36:d1a98d5f2bbd 1071 dbgPuts("AT%MEAS=3: failed!");
jmf 36:d1a98d5f2bbd 1072
jmf 36:d1a98d5f2bbd 1073 if (at_send_wnc_cmd("AT%MEAS=\"4\"", &pRespStr, m_sCmdTimeoutMs) == WNC_AT_CMD_OK) {
jmf 36:d1a98d5f2bbd 1074 logStr += *pRespStr;
jmf 36:d1a98d5f2bbd 1075 logStr += "\r\n";
jmf 36:d1a98d5f2bbd 1076 }
jmf 36:d1a98d5f2bbd 1077 else
jmf 36:d1a98d5f2bbd 1078 dbgPuts("AT%MEAS=4: failed!");
jmf 36:d1a98d5f2bbd 1079
jmf 36:d1a98d5f2bbd 1080 if (at_send_wnc_cmd("AT%MEAS=\"5\"", &pRespStr, m_sCmdTimeoutMs) == WNC_AT_CMD_OK) {
jmf 36:d1a98d5f2bbd 1081 logStr += *pRespStr;
jmf 36:d1a98d5f2bbd 1082 logStr += "\r\n";
jmf 36:d1a98d5f2bbd 1083 }
jmf 36:d1a98d5f2bbd 1084 else
jmf 36:d1a98d5f2bbd 1085 dbgPuts("AT%MEAS=5: failed!");
jmf 36:d1a98d5f2bbd 1086
jmf 36:d1a98d5f2bbd 1087 if (at_send_wnc_cmd("AT%MEAS=\"8\"", &pRespStr, m_sCmdTimeoutMs) == WNC_AT_CMD_OK) {
jmf 36:d1a98d5f2bbd 1088 logStr += *pRespStr;
jmf 36:d1a98d5f2bbd 1089 logStr += "\r\n";
jmf 36:d1a98d5f2bbd 1090 }
jmf 36:d1a98d5f2bbd 1091 else
jmf 36:d1a98d5f2bbd 1092 dbgPuts("AT%MEAS=8: failed!");
jmf 36:d1a98d5f2bbd 1093
jmf 36:d1a98d5f2bbd 1094 if (at_send_wnc_cmd("AT%MEAS=\"98\"", &pRespStr, m_sCmdTimeoutMs) == WNC_AT_CMD_OK) {
jmf 36:d1a98d5f2bbd 1095 logStr += *pRespStr;
jmf 36:d1a98d5f2bbd 1096 logStr += "\r\n";
jmf 36:d1a98d5f2bbd 1097 }
jmf 36:d1a98d5f2bbd 1098 else
jmf 36:d1a98d5f2bbd 1099 dbgPuts("AT%MEAS=98: failed!");
jmf 36:d1a98d5f2bbd 1100
jmf 36:d1a98d5f2bbd 1101 *log = logStr.c_str();
jmf 36:d1a98d5f2bbd 1102
jmf 36:d1a98d5f2bbd 1103 return (logStr.size());
jmf 36:d1a98d5f2bbd 1104 }
jmf 36:d1a98d5f2bbd 1105
jmf 36:d1a98d5f2bbd 1106 bool WncController::getTimeDate(struct WncDateTime * tod)
jmf 36:d1a98d5f2bbd 1107 {
jmf 36:d1a98d5f2bbd 1108 if (at_gettimedate_wnc(tod) == true)
jmf 36:d1a98d5f2bbd 1109 return (true);
jmf 36:d1a98d5f2bbd 1110 else {
jmf 36:d1a98d5f2bbd 1111 dbgPuts("Get time date failed!");
jmf 36:d1a98d5f2bbd 1112 return (false);
jmf 36:d1a98d5f2bbd 1113 }
jmf 36:d1a98d5f2bbd 1114 }
jmf 36:d1a98d5f2bbd 1115
jmf 36:d1a98d5f2bbd 1116 bool WncController::at_ping_wnc(const char * ip)
jmf 36:d1a98d5f2bbd 1117 {
jmf 36:d1a98d5f2bbd 1118 string * pRespStr;
jmf 36:d1a98d5f2bbd 1119 string cmdStr = "AT@PINGREQ=\"";
jmf 36:d1a98d5f2bbd 1120 cmdStr += ip;
jmf 36:d1a98d5f2bbd 1121 cmdStr += "\"";
jmf 36:d1a98d5f2bbd 1122 return (at_send_wnc_cmd(cmdStr.c_str(), &pRespStr, WNC_PING_CMD_TIMEOUT_MS) == WNC_AT_CMD_OK);
jmf 36:d1a98d5f2bbd 1123 }
jmf 36:d1a98d5f2bbd 1124
jmf 36:d1a98d5f2bbd 1125 bool WncController::at_gettimedate_wnc(struct WncDateTime * tod)
jmf 36:d1a98d5f2bbd 1126 {
jmf 36:d1a98d5f2bbd 1127 string * pRespStr;
jmf 36:d1a98d5f2bbd 1128 char * pEnd;
jmf 36:d1a98d5f2bbd 1129
jmf 36:d1a98d5f2bbd 1130 if (at_send_wnc_cmd("AT+CCLK?", &pRespStr, m_sCmdTimeoutMs) == WNC_AT_CMD_OK) {
jmf 36:d1a98d5f2bbd 1131 if (pRespStr->size() > 0) {
jmf 36:d1a98d5f2bbd 1132 size_t pos1 = pRespStr->find("+CCLK:");
jmf 36:d1a98d5f2bbd 1133 if (pos1 != string::npos) {
jmf 36:d1a98d5f2bbd 1134 pEnd = (char *)pRespStr->c_str() + pos1 + 8;
jmf 36:d1a98d5f2bbd 1135 tod->year = strtol(pEnd, &pEnd, 10);
jmf 36:d1a98d5f2bbd 1136 tod->month = strtol(pEnd+1, &pEnd, 10);
jmf 36:d1a98d5f2bbd 1137 tod->day = strtol(pEnd+1, &pEnd, 10);
jmf 36:d1a98d5f2bbd 1138 tod->hour = strtol(pEnd+1, &pEnd, 10);
jmf 36:d1a98d5f2bbd 1139 tod->min = strtol(pEnd+1, &pEnd, 10);
jmf 36:d1a98d5f2bbd 1140 tod->sec = strtol(pEnd+1, &pEnd, 10);
jmf 36:d1a98d5f2bbd 1141 return (true);
jmf 36:d1a98d5f2bbd 1142 }
jmf 36:d1a98d5f2bbd 1143 }
jmf 36:d1a98d5f2bbd 1144 }
jmf 36:d1a98d5f2bbd 1145
jmf 36:d1a98d5f2bbd 1146 return (false);
jmf 36:d1a98d5f2bbd 1147 }
jmf 36:d1a98d5f2bbd 1148
jmf 36:d1a98d5f2bbd 1149 bool WncController::at_get_wnc_net_stats(WncIpStats * s)
jmf 36:d1a98d5f2bbd 1150 {
jmf 36:d1a98d5f2bbd 1151 string * pRespStr;
jmf 36:d1a98d5f2bbd 1152 AtCmdErr_e cmdRes = at_send_wnc_cmd("AT+CGCONTRDP=1", &pRespStr, m_sCmdTimeoutMs);
jmf 36:d1a98d5f2bbd 1153
jmf 36:d1a98d5f2bbd 1154 if (WNC_AT_CMD_OK == cmdRes) {
jmf 36:d1a98d5f2bbd 1155 if (pRespStr->size() > 0) {
jmf 36:d1a98d5f2bbd 1156 memset((void*)s, '\0', sizeof(*s)); // Clean-up
jmf 36:d1a98d5f2bbd 1157 string ss;
jmf 36:d1a98d5f2bbd 1158 size_t pe;
jmf 36:d1a98d5f2bbd 1159 size_t ps = pRespStr->rfind("\"");
jmf 36:d1a98d5f2bbd 1160 if (ps != string::npos) {
jmf 36:d1a98d5f2bbd 1161 ps += 2; // Skip the , after the "
jmf 36:d1a98d5f2bbd 1162 pe = ps;
jmf 36:d1a98d5f2bbd 1163
jmf 36:d1a98d5f2bbd 1164 pe = pRespStr->find(".", pe);
jmf 36:d1a98d5f2bbd 1165 if (pe == string::npos)
jmf 36:d1a98d5f2bbd 1166 return (false);
jmf 36:d1a98d5f2bbd 1167 else
jmf 36:d1a98d5f2bbd 1168 pe += 1;
jmf 36:d1a98d5f2bbd 1169 pe = pRespStr->find(".", pe);
jmf 36:d1a98d5f2bbd 1170 if (pe == string::npos)
jmf 36:d1a98d5f2bbd 1171 return (false);
jmf 36:d1a98d5f2bbd 1172 else
jmf 36:d1a98d5f2bbd 1173 pe += 1;
jmf 36:d1a98d5f2bbd 1174 pe = pRespStr->find(".", pe);
jmf 36:d1a98d5f2bbd 1175 if (pe == string::npos)
jmf 36:d1a98d5f2bbd 1176 return (false);
jmf 36:d1a98d5f2bbd 1177 else
jmf 36:d1a98d5f2bbd 1178 pe += 1;
jmf 36:d1a98d5f2bbd 1179 pe = pRespStr->find(".", pe);
jmf 36:d1a98d5f2bbd 1180 if (pe == string::npos)
jmf 36:d1a98d5f2bbd 1181 return (false);
jmf 36:d1a98d5f2bbd 1182 else
jmf 36:d1a98d5f2bbd 1183 pe += 1;
jmf 36:d1a98d5f2bbd 1184
jmf 36:d1a98d5f2bbd 1185 ss = pRespStr->substr(ps, pe - 1 - ps);
jmf 36:d1a98d5f2bbd 1186 strncpy(s->ip, ss.c_str(), MAX_LEN_IP_STR);
jmf 36:d1a98d5f2bbd 1187 s->ip[MAX_LEN_IP_STR - 1] = '\0';
jmf 36:d1a98d5f2bbd 1188 ps = pe;
jmf 36:d1a98d5f2bbd 1189
jmf 36:d1a98d5f2bbd 1190 pe = pRespStr->find(".", pe);
jmf 36:d1a98d5f2bbd 1191 if (pe == string::npos)
jmf 36:d1a98d5f2bbd 1192 return (false);
jmf 36:d1a98d5f2bbd 1193 else
jmf 36:d1a98d5f2bbd 1194 pe += 1;
jmf 36:d1a98d5f2bbd 1195 pe = pRespStr->find(".", pe);
jmf 36:d1a98d5f2bbd 1196 if (pe == string::npos)
jmf 36:d1a98d5f2bbd 1197 return (false);
jmf 36:d1a98d5f2bbd 1198 else
jmf 36:d1a98d5f2bbd 1199 pe += 1;
jmf 36:d1a98d5f2bbd 1200 pe = pRespStr->find(".", pe);
jmf 36:d1a98d5f2bbd 1201 if (pe == string::npos)
jmf 36:d1a98d5f2bbd 1202 return (false);
jmf 36:d1a98d5f2bbd 1203 else
jmf 36:d1a98d5f2bbd 1204 pe += 1;
jmf 36:d1a98d5f2bbd 1205 pe = pRespStr->find(",", pe);
jmf 36:d1a98d5f2bbd 1206
jmf 36:d1a98d5f2bbd 1207 ss = pRespStr->substr(ps, pe - ps);
jmf 36:d1a98d5f2bbd 1208 strncpy(s->mask, ss.c_str(), MAX_LEN_IP_STR);
jmf 36:d1a98d5f2bbd 1209 s->mask[MAX_LEN_IP_STR - 1] = '\0';
jmf 36:d1a98d5f2bbd 1210 ps = pe + 1;
jmf 36:d1a98d5f2bbd 1211
jmf 36:d1a98d5f2bbd 1212 pe = pRespStr->find(".", pe);
jmf 36:d1a98d5f2bbd 1213 if (pe == string::npos)
jmf 36:d1a98d5f2bbd 1214 return (false);
jmf 36:d1a98d5f2bbd 1215 else
jmf 36:d1a98d5f2bbd 1216 pe += 1;
jmf 36:d1a98d5f2bbd 1217 pe = pRespStr->find(".", pe);
jmf 36:d1a98d5f2bbd 1218 if (pe == string::npos)
jmf 36:d1a98d5f2bbd 1219 return (false);
jmf 36:d1a98d5f2bbd 1220 else
jmf 36:d1a98d5f2bbd 1221 pe += 1;
jmf 36:d1a98d5f2bbd 1222 pe = pRespStr->find(".", pe);
jmf 36:d1a98d5f2bbd 1223 if (pe == string::npos)
jmf 36:d1a98d5f2bbd 1224 return (false);
jmf 36:d1a98d5f2bbd 1225 else
jmf 36:d1a98d5f2bbd 1226 pe += 1;
jmf 36:d1a98d5f2bbd 1227 pe = pRespStr->find(",", pe);
jmf 36:d1a98d5f2bbd 1228
jmf 36:d1a98d5f2bbd 1229 ss = pRespStr->substr(ps, pe - ps);
jmf 36:d1a98d5f2bbd 1230 strncpy(s->gateway, ss.c_str(), MAX_LEN_IP_STR);
jmf 36:d1a98d5f2bbd 1231 s->gateway[MAX_LEN_IP_STR - 1] = '\0';
jmf 36:d1a98d5f2bbd 1232 ps = pe + 1;
jmf 36:d1a98d5f2bbd 1233
jmf 36:d1a98d5f2bbd 1234 pe = pRespStr->find(".", pe);
jmf 36:d1a98d5f2bbd 1235 if (pe == string::npos)
jmf 36:d1a98d5f2bbd 1236 return (false);
jmf 36:d1a98d5f2bbd 1237 else
jmf 36:d1a98d5f2bbd 1238 pe += 1;
jmf 36:d1a98d5f2bbd 1239 pe = pRespStr->find(".", pe);
jmf 36:d1a98d5f2bbd 1240 if (pe == string::npos)
jmf 36:d1a98d5f2bbd 1241 return (false);
jmf 36:d1a98d5f2bbd 1242 else
jmf 36:d1a98d5f2bbd 1243 pe += 1;
jmf 36:d1a98d5f2bbd 1244 pe = pRespStr->find(".", pe);
jmf 36:d1a98d5f2bbd 1245 if (pe == string::npos)
jmf 36:d1a98d5f2bbd 1246 return (false);
jmf 36:d1a98d5f2bbd 1247 else
jmf 36:d1a98d5f2bbd 1248 pe += 1;
jmf 36:d1a98d5f2bbd 1249 pe = pRespStr->find(",", pe);
jmf 36:d1a98d5f2bbd 1250
jmf 36:d1a98d5f2bbd 1251
jmf 36:d1a98d5f2bbd 1252 ss = pRespStr->substr(ps, pe - ps);
jmf 36:d1a98d5f2bbd 1253 strncpy(s->dnsPrimary, ss.c_str(), MAX_LEN_IP_STR);
jmf 36:d1a98d5f2bbd 1254 s->dnsPrimary[MAX_LEN_IP_STR - 1] = '\0';
jmf 36:d1a98d5f2bbd 1255 ps = pe + 1;
jmf 36:d1a98d5f2bbd 1256
jmf 36:d1a98d5f2bbd 1257 pe = pRespStr->find(".", pe);
jmf 36:d1a98d5f2bbd 1258 if (pe == string::npos)
jmf 36:d1a98d5f2bbd 1259 return (false);
jmf 36:d1a98d5f2bbd 1260 else
jmf 36:d1a98d5f2bbd 1261 pe += 1;
jmf 36:d1a98d5f2bbd 1262 pe = pRespStr->find(".", pe);
jmf 36:d1a98d5f2bbd 1263 if (pe == string::npos)
jmf 36:d1a98d5f2bbd 1264 return (false);
jmf 36:d1a98d5f2bbd 1265 else
jmf 36:d1a98d5f2bbd 1266 pe += 1;
jmf 36:d1a98d5f2bbd 1267 pe = pRespStr->find(".", pe);
jmf 36:d1a98d5f2bbd 1268 if (pe == string::npos)
jmf 36:d1a98d5f2bbd 1269 return (false);
jmf 36:d1a98d5f2bbd 1270 else
jmf 36:d1a98d5f2bbd 1271 pe += 1;
jmf 36:d1a98d5f2bbd 1272 pe = pRespStr->find(",", pe);
jmf 36:d1a98d5f2bbd 1273
jmf 36:d1a98d5f2bbd 1274
jmf 36:d1a98d5f2bbd 1275 ss = pRespStr->substr(ps, pe - ps);
jmf 36:d1a98d5f2bbd 1276 strncpy(s->dnsSecondary, ss.c_str(), MAX_LEN_IP_STR);
jmf 36:d1a98d5f2bbd 1277 s->dnsSecondary[MAX_LEN_IP_STR - 1] = '\0';
jmf 36:d1a98d5f2bbd 1278
jmf 36:d1a98d5f2bbd 1279 dbgPuts("~~~~~~~~~~ WNC IP Stats ~~~~~~~~~~~~");
jmf 36:d1a98d5f2bbd 1280 dbgPuts("ip: ", false); dbgPutsNoTime(s->ip);
jmf 36:d1a98d5f2bbd 1281 dbgPuts("mask: ", false); dbgPutsNoTime(s->mask);
jmf 36:d1a98d5f2bbd 1282 dbgPuts("gateway: ", false); dbgPutsNoTime(s->gateway);
jmf 36:d1a98d5f2bbd 1283 dbgPuts("dns pri: ", false); dbgPutsNoTime(s->dnsPrimary);
jmf 36:d1a98d5f2bbd 1284 dbgPuts("dns sec: ", false); dbgPutsNoTime(s->dnsSecondary);
jmf 36:d1a98d5f2bbd 1285 dbgPuts("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");
jmf 36:d1a98d5f2bbd 1286
jmf 36:d1a98d5f2bbd 1287 return (true);
jmf 36:d1a98d5f2bbd 1288 }
jmf 36:d1a98d5f2bbd 1289 }
jmf 36:d1a98d5f2bbd 1290 }
jmf 36:d1a98d5f2bbd 1291
jmf 36:d1a98d5f2bbd 1292 return (false);
jmf 36:d1a98d5f2bbd 1293 }
jmf 36:d1a98d5f2bbd 1294
jmf 36:d1a98d5f2bbd 1295 bool WncController::deleteSMSTextFromMem(char msgIdx)
jmf 36:d1a98d5f2bbd 1296 {
jmf 36:d1a98d5f2bbd 1297 const char * err = "deleteSMSTextFromMem: Failed!";
jmf 36:d1a98d5f2bbd 1298
jmf 36:d1a98d5f2bbd 1299 switch (msgIdx)
jmf 36:d1a98d5f2bbd 1300 {
jmf 36:d1a98d5f2bbd 1301 case '*':
jmf 36:d1a98d5f2bbd 1302 at_deleteSMSTextFromMem_wnc('1');
jmf 36:d1a98d5f2bbd 1303 at_deleteSMSTextFromMem_wnc('2');
jmf 36:d1a98d5f2bbd 1304 at_deleteSMSTextFromMem_wnc('3');
jmf 36:d1a98d5f2bbd 1305 return (true); // WNC may error if slot empty, just ignore!
jmf 36:d1a98d5f2bbd 1306
jmf 36:d1a98d5f2bbd 1307 case '1':
jmf 36:d1a98d5f2bbd 1308 case '2':
jmf 36:d1a98d5f2bbd 1309 case '3':
jmf 36:d1a98d5f2bbd 1310 if (true == at_deleteSMSTextFromMem_wnc(msgIdx))
jmf 36:d1a98d5f2bbd 1311 return (true);
jmf 36:d1a98d5f2bbd 1312 else {
jmf 36:d1a98d5f2bbd 1313 dbgPuts(err);
jmf 36:d1a98d5f2bbd 1314 return (false);
jmf 36:d1a98d5f2bbd 1315 }
jmf 36:d1a98d5f2bbd 1316
jmf 36:d1a98d5f2bbd 1317 default:
jmf 36:d1a98d5f2bbd 1318 dbgPuts(err);
jmf 36:d1a98d5f2bbd 1319 return (false);
jmf 36:d1a98d5f2bbd 1320 }
jmf 36:d1a98d5f2bbd 1321 }
jmf 36:d1a98d5f2bbd 1322
jmf 36:d1a98d5f2bbd 1323 bool WncController::sendSMSTextFromMem(char msgIdx)
jmf 36:d1a98d5f2bbd 1324 {
jmf 36:d1a98d5f2bbd 1325 const char * err = "deleteSMSTextFromMem: Failed!";
jmf 36:d1a98d5f2bbd 1326
jmf 36:d1a98d5f2bbd 1327 switch (msgIdx)
jmf 36:d1a98d5f2bbd 1328 {
jmf 36:d1a98d5f2bbd 1329 case '*':
jmf 36:d1a98d5f2bbd 1330 at_sendSMStextMem_wnc('1');
jmf 36:d1a98d5f2bbd 1331 at_sendSMStextMem_wnc('2');
jmf 36:d1a98d5f2bbd 1332 at_sendSMStextMem_wnc('3');
jmf 36:d1a98d5f2bbd 1333 return (true); // WNC may error if slot is empty, just ignore!
jmf 36:d1a98d5f2bbd 1334
jmf 36:d1a98d5f2bbd 1335 case '1':
jmf 36:d1a98d5f2bbd 1336 case '2':
jmf 36:d1a98d5f2bbd 1337 case '3':
jmf 36:d1a98d5f2bbd 1338 if (at_sendSMStextMem_wnc(msgIdx) == true)
jmf 36:d1a98d5f2bbd 1339 return (true);
jmf 36:d1a98d5f2bbd 1340 else {
jmf 36:d1a98d5f2bbd 1341 dbgPuts(err);
jmf 36:d1a98d5f2bbd 1342 return (false);
jmf 36:d1a98d5f2bbd 1343 }
jmf 36:d1a98d5f2bbd 1344
jmf 36:d1a98d5f2bbd 1345 default:
jmf 36:d1a98d5f2bbd 1346 dbgPuts(err);
jmf 36:d1a98d5f2bbd 1347 return (false);
jmf 36:d1a98d5f2bbd 1348 }
jmf 36:d1a98d5f2bbd 1349 }
jmf 36:d1a98d5f2bbd 1350
jmf 36:d1a98d5f2bbd 1351 bool WncController::at_deleteSMSTextFromMem_wnc(char n)
jmf 36:d1a98d5f2bbd 1352 {
jmf 36:d1a98d5f2bbd 1353 string cmdStr, respStr;
jmf 36:d1a98d5f2bbd 1354 // Message is stored in WNC, now send it!
jmf 36:d1a98d5f2bbd 1355 cmdStr = "AT+CMGD=";
jmf 36:d1a98d5f2bbd 1356 cmdStr += n;
jmf 36:d1a98d5f2bbd 1357 cmdStr += "\r\n";
jmf 36:d1a98d5f2bbd 1358 dbgPuts("TX: ", false); dbgPutsNoTime(cmdStr.c_str(), false);
jmf 36:d1a98d5f2bbd 1359 AtCmdErr_e r = mdmSendAtCmdRsp(cmdStr.c_str(), m_sCmdTimeoutMs, &respStr);
jmf 36:d1a98d5f2bbd 1360 dbgPuts("RX: ", false); dbgPutsNoTime(respStr.c_str());
jmf 36:d1a98d5f2bbd 1361 return (r == WNC_AT_CMD_OK);
jmf 36:d1a98d5f2bbd 1362 }
jmf 36:d1a98d5f2bbd 1363
jmf 36:d1a98d5f2bbd 1364 bool WncController::at_sendSMStextMem_wnc(char n)
jmf 36:d1a98d5f2bbd 1365 {
jmf 36:d1a98d5f2bbd 1366 string cmdStr, respStr;
jmf 36:d1a98d5f2bbd 1367 // Message is stored in WNC, now send it!
jmf 36:d1a98d5f2bbd 1368 cmdStr = "AT+CMSS=";
jmf 36:d1a98d5f2bbd 1369 cmdStr += n;
jmf 36:d1a98d5f2bbd 1370 cmdStr += "\r\n";
jmf 36:d1a98d5f2bbd 1371 dbgPuts("TX: ", false); dbgPutsNoTime(cmdStr.c_str(), false);
jmf 36:d1a98d5f2bbd 1372 AtCmdErr_e r = mdmSendAtCmdRsp(cmdStr.c_str(), m_sCmdTimeoutMs, &respStr);
jmf 36:d1a98d5f2bbd 1373 dbgPuts("RX: ", false); dbgPutsNoTime(respStr.c_str());
jmf 36:d1a98d5f2bbd 1374 return (r == WNC_AT_CMD_OK);
jmf 36:d1a98d5f2bbd 1375 }
jmf 36:d1a98d5f2bbd 1376
jmf 36:d1a98d5f2bbd 1377 bool WncController::at_sendSMStext_wnc(const char * const phoneNum, const char * const text)
jmf 36:d1a98d5f2bbd 1378 {
jmf 36:d1a98d5f2bbd 1379 string respStr;
jmf 36:d1a98d5f2bbd 1380 string * pRespStr;
jmf 36:d1a98d5f2bbd 1381 size_t l = strlen(text);
jmf 36:d1a98d5f2bbd 1382
jmf 36:d1a98d5f2bbd 1383 if (l <= MAX_WNC_SMS_LENGTH)
jmf 36:d1a98d5f2bbd 1384 {
jmf 36:d1a98d5f2bbd 1385 // Check to see if the SMS service is available
jmf 36:d1a98d5f2bbd 1386 checkCellLink();
jmf 36:d1a98d5f2bbd 1387 if (m_sReadyForSMS == true) {
jmf 36:d1a98d5f2bbd 1388 at_send_wnc_cmd("AT+CMGF=1", &pRespStr, m_sCmdTimeoutMs);
jmf 36:d1a98d5f2bbd 1389 string cmdStr("AT+CMGS=\"");
jmf 36:d1a98d5f2bbd 1390 cmdStr += phoneNum;
jmf 36:d1a98d5f2bbd 1391 cmdStr += "\"";
jmf 36:d1a98d5f2bbd 1392 dbgPuts("TX: ", false); dbgPutsNoTime(cmdStr.c_str());
jmf 36:d1a98d5f2bbd 1393 cmdStr += "\x0d"; // x0d = <ENTER>
jmf 36:d1a98d5f2bbd 1394 // Send raw command with short timeout (the timeout will fail cause the WNC is not supposed to reply yet!
jmf 36:d1a98d5f2bbd 1395 // And we want a delay before sending the actual text part of the string!
jmf 36:d1a98d5f2bbd 1396 mdmSendAtCmdRsp(cmdStr.c_str(), 300, &respStr, false); // False turns off auto-addition of CR+LF (the WNC wants nothing here)
jmf 36:d1a98d5f2bbd 1397 dbgPuts("RX: ", false); dbgPutsNoTime(respStr.c_str());
jmf 36:d1a98d5f2bbd 1398 if ((respStr.size() > 0) && (respStr.find("ERROR") == string::npos)) {
jmf 36:d1a98d5f2bbd 1399 // Part 2 of the text, this is the actual text part:
jmf 36:d1a98d5f2bbd 1400 cmdStr = text;
jmf 36:d1a98d5f2bbd 1401 dbgPuts("TX: ", false); dbgPutsNoTime(cmdStr.c_str());
jmf 36:d1a98d5f2bbd 1402 cmdStr += "\x1A"; // <CTRL>-Z is what tells the WNC the message is complete to send!
jmf 36:d1a98d5f2bbd 1403 AtCmdErr_e r = mdmSendAtCmdRsp(cmdStr.c_str(), 10000, &respStr);
jmf 36:d1a98d5f2bbd 1404 dbgPuts("RX: ", false); dbgPutsNoTime(respStr.c_str());
jmf 36:d1a98d5f2bbd 1405 if (respStr.size() == 0)
jmf 36:d1a98d5f2bbd 1406 return (false);
jmf 36:d1a98d5f2bbd 1407 else
jmf 36:d1a98d5f2bbd 1408 return (r == WNC_AT_CMD_OK);
jmf 36:d1a98d5f2bbd 1409 }
jmf 36:d1a98d5f2bbd 1410 }
jmf 36:d1a98d5f2bbd 1411 }
jmf 36:d1a98d5f2bbd 1412
jmf 36:d1a98d5f2bbd 1413 return (false);
jmf 36:d1a98d5f2bbd 1414 }
jmf 36:d1a98d5f2bbd 1415
jmf 36:d1a98d5f2bbd 1416 bool WncController::saveSMSText(const char * const phoneNum, const char * const text, char * msgIdx)
jmf 36:d1a98d5f2bbd 1417 {
jmf 36:d1a98d5f2bbd 1418 if (at_saveSMStext_wnc(phoneNum, text, msgIdx) == true)
jmf 36:d1a98d5f2bbd 1419 return (true);
jmf 36:d1a98d5f2bbd 1420 else {
jmf 36:d1a98d5f2bbd 1421 dbgPuts("saveSMSTextToMem: failed!\r\n");
jmf 36:d1a98d5f2bbd 1422 return (false);
jmf 36:d1a98d5f2bbd 1423 }
jmf 36:d1a98d5f2bbd 1424 }
jmf 36:d1a98d5f2bbd 1425
jmf 36:d1a98d5f2bbd 1426 bool WncController::at_saveSMStext_wnc(const char * const phoneNum, const char * const text, char * msgIdx)
jmf 36:d1a98d5f2bbd 1427 {
jmf 36:d1a98d5f2bbd 1428 string respStr;
jmf 36:d1a98d5f2bbd 1429 size_t l = strlen(text);
jmf 36:d1a98d5f2bbd 1430
jmf 36:d1a98d5f2bbd 1431 if (l <= MAX_WNC_SMS_LENGTH)
jmf 36:d1a98d5f2bbd 1432 {
jmf 36:d1a98d5f2bbd 1433 // Check to see if the SMS service is available
jmf 36:d1a98d5f2bbd 1434 checkCellLink();
jmf 36:d1a98d5f2bbd 1435 if (m_sReadyForSMS == true) {
jmf 36:d1a98d5f2bbd 1436 string cmdStr("AT+CMGW=\"");
jmf 36:d1a98d5f2bbd 1437 cmdStr += phoneNum;
jmf 36:d1a98d5f2bbd 1438 cmdStr += "\"";
jmf 36:d1a98d5f2bbd 1439 dbgPuts("TX: ", false); dbgPutsNoTime(cmdStr.c_str());
jmf 36:d1a98d5f2bbd 1440 cmdStr += "\x0d"; // x0d = <ENTER>
jmf 36:d1a98d5f2bbd 1441 // Send raw command with short timeout (the timeout will fail cause the WNC is not supposed to reply yet!
jmf 36:d1a98d5f2bbd 1442 // And we want a delay before sending the actual text part of the string!
jmf 36:d1a98d5f2bbd 1443 mdmSendAtCmdRsp(cmdStr.c_str(), 300, &respStr, false); // False turns off auto-addition of CR+LF (the WNC wants nothing here)
jmf 36:d1a98d5f2bbd 1444 dbgPuts("RX: ", false); dbgPutsNoTime(respStr.c_str());
jmf 36:d1a98d5f2bbd 1445 if ((respStr.size() > 0) && (respStr.find("ERROR") == string::npos)) {
jmf 36:d1a98d5f2bbd 1446 // Part 2 of the text, this is the actual text part:
jmf 36:d1a98d5f2bbd 1447 cmdStr = text;
jmf 36:d1a98d5f2bbd 1448 dbgPuts("TX: ", false); dbgPutsNoTime(cmdStr.c_str());
jmf 36:d1a98d5f2bbd 1449 cmdStr += "\x1A"; // <CTRL>-Z is what tells the WNC the message is complete to save!
jmf 36:d1a98d5f2bbd 1450 AtCmdErr_e r = mdmSendAtCmdRsp(cmdStr.c_str(), 10000, &respStr);
jmf 36:d1a98d5f2bbd 1451 dbgPuts("RX: ", false); dbgPutsNoTime(respStr.c_str());
jmf 36:d1a98d5f2bbd 1452 if (respStr.size() > 0) {
jmf 36:d1a98d5f2bbd 1453 // respStr will have the SMS index
jmf 36:d1a98d5f2bbd 1454 size_t pos1 = respStr.find("+CMGW: ");
jmf 36:d1a98d5f2bbd 1455 size_t pos2 = respStr.rfind("OK");
jmf 36:d1a98d5f2bbd 1456 if (pos1 != string::npos && pos2 != string::npos) {
jmf 36:d1a98d5f2bbd 1457 *msgIdx = *string(respStr.substr(pos1+7, 1)).c_str();
jmf 36:d1a98d5f2bbd 1458 return (true);
jmf 36:d1a98d5f2bbd 1459 }
jmf 36:d1a98d5f2bbd 1460 else {
jmf 36:d1a98d5f2bbd 1461 *msgIdx = '!';
jmf 36:d1a98d5f2bbd 1462 }
jmf 36:d1a98d5f2bbd 1463 }
jmf 36:d1a98d5f2bbd 1464 }
jmf 36:d1a98d5f2bbd 1465 }
jmf 36:d1a98d5f2bbd 1466 }
jmf 36:d1a98d5f2bbd 1467
jmf 36:d1a98d5f2bbd 1468 return (false);
jmf 36:d1a98d5f2bbd 1469 }
jmf 36:d1a98d5f2bbd 1470
jmf 36:d1a98d5f2bbd 1471 bool WncController::at_readSMSlog_wnc(string ** log)
jmf 36:d1a98d5f2bbd 1472 {
jmf 36:d1a98d5f2bbd 1473 return (at_send_wnc_cmd("AT+CMGL", log, m_sCmdTimeoutMs) == WNC_AT_CMD_OK);
jmf 36:d1a98d5f2bbd 1474 }
jmf 36:d1a98d5f2bbd 1475
jmf 36:d1a98d5f2bbd 1476 size_t WncController::at_readSMStext_wnc(const char n, const char ** log)
jmf 36:d1a98d5f2bbd 1477 {
jmf 36:d1a98d5f2bbd 1478 static string smsReadTxtStr;
jmf 36:d1a98d5f2bbd 1479 string * pRespStr;
jmf 36:d1a98d5f2bbd 1480 string cmdStr;
jmf 36:d1a98d5f2bbd 1481
jmf 36:d1a98d5f2bbd 1482 smsReadTxtStr.erase();
jmf 36:d1a98d5f2bbd 1483 cmdStr = "AT+CMGR";
jmf 36:d1a98d5f2bbd 1484 cmdStr += '1';
jmf 36:d1a98d5f2bbd 1485 if (at_send_wnc_cmd("AT+CMGR", &pRespStr, m_sCmdTimeoutMs) == WNC_AT_CMD_OK)
jmf 36:d1a98d5f2bbd 1486 *log = pRespStr->c_str();
jmf 36:d1a98d5f2bbd 1487 else
jmf 36:d1a98d5f2bbd 1488 *log = "\0";
jmf 36:d1a98d5f2bbd 1489
jmf 36:d1a98d5f2bbd 1490 return (pRespStr->size());
jmf 36:d1a98d5f2bbd 1491 }
jmf 36:d1a98d5f2bbd 1492
jmf 36:d1a98d5f2bbd 1493 bool WncController::at_at_wnc(void)
jmf 36:d1a98d5f2bbd 1494 {
jmf 36:d1a98d5f2bbd 1495 string * pRespStr;
jmf 36:d1a98d5f2bbd 1496 return (WNC_AT_CMD_OK == at_send_wnc_cmd("AT", &pRespStr, WNC_QUICK_CMD_TIMEOUT_MS)); // Heartbeat?
jmf 36:d1a98d5f2bbd 1497 }
jmf 36:d1a98d5f2bbd 1498
jmf 36:d1a98d5f2bbd 1499 bool WncController::at_init_wnc(bool hardReset)
jmf 36:d1a98d5f2bbd 1500 {
jmf 36:d1a98d5f2bbd 1501 string * pRespStr;
jmf 36:d1a98d5f2bbd 1502 AtCmdErr_e cmdRes;
jmf 36:d1a98d5f2bbd 1503
jmf 36:d1a98d5f2bbd 1504 if (hardReset == true)
jmf 36:d1a98d5f2bbd 1505 dbgPuts("Hard Soft Reset!");
jmf 36:d1a98d5f2bbd 1506
jmf 36:d1a98d5f2bbd 1507 dbgPuts("Start AT init of WNC:");
jmf 36:d1a98d5f2bbd 1508
jmf 36:d1a98d5f2bbd 1509 // Kick it twice to perhaps remove cued responses from an incomplete
jmf 36:d1a98d5f2bbd 1510 // power cycle.
jmf 36:d1a98d5f2bbd 1511 at_send_wnc_cmd("AT", &pRespStr, WNC_QUICK_CMD_TIMEOUT_MS);
jmf 36:d1a98d5f2bbd 1512 at_send_wnc_cmd("AT", &pRespStr, WNC_QUICK_CMD_TIMEOUT_MS);
jmf 36:d1a98d5f2bbd 1513
jmf 36:d1a98d5f2bbd 1514 // Dump the firmware revision on the debug log:
jmf 36:d1a98d5f2bbd 1515 at_send_wnc_cmd("AT+GMR", &pRespStr, m_sCmdTimeoutMs);
jmf 36:d1a98d5f2bbd 1516
jmf 36:d1a98d5f2bbd 1517 // Quick commands below do not need to check cellular connectivity
jmf 36:d1a98d5f2bbd 1518 at_send_wnc_cmd("ATE0", &pRespStr, WNC_QUICK_CMD_TIMEOUT_MS); // Echo Off
jmf 36:d1a98d5f2bbd 1519 at_send_wnc_cmd("AT+CMEE=2", &pRespStr, m_sCmdTimeoutMs); // 2 - verbose error, 1 - numeric error, 0 - just ERROR
jmf 36:d1a98d5f2bbd 1520
jmf 36:d1a98d5f2bbd 1521 // Setup 3 memory slots in the WNC SIM for SMS usage.
jmf 36:d1a98d5f2bbd 1522 at_send_wnc_cmd("AT+CMGF=1", &pRespStr, m_sCmdTimeoutMs);
jmf 36:d1a98d5f2bbd 1523 at_send_wnc_cmd("AT+CPMS=\"SM\",\"SM\",\"SM\"", &pRespStr, m_sCmdTimeoutMs);
jmf 36:d1a98d5f2bbd 1524
jmf 36:d1a98d5f2bbd 1525 cmdRes = at_send_wnc_cmd("AT", &pRespStr, WNC_QUICK_CMD_TIMEOUT_MS); // Heartbeat?
jmf 36:d1a98d5f2bbd 1526
jmf 36:d1a98d5f2bbd 1527 // If the simple commands are not working, no chance of more complex.
jmf 36:d1a98d5f2bbd 1528 // I have seen re-trying commands make it worse.
jmf 36:d1a98d5f2bbd 1529 if (cmdRes != WNC_AT_CMD_OK)
jmf 36:d1a98d5f2bbd 1530 return (false);
jmf 36:d1a98d5f2bbd 1531
jmf 36:d1a98d5f2bbd 1532 cmdRes = at_send_wnc_cmd("AT@INTERNET=1", &pRespStr, m_sCmdTimeoutMs);
jmf 36:d1a98d5f2bbd 1533 if (cmdRes != WNC_AT_CMD_OK)
jmf 36:d1a98d5f2bbd 1534 return (false);
jmf 36:d1a98d5f2bbd 1535
jmf 36:d1a98d5f2bbd 1536 cmdRes = at_send_wnc_cmd("AT@SOCKDIAL=1", &pRespStr, m_sCmdTimeoutMs);
jmf 36:d1a98d5f2bbd 1537 if (cmdRes != WNC_AT_CMD_OK)
jmf 36:d1a98d5f2bbd 1538 return (false);
jmf 36:d1a98d5f2bbd 1539
jmf 36:d1a98d5f2bbd 1540 dbgPuts("SUCCESS: AT init of WNC!");
jmf 36:d1a98d5f2bbd 1541
jmf 36:d1a98d5f2bbd 1542 return (true);
jmf 36:d1a98d5f2bbd 1543 }
jmf 36:d1a98d5f2bbd 1544
jmf 36:d1a98d5f2bbd 1545 int16_t WncController::at_sockopen_wnc(const char * const ip, uint16_t port, uint16_t numSock, bool tcp, uint16_t timeOutSec)
jmf 36:d1a98d5f2bbd 1546 {
jmf 36:d1a98d5f2bbd 1547 string * pRespStr;
jmf 36:d1a98d5f2bbd 1548 string cmd_str("AT@SOCKCREAT=");
jmf 36:d1a98d5f2bbd 1549 AtCmdErr_e res;
jmf 36:d1a98d5f2bbd 1550
jmf 36:d1a98d5f2bbd 1551 if (tcp) cmd_str += "1"; // TCP
jmf 36:d1a98d5f2bbd 1552 else cmd_str += "2"; // else UDP
jmf 36:d1a98d5f2bbd 1553
jmf 36:d1a98d5f2bbd 1554 cmd_str += ",0";
jmf 36:d1a98d5f2bbd 1555 res = sendWncCmd(cmd_str.c_str(), &pRespStr, m_sCmdTimeoutMs);
jmf 36:d1a98d5f2bbd 1556 if (res == WNC_AT_CMD_OK && pRespStr->size() > 0)
jmf 36:d1a98d5f2bbd 1557 {
jmf 36:d1a98d5f2bbd 1558 size_t pos1 = pRespStr->find("T:");
jmf 36:d1a98d5f2bbd 1559 size_t pos2 = pRespStr->rfind("OK");
jmf 36:d1a98d5f2bbd 1560 if ((pos1 != string::npos) && (pos2 != string::npos)) {
jmf 36:d1a98d5f2bbd 1561 size_t numLen = pos2 - (pos1 + 2);
jmf 36:d1a98d5f2bbd 1562 string sockStr = pRespStr->substr(pos1 + 2, numLen);
jmf 36:d1a98d5f2bbd 1563 cmd_str = "AT@SOCKCONN=";
jmf 36:d1a98d5f2bbd 1564 cmd_str += sockStr;
jmf 36:d1a98d5f2bbd 1565 cmd_str += ",\"";
jmf 36:d1a98d5f2bbd 1566 cmd_str += ip;
jmf 36:d1a98d5f2bbd 1567 cmd_str += "\",";
jmf 36:d1a98d5f2bbd 1568 cmd_str += _to_string(port);
jmf 36:d1a98d5f2bbd 1569 cmd_str += ",";
jmf 36:d1a98d5f2bbd 1570 if (timeOutSec < 30)
jmf 36:d1a98d5f2bbd 1571 timeOutSec = 30;
jmf 36:d1a98d5f2bbd 1572 else if (timeOutSec > 360)
jmf 36:d1a98d5f2bbd 1573 timeOutSec = 360;
jmf 36:d1a98d5f2bbd 1574 cmd_str += _to_string(timeOutSec);
jmf 36:d1a98d5f2bbd 1575 res = sendWncCmd(cmd_str.c_str(), &pRespStr, 1000 * timeOutSec + 1000);
jmf 36:d1a98d5f2bbd 1576 if (m_sMoreDebugEnabled) {
jmf 36:d1a98d5f2bbd 1577 at_send_wnc_cmd("AT@SOCKCREAT?", &pRespStr, m_sCmdTimeoutMs);
jmf 36:d1a98d5f2bbd 1578 at_send_wnc_cmd("AT@SOCKCONN?", &pRespStr, m_sCmdTimeoutMs);
jmf 36:d1a98d5f2bbd 1579 }
jmf 36:d1a98d5f2bbd 1580 return (strtol(sockStr.c_str(), NULL, 10));
jmf 36:d1a98d5f2bbd 1581 }
jmf 36:d1a98d5f2bbd 1582 else {
jmf 36:d1a98d5f2bbd 1583 dbgPuts("Invalid sockcreat response!");
jmf 36:d1a98d5f2bbd 1584 return (0);
jmf 36:d1a98d5f2bbd 1585 }
jmf 36:d1a98d5f2bbd 1586 }
jmf 36:d1a98d5f2bbd 1587 else
jmf 36:d1a98d5f2bbd 1588 return (0);
jmf 36:d1a98d5f2bbd 1589 }
jmf 36:d1a98d5f2bbd 1590
jmf 36:d1a98d5f2bbd 1591 bool WncController::at_sockclose_wnc(uint16_t numSock)
jmf 36:d1a98d5f2bbd 1592 {
jmf 36:d1a98d5f2bbd 1593 string * pRespStr;
jmf 36:d1a98d5f2bbd 1594 string cmd_str("AT@SOCKCLOSE=");
jmf 36:d1a98d5f2bbd 1595
jmf 36:d1a98d5f2bbd 1596 cmd_str += _to_string(numSock);
jmf 36:d1a98d5f2bbd 1597
jmf 36:d1a98d5f2bbd 1598 // Don't check the cell status to close the socket
jmf 36:d1a98d5f2bbd 1599 AtCmdErr_e res = at_send_wnc_cmd(cmd_str.c_str(), &pRespStr, m_sCmdTimeoutMs);
jmf 36:d1a98d5f2bbd 1600
jmf 36:d1a98d5f2bbd 1601 if ((res != WNC_AT_CMD_TIMEOUT) && (res != WNC_AT_CMD_OK)) {
jmf 36:d1a98d5f2bbd 1602 for (unsigned i = 0; i < WNC_SOCK_CLOSE_RETRY_CNT; i++) {
jmf 36:d1a98d5f2bbd 1603 res = at_send_wnc_cmd(cmd_str.c_str(), &pRespStr, m_sCmdTimeoutMs);
jmf 36:d1a98d5f2bbd 1604 if ((res == WNC_AT_CMD_TIMEOUT) || (res == WNC_AT_CMD_OK))
jmf 36:d1a98d5f2bbd 1605 break;
jmf 36:d1a98d5f2bbd 1606 }
jmf 36:d1a98d5f2bbd 1607 }
jmf 36:d1a98d5f2bbd 1608
jmf 36:d1a98d5f2bbd 1609 return (res == WNC_AT_CMD_OK);
jmf 36:d1a98d5f2bbd 1610 }
jmf 36:d1a98d5f2bbd 1611
jmf 36:d1a98d5f2bbd 1612 bool WncController::at_dnsresolve_wnc(const char * s, string * ipStr)
jmf 36:d1a98d5f2bbd 1613 {
jmf 36:d1a98d5f2bbd 1614 string * pRespStr;
jmf 36:d1a98d5f2bbd 1615 string str(s);
jmf 36:d1a98d5f2bbd 1616 AtCmdErr_e r;
jmf 36:d1a98d5f2bbd 1617
jmf 36:d1a98d5f2bbd 1618 ipStr->erase(); // Clear out string until resolved!
jmf 36:d1a98d5f2bbd 1619 str = "AT@DNSRESVDON=\"" + str;
jmf 36:d1a98d5f2bbd 1620 str += "\"";
jmf 36:d1a98d5f2bbd 1621 r = sendWncCmd(str.c_str(), &pRespStr, WNC_DNS_RESOLVE_WAIT_MS);
jmf 36:d1a98d5f2bbd 1622 if (r == WNC_AT_CMD_OK && pRespStr->size() > 0) {
jmf 36:d1a98d5f2bbd 1623 size_t pos_start = pRespStr->find(":\"") + 2;
jmf 36:d1a98d5f2bbd 1624 if (pos_start != string::npos) {
jmf 36:d1a98d5f2bbd 1625 size_t pos_end = pRespStr->find("\"", pos_start) - 1;
jmf 36:d1a98d5f2bbd 1626 if (pos_end != string::npos) {
jmf 36:d1a98d5f2bbd 1627 if (pos_end > pos_start) {
jmf 36:d1a98d5f2bbd 1628 // Make a copy for use later (the source string is re-used)
jmf 36:d1a98d5f2bbd 1629 *ipStr = pRespStr->substr(pos_start, pos_end - pos_start + 1);
jmf 36:d1a98d5f2bbd 1630 return (true);
jmf 36:d1a98d5f2bbd 1631 }
jmf 36:d1a98d5f2bbd 1632 }
jmf 36:d1a98d5f2bbd 1633 }
jmf 36:d1a98d5f2bbd 1634 }
jmf 36:d1a98d5f2bbd 1635
jmf 36:d1a98d5f2bbd 1636 *ipStr = INVALID_IP_STR;
jmf 36:d1a98d5f2bbd 1637
jmf 36:d1a98d5f2bbd 1638 return (false);
jmf 36:d1a98d5f2bbd 1639 }
jmf 36:d1a98d5f2bbd 1640
jmf 36:d1a98d5f2bbd 1641 bool WncController::waitForPowerOnModemToRespond(uint8_t timeoutSecs)
jmf 36:d1a98d5f2bbd 1642 {
jmf 36:d1a98d5f2bbd 1643 // Now, give the modem x seconds to start responding by
jmf 36:d1a98d5f2bbd 1644 // sending simple 'AT' commands to modem once per second.
jmf 36:d1a98d5f2bbd 1645 if (timeoutSecs > 0) {
jmf 36:d1a98d5f2bbd 1646 do {
jmf 36:d1a98d5f2bbd 1647 timeoutSecs--;
jmf 36:d1a98d5f2bbd 1648 dbgPutsNoTime("\rWaiting ", false); dbgPutsNoTime(_to_string(timeoutSecs), false);
jmf 36:d1a98d5f2bbd 1649 dbgPutsNoTime(" ", false);
jmf 36:d1a98d5f2bbd 1650 AtCmdErr_e rc = mdmSendAtCmdRsp("AT", 500, &m_sWncStr);
jmf 36:d1a98d5f2bbd 1651 if (rc == WNC_AT_CMD_OK) {
jmf 36:d1a98d5f2bbd 1652 dbgPutsNoTime(""); // CR LF
jmf 36:d1a98d5f2bbd 1653 return true; //timer.read();
jmf 36:d1a98d5f2bbd 1654 }
jmf 36:d1a98d5f2bbd 1655 waitMs(500);
jmf 36:d1a98d5f2bbd 1656 }
jmf 36:d1a98d5f2bbd 1657 while (timeoutSecs > 0);
jmf 36:d1a98d5f2bbd 1658 dbgPutsNoTime(""); // CR LF
jmf 36:d1a98d5f2bbd 1659 }
jmf 36:d1a98d5f2bbd 1660
jmf 36:d1a98d5f2bbd 1661 return (false);
jmf 36:d1a98d5f2bbd 1662 }
jmf 36:d1a98d5f2bbd 1663
jmf 36:d1a98d5f2bbd 1664 WncController::AtCmdErr_e WncController::at_sockwrite_wnc(const uint8_t * s, uint16_t n, uint16_t numSock, bool isTcp)
jmf 36:d1a98d5f2bbd 1665 {
jmf 36:d1a98d5f2bbd 1666 AtCmdErr_e result;
jmf 36:d1a98d5f2bbd 1667
jmf 36:d1a98d5f2bbd 1668 if ((n > 0) && (n <= MAX_WNC_WRITE_BYTES)) {
jmf 36:d1a98d5f2bbd 1669 string * pRespStr;
jmf 36:d1a98d5f2bbd 1670 const char * num2str;
jmf 36:d1a98d5f2bbd 1671 string cmd_str;
jmf 36:d1a98d5f2bbd 1672
jmf 36:d1a98d5f2bbd 1673 if (isTcp == true)
jmf 36:d1a98d5f2bbd 1674 cmd_str="AT@SOCKWRITE=";
jmf 36:d1a98d5f2bbd 1675 else
jmf 36:d1a98d5f2bbd 1676 cmd_str="AT@SOCKWRITE="; // "AT@SOCKSEND=";
jmf 36:d1a98d5f2bbd 1677
jmf 36:d1a98d5f2bbd 1678 cmd_str += _to_string(numSock);
jmf 36:d1a98d5f2bbd 1679 cmd_str += ",";
jmf 36:d1a98d5f2bbd 1680 cmd_str += _to_string(n);
jmf 36:d1a98d5f2bbd 1681 cmd_str += ",\"";
jmf 36:d1a98d5f2bbd 1682 while(n > 0) {
jmf 36:d1a98d5f2bbd 1683 n--;
jmf 36:d1a98d5f2bbd 1684 num2str = _to_hex_string(*s++);
jmf 36:d1a98d5f2bbd 1685 // Always 2-digit ascii hex:
jmf 36:d1a98d5f2bbd 1686 if (num2str[1] == '\0')
jmf 36:d1a98d5f2bbd 1687 cmd_str += '0';
jmf 36:d1a98d5f2bbd 1688 cmd_str += num2str;
jmf 36:d1a98d5f2bbd 1689 }
jmf 36:d1a98d5f2bbd 1690 cmd_str += "\"";
jmf 36:d1a98d5f2bbd 1691 result = sendWncCmd(cmd_str.c_str(), &pRespStr, m_sCmdTimeoutMs);
jmf 36:d1a98d5f2bbd 1692 }
jmf 36:d1a98d5f2bbd 1693 else {
jmf 36:d1a98d5f2bbd 1694 dbgPuts("sockwrite Err, string len bad!");
jmf 36:d1a98d5f2bbd 1695 result = WNC_AT_CMD_ERR;
jmf 36:d1a98d5f2bbd 1696 }
jmf 36:d1a98d5f2bbd 1697
jmf 36:d1a98d5f2bbd 1698 return (result);
jmf 36:d1a98d5f2bbd 1699 }
jmf 36:d1a98d5f2bbd 1700
jmf 36:d1a98d5f2bbd 1701 WncController::AtCmdErr_e WncController::at_sockread_wnc(string * pS, uint16_t numSock, bool isTcp)
jmf 36:d1a98d5f2bbd 1702 {
jmf 36:d1a98d5f2bbd 1703 AtCmdErr_e result = WNC_AT_CMD_OK;
jmf 36:d1a98d5f2bbd 1704
jmf 36:d1a98d5f2bbd 1705 string * pRespStr;
jmf 36:d1a98d5f2bbd 1706 string cmd_str;
jmf 36:d1a98d5f2bbd 1707 size_t pos_start, pos_end;
jmf 36:d1a98d5f2bbd 1708 int i;
jmf 36:d1a98d5f2bbd 1709
jmf 36:d1a98d5f2bbd 1710 pS->erase(); // Start with a fresh string
jmf 36:d1a98d5f2bbd 1711
jmf 36:d1a98d5f2bbd 1712 if (isTcp == true)
jmf 36:d1a98d5f2bbd 1713 cmd_str="AT@SOCKREAD=";
jmf 36:d1a98d5f2bbd 1714 else
jmf 36:d1a98d5f2bbd 1715 cmd_str="AT@SOCKREAD="; // "AT@SOCKRECV=";
jmf 36:d1a98d5f2bbd 1716
jmf 36:d1a98d5f2bbd 1717 cmd_str += _to_string(numSock);
jmf 36:d1a98d5f2bbd 1718 cmd_str += ",";
jmf 36:d1a98d5f2bbd 1719 cmd_str += _to_string(MAX_WNC_READ_BYTES);
jmf 36:d1a98d5f2bbd 1720
jmf 36:d1a98d5f2bbd 1721 // Experimental: read should not need to check cell net status
jmf 36:d1a98d5f2bbd 1722 result = at_send_wnc_cmd(cmd_str.c_str(), &pRespStr, m_sCmdTimeoutMs);
jmf 36:d1a98d5f2bbd 1723 if (result == WNC_AT_CMD_OK) {
jmf 36:d1a98d5f2bbd 1724 if (pRespStr->size() > 0) {
jmf 36:d1a98d5f2bbd 1725 pos_start = pRespStr->find("\"");
jmf 36:d1a98d5f2bbd 1726 pos_end = pRespStr->rfind("\"");
jmf 36:d1a98d5f2bbd 1727 // Make sure search finds what it's looking for!
jmf 36:d1a98d5f2bbd 1728 if (pos_start != string::npos && pos_end != string::npos) {
jmf 36:d1a98d5f2bbd 1729 pos_start++;
jmf 36:d1a98d5f2bbd 1730 i = pos_end - pos_start; // Num hex chars, 2 per byte
jmf 36:d1a98d5f2bbd 1731 }
jmf 36:d1a98d5f2bbd 1732 else
jmf 36:d1a98d5f2bbd 1733 i = 0;
jmf 36:d1a98d5f2bbd 1734 }
jmf 36:d1a98d5f2bbd 1735 else
jmf 36:d1a98d5f2bbd 1736 i = 0;
jmf 36:d1a98d5f2bbd 1737
jmf 36:d1a98d5f2bbd 1738 if ((i < 0) || ((i % 2) == 1))
jmf 36:d1a98d5f2bbd 1739 dbgPuts("Invalid READ string!");
jmf 36:d1a98d5f2bbd 1740
jmf 36:d1a98d5f2bbd 1741 if (i > 2*MAX_WNC_READ_BYTES) {
jmf 36:d1a98d5f2bbd 1742 i = 2*MAX_WNC_READ_BYTES;
jmf 36:d1a98d5f2bbd 1743 dbgPuts("DANGER WNC read data does not match length!");
jmf 36:d1a98d5f2bbd 1744 }
jmf 36:d1a98d5f2bbd 1745
jmf 36:d1a98d5f2bbd 1746 // If data, convert the hex string into byte values
jmf 36:d1a98d5f2bbd 1747 while (i > 0) {
jmf 36:d1a98d5f2bbd 1748 i -= 2;
jmf 36:d1a98d5f2bbd 1749 *pS += (uint8_t)strtol(pRespStr->substr(pos_start, 2).c_str(), NULL, 16);
jmf 36:d1a98d5f2bbd 1750 pos_start += 2;
jmf 36:d1a98d5f2bbd 1751 }
jmf 36:d1a98d5f2bbd 1752 }
jmf 36:d1a98d5f2bbd 1753
jmf 36:d1a98d5f2bbd 1754 return (result);
jmf 36:d1a98d5f2bbd 1755 }
jmf 36:d1a98d5f2bbd 1756
jmf 36:d1a98d5f2bbd 1757 WncController::AtCmdErr_e WncController::at_sockread_wnc(uint8_t * pS, uint16_t * numRead, uint16_t n, uint16_t numSock, bool isTcp)
jmf 36:d1a98d5f2bbd 1758 {
jmf 36:d1a98d5f2bbd 1759 AtCmdErr_e result = WNC_AT_CMD_OK;
jmf 36:d1a98d5f2bbd 1760 *numRead = 0;
jmf 36:d1a98d5f2bbd 1761
jmf 36:d1a98d5f2bbd 1762 if ((n > 0) && (n <= MAX_WNC_READ_BYTES)) {
jmf 36:d1a98d5f2bbd 1763 string * pRespStr;
jmf 36:d1a98d5f2bbd 1764 string cmd_str;
jmf 36:d1a98d5f2bbd 1765 size_t pos_start, pos_end;
jmf 36:d1a98d5f2bbd 1766 int i;
jmf 36:d1a98d5f2bbd 1767
jmf 36:d1a98d5f2bbd 1768 if (isTcp == true)
jmf 36:d1a98d5f2bbd 1769 cmd_str="AT@SOCKREAD=";
jmf 36:d1a98d5f2bbd 1770 else
jmf 36:d1a98d5f2bbd 1771 cmd_str="AT@SOCKREAD="; // "AT@SOCKRECV=";
jmf 36:d1a98d5f2bbd 1772
jmf 36:d1a98d5f2bbd 1773 cmd_str += _to_string(numSock);
jmf 36:d1a98d5f2bbd 1774 cmd_str += ",";
jmf 36:d1a98d5f2bbd 1775 cmd_str += _to_string(n);
jmf 36:d1a98d5f2bbd 1776
jmf 36:d1a98d5f2bbd 1777 // Experimental: read should not need to check cell net status
jmf 36:d1a98d5f2bbd 1778 result = at_send_wnc_cmd(cmd_str.c_str(), &pRespStr, m_sCmdTimeoutMs);
jmf 36:d1a98d5f2bbd 1779 if (result == WNC_AT_CMD_OK) {
jmf 36:d1a98d5f2bbd 1780 if (pRespStr->size() > 0) {
jmf 36:d1a98d5f2bbd 1781 pos_start = pRespStr->find("\"");
jmf 36:d1a98d5f2bbd 1782 pos_end = pRespStr->rfind("\"");
jmf 36:d1a98d5f2bbd 1783 // Make sure search finds what it's looking for!
jmf 36:d1a98d5f2bbd 1784 if (pos_start != string::npos && pos_end != string::npos) {
jmf 36:d1a98d5f2bbd 1785 pos_start++;
jmf 36:d1a98d5f2bbd 1786 i = pos_end - pos_start; // Num hex chars, 2 per byte
jmf 36:d1a98d5f2bbd 1787 }
jmf 36:d1a98d5f2bbd 1788 else
jmf 36:d1a98d5f2bbd 1789 i = 0;
jmf 36:d1a98d5f2bbd 1790 }
jmf 36:d1a98d5f2bbd 1791 else
jmf 36:d1a98d5f2bbd 1792 i = 0;
jmf 36:d1a98d5f2bbd 1793
jmf 36:d1a98d5f2bbd 1794 if ((i < 0) || ((i % 2) == 1))
jmf 36:d1a98d5f2bbd 1795 dbgPuts("Invalid READ string!");
jmf 36:d1a98d5f2bbd 1796
jmf 36:d1a98d5f2bbd 1797 if (i > 2*n) {
jmf 36:d1a98d5f2bbd 1798 // Bound the ill formated WNC read string!
jmf 36:d1a98d5f2bbd 1799 i = 2*n;
jmf 36:d1a98d5f2bbd 1800 dbgPuts("TRUNCATING read data!");
jmf 36:d1a98d5f2bbd 1801 }
jmf 36:d1a98d5f2bbd 1802
jmf 36:d1a98d5f2bbd 1803 // If data, convert the hex string into byte values
jmf 36:d1a98d5f2bbd 1804 i /= 2;
jmf 36:d1a98d5f2bbd 1805 *numRead = i;
jmf 36:d1a98d5f2bbd 1806 while (i > 0) {
jmf 36:d1a98d5f2bbd 1807 i--;
jmf 36:d1a98d5f2bbd 1808 *pS++ = (uint8_t)strtol(pRespStr->substr(pos_start, 2).c_str(), NULL, 16);
jmf 36:d1a98d5f2bbd 1809 pos_start += 2;
jmf 36:d1a98d5f2bbd 1810 }
jmf 36:d1a98d5f2bbd 1811 }
jmf 36:d1a98d5f2bbd 1812 }
jmf 36:d1a98d5f2bbd 1813 else {
jmf 36:d1a98d5f2bbd 1814 dbgPuts("sockread Err, to many to read!");
jmf 36:d1a98d5f2bbd 1815 result = WNC_AT_CMD_ERR;
jmf 36:d1a98d5f2bbd 1816 }
jmf 36:d1a98d5f2bbd 1817
jmf 36:d1a98d5f2bbd 1818 return (result);
jmf 36:d1a98d5f2bbd 1819 }
jmf 36:d1a98d5f2bbd 1820
jmf 36:d1a98d5f2bbd 1821 bool WncController::at_reinitialize_mdm(void)
jmf 36:d1a98d5f2bbd 1822 {
jmf 36:d1a98d5f2bbd 1823 // Atempt to re-register
jmf 36:d1a98d5f2bbd 1824 // string * pRespStr;
jmf 36:d1a98d5f2bbd 1825 // dbgPuts("Force re-register!");
jmf 36:d1a98d5f2bbd 1826 // at_send_wnc_cmd("AT+CFUN=0,0", &pRespStr, m_sCmdTimeoutMs);
jmf 36:d1a98d5f2bbd 1827 // waitMs(31000);
jmf 36:d1a98d5f2bbd 1828 // at_send_wnc_cmd("AT+CFUN=1,0", &pRespStr, m_sCmdTimeoutMs);
jmf 36:d1a98d5f2bbd 1829 // waitMs(31000);
jmf 36:d1a98d5f2bbd 1830
jmf 36:d1a98d5f2bbd 1831 // Initialize the modem
jmf 36:d1a98d5f2bbd 1832 dbgPuts("Modem RE-initializing with SOFT Reset...");
jmf 36:d1a98d5f2bbd 1833
jmf 36:d1a98d5f2bbd 1834 string * pRespStr;
jmf 36:d1a98d5f2bbd 1835 at_send_wnc_cmd("AT@DMREBOOT", &pRespStr, m_sCmdTimeoutMs);
jmf 36:d1a98d5f2bbd 1836 waitMs(5000);
jmf 36:d1a98d5f2bbd 1837
jmf 36:d1a98d5f2bbd 1838 // Now, give the modem time to start responding by
jmf 36:d1a98d5f2bbd 1839 // sending simple 'AT' commands to the modem once per second.
jmf 36:d1a98d5f2bbd 1840 int timeoutSecs = WNC_REINIT_MAX_TIME_MS;
jmf 36:d1a98d5f2bbd 1841 do {
jmf 36:d1a98d5f2bbd 1842 dbgPuts("\rWaiting ", false); dbgPutsNoTime(_to_string(timeoutSecs), false);
jmf 36:d1a98d5f2bbd 1843 AtCmdErr_e rc = mdmSendAtCmdRsp("AT", 500, &m_sWncStr);
jmf 36:d1a98d5f2bbd 1844 if (rc == WNC_AT_CMD_OK) {
jmf 36:d1a98d5f2bbd 1845 dbgPutsNoTime(""); // CR LF
jmf 36:d1a98d5f2bbd 1846 break;
jmf 36:d1a98d5f2bbd 1847 }
jmf 36:d1a98d5f2bbd 1848 waitMs(500);
jmf 36:d1a98d5f2bbd 1849 timeoutSecs--;
jmf 36:d1a98d5f2bbd 1850 }
jmf 36:d1a98d5f2bbd 1851 while (timeoutSecs > 0);
jmf 36:d1a98d5f2bbd 1852
jmf 36:d1a98d5f2bbd 1853 if (timeoutSecs <= 0)
jmf 36:d1a98d5f2bbd 1854 dbgPuts("\r\nModem RE-init FAILED!");
jmf 36:d1a98d5f2bbd 1855 else
jmf 36:d1a98d5f2bbd 1856 dbgPuts("\r\nModem RE-init complete!");
jmf 36:d1a98d5f2bbd 1857
jmf 36:d1a98d5f2bbd 1858 return (timeoutSecs > 0);
jmf 36:d1a98d5f2bbd 1859 }
jmf 36:d1a98d5f2bbd 1860
jmf 36:d1a98d5f2bbd 1861 WncController::AtCmdErr_e WncController::mdmSendAtCmdRsp(const char *cmd, int timeout_ms, string * rsp, bool crLf)
jmf 36:d1a98d5f2bbd 1862 {
jmf 36:d1a98d5f2bbd 1863 rsp->erase(); // Clean up from possible prior cmd response
jmf 36:d1a98d5f2bbd 1864
jmf 36:d1a98d5f2bbd 1865 // Don't bother the WNC if user hasn't turned it on.
jmf 36:d1a98d5f2bbd 1866 if (m_sState == WNC_OFF)
jmf 36:d1a98d5f2bbd 1867 return (WNC_AT_CMD_WNC_NOT_ON);
jmf 36:d1a98d5f2bbd 1868
jmf 36:d1a98d5f2bbd 1869 size_t n = strlen(cmd);
jmf 36:d1a98d5f2bbd 1870
jmf 36:d1a98d5f2bbd 1871 // Wait per WNC advise
jmf 36:d1a98d5f2bbd 1872 waitMs(WNC_WAIT_FOR_AT_CMD_MS);
jmf 36:d1a98d5f2bbd 1873
jmf 36:d1a98d5f2bbd 1874 if (cmd && n > 0) {
jmf 36:d1a98d5f2bbd 1875 sendCmd(cmd, crLf);
jmf 36:d1a98d5f2bbd 1876 // sendCmd(cmd, n, 1000, crLf); // 3rd arg is micro seconds between chars sent
jmf 36:d1a98d5f2bbd 1877 }
jmf 36:d1a98d5f2bbd 1878
jmf 36:d1a98d5f2bbd 1879 startTimerA();
jmf 36:d1a98d5f2bbd 1880 while (getTimerTicksA_mS() < timeout_ms) {
jmf 36:d1a98d5f2bbd 1881 n = mdmGetline(rsp, timeout_ms - getTimerTicksA_mS());
jmf 36:d1a98d5f2bbd 1882
jmf 36:d1a98d5f2bbd 1883 if (n == 0)
jmf 36:d1a98d5f2bbd 1884 continue;
jmf 36:d1a98d5f2bbd 1885
jmf 36:d1a98d5f2bbd 1886 if (rsp->rfind("OK") != string::npos) {
jmf 36:d1a98d5f2bbd 1887 stopTimerA();
jmf 36:d1a98d5f2bbd 1888 return (WNC_AT_CMD_OK);
jmf 36:d1a98d5f2bbd 1889 }
jmf 36:d1a98d5f2bbd 1890
jmf 36:d1a98d5f2bbd 1891 if (rsp->rfind("+CME ERROR") != string::npos) {
jmf 36:d1a98d5f2bbd 1892 stopTimerA();
jmf 36:d1a98d5f2bbd 1893 return (WNC_AT_CMD_ERRCME);
jmf 36:d1a98d5f2bbd 1894 }
jmf 36:d1a98d5f2bbd 1895
jmf 36:d1a98d5f2bbd 1896 if (rsp->rfind("@EXTERR") != string::npos) {
jmf 36:d1a98d5f2bbd 1897 stopTimerA();
jmf 36:d1a98d5f2bbd 1898 return (WNC_AT_CMD_ERREXT);
jmf 36:d1a98d5f2bbd 1899 }
jmf 36:d1a98d5f2bbd 1900
jmf 36:d1a98d5f2bbd 1901 if (rsp->rfind("ERROR") != string::npos) {
jmf 36:d1a98d5f2bbd 1902 stopTimerA();
jmf 36:d1a98d5f2bbd 1903 return (WNC_AT_CMD_ERR);
jmf 36:d1a98d5f2bbd 1904 }
jmf 36:d1a98d5f2bbd 1905 }
jmf 36:d1a98d5f2bbd 1906 stopTimerA();
jmf 36:d1a98d5f2bbd 1907
jmf 36:d1a98d5f2bbd 1908 return (WNC_AT_CMD_TIMEOUT);
jmf 36:d1a98d5f2bbd 1909 }
jmf 36:d1a98d5f2bbd 1910
jmf 36:d1a98d5f2bbd 1911 bool WncController::at_setapn_wnc(const char * const apnStr)
jmf 36:d1a98d5f2bbd 1912 {
jmf 36:d1a98d5f2bbd 1913 string * pRespStr;
jmf 36:d1a98d5f2bbd 1914
jmf 36:d1a98d5f2bbd 1915 string cmd_str("AT%PDNSET=1,");
jmf 36:d1a98d5f2bbd 1916 cmd_str += apnStr;
jmf 36:d1a98d5f2bbd 1917 cmd_str += ",IP";
jmf 36:d1a98d5f2bbd 1918 if (WNC_AT_CMD_OK == at_send_wnc_cmd(cmd_str.c_str(), &pRespStr, WNC_APNSET_TIMEOUT_MS)) // Set APN, cmd seems to take a little longer sometimes
jmf 36:d1a98d5f2bbd 1919 return (true);
jmf 36:d1a98d5f2bbd 1920 else
jmf 36:d1a98d5f2bbd 1921 return (false);
jmf 36:d1a98d5f2bbd 1922 }
jmf 36:d1a98d5f2bbd 1923
jmf 36:d1a98d5f2bbd 1924 bool WncController::at_getrssiber_wnc(int16_t * dBm, int16_t * ber)
jmf 36:d1a98d5f2bbd 1925 {
jmf 36:d1a98d5f2bbd 1926 string * pRespStr;
jmf 36:d1a98d5f2bbd 1927 AtCmdErr_e cmdRes;
jmf 36:d1a98d5f2bbd 1928 cmdRes = at_send_wnc_cmd("AT+CSQ", &pRespStr, m_sCmdTimeoutMs); // Check RSSI,BER
jmf 36:d1a98d5f2bbd 1929 if (cmdRes != WNC_AT_CMD_OK)
jmf 36:d1a98d5f2bbd 1930 return (false);
jmf 36:d1a98d5f2bbd 1931
jmf 36:d1a98d5f2bbd 1932 if (pRespStr->size() == 0) {
jmf 36:d1a98d5f2bbd 1933 dbgPuts("Strange RSSI result!");
jmf 36:d1a98d5f2bbd 1934 return (false);
jmf 36:d1a98d5f2bbd 1935 }
jmf 36:d1a98d5f2bbd 1936 else {
jmf 36:d1a98d5f2bbd 1937 size_t pos1 = pRespStr->find("SQ:");
jmf 36:d1a98d5f2bbd 1938 size_t pos2 = pRespStr->rfind(",");
jmf 36:d1a98d5f2bbd 1939 // Sanity check
jmf 36:d1a98d5f2bbd 1940 if ((pos1 != string::npos) && (pos2 != string::npos) && (pos2 > pos1)) {
jmf 36:d1a98d5f2bbd 1941 string subStr = pRespStr->substr(pos1 + 4, pos2 - pos1 );
jmf 36:d1a98d5f2bbd 1942 int rawRssi = atoi(subStr.c_str());
jmf 36:d1a98d5f2bbd 1943
jmf 36:d1a98d5f2bbd 1944 // Convert WNC RSSI into dBm range:
jmf 36:d1a98d5f2bbd 1945 // 0 - -113 dBm
jmf 36:d1a98d5f2bbd 1946 // 1 - -111 dBm
jmf 36:d1a98d5f2bbd 1947 // 2..30 - -109 to -53 dBm
jmf 36:d1a98d5f2bbd 1948 // 31 - -51dBm or >
jmf 36:d1a98d5f2bbd 1949 // 99 - not known or not detectable
jmf 36:d1a98d5f2bbd 1950 if (rawRssi == 99)
jmf 36:d1a98d5f2bbd 1951 *dBm = -199;
jmf 36:d1a98d5f2bbd 1952 else if (rawRssi == 0)
jmf 36:d1a98d5f2bbd 1953 *dBm = -113;
jmf 36:d1a98d5f2bbd 1954 else if (rawRssi == 1)
jmf 36:d1a98d5f2bbd 1955 *dBm = -111;
jmf 36:d1a98d5f2bbd 1956 else if (rawRssi == 31)
jmf 36:d1a98d5f2bbd 1957 *dBm = -51;
jmf 36:d1a98d5f2bbd 1958 else if (rawRssi >= 2 && rawRssi <= 30)
jmf 36:d1a98d5f2bbd 1959 *dBm = -113 + 2 * rawRssi;
jmf 36:d1a98d5f2bbd 1960 else {
jmf 36:d1a98d5f2bbd 1961 dbgPuts("Invalid RSSI!");
jmf 36:d1a98d5f2bbd 1962 return (false);
jmf 36:d1a98d5f2bbd 1963 }
jmf 36:d1a98d5f2bbd 1964 // Parse out BER: 0..7 as RXQUAL values in the table 3GPP TS 45.008 subclause 8.2.4
jmf 36:d1a98d5f2bbd 1965 // 99 - unknown or undetectable
jmf 36:d1a98d5f2bbd 1966 subStr = pRespStr->substr(pos2 + 1, pRespStr->length() - (pos2 + 1));
jmf 36:d1a98d5f2bbd 1967 *ber = atoi(subStr.c_str());
jmf 36:d1a98d5f2bbd 1968 }
jmf 36:d1a98d5f2bbd 1969 else {
jmf 36:d1a98d5f2bbd 1970 dbgPuts("Strange RSSI result2!");
jmf 36:d1a98d5f2bbd 1971 return (false);
jmf 36:d1a98d5f2bbd 1972 }
jmf 36:d1a98d5f2bbd 1973 }
jmf 36:d1a98d5f2bbd 1974
jmf 36:d1a98d5f2bbd 1975 return (true);
jmf 36:d1a98d5f2bbd 1976 }
jmf 36:d1a98d5f2bbd 1977
jmf 36:d1a98d5f2bbd 1978 bool WncController::checkCellLink(void)
jmf 36:d1a98d5f2bbd 1979 {
jmf 36:d1a98d5f2bbd 1980 string * pRespStr;
jmf 36:d1a98d5f2bbd 1981 size_t pos;
jmf 36:d1a98d5f2bbd 1982 int regSts;
jmf 36:d1a98d5f2bbd 1983 int cmdRes1, cmdRes2;
jmf 36:d1a98d5f2bbd 1984
jmf 36:d1a98d5f2bbd 1985 if (m_sState == WNC_OFF)
jmf 36:d1a98d5f2bbd 1986 return (false);
jmf 36:d1a98d5f2bbd 1987
jmf 36:d1a98d5f2bbd 1988 m_sState = WNC_ON_NO_CELL_LINK;
jmf 36:d1a98d5f2bbd 1989
jmf 36:d1a98d5f2bbd 1990 if (m_sMoreDebugEnabled)
jmf 36:d1a98d5f2bbd 1991 dbgPuts("<-------- Begin Cell Status ------------");
jmf 36:d1a98d5f2bbd 1992
jmf 36:d1a98d5f2bbd 1993 cmdRes1 = at_send_wnc_cmd("AT+CSQ", &pRespStr, m_sCmdTimeoutMs); // Check RSSI,BER
jmf 36:d1a98d5f2bbd 1994
jmf 36:d1a98d5f2bbd 1995 // If no response, don't bother with more commands
jmf 36:d1a98d5f2bbd 1996 if (cmdRes1 != WNC_AT_CMD_TIMEOUT)
jmf 36:d1a98d5f2bbd 1997 cmdRes2 = at_send_wnc_cmd("AT+CPIN?", &pRespStr, m_sCmdTimeoutMs); // Check if SIM locked
jmf 36:d1a98d5f2bbd 1998 else {
jmf 36:d1a98d5f2bbd 1999 if (m_sMoreDebugEnabled)
jmf 36:d1a98d5f2bbd 2000 dbgPuts("------------ WNC No Response! --------->");
jmf 36:d1a98d5f2bbd 2001
jmf 36:d1a98d5f2bbd 2002 return (false);
jmf 36:d1a98d5f2bbd 2003 }
jmf 36:d1a98d5f2bbd 2004
jmf 36:d1a98d5f2bbd 2005 if ((cmdRes1 != WNC_AT_CMD_OK) || (cmdRes2 != WNC_AT_CMD_OK) || (pRespStr->size() == 0))
jmf 36:d1a98d5f2bbd 2006 {
jmf 36:d1a98d5f2bbd 2007 if (m_sMoreDebugEnabled)
jmf 36:d1a98d5f2bbd 2008 {
jmf 36:d1a98d5f2bbd 2009 if ((cmdRes1 == WNC_AT_CMD_TIMEOUT) || (cmdRes2 == WNC_AT_CMD_TIMEOUT))
jmf 36:d1a98d5f2bbd 2010 dbgPuts("------------ WNC No Response! --------->");
jmf 36:d1a98d5f2bbd 2011 else
jmf 36:d1a98d5f2bbd 2012 dbgPuts("------------ WNC Cmd Error! ----------->");
jmf 36:d1a98d5f2bbd 2013 }
jmf 36:d1a98d5f2bbd 2014
jmf 36:d1a98d5f2bbd 2015 // If by a miracle it responds to the 2nd after the 1st, keep going
jmf 36:d1a98d5f2bbd 2016 if ((cmdRes2 == WNC_AT_CMD_TIMEOUT) || (pRespStr->size() == 0))
jmf 36:d1a98d5f2bbd 2017 return (false);
jmf 36:d1a98d5f2bbd 2018 }
jmf 36:d1a98d5f2bbd 2019
jmf 36:d1a98d5f2bbd 2020 // If SIM Card not ready don't bother with commands!
jmf 36:d1a98d5f2bbd 2021 if (pRespStr->find("CPIN: READY") == string::npos)
jmf 36:d1a98d5f2bbd 2022 {
jmf 36:d1a98d5f2bbd 2023 if (m_sMoreDebugEnabled)
jmf 36:d1a98d5f2bbd 2024 dbgPuts("------------ WNC SIM Problem! --------->");
jmf 36:d1a98d5f2bbd 2025
jmf 36:d1a98d5f2bbd 2026 return (false);
jmf 36:d1a98d5f2bbd 2027 }
jmf 36:d1a98d5f2bbd 2028
jmf 36:d1a98d5f2bbd 2029 // SIM card OK, now check for signal and cellular network registration
jmf 36:d1a98d5f2bbd 2030 cmdRes1 = at_send_wnc_cmd("AT+CREG?", &pRespStr, m_sCmdTimeoutMs); // Check if registered on network
jmf 36:d1a98d5f2bbd 2031 if (cmdRes1 != WNC_AT_CMD_OK || pRespStr->size() == 0)
jmf 36:d1a98d5f2bbd 2032 {
jmf 36:d1a98d5f2bbd 2033 if (m_sMoreDebugEnabled)
jmf 36:d1a98d5f2bbd 2034 dbgPuts("------------ WNC +CREG? Fail! --------->");
jmf 36:d1a98d5f2bbd 2035
jmf 36:d1a98d5f2bbd 2036 return (false);
jmf 36:d1a98d5f2bbd 2037 }
jmf 36:d1a98d5f2bbd 2038 else
jmf 36:d1a98d5f2bbd 2039 {
jmf 36:d1a98d5f2bbd 2040 pos = pRespStr->find("CREG: ");
jmf 36:d1a98d5f2bbd 2041 if (pos != string::npos)
jmf 36:d1a98d5f2bbd 2042 {
jmf 36:d1a98d5f2bbd 2043 // The registration is the 2nd arg in the comma separated list
jmf 36:d1a98d5f2bbd 2044 *pRespStr = pRespStr->substr(pos+8, 1);
jmf 36:d1a98d5f2bbd 2045 regSts = atoi(pRespStr->c_str());
jmf 36:d1a98d5f2bbd 2046 switch (regSts) {
jmf 36:d1a98d5f2bbd 2047 case 1:
jmf 36:d1a98d5f2bbd 2048 case 5:
jmf 36:d1a98d5f2bbd 2049 case 6:
jmf 36:d1a98d5f2bbd 2050 case 7:
jmf 36:d1a98d5f2bbd 2051 m_sReadyForSMS = true;
jmf 36:d1a98d5f2bbd 2052 break;
jmf 36:d1a98d5f2bbd 2053 default:
jmf 36:d1a98d5f2bbd 2054 m_sReadyForSMS = false;
jmf 36:d1a98d5f2bbd 2055 dbgPuts("SMS Service Down!");
jmf 36:d1a98d5f2bbd 2056 }
jmf 36:d1a98d5f2bbd 2057
jmf 36:d1a98d5f2bbd 2058 // 1 - registered home, 5 - registered roaming
jmf 36:d1a98d5f2bbd 2059 if ((regSts != 1) && (regSts != 5))
jmf 36:d1a98d5f2bbd 2060 {
jmf 36:d1a98d5f2bbd 2061 if (m_sMoreDebugEnabled)
jmf 36:d1a98d5f2bbd 2062 dbgPuts("------ WNC Cell Link Down for Data! --->");
jmf 36:d1a98d5f2bbd 2063
jmf 36:d1a98d5f2bbd 2064 return (false);
jmf 36:d1a98d5f2bbd 2065 }
jmf 36:d1a98d5f2bbd 2066 }
jmf 36:d1a98d5f2bbd 2067
jmf 36:d1a98d5f2bbd 2068 if (m_sMoreDebugEnabled)
jmf 36:d1a98d5f2bbd 2069 dbgPuts("------------ WNC Ready ---------------->");
jmf 36:d1a98d5f2bbd 2070 }
tdMBED 38:9a1a6f211eb4 2071 dbgPuts("Testing");
tdMBED 38:9a1a6f211eb4 2072 int cmdRes4 = at_send_wnc_cmd("AT%MEAS=\"8\"", &pRespStr, m_sCmdTimeoutMs);
tdMBED 38:9a1a6f211eb4 2073 int cmdRes3 = at_send_wnc_cmd("AT+CGEQOS?", &pRespStr, m_sCmdTimeoutMs);
tdMBED 38:9a1a6f211eb4 2074
tdMBED 38:9a1a6f211eb4 2075
jmf 36:d1a98d5f2bbd 2076 // If we made it this far and the WNC did respond, keep the ON state
jmf 36:d1a98d5f2bbd 2077 if (m_sState != WNC_NO_RESPONSE)
jmf 36:d1a98d5f2bbd 2078 m_sState = WNC_ON;
jmf 36:d1a98d5f2bbd 2079
jmf 36:d1a98d5f2bbd 2080 return (true);
jmf 36:d1a98d5f2bbd 2081 }
jmf 36:d1a98d5f2bbd 2082
jmf 36:d1a98d5f2bbd 2083 int WncController::dbgPutsNoTime(const char * s, bool crlf)
jmf 36:d1a98d5f2bbd 2084 {
jmf 36:d1a98d5f2bbd 2085 if (m_sDebugEnabled == true) {
jmf 36:d1a98d5f2bbd 2086 int r = dbgWriteChars(s);
jmf 36:d1a98d5f2bbd 2087 if (crlf == true)
jmf 36:d1a98d5f2bbd 2088 return (dbgWriteChars("\r\n"));
jmf 36:d1a98d5f2bbd 2089 else
jmf 36:d1a98d5f2bbd 2090 return (r);
jmf 36:d1a98d5f2bbd 2091 }
jmf 36:d1a98d5f2bbd 2092 else
jmf 36:d1a98d5f2bbd 2093 return 0;
jmf 36:d1a98d5f2bbd 2094 };
jmf 36:d1a98d5f2bbd 2095
jmf 36:d1a98d5f2bbd 2096 int WncController::dbgPuts(const char * s, bool crlf)
jmf 36:d1a98d5f2bbd 2097 {
jmf 36:d1a98d5f2bbd 2098 dbgPutsNoTime("[*] ", false);
jmf 36:d1a98d5f2bbd 2099 dbgPutsNoTime(_to_string(getLogTimerTicks()), false);
jmf 36:d1a98d5f2bbd 2100 dbgPutsNoTime(" ", false);
jmf 36:d1a98d5f2bbd 2101
jmf 36:d1a98d5f2bbd 2102 int r = dbgPutsNoTime(s, false);
jmf 36:d1a98d5f2bbd 2103
jmf 36:d1a98d5f2bbd 2104 if (crlf == true)
jmf 36:d1a98d5f2bbd 2105 return (dbgPutsNoTime("", true));
jmf 36:d1a98d5f2bbd 2106 else
jmf 36:d1a98d5f2bbd 2107 return (r);
jmf 36:d1a98d5f2bbd 2108 };
jmf 36:d1a98d5f2bbd 2109
jmf 36:d1a98d5f2bbd 2110 void WncController::sendCmd(const char * cmd, bool crLf)
jmf 36:d1a98d5f2bbd 2111 {
jmf 36:d1a98d5f2bbd 2112 puts(cmd);
jmf 36:d1a98d5f2bbd 2113 if (crLf == true)
jmf 36:d1a98d5f2bbd 2114 puts("\r\n");
jmf 36:d1a98d5f2bbd 2115 }
jmf 36:d1a98d5f2bbd 2116
jmf 36:d1a98d5f2bbd 2117 void WncController::sendCmd(const char * cmd, unsigned n, unsigned wait_uS, bool crLf)
jmf 36:d1a98d5f2bbd 2118 {
jmf 36:d1a98d5f2bbd 2119 while (n--) {
jmf 36:d1a98d5f2bbd 2120 putc(*cmd++);
jmf 36:d1a98d5f2bbd 2121 waitUs(wait_uS);
jmf 36:d1a98d5f2bbd 2122 };
jmf 36:d1a98d5f2bbd 2123 if (crLf == true) {
jmf 36:d1a98d5f2bbd 2124 putc('\r');
jmf 36:d1a98d5f2bbd 2125 waitUs(wait_uS);
jmf 36:d1a98d5f2bbd 2126 putc('\n');
jmf 36:d1a98d5f2bbd 2127 waitUs(wait_uS);
jmf 36:d1a98d5f2bbd 2128 }
jmf 36:d1a98d5f2bbd 2129 }
jmf 36:d1a98d5f2bbd 2130
jmf 36:d1a98d5f2bbd 2131 }; // End namespace WncController_fk
jmf 36:d1a98d5f2bbd 2132