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);