Dependencies:   MMA7660 LM75B

Committer:
MACRUM
Date:
Sat Jun 30 01:40:30 2018 +0000
Revision:
0:119624335925
Initial commit

Who changed what in which revision?

UserRevisionLine numberNew 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 // Needed for PRIu64 on FreeRTOS
MACRUM 0:119624335925 20 #include <stdio.h>
MACRUM 0:119624335925 21 // Note: this macro is needed on armcc to get the the limit macros like UINT16_MAX
MACRUM 0:119624335925 22 #ifndef __STDC_LIMIT_MACROS
MACRUM 0:119624335925 23 #define __STDC_LIMIT_MACROS
MACRUM 0:119624335925 24 #endif
MACRUM 0:119624335925 25
MACRUM 0:119624335925 26 // Note: this macro is needed on armcc to get the the PRI*32 macros
MACRUM 0:119624335925 27 // from inttypes.h in a C++ code.
MACRUM 0:119624335925 28 #ifndef __STDC_FORMAT_MACROS
MACRUM 0:119624335925 29 #define __STDC_FORMAT_MACROS
MACRUM 0:119624335925 30 #endif
MACRUM 0:119624335925 31
MACRUM 0:119624335925 32 #ifdef MBED_CLOUD_CLIENT_USER_CONFIG_FILE
MACRUM 0:119624335925 33 #include MBED_CLOUD_CLIENT_USER_CONFIG_FILE
MACRUM 0:119624335925 34 #endif
MACRUM 0:119624335925 35
MACRUM 0:119624335925 36 #ifdef MBED_CLOUD_CLIENT_SUPPORT_UPDATE
MACRUM 0:119624335925 37 #include "update-client-hub/update_client_hub.h"
MACRUM 0:119624335925 38
MACRUM 0:119624335925 39 #include "update-client-source-http/arm_uc_source_http.h"
MACRUM 0:119624335925 40 #include "update-client-lwm2m/lwm2m-source.h"
MACRUM 0:119624335925 41 #include "update-client-lwm2m/lwm2m-monitor.h"
MACRUM 0:119624335925 42 #include "update-client-lwm2m/lwm2m-control.h"
MACRUM 0:119624335925 43 #include "update-client-lwm2m/FirmwareUpdateResource.h"
MACRUM 0:119624335925 44 #include "update-client-lwm2m/DeviceMetadataResource.h"
MACRUM 0:119624335925 45
MACRUM 0:119624335925 46 #include "eventOS_scheduler.h"
MACRUM 0:119624335925 47 #include "eventOS_event.h"
MACRUM 0:119624335925 48
MACRUM 0:119624335925 49 #include "include/UpdateClient.h"
MACRUM 0:119624335925 50 #include "include/UpdateClientResources.h"
MACRUM 0:119624335925 51 #include "include/CloudClientStorage.h"
MACRUM 0:119624335925 52
MACRUM 0:119624335925 53 #include "pal.h"
MACRUM 0:119624335925 54
MACRUM 0:119624335925 55 #if (!defined(MBED_CONF_MBED_TRACE_ENABLE) || MBED_CONF_MBED_TRACE_ENABLE == 0) \
MACRUM 0:119624335925 56 && ARM_UC_ALL_TRACE_ENABLE == 1
MACRUM 0:119624335925 57 #define tr_info(...) { printf(__VA_ARGS__); printf("\r\n"); }
MACRUM 0:119624335925 58 #else
MACRUM 0:119624335925 59 #include "mbed-trace/mbed_trace.h"
MACRUM 0:119624335925 60 #define TRACE_GROUP "uccc"
MACRUM 0:119624335925 61 #endif
MACRUM 0:119624335925 62
MACRUM 0:119624335925 63 /* To be removed once update storage is defined in user config file.
MACRUM 0:119624335925 64 Default to filesystem in the meantime.
MACRUM 0:119624335925 65 */
MACRUM 0:119624335925 66 #ifndef MBED_CLOUD_CLIENT_UPDATE_STORAGE
MACRUM 0:119624335925 67 #define MBED_CLOUD_CLIENT_UPDATE_STORAGE ARM_UCP_FILESYSTEM
MACRUM 0:119624335925 68 #endif
MACRUM 0:119624335925 69
MACRUM 0:119624335925 70 #ifdef MBED_CLOUD_CLIENT_UPDATE_STORAGE
MACRUM 0:119624335925 71 extern ARM_UC_PAAL_UPDATE MBED_CLOUD_CLIENT_UPDATE_STORAGE;
MACRUM 0:119624335925 72 #else
MACRUM 0:119624335925 73 #error Update client storage must be defined in user configuration file
MACRUM 0:119624335925 74 #endif
MACRUM 0:119624335925 75
MACRUM 0:119624335925 76 namespace UpdateClient
MACRUM 0:119624335925 77 {
MACRUM 0:119624335925 78 enum UpdateClientEventType {
MACRUM 0:119624335925 79 UPDATE_CLIENT_EVENT_INITIALIZE,
MACRUM 0:119624335925 80 UPDATE_CLIENT_EVENT_PROCESS_QUEUE
MACRUM 0:119624335925 81 };
MACRUM 0:119624335925 82
MACRUM 0:119624335925 83 static int8_t update_client_tasklet_id = -1;
MACRUM 0:119624335925 84 static FP1<void, int32_t> error_callback;
MACRUM 0:119624335925 85
MACRUM 0:119624335925 86 static void certificate_done(arm_uc_error_t error,
MACRUM 0:119624335925 87 const arm_uc_buffer_t* fingerprint);
MACRUM 0:119624335925 88 static void initialization(void);
MACRUM 0:119624335925 89 static void initialization_done(int32_t);
MACRUM 0:119624335925 90 static void event_handler(arm_event_s* event);
MACRUM 0:119624335925 91 static void queue_handler(void);
MACRUM 0:119624335925 92 static void schedule_event(void);
MACRUM 0:119624335925 93 static void error_handler(int32_t error);
MACRUM 0:119624335925 94 }
MACRUM 0:119624335925 95
MACRUM 0:119624335925 96 void UpdateClient::UpdateClient(FP1<void, int32_t> callback)
MACRUM 0:119624335925 97 {
MACRUM 0:119624335925 98 tr_info("Update Client External Initialization: %p", (void*)pal_osThreadGetId());
MACRUM 0:119624335925 99
MACRUM 0:119624335925 100 /* store callback handler */
MACRUM 0:119624335925 101 error_callback = callback;
MACRUM 0:119624335925 102
MACRUM 0:119624335925 103 /* create event */
MACRUM 0:119624335925 104 eventOS_scheduler_mutex_wait();
MACRUM 0:119624335925 105 if (update_client_tasklet_id == -1) {
MACRUM 0:119624335925 106 update_client_tasklet_id = eventOS_event_handler_create(UpdateClient::event_handler,
MACRUM 0:119624335925 107 UPDATE_CLIENT_EVENT_INITIALIZE);
MACRUM 0:119624335925 108
MACRUM 0:119624335925 109 tr_info("UpdateClient::update_client_tasklet_id: %d",
MACRUM 0:119624335925 110 update_client_tasklet_id);
MACRUM 0:119624335925 111 }
MACRUM 0:119624335925 112 eventOS_scheduler_mutex_release();
MACRUM 0:119624335925 113 }
MACRUM 0:119624335925 114
MACRUM 0:119624335925 115 /**
MACRUM 0:119624335925 116 * @brief Populate M2MObjectList with Update Client objects.
MACRUM 0:119624335925 117 */
MACRUM 0:119624335925 118 void UpdateClient::populate_object_list(M2MObjectList& list)
MACRUM 0:119624335925 119 {
MACRUM 0:119624335925 120 /* Setup Firmware Update LWM2M object */
MACRUM 0:119624335925 121 list.push_back(FirmwareUpdateResource::getObject());
MACRUM 0:119624335925 122 list.push_back(DeviceMetadataResource::getObject());
MACRUM 0:119624335925 123 }
MACRUM 0:119624335925 124
MACRUM 0:119624335925 125 void UpdateClient::set_update_authorize_handler(void (*handler)(int32_t request))
MACRUM 0:119624335925 126 {
MACRUM 0:119624335925 127 ARM_UC_SetAuthorizeHandler(handler);
MACRUM 0:119624335925 128 }
MACRUM 0:119624335925 129
MACRUM 0:119624335925 130 void UpdateClient::update_authorize(int32_t request)
MACRUM 0:119624335925 131 {
MACRUM 0:119624335925 132 switch (request)
MACRUM 0:119624335925 133 {
MACRUM 0:119624335925 134 case RequestDownload:
MACRUM 0:119624335925 135 ARM_UC_Authorize(ARM_UCCC_REQUEST_DOWNLOAD);
MACRUM 0:119624335925 136 break;
MACRUM 0:119624335925 137 case RequestInstall:
MACRUM 0:119624335925 138 ARM_UC_Authorize(ARM_UCCC_REQUEST_INSTALL);
MACRUM 0:119624335925 139 break;
MACRUM 0:119624335925 140 case RequestInvalid:
MACRUM 0:119624335925 141 default:
MACRUM 0:119624335925 142 break;
MACRUM 0:119624335925 143 }
MACRUM 0:119624335925 144 }
MACRUM 0:119624335925 145
MACRUM 0:119624335925 146 void UpdateClient::set_update_progress_handler(void (*handler)(uint32_t progress, uint32_t total))
MACRUM 0:119624335925 147 {
MACRUM 0:119624335925 148 ARM_UC_SetProgressHandler(handler);
MACRUM 0:119624335925 149 }
MACRUM 0:119624335925 150
MACRUM 0:119624335925 151 static void UpdateClient::initialization(void)
MACRUM 0:119624335925 152 {
MACRUM 0:119624335925 153 tr_info("internal initialization: %p", (void*)pal_osThreadGetId());
MACRUM 0:119624335925 154
MACRUM 0:119624335925 155 /* Register sources */
MACRUM 0:119624335925 156 static const ARM_UPDATE_SOURCE* sources[] = {
MACRUM 0:119624335925 157 &ARM_UCS_HTTPSource,
MACRUM 0:119624335925 158 &ARM_UCS_LWM2M_SOURCE
MACRUM 0:119624335925 159 };
MACRUM 0:119624335925 160
MACRUM 0:119624335925 161 ARM_UC_HUB_SetSources(sources, sizeof(sources)/sizeof(ARM_UPDATE_SOURCE*));
MACRUM 0:119624335925 162
MACRUM 0:119624335925 163 /* Register sink for telemetry */
MACRUM 0:119624335925 164 ARM_UC_HUB_AddMonitor(&ARM_UCS_LWM2M_MONITOR);
MACRUM 0:119624335925 165
MACRUM 0:119624335925 166 /* Register local error handler */
MACRUM 0:119624335925 167 ARM_UC_HUB_AddErrorCallback(UpdateClient::error_handler);
MACRUM 0:119624335925 168
MACRUM 0:119624335925 169 /* Link internal queue with external scheduler.
MACRUM 0:119624335925 170 The callback handler is called whenever a task is posted to
MACRUM 0:119624335925 171 an empty queue. This will trigger the queue to be processed.
MACRUM 0:119624335925 172 */
MACRUM 0:119624335925 173 ARM_UC_HUB_AddNotificationHandler(UpdateClient::queue_handler);
MACRUM 0:119624335925 174
MACRUM 0:119624335925 175 /* The override function enables the LWM2M Firmware Update Object
MACRUM 0:119624335925 176 to authorize both download and installation. The intention is
MACRUM 0:119624335925 177 that a buggy user application can't block an update.
MACRUM 0:119624335925 178 */
MACRUM 0:119624335925 179 ARM_UC_CONTROL_SetOverrideCallback(ARM_UC_OverrideAuthorization);
MACRUM 0:119624335925 180
MACRUM 0:119624335925 181 #ifdef MBED_CLOUD_CLIENT_UPDATE_STORAGE
MACRUM 0:119624335925 182 /* Set implementation for storing firmware */
MACRUM 0:119624335925 183 ARM_UC_HUB_SetStorage(&MBED_CLOUD_CLIENT_UPDATE_STORAGE);
MACRUM 0:119624335925 184 #endif
MACRUM 0:119624335925 185
MACRUM 0:119624335925 186 #ifdef MBED_CLOUD_DEV_UPDATE_PSK
MACRUM 0:119624335925 187 /* Add pre shared key */
MACRUM 0:119624335925 188 ARM_UC_AddPreSharedKey(arm_uc_default_psk, arm_uc_default_psk_bits);
MACRUM 0:119624335925 189 #endif
MACRUM 0:119624335925 190
MACRUM 0:119624335925 191 /* Insert default certificate if defined otherwise initialze
MACRUM 0:119624335925 192 Update client immediately.
MACRUM 0:119624335925 193 */
MACRUM 0:119624335925 194 #ifdef MBED_CLOUD_DEV_UPDATE_CERT
MACRUM 0:119624335925 195 /* Add verification certificate */
MACRUM 0:119624335925 196 arm_uc_error_t result = ARM_UC_AddCertificate(arm_uc_default_certificate,
MACRUM 0:119624335925 197 arm_uc_default_certificate_size,
MACRUM 0:119624335925 198 arm_uc_default_fingerprint,
MACRUM 0:119624335925 199 arm_uc_default_fingerprint_size,
MACRUM 0:119624335925 200 UpdateClient::certificate_done);
MACRUM 0:119624335925 201
MACRUM 0:119624335925 202 /* Certificate insertion failed, most likely because the certificate
MACRUM 0:119624335925 203 has already been inserted once before.
MACRUM 0:119624335925 204
MACRUM 0:119624335925 205 Continue initialization regardlessly, since the Update Client can still
MACRUM 0:119624335925 206 work if verification certificates are inserted through the Factory
MACRUM 0:119624335925 207 Client or by other means.
MACRUM 0:119624335925 208 */
MACRUM 0:119624335925 209 if (result.code != ARM_UC_CM_ERR_NONE)
MACRUM 0:119624335925 210 {
MACRUM 0:119624335925 211 tr_info("ARM_UC_AddCertificate failed");
MACRUM 0:119624335925 212
MACRUM 0:119624335925 213 ARM_UC_HUB_Initialize(UpdateClient::initialization_done);
MACRUM 0:119624335925 214 }
MACRUM 0:119624335925 215 #else
MACRUM 0:119624335925 216 ARM_UC_HUB_Initialize(UpdateClient::initialization_done);
MACRUM 0:119624335925 217 #endif
MACRUM 0:119624335925 218 }
MACRUM 0:119624335925 219
MACRUM 0:119624335925 220 static void UpdateClient::certificate_done(arm_uc_error_t error,
MACRUM 0:119624335925 221 const arm_uc_buffer_t* fingerprint)
MACRUM 0:119624335925 222 {
MACRUM 0:119624335925 223 (void) fingerprint;
MACRUM 0:119624335925 224
MACRUM 0:119624335925 225 /* Certificate insertion failure is not necessarily fatal.
MACRUM 0:119624335925 226 If verification certificates have been injected by other means
MACRUM 0:119624335925 227 it is still possible to perform updates, which is why the
MACRUM 0:119624335925 228 Update client initializes anyway.
MACRUM 0:119624335925 229 */
MACRUM 0:119624335925 230 if (error.code != ARM_UC_CM_ERR_NONE)
MACRUM 0:119624335925 231 {
MACRUM 0:119624335925 232 error_callback.call(WarningCertificateInsertion);
MACRUM 0:119624335925 233 }
MACRUM 0:119624335925 234
MACRUM 0:119624335925 235 ARM_UC_HUB_Initialize(UpdateClient::initialization_done);
MACRUM 0:119624335925 236 }
MACRUM 0:119624335925 237
MACRUM 0:119624335925 238 static void UpdateClient::initialization_done(int32_t result)
MACRUM 0:119624335925 239 {
MACRUM 0:119624335925 240 tr_info("internal initialization done: %" PRIu32 " %p", result, (void*)pal_osThreadGetId());
MACRUM 0:119624335925 241 }
MACRUM 0:119624335925 242
MACRUM 0:119624335925 243 static void UpdateClient::event_handler(arm_event_s* event)
MACRUM 0:119624335925 244 {
MACRUM 0:119624335925 245 switch (event->event_type)
MACRUM 0:119624335925 246 {
MACRUM 0:119624335925 247 case UPDATE_CLIENT_EVENT_INITIALIZE:
MACRUM 0:119624335925 248 UpdateClient::initialization();
MACRUM 0:119624335925 249 break;
MACRUM 0:119624335925 250
MACRUM 0:119624335925 251 case UPDATE_CLIENT_EVENT_PROCESS_QUEUE:
MACRUM 0:119624335925 252 {
MACRUM 0:119624335925 253 /* process a single callback, for better cooperability */
MACRUM 0:119624335925 254 bool queue_not_empty = ARM_UC_ProcessSingleCallback();
MACRUM 0:119624335925 255
MACRUM 0:119624335925 256 if (queue_not_empty)
MACRUM 0:119624335925 257 {
MACRUM 0:119624335925 258 /* reschedule event handler, if queue is not empty */
MACRUM 0:119624335925 259 UpdateClient::schedule_event();
MACRUM 0:119624335925 260 }
MACRUM 0:119624335925 261 }
MACRUM 0:119624335925 262 break;
MACRUM 0:119624335925 263
MACRUM 0:119624335925 264 default:
MACRUM 0:119624335925 265 break;
MACRUM 0:119624335925 266 }
MACRUM 0:119624335925 267 }
MACRUM 0:119624335925 268
MACRUM 0:119624335925 269 static void UpdateClient::queue_handler(void)
MACRUM 0:119624335925 270 {
MACRUM 0:119624335925 271 /* warning: queue_handler can be called from interrupt context.
MACRUM 0:119624335925 272 */
MACRUM 0:119624335925 273 UpdateClient::schedule_event();
MACRUM 0:119624335925 274 }
MACRUM 0:119624335925 275
MACRUM 0:119624335925 276 static void UpdateClient::schedule_event()
MACRUM 0:119624335925 277 {
MACRUM 0:119624335925 278 /* schedule event */
MACRUM 0:119624335925 279 arm_event_s event = {
MACRUM 0:119624335925 280 .receiver = update_client_tasklet_id,
MACRUM 0:119624335925 281 .sender = 0,
MACRUM 0:119624335925 282 .event_type = UPDATE_CLIENT_EVENT_PROCESS_QUEUE,
MACRUM 0:119624335925 283 .event_id = 0,
MACRUM 0:119624335925 284 .data_ptr = NULL,
MACRUM 0:119624335925 285 .priority = ARM_LIB_LOW_PRIORITY_EVENT,
MACRUM 0:119624335925 286 .event_data = 0,
MACRUM 0:119624335925 287 };
MACRUM 0:119624335925 288
MACRUM 0:119624335925 289 eventOS_event_send(&event);
MACRUM 0:119624335925 290 }
MACRUM 0:119624335925 291
MACRUM 0:119624335925 292 static void UpdateClient::error_handler(int32_t error)
MACRUM 0:119624335925 293 {
MACRUM 0:119624335925 294 tr_info("error reported: %" PRIi32, error);
MACRUM 0:119624335925 295
MACRUM 0:119624335925 296 /* add warning base if less severe than error */
MACRUM 0:119624335925 297 if (error < ARM_UC_ERROR)
MACRUM 0:119624335925 298 {
MACRUM 0:119624335925 299 error_callback.call(WarningBase + error);
MACRUM 0:119624335925 300 }
MACRUM 0:119624335925 301 /* add error base if less severe than fatal */
MACRUM 0:119624335925 302 else if (error < ARM_UC_FATAL)
MACRUM 0:119624335925 303 {
MACRUM 0:119624335925 304 error_callback.call(ErrorBase + error);
MACRUM 0:119624335925 305 }
MACRUM 0:119624335925 306 /* add fatal base */
MACRUM 0:119624335925 307 else
MACRUM 0:119624335925 308 {
MACRUM 0:119624335925 309 error_callback.call(FatalBase + error);
MACRUM 0:119624335925 310 }
MACRUM 0:119624335925 311 }
MACRUM 0:119624335925 312
MACRUM 0:119624335925 313 int UpdateClient::getVendorId(uint8_t* buffer, size_t buffer_size_max, size_t* value_size)
MACRUM 0:119624335925 314 {
MACRUM 0:119624335925 315 arm_uc_error_t err = ARM_UC_GetVendorId(buffer, buffer_size_max, value_size);
MACRUM 0:119624335925 316 if (err.code == ARM_UC_DI_ERR_SIZE)
MACRUM 0:119624335925 317 {
MACRUM 0:119624335925 318 return CCS_STATUS_MEMORY_ERROR;
MACRUM 0:119624335925 319 }
MACRUM 0:119624335925 320 if (err.error == ERR_NONE)
MACRUM 0:119624335925 321 {
MACRUM 0:119624335925 322 *value_size = 16;
MACRUM 0:119624335925 323 return CCS_STATUS_SUCCESS;
MACRUM 0:119624335925 324 }
MACRUM 0:119624335925 325 return CCS_STATUS_KEY_DOESNT_EXIST;
MACRUM 0:119624335925 326 }
MACRUM 0:119624335925 327 int UpdateClient::getClassId(uint8_t* buffer, size_t buffer_size_max, size_t* value_size)
MACRUM 0:119624335925 328 {
MACRUM 0:119624335925 329 arm_uc_error_t err = ARM_UC_GetClassId(buffer, buffer_size_max, value_size);
MACRUM 0:119624335925 330 if (err.code == ARM_UC_DI_ERR_SIZE)
MACRUM 0:119624335925 331 {
MACRUM 0:119624335925 332 return CCS_STATUS_MEMORY_ERROR;
MACRUM 0:119624335925 333 }
MACRUM 0:119624335925 334 if (err.error == ERR_NONE)
MACRUM 0:119624335925 335 {
MACRUM 0:119624335925 336 *value_size = 16;
MACRUM 0:119624335925 337 return CCS_STATUS_SUCCESS;
MACRUM 0:119624335925 338 }
MACRUM 0:119624335925 339 return CCS_STATUS_KEY_DOESNT_EXIST;
MACRUM 0:119624335925 340 }
MACRUM 0:119624335925 341 int UpdateClient::getDeviceId(uint8_t* buffer, size_t buffer_size_max, size_t* value_size)
MACRUM 0:119624335925 342 {
MACRUM 0:119624335925 343 arm_uc_error_t err = ARM_UC_GetDeviceId(buffer, buffer_size_max, value_size);
MACRUM 0:119624335925 344 if (err.code == ARM_UC_DI_ERR_SIZE)
MACRUM 0:119624335925 345 {
MACRUM 0:119624335925 346 return CCS_STATUS_MEMORY_ERROR;
MACRUM 0:119624335925 347 }
MACRUM 0:119624335925 348 if (err.error == ERR_NONE)
MACRUM 0:119624335925 349 {
MACRUM 0:119624335925 350 *value_size = 16;
MACRUM 0:119624335925 351 return CCS_STATUS_SUCCESS;
MACRUM 0:119624335925 352 }
MACRUM 0:119624335925 353 return CCS_STATUS_KEY_DOESNT_EXIST;
MACRUM 0:119624335925 354 }
MACRUM 0:119624335925 355
MACRUM 0:119624335925 356 #endif