From 1097819ef43a37608b55b2508ae4821fb46efb8f Mon Sep 17 00:00:00 2001 From: Sergei Lissianoi <54454955+selissia@users.noreply.github.com> Date: Thu, 19 May 2022 11:09:27 -0400 Subject: [PATCH] [EFR32] Implement methods for NotifyUpdateApplied after an OTA update (#18584) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Test added march 8 (#15957) * Added new manual scripts * Added Auto generated File * [OTA] Fix OTARequestorDriverImpl inclusion (#15981) * Regen to fix CI failures (#15990) * [ota] Store Default OTA Providers in flash (#15970) * [ota] Store Default OTA Providers in flash Store Default OTA Providers in flash each time the attribute is modified and load it back on the application startup. * Restyled by clang-format * Fix build and reduce flash usage Co-authored-by: Restyled.io * Changes for transmitting UpdateApplied for EFR32 * Delay HandleApply by EFR32_KVS_SAVE_DELAY_SECONDS + 1 Delay HandleApply() to give KVS time to store the data in StoreCurrentUpdateInfo(). Introduce EFR32_KVS_SAVE_DELAY_SECONDS to represent the delay amount KeyValueStoreManagerImpl uses before saving the key/vaule pair * Remove merge artifacts * Restyled by clang-format Co-authored-by: kowsisoundhar12 <57476670+kowsisoundhar12@users.noreply.github.com> Co-authored-by: Carol Yang Co-authored-by: Boris Zbarsky Co-authored-by: Damian Królik <66667989+Damian-Nordic@users.noreply.github.com> Co-authored-by: Restyled.io --- examples/platform/efr32/OTAConfig.cpp | 23 ++++++++++ src/platform/EFR32/EFR32Config.h | 3 ++ .../EFR32/KeyValueStoreManagerImpl.cpp | 5 ++- src/platform/EFR32/OTAImageProcessorImpl.cpp | 42 ++++++++++++++++++- src/platform/EFR32/OTAImageProcessorImpl.h | 6 +-- 5 files changed, 72 insertions(+), 7 deletions(-) diff --git a/examples/platform/efr32/OTAConfig.cpp b/examples/platform/efr32/OTAConfig.cpp index a8ff527a43698d..f3601247f4d2ee 100644 --- a/examples/platform/efr32/OTAConfig.cpp +++ b/examples/platform/efr32/OTAConfig.cpp @@ -21,6 +21,19 @@ #include "platform/bootloader/api/application_properties.h" #include +#define BOOTLOADER_SUPPORT_CERTIFICATES 1 +#define APPLICATION_CERTIFICATE_VERSION (1UL) + +#if defined(BOOTLOADER_SUPPORT_CERTIFICATES) +const ApplicationCertificate_t sl_app_certificate = { + .structVersion = APPLICATION_CERTIFICATE_VERSION, + .flags = { 0U }, + .key = { 0U }, + .version = 0, + .signature = { 0U }, +}; +#endif + // Header used for building the image GBL file #define APP_PROPERTIES_VERSION 1 #define APP_PROPERTIES_ID \ @@ -58,6 +71,16 @@ __attribute__((used)) ApplicationProperties_t sl_app_properties = { /// Unique ID (e.g. UUID/GUID) for the product this application is built for .productId = APP_PROPERTIES_ID, }, +#if defined(BOOTLOADER_SUPPORT_CERTIFICATES) + // If certificate based boot chain is enabled, the bootloader binary will be provided with + // a certificate that does not contain any key. + // A valid certificate needs to be injected to the bootloader images using Simplicity Commander. + // Simplicity Commander will replace this certificate. + .cert = (ApplicationCertificate_t *)&sl_app_certificate, +#else + .cert = NULL, +#endif + .longTokenSectionAddress = NULL, }; // Global OTA objects diff --git a/src/platform/EFR32/EFR32Config.h b/src/platform/EFR32/EFR32Config.h index 78019633342ae7..17ea6cdda6ccc8 100644 --- a/src/platform/EFR32/EFR32Config.h +++ b/src/platform/EFR32/EFR32Config.h @@ -35,6 +35,9 @@ #define KVS_MAX_ENTRIES 75 // Available key slot count for Kvs Key mapping. #endif +// Delay before Key/Value is actually saved in NVM +#define EFR32_KVS_SAVE_DELAY_SECONDS 5 + static_assert((KVS_MAX_ENTRIES <= 255), "Implementation supports up to 255 Kvs entries"); static_assert((KVS_MAX_ENTRIES >= 30), "Mininimal Kvs entries requirement is not met"); diff --git a/src/platform/EFR32/KeyValueStoreManagerImpl.cpp b/src/platform/EFR32/KeyValueStoreManagerImpl.cpp index d46079fcc78163..ec90a3f001a85b 100644 --- a/src/platform/EFR32/KeyValueStoreManagerImpl.cpp +++ b/src/platform/EFR32/KeyValueStoreManagerImpl.cpp @@ -117,8 +117,9 @@ void KeyValueStoreManagerImpl::ScheduleKeyMapSave(void) During commissioning, the key map will be modified multiples times subsequently. Commit the key map in nvm once it as stabilized. */ - SystemLayer().StartTimer(std::chrono::duration_cast(System::Clock::Seconds32(5)), - KeyValueStoreManagerImpl::OnScheduledKeyMapSave, NULL); + SystemLayer().StartTimer( + std::chrono::duration_cast(System::Clock::Seconds32(EFR32_KVS_SAVE_DELAY_SECONDS)), + KeyValueStoreManagerImpl::OnScheduledKeyMapSave, NULL); } CHIP_ERROR KeyValueStoreManagerImpl::_Get(const char * key, void * value, size_t value_size, size_t * read_bytes_size, diff --git a/src/platform/EFR32/OTAImageProcessorImpl.cpp b/src/platform/EFR32/OTAImageProcessorImpl.cpp index f5703ec7df5cb8..6d11e219fa0534 100644 --- a/src/platform/EFR32/OTAImageProcessorImpl.cpp +++ b/src/platform/EFR32/OTAImageProcessorImpl.cpp @@ -18,12 +18,15 @@ #include "OTAImageProcessorImpl.h" #include +#include extern "C" { #include "platform/bootloader/api/btl_interface.h" #include "platform/emlib/inc/em_bus.h" // For CORE_CRITICAL_SECTION } +#include "EFR32Config.h" + /// No error, operation OK #define SL_BOOTLOADER_OK 0L @@ -48,7 +51,10 @@ CHIP_ERROR OTAImageProcessorImpl::Finalize() } CHIP_ERROR OTAImageProcessorImpl::Apply() { - DeviceLayer::PlatformMgr().ScheduleWork(HandleApply, reinterpret_cast(this)); + // Delay HandleApply() to give KVS time to store the data in StoreCurrentUpdateInfo() + ChipLogError(SoftwareUpdate, "Scheduling HandleApply"); + chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Seconds32(EFR32_KVS_SAVE_DELAY_SECONDS + 1), HandleApply, + nullptr); return CHIP_NO_ERROR; } @@ -76,6 +82,38 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessBlock(ByteSpan & block) return CHIP_NO_ERROR; } +bool OTAImageProcessorImpl::IsFirstImageRun() +{ + OTARequestorInterface * requestor = chip::GetRequestorInstance(); + if (requestor == nullptr) + { + return false; + } + + return requestor->GetCurrentUpdateState() == OTARequestorInterface::OTAUpdateStateEnum::kApplying; +} + +CHIP_ERROR OTAImageProcessorImpl::ConfirmCurrentImage() +{ + OTARequestorInterface * requestor = chip::GetRequestorInstance(); + if (requestor == nullptr) + { + return CHIP_ERROR_INTERNAL; + } + + uint32_t currentVersion; + uint32_t targetVersion = requestor->GetTargetVersion(); + ReturnErrorOnFailure(DeviceLayer::ConfigurationMgr().GetSoftwareVersion(currentVersion)); + if (currentVersion != targetVersion) + { + ChipLogError(SoftwareUpdate, "Current software version = %" PRIu32 ", expected software version = %" PRIu32, currentVersion, + targetVersion); + return CHIP_ERROR_INCORRECT_STATE; + } + + return CHIP_NO_ERROR; +} + void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context) { int32_t err = SL_BOOTLOADER_OK; @@ -142,7 +180,7 @@ void OTAImageProcessorImpl::HandleFinalize(intptr_t context) ChipLogProgress(SoftwareUpdate, "OTA image downloaded successfully"); } -void OTAImageProcessorImpl::HandleApply(intptr_t context) +void OTAImageProcessorImpl::HandleApply(chip::System::Layer * systemLayer, void * context) { uint32_t err = SL_BOOTLOADER_OK; diff --git a/src/platform/EFR32/OTAImageProcessorImpl.h b/src/platform/EFR32/OTAImageProcessorImpl.h index dac479c37bd3d5..d2d8fc7a36c294 100644 --- a/src/platform/EFR32/OTAImageProcessorImpl.h +++ b/src/platform/EFR32/OTAImageProcessorImpl.h @@ -36,8 +36,8 @@ class OTAImageProcessorImpl : public OTAImageProcessorInterface CHIP_ERROR Apply() override; CHIP_ERROR Abort() override; CHIP_ERROR ProcessBlock(ByteSpan & block) override; - bool IsFirstImageRun() override { return false; } - CHIP_ERROR ConfirmCurrentImage() override { return CHIP_NO_ERROR; } + bool IsFirstImageRun() override; + CHIP_ERROR ConfirmCurrentImage() override; void SetOTADownloader(OTADownloader * downloader) { mDownloader = downloader; } void SetOTAImageFile(const char * imageFile) { mImageFile = imageFile; } @@ -46,7 +46,7 @@ class OTAImageProcessorImpl : public OTAImageProcessorInterface //////////// Actual handlers for the OTAImageProcessorInterface /////////////// static void HandlePrepareDownload(intptr_t context); static void HandleFinalize(intptr_t context); - static void HandleApply(intptr_t context); + static void HandleApply(chip::System::Layer * systemLayer, void *); static void HandleAbort(intptr_t context); static void HandleProcessBlock(intptr_t context); CHIP_ERROR ProcessHeader(ByteSpan & block);