Dependencies:
BufferedSerial
Diff: ATParser.cpp
- Revision:
- 0:c741e144517c
- Child:
- 1:66a14afe650a
diff -r 000000000000 -r c741e144517c ATParser.cpp
--- /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;
+}