Fork for workshops

Committer:
JimCarver
Date:
Fri Oct 12 21:22:49 2018 +0000
Revision:
0:6b753f761943
Initial commit

Who changed what in which revision?

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