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
Diff: operation/ControlParser.cpp
- 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; + } +}