From 2a447e73903ae9893c75f8b955fa941fa1548f7e Mon Sep 17 00:00:00 2001 From: Shubham Patil Date: Wed, 17 Aug 2022 20:54:00 +0530 Subject: [PATCH] [ESP32] Added some OTA events for the device (#21953) * [ESP32] Added some OTA events for the device * Addressed review comments * fix the cut pasted log prints --- .../ota-requestor-app/esp32/main/main.cpp | 36 +++++++++++++++++++ src/include/platform/CHIPDeviceEvent.h | 28 +++++++++++++++ src/platform/ESP32/OTAImageProcessorImpl.cpp | 35 +++++++++++++++--- 3 files changed, 94 insertions(+), 5 deletions(-) diff --git a/examples/ota-requestor-app/esp32/main/main.cpp b/examples/ota-requestor-app/esp32/main/main.cpp index 021fd5b3fb6675..ba9ed616b05e5f 100644 --- a/examples/ota-requestor-app/esp32/main/main.cpp +++ b/examples/ota-requestor-app/esp32/main/main.cpp @@ -80,6 +80,40 @@ DeviceLayer::ESP32DeviceInfoProvider gExampleDeviceInfoProvider; #else DeviceLayer::DeviceInfoProviderImpl gExampleDeviceInfoProvider; #endif // CONFIG_ENABLE_ESP32_DEVICE_INFO_PROVIDER + +void OTAEventsHandler(const DeviceLayer::ChipDeviceEvent * event, intptr_t arg) +{ + if (event->Type == DeviceLayer::DeviceEventType::kOtaStateChanged) + { + switch (event->OtaStateChanged.newState) + { + case DeviceLayer::kOtaDownloadInProgress: + ChipLogProgress(DeviceLayer, "OTA image download in progress"); + break; + case DeviceLayer::kOtaDownloadComplete: + ChipLogProgress(DeviceLayer, "OTA image download complete"); + break; + case DeviceLayer::kOtaDownloadFailed: + ChipLogProgress(DeviceLayer, "OTA image download failed"); + break; + case DeviceLayer::kOtaDownloadAborted: + ChipLogProgress(DeviceLayer, "OTA image download aborted"); + break; + case DeviceLayer::kOtaApplyInProgress: + ChipLogProgress(DeviceLayer, "OTA image apply in progress"); + break; + case DeviceLayer::kOtaApplyComplete: + ChipLogProgress(DeviceLayer, "OTA image apply complete"); + break; + case DeviceLayer::kOtaApplyFailed: + ChipLogProgress(DeviceLayer, "OTA image apply failed"); + break; + default: + break; + } + } +} + } // namespace extern "C" void app_main() @@ -136,4 +170,6 @@ extern "C" void app_main() #endif // CONFIG_ENABLE_ESP32_FACTORY_DATA_PROVIDER chip::DeviceLayer::PlatformMgr().ScheduleWork(InitServer, reinterpret_cast(nullptr)); + + chip::DeviceLayer::PlatformMgrImpl().AddEventHandler(OTAEventsHandler, reinterpret_cast(nullptr)); } diff --git a/src/include/platform/CHIPDeviceEvent.h b/src/include/platform/CHIPDeviceEvent.h index 1bbf424baa611d..4d3e8353e85e13 100644 --- a/src/include/platform/CHIPDeviceEvent.h +++ b/src/include/platform/CHIPDeviceEvent.h @@ -287,6 +287,34 @@ enum ActivityChange enum OtaState { kOtaSpaceAvailable = 0, + /** + * This state indicates that Node is currently downloading a software update. + */ + kOtaDownloadInProgress, + /** + * This state indicates that Node has successfully downloaded a software update. + */ + kOtaDownloadComplete, + /** + * This state indicates that Node has failed to download a software update. + */ + kOtaDownloadFailed, + /** + * This state indicates that Node has aborted the download of a software update. + */ + kOtaDownloadAborted, + /** + * This state indicate that Node is currently in the process of verifying and applying a software update. + */ + kOtaApplyInProgress, + /** + * This state indicates that Node has successfully applied a software update. + */ + kOtaApplyComplete, + /** + * This state indicates that Node has failed to apply a software update. + */ + kOtaApplyFailed, }; inline ConnectivityChange GetConnectivityChange(bool prevState, bool newState) diff --git a/src/platform/ESP32/OTAImageProcessorImpl.cpp b/src/platform/ESP32/OTAImageProcessorImpl.cpp index 62fbe55410bef2..ad93fa8e439238 100644 --- a/src/platform/ESP32/OTAImageProcessorImpl.cpp +++ b/src/platform/ESP32/OTAImageProcessorImpl.cpp @@ -17,6 +17,7 @@ #include #include +#include #include #include "OTAImageProcessorImpl.h" @@ -37,11 +38,25 @@ void HandleRestart(Layer * systemLayer, void * appState) { esp_restart(); } + +void PostOTAStateChangeEvent(DeviceLayer::OtaState newState) +{ + DeviceLayer::ChipDeviceEvent otaChange; + otaChange.Type = DeviceLayer::DeviceEventType::kOtaStateChanged; + otaChange.OtaStateChanged.newState = newState; + CHIP_ERROR error = DeviceLayer::PlatformMgr().PostEvent(&otaChange); + + if (error != CHIP_NO_ERROR) + { + ChipLogError(SoftwareUpdate, "Error while posting OtaChange event %" CHIP_ERROR_FORMAT, error.Format()); + } +} + } // namespace bool OTAImageProcessorImpl::IsFirstImageRun() { - OTARequestorInterface * requestor = chip::GetRequestorInstance(); + OTARequestorInterface * requestor = GetRequestorInstance(); if (requestor == nullptr) { return false; @@ -52,7 +67,7 @@ bool OTAImageProcessorImpl::IsFirstImageRun() CHIP_ERROR OTAImageProcessorImpl::ConfirmCurrentImage() { - OTARequestorInterface * requestor = chip::GetRequestorInstance(); + OTARequestorInterface * requestor = GetRequestorInstance(); if (requestor == nullptr) { return CHIP_ERROR_INTERNAL; @@ -132,6 +147,7 @@ void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context) } imageProcessor->mHeaderParser.Init(); imageProcessor->mDownloader->OnPreparedForDownload(CHIP_NO_ERROR); + PostOTAStateChangeEvent(DeviceLayer::kOtaDownloadInProgress); } void OTAImageProcessorImpl::HandleFinalize(intptr_t context) @@ -153,10 +169,12 @@ void OTAImageProcessorImpl::HandleFinalize(intptr_t context) { ESP_LOGE(TAG, "esp_ota_end failed (%s)!", esp_err_to_name(err)); } + PostOTAStateChangeEvent(DeviceLayer::kOtaDownloadFailed); return; } imageProcessor->ReleaseBlock(); ChipLogProgress(SoftwareUpdate, "OTA image downloaded to offset 0x%x", imageProcessor->mOTAUpdatePartition->address); + PostOTAStateChangeEvent(DeviceLayer::kOtaDownloadComplete); } void OTAImageProcessorImpl::HandleAbort(intptr_t context) @@ -172,6 +190,7 @@ void OTAImageProcessorImpl::HandleAbort(intptr_t context) ESP_LOGE(TAG, "ESP OTA abort failed"); } imageProcessor->ReleaseBlock(); + PostOTAStateChangeEvent(DeviceLayer::kOtaDownloadAborted); } void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context) @@ -195,6 +214,7 @@ void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context) { ESP_LOGE(TAG, "Failed to process OTA image header"); imageProcessor->mDownloader->EndDownload(error); + PostOTAStateChangeEvent(DeviceLayer::kOtaDownloadFailed); return; } @@ -203,6 +223,7 @@ void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context) { ESP_LOGE(TAG, "esp_ota_write failed (%s)", esp_err_to_name(err)); imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED); + PostOTAStateChangeEvent(DeviceLayer::kOtaDownloadFailed); return; } imageProcessor->mParams.downloadedBytes += block.size(); @@ -211,17 +232,21 @@ void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context) void OTAImageProcessorImpl::HandleApply(intptr_t context) { + PostOTAStateChangeEvent(DeviceLayer::kOtaApplyInProgress); auto * imageProcessor = reinterpret_cast(context); esp_err_t err = esp_ota_set_boot_partition(imageProcessor->mOTAUpdatePartition); if (err != ESP_OK) { ESP_LOGE(TAG, "esp_ota_set_boot_partition failed (%s)!", esp_err_to_name(err)); + PostOTAStateChangeEvent(DeviceLayer::kOtaApplyFailed); return; } ESP_LOGI(TAG, "Applying, Boot partition set offset:0x%x", imageProcessor->mOTAUpdatePartition->address); + PostOTAStateChangeEvent(DeviceLayer::kOtaApplyComplete); + // HandleApply is called after delayed action time seconds are elapsed, so it would be safe to schedule the restart - chip::DeviceLayer::SystemLayer().StartTimer(chip::System::Clock::Milliseconds32(2 * 1000), HandleRestart, nullptr); + DeviceLayer::SystemLayer().StartTimer(System::Clock::Milliseconds32(2 * 1000), HandleRestart, nullptr); } CHIP_ERROR OTAImageProcessorImpl::SetBlock(ByteSpan & block) @@ -237,7 +262,7 @@ CHIP_ERROR OTAImageProcessorImpl::SetBlock(ByteSpan & block) { ReleaseBlock(); } - uint8_t * mBlock_ptr = static_cast(chip::Platform::MemoryAlloc(block.size())); + uint8_t * mBlock_ptr = static_cast(Platform::MemoryAlloc(block.size())); if (mBlock_ptr == nullptr) { return CHIP_ERROR_NO_MEMORY; @@ -257,7 +282,7 @@ CHIP_ERROR OTAImageProcessorImpl::ReleaseBlock() { if (mBlock.data() != nullptr) { - chip::Platform::MemoryFree(mBlock.data()); + Platform::MemoryFree(mBlock.data()); } mBlock = MutableByteSpan(); return CHIP_NO_ERROR;