Cumulocity Official / Mbed 2 deprecated MbedSmartRestMain Featured

Dependencies:   C027_Support C12832 LM75B MMA7660 MbedSmartRest mbed-rtos mbed

Fork of MbedSmartRestMain by Vincent Wochnik

Committer:
vwochnik
Date:
Sat Dec 06 19:47:23 2014 +0000
Revision:
68:0dc778a16d0d
Parent:
67:c360a2b2c948
Child:
70:f489ca11f254
configuration for interval

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 68:0dc778a16d0d 13 OperationSupport::OperationSupport(AbstractSmartRest& client, SmartRestTemplate& tpl, long& deviceId, ConfigurationSynchronization& configurationSynchronization, DeviceIO& io) :
vwochnik 57:4af5f1bec3a6 14 _client(client),
vwochnik 57:4af5f1bec3a6 15 _tpl(tpl),
vwochnik 60:3c822f97fc73 16 _deviceId(deviceId),
vwochnik 68:0dc778a16d0d 17 _executor(client, tpl, deviceId, configurationSynchronization, 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 68:0dc778a16d0d 62 //TODO: only request pending until push operation works
vwochnik 63:010bbbb4732a 63 }
vwochnik 68:0dc778a16d0d 64
vwochnik 68:0dc778a16d0d 65 if (!requestPendingOperations())
vwochnik 68:0dc778a16d0d 66 return false;
vwochnik 63:010bbbb4732a 67
vwochnik 63:010bbbb4732a 68 return true;
vwochnik 63:010bbbb4732a 69 }
vwochnik 63:010bbbb4732a 70
vwochnik 63:010bbbb4732a 71 bool OperationSupport::requestPendingOperations()
vwochnik 63:010bbbb4732a 72 {
vwochnik 60:3c822f97fc73 73 uint8_t ret;
vwochnik 63:010bbbb4732a 74 OperationStore::Operation op;
vwochnik 60:3c822f97fc73 75
vwochnik 59:f96be79feccd 76 ComposedRecord record;
vwochnik 59:f96be79feccd 77 ParsedRecord received;
vwochnik 59:f96be79feccd 78
vwochnik 59:f96be79feccd 79 IntegerValue msgId(110);
vwochnik 59:f96be79feccd 80 IntegerValue deviceId(_deviceId);
vwochnik 59:f96be79feccd 81 if ((!record.add(msgId)) || (!record.add(deviceId)))
vwochnik 59:f96be79feccd 82 return false;
vwochnik 60:3c822f97fc73 83
vwochnik 59:f96be79feccd 84 if (_client.send(record) != SMARTREST_SUCCESS) {
vwochnik 59:f96be79feccd 85 _client.stop();
vwochnik 59:f96be79feccd 86 return false;
vwochnik 59:f96be79feccd 87 }
vwochnik 60:3c822f97fc73 88
vwochnik 60:3c822f97fc73 89 while ((ret = _client.receive(received)) == SMARTREST_SUCCESS) {
vwochnik 65:a62dbef2f924 90 if (!operationFromRecord(received, op))
vwochnik 63:010bbbb4732a 91 continue;
vwochnik 65:a62dbef2f924 92 if (!_store.enqueue(op))
vwochnik 63:010bbbb4732a 93 continue;
vwochnik 60:3c822f97fc73 94 }
vwochnik 59:f96be79feccd 95 _client.stop();
vwochnik 60:3c822f97fc73 96
vwochnik 60:3c822f97fc73 97 if ((ret != SMARTREST_END_OF_RESPONSE) &&
vwochnik 60:3c822f97fc73 98 (ret != SMARTREST_CONNECTION_CLOSED)) {
vwochnik 60:3c822f97fc73 99 return false;
vwochnik 60:3c822f97fc73 100 }
vwochnik 59:f96be79feccd 101
vwochnik 60:3c822f97fc73 102 return true;
vwochnik 57:4af5f1bec3a6 103 }
vwochnik 59:f96be79feccd 104
vwochnik 60:3c822f97fc73 105 bool OperationSupport::operationFromRecord(ParsedRecord& received, OperationStore::Operation& op)
vwochnik 59:f96be79feccd 106 {
vwochnik 59:f96be79feccd 107 const char *tmp;
vwochnik 59:f96be79feccd 108
vwochnik 59:f96be79feccd 109 if ((received.values() < 4) ||
vwochnik 59:f96be79feccd 110 (received.value(0).valueType() != VALUE_INTEGER) ||
vwochnik 60:3c822f97fc73 111 (received.value(0).integerValue() != 210) ||
vwochnik 59:f96be79feccd 112 (received.value(2).valueType() != VALUE_INTEGER) ||
vwochnik 59:f96be79feccd 113 (received.value(3).valueType() != VALUE_CHARACTER))
vwochnik 59:f96be79feccd 114 return false;
vwochnik 59:f96be79feccd 115
vwochnik 60:3c822f97fc73 116 op.identifier = received.value(2).integerValue();
vwochnik 59:f96be79feccd 117 tmp = received.value(3).characterValue();
vwochnik 59:f96be79feccd 118 if (strcmp(tmp, "EXECUTING") == 0)
vwochnik 62:86a04c5bda18 119 op.state = OPERATION_EXECUTING;
vwochnik 59:f96be79feccd 120 else if (strcmp(tmp, "SUCCESSFUL") == 0)
vwochnik 62:86a04c5bda18 121 op.state = OPERATION_SUCCESSFUL;
vwochnik 59:f96be79feccd 122 else if (strcmp(tmp, "FAILED") == 0)
vwochnik 62:86a04c5bda18 123 op.state = OPERATION_FAILED;
vwochnik 59:f96be79feccd 124 else
vwochnik 62:86a04c5bda18 125 op.state = OPERATION_PENDING;
vwochnik 59:f96be79feccd 126
vwochnik 59:f96be79feccd 127 return true;
vwochnik 59:f96be79feccd 128 }
vwochnik 59:f96be79feccd 129
vwochnik 59:f96be79feccd 130 bool OperationSupport::updateOperation(OperationStore::Operation& op)
vwochnik 59:f96be79feccd 131 {
vwochnik 61:15719dbe8820 132 uint8_t ret; bool found;
vwochnik 59:f96be79feccd 133 ComposedRecord record;
vwochnik 59:f96be79feccd 134 ParsedRecord received;
vwochnik 59:f96be79feccd 135
vwochnik 59:f96be79feccd 136 IntegerValue msgId(111);
vwochnik 59:f96be79feccd 137 IntegerValue operationId(op.identifier);
vwochnik 59:f96be79feccd 138 if ((!record.add(msgId)) || (!record.add(operationId)) ||
vwochnik 59:f96be79feccd 139 (!record.add(operationStateValue(op))))
vwochnik 59:f96be79feccd 140 return false;
vwochnik 59:f96be79feccd 141
vwochnik 59:f96be79feccd 142 if (_client.send(record) != SMARTREST_SUCCESS) {
vwochnik 59:f96be79feccd 143 _client.stop();
vwochnik 59:f96be79feccd 144 return false;
vwochnik 59:f96be79feccd 145 }
vwochnik 59:f96be79feccd 146
vwochnik 61:15719dbe8820 147 found = false;
vwochnik 61:15719dbe8820 148 while ((ret = _client.receive(received)) == SMARTREST_SUCCESS) {
vwochnik 61:15719dbe8820 149 if ((received.values() == 4) &&
vwochnik 61:15719dbe8820 150 (received.value(0).valueType() == VALUE_INTEGER) &&
vwochnik 61:15719dbe8820 151 (received.value(0).integerValue() == 211) &&
vwochnik 61:15719dbe8820 152 (received.value(2).valueType() == VALUE_INTEGER) &&
vwochnik 61:15719dbe8820 153 (received.value(2).integerValue() == op.identifier)) {
vwochnik 61:15719dbe8820 154 found = true;
vwochnik 61:15719dbe8820 155 break;
vwochnik 61:15719dbe8820 156 }
vwochnik 59:f96be79feccd 157 }
vwochnik 59:f96be79feccd 158 _client.stop();
vwochnik 61:15719dbe8820 159
vwochnik 61:15719dbe8820 160 return found;
vwochnik 59:f96be79feccd 161 }
vwochnik 59:f96be79feccd 162
vwochnik 59:f96be79feccd 163 CharValue& OperationSupport::operationStateValue(OperationStore::Operation& op)
vwochnik 59:f96be79feccd 164 {
vwochnik 59:f96be79feccd 165 switch (op.state) {
vwochnik 62:86a04c5bda18 166 case OPERATION_EXECUTING:
vwochnik 59:f96be79feccd 167 return aOperationStateExecuting;
vwochnik 62:86a04c5bda18 168 case OPERATION_SUCCESSFUL:
vwochnik 59:f96be79feccd 169 return aOperationStateSuccessful;
vwochnik 62:86a04c5bda18 170 case OPERATION_FAILED:
vwochnik 59:f96be79feccd 171 return aOperationStateFailed;
vwochnik 59:f96be79feccd 172 default:
vwochnik 59:f96be79feccd 173 return aOperationStatePending;
vwochnik 59:f96be79feccd 174 }
vwochnik 59:f96be79feccd 175 }
vwochnik 60:3c822f97fc73 176
vwochnik 63:010bbbb4732a 177 void OperationSupport::thread1()
vwochnik 60:3c822f97fc73 178 {
vwochnik 63:010bbbb4732a 179 OperationStore::Operation op;
vwochnik 63:010bbbb4732a 180 bool ret;
vwochnik 63:010bbbb4732a 181
vwochnik 63:010bbbb4732a 182 while (!_init)
vwochnik 63:010bbbb4732a 183 Thread::yield();
vwochnik 63:010bbbb4732a 184
vwochnik 63:010bbbb4732a 185 while (true) {
vwochnik 63:010bbbb4732a 186 if (!_store.takePending(op)) {
vwochnik 63:010bbbb4732a 187 Thread::yield();
vwochnik 63:010bbbb4732a 188 continue;
vwochnik 63:010bbbb4732a 189 }
vwochnik 63:010bbbb4732a 190
vwochnik 63:010bbbb4732a 191 updateOperation(op);
vwochnik 63:010bbbb4732a 192 ret = _executor.executeOperation(op);
vwochnik 63:010bbbb4732a 193 _store.markAsDone(op, ret);
vwochnik 63:010bbbb4732a 194 }
vwochnik 63:010bbbb4732a 195 }
vwochnik 63:010bbbb4732a 196
vwochnik 63:010bbbb4732a 197 void OperationSupport::thread2()
vwochnik 63:010bbbb4732a 198 {
vwochnik 63:010bbbb4732a 199 OperationStore::Operation op;
vwochnik 63:010bbbb4732a 200 Aggregator aggr(true);
vwochnik 63:010bbbb4732a 201
vwochnik 60:3c822f97fc73 202 while (!_init)
vwochnik 60:3c822f97fc73 203 Thread::yield();
vwochnik 60:3c822f97fc73 204
vwochnik 63:010bbbb4732a 205 while (true) {
vwochnik 63:010bbbb4732a 206 while ((!aggr.full()) && (_store.takeDone(op))) {
vwochnik 63:010bbbb4732a 207 ComposedRecord record;
vwochnik 60:3c822f97fc73 208
vwochnik 63:010bbbb4732a 209 IntegerValue msgId(111);
vwochnik 63:010bbbb4732a 210 IntegerValue operationId(op.identifier);
vwochnik 63:010bbbb4732a 211 if ((!record.add(msgId)) || (!record.add(operationId)) ||
vwochnik 63:010bbbb4732a 212 (!record.add(operationStateValue(op))))
vwochnik 63:010bbbb4732a 213 break;
vwochnik 63:010bbbb4732a 214
vwochnik 63:010bbbb4732a 215 if (!aggr.add(record))
vwochnik 63:010bbbb4732a 216 break;
vwochnik 63:010bbbb4732a 217 }
vwochnik 63:010bbbb4732a 218
vwochnik 63:010bbbb4732a 219 if (aggr.length() == 0) {
vwochnik 63:010bbbb4732a 220 Thread::yield();
vwochnik 63:010bbbb4732a 221 continue;
vwochnik 63:010bbbb4732a 222 }
vwochnik 63:010bbbb4732a 223
vwochnik 65:a62dbef2f924 224 if (_client.send(aggr) != SMARTREST_SUCCESS) { }
vwochnik 63:010bbbb4732a 225 _client.stop();
vwochnik 63:010bbbb4732a 226 aggr.clear();
vwochnik 63:010bbbb4732a 227 }
vwochnik 60:3c822f97fc73 228 }
vwochnik 60:3c822f97fc73 229
vwochnik 67:c360a2b2c948 230 void OperationSupport::thread3()
vwochnik 67:c360a2b2c948 231 {
vwochnik 68:0dc778a16d0d 232 /* char bayeuxId[33];
vwochnik 67:c360a2b2c948 233
vwochnik 67:c360a2b2c948 234 ComposedRecord record;
vwochnik 67:c360a2b2c948 235 ParsedRecord received;
vwochnik 67:c360a2b2c948 236
vwochnik 67:c360a2b2c948 237 while ((!_init) || (_firstRun))
vwochnik 67:c360a2b2c948 238 Thread::yield();
vwochnik 67:c360a2b2c948 239
vwochnik 67:c360a2b2c948 240 // request Bayeux ID
vwochnik 67:c360a2b2c948 241 {
vwochnik 67:c360a2b2c948 242 IntegerValue msgId(80);
vwochnik 67:c360a2b2c948 243 if (!record.add(msgId))
vwochnik 67:c360a2b2c948 244 return;
vwochnik 67:c360a2b2c948 245
vwochnik 67:c360a2b2c948 246 if ((_client.stream("/devicecontrol/notifications", record) != SMARTREST_SUCCESS)) {
vwochnik 67:c360a2b2c948 247 puts("Sending stream failed.");
vwochnik 67:c360a2b2c948 248 _client.stop();
vwochnik 67:c360a2b2c948 249 return;
vwochnik 67:c360a2b2c948 250 }
vwochnik 67:c360a2b2c948 251 if ((_client.receive(received) != SMARTREST_SUCCESS)) {
vwochnik 67:c360a2b2c948 252 puts("Receiving stream failed.");
vwochnik 67:c360a2b2c948 253 _client.stop();
vwochnik 67:c360a2b2c948 254 }
vwochnik 67:c360a2b2c948 255 _client.stop();
vwochnik 67:c360a2b2c948 256
vwochnik 67:c360a2b2c948 257 puts(received.value(0).characterValue());
vwochnik 67:c360a2b2c948 258 }
vwochnik 67:c360a2b2c948 259
vwochnik 67:c360a2b2c948 260 while (true) {
vwochnik 68:0dc778a16d0d 261 }*/
vwochnik 67:c360a2b2c948 262 }
vwochnik 67:c360a2b2c948 263
vwochnik 63:010bbbb4732a 264 void OperationSupport::thread1_func(void const *arg)
vwochnik 60:3c822f97fc73 265 {
vwochnik 60:3c822f97fc73 266 OperationSupport *that;
vwochnik 60:3c822f97fc73 267 that = (OperationSupport*)arg;
vwochnik 63:010bbbb4732a 268 that->thread1();
vwochnik 60:3c822f97fc73 269 }
vwochnik 63:010bbbb4732a 270
vwochnik 63:010bbbb4732a 271 void OperationSupport::thread2_func(void const *arg)
vwochnik 63:010bbbb4732a 272 {
vwochnik 63:010bbbb4732a 273 OperationSupport *that;
vwochnik 63:010bbbb4732a 274 that = (OperationSupport*)arg;
vwochnik 63:010bbbb4732a 275 that->thread2();
vwochnik 63:010bbbb4732a 276 }
vwochnik 67:c360a2b2c948 277
vwochnik 67:c360a2b2c948 278 void OperationSupport::thread3_func(void const *arg)
vwochnik 67:c360a2b2c948 279 {
vwochnik 67:c360a2b2c948 280 OperationSupport *that;
vwochnik 67:c360a2b2c948 281 that = (OperationSupport*)arg;
vwochnik 67:c360a2b2c948 282 that->thread3();
vwochnik 67:c360a2b2c948 283 }