Axel Hwang / Mbed OS ProjetIOT
Committer:
axelhwang
Date:
Wed Oct 28 07:42:46 2020 +0000
Revision:
0:5738799d7a56
Push

Who changed what in which revision?

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