Own fork of MbedSmartRestMain
Dependencies: C027_Support C12832 LM75B MMA7660 MbedSmartRest mbed-rtos mbed
Fork of MbedSmartRestMain by
operation/OperationSupport.cpp@92:0acd11870c6a, 2015-04-13 (annotated)
- Committer:
- xinlei
- Date:
- Mon Apr 13 14:24:58 2015 +0000
- Revision:
- 92:0acd11870c6a
- Parent:
- 90:423177e8a401
- Child:
- 93:61d44636f020
v2.1rc1
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
xinlei | 77:f6717e4eccc4 | 1 | #include <string.h> |
vwochnik | 57:4af5f1bec3a6 | 2 | #include "OperationSupport.h" |
xinlei | 92:0acd11870c6a | 3 | //#include "Aggregator.h" |
xinlei | 92:0acd11870c6a | 4 | #include "SmartRestConf.h" |
xinlei | 92:0acd11870c6a | 5 | #include "logging.h" |
xinlei | 92:0acd11870c6a | 6 | |
xinlei | 92:0acd11870c6a | 7 | //CharValue aOperationStatePending("PENDING"); |
xinlei | 92:0acd11870c6a | 8 | //CharValue aOperationStateExecuting("EXECUTING"); |
xinlei | 92:0acd11870c6a | 9 | //CharValue aOperationStateSuccessful("SUCCESSFUL"); |
xinlei | 92:0acd11870c6a | 10 | //CharValue aOperationStateFailed("FAILED"); |
vwochnik | 57:4af5f1bec3a6 | 11 | |
xinlei | 92:0acd11870c6a | 12 | const char strPending[] = "PENDING"; |
xinlei | 92:0acd11870c6a | 13 | const char strExecuting[] = "EXECUTING"; |
xinlei | 92:0acd11870c6a | 14 | const char strSuccessful[] = "SUCCESSFUL"; |
xinlei | 92:0acd11870c6a | 15 | const char strFailed[] = "FAILED"; |
vwochnik | 59:f96be79feccd | 16 | |
xinlei | 92:0acd11870c6a | 17 | OperationSupport::OperationSupport(RtosSmartRest& client, SmartRestTemplate& tpl, long& deviceId, |
xinlei | 92:0acd11870c6a | 18 | ConfigurationSynchronization& configurationSynchronization, |
xinlei | 92:0acd11870c6a | 19 | LCDDisplay& lcdDisplay) : |
xinlei | 82:ca7430f50b2b | 20 | _deviceId(deviceId), |
vwochnik | 57:4af5f1bec3a6 | 21 | _tpl(tpl), |
xinlei | 82:ca7430f50b2b | 22 | _client(client), |
xinlei | 92:0acd11870c6a | 23 | _executor(client, tpl, deviceId, configurationSynchronization, lcdDisplay), |
xinlei | 92:0acd11870c6a | 24 | sock(), |
vwochnik | 67:c360a2b2c948 | 25 | _thread2(OperationSupport::thread2_func, this), |
vwochnik | 67:c360a2b2c948 | 26 | _thread3(OperationSupport::thread3_func, this) |
vwochnik | 57:4af5f1bec3a6 | 27 | { |
vwochnik | 57:4af5f1bec3a6 | 28 | _init = false; |
vwochnik | 67:c360a2b2c948 | 29 | _firstRun = true; |
vwochnik | 57:4af5f1bec3a6 | 30 | } |
vwochnik | 57:4af5f1bec3a6 | 31 | |
vwochnik | 57:4af5f1bec3a6 | 32 | bool OperationSupport::init() |
vwochnik | 57:4af5f1bec3a6 | 33 | { |
vwochnik | 57:4af5f1bec3a6 | 34 | if (_init) |
vwochnik | 57:4af5f1bec3a6 | 35 | return false; |
vwochnik | 57:4af5f1bec3a6 | 36 | |
vwochnik | 57:4af5f1bec3a6 | 37 | // Get pending operations |
vwochnik | 57:4af5f1bec3a6 | 38 | // USAGE: 110,<DEVICE/ID> |
vwochnik | 57:4af5f1bec3a6 | 39 | 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 | 40 | return false; |
vwochnik | 57:4af5f1bec3a6 | 41 | |
vwochnik | 57:4af5f1bec3a6 | 42 | // Set operation state |
xinlei | 92:0acd11870c6a | 43 | // USAGE: 111,<OPERATION/ID>,<STATE> |
vwochnik | 58:4cc0ae5a7058 | 44 | 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 | 45 | return false; |
vwochnik | 57:4af5f1bec3a6 | 46 | |
vwochnik | 57:4af5f1bec3a6 | 47 | // Get operations |
vwochnik | 57:4af5f1bec3a6 | 48 | // Response: 210,<OPERATION/ID>,<STATUS> |
vwochnik | 57:4af5f1bec3a6 | 49 | if (!_tpl.add("11,210,\"$.operations\",,\"$.id\",\"$.status\"\r\n")) |
vwochnik | 57:4af5f1bec3a6 | 50 | return false; |
vwochnik | 57:4af5f1bec3a6 | 51 | |
vwochnik | 57:4af5f1bec3a6 | 52 | // Get operation |
vwochnik | 57:4af5f1bec3a6 | 53 | // Response: 211,<OPERATION/ID>,<STATUS> |
vwochnik | 57:4af5f1bec3a6 | 54 | if (!_tpl.add("11,211,,\"$.deviceId\",\"$.id\",\"$.status\"\r\n")) |
vwochnik | 57:4af5f1bec3a6 | 55 | return false; |
vwochnik | 63:010bbbb4732a | 56 | |
vwochnik | 63:010bbbb4732a | 57 | if (!_executor.init()) |
vwochnik | 63:010bbbb4732a | 58 | return false; |
vwochnik | 57:4af5f1bec3a6 | 59 | |
vwochnik | 57:4af5f1bec3a6 | 60 | _init = true; |
vwochnik | 57:4af5f1bec3a6 | 61 | return true; |
vwochnik | 57:4af5f1bec3a6 | 62 | } |
vwochnik | 57:4af5f1bec3a6 | 63 | |
vwochnik | 57:4af5f1bec3a6 | 64 | bool OperationSupport::run() |
vwochnik | 57:4af5f1bec3a6 | 65 | { |
vwochnik | 67:c360a2b2c948 | 66 | if (_firstRun) { |
vwochnik | 67:c360a2b2c948 | 67 | _firstRun = false; |
xinlei | 92:0acd11870c6a | 68 | bool b = requestPendingOperations(); |
xinlei | 92:0acd11870c6a | 69 | return b; |
xinlei | 92:0acd11870c6a | 70 | } else { |
xinlei | 92:0acd11870c6a | 71 | return true; |
xinlei | 92:0acd11870c6a | 72 | } |
xinlei | 92:0acd11870c6a | 73 | } |
xinlei | 92:0acd11870c6a | 74 | |
xinlei | 92:0acd11870c6a | 75 | bool OperationSupport::executePendingOperation(Operation& op) |
xinlei | 92:0acd11870c6a | 76 | { |
xinlei | 92:0acd11870c6a | 77 | ComposedRecord r; |
xinlei | 92:0acd11870c6a | 78 | if (!r.add(IntegerValue(112)) || !r.add(IntegerValue(op.identifier))) { |
xinlei | 92:0acd11870c6a | 79 | return false; |
xinlei | 92:0acd11870c6a | 80 | } else if (_client.send(r) != SMARTREST_SUCCESS) { |
xinlei | 92:0acd11870c6a | 81 | _client.stop(); |
xinlei | 92:0acd11870c6a | 82 | return false; |
vwochnik | 63:010bbbb4732a | 83 | } |
xinlei | 92:0acd11870c6a | 84 | ParsedRecord p; |
xinlei | 92:0acd11870c6a | 85 | bool b = true; |
xinlei | 92:0acd11870c6a | 86 | while (_client.receive(p) == SMARTREST_SUCCESS) { |
xinlei | 92:0acd11870c6a | 87 | if (p.values() >= 3 && |
xinlei | 92:0acd11870c6a | 88 | p.value(0).integerValue() >= 220 && |
xinlei | 92:0acd11870c6a | 89 | p.value(0).integerValue() <= 222 && |
xinlei | 92:0acd11870c6a | 90 | p.value(2).valueType() == VALUE_INTEGER) { |
xinlei | 92:0acd11870c6a | 91 | Operation* op1 = opool.alloc(); |
xinlei | 92:0acd11870c6a | 92 | op1->identifier = p.value(2).integerValue(); |
xinlei | 92:0acd11870c6a | 93 | bool ret = _executor.executeOperation(p); |
xinlei | 92:0acd11870c6a | 94 | op1->state = ret ? OPERATION_SUCCESSFUL : OPERATION_FAILED; |
xinlei | 92:0acd11870c6a | 95 | opool.put(op1); |
xinlei | 92:0acd11870c6a | 96 | } |
xinlei | 92:0acd11870c6a | 97 | } |
xinlei | 92:0acd11870c6a | 98 | _client.stop(); |
xinlei | 92:0acd11870c6a | 99 | return b; |
vwochnik | 63:010bbbb4732a | 100 | } |
vwochnik | 63:010bbbb4732a | 101 | |
vwochnik | 63:010bbbb4732a | 102 | bool OperationSupport::requestPendingOperations() |
vwochnik | 63:010bbbb4732a | 103 | { |
vwochnik | 59:f96be79feccd | 104 | IntegerValue msgId(110); |
vwochnik | 59:f96be79feccd | 105 | IntegerValue deviceId(_deviceId); |
xinlei | 92:0acd11870c6a | 106 | ComposedRecord record; |
xinlei | 92:0acd11870c6a | 107 | |
vwochnik | 59:f96be79feccd | 108 | if ((!record.add(msgId)) || (!record.add(deviceId))) |
vwochnik | 59:f96be79feccd | 109 | return false; |
xinlei | 92:0acd11870c6a | 110 | else if (_client.send(record) != SMARTREST_SUCCESS) { |
vwochnik | 59:f96be79feccd | 111 | _client.stop(); |
vwochnik | 59:f96be79feccd | 112 | return false; |
vwochnik | 59:f96be79feccd | 113 | } |
xinlei | 92:0acd11870c6a | 114 | |
xinlei | 92:0acd11870c6a | 115 | uint8_t ret; |
xinlei | 92:0acd11870c6a | 116 | ParsedRecord received; |
xinlei | 92:0acd11870c6a | 117 | Operation opl[10]; |
xinlei | 92:0acd11870c6a | 118 | size_t c = 0; |
xinlei | 92:0acd11870c6a | 119 | while ((ret=_client.receive(received)) == SMARTREST_SUCCESS) { |
xinlei | 92:0acd11870c6a | 120 | if (c < 10 && operationFromRecord(received, opl[c])) { |
xinlei | 92:0acd11870c6a | 121 | ++c; |
xinlei | 92:0acd11870c6a | 122 | } else { |
xinlei | 92:0acd11870c6a | 123 | aWarning("Ignored pending operation after 10.\n"); |
vwochnik | 61:15719dbe8820 | 124 | break; |
vwochnik | 61:15719dbe8820 | 125 | } |
vwochnik | 59:f96be79feccd | 126 | } |
vwochnik | 59:f96be79feccd | 127 | _client.stop(); |
xinlei | 92:0acd11870c6a | 128 | |
xinlei | 92:0acd11870c6a | 129 | for (size_t i = 0; i < c; ++i) { |
xinlei | 92:0acd11870c6a | 130 | Operation* op = opool.alloc(); |
xinlei | 92:0acd11870c6a | 131 | op->identifier = opl[i].identifier; |
xinlei | 92:0acd11870c6a | 132 | op->state = OPERATION_EXECUTING; |
xinlei | 92:0acd11870c6a | 133 | opool.put(op); |
xinlei | 92:0acd11870c6a | 134 | executePendingOperation(opl[i]); |
xinlei | 92:0acd11870c6a | 135 | } |
xinlei | 92:0acd11870c6a | 136 | return (ret == SMARTREST_END_OF_RESPONSE || ret == SMARTREST_CONNECTION_CLOSED); |
vwochnik | 59:f96be79feccd | 137 | } |
vwochnik | 59:f96be79feccd | 138 | |
xinlei | 92:0acd11870c6a | 139 | bool OperationSupport::operationFromRecord(ParsedRecord& received, Operation& op) |
vwochnik | 59:f96be79feccd | 140 | { |
xinlei | 92:0acd11870c6a | 141 | if ((received.values() < 4) || |
xinlei | 92:0acd11870c6a | 142 | (received.value(0).valueType() != VALUE_INTEGER) || |
xinlei | 92:0acd11870c6a | 143 | // (received.value(0).integerValue() != 211) || |
xinlei | 92:0acd11870c6a | 144 | (received.value(2).valueType() != VALUE_INTEGER) || |
xinlei | 92:0acd11870c6a | 145 | (received.value(3).valueType() != VALUE_CHARACTER)) |
xinlei | 92:0acd11870c6a | 146 | return false; |
xinlei | 92:0acd11870c6a | 147 | |
xinlei | 92:0acd11870c6a | 148 | op.identifier = received.value(2).integerValue(); |
xinlei | 92:0acd11870c6a | 149 | const char *tmp = received.value(3).characterValue(); |
xinlei | 92:0acd11870c6a | 150 | if (strcmp(tmp, strExecuting) == 0) |
xinlei | 92:0acd11870c6a | 151 | op.state = OPERATION_EXECUTING; |
xinlei | 92:0acd11870c6a | 152 | else if (strcmp(tmp, strSuccessful) == 0) |
xinlei | 92:0acd11870c6a | 153 | op.state = OPERATION_SUCCESSFUL; |
xinlei | 92:0acd11870c6a | 154 | else if (strcmp(tmp, strFailed) == 0) |
xinlei | 92:0acd11870c6a | 155 | op.state = OPERATION_FAILED; |
xinlei | 92:0acd11870c6a | 156 | else if (strcmp(tmp, strPending) == 0) |
xinlei | 92:0acd11870c6a | 157 | op.state = OPERATION_PENDING; |
xinlei | 92:0acd11870c6a | 158 | else |
xinlei | 92:0acd11870c6a | 159 | return false; |
xinlei | 92:0acd11870c6a | 160 | return true; |
xinlei | 92:0acd11870c6a | 161 | } |
xinlei | 92:0acd11870c6a | 162 | |
xinlei | 92:0acd11870c6a | 163 | //CharValue& OperationSupport::operationStateValue(OperationState state) const |
xinlei | 92:0acd11870c6a | 164 | //{ |
xinlei | 92:0acd11870c6a | 165 | // switch (state) { |
xinlei | 92:0acd11870c6a | 166 | // case OPERATION_EXECUTING: return aOperationStateExecuting; |
xinlei | 92:0acd11870c6a | 167 | // case OPERATION_SUCCESSFUL: return aOperationStateSuccessful; |
xinlei | 92:0acd11870c6a | 168 | // case OPERATION_FAILED: return aOperationStateFailed; |
xinlei | 92:0acd11870c6a | 169 | // default: return aOperationStatePending; |
xinlei | 92:0acd11870c6a | 170 | // } |
xinlei | 92:0acd11870c6a | 171 | //} |
xinlei | 92:0acd11870c6a | 172 | |
xinlei | 92:0acd11870c6a | 173 | const char * OperationSupport::getOperationStateChar(OperationState state) const |
xinlei | 92:0acd11870c6a | 174 | { |
xinlei | 92:0acd11870c6a | 175 | switch (state) { |
xinlei | 92:0acd11870c6a | 176 | case OPERATION_EXECUTING: return strExecuting; |
xinlei | 92:0acd11870c6a | 177 | case OPERATION_SUCCESSFUL: return strSuccessful; |
xinlei | 92:0acd11870c6a | 178 | case OPERATION_FAILED: return strFailed; |
xinlei | 92:0acd11870c6a | 179 | case OPERATION_PENDING: return strPending; |
vwochnik | 59:f96be79feccd | 180 | } |
vwochnik | 59:f96be79feccd | 181 | } |
vwochnik | 60:3c822f97fc73 | 182 | |
xinlei | 92:0acd11870c6a | 183 | //void OperationSupport::thread2() |
xinlei | 92:0acd11870c6a | 184 | //{ |
xinlei | 92:0acd11870c6a | 185 | // IntegerValue msgId(111); |
xinlei | 92:0acd11870c6a | 186 | // Aggregator aggr(true); |
xinlei | 92:0acd11870c6a | 187 | // aInfo("Report thread: %p\n", Thread::gettid()); |
xinlei | 92:0acd11870c6a | 188 | // while (true) { |
xinlei | 92:0acd11870c6a | 189 | // while (!aggr.full()) { |
xinlei | 92:0acd11870c6a | 190 | // osEvent e = opool.get(200); |
xinlei | 92:0acd11870c6a | 191 | // if (e.status == osEventTimeout) { |
xinlei | 92:0acd11870c6a | 192 | // break; |
xinlei | 92:0acd11870c6a | 193 | // } else if (e.status == osEventMail) { |
xinlei | 92:0acd11870c6a | 194 | // Operation *op = (Operation*)e.value.p; |
xinlei | 92:0acd11870c6a | 195 | // ComposedRecord record; |
xinlei | 92:0acd11870c6a | 196 | // IntegerValue operationId(op->identifier); |
xinlei | 92:0acd11870c6a | 197 | // if (record.add(msgId) && record.add(operationId) && |
xinlei | 92:0acd11870c6a | 198 | // record.add(operationStateValue(op->state)) && aggr.add(record)) { |
xinlei | 92:0acd11870c6a | 199 | // printf("Reporting: <%ld, %u>.\n", op->identifier, op->state); |
xinlei | 92:0acd11870c6a | 200 | // opool.free(op); |
xinlei | 92:0acd11870c6a | 201 | // } else { |
xinlei | 92:0acd11870c6a | 202 | // opool.put(op); |
xinlei | 92:0acd11870c6a | 203 | // } |
xinlei | 92:0acd11870c6a | 204 | // } else { |
xinlei | 92:0acd11870c6a | 205 | // break; |
xinlei | 92:0acd11870c6a | 206 | // } |
xinlei | 92:0acd11870c6a | 207 | // } |
xinlei | 92:0acd11870c6a | 208 | // if (aggr.length()) { |
xinlei | 92:0acd11870c6a | 209 | // _client.sendAndClose(aggr); |
xinlei | 92:0acd11870c6a | 210 | // _client.stop(); |
xinlei | 92:0acd11870c6a | 211 | // aggr.clear(); |
xinlei | 92:0acd11870c6a | 212 | // } |
xinlei | 92:0acd11870c6a | 213 | // } |
xinlei | 92:0acd11870c6a | 214 | //} |
vwochnik | 63:010bbbb4732a | 215 | |
xinlei | 92:0acd11870c6a | 216 | const char fmt[] = "POST /s HTTP/1.0\r\nHost: %s\r\nAuthorization: Basic %s\r\nX-Id: %s\r\nContent-Length: %d\r\n\r\n%s"; |
xinlei | 92:0acd11870c6a | 217 | const char fmt2[] = "111,%ld,%s\r\n"; |
vwochnik | 63:010bbbb4732a | 218 | void OperationSupport::thread2() |
vwochnik | 63:010bbbb4732a | 219 | { |
xinlei | 92:0acd11870c6a | 220 | aInfo("Report thread: %p\n", Thread::gettid()); |
vwochnik | 63:010bbbb4732a | 221 | while (true) { |
xinlei | 92:0acd11870c6a | 222 | osEvent e = opool.get(); |
xinlei | 92:0acd11870c6a | 223 | if (e.status == osEventMail) { |
xinlei | 92:0acd11870c6a | 224 | Operation *op = (Operation*)e.value.p; |
xinlei | 92:0acd11870c6a | 225 | aDebug("Report: <%ld, %u>.\n", op->identifier, op->state); |
xinlei | 92:0acd11870c6a | 226 | int len = snprintf(buf2, sizeof(buf2), fmt2, op->identifier, getOperationStateChar(op->state)); |
xinlei | 92:0acd11870c6a | 227 | opool.free(op); |
xinlei | 92:0acd11870c6a | 228 | int ret = sock.connect(getHost(), getPort()); |
xinlei | 92:0acd11870c6a | 229 | for (uint8_t i = 1; ret < 0 && i < 3; ++i) { |
xinlei | 92:0acd11870c6a | 230 | ret = sock.connect(getHost(), getPort()); |
xinlei | 92:0acd11870c6a | 231 | } |
xinlei | 92:0acd11870c6a | 232 | if (ret >= 0) { |
xinlei | 92:0acd11870c6a | 233 | int l = snprintf(buf, sizeof(buf), fmt, getHost(), getAuthStr(), getIdentifier(), len, buf2); |
xinlei | 92:0acd11870c6a | 234 | ret = sock.send(buf, l); |
xinlei | 92:0acd11870c6a | 235 | if (ret < 0) { |
xinlei | 92:0acd11870c6a | 236 | aError("Report: Send!\n"); |
xinlei | 92:0acd11870c6a | 237 | } |
xinlei | 92:0acd11870c6a | 238 | sock.close(); |
xinlei | 92:0acd11870c6a | 239 | } else { |
xinlei | 92:0acd11870c6a | 240 | aError("Report: Connect!\n"); |
xinlei | 92:0acd11870c6a | 241 | } |
vwochnik | 63:010bbbb4732a | 242 | } |
vwochnik | 63:010bbbb4732a | 243 | } |
vwochnik | 60:3c822f97fc73 | 244 | } |
vwochnik | 60:3c822f97fc73 | 245 | |
vwochnik | 67:c360a2b2c948 | 246 | void OperationSupport::thread3() |
vwochnik | 67:c360a2b2c948 | 247 | { |
vwochnik | 70:f489ca11f254 | 248 | char bayeuxId[33]; |
vwochnik | 67:c360a2b2c948 | 249 | ComposedRecord record; |
vwochnik | 67:c360a2b2c948 | 250 | ParsedRecord received; |
xinlei | 92:0acd11870c6a | 251 | |
xinlei | 92:0acd11870c6a | 252 | while (!_init || _firstRun) |
vwochnik | 67:c360a2b2c948 | 253 | Thread::yield(); |
xinlei | 92:0acd11870c6a | 254 | |
vwochnik | 67:c360a2b2c948 | 255 | // request Bayeux ID |
xinlei | 92:0acd11870c6a | 256 | aInfo("Polling thread: %p\n", Thread::gettid()); |
vwochnik | 67:c360a2b2c948 | 257 | { |
vwochnik | 70:f489ca11f254 | 258 | const char *str; |
vwochnik | 67:c360a2b2c948 | 259 | IntegerValue msgId(80); |
vwochnik | 67:c360a2b2c948 | 260 | if (!record.add(msgId)) |
vwochnik | 67:c360a2b2c948 | 261 | return; |
vwochnik | 67:c360a2b2c948 | 262 | |
vwochnik | 70:f489ca11f254 | 263 | if ((_client.stream("/devicecontrol/notifications", record) != SMARTREST_SUCCESS) || |
vwochnik | 70:f489ca11f254 | 264 | (_client.receive(received) != SMARTREST_SUCCESS)) { |
vwochnik | 67:c360a2b2c948 | 265 | _client.stop(); |
vwochnik | 67:c360a2b2c948 | 266 | return; |
vwochnik | 67:c360a2b2c948 | 267 | } |
vwochnik | 70:f489ca11f254 | 268 | _client.stop(); |
vwochnik | 70:f489ca11f254 | 269 | |
vwochnik | 70:f489ca11f254 | 270 | str = received.value(0).characterValue(); |
xinlei | 92:0acd11870c6a | 271 | if (str == NULL || strlen(str) > sizeof(bayeuxId)) |
vwochnik | 70:f489ca11f254 | 272 | return; |
vwochnik | 70:f489ca11f254 | 273 | |
vwochnik | 70:f489ca11f254 | 274 | strcpy(bayeuxId, str); |
vwochnik | 70:f489ca11f254 | 275 | record.clear(); |
xinlei | 92:0acd11870c6a | 276 | aInfo("Polling: bayeux ID %s\n", str); |
vwochnik | 70:f489ca11f254 | 277 | } |
xinlei | 92:0acd11870c6a | 278 | |
vwochnik | 70:f489ca11f254 | 279 | // set channel |
vwochnik | 70:f489ca11f254 | 280 | { |
xinlei | 77:f6717e4eccc4 | 281 | char chn[16]; |
xinlei | 77:f6717e4eccc4 | 282 | int len = 0; |
vwochnik | 70:f489ca11f254 | 283 | snprintf(chn, sizeof(chn), "/%ld%n", _deviceId, &len); |
xinlei | 92:0acd11870c6a | 284 | if (len == 0 || len == sizeof(chn)) { |
xinlei | 92:0acd11870c6a | 285 | aError("Polling: Invalid id %ld.\n", _deviceId); |
vwochnik | 70:f489ca11f254 | 286 | return; |
xinlei | 92:0acd11870c6a | 287 | } |
xinlei | 92:0acd11870c6a | 288 | |
vwochnik | 70:f489ca11f254 | 289 | IntegerValue msgId(81); |
vwochnik | 70:f489ca11f254 | 290 | CharValue bid(bayeuxId); |
vwochnik | 70:f489ca11f254 | 291 | CharValue channel(chn); |
xinlei | 92:0acd11870c6a | 292 | if (!record.add(msgId) || !record.add(bid) || !record.add(channel)) { |
vwochnik | 70:f489ca11f254 | 293 | return; |
xinlei | 92:0acd11870c6a | 294 | } |
vwochnik | 70:f489ca11f254 | 295 | |
vwochnik | 70:f489ca11f254 | 296 | if ((_client.stream("/devicecontrol/notifications", record) != SMARTREST_SUCCESS) || |
vwochnik | 70:f489ca11f254 | 297 | (_client.receive(received) != SMARTREST_END_OF_RESPONSE)) { |
xinlei | 92:0acd11870c6a | 298 | aError("Polling: Subscribe channel %s.\n", chn); |
vwochnik | 67:c360a2b2c948 | 299 | _client.stop(); |
vwochnik | 70:f489ca11f254 | 300 | return; |
vwochnik | 67:c360a2b2c948 | 301 | } |
vwochnik | 67:c360a2b2c948 | 302 | _client.stop(); |
vwochnik | 70:f489ca11f254 | 303 | record.clear(); |
xinlei | 92:0acd11870c6a | 304 | aInfo("Polling: Subscribed channel %s!\n", chn); |
vwochnik | 70:f489ca11f254 | 305 | } |
vwochnik | 70:f489ca11f254 | 306 | |
xinlei | 92:0acd11870c6a | 307 | if (!record.add(IntegerValue(83)) || !record.add(CharValue(bayeuxId))) { |
xinlei | 92:0acd11870c6a | 308 | return; |
vwochnik | 67:c360a2b2c948 | 309 | } |
vwochnik | 67:c360a2b2c948 | 310 | |
vwochnik | 67:c360a2b2c948 | 311 | while (true) { |
vwochnik | 70:f489ca11f254 | 312 | if (_client.stream("/devicecontrol/notifications", record) != SMARTREST_SUCCESS) { |
xinlei | 92:0acd11870c6a | 313 | aError("Polling: Connect.\n"); |
vwochnik | 70:f489ca11f254 | 314 | _client.stop(); |
vwochnik | 70:f489ca11f254 | 315 | continue; |
vwochnik | 70:f489ca11f254 | 316 | } |
vwochnik | 70:f489ca11f254 | 317 | while (_client.receive(received) == SMARTREST_SUCCESS) { |
xinlei | 92:0acd11870c6a | 318 | for (size_t i = 0; i < received.values(); ++i) { |
xinlei | 92:0acd11870c6a | 319 | printf("%s ", received.rawValue(i)); |
xinlei | 92:0acd11870c6a | 320 | } |
xinlei | 92:0acd11870c6a | 321 | puts(""); |
xinlei | 92:0acd11870c6a | 322 | if (received.values() == 0) { |
vwochnik | 70:f489ca11f254 | 323 | continue; |
xinlei | 92:0acd11870c6a | 324 | } else if (received.value(0).integerValue() == 86) { // advice responses |
xinlei | 92:0acd11870c6a | 325 | if (received.values() < 5) { |
xinlei | 92:0acd11870c6a | 326 | aWarning("Incomplete advice, %u of 5 values received.\n", received.values()); |
xinlei | 92:0acd11870c6a | 327 | continue; |
xinlei | 92:0acd11870c6a | 328 | } else if (strcmp(received.value(4).characterValue(), "retry") == 0) { |
xinlei | 92:0acd11870c6a | 329 | aDebug("Carry out 'retry' policy.\n"); |
xinlei | 92:0acd11870c6a | 330 | break; |
xinlei | 92:0acd11870c6a | 331 | } else if (strcmp(received.value(4).characterValue(), "handshake") == 0) { |
xinlei | 92:0acd11870c6a | 332 | } |
xinlei | 92:0acd11870c6a | 333 | } else if (received.value(0).integerValue() == 211) { // Operation State Message |
xinlei | 92:0acd11870c6a | 334 | Operation* op = opool.alloc(); |
xinlei | 92:0acd11870c6a | 335 | if (op == NULL) { |
xinlei | 92:0acd11870c6a | 336 | aCritical("opool full!\n"); |
xinlei | 92:0acd11870c6a | 337 | } else if (operationFromRecord(received, *op)) { |
xinlei | 92:0acd11870c6a | 338 | op->state = OPERATION_EXECUTING; |
xinlei | 92:0acd11870c6a | 339 | opool.put(op); |
xinlei | 92:0acd11870c6a | 340 | } else { |
xinlei | 92:0acd11870c6a | 341 | opool.free(op); |
xinlei | 92:0acd11870c6a | 342 | } |
xinlei | 92:0acd11870c6a | 343 | } else if (received.value(0).integerValue() >= 220 && |
xinlei | 92:0acd11870c6a | 344 | received.value(0).integerValue() <= 222) { // Real Operation |
xinlei | 92:0acd11870c6a | 345 | if (received.values() >= 3 && |
xinlei | 92:0acd11870c6a | 346 | received.value(2).valueType() == VALUE_INTEGER) { |
xinlei | 92:0acd11870c6a | 347 | Operation* op = opool.alloc(); |
xinlei | 92:0acd11870c6a | 348 | op->identifier = received.value(2).integerValue(); |
xinlei | 92:0acd11870c6a | 349 | bool ret = _executor.executeOperation(received); |
xinlei | 92:0acd11870c6a | 350 | op->state = ret ? OPERATION_SUCCESSFUL : OPERATION_FAILED; |
xinlei | 92:0acd11870c6a | 351 | opool.put(op); |
xinlei | 92:0acd11870c6a | 352 | } else { |
xinlei | 92:0acd11870c6a | 353 | aWarning("Incomplete operation, %u of 4 values received.\n", received.values()); |
xinlei | 92:0acd11870c6a | 354 | } |
xinlei | 92:0acd11870c6a | 355 | } else { |
xinlei | 92:0acd11870c6a | 356 | aError("Unknown operation ID: %d\n", received.value(0).integerValue()); |
xinlei | 92:0acd11870c6a | 357 | } |
vwochnik | 70:f489ca11f254 | 358 | } |
vwochnik | 70:f489ca11f254 | 359 | _client.stop(); |
vwochnik | 70:f489ca11f254 | 360 | } |
vwochnik | 67:c360a2b2c948 | 361 | } |
vwochnik | 67:c360a2b2c948 | 362 | |
vwochnik | 63:010bbbb4732a | 363 | void OperationSupport::thread2_func(void const *arg) |
vwochnik | 63:010bbbb4732a | 364 | { |
vwochnik | 63:010bbbb4732a | 365 | OperationSupport *that; |
vwochnik | 63:010bbbb4732a | 366 | that = (OperationSupport*)arg; |
vwochnik | 63:010bbbb4732a | 367 | that->thread2(); |
vwochnik | 63:010bbbb4732a | 368 | } |
vwochnik | 67:c360a2b2c948 | 369 | |
vwochnik | 67:c360a2b2c948 | 370 | void OperationSupport::thread3_func(void const *arg) |
vwochnik | 67:c360a2b2c948 | 371 | { |
vwochnik | 67:c360a2b2c948 | 372 | OperationSupport *that; |
vwochnik | 67:c360a2b2c948 | 373 | that = (OperationSupport*)arg; |
vwochnik | 67:c360a2b2c948 | 374 | that->thread3(); |
vwochnik | 67:c360a2b2c948 | 375 | } |