Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of ATParser by
Diff: ATParser.cpp
- Revision:
- 10:553f9ffaf657
- Parent:
- 9:9bcb87c27208
- Child:
- 11:fd406d4c4227
--- a/ATParser.cpp Mon Jul 20 21:28:39 2015 +0000
+++ b/ATParser.cpp Sun Jul 26 21:53:28 2015 +0000
@@ -17,97 +17,102 @@
* Parser for the AT command syntax
*
*/
-
+
#include "ATParser.h"
-
-// This can be defined to assist in debugging
-#define AT_ECHO 1
+#include "mbed_debug.h"
// getc/putc handling with timeouts
-int ATParser::putc(char c) {
+int ATParser::putc(char c)
+{
Timer timer;
timer.start();
-
+
while (true) {
- if (_serial->writeable())
+ if (_serial->writeable()) {
return _serial->putc(c);
-
- if (timer.read_ms() > _timeout)
+ }
+ if (timer.read_ms() > _timeout) {
return -1;
+ }
}
}
-int ATParser::getc() {
+int ATParser::getc()
+{
Timer timer;
timer.start();
-
+
while (true) {
- if (_serial->readable())
+ if (_serial->readable()) {
return _serial->getc();
-
- if (timer.read_ms() > _timeout)
+ }
+ if (timer.read_ms() > _timeout) {
return -1;
+ }
}
}
-void ATParser::flush() {
- while (_serial->readable())
+void ATParser::flush()
+{
+ while (_serial->readable()) {
_serial->getc();
+ }
}
// read/write handling with timeouts
-int ATParser::write(const char *data, int size) {
- int i;
- for (i = 0; i < size; i++) {
- if (putc(data[i]) < 0)
+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;
- for (i = 0; i < size; i++) {
+int ATParser::read(char *data, int size)
+{
+ int i = 0;
+ for ( ; i < size; i++) {
int c = getc();
- if (c < 0)
+ 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)
+int ATParser::vprintf(const char *format, va_list args)
+{
+ if (vsprintf(_buffer, format, args) < 0) {
return false;
-
- int i;
- for (i = 0; _buffer[i]; i++) {
- if (putc(_buffer[i]) < 0)
+ }
+ 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) {
+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] != '*') {
+ if (format[i] == '%' && format[i+1] != '%' && format[i+1] != '*') {
_buffer[offset++] = '%';
_buffer[offset++] = '*';
i++;
@@ -115,40 +120,40 @@
_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).
+ // 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)
+ if (j+1 >= _buffer_size - offset) {
return false;
-
+ }
// Recieve next character
int c = getc();
- if (c < 0)
+ 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
@@ -160,30 +165,31 @@
// Command parsing with line handling
-bool ATParser::vsend(const char *command, va_list args) {
+bool ATParser::vsend(const char *command, va_list args)
+{
// Create and send command
- if (vsprintf(_buffer, command, args) < 0)
+ if (vsprintf(_buffer, command, args) < 0) {
return false;
-
+ }
for (int i = 0; _buffer[i]; i++) {
- if (putc(_buffer[i]) < 0)
+ if (putc(_buffer[i]) < 0) {
return false;
+ }
}
-
+
// Finish with newline
for (int i = 0; _delimiter[i]; i++) {
- if (putc(_delimiter[i]) < 0)
+ if (putc(_delimiter[i]) < 0) {
return false;
+ }
}
-
-#ifdef AT_ECHO
- ::printf("AT> %s\r\n", _buffer);
-#endif
-
+
+ debug_if(at_echo, "AT> %s\r\n", _buffer);
return true;
}
-bool ATParser::vrecv(const char *response, va_list args) {
+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
@@ -192,14 +198,12 @@
// 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] != '*') {
+ } else if (response[i] == '%' && response[i+1] != '%' && response[i+1] != '*') {
_buffer[offset++] = '%';
_buffer[offset++] = '*';
i++;
@@ -207,73 +211,70 @@
_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).
+ // 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)
+ if (j+1 >= _buffer_size - offset) {
return false;
-
+ }
// Recieve next character
int c = getc();
- if (c < 0)
+ if (c < 0) {
return false;
-
+ }
_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) {
-#ifdef AT_ECHO
- ::printf("AT= %s\r\n", _buffer+offset);
-#endif
+ debug_if(at_echo, "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
if (strcmp(&_buffer[offset + j-_delim_size], _delimiter) == 0) {
-#ifdef AT_ECHO
- ::printf("AT< %s", _buffer+offset);
-#endif
+ debug_if(at_echo, "AT< %s", _buffer+offset);
j = 0;
}
}
}
-
+
return true;
}
// Mapping to vararg functions
-int ATParser::printf(const char *format, ...) {
+int ATParser::printf(const char *format, ...)
+{
va_list args;
va_start(args, format);
int res = vprintf(format, args);
@@ -281,7 +282,8 @@
return res;
}
-int ATParser::scanf(const char *format, ...) {
+int ATParser::scanf(const char *format, ...)
+{
va_list args;
va_start(args, format);
int res = vscanf(format, args);
@@ -289,7 +291,8 @@
return res;
}
-bool ATParser::send(const char *command, ...) {
+bool ATParser::send(const char *command, ...)
+{
va_list args;
va_start(args, command);
bool res = vsend(command, args);
@@ -297,7 +300,8 @@
return res;
}
-bool ATParser::recv(const char *response, ...) {
+bool ATParser::recv(const char *response, ...)
+{
va_list args;
va_start(args, response);
bool res = vrecv(response, args);
