Skip to content

Commit

Permalink
Implement TestEventTrigger delegate for OTA query (#19716)
Browse files Browse the repository at this point in the history
* [ota] Add TestEventTriggerDelegate for OTA query

Make it possible to use TestEventTrigger command of
GeneralDiagnostics cluster to trigger OTA query on demand.

The requested trigger must be 0x0100'0000'0000'01<fi>, where
<fi> is fabric index of the OTA provider to query, or 00 if
the OTA provider is supposed to be selected automatically.

Signed-off-by: Damian Krolik <[email protected]>

* Use OTATestEventTriggerDelegate in nRF and Linux examples

Initialize OTATestEventTriggerDelegate in nRF Connect and
Linux examples. nRF Connect examples use a constant enable
key "001122(..)ff" while Linux apps allow for configuring
the key at runtime using "--enable-key" argument.

* Restyled by clang-format

* Fix build

* Address code review comments

* Restyled by gn

* Another attempt to silence GN checker

Co-authored-by: Restyled.io <[email protected]>
  • Loading branch information
2 people authored and pull[bot] committed Dec 6, 2023
1 parent 7aea1d3 commit 2245088
Show file tree
Hide file tree
Showing 18 changed files with 222 additions and 39 deletions.
11 changes: 9 additions & 2 deletions examples/all-clusters-app/nrfconnect/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <app-common/zap-generated/attribute-type.h>
#include <app-common/zap-generated/cluster-id.h>
#include <app/clusters/identify-server/identify-server.h>
#include <app/clusters/ota-requestor/OTATestEventTriggerDelegate.h>
#include <app/util/attribute-storage.h>

#include <credentials/DeviceAttestationCredsProvider.h>
Expand Down Expand Up @@ -58,6 +59,11 @@ K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), APP_EVENT_QUEUE_SIZE, alignof(Ap

namespace {

// NOTE! This key is for test/certification only and should not be available in production devices.
// Ideally, it should be a part of the factory data set.
constexpr uint8_t kTestEventTriggerEnableKey[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };

LEDWidget sStatusLED;
UnusedLedsWrapper<3> sUnusedLeds{ { DK_LED2, DK_LED3, DK_LED4 } };
k_timer sFunctionTimer;
Expand Down Expand Up @@ -182,9 +188,10 @@ CHIP_ERROR AppTask::Init()
// Initialize CHIP server
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());

static chip::CommonCaseDeviceServerInitParams initParams;
static CommonCaseDeviceServerInitParams initParams;
static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(kTestEventTriggerEnableKey) };
(void) initParams.InitializeStaticResourcesBeforeServerInit();

initParams.testEventTriggerDelegate = &testEventTriggerDelegate;
ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams));

gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage());
Expand Down
25 changes: 15 additions & 10 deletions examples/lighting-app/nrfconnect/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
#include <app-common/zap-generated/attributes/Accessors.h>
#include <app-common/zap-generated/cluster-id.h>
#include <app/clusters/identify-server/identify-server.h>
#include <app/clusters/ota-requestor/OTATestEventTriggerDelegate.h>
#include <app/server/Dnssd.h>
#include <app/server/OnboardingCodesUtil.h>
#include <app/server/Server.h>
Expand Down Expand Up @@ -57,15 +58,17 @@ using namespace ::chip::DeviceLayer;

namespace {

constexpr int kFactoryResetTriggerTimeout = 3000;
constexpr int kFactoryResetCancelWindowTimeout = 3000;
constexpr int kAppEventQueueSize = 10;
constexpr uint8_t kButtonPushEvent = 1;
constexpr uint8_t kButtonReleaseEvent = 0;
constexpr EndpointId kLightEndpointId = 1;
constexpr uint32_t kIdentifyBlinkRateMs = 500;
constexpr uint8_t kDefaultMinLevel = 0;
constexpr uint8_t kDefaultMaxLevel = 254;
constexpr int kFactoryResetTriggerTimeout = 3000;
constexpr int kFactoryResetCancelWindowTimeout = 3000;
constexpr int kAppEventQueueSize = 10;
constexpr uint8_t kButtonPushEvent = 1;
constexpr uint8_t kButtonReleaseEvent = 0;
constexpr EndpointId kLightEndpointId = 1;
constexpr uint32_t kIdentifyBlinkRateMs = 500;
constexpr uint8_t kDefaultMinLevel = 0;
constexpr uint8_t kDefaultMaxLevel = 254;
constexpr uint8_t kTestEventTriggerEnableKey[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };

K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), kAppEventQueueSize, alignof(AppEvent));
k_timer sFunctionTimer;
Expand Down Expand Up @@ -167,8 +170,10 @@ CHIP_ERROR AppTask::Init()
// Initialize CHIP server
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());

static chip::CommonCaseDeviceServerInitParams initParams;
static CommonCaseDeviceServerInitParams initParams;
static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(kTestEventTriggerEnableKey) };
(void) initParams.InitializeStaticResourcesBeforeServerInit();
initParams.testEventTriggerDelegate = &testEventTriggerDelegate;
ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams));

gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage());
Expand Down
2 changes: 1 addition & 1 deletion examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -516,7 +516,7 @@ void AppTask::OTAHandler(AppEvent * aEvent)
#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR
void AppTask::StartOTAQuery(intptr_t arg)
{
static_cast<DefaultOTARequestor *>(GetRequestorInstance())->TriggerImmediateQuery();
GetRequestorInstance()->TriggerImmediateQuery();
}

void AppTask::PostOTAResume()
Expand Down
12 changes: 10 additions & 2 deletions examples/lock-app/nrfconnect/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include <app-common/zap-generated/attributes/Accessors.h>
#include <app-common/zap-generated/cluster-id.h>
#include <app/clusters/door-lock-server/door-lock-server.h>
#include <app/clusters/ota-requestor/OTATestEventTriggerDelegate.h>
#include <app/server/OnboardingCodesUtil.h>
#include <app/server/Server.h>
#include <credentials/DeviceAttestationCredsProvider.h>
Expand Down Expand Up @@ -60,6 +61,11 @@ using namespace ::chip::DeviceLayer;
namespace {
constexpr EndpointId kLockEndpointId = 1;

// NOTE! This key is for test/certification only and should not be available in production devices.
// Ideally, it should be a part of the factory data set.
constexpr uint8_t kTestEventTriggerEnableKey[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };

LOG_MODULE_DECLARE(app, CONFIG_MATTER_LOG_LEVEL);
K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), APP_EVENT_QUEUE_SIZE, alignof(AppEvent));
k_timer sFunctionTimer;
Expand Down Expand Up @@ -151,9 +157,11 @@ CHIP_ERROR AppTask::Init()

// Initialize CHIP server
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
static chip::CommonCaseDeviceServerInitParams initParams;
(void) initParams.InitializeStaticResourcesBeforeServerInit();

static CommonCaseDeviceServerInitParams initParams;
static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(kTestEventTriggerEnableKey) };
(void) initParams.InitializeStaticResourcesBeforeServerInit();
initParams.testEventTriggerDelegate = &testEventTriggerDelegate;
ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams));

gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage());
Expand Down
3 changes: 1 addition & 2 deletions examples/ota-requestor-app/p6/src/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -441,8 +441,7 @@ void OnTriggerUpdateTimerHandler(Layer * systemLayer, void * appState)
{
P6_LOG("Triggering immediate OTA update query");

DefaultOTARequestor * req = static_cast<DefaultOTARequestor *>(GetRequestorInstance());
req->TriggerImmediateQuery();
GetRequestorInstance()->TriggerImmediateQuery();
}

void AppTask::InitOTARequestor()
Expand Down
10 changes: 10 additions & 0 deletions examples/platform/linux/AppMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@
#include "TraceHandlers.h"
#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED

#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR
#include <app/clusters/ota-requestor/OTATestEventTriggerDelegate.h>
#endif

#include <signal.h>

#include "AppMain.h"
Expand Down Expand Up @@ -305,6 +309,12 @@ void ChipLinuxAppMainLoop()
initParams.operationalKeystore = &LinuxDeviceOptions::GetInstance().mCSRResponseOptions.badCsrOperationalKeyStoreForTest;
}

#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR
static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(
LinuxDeviceOptions::GetInstance().testEventTriggerEnableKey) };
initParams.testEventTriggerDelegate = &testEventTriggerDelegate;
#endif

// Init ZCL Data Model and CHIP App Server
Server::GetInstance().Init(initParams);

Expand Down
7 changes: 7 additions & 0 deletions examples/platform/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ config("app-main-config") {
include_dirs = [ "." ]
}

source_set("ota-test-event-trigger") {
sources = [
"${chip_root}/src/app/clusters/ota-requestor/OTATestEventTriggerDelegate.h",
]
}

source_set("app-main") {
defines = []
sources = [
Expand Down Expand Up @@ -55,6 +61,7 @@ source_set("app-main") {
}

public_deps = [
":ota-test-event-trigger",
"${chip_root}/examples/providers:device_info_provider",
"${chip_root}/src/app/server",
"${chip_root}/src/credentials:default_attestation_verifier",
Expand Down
18 changes: 18 additions & 0 deletions examples/platform/linux/Options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <crypto/CHIPCryptoPAL.h>
#include <lib/core/CHIPError.h>
#include <lib/support/Base64.h>
#include <lib/support/BytesToHex.h>

#include <credentials/examples/DeviceAttestationCredsExample.h>

Expand Down Expand Up @@ -70,6 +71,7 @@ enum
kOptionCSRResponseAttestationSignatureIncorrectType = 0x101c,
kOptionCSRResponseAttestationSignatureInvalid = 0x101d,
kOptionCSRResponseCSRExistingKeyPair = 0x101e,
kDeviceOption_TestEventTriggerEnableKey = 0x101f,
};

constexpr unsigned kAppUsageLength = 64;
Expand Down Expand Up @@ -114,6 +116,7 @@ OptionDef sDeviceOptionDefs[] = {
{ "cert_error_nocsrelements_too_long", kNoArgument, kOptionCSRResponseNOCSRElementsTooLong },
{ "cert_error_attestation_signature_incorrect_type", kNoArgument, kOptionCSRResponseAttestationSignatureIncorrectType },
{ "cert_error_attestation_signature_invalid", kNoArgument, kOptionCSRResponseAttestationSignatureInvalid },
{ "enable-key", kArgumentRequired, kDeviceOption_TestEventTriggerEnableKey },
{}
};

Expand Down Expand Up @@ -215,6 +218,8 @@ const char * sDeviceOptionHelp =
" Configure the CSRResponse to be build with an invalid AttestationSignature type.\n"
" --cert_error_attestation_signature_invalid\n"
" Configure the CSRResponse to be build with an AttestationSignature that does not match what is expected.\n"
" --enable-key <key>\n"
" A 16-byte, hex-encoded key, used to validate TestEventTrigger command of Generial Diagnostics cluster\n"
"\n";

bool Base64ArgToVector(const char * arg, size_t maxSize, std::vector<uint8_t> & outVector)
Expand Down Expand Up @@ -442,6 +447,19 @@ bool HandleOption(const char * aProgram, OptionSet * aOptions, int aIdentifier,
case kOptionCSRResponseAttestationSignatureInvalid:
LinuxDeviceOptions::GetInstance().mCSRResponseOptions.attestationSignatureInvalid = true;
break;
case kDeviceOption_TestEventTriggerEnableKey: {
constexpr size_t kEnableKeyLength = sizeof(LinuxDeviceOptions::GetInstance().testEventTriggerEnableKey);

if (Encoding::HexToBytes(aValue, strlen(aValue), LinuxDeviceOptions::GetInstance().testEventTriggerEnableKey,
kEnableKeyLength) != kEnableKeyLength)
{

PrintArgError("%s: ERROR: invalid value specified for %s\n", aProgram, aName);
retval = false;
}

break;
}

default:
PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", aProgram, aName);
Expand Down
1 change: 1 addition & 0 deletions examples/platform/linux/Options.h
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ struct LinuxDeviceOptions
chip::Optional<std::string> traceStreamFilename;
chip::Credentials::DeviceAttestationCredentialsProvider * dacProvider = nullptr;
chip::CSRResponseOptions mCSRResponseOptions;
uint8_t testEventTriggerEnableKey[16] = { 0 };

static LinuxDeviceOptions & GetInstance();
};
Expand Down
12 changes: 10 additions & 2 deletions examples/pump-app/nrfconnect/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <app-common/zap-generated/attribute-type.h>
#include <app-common/zap-generated/attributes/Accessors.h>
#include <app-common/zap-generated/cluster-id.h>
#include <app/clusters/ota-requestor/OTATestEventTriggerDelegate.h>
#include <app/server/OnboardingCodesUtil.h>
#include <app/server/Server.h>
#include <app/util/attribute-storage.h>
Expand Down Expand Up @@ -61,6 +62,11 @@ using namespace ::chip::DeviceLayer;

namespace {

// NOTE! This key is for test/certification only and should not be available in production devices.
// Ideally, it should be a part of the factory data set.
constexpr uint8_t kTestEventTriggerEnableKey[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };

LOG_MODULE_DECLARE(app, CONFIG_MATTER_LOG_LEVEL);
K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), APP_EVENT_QUEUE_SIZE, alignof(AppEvent));
k_timer sFunctionTimer;
Expand Down Expand Up @@ -149,9 +155,11 @@ CHIP_ERROR AppTask::Init()

// Initialize CHIP server
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
static chip::CommonCaseDeviceServerInitParams initParams;
(void) initParams.InitializeStaticResourcesBeforeServerInit();

static CommonCaseDeviceServerInitParams initParams;
static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(kTestEventTriggerEnableKey) };
(void) initParams.InitializeStaticResourcesBeforeServerInit();
initParams.testEventTriggerDelegate = &testEventTriggerDelegate;
ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams));

gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage());
Expand Down
12 changes: 10 additions & 2 deletions examples/pump-controller-app/nrfconnect/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#include <app-common/zap-generated/attribute-type.h>
#include <app-common/zap-generated/attributes/Accessors.h>
#include <app-common/zap-generated/cluster-id.h>
#include <app/clusters/ota-requestor/OTATestEventTriggerDelegate.h>
#include <app/server/OnboardingCodesUtil.h>
#include <app/server/Server.h>
#include <app/util/attribute-storage.h>
Expand Down Expand Up @@ -58,6 +59,11 @@ using namespace ::chip::DeviceLayer;

namespace {

// NOTE! This key is for test/certification only and should not be available in production devices.
// Ideally, it should be a part of the factory data set.
constexpr uint8_t kTestEventTriggerEnableKey[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };

LOG_MODULE_DECLARE(app, CONFIG_MATTER_LOG_LEVEL);
K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), APP_EVENT_QUEUE_SIZE, alignof(AppEvent));
k_timer sFunctionTimer;
Expand Down Expand Up @@ -146,9 +152,11 @@ CHIP_ERROR AppTask::Init()

// Initialize CHIP server
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());
static chip::CommonCaseDeviceServerInitParams initParams;
(void) initParams.InitializeStaticResourcesBeforeServerInit();

static CommonCaseDeviceServerInitParams initParams;
static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(kTestEventTriggerEnableKey) };
(void) initParams.InitializeStaticResourcesBeforeServerInit();
initParams.testEventTriggerDelegate = &testEventTriggerDelegate;
ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams));

gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage());
Expand Down
10 changes: 9 additions & 1 deletion examples/window-app/nrfconnect/main/AppTask.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include <app-common/zap-generated/attribute-id.h>
#include <app-common/zap-generated/attribute-type.h>
#include <app-common/zap-generated/cluster-id.h>
#include <app/clusters/ota-requestor/OTATestEventTriggerDelegate.h>
#include <app/util/attribute-storage.h>

#include <credentials/DeviceAttestationCredsProvider.h>
Expand All @@ -54,6 +55,11 @@ K_MSGQ_DEFINE(sAppEventQueue, sizeof(AppEvent), APP_EVENT_QUEUE_SIZE, alignof(Ap

namespace {

// NOTE! This key is for test/certification only and should not be available in production devices.
// Ideally, it should be a part of the factory data set.
constexpr uint8_t kTestEventTriggerEnableKey[16] = { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff };

LEDWidget sStatusLED;
UnusedLedsWrapper<1> sUnusedLeds{ { DK_LED4 } };
k_timer sFunctionTimer;
Expand Down Expand Up @@ -150,8 +156,10 @@ CHIP_ERROR AppTask::Init()
// Initialize CHIP server
SetDeviceAttestationCredentialsProvider(Examples::GetExampleDACProvider());

static chip::CommonCaseDeviceServerInitParams initParams;
static CommonCaseDeviceServerInitParams initParams;
static OTATestEventTriggerDelegate testEventTriggerDelegate{ ByteSpan(kTestEventTriggerEnableKey) };
(void) initParams.InitializeStaticResourcesBeforeServerInit();
initParams.testEventTriggerDelegate = &testEventTriggerDelegate;
ReturnErrorOnFailure(chip::Server::GetInstance().Init(initParams));

gExampleDeviceInfoProvider.SetStorageDelegate(&Server::GetInstance().GetPersistentStorage());
Expand Down
2 changes: 2 additions & 0 deletions src/app/chip_data_model.gni
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ template("chip_data_model") {
"${_app_root}/clusters/${cluster}/DefaultOTARequestorUserConsent.h",
"${_app_root}/clusters/${cluster}/ExtendedOTARequestorDriver.cpp",
"${_app_root}/clusters/${cluster}/OTARequestorStorage.h",
"${_app_root}/clusters/${cluster}/OTATestEventTriggerDelegate.cpp",
"${_app_root}/clusters/${cluster}/OTATestEventTriggerDelegate.h",
]
} else if (cluster == "bindings") {
sources += [
Expand Down
35 changes: 29 additions & 6 deletions src/app/clusters/ota-requestor/DefaultOTARequestor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -522,22 +522,45 @@ void DefaultOTARequestor::TriggerImmediateQueryInternal()
ConnectToProvider(kQueryImage);
}

OTARequestorInterface::OTATriggerResult DefaultOTARequestor::TriggerImmediateQuery()
CHIP_ERROR DefaultOTARequestor::TriggerImmediateQuery(FabricIndex fabricIndex)
{
ProviderLocationType providerLocation;
bool listExhausted = false;
if (mOtaRequestorDriver->GetNextProviderLocation(providerLocation, listExhausted) != true)
bool providerFound = false;

if (fabricIndex == kUndefinedFabricIndex)
{
bool listExhausted = false;
providerFound = mOtaRequestorDriver->GetNextProviderLocation(providerLocation, listExhausted);
}
else
{
for (auto providerIter = mDefaultOtaProviderList.Begin(); providerIter.Next();)
{
providerLocation = providerIter.GetValue();

if (providerLocation.GetFabricIndex() == fabricIndex)
{
providerFound = true;
break;
}
}
}

if (!providerFound)
{
ChipLogError(SoftwareUpdate, "No OTA Providers available");
return kNoProviderKnown;
ChipLogError(SoftwareUpdate, "No OTA Providers available for immediate query");
return CHIP_ERROR_NOT_FOUND;
}

SetCurrentProviderLocation(providerLocation);

// Go through the driver as it has additional logic to execute
mOtaRequestorDriver->SendQueryImage();

return kTriggerSuccessful;
ChipLogProgress(SoftwareUpdate, "Triggered immediate OTA query for fabric: 0x%x",
static_cast<unsigned>(providerLocation.GetFabricIndex()));

return CHIP_NO_ERROR;
}

void DefaultOTARequestor::DownloadUpdate()
Expand Down
Loading

0 comments on commit 2245088

Please sign in to comment.