V.06 11/3

Dependencies:   FT6206 SDFileSystem SPI_TFT_ILI9341 TFT_fonts

Fork of ATT_AWS_IoT_demo by attiot

Committer:
ampembeng
Date:
Thu Dec 01 18:05:38 2016 +0000
Revision:
15:6f2798e45099
Child:
28:54d9a550adf1
Initial commit.  Demo works with both the FRDM wired Ethernet and the Avnet Shield wireless modem.

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