V.06 11/3

Dependencies:   FT6206 SDFileSystem SPI_TFT_ILI9341 TFT_fonts

Fork of ATT_AWS_IoT_demo by attiot

Committer:
jilee
Date:
Mon Oct 09 21:13:49 2017 +0000
Revision:
28:54d9a550adf1
Parent:
15:6f2798e45099
Child:
29:f71a0be59b99
V.01

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