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
operation/OperationSupport.cpp@62:86a04c5bda18, 2014-10-29 (annotated)
- Committer:
- vwochnik
- Date:
- Wed Oct 29 21:09:29 2014 +0000
- Revision:
- 62:86a04c5bda18
- Parent:
- 61:15719dbe8820
- Child:
- 63:010bbbb4732a
introduced operation store
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
vwochnik | 57:4af5f1bec3a6 | 1 | #include "OperationSupport.h" |
vwochnik | 59:f96be79feccd | 2 | #include <string.h> |
vwochnik | 57:4af5f1bec3a6 | 3 | #include "ComposedRecord.h" |
vwochnik | 57:4af5f1bec3a6 | 4 | #include "CharValue.h" |
vwochnik | 57:4af5f1bec3a6 | 5 | #include "IntegerValue.h" |
vwochnik | 60:3c822f97fc73 | 6 | #include <stdio.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 | 57:4af5f1bec3a6 | 13 | OperationSupport::OperationSupport(AbstractSmartRest& client, SmartRestTemplate& tpl, long& deviceId) : |
vwochnik | 57:4af5f1bec3a6 | 14 | _client(client), |
vwochnik | 57:4af5f1bec3a6 | 15 | _tpl(tpl), |
vwochnik | 60:3c822f97fc73 | 16 | _deviceId(deviceId), |
vwochnik | 62:86a04c5bda18 | 17 | _executor(client, tpl, deviceId), |
vwochnik | 60:3c822f97fc73 | 18 | _thread(OperationSupport::thread_func, this) |
vwochnik | 57:4af5f1bec3a6 | 19 | { |
vwochnik | 57:4af5f1bec3a6 | 20 | _init = false; |
vwochnik | 57:4af5f1bec3a6 | 21 | } |
vwochnik | 57:4af5f1bec3a6 | 22 | |
vwochnik | 57:4af5f1bec3a6 | 23 | bool OperationSupport::init() |
vwochnik | 57:4af5f1bec3a6 | 24 | { |
vwochnik | 57:4af5f1bec3a6 | 25 | if (_init) |
vwochnik | 57:4af5f1bec3a6 | 26 | return false; |
vwochnik | 57:4af5f1bec3a6 | 27 | |
vwochnik | 57:4af5f1bec3a6 | 28 | // Get pending operations |
vwochnik | 57:4af5f1bec3a6 | 29 | // USAGE: 110,<DEVICE/ID> |
vwochnik | 57:4af5f1bec3a6 | 30 | 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 | 31 | return false; |
vwochnik | 57:4af5f1bec3a6 | 32 | |
vwochnik | 57:4af5f1bec3a6 | 33 | // Set operation state |
vwochnik | 57:4af5f1bec3a6 | 34 | // USAGE: 110,<OPERATION/ID>,<STATE> |
vwochnik | 58:4cc0ae5a7058 | 35 | 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 | 36 | return false; |
vwochnik | 57:4af5f1bec3a6 | 37 | |
vwochnik | 57:4af5f1bec3a6 | 38 | // Get operations |
vwochnik | 57:4af5f1bec3a6 | 39 | // Response: 210,<OPERATION/ID>,<STATUS> |
vwochnik | 57:4af5f1bec3a6 | 40 | if (!_tpl.add("11,210,\"$.operations\",,\"$.id\",\"$.status\"\r\n")) |
vwochnik | 57:4af5f1bec3a6 | 41 | return false; |
vwochnik | 57:4af5f1bec3a6 | 42 | |
vwochnik | 57:4af5f1bec3a6 | 43 | // Get operation |
vwochnik | 57:4af5f1bec3a6 | 44 | // Response: 211,<OPERATION/ID>,<STATUS> |
vwochnik | 57:4af5f1bec3a6 | 45 | if (!_tpl.add("11,211,,\"$.deviceId\",\"$.id\",\"$.status\"\r\n")) |
vwochnik | 57:4af5f1bec3a6 | 46 | return false; |
vwochnik | 57:4af5f1bec3a6 | 47 | |
vwochnik | 57:4af5f1bec3a6 | 48 | _init = true; |
vwochnik | 57:4af5f1bec3a6 | 49 | return true; |
vwochnik | 57:4af5f1bec3a6 | 50 | } |
vwochnik | 57:4af5f1bec3a6 | 51 | |
vwochnik | 57:4af5f1bec3a6 | 52 | bool OperationSupport::run() |
vwochnik | 57:4af5f1bec3a6 | 53 | { |
vwochnik | 60:3c822f97fc73 | 54 | uint8_t ret; |
vwochnik | 60:3c822f97fc73 | 55 | OperationStore::Operation ops[100]; |
vwochnik | 60:3c822f97fc73 | 56 | size_t nops; |
vwochnik | 60:3c822f97fc73 | 57 | |
vwochnik | 59:f96be79feccd | 58 | ComposedRecord record; |
vwochnik | 59:f96be79feccd | 59 | ParsedRecord received; |
vwochnik | 59:f96be79feccd | 60 | |
vwochnik | 59:f96be79feccd | 61 | IntegerValue msgId(110); |
vwochnik | 59:f96be79feccd | 62 | IntegerValue deviceId(_deviceId); |
vwochnik | 59:f96be79feccd | 63 | if ((!record.add(msgId)) || (!record.add(deviceId))) |
vwochnik | 59:f96be79feccd | 64 | return false; |
vwochnik | 60:3c822f97fc73 | 65 | |
vwochnik | 60:3c822f97fc73 | 66 | puts("Operation support."); |
vwochnik | 59:f96be79feccd | 67 | if (_client.send(record) != SMARTREST_SUCCESS) { |
vwochnik | 59:f96be79feccd | 68 | _client.stop(); |
vwochnik | 59:f96be79feccd | 69 | return false; |
vwochnik | 59:f96be79feccd | 70 | } |
vwochnik | 60:3c822f97fc73 | 71 | |
vwochnik | 60:3c822f97fc73 | 72 | nops = 0; |
vwochnik | 60:3c822f97fc73 | 73 | while ((ret = _client.receive(received)) == SMARTREST_SUCCESS) { |
vwochnik | 60:3c822f97fc73 | 74 | puts("Received operation."); |
vwochnik | 60:3c822f97fc73 | 75 | if (!operationFromRecord(received, ops[nops++])) |
vwochnik | 60:3c822f97fc73 | 76 | puts("Operation conversion failed."); |
vwochnik | 60:3c822f97fc73 | 77 | } |
vwochnik | 59:f96be79feccd | 78 | _client.stop(); |
vwochnik | 60:3c822f97fc73 | 79 | |
vwochnik | 60:3c822f97fc73 | 80 | if ((ret != SMARTREST_END_OF_RESPONSE) && |
vwochnik | 60:3c822f97fc73 | 81 | (ret != SMARTREST_CONNECTION_CLOSED)) { |
vwochnik | 60:3c822f97fc73 | 82 | puts("Failed receive."); |
vwochnik | 60:3c822f97fc73 | 83 | return false; |
vwochnik | 60:3c822f97fc73 | 84 | } |
vwochnik | 59:f96be79feccd | 85 | |
vwochnik | 60:3c822f97fc73 | 86 | for (size_t i = 0; i < nops; i++) { |
vwochnik | 62:86a04c5bda18 | 87 | ops[i].state = OPERATION_SUCCESSFUL; |
vwochnik | 60:3c822f97fc73 | 88 | if (!updateOperation(ops[i])) |
vwochnik | 60:3c822f97fc73 | 89 | puts("Operation update failed."); |
vwochnik | 60:3c822f97fc73 | 90 | } |
vwochnik | 60:3c822f97fc73 | 91 | |
vwochnik | 60:3c822f97fc73 | 92 | return true; |
vwochnik | 57:4af5f1bec3a6 | 93 | } |
vwochnik | 59:f96be79feccd | 94 | |
vwochnik | 60:3c822f97fc73 | 95 | bool OperationSupport::operationFromRecord(ParsedRecord& received, OperationStore::Operation& op) |
vwochnik | 59:f96be79feccd | 96 | { |
vwochnik | 59:f96be79feccd | 97 | const char *tmp; |
vwochnik | 59:f96be79feccd | 98 | |
vwochnik | 59:f96be79feccd | 99 | if ((received.values() < 4) || |
vwochnik | 59:f96be79feccd | 100 | (received.value(0).valueType() != VALUE_INTEGER) || |
vwochnik | 60:3c822f97fc73 | 101 | (received.value(0).integerValue() != 210) || |
vwochnik | 59:f96be79feccd | 102 | (received.value(2).valueType() != VALUE_INTEGER) || |
vwochnik | 59:f96be79feccd | 103 | (received.value(3).valueType() != VALUE_CHARACTER)) |
vwochnik | 59:f96be79feccd | 104 | return false; |
vwochnik | 59:f96be79feccd | 105 | |
vwochnik | 60:3c822f97fc73 | 106 | op.identifier = received.value(2).integerValue(); |
vwochnik | 59:f96be79feccd | 107 | tmp = received.value(3).characterValue(); |
vwochnik | 59:f96be79feccd | 108 | if (strcmp(tmp, "EXECUTING") == 0) |
vwochnik | 62:86a04c5bda18 | 109 | op.state = OPERATION_EXECUTING; |
vwochnik | 59:f96be79feccd | 110 | else if (strcmp(tmp, "SUCCESSFUL") == 0) |
vwochnik | 62:86a04c5bda18 | 111 | op.state = OPERATION_SUCCESSFUL; |
vwochnik | 59:f96be79feccd | 112 | else if (strcmp(tmp, "FAILED") == 0) |
vwochnik | 62:86a04c5bda18 | 113 | op.state = OPERATION_FAILED; |
vwochnik | 59:f96be79feccd | 114 | else |
vwochnik | 62:86a04c5bda18 | 115 | op.state = OPERATION_PENDING; |
vwochnik | 59:f96be79feccd | 116 | |
vwochnik | 59:f96be79feccd | 117 | return true; |
vwochnik | 59:f96be79feccd | 118 | } |
vwochnik | 59:f96be79feccd | 119 | |
vwochnik | 59:f96be79feccd | 120 | bool OperationSupport::updateOperation(OperationStore::Operation& op) |
vwochnik | 59:f96be79feccd | 121 | { |
vwochnik | 61:15719dbe8820 | 122 | uint8_t ret; bool found; |
vwochnik | 59:f96be79feccd | 123 | ComposedRecord record; |
vwochnik | 59:f96be79feccd | 124 | ParsedRecord received; |
vwochnik | 59:f96be79feccd | 125 | |
vwochnik | 59:f96be79feccd | 126 | IntegerValue msgId(111); |
vwochnik | 59:f96be79feccd | 127 | IntegerValue operationId(op.identifier); |
vwochnik | 59:f96be79feccd | 128 | if ((!record.add(msgId)) || (!record.add(operationId)) || |
vwochnik | 59:f96be79feccd | 129 | (!record.add(operationStateValue(op)))) |
vwochnik | 59:f96be79feccd | 130 | return false; |
vwochnik | 59:f96be79feccd | 131 | |
vwochnik | 59:f96be79feccd | 132 | if (_client.send(record) != SMARTREST_SUCCESS) { |
vwochnik | 59:f96be79feccd | 133 | _client.stop(); |
vwochnik | 59:f96be79feccd | 134 | return false; |
vwochnik | 59:f96be79feccd | 135 | } |
vwochnik | 59:f96be79feccd | 136 | |
vwochnik | 61:15719dbe8820 | 137 | found = false; |
vwochnik | 61:15719dbe8820 | 138 | while ((ret = _client.receive(received)) == SMARTREST_SUCCESS) { |
vwochnik | 61:15719dbe8820 | 139 | if ((received.values() == 4) && |
vwochnik | 61:15719dbe8820 | 140 | (received.value(0).valueType() == VALUE_INTEGER) && |
vwochnik | 61:15719dbe8820 | 141 | (received.value(0).integerValue() == 211) && |
vwochnik | 61:15719dbe8820 | 142 | (received.value(2).valueType() == VALUE_INTEGER) && |
vwochnik | 61:15719dbe8820 | 143 | (received.value(2).integerValue() == op.identifier)) { |
vwochnik | 61:15719dbe8820 | 144 | found = true; |
vwochnik | 61:15719dbe8820 | 145 | break; |
vwochnik | 61:15719dbe8820 | 146 | } |
vwochnik | 59:f96be79feccd | 147 | } |
vwochnik | 59:f96be79feccd | 148 | _client.stop(); |
vwochnik | 61:15719dbe8820 | 149 | |
vwochnik | 61:15719dbe8820 | 150 | return found; |
vwochnik | 59:f96be79feccd | 151 | } |
vwochnik | 59:f96be79feccd | 152 | |
vwochnik | 59:f96be79feccd | 153 | CharValue& OperationSupport::operationStateValue(OperationStore::Operation& op) |
vwochnik | 59:f96be79feccd | 154 | { |
vwochnik | 59:f96be79feccd | 155 | switch (op.state) { |
vwochnik | 62:86a04c5bda18 | 156 | case OPERATION_EXECUTING: |
vwochnik | 59:f96be79feccd | 157 | return aOperationStateExecuting; |
vwochnik | 62:86a04c5bda18 | 158 | case OPERATION_SUCCESSFUL: |
vwochnik | 59:f96be79feccd | 159 | return aOperationStateSuccessful; |
vwochnik | 62:86a04c5bda18 | 160 | case OPERATION_FAILED: |
vwochnik | 59:f96be79feccd | 161 | return aOperationStateFailed; |
vwochnik | 59:f96be79feccd | 162 | default: |
vwochnik | 59:f96be79feccd | 163 | return aOperationStatePending; |
vwochnik | 59:f96be79feccd | 164 | } |
vwochnik | 59:f96be79feccd | 165 | } |
vwochnik | 60:3c822f97fc73 | 166 | |
vwochnik | 60:3c822f97fc73 | 167 | void OperationSupport::thread() |
vwochnik | 60:3c822f97fc73 | 168 | { |
vwochnik | 60:3c822f97fc73 | 169 | while (!_init) |
vwochnik | 60:3c822f97fc73 | 170 | Thread::yield(); |
vwochnik | 60:3c822f97fc73 | 171 | |
vwochnik | 60:3c822f97fc73 | 172 | |
vwochnik | 60:3c822f97fc73 | 173 | } |
vwochnik | 60:3c822f97fc73 | 174 | |
vwochnik | 60:3c822f97fc73 | 175 | void OperationSupport::thread_func(void const *arg) |
vwochnik | 60:3c822f97fc73 | 176 | { |
vwochnik | 60:3c822f97fc73 | 177 | OperationSupport *that; |
vwochnik | 60:3c822f97fc73 | 178 | that = (OperationSupport*)arg; |
vwochnik | 60:3c822f97fc73 | 179 | that->thread(); |
vwochnik | 60:3c822f97fc73 | 180 | } |