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:
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?

UserRevisionLine numberNew 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 }