diff --git a/examples/ota-requestor-app/esp32/main/main.cpp b/examples/ota-requestor-app/esp32/main/main.cpp index 021fd5b3fb6675..3124ebbaaa9ca8 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 in progress"); + break; + case DeviceLayer::kOtaApplyFailed: + ChipLogProgress(DeviceLayer, "OTA image apply in progress"); + 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..67c98a49efad69 100644 --- a/src/include/platform/CHIPDeviceEvent.h +++ b/src/include/platform/CHIPDeviceEvent.h @@ -287,6 +287,13 @@ enum ActivityChange enum OtaState { kOtaSpaceAvailable = 0, + kOtaDownloadInProgress, + kOtaDownloadComplete, + kOtaDownloadFailed, + kOtaDownloadAborted, + kOtaApplyInProgress, + kOtaApplyComplete, + kOtaApplyFailed, }; inline ConnectivityChange GetConnectivityChange(bool prevState, bool newState) diff --git a/src/platform/ESP32/OTAImageProcessorImpl.cpp b/src/platform/ESP32/OTAImageProcessorImpl.cpp index 62fbe55410bef2..9ed082caa7fe19 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,20 @@ 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); // 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); + PostOTAStateChangeEvent(DeviceLayer::kOtaApplyComplete); } CHIP_ERROR OTAImageProcessorImpl::SetBlock(ByteSpan & block) @@ -237,7 +261,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 +281,7 @@ CHIP_ERROR OTAImageProcessorImpl::ReleaseBlock() { if (mBlock.data() != nullptr) { - chip::Platform::MemoryFree(mBlock.data()); + Platform::MemoryFree(mBlock.data()); } mBlock = MutableByteSpan(); return CHIP_NO_ERROR;