Skip to content

Commit 3d09f3b

Browse files
author
Cruz Monrreal
authored
Merge pull request #8598 from VeijoPesonen/fix_atcmdparser_oob_handling
ATCmdParser: Fix OOB handling performance-wise
2 parents d8e4dae + 6440228 commit 3d09f3b

File tree

2 files changed

+15
-50
lines changed

2 files changed

+15
-50
lines changed

platform/ATCmdParser.cpp

Lines changed: 13 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -215,7 +215,8 @@ bool ATCmdParser::vrecv(const char *response, std::va_list args)
215215
restart:
216216
_aborted = false;
217217
// Iterate through each line in the expected response
218-
while (response[0]) {
218+
// response being NULL means we just want to check for OOBs
219+
while (!response || response[0]) {
219220
// Since response is const, we need to copy it into our buffer to
220221
// add the line's null terminator and clobber value-matches with asterisks.
221222
//
@@ -224,7 +225,7 @@ bool ATCmdParser::vrecv(const char *response, std::va_list args)
224225
int offset = 0;
225226
bool whole_line_wanted = false;
226227

227-
while (response[i]) {
228+
while (response && response[i]) {
228229
if (response[i] == '%' && response[i + 1] != '%' && response[i + 1] != '*') {
229230
_buffer[offset++] = '%';
230231
_buffer[offset++] = '*';
@@ -257,6 +258,11 @@ bool ATCmdParser::vrecv(const char *response, std::va_list args)
257258
int j = 0;
258259

259260
while (true) {
261+
// If just peeking for OOBs, and at start of line, check
262+
// readability
263+
if (!response && j == 0 && !_fh->readable()) {
264+
return false;
265+
}
260266
// Receive next character
261267
int c = getc();
262268
if (c < 0) {
@@ -284,6 +290,7 @@ bool ATCmdParser::vrecv(const char *response, std::va_list args)
284290
if ((unsigned)j == oob->len && memcmp(
285291
oob->prefix, _buffer + offset, oob->len) == 0) {
286292
debug_if(_dbg_on, "AT! %s\n", oob->prefix);
293+
_oob_cb_count++;
287294
oob->cb();
288295

289296
if (_aborted) {
@@ -302,7 +309,7 @@ bool ATCmdParser::vrecv(const char *response, std::va_list args)
302309
// Don't attempt scanning until we get delimiter if they included it in format
303310
// This allows recv("Foo: %s\n") to work, and not match with just the first character of a string
304311
// (scanf does not itself match whitespace in its format string, so \n is not significant to it)
305-
} else {
312+
} else if (response) {
306313
sscanf(_buffer + offset, _buffer, &count);
307314
}
308315

@@ -388,52 +395,9 @@ void ATCmdParser::abort()
388395

389396
bool ATCmdParser::process_oob()
390397
{
391-
if (!_fh->readable()) {
392-
return false;
393-
}
394-
395-
int i = 0;
396-
while (true) {
397-
// Receive next character
398-
int c = getc();
399-
if (c < 0) {
400-
return false;
401-
}
402-
// Simplify newlines (borrowed from retarget.cpp)
403-
if ((c == CR && _in_prev != LF) ||
404-
(c == LF && _in_prev != CR)) {
405-
_in_prev = c;
406-
c = '\n';
407-
} else if ((c == CR && _in_prev == LF) ||
408-
(c == LF && _in_prev == CR)) {
409-
_in_prev = c;
410-
// onto next character
411-
continue;
412-
} else {
413-
_in_prev = c;
414-
}
415-
_buffer[i++] = c;
416-
_buffer[i] = 0;
417-
418-
// Check for oob data
419-
struct oob *oob = _oobs;
420-
while (oob) {
421-
if (i == (int)oob->len && memcmp(
422-
oob->prefix, _buffer, oob->len) == 0) {
423-
debug_if(_dbg_on, "AT! %s\r\n", oob->prefix);
424-
oob->cb();
425-
return true;
426-
}
427-
oob = oob->next;
428-
}
429-
430-
// Clear the buffer when we hit a newline or ran out of space
431-
// running out of space usually means we ran into binary data
432-
if (((i + 1) >= _buffer_size) || (c == '\n')) {
433-
debug_if(_dbg_on, "AT< %s", _buffer);
434-
i = 0;
435-
}
436-
}
398+
int pre_count = _oob_cb_count;
399+
recv(NULL);
400+
return _oob_cb_count != pre_count;
437401
}
438402

439403
}

platform/ATCmdParser.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ class ATCmdParser : private NonCopyable<ATCmdParser> {
6666
// Parsing information
6767
const char *_output_delimiter;
6868
int _output_delim_size;
69+
int _oob_cb_count;
6970
char _in_prev;
7071
bool _dbg_on;
7172
bool _aborted;
@@ -91,7 +92,7 @@ class ATCmdParser : private NonCopyable<ATCmdParser> {
9192
*/
9293
ATCmdParser(FileHandle *fh, const char *output_delimiter = "\r",
9394
int buffer_size = 256, int timeout = 8000, bool debug = false)
94-
: _fh(fh), _buffer_size(buffer_size), _in_prev(0), _oobs(NULL)
95+
: _fh(fh), _buffer_size(buffer_size), _oob_cb_count(0), _in_prev(0), _oobs(NULL)
9596
{
9697
_buffer = new char[buffer_size];
9798
set_timeout(timeout);

0 commit comments

Comments
 (0)