Official reference client implementation for Cumulocity SmartREST on u-blox C027.

Dependencies:   C027_Support C12832 LM75B MMA7660 MbedSmartRest mbed-rtos mbed

Fork of MbedSmartRestMain by Vincent Wochnik

Revision:
94:61d44636f020
Child:
95:010b0f7a0a1a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/operation/ControlParser.cpp	Mon Apr 20 15:04:23 2015 +0000
@@ -0,0 +1,216 @@
+#include <stdio.h>
+#include <string.h>
+#include "ControlParser.h"
+#include "DeviceFeedback.h"
+#include "logging.h"
+
+void ControlParser::handleControlMessage(const char *buf)
+{
+        if (buf == NULL) return;
+        const char *p = skipHTTPHeader(buf);
+        Token tok;
+        ptrPF = &ControlParser::parseGetOp;
+        do {
+                p = lex(p, tok);
+                (this->*ptrPF)(tok);
+        } while (*p);
+}
+
+void ControlParser::parseGetOp(Token& tok)
+{
+        if (tok.type == Token::INT && strncmp("211", tok.p, tok.len)==0) {
+                opType = 211;
+                ptrPF = &ControlParser::parseDeviceId;
+        } else {
+                parseError(tok);
+        }
+}
+
+void ControlParser::parseDeviceId(Token& tok)
+{
+        if (tok.type == Token::INT) {
+                ptrPF = &ControlParser::parseOpId;
+        } else {
+                parseError(tok);
+        }
+}
+
+void ControlParser::parseOpId(Token& tok)
+{
+        if (tok.type == Token::INT) {
+                if (opType == 211) {
+                        sscanf(tok.p, "%ld", &op.identifier);
+                        ptrPF = &ControlParser::parseOpState;
+                } else if (opType >= 220 && opType <= 222){
+                        ptrPF = &ControlParser::parseOpData;
+                } else {
+                        parseError(tok);
+                }
+        } else {
+                parseError(tok);
+        }
+}
+
+void ControlParser::parseOpState(Token& tok)
+{
+        if (tok.type == Token::STRING) {
+                if (strncmp(strPending, tok.p, tok.len)==0) {
+                        Operation *p = opool.alloc();
+                        p->identifier = op.identifier;
+                        p->state = OPERATION_EXECUTING;
+                        opool.put(p);
+                        ptrPF = &ControlParser::parseOpType;
+                } else {
+                        parseError(tok);
+                }
+        } else {
+                parseError(tok);
+        }
+}
+
+void ControlParser::parseOpType(Token& tok)
+{
+        if (tok.type == Token::INT) {
+                sscanf(tok.p, "%u", &opType);
+                if (opType >= 220 && opType <= 222) {
+                        ptrPF = &ControlParser::parseDeviceId;
+                } else {
+                        parseError(tok);
+                }
+        } else {
+                parseError(tok);
+        }
+}
+
+void ControlParser::parseOpData(Token& tok)
+{
+        bool ret = true;
+        if (opType == 220) {
+                if (strncmp("CLOSED", tok.p, tok.len) == 0) {
+                        closeRelay();
+                } else if (strncmp("OPEN", tok.p, tok.len) == 0) {
+                        openRelay();
+                } else {
+                        aError("Relay op (%.*s)\n", (int)tok.len, tok.p);
+                        ret = false;
+                }
+        } else if (opType == 221) {
+                char line[30] = {0};
+                size_t num = tok.len<30 ? tok.len : 30;
+                if (tok.type == Token::STRING)
+                        strncpyEscape(line, tok.p, num);
+                else
+                        strncpy(line, tok.p, num);
+                _lcdDisplay.setFirstLine(line);
+        } else if (opType == 222) {
+                char config[128];
+                size_t num = tok.len<128 ? tok.len : 128;
+                strncpy(config, tok.p, num);
+                ret = _configSync.updateConfiguration(config);
+        } else {
+                parseError(tok);
+                return;
+        }
+        Operation *p = opool.alloc();
+        p->identifier = op.identifier;
+        p->state = ret ? OPERATION_SUCCESSFUL : OPERATION_FAILED;
+        opool.put(p);
+        ptrPF = &ControlParser::parseGetOpOrBayeuxAdvice;
+}
+
+void ControlParser::parseGetOpOrBayeuxAdvice(Token& tok)
+{
+        if (strncmp("211", tok.p, tok.len) == 0) {
+                parseGetOp(tok);
+        } else if (strncmp("86", tok.p, tok.len) == 0) {
+                parseBayeuxAdvice(tok);
+        } else {
+                parseError(tok);
+        }
+}
+
+void ControlParser::parseBayeuxAdvice(Token& tok)
+{
+        if (strncmp("86", tok.p, tok.len) == 0) {
+                ptrPF = &ControlParser::parseAdviceTimeout;
+        } else {
+                parseError(tok);
+        }
+}
+
+void ControlParser::parseAdviceTimeout(Token& tok)
+{
+        if (tok.type == Token::NONE) {
+                bayeuxTimeout = -1;
+                ptrPF = &ControlParser::parseAdviceInterval;
+        } else if (tok.type == Token::INT) {
+                sscanf(tok.p, "%d", &bayeuxTimeout);
+                ptrPF = &ControlParser::parseAdviceInterval;
+        } else {
+                parseError(tok);
+        }
+}
+
+void ControlParser::parseAdviceInterval(Token& tok)
+{
+        if (tok.type == Token::NONE) {
+                bayeuxInterval = -1;
+                ptrPF = &ControlParser::parseUnknownInt;
+        } else if (tok.type == Token::INT) {
+                sscanf(tok.p, "%d", &bayeuxInterval);
+                ptrPF = &ControlParser::parseUnknownInt;
+        } else {
+                parseError(tok);
+        }
+}
+
+void ControlParser::parseUnknownInt(Token& tok)
+{
+        if (tok.type == Token::INT) {
+                ptrPF = &ControlParser::parseAdvicePolicy;
+        } else {
+                parseError(tok);
+        }
+}
+
+void ControlParser::parseAdvicePolicy(Token& tok)
+{
+        if (tok.type == Token::STRING) {
+                if (strncmp("retry", tok.p, tok.len) == 0) {
+                        bayeuxAdvice = BA_RETRY;
+                } else if (strncmp("handshake", tok.p, tok.len) == 0) {
+                        bayeuxAdvice = BA_HANDSHAKE;
+                } else if (strncmp("none", tok.p, tok.len) == 0) {
+                        bayeuxAdvice = BA_NONE;
+                } else {
+                        parseError(tok);
+                }
+        } else {
+                parseError(tok);
+        }
+}
+
+void ControlParser::parseError(Token& tok)
+{
+        aError("(%d) %.*s\n", tok.type, (int)tok.len, tok.p);
+        ptrPF = &ControlParser::parseRecover;
+}
+
+void ControlParser::parseRecover(Token& tok)
+{
+        if (tok.type == Token::INT) {
+                int i = 0;
+                sscanf(tok.p, "%d", &i);
+                if (i == 211) {
+                        parseGetOp(tok);
+                } else if (i >= 220 && i <= 222) {
+                        parseOpType(tok);
+                } else if (i == 86) {
+                        parseBayeuxAdvice(tok);
+                } else {
+                        ptrPF = &ControlParser::parseRecover;
+                }
+        } else {
+                ptrPF = &ControlParser::parseRecover;
+        }
+}