![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
OneNet_IoT_demo for ASC platform
Dependencies: Common_lib ESP8266 EdpKit_lib cJSON_lib driver_mbed_HP20x driver_mbed_TH02 wifi_example
Fork of mbed-os-example-esp8266 by
Diff: esp8266-driver/ESP8266/ATParser/ATParser.cpp
- Revision:
- 2:1dbc3aa8ae3a
- Parent:
- 1:b4a718e62e0b
--- a/esp8266-driver/ESP8266/ATParser/ATParser.cpp Thu Jan 12 22:05:15 2017 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,333 +0,0 @@ -/* Copyright (c) 2015 ARM Limited - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * @section DESCRIPTION - * - * Parser for the AT command syntax - * - */ - -#include "ATParser.h" -#include "mbed_debug.h" - - -// getc/putc handling with timeouts -int ATParser::putc(char c) -{ - Timer timer; - timer.start(); - - while (true) { - if (_serial->writeable()) { - return _serial->putc(c); - } - if (timer.read_ms() > _timeout) { - return -1; - } - } -} - -int ATParser::getc() -{ - Timer timer; - timer.start(); - - while (true) { - if (_serial->readable()) { - return _serial->getc(); - } - if (timer.read_ms() > _timeout) { - return -1; - } - } -} - -void ATParser::flush() -{ - while (_serial->readable()) { - _serial->getc(); - } -} - - -// read/write handling with timeouts -int ATParser::write(const char *data, int size) -{ - int i = 0; - for ( ; i < size; i++) { - if (putc(data[i]) < 0) { - return -1; - } - } - return i; -} - -int ATParser::read(char *data, int size) -{ - int i = 0; - for ( ; i < size; i++) { - int c = getc(); - if (c < 0) { - return -1; - } - data[i] = c; - } - return i; -} - - -// printf/scanf handling -int ATParser::vprintf(const char *format, va_list args) -{ - if (vsprintf(_buffer, format, args) < 0) { - return false; - } - int i = 0; - for ( ; _buffer[i]; i++) { - if (putc(_buffer[i]) < 0) { - return -1; - } - } - return i; -} - -int ATParser::vscanf(const char *format, va_list args) -{ - // Since format is const, we need to copy it into our buffer to - // add the line's null terminator and clobber value-matches with asterisks. - // - // We just use the beginning of the buffer to avoid unnecessary allocations. - int i = 0; - int offset = 0; - - while (format[i]) { - if (format[i] == '%' && format[i+1] != '%' && format[i+1] != '*') { - _buffer[offset++] = '%'; - _buffer[offset++] = '*'; - i++; - } else { - _buffer[offset++] = format[i++]; - } - } - - // Scanf has very poor support for catching errors - // fortunately, we can abuse the %n specifier to determine - // if the entire string was matched. - _buffer[offset++] = '%'; - _buffer[offset++] = 'n'; - _buffer[offset++] = 0; - - // To workaround scanf's lack of error reporting, we actually - // make two passes. One checks the validity with the modified - // format string that only stores the matched characters (%n). - // The other reads in the actual matched values. - // - // We keep trying the match until we succeed or some other error - // derails us. - int j = 0; - - while (true) { - // Ran out of space - if (j+1 >= _buffer_size - offset) { - return false; - } - // Recieve next character - int c = getc(); - if (c < 0) { - return -1; - } - _buffer[offset + j++] = c; - _buffer[offset + j] = 0; - - // Check for match - int count = -1; - sscanf(_buffer+offset, _buffer, &count); - - // We only succeed if all characters in the response are matched - if (count == j) { - // Store the found results - vsscanf(_buffer+offset, format, args); - return j; - } - } -} - - -// Command parsing with line handling -bool ATParser::vsend(const char *command, va_list args) -{ - // Create and send command - if (vsprintf(_buffer, command, args) < 0) { - return false; - } - for (int i = 0; _buffer[i]; i++) { - if (putc(_buffer[i]) < 0) { - return false; - } - } - - // Finish with newline - for (int i = 0; _delimiter[i]; i++) { - if (putc(_delimiter[i]) < 0) { - return false; - } - } - - debug_if(dbg_on, "AT> %s\r\n", _buffer); - return true; -} - -bool ATParser::vrecv(const char *response, va_list args) -{ - // Iterate through each line in the expected response - while (response[0]) { - // Since response is const, we need to copy it into our buffer to - // add the line's null terminator and clobber value-matches with asterisks. - // - // We just use the beginning of the buffer to avoid unnecessary allocations. - int i = 0; - int offset = 0; - - while (response[i]) { - if (memcmp(&response[i+1-_delim_size], _delimiter, _delim_size) == 0) { - i++; - break; - } else if (response[i] == '%' && response[i+1] != '%' && response[i+1] != '*') { - _buffer[offset++] = '%'; - _buffer[offset++] = '*'; - i++; - } else { - _buffer[offset++] = response[i++]; - } - } - - // Scanf has very poor support for catching errors - // fortunately, we can abuse the %n specifier to determine - // if the entire string was matched. - _buffer[offset++] = '%'; - _buffer[offset++] = 'n'; - _buffer[offset++] = 0; - - // To workaround scanf's lack of error reporting, we actually - // make two passes. One checks the validity with the modified - // format string that only stores the matched characters (%n). - // The other reads in the actual matched values. - // - // We keep trying the match until we succeed or some other error - // derails us. - int j = 0; - - while (true) { - // Recieve next character - int c = getc(); - if (c < 0) { - return false; - } - _buffer[offset + j++] = c; - _buffer[offset + j] = 0; - - // Check for oob data - for (int k = 0; k < _oobs.size(); k++) { - if (j == _oobs[k].len && memcmp( - _oobs[k].prefix, _buffer+offset, _oobs[k].len) == 0) { - debug_if(dbg_on, "AT! %s\r\n", _oobs[k].prefix); - _oobs[k].cb(); - - // oob may have corrupted non-reentrant buffer, - // so we need to set it up again - return vrecv(response, args); - } - } - - // Check for match - int count = -1; - sscanf(_buffer+offset, _buffer, &count); - - // We only succeed if all characters in the response are matched - if (count == j) { - debug_if(dbg_on, "AT= %s\r\n", _buffer+offset); - // Reuse the front end of the buffer - memcpy(_buffer, response, i); - _buffer[i] = 0; - - // Store the found results - vsscanf(_buffer+offset, _buffer, args); - - // Jump to next line and continue parsing - response += i; - break; - } - - // Clear the buffer when we hit a newline or ran out of space - // running out of space usually means we ran into binary data - if (j+1 >= _buffer_size - offset || - strcmp(&_buffer[offset + j-_delim_size], _delimiter) == 0) { - - debug_if(dbg_on, "AT< %s", _buffer+offset); - j = 0; - } - } - } - - return true; -} - - -// Mapping to vararg functions -int ATParser::printf(const char *format, ...) -{ - va_list args; - va_start(args, format); - int res = vprintf(format, args); - va_end(args); - return res; -} - -int ATParser::scanf(const char *format, ...) -{ - va_list args; - va_start(args, format); - int res = vscanf(format, args); - va_end(args); - return res; -} - -bool ATParser::send(const char *command, ...) -{ - va_list args; - va_start(args, command); - bool res = vsend(command, args); - va_end(args); - return res; -} - -bool ATParser::recv(const char *response, ...) -{ - va_list args; - va_start(args, response); - bool res = vrecv(response, args); - va_end(args); - return res; -} - - -// oob registration -void ATParser::oob(const char *prefix, Callback<void()> cb) -{ - struct oob oob; - oob.len = strlen(prefix); - oob.prefix = prefix; - oob.cb = cb; - _oobs.push_back(oob); -}