Parser for AT commands and similar protocols

Dependencies:   BufferedSerial

Dependents:   ESP8266 Final_Project_2 Final_Project CHEN_Final_Project

Files at this revision

API Documentation at this revision

Comitter:
geky
Date:
Wed Jul 15 22:39:25 2015 +0000
Child:
1:66a14afe650a
Commit message:
Initial Commit

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
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ATParser.cpp	Wed Jul 15 22:39:25 2015 +0000
@@ -0,0 +1,136 @@
+/* Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @section DESCRIPTION
+ *
+ * Parser for the AT command syntax
+ *
+ */
+ 
+#include "ATParser.h"
+#include <cstdarg>
+
+// This can be defined to assist in debugging
+#define AT_ECHO 1
+
+
+// getc/putc handling with timeouts
+int ATParser::_putc(char c) {
+    Timer timer;
+    timer.start();
+    
+    while (true) {
+        if (_serial->writeable())
+            return _serial->putc(c);
+            
+        if (timer.read_ms() > _timeout)
+            return -1;
+    }
+}
+
+int ATParser::_getc() {
+    Timer timer;
+    timer.start();
+    
+    while (true) {
+        if (_serial->readable())
+            return _serial->getc();
+            
+        if (timer.read_ms() > _timeout)
+            return -1;
+    }
+}
+
+void ATParser::_flush() {
+    while (_serial->readable())
+        _serial->getc();
+}
+
+// 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)
+            return false;
+    }
+    
+    // Finish with newline
+    if (_putc('\r') < 0 ||
+        _putc('\n') < 0)
+        return false;
+    
+#ifdef AT_ECHO
+    printf("AT> %s\r\n", line);
+#endif
+
+    return true;
+}
+
+bool ATParser::_getline(int size, char *line) {
+    for (int i = 0; i < size; i++) {
+        int c = _getc();
+            
+                if (c < 0)
+                        return false;
+        
+        // Finish if newline
+        if (c == '\r') {
+            if (_getc() != '\n')
+                return false;
+            
+            line[i] = 0;      
+#ifdef AT_ECHO
+            printf("AT< %s\r\n", line);
+#endif
+            return true;
+        }
+        
+        line[i] = c;
+    }
+    
+    // Ran out of space
+    return false;
+}      
+
+ 
+bool ATParser::command(const char *command, const char *response, ...) {
+    va_list args;
+    va_start(args, response);
+    
+    _flush();
+    
+    // Create and send command
+    if (vsprintf(_buffer, command, args) < 0 ||
+        !_putline(_buffer)) {
+        va_end(args);
+        return false;
+    }
+       
+    // Determine number of parameters
+    // this is needed for scanf's funky error signaling
+    int params = 0;
+    for (int i = 0; response[i]; i++) {
+        if (response[i] == '%' && response[i+1] != '%')
+            params++;
+    }
+    
+    // Recieve and parse response
+    if (!_getline(_buffer_size, _buffer) ||
+        vsscanf(_buffer, response, args) < params) {
+        va_end(args);
+        return false;
+    }
+ 
+    va_end(args);
+    return true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ATParser.h	Wed Jul 15 22:39:25 2015 +0000
@@ -0,0 +1,88 @@
+/* Copyright (c) 2015 ARM Limited
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ * @section DESCRIPTION
+ *
+ * Parser for the AT command syntax
+ *
+ */
+ 
+#include "mbed.h"
+
+ 
+/**
+* The ATParser class wraps information about the serial in use
+*/
+class ATParser {
+private:
+    // Serial information
+    RawSerial *_serial;
+    int _buffer_size;
+    char *_buffer;
+    int _timeout;
+    
+    // Helper methods for putc/getc with timeout
+    int _putc(char c);
+    int _getc();
+    
+    // Flush used to clear serial connection
+    void _flush();
+    
+    // Helper methods for reading/writing lines with 
+    // timeout and buffer limitations
+    bool _putline(const char *line);
+    bool _getline(int size, char *line);
+
+public:
+    /**
+    * Constructor
+    *
+    * @param serial serial interface to use for AT commands
+    * @param timeout timeout of the connection
+    */
+    ATParser(RawSerial *serial, int buffer_size = 256, int timeout = 3000) :
+            _serial(serial),
+            _buffer_size(buffer_size),
+            _timeout(timeout) {
+        _buffer = new char[buffer_size];
+    }
+    
+    /**
+    * Destructor
+    */
+    ~ATParser() {
+        delete [] _buffer;
+    }
+    
+    /**
+    * Allows timeout to be changed between commands
+    *
+    * @param timeout timeout of the connection
+    */
+    void setTimeout(int timeout) {
+        _timeout = timeout;
+    }
+            
+    /**
+    * Issue AT commands with specified command and expected response
+    *
+    * @param command printf-like format string of command to send
+    * @param response scanf-like format string of response to parse
+    * @param ... all printf-like arguments to insert into command followed by 
+    *            all scanf-like pointers to destinations for response values
+    * @return true if response is successfully matched
+    */
+    bool command(const char *command, const char *response, ...);
+};
+    
\ No newline at end of file