driver for the WNC M14A2A Cellular Data Module

Committer:
JMF
Date:
Tue Feb 06 16:10:48 2018 +0000
Revision:
0:6a2d96c2a520
Incorporating changes suggested by ARM

Who changed what in which revision?

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