Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: FXAS21002 FXOS8700Q
update_client_hub.c
00001 // ---------------------------------------------------------------------------- 00002 // Copyright 2016-2017 ARM Ltd. 00003 // 00004 // SPDX-License-Identifier: Apache-2.0 00005 // 00006 // Licensed under the Apache License, Version 2.0 (the "License"); 00007 // you may not use this file except in compliance with the License. 00008 // You may obtain a copy of the License at 00009 // 00010 // http://www.apache.org/licenses/LICENSE-2.0 00011 // 00012 // Unless required by applicable law or agreed to in writing, software 00013 // distributed under the License is distributed on an "AS IS" BASIS, 00014 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 // See the License for the specific language governing permissions and 00016 // limitations under the License. 00017 // ---------------------------------------------------------------------------- 00018 00019 #include "update-client-hub/update_client_hub.h" 00020 00021 #include "update-client-common/arm_uc_common.h" 00022 #include "update-client-control-center/arm_uc_control_center.h" 00023 #include "update-client-control-center/arm_uc_pre_shared_key.h" 00024 #include "update-client-control-center/arm_uc_certificate.h" 00025 #include "update-client-source-manager/arm_uc_source_manager.h" 00026 #include "update-client-firmware-manager/arm_uc_firmware_manager.h" 00027 #include "update-client-manifest-manager/update-client-manifest-manager.h" 00028 00029 #include "update_client_hub_state_machine.h" 00030 #include "update_client_hub_event_handlers.h" 00031 #include "update_client_hub_error_handler.h" 00032 00033 #include "pal4life-device-identity/pal_device_identity.h" 00034 00035 #define HANDLE_INIT_ERROR(retval, msg, ...)\ 00036 if (retval.error != ERR_NONE)\ 00037 {\ 00038 ARM_UC_HUB_setState(ARM_UC_HUB_STATE_UNINITIALIZED);\ 00039 UC_HUB_ERR_MSG(msg " error code %s", ##__VA_ARGS__, ARM_UC_err2Str(retval));\ 00040 return retval;\ 00041 } 00042 00043 static const ARM_UPDATE_SOURCE **arm_uc_sources = NULL; 00044 static uint8_t arm_uc_sources_size = 0; 00045 extern arm_uc_mmContext_t *pManifestManagerContext; 00046 00047 /** 00048 * @brief Handle any errors posted by the scheduler. 00049 * @details This explicitly runs *not* in interrupt context, the scheduler has a dedicated 00050 * callback structure to ensure it can post at least this event. 00051 * ARM_UC_HUB_ErrorHandler() will invoke the HUB callback that was set up. 00052 * It is up to the external application to go about inducing a reset etc, 00053 * if that is what it decides. Note that the HUB is no longer operable 00054 * and the app should probably Uninitialize it and report an error. 00055 * However, the HUB will attempt some cleanup after it returns. 00056 * @param an_event the type of the event causing the error callback. 00057 * The only possible errors from the scheduler are currently: 00058 * ARM_UC_EQ_ERR_POOL_EXHAUSTED 00059 * ARM_UC_EQ_ERR_FAILED_TAKE 00060 * These are passed on to the Hub error handler as an internal error, 00061 * and the hub state is now considered unknown from this perspective. 00062 * (An internal error is considered fatal by the hub.) 00063 */ 00064 void UC_HUB_scheduler_error_handler(uint32_t an_event) 00065 { 00066 UC_HUB_ERR_MSG("scheduler error: %" PRIu32, an_event); 00067 ARM_UC_HUB_ErrorHandler(HUB_ERR_INTERNAL_ERROR, ARM_UC_HUB_getState()); 00068 } 00069 00070 /** 00071 * @brief Call initialiser of all components of the client. 00072 * finish asynchronously, will invoke callback when initialization is done. 00073 * @param init_cb the callback to be invoked at the end of initialization. 00074 */ 00075 arm_uc_error_t ARM_UC_HUB_Initialize(void (*init_cb)(uintptr_t)) 00076 { 00077 arm_uc_error_t retval; 00078 00079 if (ARM_UC_HUB_getState() != ARM_UC_HUB_STATE_UNINITIALIZED) { 00080 UC_HUB_ERR_MSG("Already Initialized/Initializing"); 00081 return (arm_uc_error_t) { ERR_INVALID_STATE }; 00082 } 00083 ARM_UC_HUB_setState(ARM_UC_HUB_STATE_INITIALIZING); 00084 00085 ARM_UC_SchedulerInit(); 00086 ARM_UC_HUB_setInitializationCallback(init_cb); 00087 ARM_UC_SetSchedulerErrorHandler(UC_HUB_scheduler_error_handler); 00088 00089 /* Register event handler with Control Center. */ 00090 retval = ARM_UC_ControlCenter_Initialize(ARM_UC_HUB_ControlCenterEventHandler); 00091 HANDLE_INIT_ERROR(retval, "Control Center init failed") 00092 00093 /* Register event handler with Firmware Manager */ 00094 retval = ARM_UC_FirmwareManager.Initialize(ARM_UC_HUB_FirmwareManagerEventHandler); 00095 HANDLE_INIT_ERROR(retval, "Firmware Manager init failed") 00096 00097 /* Register event handler with Source Manager */ 00098 retval = ARM_UC_SourceManager.Initialize(ARM_UC_HUB_SourceManagerEventHandler); 00099 HANDLE_INIT_ERROR(retval, "Source Manager init failed") 00100 00101 for (uint8_t index = 0; index < arm_uc_sources_size; index++) { 00102 ARM_UC_SourceManager.AddSource(arm_uc_sources[index]); 00103 } 00104 00105 /* Register event handler and add config store implementation to manifest 00106 manager. 00107 */ 00108 retval = ARM_UC_mmInit(&pManifestManagerContext, 00109 ARM_UC_HUB_ManifestManagerEventHandler, 00110 NULL); 00111 HANDLE_INIT_ERROR(retval, "Manifest manager init failed") 00112 00113 /* add hard coded certificates to the manifest manager */ 00114 // retval = ARM_UC_mmStoreCertificate(CA_PATH, cert, CERT_SIZE); 00115 // if ((retval.error != ERR_NONE) && (retval.code != MFST_ERR_PENDING)) 00116 // { 00117 // HANDLE_INIT_ERROR(retval, "Manifest manager StoreCertificate failed") 00118 // } 00119 00120 return (arm_uc_error_t) { ERR_NONE }; 00121 } 00122 00123 /** 00124 * @brief Process events in the event queue. 00125 */ 00126 arm_uc_error_t ARM_UC_HUB_ProcessEvents() 00127 { 00128 ARM_UC_ProcessQueue(); 00129 00130 return (arm_uc_error_t) { ERR_NONE }; 00131 } 00132 00133 /** 00134 * @brief Register callback function for when callbacks are added to an empty queue. 00135 */ 00136 arm_uc_error_t ARM_UC_HUB_AddNotificationHandler(void (*handler)(void)) 00137 { 00138 ARM_UC_AddNotificationHandler(handler); 00139 00140 return (arm_uc_error_t) { ERR_NONE }; 00141 } 00142 00143 /** 00144 * @brief Add source to the Update Client. 00145 */ 00146 arm_uc_error_t ARM_UC_HUB_SetSources(const ARM_UPDATE_SOURCE *sources[], 00147 uint8_t size) 00148 { 00149 arm_uc_sources = sources; 00150 arm_uc_sources_size = size; 00151 00152 return (arm_uc_error_t) { ERR_NONE }; 00153 } 00154 00155 /** 00156 * Set PAAL Update implementation 00157 */ 00158 arm_uc_error_t ARM_UC_HUB_SetStorage(const ARM_UC_PAAL_UPDATE *implementation) 00159 { 00160 return ARM_UCP_SetPAALUpdate(implementation); 00161 } 00162 00163 /** 00164 * @brief Add monitor to the control center. 00165 */ 00166 arm_uc_error_t ARM_UC_HUB_AddMonitor(const ARM_UPDATE_MONITOR *monitor) 00167 { 00168 return ARM_UC_ControlCenter_AddMonitor(monitor); 00169 } 00170 00171 /** 00172 * @brief Temporary error reporting function. 00173 */ 00174 void ARM_UC_HUB_AddErrorCallback(void (*callback)(int32_t error)) 00175 { 00176 ARM_UC_HUB_AddErrorCallbackInternal(callback); 00177 } 00178 00179 /** 00180 * @brief Authorize request. 00181 */ 00182 arm_uc_error_t ARM_UC_Authorize(arm_uc_request_t request) 00183 { 00184 return ARM_UC_ControlCenter_Authorize(request); 00185 } 00186 00187 /** 00188 * @brief Set callback for receiving download progress. 00189 * @details User application call for setting callback handler. 00190 * The callback function takes the progreess in percent as argument. 00191 * 00192 * @param callback Function pointer to the progress function. 00193 * @return Error code. 00194 */ 00195 arm_uc_error_t ARM_UC_SetProgressHandler(void (*callback)(uint32_t progress, uint32_t total)) 00196 { 00197 return ARM_UC_ControlCenter_SetProgressHandler(callback); 00198 } 00199 00200 /** 00201 * @brief Set callback function for authorizing requests. 00202 * @details User application call for setting callback handler. 00203 * The callback function takes an enum request and an authorization 00204 * function pointer. To authorize the given request, the caller 00205 * invokes the authorization function. 00206 * 00207 * @param callback Function pointer to the authorization function. 00208 * @return Error code. 00209 */ 00210 arm_uc_error_t ARM_UC_SetAuthorizeHandler(void (*callback)(int32_t)) 00211 { 00212 return ARM_UC_ControlCenter_SetAuthorityHandler(callback); 00213 } 00214 00215 /** 00216 * @brief Override update authorization handler. 00217 * @details Force download and update to progress regardless of authorization 00218 * handler. This function is used for unblocking an update in a buggy 00219 * application. 00220 */ 00221 void ARM_UC_OverrideAuthorization(void) 00222 { 00223 ARM_UC_ControlCenter_OverrideAuthorization(); 00224 } 00225 00226 #if defined(ARM_UC_FEATURE_MANIFEST_PUBKEY) && (ARM_UC_FEATURE_MANIFEST_PUBKEY == 1) 00227 /** 00228 * @brief Add certificate. 00229 * @details [long description] 00230 * 00231 * @param certificate Pointer to certiface being added. 00232 * @param certificate_length Certificate length. 00233 * @param fingerprint Pointer to the fingerprint of the certificate being added. 00234 * @param fingerprint_length Fingerprint length. 00235 * @return Error code. 00236 */ 00237 arm_uc_error_t ARM_UC_AddCertificate(const uint8_t *certificate, 00238 uint16_t certificate_length, 00239 const uint8_t *fingerprint, 00240 uint16_t fingerprint_length, 00241 void (*callback)(arm_uc_error_t, const arm_uc_buffer_t *)) 00242 { 00243 return ARM_UC_Certificate_Add(certificate, 00244 certificate_length, 00245 fingerprint, 00246 fingerprint_length, 00247 callback); 00248 } 00249 #endif /* ARM_UC_FEATURE_MANIFEST_PUBKEY */ 00250 00251 #if defined(ARM_UC_FEATURE_MANIFEST_PSK) && (ARM_UC_FEATURE_MANIFEST_PSK == 1) 00252 /** 00253 * @brief Set pointer to pre-shared-key with the given size. 00254 * 00255 * @param key Pointer to pre-shared-key. 00256 * @param bits Key size in bits. 00257 * 00258 * @return Error code. 00259 */ 00260 arm_uc_error_t ARM_UC_AddPreSharedKey(const uint8_t *key, uint16_t bits) 00261 { 00262 return ARM_UC_PreSharedKey_SetSecret(key, bits); 00263 } 00264 #endif 00265 00266 /** 00267 * @brief Function for setting the vendor ID. 00268 * @details The ID is copied to a 16 byte struct. Any data after the first 00269 * 16 bytes will be ignored. 00270 * @param id Pointer to ID. 00271 * @param length Length of ID. 00272 * @return Error code. 00273 */ 00274 arm_uc_error_t ARM_UC_SetVendorId(const uint8_t *id, uint8_t length) 00275 { 00276 arm_uc_guid_t uuid = { 0 }; 00277 00278 if (id) { 00279 for (uint8_t index = 0; 00280 (index < sizeof(arm_uc_guid_t) && (index < length)); 00281 index++) { 00282 ((uint8_t *) uuid)[index] = id[index]; 00283 } 00284 } 00285 00286 return pal_setVendorGuid(&uuid); 00287 } 00288 00289 /** 00290 * @brief Function for setting the class ID. 00291 * @details The ID is copied to a 16 byte struct. Any data after the first 00292 * 16 bytes will be ignored. 00293 * @param id Pointer to ID. 00294 * @param length Length of ID. 00295 * @return Error code. 00296 */ 00297 arm_uc_error_t ARM_UC_SetClassId(const uint8_t *id, uint8_t length) 00298 { 00299 arm_uc_guid_t uuid = { 0 }; 00300 00301 if (id) { 00302 for (uint8_t index = 0; 00303 (index < sizeof(arm_uc_guid_t) && (index < length)); 00304 index++) { 00305 ((uint8_t *) uuid)[index] = id[index]; 00306 } 00307 } 00308 00309 return pal_setClassGuid(&uuid); 00310 } 00311 00312 /** 00313 * @brief Function for setting the device ID. 00314 * @details The ID is copied to a 16 byte struct. Any data after the first 00315 * 16 bytes will be ignored. 00316 * @param id Pointer to ID. 00317 * @param length Length of ID. 00318 * @return Error code. 00319 */ 00320 arm_uc_error_t ARM_UC_SetDeviceId(const uint8_t *id, uint8_t length) 00321 { 00322 arm_uc_guid_t uuid = { 0 }; 00323 00324 if (id) { 00325 for (uint8_t index = 0; 00326 (index < sizeof(arm_uc_guid_t) && (index < length)); 00327 index++) { 00328 ((uint8_t *) uuid)[index] = id[index]; 00329 } 00330 } 00331 00332 return pal_setDeviceGuid(&uuid); 00333 } 00334 00335 /** 00336 * @brief Function for reporting the vendor ID. 00337 * @details 16 bytes are copied into the supplied buffer. 00338 * @param id Pointer to storage for ID. MUST be at least 16 bytes long. 00339 * @param id_max the size of the ID buffer 00340 * @param id_size pointer to a variable to receive the size of the ID 00341 * written into the buffer (always 16). 00342 * @return Error code. 00343 */ 00344 arm_uc_error_t ARM_UC_GetVendorId(uint8_t *id, 00345 const size_t id_max, 00346 size_t *id_size) 00347 { 00348 arm_uc_guid_t guid = {0}; 00349 arm_uc_error_t err = {ERR_NONE}; 00350 if (id_max < sizeof(arm_uc_guid_t)) { 00351 err.code = ARM_UC_DI_ERR_SIZE; 00352 } 00353 if (err.error == ERR_NONE) { 00354 err = pal_getVendorGuid(&guid); 00355 } 00356 if (err.error == ERR_NONE) { 00357 memcpy(id, guid, sizeof(arm_uc_guid_t)); 00358 if (id_size != NULL) { 00359 *id_size = sizeof(arm_uc_guid_t); 00360 } 00361 } 00362 return err; 00363 } 00364 00365 /** 00366 * @brief Function for reporting the class ID. 00367 * @details 16 bytes are copied into the supplied buffer. 00368 * @param id Pointer to storage for ID. MUST be at least 16 bytes long. 00369 * @param id_max the size of the ID buffer 00370 * @param id_size pointer to a variable to receive the size of the ID 00371 * written into the buffer (always 16). 00372 * @return Error code. 00373 */ 00374 arm_uc_error_t ARM_UC_GetClassId(uint8_t *id, 00375 const size_t id_max, 00376 size_t *id_size) 00377 { 00378 arm_uc_guid_t guid = {0}; 00379 arm_uc_error_t err = {ERR_NONE}; 00380 if (id_max < sizeof(arm_uc_guid_t)) { 00381 err.code = ARM_UC_DI_ERR_SIZE; 00382 } 00383 if (err.error == ERR_NONE) { 00384 err = pal_getClassGuid(&guid); 00385 } 00386 if (err.error == ERR_NONE) { 00387 memcpy(id, guid, sizeof(arm_uc_guid_t)); 00388 if (id_size != NULL) { 00389 *id_size = sizeof(arm_uc_guid_t); 00390 } 00391 } 00392 return err; 00393 } 00394 00395 /** 00396 * @brief Function for reporting the device ID. 00397 * @details 16 bytes are copied into the supplied buffer. 00398 * @param id Pointer to storage for ID. MUST be at least 16 bytes long. 00399 * @param id_max the size of the ID buffer 00400 * @param id_size pointer to a variable to receive the size of the ID 00401 * written into the buffer (always 16). 00402 * @return Error code. 00403 */ 00404 arm_uc_error_t ARM_UC_GetDeviceId(uint8_t *id, 00405 const size_t id_max, 00406 size_t *id_size) 00407 { 00408 arm_uc_guid_t guid = {0}; 00409 arm_uc_error_t err = {ERR_NONE}; 00410 if (id_max < sizeof(arm_uc_guid_t)) { 00411 err.code = ARM_UC_DI_ERR_SIZE; 00412 } 00413 if (err.error == ERR_NONE) { 00414 err = pal_getDeviceGuid(&guid); 00415 } 00416 if (err.error == ERR_NONE) { 00417 memcpy(id, guid, sizeof(arm_uc_guid_t)); 00418 if (id_size != NULL) { 00419 *id_size = sizeof(arm_uc_guid_t); 00420 } 00421 } 00422 return err; 00423 } 00424 00425 arm_uc_error_t ARM_UC_HUB_Uninitialize(void) 00426 { 00427 if (ARM_UC_HUB_getState() <= ARM_UC_HUB_STATE_INITIALIZED) { 00428 UC_HUB_ERR_MSG("Update Client not initialized"); 00429 return (arm_uc_error_t) { ERR_INVALID_STATE }; 00430 } 00431 00432 arm_uc_error_t err = ARM_UC_SourceManager.Uninitialize(); 00433 ARM_UC_HUB_setState(ARM_UC_HUB_STATE_UNINITIALIZED); 00434 return err; 00435 } 00436 00437 /** 00438 * @brief Return the details of the active firmware. 00439 * @param details Pointer to the firmware details structure. 00440 * @return ARM_UC_HUB_ERR_NOT_AVAILABLE if the active firmware details 00441 * are not yet available, ERR_INVALID_PARAMETER if "details" is 00442 * NULL or ERR_NONE for success. 00443 */ 00444 arm_uc_error_t ARM_UC_API_GetActiveFirmwareDetails(arm_uc_firmware_details_t *details) 00445 { 00446 arm_uc_error_t err = {ARM_UC_HUB_ERR_NOT_AVAILABLE}; 00447 00448 if (details == NULL) { 00449 err.code = ERR_INVALID_PARAMETER; 00450 } else { 00451 arm_uc_firmware_details_t *hub_details = ARM_UC_HUB_getActiveFirmwareDetails(); 00452 if (hub_details) { 00453 memcpy(details, hub_details, sizeof(arm_uc_firmware_details_t)); 00454 err.code = ERR_NONE; 00455 } 00456 } 00457 return err; 00458 } 00459 00460 /** 00461 * @brief Return whether or not the given state is a valid defined one. 00462 */ 00463 bool ARM_UC_IsValidState(arm_uc_update_state_t an_update_state) 00464 { 00465 int val = (int)an_update_state; 00466 bool is_valid = ((val >= (int)ARM_UC_UPDATE_STATE_FIRST) 00467 && (val <= (int)ARM_UC_UPDATE_STATE_LAST)); 00468 if (!is_valid) UC_ERROR_ERR_MSG("Invalid UC HUB reported state"); 00469 return is_valid; 00470 } 00471 00472 /** 00473 * @brief Return whether or not the given result is a valid defined one. 00474 */ 00475 bool ARM_UC_IsValidResult(arm_uc_update_result_t an_update_result) 00476 { 00477 bool is_valid = ((an_update_result >= ARM_UC_UPDATE_RESULT_UPDATE_FIRST) 00478 && (an_update_result <= ARM_UC_UPDATE_RESULT_UPDATE_LAST)) 00479 || ((an_update_result >= ARM_UC_UPDATE_RESULT_FETCHER_FIRST) 00480 && (an_update_result <= ARM_UC_UPDATE_RESULT_FETCHER_LAST)) 00481 || ((an_update_result >= ARM_UC_UPDATE_RESULT_WRITER_FIRST) 00482 && (an_update_result <= ARM_UC_UPDATE_RESULT_WRITER_LAST)) 00483 || ((an_update_result >= ARM_UC_UPDATE_RESULT_PROCESSOR_FIRST) 00484 && (an_update_result <= ARM_UC_UPDATE_RESULT_PROCESSOR_LAST)) 00485 || ((an_update_result >= ARM_UC_UPDATE_RESULT_MANIFEST_FIRST) 00486 && (an_update_result <= ARM_UC_UPDATE_RESULT_MANIFEST_LAST)); 00487 if (!is_valid) UC_ERROR_ERR_MSG("Invalid UC HUB reported state"); 00488 return is_valid; 00489 }
Generated on Tue Jul 12 2022 20:21:04 by
