Skip to content

Commit

Permalink
[EFR32] Implement methods for NotifyUpdateApplied after an OTA update (
Browse files Browse the repository at this point in the history
…#18584)

* 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 <[email protected]>

* 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 <[email protected]>
Co-authored-by: Carol Yang <[email protected]>
Co-authored-by: Boris Zbarsky <[email protected]>
Co-authored-by: Damian Królik <[email protected]>
Co-authored-by: Restyled.io <[email protected]>
  • Loading branch information
6 people authored and pull[bot] committed Sep 18, 2023
1 parent 8ca98e1 commit 1097819
Show file tree
Hide file tree
Showing 5 changed files with 72 additions and 7 deletions.
23 changes: 23 additions & 0 deletions examples/platform/efr32/OTAConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@
#include "platform/bootloader/api/application_properties.h"
#include <app/server/Server.h>

#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 \
Expand Down Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions src/platform/EFR32/EFR32Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -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");

Expand Down
5 changes: 3 additions & 2 deletions src/platform/EFR32/KeyValueStoreManagerImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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::Timeout>(System::Clock::Seconds32(5)),
KeyValueStoreManagerImpl::OnScheduledKeyMapSave, NULL);
SystemLayer().StartTimer(
std::chrono::duration_cast<System::Clock::Timeout>(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,
Expand Down
42 changes: 40 additions & 2 deletions src/platform/EFR32/OTAImageProcessorImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@

#include "OTAImageProcessorImpl.h"
#include <app/clusters/ota-requestor/OTADownloader.h>
#include <app/clusters/ota-requestor/OTARequestorInterface.h>

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

Expand All @@ -48,7 +51,10 @@ CHIP_ERROR OTAImageProcessorImpl::Finalize()
}
CHIP_ERROR OTAImageProcessorImpl::Apply()
{
DeviceLayer::PlatformMgr().ScheduleWork(HandleApply, reinterpret_cast<intptr_t>(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;
}

Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down
6 changes: 3 additions & 3 deletions src/platform/EFR32/OTAImageProcessorImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
Expand All @@ -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);
Expand Down

0 comments on commit 1097819

Please sign in to comment.