mirror of https://github.com/ARMmbed/mbed-os.git
Merge pull request #8598 from VeijoPesonen/fix_atcmdparser_oob_handling
ATCmdParser: Fix OOB handling performance-wisepull/8614/head
commit
3d09f3bd98
|
@ -215,7 +215,8 @@ bool ATCmdParser::vrecv(const char *response, std::va_list args)
|
|||
restart:
|
||||
_aborted = false;
|
||||
// Iterate through each line in the expected response
|
||||
while (response[0]) {
|
||||
// response being NULL means we just want to check for OOBs
|
||||
while (!response || 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.
|
||||
//
|
||||
|
@ -224,7 +225,7 @@ restart:
|
|||
int offset = 0;
|
||||
bool whole_line_wanted = false;
|
||||
|
||||
while (response[i]) {
|
||||
while (response && response[i]) {
|
||||
if (response[i] == '%' && response[i + 1] != '%' && response[i + 1] != '*') {
|
||||
_buffer[offset++] = '%';
|
||||
_buffer[offset++] = '*';
|
||||
|
@ -257,6 +258,11 @@ restart:
|
|||
int j = 0;
|
||||
|
||||
while (true) {
|
||||
// If just peeking for OOBs, and at start of line, check
|
||||
// readability
|
||||
if (!response && j == 0 && !_fh->readable()) {
|
||||
return false;
|
||||
}
|
||||
// Receive next character
|
||||
int c = getc();
|
||||
if (c < 0) {
|
||||
|
@ -284,6 +290,7 @@ restart:
|
|||
if ((unsigned)j == oob->len && memcmp(
|
||||
oob->prefix, _buffer + offset, oob->len) == 0) {
|
||||
debug_if(_dbg_on, "AT! %s\n", oob->prefix);
|
||||
_oob_cb_count++;
|
||||
oob->cb();
|
||||
|
||||
if (_aborted) {
|
||||
|
@ -302,7 +309,7 @@ restart:
|
|||
// Don't attempt scanning until we get delimiter if they included it in format
|
||||
// This allows recv("Foo: %s\n") to work, and not match with just the first character of a string
|
||||
// (scanf does not itself match whitespace in its format string, so \n is not significant to it)
|
||||
} else {
|
||||
} else if (response) {
|
||||
sscanf(_buffer + offset, _buffer, &count);
|
||||
}
|
||||
|
||||
|
@ -388,52 +395,9 @@ void ATCmdParser::abort()
|
|||
|
||||
bool ATCmdParser::process_oob()
|
||||
{
|
||||
if (!_fh->readable()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
while (true) {
|
||||
// Receive next character
|
||||
int c = getc();
|
||||
if (c < 0) {
|
||||
return false;
|
||||
}
|
||||
// Simplify newlines (borrowed from retarget.cpp)
|
||||
if ((c == CR && _in_prev != LF) ||
|
||||
(c == LF && _in_prev != CR)) {
|
||||
_in_prev = c;
|
||||
c = '\n';
|
||||
} else if ((c == CR && _in_prev == LF) ||
|
||||
(c == LF && _in_prev == CR)) {
|
||||
_in_prev = c;
|
||||
// onto next character
|
||||
continue;
|
||||
} else {
|
||||
_in_prev = c;
|
||||
}
|
||||
_buffer[i++] = c;
|
||||
_buffer[i] = 0;
|
||||
|
||||
// Check for oob data
|
||||
struct oob *oob = _oobs;
|
||||
while (oob) {
|
||||
if (i == (int)oob->len && memcmp(
|
||||
oob->prefix, _buffer, oob->len) == 0) {
|
||||
debug_if(_dbg_on, "AT! %s\r\n", oob->prefix);
|
||||
oob->cb();
|
||||
return true;
|
||||
}
|
||||
oob = oob->next;
|
||||
}
|
||||
|
||||
// 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 (((i + 1) >= _buffer_size) || (c == '\n')) {
|
||||
debug_if(_dbg_on, "AT< %s", _buffer);
|
||||
i = 0;
|
||||
}
|
||||
}
|
||||
int pre_count = _oob_cb_count;
|
||||
recv(NULL);
|
||||
return _oob_cb_count != pre_count;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -66,6 +66,7 @@ private:
|
|||
// Parsing information
|
||||
const char *_output_delimiter;
|
||||
int _output_delim_size;
|
||||
int _oob_cb_count;
|
||||
char _in_prev;
|
||||
bool _dbg_on;
|
||||
bool _aborted;
|
||||
|
@ -91,7 +92,7 @@ public:
|
|||
*/
|
||||
ATCmdParser(FileHandle *fh, const char *output_delimiter = "\r",
|
||||
int buffer_size = 256, int timeout = 8000, bool debug = false)
|
||||
: _fh(fh), _buffer_size(buffer_size), _in_prev(0), _oobs(NULL)
|
||||
: _fh(fh), _buffer_size(buffer_size), _oob_cb_count(0), _in_prev(0), _oobs(NULL)
|
||||
{
|
||||
_buffer = new char[buffer_size];
|
||||
set_timeout(timeout);
|
||||
|
|
Loading…
Reference in New Issue