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

operation/ControlParser.cpp

Committer:
xinlei
Date:
2015-04-22
Revision:
95:010b0f7a0a1a
Parent:
94:61d44636f020
Child:
96:5dfdc8568e9f

File content as of revision 95:010b0f7a0a1a:

#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, "%hu", &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] = {0};
                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();
        if (p) {
                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;
        }
}