Skip to content

Commit

Permalink
[ESP32] Parse OTA image header (#14957)
Browse files Browse the repository at this point in the history
* [ESP32] Parse OTA image header

Added documentation for building OTA image
Added more help for CHIP_OTA_IMAGE_BUILD config option
Fixed the usage of CHIP_OTA_IMAGE_BUILD option

* End download if OTA image header parsing fails
  • Loading branch information
shubhamdp authored and pull[bot] committed Nov 1, 2023
1 parent d7ae850 commit 2776977
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 6 deletions.
7 changes: 5 additions & 2 deletions config/esp32/components/chip/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -789,8 +789,11 @@ menu "CHIP Device Layer"
string "OTA image creator extra arguments"
depends on CHIP_OTA_IMAGE_BUILD
help
This option allows one to pass optional arguments to the ota_image_tool.py script,
used for building OTA image with Matter OTA header.
ota_image_tool.py is used to create the OTA image.
Mandatory arguments(Version, VersionString, VID, PID) are picked up from the config options.
This option allows us to pass optional arguments(MinApplicableSoftwareVersion, MaxApplicableSoftwareVersion,
and ReleaseNotesURL) to the ota_image_tool.py script.
eg: "-mi 2 -ma 4 -rn https://github.com/espressif/esp-idf/releases/tag/v4.4"

endmenu

Expand Down
3 changes: 1 addition & 2 deletions config/esp32/components/chip/ota-image.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ function(chip_ota_image TARGET_NAME)
"sha256"
)

separate_arguments(OTA_EXTRA_ARGS NATIVE_COMMAND "${CHIP_OTA_IMAGE_EXTRA_ARGS}")
separate_arguments(OTA_EXTRA_ARGS NATIVE_COMMAND "${CONFIG_CHIP_OTA_IMAGE_EXTRA_ARGS}")

list(APPEND OTA_ARGS ${OTA_EXTRA_ARGS})
list(APPEND OTA_ARGS ${ARG_INPUT_FILES})
Expand All @@ -60,6 +60,5 @@ function(chip_ota_image TARGET_NAME)

add_custom_target(${TARGET_NAME} ALL
COMMAND ${Python3_EXECUTABLE} ${CHIP_ROOT}/src/app/ota_image_tool.py create @${BUILD_DIR}/args-ota-image.tmp
COMMAND ${CMAKE_COMMAND} -E remove ${BUILD_DIR}/args-ota-image.tmp
)
endfunction()
15 changes: 15 additions & 0 deletions examples/ota-requestor-app/esp32/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,18 @@ application of OTA image.
```
./out/debug/chip-tool pairing onnetwork 12345 20202021
```

## Generate OTA image

User can generate the Matter OTA image by simply enabling
`CONFIG_CHIP_OTA_IMAGE_BUILD` config option. OTA image is generated in `build`
directory with name `<project name>-ota.bin`. This image then can be used with
OTA Provider Application.

Please make sure that version number is set to correct value. Use
`CONFIG_DEVICE_SOFTWARE_VERSION` and `CONFIG_DEVICE_SOFTWARE_VERSION_NUMBER`
config options for setting software version.

Matter OTA image can also be generated using
[ota_image_tool.py](https://github.com/project-chip/connectedhomeip/blob/master/src/app/ota_image_tool.py)
script.
36 changes: 34 additions & 2 deletions src/platform/ESP32/OTAImageProcessorImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context)
imageProcessor->mDownloader->OnPreparedForDownload(ESP32Utils::MapError(err));
return;
}
imageProcessor->mHeaderParser.Init();
imageProcessor->mDownloader->OnPreparedForDownload(CHIP_NO_ERROR);
}

Expand Down Expand Up @@ -156,13 +157,25 @@ void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context)
ChipLogError(SoftwareUpdate, "mDownloader is null");
return;
}
esp_err_t err = esp_ota_write(imageProcessor->mOTAUpdateHandle, imageProcessor->mBlock.data(), imageProcessor->mBlock.size());

ByteSpan block = ByteSpan(imageProcessor->mBlock.data(), imageProcessor->mBlock.size());

CHIP_ERROR error = imageProcessor->ProcessBlock(block);
if (error != CHIP_NO_ERROR)
{
ESP_LOGE(TAG, "Failed to process OTA image header");
imageProcessor->mDownloader->EndDownload(error);
return;
}

esp_err_t err = esp_ota_write(imageProcessor->mOTAUpdateHandle, block.data(), block.size());
if (err != ESP_OK)
{
ESP_LOGE(TAG, "esp_ota_write failed (%s)", esp_err_to_name(err));
imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED);
return;
}
imageProcessor->mParams.downloadedBytes += imageProcessor->mBlock.size();
imageProcessor->mParams.downloadedBytes += block.size();
imageProcessor->mDownloader->FetchNextData();
}

Expand Down Expand Up @@ -219,4 +232,23 @@ CHIP_ERROR OTAImageProcessorImpl::ReleaseBlock()
mBlock = MutableByteSpan();
return CHIP_NO_ERROR;
}

CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block)
{
if (mHeaderParser.IsInitialized())
{
OTAImageHeader header;
CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header);

// Need more data to decode the header
ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR);
ReturnErrorOnFailure(error);

mParams.totalFileBytes = header.mPayloadSize;
mHeaderParser.Clear();
}

return CHIP_NO_ERROR;
}

} // namespace chip
3 changes: 3 additions & 0 deletions src/platform/ESP32/OTAImageProcessorImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

#include "esp_ota_ops.h"
#include <app/clusters/ota-requestor/BDXDownloader.h>
#include <lib/core/OTAImageHeader.h>
#include <platform/CHIPDeviceLayer.h>
#include <platform/OTAImageProcessor.h>

Expand All @@ -44,11 +45,13 @@ class OTAImageProcessorImpl : public OTAImageProcessorInterface

CHIP_ERROR SetBlock(ByteSpan & block);
CHIP_ERROR ReleaseBlock();
CHIP_ERROR ProcessHeader(ByteSpan & block);

OTADownloader * mDownloader = nullptr;
MutableByteSpan mBlock;
const esp_partition_t * mOTAUpdatePartition = nullptr;
esp_ota_handle_t mOTAUpdateHandle;
OTAImageHeaderParser mHeaderParser;
};

} // namespace chip

0 comments on commit 2776977

Please sign in to comment.