Parser for AT commands and similar protocols

Dependencies:   BufferedSerial

Revision:
5:26bc9255b751
Parent:
4:38acbd6f9d9e
Child:
6:51f1171b5ebc
--- a/ATParser.cpp	Fri Jul 17 16:38:44 2015 +0000
+++ b/ATParser.cpp	Fri Jul 17 17:23:57 2015 +0000
@@ -19,7 +19,6 @@
  */
  
 #include "ATParser.h"
-#include <cstdarg>
 
 // This can be defined to assist in debugging
 #define AT_ECHO 1
@@ -102,24 +101,23 @@
     return false;
 }
 
- 
-bool ATParser::command(const char *command, const char *response, ...) {
-    va_list args;
-    va_start(args, response);
-    
+
+// Command parsing with line handling
+bool ATParser::vsend(const char *command, va_list args) {
     flush();
     
     // Create and send command
-    if (command) {
-        if (vsprintf(_buffer, command, args) < 0 ||
-            !_putline(_buffer)) {
-            va_end(args);
-            return false;
-        }
-    }
-    
+    if (vsprintf(_buffer, command, args) < 0)
+        return false;
+    if (!_putline(_buffer))
+        return false;
+        
+    return true;
+}
+
+bool ATParser::vrecv(const char *response, va_list args) {
     // Iterate through each line in the expected response
-    while (response && response[0]) {
+    while (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.
         //
@@ -128,8 +126,8 @@
         int offset = 0;
         
         while (response[i]) {
-            if (memcmp(&response[i-_delim_size], _delimiter, _delim_size) == 0) {
-                i += _delim_size;
+            if (memcmp(&response[i+1-_delim_size], _delimiter, _delim_size) == 0) {
+                i++;
                 break;
             } else if (response[i] == '%' && 
                        response[i+1] != '%' && 
@@ -158,10 +156,8 @@
         // derails us.
         while (true) {
             // Recieve response
-            if (!_getline(_buffer+offset, _buffer_size-offset)) {
-                va_end(args);
+            if (!_getline(_buffer+offset, _buffer_size-offset))
                 return false;
-            }
             
             int count = -1;
             sscanf(_buffer+offset, _buffer, &count);
@@ -184,7 +180,45 @@
             }
         }
     }
- 
-    va_end(args);
+    
+    return true;
+}
+
+bool ATParser::vcommand(const char *command, const char *response, va_list args) {
+    if (command) {
+        if (!vsend(command, args))
+            return false;
+    }
+    
+    if (response) {
+        if (!vrecv(response, args))
+            return false;
+    }
+    
     return true;
 }
+
+// Mapping to vararg functions
+bool ATParser::send(const char *command, ...) {
+    va_list args;
+    va_start(args, command);
+    bool res = vsend(command, args);
+    va_end(args);
+    return res;
+}
+
+bool ATParser::recv(const char *response, ...) {
+    va_list args;
+    va_start(args, response);
+    bool res = vrecv(response, args);
+    va_end(args);
+    return res;
+}
+
+bool ATParser::command(const char *command, const char *response, ...) {
+    va_list args;
+    va_start(args, response);
+    bool res = vcommand(command, response, args);
+    va_end(args);
+    return res;
+}