![](/media/cache/group/default_image.jpg.50x50_q85.jpg)
V.06 11/3
Dependencies: FT6206 SDFileSystem SPI_TFT_ILI9341 TFT_fonts
Fork of ATT_AWS_IoT_demo by
WNCInterface/WncControllerK64F/WncController/WncController.cpp@28:54d9a550adf1, 2017-10-09 (annotated)
- 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?
User | Revision | Line number | New 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 |