Rahul Dahiya / Mbed OS STM32F7 Ethernet
Committer:
rahul_dahiya
Date:
Wed Jan 15 15:57:15 2020 +0530
Revision:
0:fb8047b156bb
STM32F7 LWIP

Who changed what in which revision?

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