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 11:58:03 2014 +0000
Revision:
63:010bbbb4732a
Parent:
62:86a04c5bda18
Child:
65:a62dbef2f924
Operation support class functional

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