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:
vwochnik
Date:
Sun Nov 30 19:34:49 2014 +0000
Revision:
67:c360a2b2c948
Parent:
65:a62dbef2f924
Child:
68:0dc778a16d0d
refactor credentials persistence, add factory reset upon fire press button

Who changed what in which revision?

UserRevisionLine numberNew contents of line
vwochnik 57:4af5f1bec3a6 1 #include "OperationSupport.h"
vwochnik 59:f96be79feccd 2 #include <string.h>
vwochnik 63:010bbbb4732a 3 #include "Aggregator.h"
vwochnik 57:4af5f1bec3a6 4 #include "ComposedRecord.h"
vwochnik 57:4af5f1bec3a6 5 #include "CharValue.h"
vwochnik 57:4af5f1bec3a6 6 #include "IntegerValue.h"
vwochnik 57:4af5f1bec3a6 7
vwochnik 59:f96be79feccd 8 CharValue aOperationStatePending("PENDING");
vwochnik 59:f96be79feccd 9 CharValue aOperationStateExecuting("EXECUTING");
vwochnik 59:f96be79feccd 10 CharValue aOperationStateSuccessful("SUCCESSFUL");
vwochnik 59:f96be79feccd 11 CharValue aOperationStateFailed("FAILED");
vwochnik 59:f96be79feccd 12
vwochnik 65:a62dbef2f924 13 OperationSupport::OperationSupport(AbstractSmartRest& client, SmartRestTemplate& tpl, long& deviceId, DeviceIO& io) :
vwochnik 57:4af5f1bec3a6 14 _client(client),
vwochnik 57:4af5f1bec3a6 15 _tpl(tpl),
vwochnik 60:3c822f97fc73 16 _deviceId(deviceId),
vwochnik 65:a62dbef2f924 17 _executor(client, tpl, deviceId, io),
vwochnik 63:010bbbb4732a 18 _thread1(OperationSupport::thread1_func, this),
vwochnik 67:c360a2b2c948 19 _thread2(OperationSupport::thread2_func, this),
vwochnik 67:c360a2b2c948 20 _thread3(OperationSupport::thread3_func, this)
vwochnik 57:4af5f1bec3a6 21 {
vwochnik 57:4af5f1bec3a6 22 _init = false;
vwochnik 67:c360a2b2c948 23 _firstRun = true;
vwochnik 57:4af5f1bec3a6 24 }
vwochnik 57:4af5f1bec3a6 25
vwochnik 57:4af5f1bec3a6 26 bool OperationSupport::init()
vwochnik 57:4af5f1bec3a6 27 {
vwochnik 57:4af5f1bec3a6 28 if (_init)
vwochnik 57:4af5f1bec3a6 29 return false;
vwochnik 57:4af5f1bec3a6 30
vwochnik 57:4af5f1bec3a6 31 // Get pending operations
vwochnik 57:4af5f1bec3a6 32 // USAGE: 110,<DEVICE/ID>
vwochnik 57:4af5f1bec3a6 33 if (!_tpl.add("10,110,GET,/devicecontrol/operations?status=PENDING&deviceId=%%&pageSize=100,,application/vnd.com.nsn.cumulocity.operationCollection+json,%%,UNSIGNED,\r\n"))
vwochnik 57:4af5f1bec3a6 34 return false;
vwochnik 57:4af5f1bec3a6 35
vwochnik 57:4af5f1bec3a6 36 // Set operation state
vwochnik 57:4af5f1bec3a6 37 // USAGE: 110,<OPERATION/ID>,<STATE>
vwochnik 58:4cc0ae5a7058 38 if (!_tpl.add("10,111,PUT,/devicecontrol/operations/%%,application/vnd.com.nsn.cumulocity.operation+json,application/vnd.com.nsn.cumulocity.operation+json,%%,UNSIGNED STRING,\"{\"\"status\"\":\"\"%%\"\"}\"\r\n"))
vwochnik 57:4af5f1bec3a6 39 return false;
vwochnik 57:4af5f1bec3a6 40
vwochnik 57:4af5f1bec3a6 41 // Get operations
vwochnik 57:4af5f1bec3a6 42 // Response: 210,<OPERATION/ID>,<STATUS>
vwochnik 57:4af5f1bec3a6 43 if (!_tpl.add("11,210,\"$.operations\",,\"$.id\",\"$.status\"\r\n"))
vwochnik 57:4af5f1bec3a6 44 return false;
vwochnik 57:4af5f1bec3a6 45
vwochnik 57:4af5f1bec3a6 46 // Get operation
vwochnik 57:4af5f1bec3a6 47 // Response: 211,<OPERATION/ID>,<STATUS>
vwochnik 57:4af5f1bec3a6 48 if (!_tpl.add("11,211,,\"$.deviceId\",\"$.id\",\"$.status\"\r\n"))
vwochnik 57:4af5f1bec3a6 49 return false;
vwochnik 63:010bbbb4732a 50
vwochnik 63:010bbbb4732a 51 if (!_executor.init())
vwochnik 63:010bbbb4732a 52 return false;
vwochnik 57:4af5f1bec3a6 53
vwochnik 57:4af5f1bec3a6 54 _init = true;
vwochnik 57:4af5f1bec3a6 55 return true;
vwochnik 57:4af5f1bec3a6 56 }
vwochnik 57:4af5f1bec3a6 57
vwochnik 57:4af5f1bec3a6 58 bool OperationSupport::run()
vwochnik 57:4af5f1bec3a6 59 {
vwochnik 67:c360a2b2c948 60 if (_firstRun) {
vwochnik 67:c360a2b2c948 61 _firstRun = false;
vwochnik 67:c360a2b2c948 62 return true;
vwochnik 63:010bbbb4732a 63 if (!requestPendingOperations())
vwochnik 63:010bbbb4732a 64 return false;
vwochnik 63:010bbbb4732a 65 }
vwochnik 63:010bbbb4732a 66
vwochnik 63:010bbbb4732a 67 return true;
vwochnik 63:010bbbb4732a 68 }
vwochnik 63:010bbbb4732a 69
vwochnik 63:010bbbb4732a 70 bool OperationSupport::requestPendingOperations()
vwochnik 63:010bbbb4732a 71 {
vwochnik 60:3c822f97fc73 72 uint8_t ret;
vwochnik 63:010bbbb4732a 73 OperationStore::Operation op;
vwochnik 60:3c822f97fc73 74
vwochnik 59:f96be79feccd 75 ComposedRecord record;
vwochnik 59:f96be79feccd 76 ParsedRecord received;
vwochnik 59:f96be79feccd 77
vwochnik 59:f96be79feccd 78 IntegerValue msgId(110);
vwochnik 59:f96be79feccd 79 IntegerValue deviceId(_deviceId);
vwochnik 59:f96be79feccd 80 if ((!record.add(msgId)) || (!record.add(deviceId)))
vwochnik 59:f96be79feccd 81 return false;
vwochnik 60:3c822f97fc73 82
vwochnik 59:f96be79feccd 83 if (_client.send(record) != SMARTREST_SUCCESS) {
vwochnik 59:f96be79feccd 84 _client.stop();
vwochnik 59:f96be79feccd 85 return false;
vwochnik 59:f96be79feccd 86 }
vwochnik 60:3c822f97fc73 87
vwochnik 60:3c822f97fc73 88 while ((ret = _client.receive(received)) == SMARTREST_SUCCESS) {
vwochnik 65:a62dbef2f924 89 if (!operationFromRecord(received, op))
vwochnik 63:010bbbb4732a 90 continue;
vwochnik 65:a62dbef2f924 91 if (!_store.enqueue(op))
vwochnik 63:010bbbb4732a 92 continue;
vwochnik 60:3c822f97fc73 93 }
vwochnik 59:f96be79feccd 94 _client.stop();
vwochnik 60:3c822f97fc73 95
vwochnik 60:3c822f97fc73 96 if ((ret != SMARTREST_END_OF_RESPONSE) &&
vwochnik 60:3c822f97fc73 97 (ret != SMARTREST_CONNECTION_CLOSED)) {
vwochnik 60:3c822f97fc73 98 return false;
vwochnik 60:3c822f97fc73 99 }
vwochnik 59:f96be79feccd 100
vwochnik 60:3c822f97fc73 101 return true;
vwochnik 57:4af5f1bec3a6 102 }
vwochnik 59:f96be79feccd 103
vwochnik 60:3c822f97fc73 104 bool OperationSupport::operationFromRecord(ParsedRecord& received, OperationStore::Operation& op)
vwochnik 59:f96be79feccd 105 {
vwochnik 59:f96be79feccd 106 const char *tmp;
vwochnik 59:f96be79feccd 107
vwochnik 59:f96be79feccd 108 if ((received.values() < 4) ||
vwochnik 59:f96be79feccd 109 (received.value(0).valueType() != VALUE_INTEGER) ||
vwochnik 60:3c822f97fc73 110 (received.value(0).integerValue() != 210) ||
vwochnik 59:f96be79feccd 111 (received.value(2).valueType() != VALUE_INTEGER) ||
vwochnik 59:f96be79feccd 112 (received.value(3).valueType() != VALUE_CHARACTER))
vwochnik 59:f96be79feccd 113 return false;
vwochnik 59:f96be79feccd 114
vwochnik 60:3c822f97fc73 115 op.identifier = received.value(2).integerValue();
vwochnik 59:f96be79feccd 116 tmp = received.value(3).characterValue();
vwochnik 59:f96be79feccd 117 if (strcmp(tmp, "EXECUTING") == 0)
vwochnik 62:86a04c5bda18 118 op.state = OPERATION_EXECUTING;
vwochnik 59:f96be79feccd 119 else if (strcmp(tmp, "SUCCESSFUL") == 0)
vwochnik 62:86a04c5bda18 120 op.state = OPERATION_SUCCESSFUL;
vwochnik 59:f96be79feccd 121 else if (strcmp(tmp, "FAILED") == 0)
vwochnik 62:86a04c5bda18 122 op.state = OPERATION_FAILED;
vwochnik 59:f96be79feccd 123 else
vwochnik 62:86a04c5bda18 124 op.state = OPERATION_PENDING;
vwochnik 59:f96be79feccd 125
vwochnik 59:f96be79feccd 126 return true;
vwochnik 59:f96be79feccd 127 }
vwochnik 59:f96be79feccd 128
vwochnik 59:f96be79feccd 129 bool OperationSupport::updateOperation(OperationStore::Operation& op)
vwochnik 59:f96be79feccd 130 {
vwochnik 61:15719dbe8820 131 uint8_t ret; bool found;
vwochnik 59:f96be79feccd 132 ComposedRecord record;
vwochnik 59:f96be79feccd 133 ParsedRecord received;
vwochnik 59:f96be79feccd 134
vwochnik 59:f96be79feccd 135 IntegerValue msgId(111);
vwochnik 59:f96be79feccd 136 IntegerValue operationId(op.identifier);
vwochnik 59:f96be79feccd 137 if ((!record.add(msgId)) || (!record.add(operationId)) ||
vwochnik 59:f96be79feccd 138 (!record.add(operationStateValue(op))))
vwochnik 59:f96be79feccd 139 return false;
vwochnik 59:f96be79feccd 140
vwochnik 59:f96be79feccd 141 if (_client.send(record) != SMARTREST_SUCCESS) {
vwochnik 59:f96be79feccd 142 _client.stop();
vwochnik 59:f96be79feccd 143 return false;
vwochnik 59:f96be79feccd 144 }
vwochnik 59:f96be79feccd 145
vwochnik 61:15719dbe8820 146 found = false;
vwochnik 61:15719dbe8820 147 while ((ret = _client.receive(received)) == SMARTREST_SUCCESS) {
vwochnik 61:15719dbe8820 148 if ((received.values() == 4) &&
vwochnik 61:15719dbe8820 149 (received.value(0).valueType() == VALUE_INTEGER) &&
vwochnik 61:15719dbe8820 150 (received.value(0).integerValue() == 211) &&
vwochnik 61:15719dbe8820 151 (received.value(2).valueType() == VALUE_INTEGER) &&
vwochnik 61:15719dbe8820 152 (received.value(2).integerValue() == op.identifier)) {
vwochnik 61:15719dbe8820 153 found = true;
vwochnik 61:15719dbe8820 154 break;
vwochnik 61:15719dbe8820 155 }
vwochnik 59:f96be79feccd 156 }
vwochnik 59:f96be79feccd 157 _client.stop();
vwochnik 61:15719dbe8820 158
vwochnik 61:15719dbe8820 159 return found;
vwochnik 59:f96be79feccd 160 }
vwochnik 59:f96be79feccd 161
vwochnik 59:f96be79feccd 162 CharValue& OperationSupport::operationStateValue(OperationStore::Operation& op)
vwochnik 59:f96be79feccd 163 {
vwochnik 59:f96be79feccd 164 switch (op.state) {
vwochnik 62:86a04c5bda18 165 case OPERATION_EXECUTING:
vwochnik 59:f96be79feccd 166 return aOperationStateExecuting;
vwochnik 62:86a04c5bda18 167 case OPERATION_SUCCESSFUL:
vwochnik 59:f96be79feccd 168 return aOperationStateSuccessful;
vwochnik 62:86a04c5bda18 169 case OPERATION_FAILED:
vwochnik 59:f96be79feccd 170 return aOperationStateFailed;
vwochnik 59:f96be79feccd 171 default:
vwochnik 59:f96be79feccd 172 return aOperationStatePending;
vwochnik 59:f96be79feccd 173 }
vwochnik 59:f96be79feccd 174 }
vwochnik 60:3c822f97fc73 175
vwochnik 63:010bbbb4732a 176 void OperationSupport::thread1()
vwochnik 60:3c822f97fc73 177 {
vwochnik 63:010bbbb4732a 178 OperationStore::Operation op;
vwochnik 63:010bbbb4732a 179 bool ret;
vwochnik 63:010bbbb4732a 180
vwochnik 63:010bbbb4732a 181 while (!_init)
vwochnik 63:010bbbb4732a 182 Thread::yield();
vwochnik 63:010bbbb4732a 183
vwochnik 63:010bbbb4732a 184 while (true) {
vwochnik 63:010bbbb4732a 185 if (!_store.takePending(op)) {
vwochnik 63:010bbbb4732a 186 Thread::yield();
vwochnik 63:010bbbb4732a 187 continue;
vwochnik 63:010bbbb4732a 188 }
vwochnik 63:010bbbb4732a 189
vwochnik 63:010bbbb4732a 190 updateOperation(op);
vwochnik 63:010bbbb4732a 191 ret = _executor.executeOperation(op);
vwochnik 63:010bbbb4732a 192 _store.markAsDone(op, ret);
vwochnik 63:010bbbb4732a 193 }
vwochnik 63:010bbbb4732a 194 }
vwochnik 63:010bbbb4732a 195
vwochnik 63:010bbbb4732a 196 void OperationSupport::thread2()
vwochnik 63:010bbbb4732a 197 {
vwochnik 63:010bbbb4732a 198 OperationStore::Operation op;
vwochnik 63:010bbbb4732a 199 Aggregator aggr(true);
vwochnik 63:010bbbb4732a 200
vwochnik 60:3c822f97fc73 201 while (!_init)
vwochnik 60:3c822f97fc73 202 Thread::yield();
vwochnik 60:3c822f97fc73 203
vwochnik 63:010bbbb4732a 204 while (true) {
vwochnik 63:010bbbb4732a 205 while ((!aggr.full()) && (_store.takeDone(op))) {
vwochnik 63:010bbbb4732a 206 ComposedRecord record;
vwochnik 60:3c822f97fc73 207
vwochnik 63:010bbbb4732a 208 IntegerValue msgId(111);
vwochnik 63:010bbbb4732a 209 IntegerValue operationId(op.identifier);
vwochnik 63:010bbbb4732a 210 if ((!record.add(msgId)) || (!record.add(operationId)) ||
vwochnik 63:010bbbb4732a 211 (!record.add(operationStateValue(op))))
vwochnik 63:010bbbb4732a 212 break;
vwochnik 63:010bbbb4732a 213
vwochnik 63:010bbbb4732a 214 if (!aggr.add(record))
vwochnik 63:010bbbb4732a 215 break;
vwochnik 63:010bbbb4732a 216 }
vwochnik 63:010bbbb4732a 217
vwochnik 63:010bbbb4732a 218 if (aggr.length() == 0) {
vwochnik 63:010bbbb4732a 219 Thread::yield();
vwochnik 63:010bbbb4732a 220 continue;
vwochnik 63:010bbbb4732a 221 }
vwochnik 63:010bbbb4732a 222
vwochnik 65:a62dbef2f924 223 if (_client.send(aggr) != SMARTREST_SUCCESS) { }
vwochnik 63:010bbbb4732a 224 _client.stop();
vwochnik 63:010bbbb4732a 225 aggr.clear();
vwochnik 63:010bbbb4732a 226 }
vwochnik 60:3c822f97fc73 227 }
vwochnik 60:3c822f97fc73 228
vwochnik 67:c360a2b2c948 229 void OperationSupport::thread3()
vwochnik 67:c360a2b2c948 230 {
vwochnik 67:c360a2b2c948 231 char bayeuxId[33];
vwochnik 67:c360a2b2c948 232
vwochnik 67:c360a2b2c948 233 ComposedRecord record;
vwochnik 67:c360a2b2c948 234 ParsedRecord received;
vwochnik 67:c360a2b2c948 235
vwochnik 67:c360a2b2c948 236 while ((!_init) || (_firstRun))
vwochnik 67:c360a2b2c948 237 Thread::yield();
vwochnik 67:c360a2b2c948 238
vwochnik 67:c360a2b2c948 239 // request Bayeux ID
vwochnik 67:c360a2b2c948 240 {
vwochnik 67:c360a2b2c948 241 IntegerValue msgId(80);
vwochnik 67:c360a2b2c948 242 if (!record.add(msgId))
vwochnik 67:c360a2b2c948 243 return;
vwochnik 67:c360a2b2c948 244
vwochnik 67:c360a2b2c948 245 if ((_client.stream("/devicecontrol/notifications", record) != SMARTREST_SUCCESS)) {
vwochnik 67:c360a2b2c948 246 puts("Sending stream failed.");
vwochnik 67:c360a2b2c948 247 _client.stop();
vwochnik 67:c360a2b2c948 248 return;
vwochnik 67:c360a2b2c948 249 }
vwochnik 67:c360a2b2c948 250 if ((_client.receive(received) != SMARTREST_SUCCESS)) {
vwochnik 67:c360a2b2c948 251 puts("Receiving stream failed.");
vwochnik 67:c360a2b2c948 252 _client.stop();
vwochnik 67:c360a2b2c948 253 }
vwochnik 67:c360a2b2c948 254 _client.stop();
vwochnik 67:c360a2b2c948 255
vwochnik 67:c360a2b2c948 256 puts(received.value(0).characterValue());
vwochnik 67:c360a2b2c948 257 }
vwochnik 67:c360a2b2c948 258
vwochnik 67:c360a2b2c948 259 while (true) {
vwochnik 67:c360a2b2c948 260 }
vwochnik 67:c360a2b2c948 261 }
vwochnik 67:c360a2b2c948 262
vwochnik 63:010bbbb4732a 263 void OperationSupport::thread1_func(void const *arg)
vwochnik 60:3c822f97fc73 264 {
vwochnik 60:3c822f97fc73 265 OperationSupport *that;
vwochnik 60:3c822f97fc73 266 that = (OperationSupport*)arg;
vwochnik 63:010bbbb4732a 267 that->thread1();
vwochnik 60:3c822f97fc73 268 }
vwochnik 63:010bbbb4732a 269
vwochnik 63:010bbbb4732a 270 void OperationSupport::thread2_func(void const *arg)
vwochnik 63:010bbbb4732a 271 {
vwochnik 63:010bbbb4732a 272 OperationSupport *that;
vwochnik 63:010bbbb4732a 273 that = (OperationSupport*)arg;
vwochnik 63:010bbbb4732a 274 that->thread2();
vwochnik 63:010bbbb4732a 275 }
vwochnik 67:c360a2b2c948 276
vwochnik 67:c360a2b2c948 277 void OperationSupport::thread3_func(void const *arg)
vwochnik 67:c360a2b2c948 278 {
vwochnik 67:c360a2b2c948 279 OperationSupport *that;
vwochnik 67:c360a2b2c948 280 that = (OperationSupport*)arg;
vwochnik 67:c360a2b2c948 281 that->thread3();
vwochnik 67:c360a2b2c948 282 }