From 3867391e279b3f5e26a4dde01f8e8a8dd50da028 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Damian=20Kr=C3=B3lik?= <66667989+Damian-Nordic@users.noreply.github.com> Date: Wed, 22 Jun 2022 04:49:37 +0200 Subject: [PATCH] Implement TestEventTrigger delegate for OTA query (#19716) * [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, where 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 * 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 --- .../nrfconnect/main/AppTask.cpp | 11 ++++- .../lighting-app/nrfconnect/main/AppTask.cpp | 25 ++++++---- .../nxp/k32w/k32w0/main/AppTask.cpp | 2 +- examples/lock-app/nrfconnect/main/AppTask.cpp | 12 ++++- examples/ota-requestor-app/p6/src/AppTask.cpp | 3 +- examples/platform/linux/AppMain.cpp | 10 ++++ examples/platform/linux/BUILD.gn | 7 +++ examples/platform/linux/Options.cpp | 18 ++++++++ examples/platform/linux/Options.h | 1 + examples/pump-app/nrfconnect/main/AppTask.cpp | 12 ++++- .../nrfconnect/main/AppTask.cpp | 12 ++++- .../window-app/nrfconnect/main/AppTask.cpp | 10 +++- src/app/chip_data_model.gni | 2 + .../ota-requestor/DefaultOTARequestor.cpp | 35 +++++++++++--- .../ota-requestor/DefaultOTARequestor.h | 2 +- .../ota-requestor/OTARequestorInterface.h | 13 ++---- .../OTATestEventTriggerDelegate.cpp | 46 +++++++++++++++++++ .../OTATestEventTriggerDelegate.h | 40 ++++++++++++++++ 18 files changed, 222 insertions(+), 39 deletions(-) create mode 100644 src/app/clusters/ota-requestor/OTATestEventTriggerDelegate.cpp create mode 100644 src/app/clusters/ota-requestor/OTATestEventTriggerDelegate.h diff --git a/examples/all-clusters-app/nrfconnect/main/AppTask.cpp b/examples/all-clusters-app/nrfconnect/main/AppTask.cpp index 106c3957f4c5af..0dfbac06c45396 100644 --- a/examples/all-clusters-app/nrfconnect/main/AppTask.cpp +++ b/examples/all-clusters-app/nrfconnect/main/AppTask.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -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; @@ -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()); diff --git a/examples/lighting-app/nrfconnect/main/AppTask.cpp b/examples/lighting-app/nrfconnect/main/AppTask.cpp index 46ea48cf6b1a19..d01a327d62275e 100644 --- a/examples/lighting-app/nrfconnect/main/AppTask.cpp +++ b/examples/lighting-app/nrfconnect/main/AppTask.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -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; @@ -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()); diff --git a/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp b/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp index 8d120eb6c5abaa..d5f30e05b79224 100644 --- a/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp +++ b/examples/lighting-app/nxp/k32w/k32w0/main/AppTask.cpp @@ -516,7 +516,7 @@ void AppTask::OTAHandler(AppEvent * aEvent) #if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR void AppTask::StartOTAQuery(intptr_t arg) { - static_cast(GetRequestorInstance())->TriggerImmediateQuery(); + GetRequestorInstance()->TriggerImmediateQuery(); } void AppTask::PostOTAResume() diff --git a/examples/lock-app/nrfconnect/main/AppTask.cpp b/examples/lock-app/nrfconnect/main/AppTask.cpp index d1b1e2266810a6..8cd120d40a283e 100644 --- a/examples/lock-app/nrfconnect/main/AppTask.cpp +++ b/examples/lock-app/nrfconnect/main/AppTask.cpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -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; @@ -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()); diff --git a/examples/ota-requestor-app/p6/src/AppTask.cpp b/examples/ota-requestor-app/p6/src/AppTask.cpp index a0507142cf0af4..0fb347d11f30d1 100644 --- a/examples/ota-requestor-app/p6/src/AppTask.cpp +++ b/examples/ota-requestor-app/p6/src/AppTask.cpp @@ -441,8 +441,7 @@ void OnTriggerUpdateTimerHandler(Layer * systemLayer, void * appState) { P6_LOG("Triggering immediate OTA update query"); - DefaultOTARequestor * req = static_cast(GetRequestorInstance()); - req->TriggerImmediateQuery(); + GetRequestorInstance()->TriggerImmediateQuery(); } void AppTask::InitOTARequestor() diff --git a/examples/platform/linux/AppMain.cpp b/examples/platform/linux/AppMain.cpp index 15acc38f3a5c0e..052000f033c1b4 100644 --- a/examples/platform/linux/AppMain.cpp +++ b/examples/platform/linux/AppMain.cpp @@ -67,6 +67,10 @@ #include "TraceHandlers.h" #endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR +#include +#endif + #include #include "AppMain.h" @@ -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); diff --git a/examples/platform/linux/BUILD.gn b/examples/platform/linux/BUILD.gn index d806ca2c6587aa..1a2f35921095a0 100644 --- a/examples/platform/linux/BUILD.gn +++ b/examples/platform/linux/BUILD.gn @@ -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 = [ @@ -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", diff --git a/examples/platform/linux/Options.cpp b/examples/platform/linux/Options.cpp index 6d74aa1dcc0451..4074c155889d48 100644 --- a/examples/platform/linux/Options.cpp +++ b/examples/platform/linux/Options.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include @@ -70,6 +71,7 @@ enum kOptionCSRResponseAttestationSignatureIncorrectType = 0x101c, kOptionCSRResponseAttestationSignatureInvalid = 0x101d, kOptionCSRResponseCSRExistingKeyPair = 0x101e, + kDeviceOption_TestEventTriggerEnableKey = 0x101f, }; constexpr unsigned kAppUsageLength = 64; @@ -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 }, {} }; @@ -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 \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 & outVector) @@ -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); diff --git a/examples/platform/linux/Options.h b/examples/platform/linux/Options.h index 56a95b772cafd8..00817f95a16378 100644 --- a/examples/platform/linux/Options.h +++ b/examples/platform/linux/Options.h @@ -59,6 +59,7 @@ struct LinuxDeviceOptions chip::Optional traceStreamFilename; chip::Credentials::DeviceAttestationCredentialsProvider * dacProvider = nullptr; chip::CSRResponseOptions mCSRResponseOptions; + uint8_t testEventTriggerEnableKey[16] = { 0 }; static LinuxDeviceOptions & GetInstance(); }; diff --git a/examples/pump-app/nrfconnect/main/AppTask.cpp b/examples/pump-app/nrfconnect/main/AppTask.cpp index b101418cad4ebf..45ca1d5a06599c 100644 --- a/examples/pump-app/nrfconnect/main/AppTask.cpp +++ b/examples/pump-app/nrfconnect/main/AppTask.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -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; @@ -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()); diff --git a/examples/pump-controller-app/nrfconnect/main/AppTask.cpp b/examples/pump-controller-app/nrfconnect/main/AppTask.cpp index 1a0aa8202bbdfd..621d4f97af16e9 100644 --- a/examples/pump-controller-app/nrfconnect/main/AppTask.cpp +++ b/examples/pump-controller-app/nrfconnect/main/AppTask.cpp @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -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; @@ -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()); diff --git a/examples/window-app/nrfconnect/main/AppTask.cpp b/examples/window-app/nrfconnect/main/AppTask.cpp index f62b096c61d878..44c42effffef50 100644 --- a/examples/window-app/nrfconnect/main/AppTask.cpp +++ b/examples/window-app/nrfconnect/main/AppTask.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #include #include @@ -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; @@ -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()); diff --git a/src/app/chip_data_model.gni b/src/app/chip_data_model.gni index 1c08a5e433e4f1..8c721b2ecefca0 100644 --- a/src/app/chip_data_model.gni +++ b/src/app/chip_data_model.gni @@ -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 += [ diff --git a/src/app/clusters/ota-requestor/DefaultOTARequestor.cpp b/src/app/clusters/ota-requestor/DefaultOTARequestor.cpp index 6cdd65f91a1a07..b34d08c646e05f 100644 --- a/src/app/clusters/ota-requestor/DefaultOTARequestor.cpp +++ b/src/app/clusters/ota-requestor/DefaultOTARequestor.cpp @@ -522,14 +522,34 @@ 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); @@ -537,7 +557,10 @@ OTARequestorInterface::OTATriggerResult DefaultOTARequestor::TriggerImmediateQue // 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(providerLocation.GetFabricIndex())); + + return CHIP_NO_ERROR; } void DefaultOTARequestor::DownloadUpdate() diff --git a/src/app/clusters/ota-requestor/DefaultOTARequestor.h b/src/app/clusters/ota-requestor/DefaultOTARequestor.h index 5d5000f22a1e91..13c2f1bea9a504 100644 --- a/src/app/clusters/ota-requestor/DefaultOTARequestor.h +++ b/src/app/clusters/ota-requestor/DefaultOTARequestor.h @@ -47,7 +47,7 @@ class DefaultOTARequestor : public OTARequestorInterface, public BDXDownloader:: const app::Clusters::OtaSoftwareUpdateRequestor::Commands::AnnounceOtaProvider::DecodableType & commandData) override; // Application API to send the QueryImage command and start the image update process with the next available Provider - OTATriggerResult TriggerImmediateQuery() override; + CHIP_ERROR TriggerImmediateQuery(FabricIndex fabricIndex) override; // Internal API meant for use by OTARequestorDriver to send the QueryImage command and start the image update process // with the Provider currently set diff --git a/src/app/clusters/ota-requestor/OTARequestorInterface.h b/src/app/clusters/ota-requestor/OTARequestorInterface.h index cb5ac8c977a6dc..f24563d36c3c79 100644 --- a/src/app/clusters/ota-requestor/OTARequestorInterface.h +++ b/src/app/clusters/ota-requestor/OTARequestorInterface.h @@ -145,14 +145,6 @@ class OTARequestorInterface using OTAUpdateStateEnum = chip::app::Clusters::OtaSoftwareUpdateRequestor::OTAUpdateStateEnum; using ProviderLocationType = app::Clusters::OtaSoftwareUpdateRequestor::Structs::ProviderLocation::Type; - // Return value for various trigger-type APIs - enum OTATriggerResult - { - kTriggerSuccessful = 0, - kNoProviderKnown = 1, - kWrongState = 2 - }; - // Reset any relevant states virtual void Reset(void) = 0; @@ -167,8 +159,9 @@ class OTARequestorInterface // Destructor virtual ~OTARequestorInterface() = default; - // Application API to send the QueryImage command and start the image update process with the next available Provider - virtual OTATriggerResult TriggerImmediateQuery() = 0; + // Application API to send the QueryImage command and start the image update process. + // The `fabricIndex` optional argument can be used to explicitly select the OTA provider. + virtual CHIP_ERROR TriggerImmediateQuery(FabricIndex fabricIndex = kUndefinedFabricIndex) = 0; // Internal API meant for use by OTARequestorDriver to send the QueryImage command and start the image update process // with the preset provider diff --git a/src/app/clusters/ota-requestor/OTATestEventTriggerDelegate.cpp b/src/app/clusters/ota-requestor/OTATestEventTriggerDelegate.cpp new file mode 100644 index 00000000000000..a879f817ed9b86 --- /dev/null +++ b/src/app/clusters/ota-requestor/OTATestEventTriggerDelegate.cpp @@ -0,0 +1,46 @@ +/* + * + * Copyright (c) 2022 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 "OTATestEventTriggerDelegate.h" + +#include "OTARequestorInterface.h" + +#include + +namespace chip { + +bool OTATestEventTriggerDelegate::DoesEnableKeyMatch(const ByteSpan & enableKey) const +{ + return !mEnableKey.empty() && mEnableKey.data_equal(enableKey); +} + +CHIP_ERROR OTATestEventTriggerDelegate::HandleEventTrigger(uint64_t eventTrigger) +{ + if ((eventTrigger & ~kOtaQueryFabricIndexMask) == kOtaQueryTrigger) + { + OTARequestorInterface * requestor = GetRequestorInstance(); + const FabricIndex fabricIndex = eventTrigger & kOtaQueryFabricIndexMask; + + VerifyOrReturnError(requestor != nullptr, CHIP_ERROR_INCORRECT_STATE); + return requestor->TriggerImmediateQuery(fabricIndex); + } + + return CHIP_ERROR_INVALID_ARGUMENT; +} + +} // namespace chip diff --git a/src/app/clusters/ota-requestor/OTATestEventTriggerDelegate.h b/src/app/clusters/ota-requestor/OTATestEventTriggerDelegate.h new file mode 100644 index 00000000000000..6c78a16a7665ff --- /dev/null +++ b/src/app/clusters/ota-requestor/OTATestEventTriggerDelegate.h @@ -0,0 +1,40 @@ +/* + * + * Copyright (c) 2022 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 + +namespace chip { + +class OTATestEventTriggerDelegate : public TestEventTriggerDelegate +{ +public: + static constexpr uint64_t kOtaQueryTrigger = 0x0100'0000'0000'0100; + static constexpr uint64_t kOtaQueryFabricIndexMask = 0xff; + + explicit OTATestEventTriggerDelegate(const ByteSpan & enableKey) : mEnableKey(enableKey) {} + + bool DoesEnableKeyMatch(const ByteSpan & enableKey) const override; + CHIP_ERROR HandleEventTrigger(uint64_t eventTrigger) override; + +private: + ByteSpan mEnableKey; +}; + +} // namespace chip