Parser for AT commands and similar protocols

Dependencies:   BufferedSerial

Dependents:   ESP8266 xdot-passthru Lab_10 Lab9 ... more

Fork of ATParser by NetworkSocketAPI

Files at this revision

API Documentation at this revision

Comitter:
geky
Date:
Mon Jul 20 18:23:54 2015 +0000
Parent:
6:51f1171b5ebc
Child:
8:91515b168c70
Commit message:
Modified response parsing to try every character instead of waiting for newlines. This means the ATParser can now handle trailing binary data in AT commands.

Changed in this revision

ATParser.cpp Show annotated file Show diff for this revision Revisions of this file
ATParser.h Show annotated file Show diff for this revision Revisions of this file
--- a/ATParser.cpp	Fri Jul 17 21:00:23 2015 +0000
+++ b/ATParser.cpp	Mon Jul 20 18:23:54 2015 +0000
@@ -56,6 +56,7 @@
         _serial->getc();
 }
 
+
 // read/write handling with timeouts
 int ATParser::write(const char *data, int size) {
     int i;
@@ -84,10 +85,16 @@
 }
 
 
-// getline/putline handling with timeouts/bounds checking
-bool ATParser::_putline(const char *line) {    
-    for (int i = 0; line[i]; i++) {
-        if (putc(line[i]) < 0)
+// Command parsing with line handling
+bool ATParser::vsend(const char *command, va_list args) {
+    flush();
+    
+    // Create and send command
+    if (vsprintf(_buffer, command, args) < 0)
+        return false;
+        
+    for (int i = 0; _buffer[i]; i++) {
+        if (putc(_buffer[i]) < 0)
             return false;
     }
     
@@ -98,46 +105,8 @@
     }
     
 #ifdef AT_ECHO
-    printf("AT> %s\r\n", line);
+    printf("AT> %s\r\n", _buffer);
 #endif
-    
-    return true;
-}
-
-bool ATParser::_getline(char *line, int size) {
-    int i = 0;
-    
-    while (i < size) {
-        int c = getc();
-        if (c < 0)
-            return false;
-            
-        line[i++] = c;
-        
-        // Finish when we hit a newline
-        if (memcmp(&line[i-_delim_size], _delimiter, _delim_size) == 0) {
-            line[i-_delim_size] = 0;
-#ifdef AT_ECHO            
-            printf("AT< %s\r\n", line);
-#endif
-            return true;
-        }
-    }
-    
-    // Ran out of space
-    return false;
-}
-
-
-// Command parsing with line handling
-bool ATParser::vsend(const char *command, va_list args) {
-    flush();
-    
-    // Create and send command
-    if (vsprintf(_buffer, command, args) < 0)
-        return false;
-    if (!_putline(_buffer))
-        return false;
         
     return true;
 }
@@ -146,9 +115,9 @@
     // Iterate through each line in the expected response
     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.
+        // add the line's null terminator and clobber value-matches with asterisks.
         //
-        // We just use the beginning of the buffer to avoid unecessary allocations.
+        // We just use the beginning of the buffer to avoid unnecessary allocations.
         int i = 0;
         int offset = 0;
         
@@ -181,16 +150,26 @@
         //
         // We keep trying the match until we succeed or some other error
         // derails us.
-        while (true) {
-            // Recieve response
-            if (!_getline(_buffer+offset, _buffer_size-offset))
+        int j = 0;
+        
+        while (j+1 < _buffer_size - offset) {
+            // Recieve next character
+            int c = getc();
+            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 is matched
-            if (count >= 0 && (_buffer+offset)[count] == 0) {
+            // 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
                 // Reuse the front end of the buffer
                 memcpy(_buffer, response, i);
                 _buffer[i] = 0;
@@ -202,6 +181,14 @@
                 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
+                j = 0;
+            }
         }
     }
     
@@ -222,6 +209,7 @@
     return true;
 }
 
+
 // Mapping to vararg functions
 bool ATParser::send(const char *command, ...) {
     va_list args;
--- a/ATParser.h	Fri Jul 17 21:00:23 2015 +0000
+++ b/ATParser.h	Mon Jul 20 18:23:54 2015 +0000
@@ -37,12 +37,7 @@
     
     // Parsing information
     const char *_delimiter;
-    int _delim_size;    
-    
-    // Helper methods for reading/writing lines with 
-    // timeout and buffer limitations
-    bool _putline(const char *line);
-    bool _getline(char *line, int size);
+    int _delim_size;
 
 public:
     /**