DIYmall 0.96" Inch I2c IIC Serial 128x64 Oled LCD LED White Display Module

Dependencies:   Adafruit_GFX SDFileSystem

Fork of ATT_AWS_IoT_demo by AT&T IoT

Committer:
afmiee
Date:
Tue Oct 09 20:57:34 2018 +0000
Revision:
28:4650c541b029
Parent:
15:6f2798e45099
DIYmall 0.96" Inch I2c IIC Serial 128x64 Oled LCD LED White Display Module

Who changed what in which revision?

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