Parser for AT commands and similar protocols

Dependencies:   BufferedSerial

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