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