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:
Wed May 13 13:03:20 2015 +0000
Revision:
108:f1ee3e1eb126
Parent:
107:fc5f25f0e0d5
Child:
113:3872569be2af
ConfigSync is now singleton

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