Skip to content

Commit

Permalink
Added changes for the multi ota 917 soc
Browse files Browse the repository at this point in the history
  • Loading branch information
shgutte committed Mar 26, 2024
1 parent d26d2e5 commit 37c9252
Show file tree
Hide file tree
Showing 6 changed files with 334 additions and 3 deletions.
4 changes: 3 additions & 1 deletion scripts/tools/silabs/ota/ota_image_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,9 @@ class TAG:
APPLICATION = 1
BOOTLOADER = 2
FACTORY_DATA = 3

WIFI_917_NCP_TA = 4
WIFI_917_SOC_COMBINED = 5
WIFI_917_NCP_COMBINED = 6

def write_to_temp(path: str, payload: bytearray):
with open(path, "wb") as _handle:
Expand Down
12 changes: 11 additions & 1 deletion src/platform/silabs/SiWx917/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,17 @@ static_library("SiWx917") {
"PlatformManagerImpl.cpp",
]

if (chip_enable_ota_requestor) {
if (chip_enable_multi_ota_requestor) {
sources += [
"${silabs_platform_dir}/multi-ota/OTAMultiImageProcessorImpl.cpp",
"${silabs_platform_dir}/multi-ota/OTAMultiImageProcessorImpl.h",
"${silabs_platform_dir}/multi-ota/OTATlvProcessor.cpp",
"${silabs_platform_dir}/multi-ota/OTATlvProcessor.h",
"${silabs_platform_dir}/multi-ota/SiWx917/OTAFirmwareProcessor.cpp",
"${silabs_platform_dir}/multi-ota/SiWx917/OTAFirmwareProcessor.h",
"${silabs_platform_dir}/multi-ota/SiWx917/OTAHooks.cpp",
]
} else if (chip_enable_ota_requestor) {
sources += [
"${silabs_platform_dir}/OTAImageProcessorImpl.h",
"OTAImageProcessorImpl.cpp",
Expand Down
11 changes: 10 additions & 1 deletion src/platform/silabs/multi-ota/OTATlvProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@
#endif
namespace chip {

typedef enum
{
APPLICATION,
BOOTLOADER,
FACTORY_DATA,
WIFI_917_NCP_TA,
WIFI_917_SOC_TA, /* This is used as scan result and start */
WIFI_917_NCP_COMBINED
} OTAImageType;

#if OTA_ENCRYPTION_ENABLE
constexpr uint8_t au8Iv[] = { 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x00, 0x00, 0x00, 0x00 };
#endif
Expand All @@ -54,7 +64,6 @@ CHIP_ERROR OTATlvProcessor::Process(ByteSpan & block)
}
}
}

return status;
}

Expand Down
207 changes: 207 additions & 0 deletions src/platform/silabs/multi-ota/SiWx917/OTAFirmwareProcessor.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
/*
*
* Copyright (c) 2023 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <platform/internal/CHIPDeviceLayerInternal.h>
#include <platform/silabs/multi-ota/OTAMultiImageProcessorImpl.h>
#include <platform/silabs/multi-ota/efr32/OTAFirmwareProcessor.h>

#include <app/clusters/ota-requestor/OTARequestorInterface.h>
#include "wfx_host_events.h"
#include <platform/silabs/SilabsConfig.h>
#ifdef __cplusplus
extern "C" {
#endif
#include "sl_si91x_driver.h"
#ifdef SLI_SI91X_MCU_INTERFACE
#include "sl_si91x_hal_soc_soft_reset.h"
#endif
#ifdef __cplusplus
}
#endif

#define RPS_HEADER 1
#define RPS_DATA 2

#define SL_STATUS_FW_UPDATE_DONE SL_STATUS_SI91X_NO_AP_FOUND
uint8_t flag = RPS_HEADER;

// TODO: more descriptive error codes
#define SL_OTA_ERROR 1L

namespace chip {

// Define static memebers
uint8_t OTAFirmwareProcessor::mReset = false;
uint32_t OTAFirmwareProcessor::mWriteOffset = 0;
uint16_t OTAFirmwareProcessor::writeBufOffset = 0;
uint8_t OTAFirmwareProcessor::writeBuffer[kAlignmentBytes] __attribute__((aligned(4))) = { 0 };

CHIP_ERROR OTAFirmwareProcessor::Init()
{
ReturnErrorCodeIf(mCallbackProcessDescriptor == nullptr, CHIP_OTA_PROCESSOR_CB_NOT_REGISTERED);
mAccumulator.Init(sizeof(Descriptor));
#if OTA_ENCRYPTION_ENABLE
mUnalignmentNum = 0;
#endif

return CHIP_NO_ERROR;
}

CHIP_ERROR OTAFirmwareProcessor::Clear()
{
OTATlvProcessor::ClearInternal();
mAccumulator.Clear();
mDescriptorProcessed = false;
#if OTA_ENCRYPTION_ENABLE
mUnalignmentNum = 0;
#endif

return CHIP_NO_ERROR;
}

CHIP_ERROR OTAFirmwareProcessor::ProcessInternal(ByteSpan & block)
{
int32_t status = SL_STATUS_OK;
if (!mDescriptorProcessed)
{
ReturnErrorOnFailure(ProcessDescriptor(block));
}

uint32_t blockReadOffset = 0;
while (blockReadOffset < block.size())
{
writeBuffer[writeBufOffset] = *((block.data()) + blockReadOffset);
writeBufOffset++;
blockReadOffset++;
if (writeBufOffset == kAlignmentBytes)
{
writeBufOffset = 0;

if (flag == RPS_HEADER)
{
// Send RPS header which is received as first chunk
status = sl_si91x_fwup_start(writeBuffer);
status = sl_si91x_fwup_load(writeBuffer, kAlignmentBytes);
flag = RPS_DATA;
}
else if (flag == RPS_DATA)
{
// Send RPS content
status = sl_si91x_fwup_load(writeBuffer, kAlignmentBytes);
if (status != SL_STATUS_OK)
{
// If the last chunk of last block-writeBufOffset length is exactly kAlignmentBytes(64) bytes then mReset value
// should be set to true in HandleProcessBlock
if (status == SL_STATUS_FW_UPDATE_DONE)
{
mReset = true;
}
else
{
ChipLogError(SoftwareUpdate, "ERROR: In HandleProcessBlock sl_si91x_fwup_load() error %ld", status);
imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED);
return;
}
}
}
if (err)
{
ChipLogError(SoftwareUpdate, "bootloader_eraseWriteStorage() error: %ld", err);
// TODO: add this somewhere
// imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED);
// TODO: Replace CHIP_ERROR_CANCELLED with new error statement
return CHIP_ERROR_CANCELLED;
}
mWriteOffset += kAlignmentBytes;
}
}

return CHIP_NO_ERROR;
}

CHIP_ERROR OTAFirmwareProcessor::ProcessDescriptor(ByteSpan & block)
{
ReturnErrorOnFailure(mAccumulator.Accumulate(block));
ReturnErrorOnFailure(mCallbackProcessDescriptor(static_cast<void *>(mAccumulator.data())));

mDescriptorProcessed = true;
mAccumulator.Clear();

return CHIP_NO_ERROR;
}

CHIP_ERROR OTAFirmwareProcessor::ApplyAction()
{
uint32_t err = SL_BOOTLOADER_OK;
if (err != SL_BOOTLOADER_OK)
{
ChipLogError(SoftwareUpdate, "bootloader_verifyImage() error: %ld", err);
// Call the OTARequestor API to reset the state
GetRequestorInstance()->CancelImageUpdate();

return SL_GENERIC_OTA_ERROR;
}

CORE_CRITICAL_SECTION(err = bootloader_setImageToBootload(mSlotId);)
if (err != SL_BOOTLOADER_OK)
{
ChipLogError(SoftwareUpdate, "bootloader_setImageToBootload() error: %ld", err);
// Call the OTARequestor API to reset the state
GetRequestorInstance()->CancelImageUpdate();
return SL_GENERIC_OTA_ERROR;
}

return CHIP_NO_ERROR;
}

CHIP_ERROR OTAFirmwareProcessor::FinalizeAction()
{
int32_t status = SL_STATUS_OK;

// Pad the remainder of the write buffer with zeros and write it to bootloader storage
if (writeBufOffset != 0)
{

while (writeBufOffset != kAlignmentBytes)
{
writeBuffer[writeBufOffset] = 0;
writeBufOffset++;
}
status = sl_si91x_fwup_load(writeBuffer, writeBufOffset);
ChipLogProgress(SoftwareUpdate, "status: 0x%lX", status);

if (status != SL_STATUS_OK)
{
if (status == SL_STATUS_FW_UPDATE_DONE)
{
mReset = true;
}
else
{
ChipLogError(SoftwareUpdate, "ERROR: In HandleFinalize for last chunk sl_si91x_fwup_load() error %ld", status);
imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED);
return;
}
}

}

return err ? CHIP_ERROR_WRITE_FAILED : CHIP_NO_ERROR;
}

} // namespace chip
59 changes: 59 additions & 0 deletions src/platform/silabs/multi-ota/SiWx917/OTAFirmwareProcessor.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
*
* Copyright (c) 2023 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include <lib/support/Span.h>
#include <platform/silabs/multi-ota/OTATlvProcessor.h>

namespace chip {

class OTAFirmwareProcessor : public OTATlvProcessor
{
public:
struct Descriptor
{
uint32_t version;
char versionString[kVersionStringSize];
char buildDate[kBuildDateSize];
};

CHIP_ERROR Init() override;
CHIP_ERROR Clear() override;
CHIP_ERROR ApplyAction() override;
CHIP_ERROR FinalizeAction() override;

private:
CHIP_ERROR ProcessInternal(ByteSpan & block) override;
CHIP_ERROR ProcessDescriptor(ByteSpan & block);

OTADataAccumulator mAccumulator;
bool mDescriptorProcessed = false;
#if OTA_ENCRYPTION_ENABLE
uint32_t mUnalignmentNum;
#endif
static constexpr size_t kAlignmentBytes = 64;
static uint32_t mWriteOffset; // End of last written block
static uint8_t mSlotId; // Bootloader storage slot
// Bootloader storage API requires the buffer size to be a multiple of 4.
static uint8_t writeBuffer[kAlignmentBytes] __attribute__((aligned(4)));
// Offset indicates how far the write buffer has been filled
static uint16_t writeBufOffset;
};

} // namespace chip
44 changes: 44 additions & 0 deletions src/platform/silabs/multi-ota/SiWx917/OTAHooks.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
/*
*
* Copyright (c) 2023 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include <include/platform/CHIPDeviceLayer.h>
#include <platform/silabs/multi-ota/OTAMultiImageProcessorImpl.h>

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

#include <platform/silabs/multi-ota/efr32/OTAFirmwareProcessor.h>

CHIP_ERROR chip::OTAMultiImageProcessorImpl::ProcessDescriptor(void * descriptor)
{
auto desc = static_cast<chip::OTAFirmwareProcessor::Descriptor *>(descriptor);
ChipLogDetail(SoftwareUpdate, "Descriptor: %ld, %s, %s", desc->version, desc->versionString, desc->buildDate);

return CHIP_NO_ERROR;
}

CHIP_ERROR chip::OTAMultiImageProcessorImpl::OtaHookInit()
{
static chip::OTAFirmwareProcessor sApplicationProcessor;

sApplicationProcessor.RegisterDescriptorCallback(ProcessDescriptor);

auto & imageProcessor = chip::OTAMultiImageProcessorImpl::GetDefaultInstance();
ReturnErrorOnFailure(imageProcessor.RegisterProcessor(1, &sApplicationProcessor));

return CHIP_NO_ERROR;
}

0 comments on commit 37c9252

Please sign in to comment.