Committer:
leothedragon
Date:
Sun Apr 18 15:20:23 2021 +0000
Revision:
0:25fa8795676b
DS

Who changed what in which revision?

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