wifi test

Dependencies:   X_NUCLEO_IKS01A2 mbed-http

Committer:
JMF
Date:
Wed Sep 05 14:28:24 2018 +0000
Revision:
0:24d3eb812fd4
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew contents of line
JMF 0:24d3eb812fd4 1 /* Copyright (c) 2015 ARM Limited
JMF 0:24d3eb812fd4 2 *
JMF 0:24d3eb812fd4 3 * Licensed under the Apache License, Version 2.0 (the "License");
JMF 0:24d3eb812fd4 4 * you may not use this file except in compliance with the License.
JMF 0:24d3eb812fd4 5 * You may obtain a copy of the License at
JMF 0:24d3eb812fd4 6 *
JMF 0:24d3eb812fd4 7 * http://www.apache.org/licenses/LICENSE-2.0
JMF 0:24d3eb812fd4 8 *
JMF 0:24d3eb812fd4 9 * Unless required by applicable law or agreed to in writing, software
JMF 0:24d3eb812fd4 10 * distributed under the License is distributed on an "AS IS" BASIS,
JMF 0:24d3eb812fd4 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
JMF 0:24d3eb812fd4 12 * See the License for the specific language governing permissions and
JMF 0:24d3eb812fd4 13 * limitations under the License.
JMF 0:24d3eb812fd4 14 *
JMF 0:24d3eb812fd4 15 * @section DESCRIPTION
JMF 0:24d3eb812fd4 16 *
JMF 0:24d3eb812fd4 17 * Parser for the AT command syntax
JMF 0:24d3eb812fd4 18 *
JMF 0:24d3eb812fd4 19 */
JMF 0:24d3eb812fd4 20
JMF 0:24d3eb812fd4 21 #include "ATParser.h"
JMF 0:24d3eb812fd4 22 #include "mbed_debug.h"
JMF 0:24d3eb812fd4 23
JMF 0:24d3eb812fd4 24 #ifdef LF
JMF 0:24d3eb812fd4 25 #undef LF
JMF 0:24d3eb812fd4 26 #define LF 10
JMF 0:24d3eb812fd4 27 #else
JMF 0:24d3eb812fd4 28 #define LF 10
JMF 0:24d3eb812fd4 29 #endif
JMF 0:24d3eb812fd4 30
JMF 0:24d3eb812fd4 31 #ifdef CR
JMF 0:24d3eb812fd4 32 #undef CR
JMF 0:24d3eb812fd4 33 #define CR 13
JMF 0:24d3eb812fd4 34 #else
JMF 0:24d3eb812fd4 35 #define CR 13
JMF 0:24d3eb812fd4 36 #endif
JMF 0:24d3eb812fd4 37 #define MIN(a,b) (((a)<(b))?(a):(b))
JMF 0:24d3eb812fd4 38
JMF 0:24d3eb812fd4 39 // activate / de-activate debug
JMF 0:24d3eb812fd4 40 #define dbg_on 0
JMF 0:24d3eb812fd4 41 #define AT_DATA_PRINT 0
JMF 0:24d3eb812fd4 42 #define AT_COMMAND_PRINT 0
JMF 0:24d3eb812fd4 43 #define AT_HEXA_DATA 0
JMF 0:24d3eb812fd4 44
JMF 0:24d3eb812fd4 45 ATParser::ATParser(BufferedSpi &serial_spi, const char *delimiter, int buffer_size, int timeout) :
JMF 0:24d3eb812fd4 46 _serial_spi(&serial_spi),
JMF 0:24d3eb812fd4 47 _buffer_size(buffer_size), _in_prev(0), _oobs(NULL)
JMF 0:24d3eb812fd4 48 {
JMF 0:24d3eb812fd4 49 _buffer = new char[buffer_size];
JMF 0:24d3eb812fd4 50 setTimeout(timeout);
JMF 0:24d3eb812fd4 51 setDelimiter(delimiter);
JMF 0:24d3eb812fd4 52 }
JMF 0:24d3eb812fd4 53
JMF 0:24d3eb812fd4 54
JMF 0:24d3eb812fd4 55 // getc/putc handling with timeouts
JMF 0:24d3eb812fd4 56 int ATParser::putc(char c)
JMF 0:24d3eb812fd4 57 {
JMF 0:24d3eb812fd4 58 return _serial_spi->putc(c);
JMF 0:24d3eb812fd4 59 }
JMF 0:24d3eb812fd4 60
JMF 0:24d3eb812fd4 61 int ATParser::getc()
JMF 0:24d3eb812fd4 62 {
JMF 0:24d3eb812fd4 63 return _serial_spi->getc();
JMF 0:24d3eb812fd4 64 }
JMF 0:24d3eb812fd4 65
JMF 0:24d3eb812fd4 66 void ATParser::flush()
JMF 0:24d3eb812fd4 67 {
JMF 0:24d3eb812fd4 68 _bufferMutex.lock();
JMF 0:24d3eb812fd4 69 while (_serial_spi->readable()) {
JMF 0:24d3eb812fd4 70 _serial_spi->getc();
JMF 0:24d3eb812fd4 71 }
JMF 0:24d3eb812fd4 72 _bufferMutex.unlock();
JMF 0:24d3eb812fd4 73 }
JMF 0:24d3eb812fd4 74
JMF 0:24d3eb812fd4 75 // read/write handling with timeouts
JMF 0:24d3eb812fd4 76 int ATParser::write(const char *data, int size_of_data, int size_in_buff)
JMF 0:24d3eb812fd4 77 {
JMF 0:24d3eb812fd4 78 int i = 0;
JMF 0:24d3eb812fd4 79 _bufferMutex.lock();
JMF 0:24d3eb812fd4 80 debug_if(dbg_on, "ATParser write: %d BYTES\r\n", size_of_data);
JMF 0:24d3eb812fd4 81 debug_if(AT_DATA_PRINT, "ATParser write: (ASCII) ", size_of_data);
JMF 0:24d3eb812fd4 82 for (; i < size_of_data; i++) {
JMF 0:24d3eb812fd4 83 debug_if(AT_DATA_PRINT, "%c", data[i]);
JMF 0:24d3eb812fd4 84 if (putc(data[i]) < 0) {
JMF 0:24d3eb812fd4 85 debug_if(AT_DATA_PRINT, "\r\n");
JMF 0:24d3eb812fd4 86 _bufferMutex.unlock();
JMF 0:24d3eb812fd4 87 return -1;
JMF 0:24d3eb812fd4 88 }
JMF 0:24d3eb812fd4 89 }
JMF 0:24d3eb812fd4 90 debug_if(AT_DATA_PRINT, "\r\n");
JMF 0:24d3eb812fd4 91
JMF 0:24d3eb812fd4 92 _serial_spi->buffsend(size_of_data + size_in_buff);
JMF 0:24d3eb812fd4 93 _bufferMutex.unlock();
JMF 0:24d3eb812fd4 94
JMF 0:24d3eb812fd4 95 return (size_of_data + size_in_buff);
JMF 0:24d3eb812fd4 96 }
JMF 0:24d3eb812fd4 97
JMF 0:24d3eb812fd4 98 int ATParser::read(char *data)
JMF 0:24d3eb812fd4 99 {
JMF 0:24d3eb812fd4 100 int readsize;
JMF 0:24d3eb812fd4 101 int i = 0;
JMF 0:24d3eb812fd4 102
JMF 0:24d3eb812fd4 103 _bufferMutex.lock();
JMF 0:24d3eb812fd4 104
JMF 0:24d3eb812fd4 105 //this->flush();
JMF 0:24d3eb812fd4 106 if (!_serial_spi->readable()) {
JMF 0:24d3eb812fd4 107 readsize = _serial_spi->read();
JMF 0:24d3eb812fd4 108 } else {
JMF 0:24d3eb812fd4 109 debug_if(dbg_on, "Pending data when reading from WIFI\r\n");
JMF 0:24d3eb812fd4 110 return -1;
JMF 0:24d3eb812fd4 111 }
JMF 0:24d3eb812fd4 112
JMF 0:24d3eb812fd4 113 debug_if(dbg_on, "ATParser read: %d data avail in SPI\r\n", readsize);
JMF 0:24d3eb812fd4 114
JMF 0:24d3eb812fd4 115 if (readsize < 0) {
JMF 0:24d3eb812fd4 116 _bufferMutex.unlock();
JMF 0:24d3eb812fd4 117 return -1;
JMF 0:24d3eb812fd4 118 }
JMF 0:24d3eb812fd4 119
JMF 0:24d3eb812fd4 120 for (i = 0 ; i < readsize; i++) {
JMF 0:24d3eb812fd4 121 int c = getc();
JMF 0:24d3eb812fd4 122 if (c < 0) {
JMF 0:24d3eb812fd4 123 _bufferMutex.unlock();
JMF 0:24d3eb812fd4 124 return -1;
JMF 0:24d3eb812fd4 125 }
JMF 0:24d3eb812fd4 126 data[i] = c;
JMF 0:24d3eb812fd4 127 }
JMF 0:24d3eb812fd4 128
JMF 0:24d3eb812fd4 129 #if AT_HEXA_DATA
JMF 0:24d3eb812fd4 130 debug_if(AT_DATA_PRINT, "ATParser read: (HEXA) ");
JMF 0:24d3eb812fd4 131 for (i = 0; i < readsize; i++) {
JMF 0:24d3eb812fd4 132 debug_if(AT_DATA_PRINT, "%2X ", data[i]);
JMF 0:24d3eb812fd4 133 if ((i + 1) % 20 == 0) {
JMF 0:24d3eb812fd4 134 debug_if(AT_DATA_PRINT, "\r\n");
JMF 0:24d3eb812fd4 135 }
JMF 0:24d3eb812fd4 136 }
JMF 0:24d3eb812fd4 137 debug_if(AT_DATA_PRINT, "\r\n");
JMF 0:24d3eb812fd4 138 #endif
JMF 0:24d3eb812fd4 139 debug_if(AT_DATA_PRINT, "ATParser read: (ASCII) ");
JMF 0:24d3eb812fd4 140 for (i = 0; i < readsize; i++) {
JMF 0:24d3eb812fd4 141 debug_if(AT_DATA_PRINT, "%c", data[i]);
JMF 0:24d3eb812fd4 142 }
JMF 0:24d3eb812fd4 143 debug_if(AT_DATA_PRINT, "\r\n");
JMF 0:24d3eb812fd4 144
JMF 0:24d3eb812fd4 145 _bufferMutex.unlock();
JMF 0:24d3eb812fd4 146
JMF 0:24d3eb812fd4 147 return (readsize);
JMF 0:24d3eb812fd4 148 }
JMF 0:24d3eb812fd4 149
JMF 0:24d3eb812fd4 150 // printf/scanf handling
JMF 0:24d3eb812fd4 151 int ATParser::vprintf(const char *format, va_list args)
JMF 0:24d3eb812fd4 152 {
JMF 0:24d3eb812fd4 153 _bufferMutex.lock();
JMF 0:24d3eb812fd4 154 if (vsprintf(_buffer, format, args) < 0) {
JMF 0:24d3eb812fd4 155 _bufferMutex.unlock();
JMF 0:24d3eb812fd4 156 return false;
JMF 0:24d3eb812fd4 157 }
JMF 0:24d3eb812fd4 158
JMF 0:24d3eb812fd4 159 int i = 0;
JMF 0:24d3eb812fd4 160 for (; _buffer[i]; i++) {
JMF 0:24d3eb812fd4 161 if (putc(_buffer[i]) < 0) {
JMF 0:24d3eb812fd4 162 _bufferMutex.unlock();
JMF 0:24d3eb812fd4 163 return -1;
JMF 0:24d3eb812fd4 164 }
JMF 0:24d3eb812fd4 165 }
JMF 0:24d3eb812fd4 166 _bufferMutex.unlock();
JMF 0:24d3eb812fd4 167
JMF 0:24d3eb812fd4 168 return i;
JMF 0:24d3eb812fd4 169 }
JMF 0:24d3eb812fd4 170
JMF 0:24d3eb812fd4 171 int ATParser::vscanf(const char *format, va_list args)
JMF 0:24d3eb812fd4 172 {
JMF 0:24d3eb812fd4 173 // Since format is const, we need to copy it into our buffer to
JMF 0:24d3eb812fd4 174 // add the line's null terminator and clobber value-matches with asterisks.
JMF 0:24d3eb812fd4 175 //
JMF 0:24d3eb812fd4 176 // We just use the beginning of the buffer to avoid unnecessary allocations.
JMF 0:24d3eb812fd4 177 int i = 0;
JMF 0:24d3eb812fd4 178 int offset = 0;
JMF 0:24d3eb812fd4 179
JMF 0:24d3eb812fd4 180 _bufferMutex.lock();
JMF 0:24d3eb812fd4 181
JMF 0:24d3eb812fd4 182 while (format[i]) {
JMF 0:24d3eb812fd4 183 if (format[i] == '%' && format[i + 1] != '%' && format[i + 1] != '*') {
JMF 0:24d3eb812fd4 184 _buffer[offset++] = '%';
JMF 0:24d3eb812fd4 185 _buffer[offset++] = '*';
JMF 0:24d3eb812fd4 186 i++;
JMF 0:24d3eb812fd4 187 } else {
JMF 0:24d3eb812fd4 188 _buffer[offset++] = format[i++];
JMF 0:24d3eb812fd4 189 }
JMF 0:24d3eb812fd4 190 }
JMF 0:24d3eb812fd4 191
JMF 0:24d3eb812fd4 192 // Scanf has very poor support for catching errors
JMF 0:24d3eb812fd4 193 // fortunately, we can abuse the %n specifier to determine
JMF 0:24d3eb812fd4 194 // if the entire string was matched.
JMF 0:24d3eb812fd4 195 _buffer[offset++] = '%';
JMF 0:24d3eb812fd4 196 _buffer[offset++] = 'n';
JMF 0:24d3eb812fd4 197 _buffer[offset++] = 0;
JMF 0:24d3eb812fd4 198
JMF 0:24d3eb812fd4 199 // To workaround scanf's lack of error reporting, we actually
JMF 0:24d3eb812fd4 200 // make two passes. One checks the validity with the modified
JMF 0:24d3eb812fd4 201 // format string that only stores the matched characters (%n).
JMF 0:24d3eb812fd4 202 // The other reads in the actual matched values.
JMF 0:24d3eb812fd4 203 //
JMF 0:24d3eb812fd4 204 // We keep trying the match until we succeed or some other error
JMF 0:24d3eb812fd4 205 // derails us.
JMF 0:24d3eb812fd4 206 int j = 0;
JMF 0:24d3eb812fd4 207
JMF 0:24d3eb812fd4 208 while (true) {
JMF 0:24d3eb812fd4 209 // Ran out of space
JMF 0:24d3eb812fd4 210 if (j + 1 >= _buffer_size - offset) {
JMF 0:24d3eb812fd4 211 _bufferMutex.unlock();
JMF 0:24d3eb812fd4 212 return false;
JMF 0:24d3eb812fd4 213 }
JMF 0:24d3eb812fd4 214 // Recieve next character
JMF 0:24d3eb812fd4 215 int c = getc();
JMF 0:24d3eb812fd4 216 if (c < 0) {
JMF 0:24d3eb812fd4 217 _bufferMutex.unlock();
JMF 0:24d3eb812fd4 218 return -1;
JMF 0:24d3eb812fd4 219 }
JMF 0:24d3eb812fd4 220 _buffer[offset + j++] = c;
JMF 0:24d3eb812fd4 221 _buffer[offset + j] = 0;
JMF 0:24d3eb812fd4 222
JMF 0:24d3eb812fd4 223 // Check for match
JMF 0:24d3eb812fd4 224 int count = -1;
JMF 0:24d3eb812fd4 225 sscanf(_buffer + offset, _buffer, &count);
JMF 0:24d3eb812fd4 226
JMF 0:24d3eb812fd4 227 // We only succeed if all characters in the response are matched
JMF 0:24d3eb812fd4 228 if (count == j) {
JMF 0:24d3eb812fd4 229 // Store the found results
JMF 0:24d3eb812fd4 230 vsscanf(_buffer + offset, format, args);
JMF 0:24d3eb812fd4 231 _bufferMutex.unlock();
JMF 0:24d3eb812fd4 232 return j;
JMF 0:24d3eb812fd4 233 }
JMF 0:24d3eb812fd4 234 }
JMF 0:24d3eb812fd4 235 }
JMF 0:24d3eb812fd4 236
JMF 0:24d3eb812fd4 237
JMF 0:24d3eb812fd4 238 // Command parsing with line handling
JMF 0:24d3eb812fd4 239 bool ATParser::vsend(const char *command, va_list args)
JMF 0:24d3eb812fd4 240 {
JMF 0:24d3eb812fd4 241 int i = 0, j = 0;
JMF 0:24d3eb812fd4 242 _bufferMutex.lock();
JMF 0:24d3eb812fd4 243 // Create and send command
JMF 0:24d3eb812fd4 244 if (vsprintf(_buffer, command, args) < 0) {
JMF 0:24d3eb812fd4 245 _bufferMutex.unlock();
JMF 0:24d3eb812fd4 246 return false;
JMF 0:24d3eb812fd4 247 }
JMF 0:24d3eb812fd4 248 /* get buffer length */
JMF 0:24d3eb812fd4 249 for (i = 0; _buffer[i]; i++) {
JMF 0:24d3eb812fd4 250 }
JMF 0:24d3eb812fd4 251
JMF 0:24d3eb812fd4 252 for (j = 0; _delimiter[j]; j++) {
JMF 0:24d3eb812fd4 253 _buffer[i + j] = _delimiter[j];
JMF 0:24d3eb812fd4 254 }
JMF 0:24d3eb812fd4 255 _buffer[i + j] = 0; // only to get a clean debug log
JMF 0:24d3eb812fd4 256
JMF 0:24d3eb812fd4 257 bool ret = !(_serial_spi->buffwrite(_buffer, i + j) < 0);
JMF 0:24d3eb812fd4 258
JMF 0:24d3eb812fd4 259 debug_if(AT_COMMAND_PRINT, "AT> %s\n", _buffer);
JMF 0:24d3eb812fd4 260 _bufferMutex.unlock();
JMF 0:24d3eb812fd4 261 return ret;
JMF 0:24d3eb812fd4 262 }
JMF 0:24d3eb812fd4 263
JMF 0:24d3eb812fd4 264 bool ATParser::vrecv(const char *response, va_list args)
JMF 0:24d3eb812fd4 265 {
JMF 0:24d3eb812fd4 266 _bufferMutex.lock();
JMF 0:24d3eb812fd4 267
JMF 0:24d3eb812fd4 268 if (!_serial_spi->readable()) {
JMF 0:24d3eb812fd4 269 // debug_if(dbg_on, "NO DATA, read again\r\n");
JMF 0:24d3eb812fd4 270 if (_serial_spi->read() < 0) {
JMF 0:24d3eb812fd4 271 return false;
JMF 0:24d3eb812fd4 272 }
JMF 0:24d3eb812fd4 273 }
JMF 0:24d3eb812fd4 274 // else {
JMF 0:24d3eb812fd4 275 // debug_if(dbg_on, "Pending data\r\n");
JMF 0:24d3eb812fd4 276 // }
JMF 0:24d3eb812fd4 277
JMF 0:24d3eb812fd4 278 restart:
JMF 0:24d3eb812fd4 279 _aborted = false;
JMF 0:24d3eb812fd4 280 // Iterate through each line in the expected response
JMF 0:24d3eb812fd4 281 while (response[0]) {
JMF 0:24d3eb812fd4 282 // Since response is const, we need to copy it into our buffer to
JMF 0:24d3eb812fd4 283 // add the line's null terminator and clobber value-matches with asterisks.
JMF 0:24d3eb812fd4 284 //
JMF 0:24d3eb812fd4 285 // We just use the beginning of the buffer to avoid unnecessary allocations.
JMF 0:24d3eb812fd4 286 int i = 0;
JMF 0:24d3eb812fd4 287 int offset = 0;
JMF 0:24d3eb812fd4 288 bool whole_line_wanted = false;
JMF 0:24d3eb812fd4 289
JMF 0:24d3eb812fd4 290 while (response[i]) {
JMF 0:24d3eb812fd4 291 if (response[i] == '%' && response[i + 1] != '%' && response[i + 1] != '*') {
JMF 0:24d3eb812fd4 292 _buffer[offset++] = '%';
JMF 0:24d3eb812fd4 293 _buffer[offset++] = '*';
JMF 0:24d3eb812fd4 294 i++;
JMF 0:24d3eb812fd4 295 } else {
JMF 0:24d3eb812fd4 296 _buffer[offset++] = response[i++];
JMF 0:24d3eb812fd4 297 // Find linebreaks, taking care not to be fooled if they're in a %[^\n] conversion specification
JMF 0:24d3eb812fd4 298 if (response[i - 1] == '\n' && !(i >= 3 && response[i - 3] == '[' && response[i - 2] == '^')) {
JMF 0:24d3eb812fd4 299 whole_line_wanted = true;
JMF 0:24d3eb812fd4 300 break;
JMF 0:24d3eb812fd4 301 }
JMF 0:24d3eb812fd4 302 }
JMF 0:24d3eb812fd4 303 }
JMF 0:24d3eb812fd4 304
JMF 0:24d3eb812fd4 305 // Scanf has very poor support for catching errors
JMF 0:24d3eb812fd4 306 // fortunately, we can abuse the %n specifier to determine
JMF 0:24d3eb812fd4 307 // if the entire string was matched.
JMF 0:24d3eb812fd4 308 _buffer[offset++] = '%';
JMF 0:24d3eb812fd4 309 _buffer[offset++] = 'n';
JMF 0:24d3eb812fd4 310 _buffer[offset++] = 0;
JMF 0:24d3eb812fd4 311
JMF 0:24d3eb812fd4 312 // debug_if(dbg_on, "ATParser vrecv: AT? ====%s====\n", _buffer);
JMF 0:24d3eb812fd4 313 // To workaround scanf's lack of error reporting, we actually
JMF 0:24d3eb812fd4 314 // make two passes. One checks the validity with the modified
JMF 0:24d3eb812fd4 315 // format string that only stores the matched characters (%n).
JMF 0:24d3eb812fd4 316 // The other reads in the actual matched values.
JMF 0:24d3eb812fd4 317 //
JMF 0:24d3eb812fd4 318 // We keep trying the match until we succeed or some other error
JMF 0:24d3eb812fd4 319 // derails us.
JMF 0:24d3eb812fd4 320 int j = 0;
JMF 0:24d3eb812fd4 321
JMF 0:24d3eb812fd4 322 while (true) {
JMF 0:24d3eb812fd4 323 // Recieve next character
JMF 0:24d3eb812fd4 324 int c = getc();
JMF 0:24d3eb812fd4 325 if (c < 0) {
JMF 0:24d3eb812fd4 326 debug_if(dbg_on, "AT(Timeout)\n");
JMF 0:24d3eb812fd4 327 _bufferMutex.unlock();
JMF 0:24d3eb812fd4 328 return false;
JMF 0:24d3eb812fd4 329 }
JMF 0:24d3eb812fd4 330
JMF 0:24d3eb812fd4 331 // debug_if(AT_DATA_PRINT, "%2X ", c);
JMF 0:24d3eb812fd4 332
JMF 0:24d3eb812fd4 333 _buffer[offset + j++] = c;
JMF 0:24d3eb812fd4 334 _buffer[offset + j] = 0;
JMF 0:24d3eb812fd4 335
JMF 0:24d3eb812fd4 336 // Check for oob data
JMF 0:24d3eb812fd4 337 for (struct oob *oob = _oobs; oob; oob = oob->next) {
JMF 0:24d3eb812fd4 338 if ((unsigned)j == oob->len && memcmp(
JMF 0:24d3eb812fd4 339 oob->prefix, _buffer + offset, oob->len) == 0) {
JMF 0:24d3eb812fd4 340 debug_if(dbg_on, "AT! %s\n", oob->prefix);
JMF 0:24d3eb812fd4 341 oob->cb();
JMF 0:24d3eb812fd4 342
JMF 0:24d3eb812fd4 343 if (_aborted) {
JMF 0:24d3eb812fd4 344 debug_if(dbg_on, "AT(Aborted)\n");
JMF 0:24d3eb812fd4 345 _bufferMutex.unlock();
JMF 0:24d3eb812fd4 346 return false;
JMF 0:24d3eb812fd4 347 }
JMF 0:24d3eb812fd4 348 // oob may have corrupted non-reentrant buffer,
JMF 0:24d3eb812fd4 349 // so we need to set it up again
JMF 0:24d3eb812fd4 350 goto restart;
JMF 0:24d3eb812fd4 351 }
JMF 0:24d3eb812fd4 352 }
JMF 0:24d3eb812fd4 353
JMF 0:24d3eb812fd4 354 // Check for match
JMF 0:24d3eb812fd4 355 int count = -1;
JMF 0:24d3eb812fd4 356 if (whole_line_wanted && c != '\n') {
JMF 0:24d3eb812fd4 357 // Don't attempt scanning until we get delimiter if they included it in format
JMF 0:24d3eb812fd4 358 // This allows recv("Foo: %s\n") to work, and not match with just the first character of a string
JMF 0:24d3eb812fd4 359 // (scanf does not itself match whitespace in its format string, so \n is not significant to it)
JMF 0:24d3eb812fd4 360 } else {
JMF 0:24d3eb812fd4 361 sscanf(_buffer + offset, _buffer, &count);
JMF 0:24d3eb812fd4 362 }
JMF 0:24d3eb812fd4 363
JMF 0:24d3eb812fd4 364 // We only succeed if all characters in the response are matched
JMF 0:24d3eb812fd4 365 if (count == j) {
JMF 0:24d3eb812fd4 366 debug_if(AT_COMMAND_PRINT, "AT= ====%s====\n", _buffer + offset);
JMF 0:24d3eb812fd4 367 // Reuse the front end of the buffer
JMF 0:24d3eb812fd4 368 memcpy(_buffer, response, i);
JMF 0:24d3eb812fd4 369 _buffer[i] = 0;
JMF 0:24d3eb812fd4 370
JMF 0:24d3eb812fd4 371 // Store the found results
JMF 0:24d3eb812fd4 372 vsscanf(_buffer + offset, _buffer, args);
JMF 0:24d3eb812fd4 373
JMF 0:24d3eb812fd4 374 // Jump to next line and continue parsing
JMF 0:24d3eb812fd4 375 response += i;
JMF 0:24d3eb812fd4 376 break;
JMF 0:24d3eb812fd4 377 }
JMF 0:24d3eb812fd4 378
JMF 0:24d3eb812fd4 379 // Clear the buffer when we hit a newline or ran out of space
JMF 0:24d3eb812fd4 380 // running out of space usually means we ran into binary data
JMF 0:24d3eb812fd4 381 if ((c == '\n')) {
JMF 0:24d3eb812fd4 382 // debug_if(dbg_on, "New line AT<<< %s", _buffer+offset);
JMF 0:24d3eb812fd4 383 j = 0;
JMF 0:24d3eb812fd4 384 }
JMF 0:24d3eb812fd4 385 if ((j + 1 >= (_buffer_size - offset))) {
JMF 0:24d3eb812fd4 386
JMF 0:24d3eb812fd4 387 debug_if(dbg_on, "Out of space AT<<< %s, j=%d", _buffer + offset, j);
JMF 0:24d3eb812fd4 388 j = 0;
JMF 0:24d3eb812fd4 389 }
JMF 0:24d3eb812fd4 390 }
JMF 0:24d3eb812fd4 391 }
JMF 0:24d3eb812fd4 392
JMF 0:24d3eb812fd4 393 _bufferMutex.unlock();
JMF 0:24d3eb812fd4 394
JMF 0:24d3eb812fd4 395 return true;
JMF 0:24d3eb812fd4 396 }
JMF 0:24d3eb812fd4 397
JMF 0:24d3eb812fd4 398
JMF 0:24d3eb812fd4 399 // Mapping to vararg functions
JMF 0:24d3eb812fd4 400 int ATParser::printf(const char *format, ...)
JMF 0:24d3eb812fd4 401 {
JMF 0:24d3eb812fd4 402 va_list args;
JMF 0:24d3eb812fd4 403 va_start(args, format);
JMF 0:24d3eb812fd4 404 int res = vprintf(format, args);
JMF 0:24d3eb812fd4 405 va_end(args);
JMF 0:24d3eb812fd4 406 return res;
JMF 0:24d3eb812fd4 407 }
JMF 0:24d3eb812fd4 408
JMF 0:24d3eb812fd4 409 int ATParser::scanf(const char *format, ...)
JMF 0:24d3eb812fd4 410 {
JMF 0:24d3eb812fd4 411 va_list args;
JMF 0:24d3eb812fd4 412 va_start(args, format);
JMF 0:24d3eb812fd4 413 int res = vscanf(format, args);
JMF 0:24d3eb812fd4 414 va_end(args);
JMF 0:24d3eb812fd4 415 return res;
JMF 0:24d3eb812fd4 416 }
JMF 0:24d3eb812fd4 417
JMF 0:24d3eb812fd4 418 bool ATParser::send(const char *command, ...)
JMF 0:24d3eb812fd4 419 {
JMF 0:24d3eb812fd4 420 va_list args;
JMF 0:24d3eb812fd4 421 va_start(args, command);
JMF 0:24d3eb812fd4 422 bool res = vsend(command, args);
JMF 0:24d3eb812fd4 423 va_end(args);
JMF 0:24d3eb812fd4 424 return res;
JMF 0:24d3eb812fd4 425 }
JMF 0:24d3eb812fd4 426
JMF 0:24d3eb812fd4 427 bool ATParser::recv(const char *response, ...)
JMF 0:24d3eb812fd4 428 {
JMF 0:24d3eb812fd4 429 va_list args;
JMF 0:24d3eb812fd4 430 va_start(args, response);
JMF 0:24d3eb812fd4 431 bool res = vrecv(response, args);
JMF 0:24d3eb812fd4 432 va_end(args);
JMF 0:24d3eb812fd4 433 return res;
JMF 0:24d3eb812fd4 434 }
JMF 0:24d3eb812fd4 435
JMF 0:24d3eb812fd4 436
JMF 0:24d3eb812fd4 437 // oob registration
JMF 0:24d3eb812fd4 438 void ATParser::oob(const char *prefix, Callback<void()> cb)
JMF 0:24d3eb812fd4 439 {
JMF 0:24d3eb812fd4 440 struct oob *oob = new struct oob;
JMF 0:24d3eb812fd4 441 oob->len = strlen(prefix);
JMF 0:24d3eb812fd4 442 oob->prefix = prefix;
JMF 0:24d3eb812fd4 443 oob->cb = cb;
JMF 0:24d3eb812fd4 444 oob->next = _oobs;
JMF 0:24d3eb812fd4 445 _oobs = oob;
JMF 0:24d3eb812fd4 446 }
JMF 0:24d3eb812fd4 447
JMF 0:24d3eb812fd4 448 void ATParser::abort()
JMF 0:24d3eb812fd4 449 {
JMF 0:24d3eb812fd4 450 _aborted = true;
JMF 0:24d3eb812fd4 451 }
JMF 0:24d3eb812fd4 452
JMF 0:24d3eb812fd4 453
JMF 0:24d3eb812fd4 454