Skip to content

Commit 1050772

Browse files
tima-qrestyled-commits
authored andcommitted
[QPG] OTA updates + Move to secure bootloader (#20224)
* [QPG] * OTA updates + Move to secure bootloader * SDK submodule update for changes * Restyled by clang-format * [QPG] * Update persistent-storage app to SDK API change Co-authored-by: Restyled.io <commits@restyled.io>
1 parent 5ca6bd0 commit 1050772

File tree

10 files changed

+153
-51
lines changed

10 files changed

+153
-51
lines changed

examples/lighting-app/qpg/include/CHIPProjectConfig.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@
6868
*/
6969
#define CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION 1
7070

71+
/**
72+
* CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION
73+
*
74+
* A uint32_t identifying the software version running on the device.
75+
*/
76+
#ifndef CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION
77+
#define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION 0x0001
78+
#endif
79+
7180
/**
7281
* CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING
7382
*

examples/persistent-storage/qpg/main.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,25 +47,29 @@ void TestTask(void * pvParameter)
4747
}
4848
}
4949

50+
void Application_Init(void)
51+
{
52+
/* Launch application task */
53+
qvCHIP_Printf(LOG_MODULE_ID, "============================");
54+
qvCHIP_Printf(LOG_MODULE_ID, "Qorvo " APP_NAME " Launching");
55+
qvCHIP_Printf(LOG_MODULE_ID, "============================");
56+
57+
// Run tests
58+
xTaskCreateStatic(TestTask, APP_NAME, 2048, NULL, 1, appStack, &appTaskStruct);
59+
}
60+
5061
int main(void)
5162
{
5263

5364
int result;
5465

5566
/* Initialize Qorvo stack */
56-
result = qvCHIP_init();
67+
result = qvCHIP_init(Application_Init);
5768
if (result < 0)
5869
{
5970
goto exit;
6071
}
6172

62-
/* Launch application task */
63-
qvCHIP_Printf(LOG_MODULE_ID, "============================");
64-
qvCHIP_Printf(LOG_MODULE_ID, "Qorvo " APP_NAME " Launching");
65-
qvCHIP_Printf(LOG_MODULE_ID, "============================");
66-
67-
// Run tests
68-
xTaskCreateStatic(TestTask, APP_NAME, 2048, NULL, 1, appStack, &appTaskStruct);
6973
qvCHIP_Printf(LOG_MODULE_ID, "Starting FreeRTOS scheduler");
7074
vTaskStartScheduler();
7175

examples/platform/qpg/app/main.cpp

Lines changed: 15 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,20 @@ constexpr int extDiscTimeoutSecs = 20;
6969
/*****************************************************************************
7070
* Application Function Definitions
7171
*****************************************************************************/
72+
CHIP_ERROR CHIP_Init(void);
7273

73-
int Application_Init(void)
74+
void Application_Init(void)
7475
{
76+
CHIP_ERROR error;
77+
78+
/* Initialize CHIP stack */
79+
error = CHIP_Init();
80+
if (error != CHIP_NO_ERROR)
81+
{
82+
ChipLogError(NotSpecified, "CHIP_Init failed");
83+
return;
84+
}
85+
7586
/* Launch application task */
7687
ChipLogProgress(NotSpecified, "============================");
7788
ChipLogProgress(NotSpecified, "Qorvo " APP_NAME " Launching");
@@ -81,10 +92,8 @@ int Application_Init(void)
8192
if (ret != CHIP_NO_ERROR)
8293
{
8394
ChipLogError(NotSpecified, "GetAppTask().Init() failed");
84-
return -1;
95+
return;
8596
}
86-
87-
return 0;
8897
}
8998

9099
CHIP_ERROR CHIP_Init(void)
@@ -172,32 +181,15 @@ CHIP_ERROR CHIP_Init(void)
172181
int main(void)
173182
{
174183
int result;
175-
CHIP_ERROR error;
176184

177185
/* Initialize Qorvo stack */
178-
result = qvCHIP_init();
179-
if (result < 0)
180-
{
181-
goto exit;
182-
}
183-
184-
/* Initialize CHIP stack */
185-
error = CHIP_Init();
186-
if (error != CHIP_NO_ERROR)
187-
{
188-
goto exit;
189-
}
190-
191-
/* Application task */
192-
result = Application_Init();
186+
result = qvCHIP_init(Application_Init);
193187
if (result < 0)
194188
{
195-
goto exit;
189+
return 0;
196190
}
197191

198192
/* Start FreeRTOS */
199193
vTaskStartScheduler();
200-
201-
exit:
202194
return 0;
203195
}

examples/platform/qpg/ota/ota.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,19 @@ OTAImageProcessorImpl gImageProcessor;
5050
* Application Function Definitions
5151
*****************************************************************************/
5252

53+
bool OtaHeaderValidationCb(qvCHIP_Ota_ImageHeader_t imageHeader)
54+
{
55+
// Check that the image matches vendor and product ID and that the version is higher than what we currently have
56+
if (imageHeader.vendorId != CHIP_DEVICE_CONFIG_DEVICE_VENDOR_ID ||
57+
imageHeader.productId != CHIP_DEVICE_CONFIG_DEVICE_PRODUCT_ID ||
58+
imageHeader.softwareVersion <= CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION)
59+
{
60+
return false;
61+
}
62+
63+
return true;
64+
}
65+
5366
void InitializeOTARequestor(void)
5467
{
5568
// Initialize and interconnect the Requestor and Image Processor objects
@@ -60,6 +73,9 @@ void InitializeOTARequestor(void)
6073
gImageProcessor.SetOTADownloader(&gDownloader);
6174
gDownloader.SetImageProcessorDelegate(&gImageProcessor);
6275
gRequestorUser.Init(&gRequestorCore, &gImageProcessor);
76+
77+
// Initialize OTA image validation callback
78+
qvCHIP_OtaSetHeaderValidationCb(OtaHeaderValidationCb);
6379
}
6480

6581
void TriggerOTAQuery(void)

src/platform/qpg/CHIPDevicePlatformConfig.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
// ========== Platform-specific Configuration Overrides =========
5050

5151
#ifndef CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE
52-
#define CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE (5 * 1024)
52+
#define CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE (6 * 1024)
5353
#endif // CHIP_DEVICE_CONFIG_CHIP_TASK_STACK_SIZE
5454

5555
#ifndef CHIP_DEVICE_CONFIG_THREAD_TASK_STACK_SIZE

src/platform/qpg/OTAImageProcessorImpl.cpp

Lines changed: 82 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,87 @@
1717
*/
1818

1919
#include <app/clusters/ota-requestor/OTADownloader.h>
20+
#include <app/clusters/ota-requestor/OTARequestorInterface.h>
2021

2122
#include "OTAImageProcessorImpl.h"
2223

2324
namespace chip {
2425

26+
bool OTAImageProcessorImpl::IsFirstImageRun()
27+
{
28+
OTARequestorInterface * requestor = chip::GetRequestorInstance();
29+
if (requestor == nullptr)
30+
{
31+
return false;
32+
}
33+
34+
return requestor->GetCurrentUpdateState() == OTARequestorInterface::OTAUpdateStateEnum::kApplying;
35+
}
36+
37+
CHIP_ERROR OTAImageProcessorImpl::ConfirmCurrentImage()
38+
{
39+
OTARequestorInterface * requestor = chip::GetRequestorInstance();
40+
if (requestor == nullptr)
41+
{
42+
return CHIP_ERROR_INTERNAL;
43+
}
44+
45+
uint32_t currentVersion;
46+
ReturnErrorOnFailure(DeviceLayer::ConfigurationMgr().GetSoftwareVersion(currentVersion));
47+
48+
if (currentVersion != requestor->GetTargetVersion())
49+
{
50+
return CHIP_ERROR_INCORRECT_STATE;
51+
}
52+
53+
return CHIP_NO_ERROR;
54+
}
55+
2556
CHIP_ERROR OTAImageProcessorImpl::PrepareDownload()
2657
{
2758

2859
// Get OTA status - under what circumstances does prepared break?
2960
// what happens if a prepare is pending and another one is invoked
30-
// Should we store the state here and wait til we receive notification
61+
// Should we store the state here and wait until we receive notification
62+
63+
mHeaderParser.Init();
3164

3265
DeviceLayer::PlatformMgr().ScheduleWork(HandlePrepareDownload, reinterpret_cast<intptr_t>(this));
3366
return CHIP_NO_ERROR;
3467
}
3568

69+
CHIP_ERROR OTAImageProcessorImpl::ProcessHeader(ByteSpan & block)
70+
{
71+
if (mHeaderParser.IsInitialized())
72+
{
73+
OTAImageHeader header;
74+
CHIP_ERROR error = mHeaderParser.AccumulateAndDecode(block, header);
75+
76+
// Needs more data to decode the header
77+
ReturnErrorCodeIf(error == CHIP_ERROR_BUFFER_TOO_SMALL, CHIP_NO_ERROR);
78+
ReturnErrorOnFailure(error);
79+
80+
mParams.totalFileBytes = header.mPayloadSize;
81+
mHeaderParser.Clear();
82+
83+
// Load qvCHIP_Ota header structure and call application callback to validate image header
84+
qvCHIP_Ota_ImageHeader_t qvCHIP_OtaImgHeader;
85+
this->mSwVer = header.mSoftwareVersion; // Store software version in imageProcessor as well
86+
qvCHIP_OtaImgHeader.vendorId = header.mVendorId;
87+
qvCHIP_OtaImgHeader.productId = header.mProductId;
88+
qvCHIP_OtaImgHeader.softwareVersion = header.mSoftwareVersion;
89+
qvCHIP_OtaImgHeader.minApplicableVersion = header.mMinApplicableVersion.ValueOr(0);
90+
qvCHIP_OtaImgHeader.maxApplicableVersion = header.mMaxApplicableVersion.ValueOr(0);
91+
92+
if (true != qvCHIP_OtaValidateImage(qvCHIP_OtaImgHeader))
93+
{
94+
return CHIP_ERROR_UNSUPPORTED_EXCHANGE_VERSION;
95+
}
96+
}
97+
98+
return CHIP_NO_ERROR;
99+
}
100+
36101
CHIP_ERROR OTAImageProcessorImpl::Finalize()
37102
{
38103
DeviceLayer::PlatformMgr().ScheduleWork(HandleFinalize, reinterpret_cast<intptr_t>(this));
@@ -57,16 +122,27 @@ CHIP_ERROR OTAImageProcessorImpl::Abort()
57122

58123
CHIP_ERROR OTAImageProcessorImpl::ProcessBlock(ByteSpan & block)
59124
{
125+
CHIP_ERROR err;
126+
60127
if ((block.data() == nullptr) || block.empty())
61128
{
62129
return CHIP_ERROR_INVALID_ARGUMENT;
63130
}
64131

132+
// Process block header info
133+
err = ProcessHeader(block);
134+
if (err != CHIP_NO_ERROR)
135+
{
136+
ChipLogError(SoftwareUpdate, "Cannot process block header: %" CHIP_ERROR_FORMAT, err.Format());
137+
return err;
138+
}
139+
65140
// Store block data for HandleProcessBlock to access
66-
CHIP_ERROR err = SetBlock(block);
141+
err = SetBlock(block);
67142
if (err != CHIP_NO_ERROR)
68143
{
69144
ChipLogError(SoftwareUpdate, "Cannot set block data: %" CHIP_ERROR_FORMAT, err.Format());
145+
return err;
70146
}
71147

72148
DeviceLayer::PlatformMgr().ScheduleWork(HandleProcessBlock, reinterpret_cast<intptr_t>(this));
@@ -109,8 +185,7 @@ void OTAImageProcessorImpl::HandleFinalize(intptr_t context)
109185

110186
ChipLogProgress(SoftwareUpdate, "Q: HandleFinalize");
111187

112-
// FIXME - Versions need to be filled in
113-
qvCHIP_OtaSetPendingImage(imageProcessor->mSwVer /*swVer*/, imageProcessor->mHwVer /*hwVer*/, qvCHIP_OtaGetAreaStartAddress(),
188+
qvCHIP_OtaSetPendingImage(imageProcessor->mSwVer /*swVer*/, CHIP_DEVICE_CONFIG_DEVICE_HARDWARE_VERSION /*hwVer*/, 0,
114189
static_cast<std::uint32_t>(imageProcessor->mParams.downloadedBytes) /*imgSz*/);
115190

116191
imageProcessor->ReleaseBlock();
@@ -149,11 +224,10 @@ void OTAImageProcessorImpl::HandleProcessBlock(intptr_t context)
149224
}
150225

151226
ChipLogProgress(SoftwareUpdate, "Q: HandleProcessBlock");
152-
// TODO: Process block header if any
153227

154-
status = qvCHIP_OtaWriteChunk(qvCHIP_OtaGetAreaStartAddress() + imageProcessor->mParams.downloadedBytes,
155-
static_cast<std::uint16_t>(imageProcessor->mBlock.size()),
156-
reinterpret_cast<std::uint8_t *>(imageProcessor->mBlock.data()));
228+
status =
229+
qvCHIP_OtaWriteChunk(imageProcessor->mParams.downloadedBytes, static_cast<std::uint16_t>(imageProcessor->mBlock.size()),
230+
reinterpret_cast<std::uint8_t *>(imageProcessor->mBlock.data()));
157231

158232
if (status != qvCHIP_OtaStatusSuccess)
159233
{

src/platform/qpg/OTAImageProcessorImpl.h

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#pragma once
2020

2121
#include <app/clusters/ota-requestor/OTADownloader.h>
22+
#include <lib/core/OTAImageHeader.h>
2223
#include <platform/CHIPDeviceLayer.h>
2324
#include <platform/OTAImageProcessor.h>
2425

@@ -29,12 +30,13 @@ class OTAImageProcessorImpl : public OTAImageProcessorInterface
2930
public:
3031
//////////// OTAImageProcessorInterface Implementation ///////////////
3132
CHIP_ERROR PrepareDownload() override;
33+
CHIP_ERROR ProcessHeader(ByteSpan & block);
3234
CHIP_ERROR Finalize() override;
3335
CHIP_ERROR Apply() override;
3436
CHIP_ERROR Abort() override;
3537
CHIP_ERROR ProcessBlock(ByteSpan & block) override;
36-
bool IsFirstImageRun() override { return false; }
37-
CHIP_ERROR ConfirmCurrentImage() override { return CHIP_NO_ERROR; }
38+
bool IsFirstImageRun() override;
39+
CHIP_ERROR ConfirmCurrentImage() override;
3840

3941
void SetOTADownloader(OTADownloader * downloader) { mDownloader = downloader; }
4042

@@ -59,7 +61,8 @@ class OTAImageProcessorImpl : public OTAImageProcessorInterface
5961
std::uint32_t mHwVer;
6062

6163
MutableByteSpan mBlock;
62-
OTADownloader * mDownloader;
64+
OTADownloader * mDownloader = nullptr;
65+
OTAImageHeaderParser mHeaderParser;
6366
};
6467

6568
} // namespace chip

third_party/qpg_sdk/qpg_executable.gni

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,11 +14,9 @@
1414

1515
import("//build_overrides/build.gni")
1616
import("//build_overrides/chip.gni")
17-
import("//build_overrides/pigweed.gni")
1817

1918
import("${build_root}/toolchain/flashable_executable.gni")
2019
import("${chip_root}/src/platform/device.gni")
21-
import("${dir_pw_build}/python_action.gni")
2220
import("qpg_sdk.gni")
2321

2422
# Run the generator script that takes a .HEX file and adds the OTA header to it.
@@ -43,7 +41,7 @@ template("gen_ota_header") {
4341
"data_deps",
4442
])
4543

46-
pw_python_action(target_name) {
44+
action(target_name) {
4745
outputs = [ ota_header_script_name ]
4846

4947
args = ota_header_options
@@ -96,10 +94,8 @@ template("qpg_executable") {
9694

9795
# If OTA requestor is enabled, generate OTA image from HEX
9896
if (chip_enable_ota_requestor) {
99-
ota_image_name = invoker.output_name + ".ota"
100-
10197
gen_ota_header("$executable_target_name.ota") {
102-
ota_header_script_name = "${root_out_dir}/${ota_image_name}"
98+
ota_header_script_name = "${root_out_dir}/${executable_target_name}.ota"
10399
out_dir = rebase_path(root_out_dir, root_build_dir)
104100
ota_header_generator = "${qpg_sdk_root}/Tools/ota/generate_ota_img.py"
105101

@@ -119,6 +115,14 @@ template("qpg_executable") {
119115
"--out_file",
120116
"${out_dir}/${invoker.output_name}.ota",
121117
]),
118+
string_join("=",
119+
[
120+
"--pem_file_path",
121+
rebase_path(qpg_sdk_root, root_build_dir) +
122+
"/Tools/ota/example_private_key.pem.example",
123+
]),
124+
"--pem_password=test1234",
125+
"--sign",
122126
]
123127
deps = [ ":$executable_target_name" ]
124128
}

third_party/qpg_sdk/qpg_sdk.gni

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ template("qpg_sdk") {
8282
"${qpg_sdk_root}/${qpg_sdk_lib_dir}/MatterQorvoGlue_${qpg_target_ic}_libbuild/libMatterQorvoGlue_${qpg_target_ic}_libbuild.a",
8383
"${qpg_sdk_root}/${qpg_sdk_lib_dir}/QorvoStack_${qpg_target_ic}/libQorvoStack_${qpg_target_ic}.a",
8484
"${qpg_sdk_root}/${qpg_sdk_lib_dir}/mbedtls_alt_${qpg_target_ic}/libmbedtls_alt_${qpg_target_ic}.a",
85-
"${qpg_sdk_root}/${qpg_sdk_lib_dir}/Bootloader_${qpg_target_ic}/libBootloader_${qpg_target_ic}.a",
85+
"${qpg_sdk_root}/${qpg_sdk_lib_dir}/Bootloader_${qpg_target_ic}_compr_secure/libBootloader_${qpg_target_ic}_compr_secure.a",
8686
]
8787
}
8888

third_party/qpg_sdk/repo

Submodule repo updated from a29b995 to fa660d1

0 commit comments

Comments
 (0)