Simulated product dispenser
Fork of mbed-cloud-workshop-connect-HTS221 by
update_client_hub_state_machine.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_state_machine.h" 00020 #include "update_client_hub_error_handler.h" 00021 #include "update-client-hub/update_client_hub.h" 00022 00023 #include "update-client-common/arm_uc_common.h" 00024 #include "update-client-firmware-manager/arm_uc_firmware_manager.h" 00025 #include "update-client-manifest-manager/update-client-manifest-manager.h" 00026 #include "update-client-source-manager/arm_uc_source_manager.h" 00027 #include "update-client-control-center/arm_uc_control_center.h" 00028 #include "update-client-control-center/arm_uc_pre_shared_key.h" 00029 00030 #include "mbedtls/aes.h" 00031 00032 #include "pal.h" 00033 00034 #include <inttypes.h> 00035 00036 /*****************************************************************************/ 00037 /* Global variables */ 00038 /*****************************************************************************/ 00039 00040 // state of the hub state machine 00041 static arm_uc_hub_state_t arm_uc_hub_state = ARM_UC_HUB_STATE_UNINITIALIZED; 00042 00043 // the call back function registered by the user to signal end of intilisation 00044 static void (*arm_uc_hub_init_cb)(int32_t) = NULL; 00045 00046 // The hub uses a double buffer system to speed up firmware download and storage 00047 #define BUFFER_SIZE_MAX (ARM_UC_BUFFER_SIZE / 2) // define size of the double buffers 00048 static uint8_t message[BUFFER_SIZE_MAX]; 00049 static arm_uc_buffer_t front_buffer = { 00050 .size_max = BUFFER_SIZE_MAX, 00051 .size = 0, 00052 .ptr = message 00053 }; 00054 00055 static uint8_t message2[BUFFER_SIZE_MAX]; 00056 static arm_uc_buffer_t back_buffer = { 00057 .size_max = BUFFER_SIZE_MAX, 00058 .size = 0, 00059 .ptr = message2 00060 }; 00061 00062 // version (timestamp) of the current running application 00063 static arm_uc_firmware_details_t arm_uc_active_details = { 0 }; 00064 static bool arm_uc_active_details_available = false; 00065 00066 // bootloader information 00067 static arm_uc_installer_details_t arm_uc_installer_details = { 0 }; 00068 00069 // variable to keep track of the offset into the firmware image during download 00070 static uint32_t firmware_offset = 0; 00071 00072 // variable to store the firmware config during firmware manager setup 00073 // Initialisation with an enum silences a compiler warning for ARM ("188-D: enumerated type mixed with another type"). 00074 static ARM_UCFM_Setup_t arm_uc_hub_firmware_config = { UCFM_MODE_UNINIT }; 00075 00076 // buffer to store the decoded firmware key 00077 #define PLAIN_FIRMWARE_KEY_SIZE 16 00078 static uint8_t plainFirmwareKey[PLAIN_FIRMWARE_KEY_SIZE]; 00079 static arm_uc_buffer_t arm_uc_hub_plain_key = { 00080 .size_max = PLAIN_FIRMWARE_KEY_SIZE, 00081 .size = PLAIN_FIRMWARE_KEY_SIZE, 00082 .ptr = plainFirmwareKey 00083 }; 00084 00085 static arm_uc_mmContext_t manifestManagerContext = { 0 }; 00086 static arm_uc_mmContext_t* pManifestManagerContext = &manifestManagerContext; 00087 static manifest_firmware_info_t fwinfo = { 0 }; 00088 00089 // buffer to store a uri struct 00090 #define URI_STRING_LEN 256 00091 uint8_t uri_buffer[URI_STRING_LEN] = {0}; 00092 00093 static arm_uc_uri_t uri = { 00094 .size_max = sizeof(uri_buffer), 00095 .size = 0, 00096 .ptr = uri_buffer, 00097 .port = 0, 00098 .scheme = URI_SCHEME_NONE, 00099 .host = NULL, 00100 .path = NULL, 00101 }; 00102 00103 /*****************************************************************************/ 00104 /* Debug */ 00105 /*****************************************************************************/ 00106 00107 #if ARM_UC_HUB_TRACE_ENABLE 00108 static void arm_uc_hub_debug_output() 00109 { 00110 printf("Manifest timestamp: %" PRIu64 "\r\n", fwinfo.timestamp); 00111 00112 if (uri.scheme == URI_SCHEME_HTTP) 00113 { 00114 printf("Firmware URL http://%s:%" PRIu16 "%s\r\n", 00115 uri.host, uri.port, uri.path); 00116 } 00117 00118 printf("Firmware size: %" PRIu32 "\r\n",fwinfo.size); 00119 00120 printf("Firmware hash (%" PRIu32 "): ", fwinfo.hash.size); 00121 for (unsigned i = 0; i < fwinfo.hash.size; i++) 00122 { 00123 printf("%02" PRIx8, fwinfo.hash.ptr[i]); 00124 } 00125 printf("\r\n"); 00126 00127 if (fwinfo.cipherMode == ARM_UC_MM_CIPHERMODE_PSK) 00128 { 00129 printf("PSK ID: "); 00130 for (unsigned i = 0; i < fwinfo.psk.keyID.size; i++) 00131 { 00132 printf("%02" PRIx8, *(fwinfo.psk.keyID.ptr+i)); 00133 } 00134 printf("\r\n"); 00135 00136 printf("cipherKey(16): "); 00137 for (unsigned i = 0; i < 16; i++) 00138 { 00139 printf("%02" PRIx8, *(fwinfo.psk.cipherKey.ptr+i)); 00140 } 00141 printf("\r\n"); 00142 00143 printf("Decrypted Firmware Symmetric Key(16): "); 00144 for (unsigned i = 0; i < 16; i++) 00145 { 00146 printf("%02" PRIx8, arm_uc_hub_plain_key.ptr[i]); 00147 } 00148 printf("\r\n"); 00149 00150 printf("fwinfo.initVector\r\n"); 00151 for (unsigned i = 0; i < 16; i++) 00152 { 00153 printf("%02" PRIx8, *(fwinfo.initVector.ptr+i)); 00154 } 00155 printf("\r\n"); 00156 } 00157 00158 printf("Storage location: %" PRIu32 "\r\n", 00159 arm_uc_hub_firmware_config.package_id); 00160 } 00161 #endif 00162 00163 /*****************************************************************************/ 00164 /* State machine */ 00165 /*****************************************************************************/ 00166 00167 /* Short hand for simple error handling code */ 00168 #define HANDLE_ERROR(retval, msg, ...) \ 00169 if (retval.error != ERR_NONE) \ 00170 { \ 00171 UC_HUB_ERR_MSG(msg " error code %s", \ 00172 ##__VA_ARGS__, \ 00173 ARM_UC_err2Str(retval)); \ 00174 new_state = ARM_UC_HUB_STATE_IDLE; \ 00175 break; \ 00176 } 00177 00178 arm_uc_hub_state_t ARM_UC_HUB_getState() 00179 { 00180 return arm_uc_hub_state; 00181 } 00182 00183 void ARM_UC_HUB_setInitializationCallback(void (*callback)(int32_t)) 00184 { 00185 arm_uc_hub_init_cb = callback; 00186 } 00187 00188 /** 00189 * @brief Return the active firmware details or NULL if they're not yet available. 00190 */ 00191 arm_uc_firmware_details_t* ARM_UC_HUB_getActiveFirmwareDetails(void) 00192 { 00193 return arm_uc_active_details_available ? &arm_uc_active_details : NULL; 00194 } 00195 00196 void ARM_UC_HUB_setState(arm_uc_hub_state_t new_state) 00197 { 00198 arm_uc_error_t retval; 00199 00200 /* Loop until state is unchanged. 00201 First loop is mandatory regardless of current state. 00202 */ 00203 do 00204 { 00205 /* store new stage */ 00206 arm_uc_hub_state = new_state; 00207 00208 switch (arm_uc_hub_state) 00209 { 00210 /*****************************************************************/ 00211 /* Initialization */ 00212 /*****************************************************************/ 00213 case ARM_UC_HUB_STATE_INITIALIZED: 00214 UC_HUB_TRACE("ARM_UC_HUB_STATE_INITIALIZED"); 00215 00216 /* signal that the Hub is initialized */ 00217 if (arm_uc_hub_init_cb) 00218 { 00219 arm_uc_hub_init_cb(ARM_UC_INIT_DONE); 00220 } 00221 00222 /* report the active firmware hash to the Cloud in parallel 00223 with the main user application. 00224 */ 00225 arm_uc_active_details_available = false; 00226 new_state = ARM_UC_HUB_STATE_GET_ACTIVE_FIRMWARE_DETAILS; 00227 break; 00228 00229 case ARM_UC_HUB_STATE_INITIALIZING: 00230 UC_HUB_TRACE("ARM_UC_HUB_STATE_INITIALIZING"); 00231 break; 00232 00233 /*****************************************************************/ 00234 /* Report current firmware hash */ 00235 /*****************************************************************/ 00236 case ARM_UC_HUB_STATE_GET_ACTIVE_FIRMWARE_DETAILS: 00237 UC_HUB_TRACE("ARM_UC_HUB_STATE_GET_ACTIVE_FIRMWARE_DETAILS"); 00238 00239 retval = ARM_UC_FirmwareManager.GetActiveFirmwareDetails(&arm_uc_active_details); 00240 HANDLE_ERROR(retval, "Firmware manager GetActiveFirmwareDetails failed"); 00241 break; 00242 00243 case ARM_UC_HUB_STATE_REPORT_ACTIVE_HASH: 00244 UC_HUB_TRACE("ARM_UC_HUB_STATE_REPORT_ACTIVE_HASH"); 00245 00246 /* copy hash to buffer */ 00247 memcpy(front_buffer.ptr, 00248 arm_uc_active_details.hash, 00249 ARM_UC_SHA256_SIZE); 00250 00251 front_buffer.size = ARM_UC_SHA256_SIZE; 00252 00253 /* send hash to update service */ 00254 ARM_UC_ControlCenter_ReportName(&front_buffer); 00255 00256 /* signal to the API that the firmware details are now available */ 00257 arm_uc_active_details_available = true; 00258 00259 new_state = ARM_UC_HUB_STATE_REPORT_ACTIVE_VERSION; 00260 break; 00261 00262 /*****************************************************************/ 00263 /* Report current firmware version */ 00264 /*****************************************************************/ 00265 case ARM_UC_HUB_STATE_REPORT_ACTIVE_VERSION: 00266 UC_HUB_TRACE("ARM_UC_HUB_STATE_REPORT_ACTIVE_VERSION"); 00267 00268 UC_HUB_TRACE("Active version: %" PRIu64, 00269 arm_uc_active_details.version); 00270 00271 /* send timestamp to update service */ 00272 ARM_UC_ControlCenter_ReportVersion(arm_uc_active_details.version); 00273 00274 new_state = ARM_UC_HUB_STATE_GET_INSTALLER_DETAILS; 00275 break; 00276 00277 /*****************************************************************/ 00278 /* Report bootloader information */ 00279 /*****************************************************************/ 00280 case ARM_UC_HUB_STATE_GET_INSTALLER_DETAILS: 00281 UC_HUB_TRACE("ARM_UC_HUB_STATE_GET_INSTALLER_DETAILS"); 00282 00283 retval = ARM_UC_FirmwareManager.GetInstallerDetails(&arm_uc_installer_details); 00284 HANDLE_ERROR(retval, "Firmware manager GetInstallerDetails failed"); 00285 break; 00286 00287 case ARM_UC_HUB_STATE_REPORT_INSTALLER_DETAILS: 00288 { 00289 UC_HUB_TRACE("ARM_UC_HUB_STATE_REPORT_INSTALLER_DETAILS"); 00290 00291 #if 0 00292 printf("bootloader: "); 00293 for (uint32_t index = 0; index < 20; index++) 00294 { 00295 printf("%02X", arm_uc_installer_details.arm_hash[index]); 00296 } 00297 printf("\r\n"); 00298 00299 printf("layout: %" PRIu32 "\r\n", arm_uc_installer_details.layout); 00300 #endif 00301 00302 /* report installer details to mbed cloud */ 00303 arm_uc_buffer_t bootloader_hash = { 00304 .size_max = ARM_UC_SHA256_SIZE, 00305 .size = ARM_UC_SHA256_SIZE, 00306 .ptr = (arm_uc_installer_details.arm_hash) 00307 }; 00308 ARM_UC_ControlCenter_ReportBootloaderHash(&bootloader_hash); 00309 00310 bootloader_hash.ptr = (arm_uc_installer_details.oem_hash); 00311 ARM_UC_ControlCenter_ReportOEMBootloaderHash(&bootloader_hash); 00312 00313 /* set new state */ 00314 new_state = ARM_UC_HUB_STATE_IDLE; 00315 break; 00316 } 00317 00318 /*****************************************************************/ 00319 /* Idle */ 00320 /*****************************************************************/ 00321 case ARM_UC_HUB_STATE_IDLE: 00322 UC_HUB_TRACE("ARM_UC_MONITOR_STATE_IDLE"); 00323 00324 /* signal monitor that device has entered IDLE state */ 00325 ARM_UC_ControlCenter_ReportState(ARM_UC_MONITOR_STATE_IDLE); 00326 break; 00327 00328 /*****************************************************************/ 00329 /* Download manifest */ 00330 /*****************************************************************/ 00331 case ARM_UC_HUB_STATE_NOTIFIED: 00332 UC_HUB_TRACE("ARM_UC_HUB_STATE_NOTIFIED"); 00333 00334 /* notification received of a new manifest, hence go get said manifest */ 00335 retval = ARM_UC_SourceManager.GetManifest(&front_buffer, 0); 00336 HANDLE_ERROR(retval, "Source manager GetManifest failed"); 00337 break; 00338 00339 case ARM_UC_HUB_STATE_MANIFEST_FETCHED: 00340 UC_HUB_TRACE("ARM_UC_HUB_STATE_MANIFEST_FETCHED"); 00341 00342 /* Save the manifest for later */ 00343 memcpy(&fwinfo.manifestBuffer, front_buffer.ptr, 00344 ARM_UC_util_min(sizeof(fwinfo.manifestBuffer), front_buffer.size)); 00345 /* Save the manifest size for later */ 00346 fwinfo.manifestSize = front_buffer.size; 00347 /* insert the manifest we just fetched into manifest manager */ 00348 retval = ARM_UC_mmInsert(&pManifestManagerContext, &front_buffer, &back_buffer, NULL); 00349 if (retval.code != MFST_ERR_PENDING) 00350 { 00351 HANDLE_ERROR(retval, "Manifest manager Insert failed") 00352 } 00353 break; 00354 00355 /*****************************************************************/ 00356 /* Rollback protection */ 00357 /*****************************************************************/ 00358 case ARM_UC_HUB_STATE_MANIFEST_COMPLETE: 00359 UC_HUB_TRACE("ARM_UC_HUB_STATE_MANIFEST_COMPLETE"); 00360 00361 /* get the firmware info out of the manifest we just inserted 00362 into the manifest manager 00363 */ 00364 retval = ARM_UC_mmFetchFirmwareInfo(&pManifestManagerContext, 00365 &fwinfo, 00366 NULL); 00367 if (retval.code != MFST_ERR_PENDING) 00368 { 00369 HANDLE_ERROR(retval, "Manifest manager fetch info failed") 00370 } 00371 break; 00372 00373 case ARM_UC_HUB_STATE_CHECK_VERSION: 00374 UC_HUB_TRACE("ARM_UC_HUB_STATE_CHECK_VERSION"); 00375 00376 /* only continue if timestamp is newer than active version */ 00377 if (fwinfo.timestamp > arm_uc_active_details.version) 00378 { 00379 /* set new state */ 00380 new_state = ARM_UC_HUB_STATE_PREPARE_FIRMWARE_SETUP; 00381 } 00382 else 00383 { 00384 UC_HUB_ERR_MSG("version: %" PRIu64 " <= %" PRIu64, 00385 fwinfo.timestamp, 00386 arm_uc_active_details.version); 00387 00388 /* signal warning through external handler */ 00389 ARM_UC_HUB_ErrorHandler(HUB_ERR_ROLLBACK_PROTECTION, 00390 ARM_UC_HUB_STATE_CHECK_VERSION); 00391 00392 /* set new state */ 00393 new_state = ARM_UC_HUB_STATE_IDLE; 00394 } 00395 break; 00396 00397 /*****************************************************************/ 00398 /* Parse manifest */ 00399 /*****************************************************************/ 00400 case ARM_UC_HUB_STATE_PREPARE_FIRMWARE_SETUP: 00401 UC_HUB_TRACE("ARM_UC_HUB_STATE_PREPARE_FIRMWARE_SETUP"); 00402 00403 /* store pointer to hash */ 00404 arm_uc_hub_firmware_config.hash = &fwinfo.hash; 00405 00406 /* parse the url string into a arm_uc_uri_t struct */ 00407 retval = arm_uc_str2uri(fwinfo.uri.ptr, 00408 fwinfo.uri.size, 00409 &uri); 00410 00411 /* URI-based errors are propagated to monitor */ 00412 if (retval.error != ERR_NONE) 00413 { 00414 /* make sure that the URI string is always 0-terminated */ 00415 fwinfo.uri.ptr[fwinfo.uri.size_max - 1] = '\0'; 00416 UC_HUB_ERR_MSG("Unable to parse URI string %s", fwinfo.uri.ptr); 00417 00418 /* signal warning through external handler */ 00419 ARM_UC_HUB_ErrorHandler(SOMA_ERR_INVALID_PARAMETER, 00420 ARM_UC_HUB_STATE_PREPARE_FIRMWARE_SETUP); 00421 00422 /* set new state */ 00423 new_state = ARM_UC_HUB_STATE_IDLE; 00424 break; 00425 } 00426 00427 /* store firmware size */ 00428 arm_uc_hub_firmware_config.package_size = fwinfo.size; 00429 00430 /* read cryptography mode to determine if firmware is encrypted */ 00431 switch(fwinfo.cipherMode) 00432 { 00433 case ARM_UC_MM_CIPHERMODE_NONE: 00434 arm_uc_hub_firmware_config.mode = UCFM_MODE_NONE_SHA_256; 00435 break; 00436 00437 case ARM_UC_MM_CIPHERMODE_PSK: 00438 { 00439 /* Get pre-shared-key from the Control Center */ 00440 /* TODO: this call should be asynchronous */ 00441 const uint8_t* arm_uc_pre_shared_key = NULL; 00442 retval = ARM_UC_PreSharedKey_GetKey(&arm_uc_pre_shared_key, 128); 00443 HANDLE_ERROR(retval, "Unable to get PSK"); 00444 00445 /* Decode the firmware key to be used to decode the firmware */ 00446 UC_HUB_TRACE("Decoding firmware AES key..."); 00447 mbedtls_aes_context ctx; 00448 mbedtls_aes_init(&ctx); 00449 mbedtls_aes_setkey_dec(&ctx, arm_uc_pre_shared_key, 128); 00450 mbedtls_aes_crypt_ecb(&ctx, MBEDTLS_AES_DECRYPT, fwinfo.psk.cipherKey.ptr, arm_uc_hub_plain_key.ptr); 00451 00452 arm_uc_hub_firmware_config.mode = UCFM_MODE_AES_CTR_128_SHA_256; 00453 arm_uc_hub_firmware_config.key = &arm_uc_hub_plain_key; 00454 arm_uc_hub_firmware_config.iv = &fwinfo.initVector; 00455 } 00456 break; 00457 00458 case ARM_UC_MM_CIPHERMODE_CERT_CIPHERKEY: 00459 case ARM_UC_MM_CIPHERMODE_CERT_KEYTABLE: 00460 default: 00461 retval.code = MFST_ERR_CRYPTO_MODE; 00462 HANDLE_ERROR(retval, "Unsupported AES Key distribution mode..."); 00463 break; 00464 } 00465 00466 /* check if storage ID has been set */ 00467 if (fwinfo.strgId.size == 0 || fwinfo.strgId.ptr == NULL) 00468 { 00469 /* no storage ID set, use default value 0 */ 00470 arm_uc_hub_firmware_config.package_id = 0; 00471 } 00472 else 00473 { 00474 /* check if storage ID is "default" */ 00475 uint32_t location = arm_uc_strnstrn(fwinfo.strgId.ptr, 00476 fwinfo.strgId.size, 00477 (const uint8_t*) "default", 00478 7); 00479 00480 if (location != UINT32_MAX) 00481 { 00482 arm_uc_hub_firmware_config.package_id = 0; 00483 } 00484 else 00485 { 00486 /* parse storage ID */ 00487 bool success = false; 00488 arm_uc_hub_firmware_config.package_id = 00489 arm_uc_str2uint32(fwinfo.strgId.ptr, 00490 fwinfo.strgId.size, 00491 &success); 00492 } 00493 } 00494 00495 #if ARM_UC_HUB_TRACE_ENABLE 00496 arm_uc_hub_debug_output(); 00497 #endif 00498 00499 /* Set new state */ 00500 new_state = ARM_UC_HUB_STATE_REQUEST_DOWNLOAD_AUTHORIZATION; 00501 break; 00502 00503 /*****************************************************************/ 00504 /* Download authorization */ 00505 /*****************************************************************/ 00506 case ARM_UC_HUB_STATE_REQUEST_DOWNLOAD_AUTHORIZATION: 00507 UC_HUB_TRACE("ARM_UC_HUB_STATE_REQUEST_DOWNLOAD_AUTHORIZATION"); 00508 00509 /* Signal control center */ 00510 ARM_UC_ControlCenter_GetAuthorization(ARM_UCCC_REQUEST_DOWNLOAD); 00511 00512 /* Set new state */ 00513 new_state = ARM_UC_HUB_STATE_WAIT_FOR_DOWNLOAD_AUTHORIZATION; 00514 break; 00515 00516 case ARM_UC_HUB_STATE_WAIT_FOR_DOWNLOAD_AUTHORIZATION: 00517 UC_HUB_TRACE("ARM_UC_HUB_STATE_WAIT_FOR_DOWNLOAD_AUTHORIZATION"); 00518 break; 00519 00520 case ARM_UC_HUB_STATE_DOWNLOAD_AUTHORIZED: 00521 UC_HUB_TRACE("ARM_UC_HUB_STATE_DOWNLOAD_AUTHORIZED"); 00522 00523 /* Set new state */ 00524 new_state = ARM_UC_HUB_STATE_SETUP_FIRMWARE; 00525 break; 00526 00527 /*****************************************************************/ 00528 /* Download firmware */ 00529 /*****************************************************************/ 00530 00531 /* The firmware is downloaded in fragments. While one fragment is 00532 written to storage, the next fragment is being downloaded. 00533 00534 In the ARM_UC_HUB_STATE_FETCH_FIRST_FRAGMENT state, the first 00535 fragment is being downloaded. Once completed, the first fragment 00536 will be in the front_buffer and both the network stack and 00537 storage stack will be idle. 00538 00539 In the ARM_UC_HUB_STATE_STORE_AND_DOWNLOAD state, the front and 00540 back buffers are swapped. The front buffer is being used for 00541 downloading the next fragment while the back buffer is being 00542 written to storage. 00543 00544 ARM_UC_FirmwareManager.Write and 00545 ARM_UC_SourceManager.GetFirmwareFragment will both finish 00546 asynchronously generating two events: 00547 ARM_UC_SM_EVENT_FIRMWARE and UCFM_EVENT_UPDATE_DONE. 00548 00549 If the ARM_UC_SM_EVENT_FIRMWARE event is generated first, the 00550 system enters the ARM_UC_HUB_STATE_WAIT_FOR_STORAGE state. 00551 If the UCFM_EVENT_UPDATE_DONE event is generated first, the 00552 system enters the ARM_UC_HUB_STATE_WAIT_FOR_NETWORK state. 00553 The second generated event will move the system back to the 00554 ARM_UC_HUB_STATE_STORE_AND_DOWNLOAD state. 00555 00556 The download will stop once the fragment offset is larger than 00557 the firmware size written in the manifest. This moves the system 00558 to the ARM_UC_HUB_STATE_STORE_LAST_FRAGMENT state. 00559 00560 Once the last fragment is written, the newly written firmware 00561 committed in the ARM_UC_HUB_STATE_FINALIZE_STORAGE state. 00562 */ 00563 case ARM_UC_HUB_STATE_SETUP_FIRMWARE: 00564 { 00565 UC_HUB_TRACE("ARM_UC_HUB_STATE_SETUP_FIRMWARE"); 00566 00567 /* store the firmware info in the manifest_firmware_info_t struct */ 00568 arm_uc_firmware_details_t arm_uc_hub_firmware_details = { 0 }; 00569 00570 /* use manifest timestamp as firmware header version */ 00571 arm_uc_hub_firmware_details.version = fwinfo.timestamp; 00572 arm_uc_hub_firmware_details.size = fwinfo.size; 00573 00574 /* copy hash */ 00575 memcpy(arm_uc_hub_firmware_details.hash, 00576 fwinfo.hash.ptr, 00577 ARM_UC_SHA256_SIZE); 00578 00579 #if 0 00580 memcpy(arm_uc_hub_firmware_details.campaign, 00581 configuration.campaign, 00582 ARM_UC_GUID_SIZE); 00583 #endif 00584 00585 /* setup the firmware manager to get ready for firmware storage */ 00586 retval = ARM_UC_FirmwareManager.Prepare(&arm_uc_hub_firmware_config, 00587 &arm_uc_hub_firmware_details, 00588 &front_buffer); 00589 HANDLE_ERROR(retval, "ARM_UC_FirmwareManager Setup failed") 00590 } 00591 break; 00592 00593 case ARM_UC_HUB_STATE_FETCH_FIRST_FRAGMENT: 00594 UC_HUB_TRACE("ARM_UC_HUB_STATE_FETCH_FIRST_FRAGMENT"); 00595 00596 /* set state to downloading when trying to fetch the first chunk of firmware */ 00597 UC_HUB_TRACE("Setting Monitor State: ARM_UC_MONITOR_STATE_DOWNLOADING"); 00598 ARM_UC_ControlCenter_ReportState(ARM_UC_MONITOR_STATE_DOWNLOADING); 00599 00600 /* reset download values */ 00601 front_buffer.size = 0; 00602 back_buffer.size = 0; 00603 firmware_offset = 0; 00604 00605 /* Check firmware size before entering the download state machine. 00606 An empty firmware is used for erasing a slot. 00607 */ 00608 if (firmware_offset < fwinfo.size) 00609 { 00610 /* get first firmware fragment */ 00611 UC_HUB_TRACE("Getting next chunk at offset %" PRIu32, 00612 firmware_offset); 00613 retval = ARM_UC_SourceManager.GetFirmwareFragment(&uri, 00614 &front_buffer, 00615 firmware_offset); 00616 HANDLE_ERROR(retval, "GetFirmwareFragment failed") 00617 } 00618 else 00619 { 00620 /* No download is necessary, send next state to monitor service 00621 and close storage slot. 00622 */ 00623 UC_HUB_TRACE("Firmware empty, skip download phase and finalize"); 00624 UC_HUB_TRACE("Setting Monitor State: ARM_UC_MONITOR_STATE_DOWNLOADED"); 00625 ARM_UC_ControlCenter_ReportState(ARM_UC_MONITOR_STATE_DOWNLOADED); 00626 new_state = ARM_UC_HUB_STATE_FINALIZE_STORAGE; 00627 } 00628 break; 00629 00630 case ARM_UC_HUB_STATE_STORE_AND_DOWNLOAD: 00631 UC_HUB_TRACE("ARM_UC_HUB_STATE_STORE_AND_DOWNLOAD"); 00632 00633 /* swap the front and back buffers 00634 the back buffer contained just downloaded firmware chunk 00635 the front buffer can now be cleared and used to download new chunk 00636 */ 00637 { 00638 arm_uc_buffer_t temp_buf_ptr = front_buffer; 00639 front_buffer = back_buffer; 00640 back_buffer = temp_buf_ptr; 00641 } 00642 00643 UC_HUB_TRACE("Fragment: %" PRIu32 " %" PRIu32, firmware_offset, back_buffer.size); 00644 00645 /* increase offset by the amount that we just downloaded */ 00646 firmware_offset += back_buffer.size; 00647 00648 /* store the downloaded chunk in the back buffer */ 00649 if (back_buffer.size > 0) 00650 { 00651 retval = ARM_UC_FirmwareManager.Write(&back_buffer); 00652 HANDLE_ERROR(retval, "ARM_UC_FirmwareManager Update failed") 00653 } 00654 00655 /* go fetch a new chunk using the front buffer if more are expected */ 00656 if (firmware_offset < fwinfo.size) 00657 { 00658 front_buffer.size = 0; 00659 UC_HUB_TRACE("Getting next chunk at offset: %" PRIu32, firmware_offset); 00660 retval = ARM_UC_SourceManager.GetFirmwareFragment(&uri, &front_buffer, firmware_offset); 00661 HANDLE_ERROR(retval, "GetFirmwareFragment failed") 00662 } 00663 else 00664 { 00665 UC_HUB_TRACE("Store last fragment"); 00666 new_state = ARM_UC_HUB_STATE_STORE_LAST_FRAGMENT; 00667 } 00668 00669 /* report progress */ 00670 ARM_UC_ControlCenter_ReportProgress(firmware_offset, fwinfo.size); 00671 break; 00672 00673 case ARM_UC_HUB_STATE_WAIT_FOR_STORAGE: 00674 UC_HUB_TRACE("ARM_UC_HUB_STATE_WAIT_FOR_STORAGE"); 00675 break; 00676 00677 case ARM_UC_HUB_STATE_WAIT_FOR_NETWORK: 00678 UC_HUB_TRACE("ARM_UC_HUB_STATE_WAIT_FOR_NETWORK"); 00679 break; 00680 00681 case ARM_UC_HUB_STATE_STORE_LAST_FRAGMENT: 00682 UC_HUB_TRACE("ARM_UC_HUB_STATE_STORE_LAST_FRAGMENT"); 00683 00684 /* set state to downloaded when the full size of the firmware 00685 have been fetched. 00686 */ 00687 UC_HUB_TRACE("Setting Monitor State: ARM_UC_MONITOR_STATE_DOWNLOADED"); 00688 ARM_UC_ControlCenter_ReportState(ARM_UC_MONITOR_STATE_DOWNLOADED); 00689 break; 00690 00691 case ARM_UC_HUB_STATE_FINALIZE_STORAGE: 00692 UC_HUB_TRACE("ARM_UC_HUB_STATE_FINALIZE_STORAGE"); 00693 00694 retval = ARM_UC_FirmwareManager.Finalize(&front_buffer, &back_buffer); 00695 HANDLE_ERROR(retval, "ARM_UC_FirmwareManager Finalize failed") 00696 break; 00697 00698 /*****************************************************************/ 00699 /* Install authorization */ 00700 /*****************************************************************/ 00701 case ARM_UC_HUB_STATE_STORAGE_FINALIZED: 00702 UC_HUB_TRACE("ARM_UC_HUB_STATE_STORAGE_FINALIZED"); 00703 00704 /* Signal control center */ 00705 ARM_UC_ControlCenter_GetAuthorization(ARM_UCCC_REQUEST_INSTALL); 00706 00707 /* Set new state */ 00708 new_state = ARM_UC_HUB_STATE_WAIT_FOR_INSTALL_AUTHORIZATION; 00709 break; 00710 00711 case ARM_UC_HUB_STATE_WAIT_FOR_INSTALL_AUTHORIZATION: 00712 UC_HUB_TRACE("ARM_UC_HUB_STATE_WAIT_FOR_INSTALL_AUTHORIZATION"); 00713 break; 00714 00715 case ARM_UC_HUB_STATE_INSTALL_AUTHORIZED: 00716 UC_HUB_TRACE("ARM_UC_HUB_STATE_INSTALL_AUTHORIZED"); 00717 00718 UC_HUB_TRACE("Setting Monitor State: ARM_UC_MONITOR_STATE_UPDATING"); 00719 ARM_UC_ControlCenter_ReportState(ARM_UC_MONITOR_STATE_UPDATING); 00720 00721 /* TODO: set timeout on ReportState before relying on callback to progress state machine */ 00722 new_state = ARM_UC_HUB_STATE_ACTIVATE_FIRMWARE; 00723 break; 00724 00725 case ARM_UC_HUB_STATE_ACTIVATE_FIRMWARE: 00726 UC_HUB_TRACE("ARM_UC_HUB_STATE_ACTIVATE_FIRMWARE"); 00727 00728 /* Firmware verification passes, activate firmware image. 00729 */ 00730 ARM_UC_FirmwareManager.Activate(arm_uc_hub_firmware_config.package_id); 00731 break; 00732 00733 case ARM_UC_HUB_STATE_REBOOT: 00734 UC_HUB_TRACE("ARM_UC_HUB_STATE_REBOOT"); 00735 00736 /* Firmware activated, now reboot the system to apply 00737 the new image. 00738 */ 00739 pal_osReboot(); 00740 00741 /* Reboot not implemented on this platform. 00742 Report new firmware hash and continue operation. 00743 */ 00744 new_state = ARM_UC_HUB_STATE_GET_ACTIVE_FIRMWARE_DETAILS; 00745 break; 00746 00747 /*****************************************************************/ 00748 /* Error */ 00749 /*****************************************************************/ 00750 case ARM_UC_HUB_STATE_ERROR_FIRMWARE_MANAGER: 00751 UC_HUB_TRACE("ARM_UC_HUB_STATE_ERROR_FIRMWARE_MANAGER"); 00752 new_state = ARM_UC_HUB_STATE_IDLE; 00753 break; 00754 00755 case ARM_UC_HUB_STATE_ERROR_MANIFEST_MANAGER: 00756 UC_HUB_TRACE("ARM_UC_HUB_STATE_ERROR_MANIFEST_MANAGER"); 00757 new_state = ARM_UC_HUB_STATE_IDLE; 00758 break; 00759 00760 case ARM_UC_HUB_STATE_ERROR_SOURCE_MANAGER: 00761 UC_HUB_TRACE("ARM_UC_HUB_STATE_ERROR_SOURCE_MANAGER"); 00762 new_state = ARM_UC_HUB_STATE_IDLE; 00763 break; 00764 00765 case ARM_UC_HUB_STATE_ERROR_CONTROL_CENTER: 00766 UC_HUB_TRACE("ARM_UC_HUB_STATE_ERROR_CONTROL_CENTER"); 00767 new_state = ARM_UC_HUB_STATE_IDLE; 00768 break; 00769 00770 case ARM_UC_HUB_STATE_WAIT_FOR_ERROR_ACK: 00771 UC_HUB_TRACE("ARM_UC_HUB_STATE_WAIT_FOR_ERROR_ACK"); 00772 /* Don't change state. The only place where this state is set is in 00773 update_client_hub_error_handler.c, right after reporting the update 00774 result, so we wait for a "report done" event (ARM_UCCC_EVENT_MONITOR_SEND_DONE 00775 in arm_uc_hub_event_handlers.c). The handler for this particular 00776 event will then set the state to 'idle' */ 00777 break; 00778 00779 default: 00780 new_state = ARM_UC_HUB_STATE_IDLE; 00781 break; 00782 } 00783 } 00784 while (arm_uc_hub_state != new_state); 00785 } 00786
Generated on Tue Jul 12 2022 19:12:17 by 1.7.2