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:
Thu Oct 30 13:38:20 2014 +0000
Revision:
65:a62dbef2f924
Parent:
63:010bbbb4732a
Child:
67:c360a2b2c948
operation support

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 63:010bbbb4732a 19 _thread2(OperationSupport::thread2_func, this)
vwochnik 57:4af5f1bec3a6 20 {
vwochnik 57:4af5f1bec3a6 21 _init = false;
vwochnik 57:4af5f1bec3a6 22 }
vwochnik 57:4af5f1bec3a6 23
vwochnik 57:4af5f1bec3a6 24 bool OperationSupport::init()
vwochnik 57:4af5f1bec3a6 25 {
vwochnik 57:4af5f1bec3a6 26 if (_init)
vwochnik 57:4af5f1bec3a6 27 return false;
vwochnik 57:4af5f1bec3a6 28
vwochnik 57:4af5f1bec3a6 29 // Get pending operations
vwochnik 57:4af5f1bec3a6 30 // USAGE: 110,<DEVICE/ID>
vwochnik 57:4af5f1bec3a6 31 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 32 return false;
vwochnik 57:4af5f1bec3a6 33
vwochnik 57:4af5f1bec3a6 34 // Set operation state
vwochnik 57:4af5f1bec3a6 35 // USAGE: 110,<OPERATION/ID>,<STATE>
vwochnik 58:4cc0ae5a7058 36 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 37 return false;
vwochnik 57:4af5f1bec3a6 38
vwochnik 57:4af5f1bec3a6 39 // Get operations
vwochnik 57:4af5f1bec3a6 40 // Response: 210,<OPERATION/ID>,<STATUS>
vwochnik 57:4af5f1bec3a6 41 if (!_tpl.add("11,210,\"$.operations\",,\"$.id\",\"$.status\"\r\n"))
vwochnik 57:4af5f1bec3a6 42 return false;
vwochnik 57:4af5f1bec3a6 43
vwochnik 57:4af5f1bec3a6 44 // Get operation
vwochnik 57:4af5f1bec3a6 45 // Response: 211,<OPERATION/ID>,<STATUS>
vwochnik 57:4af5f1bec3a6 46 if (!_tpl.add("11,211,,\"$.deviceId\",\"$.id\",\"$.status\"\r\n"))
vwochnik 57:4af5f1bec3a6 47 return false;
vwochnik 63:010bbbb4732a 48
vwochnik 63:010bbbb4732a 49 if (!_executor.init())
vwochnik 63:010bbbb4732a 50 return false;
vwochnik 57:4af5f1bec3a6 51
vwochnik 57:4af5f1bec3a6 52 _init = true;
vwochnik 57:4af5f1bec3a6 53 return true;
vwochnik 57:4af5f1bec3a6 54 }
vwochnik 57:4af5f1bec3a6 55
vwochnik 57:4af5f1bec3a6 56 bool OperationSupport::run()
vwochnik 57:4af5f1bec3a6 57 {
vwochnik 63:010bbbb4732a 58 if (!_store.hasPending()) {
vwochnik 63:010bbbb4732a 59 if (!requestPendingOperations())
vwochnik 63:010bbbb4732a 60 return false;
vwochnik 63:010bbbb4732a 61 }
vwochnik 63:010bbbb4732a 62
vwochnik 63:010bbbb4732a 63 return true;
vwochnik 63:010bbbb4732a 64 }
vwochnik 63:010bbbb4732a 65
vwochnik 63:010bbbb4732a 66 bool OperationSupport::requestPendingOperations()
vwochnik 63:010bbbb4732a 67 {
vwochnik 60:3c822f97fc73 68 uint8_t ret;
vwochnik 63:010bbbb4732a 69 OperationStore::Operation op;
vwochnik 60:3c822f97fc73 70
vwochnik 59:f96be79feccd 71 ComposedRecord record;
vwochnik 59:f96be79feccd 72 ParsedRecord received;
vwochnik 59:f96be79feccd 73
vwochnik 59:f96be79feccd 74 IntegerValue msgId(110);
vwochnik 59:f96be79feccd 75 IntegerValue deviceId(_deviceId);
vwochnik 59:f96be79feccd 76 if ((!record.add(msgId)) || (!record.add(deviceId)))
vwochnik 59:f96be79feccd 77 return false;
vwochnik 60:3c822f97fc73 78
vwochnik 59:f96be79feccd 79 if (_client.send(record) != SMARTREST_SUCCESS) {
vwochnik 59:f96be79feccd 80 _client.stop();
vwochnik 59:f96be79feccd 81 return false;
vwochnik 59:f96be79feccd 82 }
vwochnik 60:3c822f97fc73 83
vwochnik 60:3c822f97fc73 84 while ((ret = _client.receive(received)) == SMARTREST_SUCCESS) {
vwochnik 65:a62dbef2f924 85 if (!operationFromRecord(received, op))
vwochnik 63:010bbbb4732a 86 continue;
vwochnik 65:a62dbef2f924 87 if (!_store.enqueue(op))
vwochnik 63:010bbbb4732a 88 continue;
vwochnik 60:3c822f97fc73 89 }
vwochnik 59:f96be79feccd 90 _client.stop();
vwochnik 60:3c822f97fc73 91
vwochnik 60:3c822f97fc73 92 if ((ret != SMARTREST_END_OF_RESPONSE) &&
vwochnik 60:3c822f97fc73 93 (ret != SMARTREST_CONNECTION_CLOSED)) {
vwochnik 60:3c822f97fc73 94 return false;
vwochnik 60:3c822f97fc73 95 }
vwochnik 59:f96be79feccd 96
vwochnik 60:3c822f97fc73 97 return true;
vwochnik 57:4af5f1bec3a6 98 }
vwochnik 59:f96be79feccd 99
vwochnik 60:3c822f97fc73 100 bool OperationSupport::operationFromRecord(ParsedRecord& received, OperationStore::Operation& op)
vwochnik 59:f96be79feccd 101 {
vwochnik 59:f96be79feccd 102 const char *tmp;
vwochnik 59:f96be79feccd 103
vwochnik 59:f96be79feccd 104 if ((received.values() < 4) ||
vwochnik 59:f96be79feccd 105 (received.value(0).valueType() != VALUE_INTEGER) ||
vwochnik 60:3c822f97fc73 106 (received.value(0).integerValue() != 210) ||
vwochnik 59:f96be79feccd 107 (received.value(2).valueType() != VALUE_INTEGER) ||
vwochnik 59:f96be79feccd 108 (received.value(3).valueType() != VALUE_CHARACTER))
vwochnik 59:f96be79feccd 109 return false;
vwochnik 59:f96be79feccd 110
vwochnik 60:3c822f97fc73 111 op.identifier = received.value(2).integerValue();
vwochnik 59:f96be79feccd 112 tmp = received.value(3).characterValue();
vwochnik 59:f96be79feccd 113 if (strcmp(tmp, "EXECUTING") == 0)
vwochnik 62:86a04c5bda18 114 op.state = OPERATION_EXECUTING;
vwochnik 59:f96be79feccd 115 else if (strcmp(tmp, "SUCCESSFUL") == 0)
vwochnik 62:86a04c5bda18 116 op.state = OPERATION_SUCCESSFUL;
vwochnik 59:f96be79feccd 117 else if (strcmp(tmp, "FAILED") == 0)
vwochnik 62:86a04c5bda18 118 op.state = OPERATION_FAILED;
vwochnik 59:f96be79feccd 119 else
vwochnik 62:86a04c5bda18 120 op.state = OPERATION_PENDING;
vwochnik 59:f96be79feccd 121
vwochnik 59:f96be79feccd 122 return true;
vwochnik 59:f96be79feccd 123 }
vwochnik 59:f96be79feccd 124
vwochnik 59:f96be79feccd 125 bool OperationSupport::updateOperation(OperationStore::Operation& op)
vwochnik 59:f96be79feccd 126 {
vwochnik 61:15719dbe8820 127 uint8_t ret; bool found;
vwochnik 59:f96be79feccd 128 ComposedRecord record;
vwochnik 59:f96be79feccd 129 ParsedRecord received;
vwochnik 59:f96be79feccd 130
vwochnik 59:f96be79feccd 131 IntegerValue msgId(111);
vwochnik 59:f96be79feccd 132 IntegerValue operationId(op.identifier);
vwochnik 59:f96be79feccd 133 if ((!record.add(msgId)) || (!record.add(operationId)) ||
vwochnik 59:f96be79feccd 134 (!record.add(operationStateValue(op))))
vwochnik 59:f96be79feccd 135 return false;
vwochnik 59:f96be79feccd 136
vwochnik 59:f96be79feccd 137 if (_client.send(record) != SMARTREST_SUCCESS) {
vwochnik 59:f96be79feccd 138 _client.stop();
vwochnik 59:f96be79feccd 139 return false;
vwochnik 59:f96be79feccd 140 }
vwochnik 59:f96be79feccd 141
vwochnik 61:15719dbe8820 142 found = false;
vwochnik 61:15719dbe8820 143 while ((ret = _client.receive(received)) == SMARTREST_SUCCESS) {
vwochnik 61:15719dbe8820 144 if ((received.values() == 4) &&
vwochnik 61:15719dbe8820 145 (received.value(0).valueType() == VALUE_INTEGER) &&
vwochnik 61:15719dbe8820 146 (received.value(0).integerValue() == 211) &&
vwochnik 61:15719dbe8820 147 (received.value(2).valueType() == VALUE_INTEGER) &&
vwochnik 61:15719dbe8820 148 (received.value(2).integerValue() == op.identifier)) {
vwochnik 61:15719dbe8820 149 found = true;
vwochnik 61:15719dbe8820 150 break;
vwochnik 61:15719dbe8820 151 }
vwochnik 59:f96be79feccd 152 }
vwochnik 59:f96be79feccd 153 _client.stop();
vwochnik 61:15719dbe8820 154
vwochnik 61:15719dbe8820 155 return found;
vwochnik 59:f96be79feccd 156 }
vwochnik 59:f96be79feccd 157
vwochnik 59:f96be79feccd 158 CharValue& OperationSupport::operationStateValue(OperationStore::Operation& op)
vwochnik 59:f96be79feccd 159 {
vwochnik 59:f96be79feccd 160 switch (op.state) {
vwochnik 62:86a04c5bda18 161 case OPERATION_EXECUTING:
vwochnik 59:f96be79feccd 162 return aOperationStateExecuting;
vwochnik 62:86a04c5bda18 163 case OPERATION_SUCCESSFUL:
vwochnik 59:f96be79feccd 164 return aOperationStateSuccessful;
vwochnik 62:86a04c5bda18 165 case OPERATION_FAILED:
vwochnik 59:f96be79feccd 166 return aOperationStateFailed;
vwochnik 59:f96be79feccd 167 default:
vwochnik 59:f96be79feccd 168 return aOperationStatePending;
vwochnik 59:f96be79feccd 169 }
vwochnik 59:f96be79feccd 170 }
vwochnik 60:3c822f97fc73 171
vwochnik 63:010bbbb4732a 172 void OperationSupport::thread1()
vwochnik 60:3c822f97fc73 173 {
vwochnik 63:010bbbb4732a 174 OperationStore::Operation op;
vwochnik 63:010bbbb4732a 175 bool ret;
vwochnik 63:010bbbb4732a 176
vwochnik 63:010bbbb4732a 177 while (!_init)
vwochnik 63:010bbbb4732a 178 Thread::yield();
vwochnik 63:010bbbb4732a 179
vwochnik 63:010bbbb4732a 180 while (true) {
vwochnik 63:010bbbb4732a 181 if (!_store.takePending(op)) {
vwochnik 63:010bbbb4732a 182 Thread::yield();
vwochnik 63:010bbbb4732a 183 continue;
vwochnik 63:010bbbb4732a 184 }
vwochnik 63:010bbbb4732a 185
vwochnik 63:010bbbb4732a 186 updateOperation(op);
vwochnik 63:010bbbb4732a 187 ret = _executor.executeOperation(op);
vwochnik 63:010bbbb4732a 188 _store.markAsDone(op, ret);
vwochnik 63:010bbbb4732a 189 }
vwochnik 63:010bbbb4732a 190 }
vwochnik 63:010bbbb4732a 191
vwochnik 63:010bbbb4732a 192 void OperationSupport::thread2()
vwochnik 63:010bbbb4732a 193 {
vwochnik 63:010bbbb4732a 194 OperationStore::Operation op;
vwochnik 63:010bbbb4732a 195 Aggregator aggr(true);
vwochnik 63:010bbbb4732a 196
vwochnik 60:3c822f97fc73 197 while (!_init)
vwochnik 60:3c822f97fc73 198 Thread::yield();
vwochnik 60:3c822f97fc73 199
vwochnik 63:010bbbb4732a 200 while (true) {
vwochnik 63:010bbbb4732a 201 while ((!aggr.full()) && (_store.takeDone(op))) {
vwochnik 63:010bbbb4732a 202 ComposedRecord record;
vwochnik 60:3c822f97fc73 203
vwochnik 63:010bbbb4732a 204 IntegerValue msgId(111);
vwochnik 63:010bbbb4732a 205 IntegerValue operationId(op.identifier);
vwochnik 63:010bbbb4732a 206 if ((!record.add(msgId)) || (!record.add(operationId)) ||
vwochnik 63:010bbbb4732a 207 (!record.add(operationStateValue(op))))
vwochnik 63:010bbbb4732a 208 break;
vwochnik 63:010bbbb4732a 209
vwochnik 63:010bbbb4732a 210 if (!aggr.add(record))
vwochnik 63:010bbbb4732a 211 break;
vwochnik 63:010bbbb4732a 212 }
vwochnik 63:010bbbb4732a 213
vwochnik 63:010bbbb4732a 214 if (aggr.length() == 0) {
vwochnik 63:010bbbb4732a 215 Thread::yield();
vwochnik 63:010bbbb4732a 216 continue;
vwochnik 63:010bbbb4732a 217 }
vwochnik 63:010bbbb4732a 218
vwochnik 65:a62dbef2f924 219 if (_client.send(aggr) != SMARTREST_SUCCESS) { }
vwochnik 63:010bbbb4732a 220 _client.stop();
vwochnik 63:010bbbb4732a 221 aggr.clear();
vwochnik 63:010bbbb4732a 222 }
vwochnik 60:3c822f97fc73 223 }
vwochnik 60:3c822f97fc73 224
vwochnik 63:010bbbb4732a 225 void OperationSupport::thread1_func(void const *arg)
vwochnik 60:3c822f97fc73 226 {
vwochnik 60:3c822f97fc73 227 OperationSupport *that;
vwochnik 60:3c822f97fc73 228 that = (OperationSupport*)arg;
vwochnik 63:010bbbb4732a 229 that->thread1();
vwochnik 60:3c822f97fc73 230 }
vwochnik 63:010bbbb4732a 231
vwochnik 63:010bbbb4732a 232 void OperationSupport::thread2_func(void const *arg)
vwochnik 63:010bbbb4732a 233 {
vwochnik 63:010bbbb4732a 234 OperationSupport *that;
vwochnik 63:010bbbb4732a 235 that = (OperationSupport*)arg;
vwochnik 63:010bbbb4732a 236 that->thread2();
vwochnik 63:010bbbb4732a 237 }