Skip to content

Commit 37c9252

Browse files
committed
Added changes for the multi ota 917 soc
1 parent d26d2e5 commit 37c9252

File tree

6 files changed

+334
-3
lines changed

6 files changed

+334
-3
lines changed

scripts/tools/silabs/ota/ota_image_tool.py

+3-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ class TAG:
6363
APPLICATION = 1
6464
BOOTLOADER = 2
6565
FACTORY_DATA = 3
66-
66+
WIFI_917_NCP_TA = 4
67+
WIFI_917_SOC_COMBINED = 5
68+
WIFI_917_NCP_COMBINED = 6
6769

6870
def write_to_temp(path: str, payload: bytearray):
6971
with open(path, "wb") as _handle:

src/platform/silabs/SiWx917/BUILD.gn

+11-1
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,17 @@ static_library("SiWx917") {
6666
"PlatformManagerImpl.cpp",
6767
]
6868

69-
if (chip_enable_ota_requestor) {
69+
if (chip_enable_multi_ota_requestor) {
70+
sources += [
71+
"${silabs_platform_dir}/multi-ota/OTAMultiImageProcessorImpl.cpp",
72+
"${silabs_platform_dir}/multi-ota/OTAMultiImageProcessorImpl.h",
73+
"${silabs_platform_dir}/multi-ota/OTATlvProcessor.cpp",
74+
"${silabs_platform_dir}/multi-ota/OTATlvProcessor.h",
75+
"${silabs_platform_dir}/multi-ota/SiWx917/OTAFirmwareProcessor.cpp",
76+
"${silabs_platform_dir}/multi-ota/SiWx917/OTAFirmwareProcessor.h",
77+
"${silabs_platform_dir}/multi-ota/SiWx917/OTAHooks.cpp",
78+
]
79+
} else if (chip_enable_ota_requestor) {
7080
sources += [
7181
"${silabs_platform_dir}/OTAImageProcessorImpl.h",
7282
"OTAImageProcessorImpl.cpp",

src/platform/silabs/multi-ota/OTATlvProcessor.cpp

+10-1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@
2828
#endif
2929
namespace chip {
3030

31+
typedef enum
32+
{
33+
APPLICATION,
34+
BOOTLOADER,
35+
FACTORY_DATA,
36+
WIFI_917_NCP_TA,
37+
WIFI_917_SOC_TA, /* This is used as scan result and start */
38+
WIFI_917_NCP_COMBINED
39+
} OTAImageType;
40+
3141
#if OTA_ENCRYPTION_ENABLE
3242
constexpr uint8_t au8Iv[] = { 0x00, 0x00, 0x00, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x00, 0x00, 0x00, 0x00 };
3343
#endif
@@ -54,7 +64,6 @@ CHIP_ERROR OTATlvProcessor::Process(ByteSpan & block)
5464
}
5565
}
5666
}
57-
5867
return status;
5968
}
6069

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
/*
2+
*
3+
* Copyright (c) 2023 Project CHIP Authors
4+
* All rights reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#include <platform/internal/CHIPDeviceLayerInternal.h>
20+
#include <platform/silabs/multi-ota/OTAMultiImageProcessorImpl.h>
21+
#include <platform/silabs/multi-ota/efr32/OTAFirmwareProcessor.h>
22+
23+
#include <app/clusters/ota-requestor/OTARequestorInterface.h>
24+
#include "wfx_host_events.h"
25+
#include <platform/silabs/SilabsConfig.h>
26+
#ifdef __cplusplus
27+
extern "C" {
28+
#endif
29+
#include "sl_si91x_driver.h"
30+
#ifdef SLI_SI91X_MCU_INTERFACE
31+
#include "sl_si91x_hal_soc_soft_reset.h"
32+
#endif
33+
#ifdef __cplusplus
34+
}
35+
#endif
36+
37+
#define RPS_HEADER 1
38+
#define RPS_DATA 2
39+
40+
#define SL_STATUS_FW_UPDATE_DONE SL_STATUS_SI91X_NO_AP_FOUND
41+
uint8_t flag = RPS_HEADER;
42+
43+
// TODO: more descriptive error codes
44+
#define SL_OTA_ERROR 1L
45+
46+
namespace chip {
47+
48+
// Define static memebers
49+
uint8_t OTAFirmwareProcessor::mReset = false;
50+
uint32_t OTAFirmwareProcessor::mWriteOffset = 0;
51+
uint16_t OTAFirmwareProcessor::writeBufOffset = 0;
52+
uint8_t OTAFirmwareProcessor::writeBuffer[kAlignmentBytes] __attribute__((aligned(4))) = { 0 };
53+
54+
CHIP_ERROR OTAFirmwareProcessor::Init()
55+
{
56+
ReturnErrorCodeIf(mCallbackProcessDescriptor == nullptr, CHIP_OTA_PROCESSOR_CB_NOT_REGISTERED);
57+
mAccumulator.Init(sizeof(Descriptor));
58+
#if OTA_ENCRYPTION_ENABLE
59+
mUnalignmentNum = 0;
60+
#endif
61+
62+
return CHIP_NO_ERROR;
63+
}
64+
65+
CHIP_ERROR OTAFirmwareProcessor::Clear()
66+
{
67+
OTATlvProcessor::ClearInternal();
68+
mAccumulator.Clear();
69+
mDescriptorProcessed = false;
70+
#if OTA_ENCRYPTION_ENABLE
71+
mUnalignmentNum = 0;
72+
#endif
73+
74+
return CHIP_NO_ERROR;
75+
}
76+
77+
CHIP_ERROR OTAFirmwareProcessor::ProcessInternal(ByteSpan & block)
78+
{
79+
int32_t status = SL_STATUS_OK;
80+
if (!mDescriptorProcessed)
81+
{
82+
ReturnErrorOnFailure(ProcessDescriptor(block));
83+
}
84+
85+
uint32_t blockReadOffset = 0;
86+
while (blockReadOffset < block.size())
87+
{
88+
writeBuffer[writeBufOffset] = *((block.data()) + blockReadOffset);
89+
writeBufOffset++;
90+
blockReadOffset++;
91+
if (writeBufOffset == kAlignmentBytes)
92+
{
93+
writeBufOffset = 0;
94+
95+
if (flag == RPS_HEADER)
96+
{
97+
// Send RPS header which is received as first chunk
98+
status = sl_si91x_fwup_start(writeBuffer);
99+
status = sl_si91x_fwup_load(writeBuffer, kAlignmentBytes);
100+
flag = RPS_DATA;
101+
}
102+
else if (flag == RPS_DATA)
103+
{
104+
// Send RPS content
105+
status = sl_si91x_fwup_load(writeBuffer, kAlignmentBytes);
106+
if (status != SL_STATUS_OK)
107+
{
108+
// If the last chunk of last block-writeBufOffset length is exactly kAlignmentBytes(64) bytes then mReset value
109+
// should be set to true in HandleProcessBlock
110+
if (status == SL_STATUS_FW_UPDATE_DONE)
111+
{
112+
mReset = true;
113+
}
114+
else
115+
{
116+
ChipLogError(SoftwareUpdate, "ERROR: In HandleProcessBlock sl_si91x_fwup_load() error %ld", status);
117+
imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED);
118+
return;
119+
}
120+
}
121+
}
122+
if (err)
123+
{
124+
ChipLogError(SoftwareUpdate, "bootloader_eraseWriteStorage() error: %ld", err);
125+
// TODO: add this somewhere
126+
// imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED);
127+
// TODO: Replace CHIP_ERROR_CANCELLED with new error statement
128+
return CHIP_ERROR_CANCELLED;
129+
}
130+
mWriteOffset += kAlignmentBytes;
131+
}
132+
}
133+
134+
return CHIP_NO_ERROR;
135+
}
136+
137+
CHIP_ERROR OTAFirmwareProcessor::ProcessDescriptor(ByteSpan & block)
138+
{
139+
ReturnErrorOnFailure(mAccumulator.Accumulate(block));
140+
ReturnErrorOnFailure(mCallbackProcessDescriptor(static_cast<void *>(mAccumulator.data())));
141+
142+
mDescriptorProcessed = true;
143+
mAccumulator.Clear();
144+
145+
return CHIP_NO_ERROR;
146+
}
147+
148+
CHIP_ERROR OTAFirmwareProcessor::ApplyAction()
149+
{
150+
uint32_t err = SL_BOOTLOADER_OK;
151+
if (err != SL_BOOTLOADER_OK)
152+
{
153+
ChipLogError(SoftwareUpdate, "bootloader_verifyImage() error: %ld", err);
154+
// Call the OTARequestor API to reset the state
155+
GetRequestorInstance()->CancelImageUpdate();
156+
157+
return SL_GENERIC_OTA_ERROR;
158+
}
159+
160+
CORE_CRITICAL_SECTION(err = bootloader_setImageToBootload(mSlotId);)
161+
if (err != SL_BOOTLOADER_OK)
162+
{
163+
ChipLogError(SoftwareUpdate, "bootloader_setImageToBootload() error: %ld", err);
164+
// Call the OTARequestor API to reset the state
165+
GetRequestorInstance()->CancelImageUpdate();
166+
return SL_GENERIC_OTA_ERROR;
167+
}
168+
169+
return CHIP_NO_ERROR;
170+
}
171+
172+
CHIP_ERROR OTAFirmwareProcessor::FinalizeAction()
173+
{
174+
int32_t status = SL_STATUS_OK;
175+
176+
// Pad the remainder of the write buffer with zeros and write it to bootloader storage
177+
if (writeBufOffset != 0)
178+
{
179+
180+
while (writeBufOffset != kAlignmentBytes)
181+
{
182+
writeBuffer[writeBufOffset] = 0;
183+
writeBufOffset++;
184+
}
185+
status = sl_si91x_fwup_load(writeBuffer, writeBufOffset);
186+
ChipLogProgress(SoftwareUpdate, "status: 0x%lX", status);
187+
188+
if (status != SL_STATUS_OK)
189+
{
190+
if (status == SL_STATUS_FW_UPDATE_DONE)
191+
{
192+
mReset = true;
193+
}
194+
else
195+
{
196+
ChipLogError(SoftwareUpdate, "ERROR: In HandleFinalize for last chunk sl_si91x_fwup_load() error %ld", status);
197+
imageProcessor->mDownloader->EndDownload(CHIP_ERROR_WRITE_FAILED);
198+
return;
199+
}
200+
}
201+
202+
}
203+
204+
return err ? CHIP_ERROR_WRITE_FAILED : CHIP_NO_ERROR;
205+
}
206+
207+
} // namespace chip
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
*
3+
* Copyright (c) 2023 Project CHIP Authors
4+
* All rights reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#pragma once
20+
21+
#include <lib/support/Span.h>
22+
#include <platform/silabs/multi-ota/OTATlvProcessor.h>
23+
24+
namespace chip {
25+
26+
class OTAFirmwareProcessor : public OTATlvProcessor
27+
{
28+
public:
29+
struct Descriptor
30+
{
31+
uint32_t version;
32+
char versionString[kVersionStringSize];
33+
char buildDate[kBuildDateSize];
34+
};
35+
36+
CHIP_ERROR Init() override;
37+
CHIP_ERROR Clear() override;
38+
CHIP_ERROR ApplyAction() override;
39+
CHIP_ERROR FinalizeAction() override;
40+
41+
private:
42+
CHIP_ERROR ProcessInternal(ByteSpan & block) override;
43+
CHIP_ERROR ProcessDescriptor(ByteSpan & block);
44+
45+
OTADataAccumulator mAccumulator;
46+
bool mDescriptorProcessed = false;
47+
#if OTA_ENCRYPTION_ENABLE
48+
uint32_t mUnalignmentNum;
49+
#endif
50+
static constexpr size_t kAlignmentBytes = 64;
51+
static uint32_t mWriteOffset; // End of last written block
52+
static uint8_t mSlotId; // Bootloader storage slot
53+
// Bootloader storage API requires the buffer size to be a multiple of 4.
54+
static uint8_t writeBuffer[kAlignmentBytes] __attribute__((aligned(4)));
55+
// Offset indicates how far the write buffer has been filled
56+
static uint16_t writeBufOffset;
57+
};
58+
59+
} // namespace chip
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
/*
2+
*
3+
* Copyright (c) 2023 Project CHIP Authors
4+
* All rights reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#include <include/platform/CHIPDeviceLayer.h>
20+
#include <platform/silabs/multi-ota/OTAMultiImageProcessorImpl.h>
21+
22+
#include <app/clusters/ota-requestor/OTARequestorInterface.h>
23+
24+
#include <platform/silabs/multi-ota/efr32/OTAFirmwareProcessor.h>
25+
26+
CHIP_ERROR chip::OTAMultiImageProcessorImpl::ProcessDescriptor(void * descriptor)
27+
{
28+
auto desc = static_cast<chip::OTAFirmwareProcessor::Descriptor *>(descriptor);
29+
ChipLogDetail(SoftwareUpdate, "Descriptor: %ld, %s, %s", desc->version, desc->versionString, desc->buildDate);
30+
31+
return CHIP_NO_ERROR;
32+
}
33+
34+
CHIP_ERROR chip::OTAMultiImageProcessorImpl::OtaHookInit()
35+
{
36+
static chip::OTAFirmwareProcessor sApplicationProcessor;
37+
38+
sApplicationProcessor.RegisterDescriptorCallback(ProcessDescriptor);
39+
40+
auto & imageProcessor = chip::OTAMultiImageProcessorImpl::GetDefaultInstance();
41+
ReturnErrorOnFailure(imageProcessor.RegisterProcessor(1, &sApplicationProcessor));
42+
43+
return CHIP_NO_ERROR;
44+
}

0 commit comments

Comments
 (0)