Skip to content

Commit

Permalink
Delta OTA Feature
Browse files Browse the repository at this point in the history
  • Loading branch information
PSONALl committed Aug 2, 2023
1 parent 5b4f800 commit 695c736
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 4 deletions.
8 changes: 8 additions & 0 deletions config/esp32/components/chip/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,9 @@ if (CONFIG_ENABLE_ENCRYPTED_OTA)
list(APPEND chip_libraries $<TARGET_FILE:${esp_encrypted_img_lib}>)
endif()

idf_component_get_property(esp_delta_ota_lib espressif__esp_delta_ota COMPONENT_LIB)
list(APPEND chip_libraries $<TARGET_FILE:${esp_delta_ota_lib}>)

idf_component_get_property(main_lib main COMPONENT_LIB)
list(APPEND chip_libraries $<TARGET_FILE:${main_lib}>)

Expand Down Expand Up @@ -441,6 +444,11 @@ if (CONFIG_ETH_ENABLED)
list(APPEND chip_libraries $<TARGET_FILE:${esp_eth_lib}>)
endif()

if (CONFIG_ENABLE_ESP32_BLE_CONTROLLER)
idf_component_get_property(esp_coex_lib esp_coex COMPONENT_LIB)
list(APPEND chip_libraries $<TARGET_FILE:${esp_coex_lib}>)
endif()

idf_component_get_property(esp_netif_lib esp_netif COMPONENT_LIB)
list(APPEND chip_libraries $<TARGET_FILE:${esp_netif_lib}>)

Expand Down
5 changes: 5 additions & 0 deletions config/esp32/components/chip/idf_component.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,8 @@ dependencies:
version: "2.0.3"
rules:
- if: "idf_version >=4.4"

espressif/esp_delta_ota:
version: "1.0.1"
service_url: "https://api.components-staging.espressif.com"
require: public
71 changes: 68 additions & 3 deletions src/platform/ESP32/OTAImageProcessorImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,14 @@
#include "esp_log.h"
#include "esp_ota_ops.h"
#include "esp_system.h"
#include "esp_app_format.h"
#include "lib/core/CHIPError.h"

#if CONFIG_ENABLE_ENCRYPTED_OTA
#include <esp_encrypted_img.h>
#endif // CONFIG_ENABLE_ENCRYPTED_OTA

#include <esp_delta_ota.h>
#define TAG "OTAImageProcessor"
using namespace chip::System;
using namespace ::chip::DeviceLayer::Internal;
Expand Down Expand Up @@ -137,6 +139,49 @@ CHIP_ERROR OTAImageProcessorImpl::ProcessBlock(ByteSpan & block)
return CHIP_NO_ERROR;
}

esp_err_t OTAImageProcessorImpl::DeltaOTAReadCallback(uint8_t *buf_p, size_t size, int src_offset)
{
if (size <= 0) {
return ESP_ERR_INVALID_ARG;
}
const esp_partition_t *current_partition = esp_ota_get_running_partition();
return esp_partition_read(current_partition, src_offset, buf_p, size);
}

esp_err_t OTAImageProcessorImpl::DeltaOTAWriteCallback(const uint8_t *buf_p, size_t size, void *arg)
{
auto * imageProcessor = reinterpret_cast<OTAImageProcessorImpl *>(arg);
if (size <= 0) {
return ESP_ERR_INVALID_ARG;
}
#define IMG_HEADER_LEN sizeof(esp_image_header_t)

static char header_data[IMG_HEADER_LEN];
static bool chip_id_verified = false;
static int header_data_read = 0;
int index = 0;

if (!chip_id_verified) {
if (header_data_read + size <= IMG_HEADER_LEN) {
memcpy(header_data + header_data_read, buf_p, size);
header_data_read += size;
return ESP_OK;
} else {
index = IMG_HEADER_LEN - header_data_read;
memcpy(header_data + header_data_read, buf_p, index);

chip_id_verified = true;

// Write data in header_data buffer.
esp_err_t err = esp_ota_write(imageProcessor->mOTAUpdateHandle, header_data, IMG_HEADER_LEN);
if (err != ESP_OK) {
return err;
}
}
}
return esp_ota_write(imageProcessor->mOTAUpdateHandle, buf_p + index, size - index);
}

void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context)
{
auto * imageProcessor = reinterpret_cast<OTAImageProcessorImpl *>(context);
Expand All @@ -163,6 +208,16 @@ void OTAImageProcessorImpl::HandlePrepareDownload(intptr_t context)
imageProcessor->mDownloader->OnPreparedForDownload(ESP32Utils::MapError(err));
return;
}
esp_delta_ota_cfg_t cfg = {
.user_data = imageProcessor,
.read_cb = &(imageProcessor->DeltaOTAReadCallback),
.write_cb = &(imageProcessor->DeltaOTAWriteCallback),
};

imageProcessor->mDeltaOTAUpdateHandle = esp_delta_ota_init(&cfg);
if (imageProcessor->mDeltaOTAUpdateHandle == NULL) {
ESP_LOGE(TAG, "delta_ota_set_cfg failed");
}

#if CONFIG_ENABLE_ENCRYPTED_OTA
if (imageProcessor->mEncryptedOTAEnabled == false)
Expand Down Expand Up @@ -207,7 +262,17 @@ void OTAImageProcessorImpl::HandleFinalize(intptr_t context)
imageProcessor->EndDecryption();
#endif // CONFIG_ENABLE_ENCRYPTED_OTA

esp_err_t err = esp_ota_end(imageProcessor->mOTAUpdateHandle);
esp_err_t err = esp_delta_ota_finalize(imageProcessor->mDeltaOTAUpdateHandle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_delta_ota_finalize() failed : %s", esp_err_to_name(err));
}

err = esp_delta_ota_deinit(imageProcessor->mDeltaOTAUpdateHandle);
if (err != ESP_OK) {
ESP_LOGE(TAG, "esp_delta_ota_deinit() failed : %s", esp_err_to_name(err));
}

err = esp_ota_end(imageProcessor->mOTAUpdateHandle);
if (err != ESP_OK)
{
if (err == ESP_ERR_OTA_VALIDATE_FAILED)
Expand Down Expand Up @@ -319,8 +384,8 @@ void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context)
blockToWrite = ByteSpan(reinterpret_cast<const uint8_t *>(preEncOtaDecryptArgs.data_out), preEncOtaDecryptArgs.data_out_len);
#endif // CONFIG_ENABLE_ENCRYPTED_OTA

err = esp_ota_write(imageProcessor->mOTAUpdateHandle, blockToWrite.data(), blockToWrite.size());

// err = esp_ota_write(imageProcessor->mOTAUpdateHandle, blockToWrite.data(), blockToWrite.size());
err = esp_delta_ota_feed_patch(imageProcessor->mDeltaOTAUpdateHandle, blockToWrite.data(), blockToWrite.size());
#if CONFIG_ENABLE_ENCRYPTED_OTA
free(preEncOtaDecryptArgs.data_out);
#endif // CONFIG_ENABLE_ENCRYPTED_OTA
Expand Down
5 changes: 4 additions & 1 deletion src/platform/ESP32/OTAImageProcessorImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#if CONFIG_ENABLE_ENCRYPTED_OTA
#include <esp_encrypted_img.h>
#endif // CONFIG_ENABLE_ENCRYPTED_OTA
#include <esp_delta_ota.h>

namespace chip {

Expand All @@ -48,7 +49,8 @@ class OTAImageProcessorImpl : public OTAImageProcessorInterface
// @return CHIP_NO_ERROR on success, appropriate error code otherwise
CHIP_ERROR InitEncryptedOTA(const CharSpan & key);
#endif // CONFIG_ENABLE_ENCRYPTED_OTA

static esp_err_t DeltaOTAReadCallback(uint8_t *buf_p, size_t size, int src_offset);
static esp_err_t DeltaOTAWriteCallback(const uint8_t *buf_p, size_t size, void *arg);
private:
static void HandlePrepareDownload(intptr_t context);
static void HandleFinalize(intptr_t context);
Expand All @@ -64,6 +66,7 @@ class OTAImageProcessorImpl : public OTAImageProcessorInterface
MutableByteSpan mBlock;
const esp_partition_t * mOTAUpdatePartition = nullptr;
esp_ota_handle_t mOTAUpdateHandle;
esp_delta_ota_handle_t mDeltaOTAUpdateHandle;
OTAImageHeaderParser mHeaderParser;

#if CONFIG_ENABLE_ENCRYPTED_OTA
Expand Down

0 comments on commit 695c736

Please sign in to comment.