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
- Committer:
- vwochnik
- Date:
- 2014-10-29
- Revision:
- 62:86a04c5bda18
- Parent:
- 61:15719dbe8820
- Child:
- 63:010bbbb4732a
File content as of revision 62:86a04c5bda18:
#include "OperationSupport.h" #include <string.h> #include "ComposedRecord.h" #include "CharValue.h" #include "IntegerValue.h" #include <stdio.h> CharValue aOperationStatePending("PENDING"); CharValue aOperationStateExecuting("EXECUTING"); CharValue aOperationStateSuccessful("SUCCESSFUL"); CharValue aOperationStateFailed("FAILED"); OperationSupport::OperationSupport(AbstractSmartRest& client, SmartRestTemplate& tpl, long& deviceId) : _client(client), _tpl(tpl), _deviceId(deviceId), _executor(client, tpl, deviceId), _thread(OperationSupport::thread_func, this) { _init = false; } bool OperationSupport::init() { if (_init) return false; // Get pending operations // USAGE: 110,<DEVICE/ID> if (!_tpl.add("10,110,GET,/devicecontrol/operations?status=PENDING&deviceId=%%&pageSize=100,,application/vnd.com.nsn.cumulocity.operationCollection+json,%%,UNSIGNED,\r\n")) return false; // Set operation state // USAGE: 110,<OPERATION/ID>,<STATE> 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")) return false; // Get operations // Response: 210,<OPERATION/ID>,<STATUS> if (!_tpl.add("11,210,\"$.operations\",,\"$.id\",\"$.status\"\r\n")) return false; // Get operation // Response: 211,<OPERATION/ID>,<STATUS> if (!_tpl.add("11,211,,\"$.deviceId\",\"$.id\",\"$.status\"\r\n")) return false; _init = true; return true; } bool OperationSupport::run() { uint8_t ret; OperationStore::Operation ops[100]; size_t nops; ComposedRecord record; ParsedRecord received; IntegerValue msgId(110); IntegerValue deviceId(_deviceId); if ((!record.add(msgId)) || (!record.add(deviceId))) return false; puts("Operation support."); if (_client.send(record) != SMARTREST_SUCCESS) { _client.stop(); return false; } nops = 0; while ((ret = _client.receive(received)) == SMARTREST_SUCCESS) { puts("Received operation."); if (!operationFromRecord(received, ops[nops++])) puts("Operation conversion failed."); } _client.stop(); if ((ret != SMARTREST_END_OF_RESPONSE) && (ret != SMARTREST_CONNECTION_CLOSED)) { puts("Failed receive."); return false; } for (size_t i = 0; i < nops; i++) { ops[i].state = OPERATION_SUCCESSFUL; if (!updateOperation(ops[i])) puts("Operation update failed."); } return true; } bool OperationSupport::operationFromRecord(ParsedRecord& received, OperationStore::Operation& op) { const char *tmp; if ((received.values() < 4) || (received.value(0).valueType() != VALUE_INTEGER) || (received.value(0).integerValue() != 210) || (received.value(2).valueType() != VALUE_INTEGER) || (received.value(3).valueType() != VALUE_CHARACTER)) return false; op.identifier = received.value(2).integerValue(); tmp = received.value(3).characterValue(); if (strcmp(tmp, "EXECUTING") == 0) op.state = OPERATION_EXECUTING; else if (strcmp(tmp, "SUCCESSFUL") == 0) op.state = OPERATION_SUCCESSFUL; else if (strcmp(tmp, "FAILED") == 0) op.state = OPERATION_FAILED; else op.state = OPERATION_PENDING; return true; } bool OperationSupport::updateOperation(OperationStore::Operation& op) { uint8_t ret; bool found; ComposedRecord record; ParsedRecord received; IntegerValue msgId(111); IntegerValue operationId(op.identifier); if ((!record.add(msgId)) || (!record.add(operationId)) || (!record.add(operationStateValue(op)))) return false; if (_client.send(record) != SMARTREST_SUCCESS) { _client.stop(); return false; } found = false; while ((ret = _client.receive(received)) == SMARTREST_SUCCESS) { if ((received.values() == 4) && (received.value(0).valueType() == VALUE_INTEGER) && (received.value(0).integerValue() == 211) && (received.value(2).valueType() == VALUE_INTEGER) && (received.value(2).integerValue() == op.identifier)) { found = true; break; } } _client.stop(); return found; } CharValue& OperationSupport::operationStateValue(OperationStore::Operation& op) { switch (op.state) { case OPERATION_EXECUTING: return aOperationStateExecuting; case OPERATION_SUCCESSFUL: return aOperationStateSuccessful; case OPERATION_FAILED: return aOperationStateFailed; default: return aOperationStatePending; } } void OperationSupport::thread() { while (!_init) Thread::yield(); } void OperationSupport::thread_func(void const *arg) { OperationSupport *that; that = (OperationSupport*)arg; that->thread(); }