Toyomasa Watarai
/
Mbed-example-WS-W27
simple-mbed-cloud-client/mbed-cloud-client/source/ServiceClient.cpp@0:119624335925, 2018-06-30 (annotated)
- Committer:
- MACRUM
- Date:
- Sat Jun 30 01:40:30 2018 +0000
- Revision:
- 0:119624335925
Initial commit
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
MACRUM | 0:119624335925 | 1 | // ---------------------------------------------------------------------------- |
MACRUM | 0:119624335925 | 2 | // Copyright 2016-2017 ARM Ltd. |
MACRUM | 0:119624335925 | 3 | // |
MACRUM | 0:119624335925 | 4 | // SPDX-License-Identifier: Apache-2.0 |
MACRUM | 0:119624335925 | 5 | // |
MACRUM | 0:119624335925 | 6 | // Licensed under the Apache License, Version 2.0 (the "License"); |
MACRUM | 0:119624335925 | 7 | // you may not use this file except in compliance with the License. |
MACRUM | 0:119624335925 | 8 | // You may obtain a copy of the License at |
MACRUM | 0:119624335925 | 9 | // |
MACRUM | 0:119624335925 | 10 | // http://www.apache.org/licenses/LICENSE-2.0 |
MACRUM | 0:119624335925 | 11 | // |
MACRUM | 0:119624335925 | 12 | // Unless required by applicable law or agreed to in writing, software |
MACRUM | 0:119624335925 | 13 | // distributed under the License is distributed on an "AS IS" BASIS, |
MACRUM | 0:119624335925 | 14 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
MACRUM | 0:119624335925 | 15 | // See the License for the specific language governing permissions and |
MACRUM | 0:119624335925 | 16 | // limitations under the License. |
MACRUM | 0:119624335925 | 17 | // ---------------------------------------------------------------------------- |
MACRUM | 0:119624335925 | 18 | |
MACRUM | 0:119624335925 | 19 | // Note: this macro is needed on armcc to get the the PRI*32 macros |
MACRUM | 0:119624335925 | 20 | // from inttypes.h in a C++ code. |
MACRUM | 0:119624335925 | 21 | #ifndef __STDC_FORMAT_MACROS |
MACRUM | 0:119624335925 | 22 | #define __STDC_FORMAT_MACROS |
MACRUM | 0:119624335925 | 23 | #endif |
MACRUM | 0:119624335925 | 24 | #include <inttypes.h> |
MACRUM | 0:119624335925 | 25 | |
MACRUM | 0:119624335925 | 26 | #include <string> |
MACRUM | 0:119624335925 | 27 | #include "include/ServiceClient.h" |
MACRUM | 0:119624335925 | 28 | #include "include/CloudClientStorage.h" |
MACRUM | 0:119624335925 | 29 | #include "include/UpdateClientResources.h" |
MACRUM | 0:119624335925 | 30 | #include "include/UpdateClient.h" |
MACRUM | 0:119624335925 | 31 | #include "factory_configurator_client.h" |
MACRUM | 0:119624335925 | 32 | #include "mbed-trace/mbed_trace.h" |
MACRUM | 0:119624335925 | 33 | #include <assert.h> |
MACRUM | 0:119624335925 | 34 | |
MACRUM | 0:119624335925 | 35 | #define TRACE_GROUP "mClt" |
MACRUM | 0:119624335925 | 36 | |
MACRUM | 0:119624335925 | 37 | #define CONNECT 0 |
MACRUM | 0:119624335925 | 38 | #define ERROR_UPDATE "Update has failed, check MbedCloudClient::Error" |
MACRUM | 0:119624335925 | 39 | |
MACRUM | 0:119624335925 | 40 | /* lookup table for printing hexadecimal values */ |
MACRUM | 0:119624335925 | 41 | const uint8_t ServiceClient::hex_table[16] = { |
MACRUM | 0:119624335925 | 42 | '0', '1', '2', '3', '4', '5', '6', '7', |
MACRUM | 0:119624335925 | 43 | '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' |
MACRUM | 0:119624335925 | 44 | }; |
MACRUM | 0:119624335925 | 45 | |
MACRUM | 0:119624335925 | 46 | ServiceClient::ServiceClient(ServiceClientCallback& callback) |
MACRUM | 0:119624335925 | 47 | : _service_callback(callback), |
MACRUM | 0:119624335925 | 48 | _service_uri(NULL), |
MACRUM | 0:119624335925 | 49 | _stack(NULL), |
MACRUM | 0:119624335925 | 50 | _client_objs(NULL), |
MACRUM | 0:119624335925 | 51 | _current_state(State_Init), |
MACRUM | 0:119624335925 | 52 | _event_generated(false), |
MACRUM | 0:119624335925 | 53 | _state_engine_running(false), |
MACRUM | 0:119624335925 | 54 | #ifdef MBED_CLOUD_CLIENT_SUPPORT_UPDATE |
MACRUM | 0:119624335925 | 55 | _setup_update_client(false), |
MACRUM | 0:119624335925 | 56 | #endif |
MACRUM | 0:119624335925 | 57 | _connector_client(this) |
MACRUM | 0:119624335925 | 58 | { |
MACRUM | 0:119624335925 | 59 | } |
MACRUM | 0:119624335925 | 60 | |
MACRUM | 0:119624335925 | 61 | ServiceClient::~ServiceClient() |
MACRUM | 0:119624335925 | 62 | { |
MACRUM | 0:119624335925 | 63 | } |
MACRUM | 0:119624335925 | 64 | |
MACRUM | 0:119624335925 | 65 | void ServiceClient::initialize_and_register(M2MObjectList& client_objs) |
MACRUM | 0:119624335925 | 66 | { |
MACRUM | 0:119624335925 | 67 | tr_debug("ServiceClient::initialize_and_register"); |
MACRUM | 0:119624335925 | 68 | if(_current_state == State_Init || |
MACRUM | 0:119624335925 | 69 | _current_state == State_Unregister || |
MACRUM | 0:119624335925 | 70 | _current_state == State_Failure) { |
MACRUM | 0:119624335925 | 71 | _client_objs = &client_objs; |
MACRUM | 0:119624335925 | 72 | |
MACRUM | 0:119624335925 | 73 | #ifdef MBED_CLOUD_CLIENT_SUPPORT_UPDATE |
MACRUM | 0:119624335925 | 74 | tr_debug("ServiceClient::initialize_and_register: update client supported"); |
MACRUM | 0:119624335925 | 75 | |
MACRUM | 0:119624335925 | 76 | if(!_setup_update_client) { |
MACRUM | 0:119624335925 | 77 | _setup_update_client = true; |
MACRUM | 0:119624335925 | 78 | |
MACRUM | 0:119624335925 | 79 | #ifdef MBED_CLOUD_DEV_UPDATE_ID |
MACRUM | 0:119624335925 | 80 | /* Overwrite values stored in KCM. This is for development only |
MACRUM | 0:119624335925 | 81 | since these IDs should be provisioned in the factory. |
MACRUM | 0:119624335925 | 82 | */ |
MACRUM | 0:119624335925 | 83 | tr_debug("ServiceClient::initialize_and_register: update IDs defined"); |
MACRUM | 0:119624335925 | 84 | |
MACRUM | 0:119624335925 | 85 | /* Delete VendorId */ |
MACRUM | 0:119624335925 | 86 | delete_config_parameter("mbed.VendorId"); |
MACRUM | 0:119624335925 | 87 | /* Store Vendor Id to mbed.VendorId. No conversion is performed. */ |
MACRUM | 0:119624335925 | 88 | set_device_resource_value(M2MDevice::Manufacturer, |
MACRUM | 0:119624335925 | 89 | (const char*) arm_uc_vendor_id, |
MACRUM | 0:119624335925 | 90 | arm_uc_vendor_id_size); |
MACRUM | 0:119624335925 | 91 | |
MACRUM | 0:119624335925 | 92 | /* Delete ClassId */ |
MACRUM | 0:119624335925 | 93 | delete_config_parameter("mbed.ClassId"); |
MACRUM | 0:119624335925 | 94 | /* Store Class Id to mbed.ClassId. No conversion is performed. */ |
MACRUM | 0:119624335925 | 95 | set_device_resource_value(M2MDevice::ModelNumber, |
MACRUM | 0:119624335925 | 96 | (const char*) arm_uc_class_id, |
MACRUM | 0:119624335925 | 97 | arm_uc_class_id_size); |
MACRUM | 0:119624335925 | 98 | #endif /* MBED_CLOUD_DEV_UPDATE_ID */ |
MACRUM | 0:119624335925 | 99 | |
MACRUM | 0:119624335925 | 100 | #ifdef ARM_UPDATE_CLIENT_VERSION |
MACRUM | 0:119624335925 | 101 | /* Inject Update Client version number if no other software |
MACRUM | 0:119624335925 | 102 | version is present in the KCM. |
MACRUM | 0:119624335925 | 103 | */ |
MACRUM | 0:119624335925 | 104 | tr_debug("ServiceClient::initialize_and_register: update version defined"); |
MACRUM | 0:119624335925 | 105 | ; |
MACRUM | 0:119624335925 | 106 | const size_t buffer_size = 16; |
MACRUM | 0:119624335925 | 107 | uint8_t buffer[buffer_size]; |
MACRUM | 0:119624335925 | 108 | size_t size = 0; |
MACRUM | 0:119624335925 | 109 | |
MACRUM | 0:119624335925 | 110 | /* check if software version is already set */ |
MACRUM | 0:119624335925 | 111 | ccs_status_e status = get_config_parameter(KEY_DEVICE_SOFTWAREVERSION, |
MACRUM | 0:119624335925 | 112 | buffer, buffer_size, &size); |
MACRUM | 0:119624335925 | 113 | |
MACRUM | 0:119624335925 | 114 | if (status == CCS_STATUS_KEY_DOESNT_EXIST) { |
MACRUM | 0:119624335925 | 115 | tr_debug("ServiceClient::initialize_and_register: insert update version"); |
MACRUM | 0:119624335925 | 116 | |
MACRUM | 0:119624335925 | 117 | /* insert value from Update Client Common */ |
MACRUM | 0:119624335925 | 118 | set_config_parameter(KEY_DEVICE_SOFTWAREVERSION, |
MACRUM | 0:119624335925 | 119 | (const uint8_t*) ARM_UPDATE_CLIENT_VERSION, |
MACRUM | 0:119624335925 | 120 | sizeof(ARM_UPDATE_CLIENT_VERSION)); |
MACRUM | 0:119624335925 | 121 | } |
MACRUM | 0:119624335925 | 122 | #endif /* ARM_UPDATE_CLIENT_VERSION */ |
MACRUM | 0:119624335925 | 123 | |
MACRUM | 0:119624335925 | 124 | /* Update Client adds the OMA LWM2M Firmware Update object */ |
MACRUM | 0:119624335925 | 125 | UpdateClient::populate_object_list(*_client_objs); |
MACRUM | 0:119624335925 | 126 | |
MACRUM | 0:119624335925 | 127 | /* Initialize Update Client */ |
MACRUM | 0:119624335925 | 128 | FP1<void, int32_t> callback(this, &ServiceClient::update_error_callback); |
MACRUM | 0:119624335925 | 129 | UpdateClient::UpdateClient(callback); |
MACRUM | 0:119624335925 | 130 | } |
MACRUM | 0:119624335925 | 131 | #endif /* MBED_CLOUD_CLIENT_SUPPORT_UPDATE */ |
MACRUM | 0:119624335925 | 132 | |
MACRUM | 0:119624335925 | 133 | /* Device Object is mandatory. |
MACRUM | 0:119624335925 | 134 | Get instance and add it to object list |
MACRUM | 0:119624335925 | 135 | */ |
MACRUM | 0:119624335925 | 136 | M2MDevice *device_object = device_object_from_storage(); |
MACRUM | 0:119624335925 | 137 | |
MACRUM | 0:119624335925 | 138 | if (device_object) { |
MACRUM | 0:119624335925 | 139 | /* Publish device object resource to mds */ |
MACRUM | 0:119624335925 | 140 | M2MResourceList list = device_object->object_instance()->resources(); |
MACRUM | 0:119624335925 | 141 | if(!list.empty()) { |
MACRUM | 0:119624335925 | 142 | M2MResourceList::const_iterator it; |
MACRUM | 0:119624335925 | 143 | it = list.begin(); |
MACRUM | 0:119624335925 | 144 | for ( ; it != list.end(); it++ ) { |
MACRUM | 0:119624335925 | 145 | (*it)->set_register_uri(true); |
MACRUM | 0:119624335925 | 146 | } |
MACRUM | 0:119624335925 | 147 | } |
MACRUM | 0:119624335925 | 148 | |
MACRUM | 0:119624335925 | 149 | /* Add Device Object to object list. */ |
MACRUM | 0:119624335925 | 150 | _client_objs->push_back(device_object); |
MACRUM | 0:119624335925 | 151 | } |
MACRUM | 0:119624335925 | 152 | |
MACRUM | 0:119624335925 | 153 | internal_event(State_Bootstrap); |
MACRUM | 0:119624335925 | 154 | } else if (_current_state == State_Success) { |
MACRUM | 0:119624335925 | 155 | state_success(); |
MACRUM | 0:119624335925 | 156 | } |
MACRUM | 0:119624335925 | 157 | } |
MACRUM | 0:119624335925 | 158 | |
MACRUM | 0:119624335925 | 159 | ConnectorClient &ServiceClient::connector_client() |
MACRUM | 0:119624335925 | 160 | { |
MACRUM | 0:119624335925 | 161 | return _connector_client; |
MACRUM | 0:119624335925 | 162 | } |
MACRUM | 0:119624335925 | 163 | |
MACRUM | 0:119624335925 | 164 | const ConnectorClient &ServiceClient::connector_client() const |
MACRUM | 0:119624335925 | 165 | { |
MACRUM | 0:119624335925 | 166 | return _connector_client; |
MACRUM | 0:119624335925 | 167 | } |
MACRUM | 0:119624335925 | 168 | |
MACRUM | 0:119624335925 | 169 | // generates an internal event. called from within a state |
MACRUM | 0:119624335925 | 170 | // function to transition to a new state |
MACRUM | 0:119624335925 | 171 | void ServiceClient::internal_event(StartupMainState new_state) |
MACRUM | 0:119624335925 | 172 | { |
MACRUM | 0:119624335925 | 173 | tr_debug("ServiceClient::internal_event: state: %d -> %d", _current_state, new_state); |
MACRUM | 0:119624335925 | 174 | |
MACRUM | 0:119624335925 | 175 | _event_generated = true; |
MACRUM | 0:119624335925 | 176 | _current_state = new_state; |
MACRUM | 0:119624335925 | 177 | |
MACRUM | 0:119624335925 | 178 | if (!_state_engine_running) { |
MACRUM | 0:119624335925 | 179 | state_engine(); |
MACRUM | 0:119624335925 | 180 | } |
MACRUM | 0:119624335925 | 181 | } |
MACRUM | 0:119624335925 | 182 | |
MACRUM | 0:119624335925 | 183 | // the state engine executes the state machine states |
MACRUM | 0:119624335925 | 184 | void ServiceClient::state_engine(void) |
MACRUM | 0:119624335925 | 185 | { |
MACRUM | 0:119624335925 | 186 | tr_debug("ServiceClient::state_engine"); |
MACRUM | 0:119624335925 | 187 | |
MACRUM | 0:119624335925 | 188 | // this simple flagging gets rid of recursive calls to this method |
MACRUM | 0:119624335925 | 189 | _state_engine_running = true; |
MACRUM | 0:119624335925 | 190 | |
MACRUM | 0:119624335925 | 191 | // while events are being generated keep executing states |
MACRUM | 0:119624335925 | 192 | while (_event_generated) { |
MACRUM | 0:119624335925 | 193 | _event_generated = false; // event used up, reset flag |
MACRUM | 0:119624335925 | 194 | |
MACRUM | 0:119624335925 | 195 | state_function(_current_state); |
MACRUM | 0:119624335925 | 196 | } |
MACRUM | 0:119624335925 | 197 | |
MACRUM | 0:119624335925 | 198 | _state_engine_running = false; |
MACRUM | 0:119624335925 | 199 | } |
MACRUM | 0:119624335925 | 200 | |
MACRUM | 0:119624335925 | 201 | void ServiceClient::state_function(StartupMainState current_state) |
MACRUM | 0:119624335925 | 202 | { |
MACRUM | 0:119624335925 | 203 | switch (current_state) { |
MACRUM | 0:119624335925 | 204 | case State_Init: // -> Goes to bootstrap state |
MACRUM | 0:119624335925 | 205 | case State_Bootstrap: // -> State_Register OR State_Failure |
MACRUM | 0:119624335925 | 206 | state_bootstrap(); |
MACRUM | 0:119624335925 | 207 | break; |
MACRUM | 0:119624335925 | 208 | case State_Register: // -> State_Succes OR State_Failure |
MACRUM | 0:119624335925 | 209 | state_register(); |
MACRUM | 0:119624335925 | 210 | break; |
MACRUM | 0:119624335925 | 211 | case State_Success: // return success to user |
MACRUM | 0:119624335925 | 212 | state_success(); |
MACRUM | 0:119624335925 | 213 | break; |
MACRUM | 0:119624335925 | 214 | case State_Failure: // return error to user |
MACRUM | 0:119624335925 | 215 | state_failure(); |
MACRUM | 0:119624335925 | 216 | break; |
MACRUM | 0:119624335925 | 217 | case State_Unregister: // return error to user |
MACRUM | 0:119624335925 | 218 | state_unregister(); |
MACRUM | 0:119624335925 | 219 | break; |
MACRUM | 0:119624335925 | 220 | } |
MACRUM | 0:119624335925 | 221 | } |
MACRUM | 0:119624335925 | 222 | |
MACRUM | 0:119624335925 | 223 | void ServiceClient::state_bootstrap() |
MACRUM | 0:119624335925 | 224 | { |
MACRUM | 0:119624335925 | 225 | tr_info("ServiceClient::state_bootstrap()"); |
MACRUM | 0:119624335925 | 226 | bool credentials_ready = _connector_client.connector_credentials_available(); |
MACRUM | 0:119624335925 | 227 | bool bootstrap = _connector_client.use_bootstrap(); |
MACRUM | 0:119624335925 | 228 | tr_info("ServiceClient::state_bootstrap() - lwm2m credentials available: %d", credentials_ready); |
MACRUM | 0:119624335925 | 229 | tr_info("ServiceClient::state_bootstrap() - use bootstrap: %d", bootstrap); |
MACRUM | 0:119624335925 | 230 | if (credentials_ready || !bootstrap) { |
MACRUM | 0:119624335925 | 231 | internal_event(State_Register); |
MACRUM | 0:119624335925 | 232 | } else { |
MACRUM | 0:119624335925 | 233 | _connector_client.start_bootstrap(); |
MACRUM | 0:119624335925 | 234 | } |
MACRUM | 0:119624335925 | 235 | } |
MACRUM | 0:119624335925 | 236 | |
MACRUM | 0:119624335925 | 237 | void ServiceClient::state_register() |
MACRUM | 0:119624335925 | 238 | { |
MACRUM | 0:119624335925 | 239 | tr_info("ServiceClient::state_register()"); |
MACRUM | 0:119624335925 | 240 | _connector_client.start_registration(_client_objs); |
MACRUM | 0:119624335925 | 241 | } |
MACRUM | 0:119624335925 | 242 | |
MACRUM | 0:119624335925 | 243 | void ServiceClient::registration_process_result(ConnectorClient::StartupSubStateRegistration status) |
MACRUM | 0:119624335925 | 244 | { |
MACRUM | 0:119624335925 | 245 | tr_debug("ServiceClient::registration_process_result(): status: %d", status); |
MACRUM | 0:119624335925 | 246 | if (status == ConnectorClient::State_Registration_Success) { |
MACRUM | 0:119624335925 | 247 | internal_event(State_Success); |
MACRUM | 0:119624335925 | 248 | } else if(status == ConnectorClient::State_Registration_Failure || |
MACRUM | 0:119624335925 | 249 | status == ConnectorClient::State_Bootstrap_Failure){ |
MACRUM | 0:119624335925 | 250 | internal_event(State_Failure); // XXX: the status should be saved to eg. event object |
MACRUM | 0:119624335925 | 251 | } |
MACRUM | 0:119624335925 | 252 | if(status == ConnectorClient::State_Bootstrap_Success) { |
MACRUM | 0:119624335925 | 253 | internal_event(State_Register); |
MACRUM | 0:119624335925 | 254 | } |
MACRUM | 0:119624335925 | 255 | if(status == ConnectorClient::State_Unregistered) { |
MACRUM | 0:119624335925 | 256 | internal_event(State_Unregister); |
MACRUM | 0:119624335925 | 257 | } |
MACRUM | 0:119624335925 | 258 | if (status == ConnectorClient::State_Registration_Updated) { |
MACRUM | 0:119624335925 | 259 | _service_callback.complete(ServiceClientCallback::Service_Client_Status_Register_Updated); |
MACRUM | 0:119624335925 | 260 | } |
MACRUM | 0:119624335925 | 261 | } |
MACRUM | 0:119624335925 | 262 | |
MACRUM | 0:119624335925 | 263 | void ServiceClient::connector_error(M2MInterface::Error error, const char *reason) |
MACRUM | 0:119624335925 | 264 | { |
MACRUM | 0:119624335925 | 265 | tr_error("ServiceClient::connector_error() error %d", (int)error); |
MACRUM | 0:119624335925 | 266 | if (_current_state == State_Register) { |
MACRUM | 0:119624335925 | 267 | registration_process_result(ConnectorClient::State_Registration_Failure); |
MACRUM | 0:119624335925 | 268 | } |
MACRUM | 0:119624335925 | 269 | else if (_current_state == State_Bootstrap) { |
MACRUM | 0:119624335925 | 270 | registration_process_result(ConnectorClient::State_Bootstrap_Failure); |
MACRUM | 0:119624335925 | 271 | } |
MACRUM | 0:119624335925 | 272 | _service_callback.error(int(error),reason); |
MACRUM | 0:119624335925 | 273 | internal_event(State_Failure); |
MACRUM | 0:119624335925 | 274 | } |
MACRUM | 0:119624335925 | 275 | |
MACRUM | 0:119624335925 | 276 | void ServiceClient::value_updated(M2MBase *base, M2MBase::BaseType type) |
MACRUM | 0:119624335925 | 277 | { |
MACRUM | 0:119624335925 | 278 | tr_debug("ServiceClient::value_updated()"); |
MACRUM | 0:119624335925 | 279 | _service_callback.value_updated(base, type); |
MACRUM | 0:119624335925 | 280 | } |
MACRUM | 0:119624335925 | 281 | |
MACRUM | 0:119624335925 | 282 | void ServiceClient::state_success() |
MACRUM | 0:119624335925 | 283 | { |
MACRUM | 0:119624335925 | 284 | tr_info("ServiceClient::state_success()"); |
MACRUM | 0:119624335925 | 285 | // this is verified already at client API level, but this might still catch some logic failures |
MACRUM | 0:119624335925 | 286 | _service_callback.complete(ServiceClientCallback::Service_Client_Status_Registered); |
MACRUM | 0:119624335925 | 287 | } |
MACRUM | 0:119624335925 | 288 | |
MACRUM | 0:119624335925 | 289 | void ServiceClient::state_failure() |
MACRUM | 0:119624335925 | 290 | { |
MACRUM | 0:119624335925 | 291 | tr_error("ServiceClient::state_failure()"); |
MACRUM | 0:119624335925 | 292 | _service_callback.complete(ServiceClientCallback::Service_Client_Status_Failure); |
MACRUM | 0:119624335925 | 293 | } |
MACRUM | 0:119624335925 | 294 | |
MACRUM | 0:119624335925 | 295 | void ServiceClient::state_unregister() |
MACRUM | 0:119624335925 | 296 | { |
MACRUM | 0:119624335925 | 297 | tr_debug("ServiceClient::state_unregister()"); |
MACRUM | 0:119624335925 | 298 | _service_callback.complete(ServiceClientCallback::Service_Client_Status_Unregistered); |
MACRUM | 0:119624335925 | 299 | } |
MACRUM | 0:119624335925 | 300 | |
MACRUM | 0:119624335925 | 301 | M2MDevice* ServiceClient::device_object_from_storage() |
MACRUM | 0:119624335925 | 302 | { |
MACRUM | 0:119624335925 | 303 | M2MDevice *device_object = M2MInterfaceFactory::create_device(); |
MACRUM | 0:119624335925 | 304 | if (device_object == NULL) { |
MACRUM | 0:119624335925 | 305 | return NULL; |
MACRUM | 0:119624335925 | 306 | } |
MACRUM | 0:119624335925 | 307 | |
MACRUM | 0:119624335925 | 308 | const size_t buffer_size = 128; |
MACRUM | 0:119624335925 | 309 | uint8_t buffer[buffer_size]; |
MACRUM | 0:119624335925 | 310 | size_t size = 0; |
MACRUM | 0:119624335925 | 311 | |
MACRUM | 0:119624335925 | 312 | #ifdef MBED_CLOUD_CLIENT_SUPPORT_UPDATE |
MACRUM | 0:119624335925 | 313 | uint8_t guid[sizeof(arm_uc_guid_t)] = {0}; |
MACRUM | 0:119624335925 | 314 | // Read out the binary Vendor UUID |
MACRUM | 0:119624335925 | 315 | ccs_status_e status = (ccs_status_e)UpdateClient::getVendorId(guid, sizeof(arm_uc_guid_t), &size); |
MACRUM | 0:119624335925 | 316 | |
MACRUM | 0:119624335925 | 317 | // Format the binary Vendor UUID into a hex string |
MACRUM | 0:119624335925 | 318 | if (status == CCS_STATUS_SUCCESS) { |
MACRUM | 0:119624335925 | 319 | size_t j = 0; |
MACRUM | 0:119624335925 | 320 | for(size_t i = 0; i < size; i++) |
MACRUM | 0:119624335925 | 321 | { |
MACRUM | 0:119624335925 | 322 | buffer[j++] = hex_table[(guid[i] >> 4) & 0xF]; |
MACRUM | 0:119624335925 | 323 | buffer[j++] = hex_table[(guid[i] >> 0) & 0xF]; |
MACRUM | 0:119624335925 | 324 | } |
MACRUM | 0:119624335925 | 325 | buffer[j] = '\0'; |
MACRUM | 0:119624335925 | 326 | device_object->create_resource(M2MDevice::Manufacturer, String((char*)buffer, size * 2)); |
MACRUM | 0:119624335925 | 327 | } |
MACRUM | 0:119624335925 | 328 | |
MACRUM | 0:119624335925 | 329 | // Read out the binary Class UUID |
MACRUM | 0:119624335925 | 330 | status = (ccs_status_e)UpdateClient::getClassId(guid, sizeof(arm_uc_guid_t), &size); |
MACRUM | 0:119624335925 | 331 | |
MACRUM | 0:119624335925 | 332 | // Format the binary Class UUID into a hex string |
MACRUM | 0:119624335925 | 333 | if (status == CCS_STATUS_SUCCESS) { |
MACRUM | 0:119624335925 | 334 | size_t j = 0; |
MACRUM | 0:119624335925 | 335 | for(size_t i = 0; i < size; i++) |
MACRUM | 0:119624335925 | 336 | { |
MACRUM | 0:119624335925 | 337 | buffer[j++] = hex_table[(guid[i] >> 4) & 0xF]; |
MACRUM | 0:119624335925 | 338 | buffer[j++] = hex_table[(guid[i] >> 0) & 0xF]; |
MACRUM | 0:119624335925 | 339 | } |
MACRUM | 0:119624335925 | 340 | buffer[j] = '\0'; |
MACRUM | 0:119624335925 | 341 | device_object->create_resource(M2MDevice::ModelNumber, String((char*)buffer, size * 2)); |
MACRUM | 0:119624335925 | 342 | } |
MACRUM | 0:119624335925 | 343 | #else |
MACRUM | 0:119624335925 | 344 | ccs_status_e status = get_config_parameter(g_fcc_manufacturer_parameter_name, buffer, buffer_size, &size); |
MACRUM | 0:119624335925 | 345 | if (status == CCS_STATUS_SUCCESS) { |
MACRUM | 0:119624335925 | 346 | device_object->create_resource(M2MDevice::Manufacturer, String((char*)buffer, size)); |
MACRUM | 0:119624335925 | 347 | } |
MACRUM | 0:119624335925 | 348 | status = get_config_parameter(g_fcc_model_number_parameter_name, buffer, buffer_size, &size); |
MACRUM | 0:119624335925 | 349 | if (status == CCS_STATUS_SUCCESS) { |
MACRUM | 0:119624335925 | 350 | device_object->create_resource(M2MDevice::ModelNumber, String((char*)buffer, size)); |
MACRUM | 0:119624335925 | 351 | } |
MACRUM | 0:119624335925 | 352 | #endif |
MACRUM | 0:119624335925 | 353 | status = get_config_parameter(g_fcc_device_serial_number_parameter_name, buffer, buffer_size, &size); |
MACRUM | 0:119624335925 | 354 | if (status == CCS_STATUS_SUCCESS) { |
MACRUM | 0:119624335925 | 355 | device_object->create_resource(M2MDevice::SerialNumber, String((char*)buffer, size)); |
MACRUM | 0:119624335925 | 356 | } |
MACRUM | 0:119624335925 | 357 | status = get_config_parameter(g_fcc_device_type_parameter_name, buffer, buffer_size, &size); |
MACRUM | 0:119624335925 | 358 | if (status == CCS_STATUS_SUCCESS) { |
MACRUM | 0:119624335925 | 359 | device_object->create_resource(M2MDevice::DeviceType, String((char*)buffer, size)); |
MACRUM | 0:119624335925 | 360 | } |
MACRUM | 0:119624335925 | 361 | status = get_config_parameter(g_fcc_hardware_version_parameter_name, buffer, buffer_size, &size); |
MACRUM | 0:119624335925 | 362 | if (status == CCS_STATUS_SUCCESS) { |
MACRUM | 0:119624335925 | 363 | device_object->create_resource(M2MDevice::HardwareVersion, String((char*)buffer, size)); |
MACRUM | 0:119624335925 | 364 | } |
MACRUM | 0:119624335925 | 365 | status = get_config_parameter(KEY_DEVICE_SOFTWAREVERSION, buffer, buffer_size, &size); |
MACRUM | 0:119624335925 | 366 | if (status == CCS_STATUS_SUCCESS) { |
MACRUM | 0:119624335925 | 367 | device_object->create_resource(M2MDevice::SoftwareVersion, String((char*)buffer, size)); |
MACRUM | 0:119624335925 | 368 | } |
MACRUM | 0:119624335925 | 369 | uint8_t data[4] = {0}; |
MACRUM | 0:119624335925 | 370 | uint32_t value; |
MACRUM | 0:119624335925 | 371 | status = get_config_parameter(g_fcc_memory_size_parameter_name, data, 4, &size); |
MACRUM | 0:119624335925 | 372 | if (status == CCS_STATUS_SUCCESS) { |
MACRUM | 0:119624335925 | 373 | memcpy(&value, data, 4); |
MACRUM | 0:119624335925 | 374 | device_object->create_resource(M2MDevice::MemoryTotal, value); |
MACRUM | 0:119624335925 | 375 | tr_debug("ServiceClient::device_object_from_storage() - setting memory total value %" PRIu32 " (%s)", value, tr_array(data, 4)); |
MACRUM | 0:119624335925 | 376 | } |
MACRUM | 0:119624335925 | 377 | status = get_config_parameter(g_fcc_current_time_parameter_name, data, 4, &size); |
MACRUM | 0:119624335925 | 378 | if (status == CCS_STATUS_SUCCESS) { |
MACRUM | 0:119624335925 | 379 | memcpy(&value, data, 4); |
MACRUM | 0:119624335925 | 380 | device_object->create_resource(M2MDevice::CurrentTime, value); |
MACRUM | 0:119624335925 | 381 | tr_debug("ServiceClient::device_object_from_storage() - setting current time value %" PRIu32 " (%s)", value, tr_array(data, 4)); |
MACRUM | 0:119624335925 | 382 | } |
MACRUM | 0:119624335925 | 383 | status = get_config_parameter(g_fcc_device_time_zone_parameter_name, buffer, buffer_size, &size); |
MACRUM | 0:119624335925 | 384 | if (status == CCS_STATUS_SUCCESS) { |
MACRUM | 0:119624335925 | 385 | device_object->create_resource(M2MDevice::Timezone, String((char*)buffer, size)); |
MACRUM | 0:119624335925 | 386 | } |
MACRUM | 0:119624335925 | 387 | status = get_config_parameter(g_fcc_offset_from_utc_parameter_name, buffer, buffer_size, &size); |
MACRUM | 0:119624335925 | 388 | if (status == CCS_STATUS_SUCCESS) { |
MACRUM | 0:119624335925 | 389 | device_object->create_resource(M2MDevice::UTCOffset, String((char*)buffer, size)); |
MACRUM | 0:119624335925 | 390 | } |
MACRUM | 0:119624335925 | 391 | return device_object; |
MACRUM | 0:119624335925 | 392 | } |
MACRUM | 0:119624335925 | 393 | |
MACRUM | 0:119624335925 | 394 | /** |
MACRUM | 0:119624335925 | 395 | * \brief Set resource value in the Device Object |
MACRUM | 0:119624335925 | 396 | * |
MACRUM | 0:119624335925 | 397 | * \param resource Device enum to have value set. |
MACRUM | 0:119624335925 | 398 | * \param value String object. |
MACRUM | 0:119624335925 | 399 | * \return True if successful, false otherwise. |
MACRUM | 0:119624335925 | 400 | */ |
MACRUM | 0:119624335925 | 401 | bool ServiceClient::set_device_resource_value(M2MDevice::DeviceResource resource, |
MACRUM | 0:119624335925 | 402 | const std::string& value) |
MACRUM | 0:119624335925 | 403 | { |
MACRUM | 0:119624335925 | 404 | return set_device_resource_value(resource, |
MACRUM | 0:119624335925 | 405 | value.c_str(), |
MACRUM | 0:119624335925 | 406 | value.size() - 1); |
MACRUM | 0:119624335925 | 407 | } |
MACRUM | 0:119624335925 | 408 | |
MACRUM | 0:119624335925 | 409 | /** |
MACRUM | 0:119624335925 | 410 | * \brief Set resource value in the Device Object |
MACRUM | 0:119624335925 | 411 | * |
MACRUM | 0:119624335925 | 412 | * \param resource Device enum to have value set. |
MACRUM | 0:119624335925 | 413 | * \param value Byte buffer. |
MACRUM | 0:119624335925 | 414 | * \param length Buffer length. |
MACRUM | 0:119624335925 | 415 | * \return True if successful, false otherwise. |
MACRUM | 0:119624335925 | 416 | */ |
MACRUM | 0:119624335925 | 417 | bool ServiceClient::set_device_resource_value(M2MDevice::DeviceResource resource, |
MACRUM | 0:119624335925 | 418 | const char* value, |
MACRUM | 0:119624335925 | 419 | uint32_t length) |
MACRUM | 0:119624335925 | 420 | { |
MACRUM | 0:119624335925 | 421 | bool retval = false; |
MACRUM | 0:119624335925 | 422 | |
MACRUM | 0:119624335925 | 423 | /* sanity check */ |
MACRUM | 0:119624335925 | 424 | if (value && (length < 256) && (length > 0)) |
MACRUM | 0:119624335925 | 425 | { |
MACRUM | 0:119624335925 | 426 | #ifdef MBED_CLOUD_CLIENT_SUPPORT_UPDATE |
MACRUM | 0:119624335925 | 427 | /* Pass resource value to Update Client. |
MACRUM | 0:119624335925 | 428 | Used for validating the manifest. |
MACRUM | 0:119624335925 | 429 | */ |
MACRUM | 0:119624335925 | 430 | switch (resource) { |
MACRUM | 0:119624335925 | 431 | case M2MDevice::Manufacturer: |
MACRUM | 0:119624335925 | 432 | ARM_UC_SetVendorId((const uint8_t*) value, length); |
MACRUM | 0:119624335925 | 433 | break; |
MACRUM | 0:119624335925 | 434 | case M2MDevice::ModelNumber: |
MACRUM | 0:119624335925 | 435 | ARM_UC_SetClassId((const uint8_t*) value, length); |
MACRUM | 0:119624335925 | 436 | break; |
MACRUM | 0:119624335925 | 437 | default: |
MACRUM | 0:119624335925 | 438 | break; |
MACRUM | 0:119624335925 | 439 | } |
MACRUM | 0:119624335925 | 440 | #endif |
MACRUM | 0:119624335925 | 441 | |
MACRUM | 0:119624335925 | 442 | /* Convert resource to printable string if necessary */ |
MACRUM | 0:119624335925 | 443 | |
MACRUM | 0:119624335925 | 444 | /* Getting object instance from factory */ |
MACRUM | 0:119624335925 | 445 | M2MDevice *device_object = M2MInterfaceFactory::create_device(); |
MACRUM | 0:119624335925 | 446 | |
MACRUM | 0:119624335925 | 447 | /* Check device object and resource both are present */ |
MACRUM | 0:119624335925 | 448 | if (device_object && device_object->is_resource_present(resource)) { |
MACRUM | 0:119624335925 | 449 | /* set counter to not-zero */ |
MACRUM | 0:119624335925 | 450 | uint8_t printable_length = 0xFF; |
MACRUM | 0:119624335925 | 451 | |
MACRUM | 0:119624335925 | 452 | /* set printable_length to 0 if the buffer is not printable */ |
MACRUM | 0:119624335925 | 453 | for (uint8_t index = 0; index < length; index++) { |
MACRUM | 0:119624335925 | 454 | /* break if character is not printable */ |
MACRUM | 0:119624335925 | 455 | if ((value[index] < ' ') || (value[index] > '~')) { |
MACRUM | 0:119624335925 | 456 | printable_length = 0; |
MACRUM | 0:119624335925 | 457 | break; |
MACRUM | 0:119624335925 | 458 | } |
MACRUM | 0:119624335925 | 459 | } |
MACRUM | 0:119624335925 | 460 | |
MACRUM | 0:119624335925 | 461 | /* resource is a string */ |
MACRUM | 0:119624335925 | 462 | if (printable_length != 0) { |
MACRUM | 0:119624335925 | 463 | /* reset counter */ |
MACRUM | 0:119624335925 | 464 | printable_length = 0; |
MACRUM | 0:119624335925 | 465 | |
MACRUM | 0:119624335925 | 466 | /* find actual printable length */ |
MACRUM | 0:119624335925 | 467 | for ( ; printable_length < length; printable_length++) { |
MACRUM | 0:119624335925 | 468 | /* break prematurely if end-of-string character is found */ |
MACRUM | 0:119624335925 | 469 | if (value[printable_length] == '\0') { |
MACRUM | 0:119624335925 | 470 | break; |
MACRUM | 0:119624335925 | 471 | } |
MACRUM | 0:119624335925 | 472 | } |
MACRUM | 0:119624335925 | 473 | |
MACRUM | 0:119624335925 | 474 | /* convert to string and set value in object */ |
MACRUM | 0:119624335925 | 475 | String string_value(value, printable_length); |
MACRUM | 0:119624335925 | 476 | retval = device_object->set_resource_value(resource, string_value); |
MACRUM | 0:119624335925 | 477 | } |
MACRUM | 0:119624335925 | 478 | else |
MACRUM | 0:119624335925 | 479 | { |
MACRUM | 0:119624335925 | 480 | /* resource is a byte array */ |
MACRUM | 0:119624335925 | 481 | char value_buffer[0xFF] = { 0 }; |
MACRUM | 0:119624335925 | 482 | |
MACRUM | 0:119624335925 | 483 | /* count length */ |
MACRUM | 0:119624335925 | 484 | uint8_t index = 0; |
MACRUM | 0:119624335925 | 485 | |
MACRUM | 0:119624335925 | 486 | /* convert byte array to string */ |
MACRUM | 0:119624335925 | 487 | for ( ; |
MACRUM | 0:119624335925 | 488 | (index < length) && ((2*index +1) < 0xFF); |
MACRUM | 0:119624335925 | 489 | index++) { |
MACRUM | 0:119624335925 | 490 | |
MACRUM | 0:119624335925 | 491 | uint8_t byte = value[index]; |
MACRUM | 0:119624335925 | 492 | |
MACRUM | 0:119624335925 | 493 | value_buffer[2 * index] = hex_table[byte >> 4]; |
MACRUM | 0:119624335925 | 494 | value_buffer[2 * index + 1] = hex_table[byte & 0x0F]; |
MACRUM | 0:119624335925 | 495 | } |
MACRUM | 0:119624335925 | 496 | |
MACRUM | 0:119624335925 | 497 | /* convert to string and set value in object */ |
MACRUM | 0:119624335925 | 498 | String string_value(value_buffer, 2 * (index - 1)); |
MACRUM | 0:119624335925 | 499 | retval = device_object->set_resource_value(resource, string_value); |
MACRUM | 0:119624335925 | 500 | } |
MACRUM | 0:119624335925 | 501 | } |
MACRUM | 0:119624335925 | 502 | } |
MACRUM | 0:119624335925 | 503 | |
MACRUM | 0:119624335925 | 504 | return retval; |
MACRUM | 0:119624335925 | 505 | } |
MACRUM | 0:119624335925 | 506 | |
MACRUM | 0:119624335925 | 507 | #ifdef MBED_CLOUD_CLIENT_SUPPORT_UPDATE |
MACRUM | 0:119624335925 | 508 | void ServiceClient::set_update_authorize_handler(void (*handler)(int32_t request)) |
MACRUM | 0:119624335925 | 509 | { |
MACRUM | 0:119624335925 | 510 | UpdateClient::set_update_authorize_handler(handler); |
MACRUM | 0:119624335925 | 511 | } |
MACRUM | 0:119624335925 | 512 | |
MACRUM | 0:119624335925 | 513 | void ServiceClient::update_authorize(int32_t request) |
MACRUM | 0:119624335925 | 514 | { |
MACRUM | 0:119624335925 | 515 | UpdateClient::update_authorize(request); |
MACRUM | 0:119624335925 | 516 | } |
MACRUM | 0:119624335925 | 517 | |
MACRUM | 0:119624335925 | 518 | void ServiceClient::set_update_progress_handler(void (*handler)(uint32_t progress, uint32_t total)) |
MACRUM | 0:119624335925 | 519 | { |
MACRUM | 0:119624335925 | 520 | UpdateClient::set_update_progress_handler(handler); |
MACRUM | 0:119624335925 | 521 | } |
MACRUM | 0:119624335925 | 522 | |
MACRUM | 0:119624335925 | 523 | void ServiceClient::update_error_callback(int32_t error) |
MACRUM | 0:119624335925 | 524 | { |
MACRUM | 0:119624335925 | 525 | _service_callback.error(error, ERROR_UPDATE); |
MACRUM | 0:119624335925 | 526 | } |
MACRUM | 0:119624335925 | 527 | #endif |