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

Committer:
xinlei
Date:
Thu May 07 09:57:55 2015 +0000
Revision:
99:e369fc75c000
Parent:
96:5dfdc8568e9f
Child:
101:dbcd3bc51758
prepare for v2.1rc3.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
xinlei 94:61d44636f020 1 #include <stdio.h>
xinlei 94:61d44636f020 2 #include <string.h>
xinlei 94:61d44636f020 3 #include "ControlParser.h"
xinlei 94:61d44636f020 4 #include "DeviceFeedback.h"
xinlei 96:5dfdc8568e9f 5 #include "LCDDisplay.h"
xinlei 94:61d44636f020 6 #include "logging.h"
xinlei 94:61d44636f020 7
xinlei 99:e369fc75c000 8 void ControlParser::parse(const char *buf)
xinlei 94:61d44636f020 9 {
xinlei 94:61d44636f020 10 if (buf == NULL) return;
xinlei 94:61d44636f020 11 const char *p = skipHTTPHeader(buf);
xinlei 99:e369fc75c000 12 if (p == NULL) return;
xinlei 94:61d44636f020 13 Token tok;
xinlei 94:61d44636f020 14 ptrPF = &ControlParser::parseGetOp;
xinlei 94:61d44636f020 15 do {
xinlei 94:61d44636f020 16 p = lex(p, tok);
xinlei 94:61d44636f020 17 (this->*ptrPF)(tok);
xinlei 94:61d44636f020 18 } while (*p);
xinlei 94:61d44636f020 19 }
xinlei 94:61d44636f020 20
xinlei 94:61d44636f020 21 void ControlParser::parseGetOp(Token& tok)
xinlei 94:61d44636f020 22 {
xinlei 94:61d44636f020 23 if (tok.type == Token::INT && strncmp("211", tok.p, tok.len)==0) {
xinlei 94:61d44636f020 24 opType = 211;
xinlei 94:61d44636f020 25 ptrPF = &ControlParser::parseDeviceId;
xinlei 94:61d44636f020 26 } else {
xinlei 94:61d44636f020 27 parseError(tok);
xinlei 94:61d44636f020 28 }
xinlei 94:61d44636f020 29 }
xinlei 94:61d44636f020 30
xinlei 94:61d44636f020 31 void ControlParser::parseDeviceId(Token& tok)
xinlei 94:61d44636f020 32 {
xinlei 94:61d44636f020 33 if (tok.type == Token::INT) {
xinlei 94:61d44636f020 34 ptrPF = &ControlParser::parseOpId;
xinlei 94:61d44636f020 35 } else {
xinlei 94:61d44636f020 36 parseError(tok);
xinlei 94:61d44636f020 37 }
xinlei 94:61d44636f020 38 }
xinlei 94:61d44636f020 39
xinlei 94:61d44636f020 40 void ControlParser::parseOpId(Token& tok)
xinlei 94:61d44636f020 41 {
xinlei 94:61d44636f020 42 if (tok.type == Token::INT) {
xinlei 94:61d44636f020 43 if (opType == 211) {
xinlei 94:61d44636f020 44 sscanf(tok.p, "%ld", &op.identifier);
xinlei 94:61d44636f020 45 ptrPF = &ControlParser::parseOpState;
xinlei 94:61d44636f020 46 } else if (opType >= 220 && opType <= 222){
xinlei 94:61d44636f020 47 ptrPF = &ControlParser::parseOpData;
xinlei 94:61d44636f020 48 } else {
xinlei 94:61d44636f020 49 parseError(tok);
xinlei 94:61d44636f020 50 }
xinlei 94:61d44636f020 51 } else {
xinlei 94:61d44636f020 52 parseError(tok);
xinlei 94:61d44636f020 53 }
xinlei 94:61d44636f020 54 }
xinlei 94:61d44636f020 55
xinlei 94:61d44636f020 56 void ControlParser::parseOpState(Token& tok)
xinlei 94:61d44636f020 57 {
xinlei 94:61d44636f020 58 if (tok.type == Token::STRING) {
xinlei 94:61d44636f020 59 if (strncmp(strPending, tok.p, tok.len)==0) {
xinlei 94:61d44636f020 60 Operation *p = opool.alloc();
xinlei 99:e369fc75c000 61 if (p) {
xinlei 99:e369fc75c000 62 p->identifier = op.identifier;
xinlei 99:e369fc75c000 63 p->state = OPERATION_EXECUTING;
xinlei 99:e369fc75c000 64 opool.put(p);
xinlei 99:e369fc75c000 65 }
xinlei 94:61d44636f020 66 ptrPF = &ControlParser::parseOpType;
xinlei 94:61d44636f020 67 } else {
xinlei 94:61d44636f020 68 parseError(tok);
xinlei 94:61d44636f020 69 }
xinlei 94:61d44636f020 70 } else {
xinlei 94:61d44636f020 71 parseError(tok);
xinlei 94:61d44636f020 72 }
xinlei 94:61d44636f020 73 }
xinlei 94:61d44636f020 74
xinlei 94:61d44636f020 75 void ControlParser::parseOpType(Token& tok)
xinlei 94:61d44636f020 76 {
xinlei 94:61d44636f020 77 if (tok.type == Token::INT) {
xinlei 95:010b0f7a0a1a 78 sscanf(tok.p, "%hu", &opType);
xinlei 94:61d44636f020 79 if (opType >= 220 && opType <= 222) {
xinlei 94:61d44636f020 80 ptrPF = &ControlParser::parseDeviceId;
xinlei 94:61d44636f020 81 } else {
xinlei 94:61d44636f020 82 parseError(tok);
xinlei 94:61d44636f020 83 }
xinlei 94:61d44636f020 84 } else {
xinlei 94:61d44636f020 85 parseError(tok);
xinlei 94:61d44636f020 86 }
xinlei 94:61d44636f020 87 }
xinlei 94:61d44636f020 88
xinlei 94:61d44636f020 89 void ControlParser::parseOpData(Token& tok)
xinlei 94:61d44636f020 90 {
xinlei 94:61d44636f020 91 bool ret = true;
xinlei 94:61d44636f020 92 if (opType == 220) {
xinlei 94:61d44636f020 93 if (strncmp("CLOSED", tok.p, tok.len) == 0) {
xinlei 94:61d44636f020 94 closeRelay();
xinlei 94:61d44636f020 95 } else if (strncmp("OPEN", tok.p, tok.len) == 0) {
xinlei 94:61d44636f020 96 openRelay();
xinlei 94:61d44636f020 97 } else {
xinlei 94:61d44636f020 98 aError("Relay op (%.*s)\n", (int)tok.len, tok.p);
xinlei 94:61d44636f020 99 ret = false;
xinlei 94:61d44636f020 100 }
xinlei 94:61d44636f020 101 } else if (opType == 221) {
xinlei 94:61d44636f020 102 char line[30] = {0};
xinlei 96:5dfdc8568e9f 103 size_t num = tok.len < 30 ? tok.len : 30;
xinlei 94:61d44636f020 104 if (tok.type == Token::STRING)
xinlei 94:61d44636f020 105 strncpyEscape(line, tok.p, num);
xinlei 94:61d44636f020 106 else
xinlei 94:61d44636f020 107 strncpy(line, tok.p, num);
xinlei 96:5dfdc8568e9f 108 LCDDisplay::inst().setFirstLine(line);
xinlei 94:61d44636f020 109 } else if (opType == 222) {
xinlei 95:010b0f7a0a1a 110 char config[128] = {0};
xinlei 96:5dfdc8568e9f 111 size_t num = tok.len < 127 ? tok.len : 127;
xinlei 94:61d44636f020 112 strncpy(config, tok.p, num);
xinlei 94:61d44636f020 113 ret = _configSync.updateConfiguration(config);
xinlei 94:61d44636f020 114 } else {
xinlei 94:61d44636f020 115 parseError(tok);
xinlei 94:61d44636f020 116 return;
xinlei 94:61d44636f020 117 }
xinlei 94:61d44636f020 118 Operation *p = opool.alloc();
xinlei 95:010b0f7a0a1a 119 if (p) {
xinlei 95:010b0f7a0a1a 120 p->identifier = op.identifier;
xinlei 95:010b0f7a0a1a 121 p->state = ret ? OPERATION_SUCCESSFUL : OPERATION_FAILED;
xinlei 95:010b0f7a0a1a 122 opool.put(p);
xinlei 95:010b0f7a0a1a 123 }
xinlei 94:61d44636f020 124 ptrPF = &ControlParser::parseGetOpOrBayeuxAdvice;
xinlei 94:61d44636f020 125 }
xinlei 94:61d44636f020 126
xinlei 94:61d44636f020 127 void ControlParser::parseGetOpOrBayeuxAdvice(Token& tok)
xinlei 94:61d44636f020 128 {
xinlei 94:61d44636f020 129 if (strncmp("211", tok.p, tok.len) == 0) {
xinlei 94:61d44636f020 130 parseGetOp(tok);
xinlei 94:61d44636f020 131 } else if (strncmp("86", tok.p, tok.len) == 0) {
xinlei 94:61d44636f020 132 parseBayeuxAdvice(tok);
xinlei 94:61d44636f020 133 } else {
xinlei 94:61d44636f020 134 parseError(tok);
xinlei 94:61d44636f020 135 }
xinlei 94:61d44636f020 136 }
xinlei 94:61d44636f020 137
xinlei 94:61d44636f020 138 void ControlParser::parseBayeuxAdvice(Token& tok)
xinlei 94:61d44636f020 139 {
xinlei 94:61d44636f020 140 if (strncmp("86", tok.p, tok.len) == 0) {
xinlei 99:e369fc75c000 141 ptrPF = &ControlParser::parseRowNumber;
xinlei 99:e369fc75c000 142 } else {
xinlei 99:e369fc75c000 143 parseError(tok);
xinlei 99:e369fc75c000 144 }
xinlei 99:e369fc75c000 145 }
xinlei 99:e369fc75c000 146
xinlei 99:e369fc75c000 147 void ControlParser::parseRowNumber(Token& tok)
xinlei 99:e369fc75c000 148 {
xinlei 99:e369fc75c000 149 if (tok.type == Token::INT || tok.type == Token::NONE) {
xinlei 94:61d44636f020 150 ptrPF = &ControlParser::parseAdviceTimeout;
xinlei 94:61d44636f020 151 } else {
xinlei 94:61d44636f020 152 parseError(tok);
xinlei 94:61d44636f020 153 }
xinlei 94:61d44636f020 154 }
xinlei 94:61d44636f020 155
xinlei 94:61d44636f020 156 void ControlParser::parseAdviceTimeout(Token& tok)
xinlei 94:61d44636f020 157 {
xinlei 94:61d44636f020 158 if (tok.type == Token::NONE) {
xinlei 94:61d44636f020 159 bayeuxTimeout = -1;
xinlei 94:61d44636f020 160 ptrPF = &ControlParser::parseAdviceInterval;
xinlei 94:61d44636f020 161 } else if (tok.type == Token::INT) {
xinlei 94:61d44636f020 162 sscanf(tok.p, "%d", &bayeuxTimeout);
xinlei 94:61d44636f020 163 ptrPF = &ControlParser::parseAdviceInterval;
xinlei 94:61d44636f020 164 } else {
xinlei 94:61d44636f020 165 parseError(tok);
xinlei 94:61d44636f020 166 }
xinlei 94:61d44636f020 167 }
xinlei 94:61d44636f020 168
xinlei 94:61d44636f020 169 void ControlParser::parseAdviceInterval(Token& tok)
xinlei 94:61d44636f020 170 {
xinlei 94:61d44636f020 171 if (tok.type == Token::NONE) {
xinlei 99:e369fc75c000 172 bayeuxInterval = 0;
xinlei 99:e369fc75c000 173 ptrPF = &ControlParser::parseAdvicePolicy;
xinlei 94:61d44636f020 174 } else if (tok.type == Token::INT) {
xinlei 94:61d44636f020 175 sscanf(tok.p, "%d", &bayeuxInterval);
xinlei 94:61d44636f020 176 ptrPF = &ControlParser::parseAdvicePolicy;
xinlei 94:61d44636f020 177 } else {
xinlei 94:61d44636f020 178 parseError(tok);
xinlei 94:61d44636f020 179 }
xinlei 94:61d44636f020 180 }
xinlei 94:61d44636f020 181
xinlei 94:61d44636f020 182 void ControlParser::parseAdvicePolicy(Token& tok)
xinlei 94:61d44636f020 183 {
xinlei 94:61d44636f020 184 if (tok.type == Token::STRING) {
xinlei 94:61d44636f020 185 if (strncmp("retry", tok.p, tok.len) == 0) {
xinlei 94:61d44636f020 186 bayeuxAdvice = BA_RETRY;
xinlei 94:61d44636f020 187 } else if (strncmp("handshake", tok.p, tok.len) == 0) {
xinlei 94:61d44636f020 188 bayeuxAdvice = BA_HANDSHAKE;
xinlei 94:61d44636f020 189 } else if (strncmp("none", tok.p, tok.len) == 0) {
xinlei 94:61d44636f020 190 bayeuxAdvice = BA_NONE;
xinlei 94:61d44636f020 191 } else {
xinlei 94:61d44636f020 192 parseError(tok);
xinlei 94:61d44636f020 193 }
xinlei 94:61d44636f020 194 } else {
xinlei 94:61d44636f020 195 parseError(tok);
xinlei 94:61d44636f020 196 }
xinlei 94:61d44636f020 197 }
xinlei 94:61d44636f020 198
xinlei 94:61d44636f020 199 void ControlParser::parseError(Token& tok)
xinlei 94:61d44636f020 200 {
xinlei 94:61d44636f020 201 aError("(%d) %.*s\n", tok.type, (int)tok.len, tok.p);
xinlei 99:e369fc75c000 202 parseRecover(tok);
xinlei 94:61d44636f020 203 }
xinlei 94:61d44636f020 204
xinlei 94:61d44636f020 205 void ControlParser::parseRecover(Token& tok)
xinlei 94:61d44636f020 206 {
xinlei 94:61d44636f020 207 if (tok.type == Token::INT) {
xinlei 94:61d44636f020 208 int i = 0;
xinlei 94:61d44636f020 209 sscanf(tok.p, "%d", &i);
xinlei 94:61d44636f020 210 if (i == 211) {
xinlei 94:61d44636f020 211 parseGetOp(tok);
xinlei 94:61d44636f020 212 } else if (i >= 220 && i <= 222) {
xinlei 94:61d44636f020 213 parseOpType(tok);
xinlei 94:61d44636f020 214 } else if (i == 86) {
xinlei 94:61d44636f020 215 parseBayeuxAdvice(tok);
xinlei 94:61d44636f020 216 } else {
xinlei 94:61d44636f020 217 ptrPF = &ControlParser::parseRecover;
xinlei 94:61d44636f020 218 }
xinlei 94:61d44636f020 219 } else {
xinlei 94:61d44636f020 220 ptrPF = &ControlParser::parseRecover;
xinlei 94:61d44636f020 221 }
xinlei 94:61d44636f020 222 }