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:
Mon Aug 10 14:18:05 2015 +0000
Revision:
135:c4009ecaf5c0
Parent:
113:3872569be2af
various clean-ups

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