From f70fbdb52ff067b6fd9b990dbc48d1dc16f43d2c Mon Sep 17 00:00:00 2001 From: Carol Yang Date: Mon, 4 Apr 2022 14:35:59 -0700 Subject: [PATCH] [OTA] Make OTARequestor responsible for responding to AnnounceOTAProvider command (#16952) --- .../clusters/ota-requestor/OTARequestor.cpp | 16 +++++-------- src/app/clusters/ota-requestor/OTARequestor.h | 2 +- .../ota-requestor/OTARequestorInterface.h | 7 ++++-- .../ota-requestor/ota-requestor-server.cpp | 24 +++++++++++++------ 4 files changed, 29 insertions(+), 20 deletions(-) diff --git a/src/app/clusters/ota-requestor/OTARequestor.cpp b/src/app/clusters/ota-requestor/OTARequestor.cpp index c65620f09e8d10..5a5e8bff2d75b9 100644 --- a/src/app/clusters/ota-requestor/OTARequestor.cpp +++ b/src/app/clusters/ota-requestor/OTARequestor.cpp @@ -41,6 +41,7 @@ using namespace app::Clusters::OtaSoftwareUpdateRequestor::Commands; using namespace app::Clusters::OtaSoftwareUpdateRequestor::Structs; using app::DataModel::Nullable; using bdx::TransferSession; +using Protocols::InteractionModel::Status; // Global instance of the OTARequestorInterface. OTARequestorInterface * globalOTARequestorInstance = nullptr; @@ -286,20 +287,15 @@ void OTARequestor::Reset() StoreCurrentUpdateInfo(); } -EmberAfStatus OTARequestor::HandleAnnounceOTAProvider(app::CommandHandler * commandObj, - const app::ConcreteCommandPath & commandPath, - const AnnounceOtaProvider::DecodableType & commandData) +void OTARequestor::HandleAnnounceOTAProvider(app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, + const AnnounceOtaProvider::DecodableType & commandData) { + VerifyOrReturn(commandObj != nullptr, ChipLogError(SoftwareUpdate, "Invalid commandObj, cannot handle AnnounceOTAProvider")); + auto & announcementReason = commandData.announcementReason; ChipLogProgress(SoftwareUpdate, "OTA Requestor received AnnounceOTAProvider"); - if (commandObj == nullptr || commandObj->GetExchangeContext() == nullptr) - { - ChipLogError(SoftwareUpdate, "Cannot access ExchangeContext for FabricIndex"); - return EMBER_ZCL_STATUS_FAILURE; - } - ProviderLocationType providerLocation = { .providerNodeID = commandData.providerNodeId, .endpoint = commandData.endpoint, .fabricIndex = commandObj->GetAccessingFabricIndex() }; @@ -316,7 +312,7 @@ EmberAfStatus OTARequestor::HandleAnnounceOTAProvider(app::CommandHandler * comm mOtaRequestorDriver->ProcessAnnounceOTAProviders(providerLocation, announcementReason); - return EMBER_ZCL_STATUS_SUCCESS; + commandObj->AddStatus(commandPath, Status::Success); } void OTARequestor::ConnectToProvider(OnConnectedAction onConnectedAction) diff --git a/src/app/clusters/ota-requestor/OTARequestor.h b/src/app/clusters/ota-requestor/OTARequestor.h index 5c64a18adf8a56..e8affbcd066202 100644 --- a/src/app/clusters/ota-requestor/OTARequestor.h +++ b/src/app/clusters/ota-requestor/OTARequestor.h @@ -42,7 +42,7 @@ class OTARequestor : public OTARequestorInterface, public BDXDownloader::StateDe //////////// OTARequestorInterface Implementation /////////////// void Reset(void) override; - EmberAfStatus HandleAnnounceOTAProvider( + void HandleAnnounceOTAProvider( app::CommandHandler * commandObj, const app::ConcreteCommandPath & commandPath, const app::Clusters::OtaSoftwareUpdateRequestor::Commands::AnnounceOtaProvider::DecodableType & commandData) override; diff --git a/src/app/clusters/ota-requestor/OTARequestorInterface.h b/src/app/clusters/ota-requestor/OTARequestorInterface.h index f4d593fc217ec8..d5139fb81777f0 100644 --- a/src/app/clusters/ota-requestor/OTARequestorInterface.h +++ b/src/app/clusters/ota-requestor/OTARequestorInterface.h @@ -156,8 +156,11 @@ class OTARequestorInterface // Reset any relevant states virtual void Reset(void) = 0; - // Handler for the AnnounceOTAProvider command - virtual EmberAfStatus HandleAnnounceOTAProvider( + /** + * Called to handle an AnnounceOTAProvider command and is responsible for sending the status. The caller is responsible for + * validating fields in the command. + */ + virtual void HandleAnnounceOTAProvider( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::OtaSoftwareUpdateRequestor::Commands::AnnounceOtaProvider::DecodableType & commandData) = 0; diff --git a/src/app/clusters/ota-requestor/ota-requestor-server.cpp b/src/app/clusters/ota-requestor/ota-requestor-server.cpp index a6e987cb05711c..4010598c295a85 100644 --- a/src/app/clusters/ota-requestor/ota-requestor-server.cpp +++ b/src/app/clusters/ota-requestor/ota-requestor-server.cpp @@ -21,6 +21,7 @@ */ #include +#include #include #include #include @@ -32,9 +33,12 @@ using namespace chip::app::Clusters; using namespace chip::app::Clusters::OtaSoftwareUpdateRequestor; using namespace chip::app::Clusters::OtaSoftwareUpdateRequestor::Attributes; using namespace chip::app::Clusters::OtaSoftwareUpdateRequestor::Structs; +using Protocols::InteractionModel::Status; namespace { +constexpr size_t kMaxMetadataLen = 512; // The maximum length of Metadata in any OTA Requestor command + class OtaSoftwareUpdateRequestorAttrAccess : public AttributeAccessInterface { public: @@ -258,19 +262,25 @@ bool emberAfOtaSoftwareUpdateRequestorClusterAnnounceOtaProviderCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::OtaSoftwareUpdateRequestor::Commands::AnnounceOtaProvider::DecodableType & commandData) { - EmberAfStatus status; - chip::OTARequestorInterface * requestor = chip::GetRequestorInstance(); + auto & metadataForNode = commandData.metadataForNode; - if (requestor != nullptr) + chip::OTARequestorInterface * requestor = chip::GetRequestorInstance(); + if (requestor == nullptr) { - status = requestor->HandleAnnounceOTAProvider(commandObj, commandPath, commandData); + commandObj->AddStatus(commandPath, Status::UnsupportedCommand); + return true; } - else + + if (metadataForNode.HasValue() && metadataForNode.Value().size() > kMaxMetadataLen) { - status = EMBER_ZCL_STATUS_FAILURE; + ChipLogError(Zcl, "Metadata size %u exceeds max %u", static_cast(metadataForNode.Value().size()), + static_cast(kMaxMetadataLen)); + commandObj->AddStatus(commandPath, Status::InvalidCommand); + return true; } - emberAfSendImmediateDefaultResponse(status); + requestor->HandleAnnounceOTAProvider(commandObj, commandPath, commandData); + return true; }