diff --git a/examples/common/pigweed/protos/device_service.options b/examples/common/pigweed/protos/device_service.options index b5f9da673ff778..a0798688c38a84 100644 --- a/examples/common/pigweed/protos/device_service.options +++ b/examples/common/pigweed/protos/device_service.options @@ -5,3 +5,4 @@ chip.rpc.PairingInfo.qr_code max_size:256 chip.rpc.PairingInfo.qr_code_url max_size:256 chip.rpc.SpakeInfo.verifier max_size:97 // kSpake2p_VerifierSerialized_Length chip.rpc.SpakeInfo.salt max_size:32 // kSpake2p_Max_PBKDF_Salt_Length +chip.rpc.MetadataForProvider.tlv max_size:512 // length defined in chip spec 11.20.6.7 diff --git a/examples/common/pigweed/protos/device_service.proto b/examples/common/pigweed/protos/device_service.proto index 1c13d7d7281f14..6903e4a9055414 100644 --- a/examples/common/pigweed/protos/device_service.proto +++ b/examples/common/pigweed/protos/device_service.proto @@ -41,10 +41,15 @@ message PairingState { bool pairing_enabled = 1; } +message MetadataForProvider { + bytes tlv = 1; +} + service Device { rpc FactoryReset(pw.protobuf.Empty) returns (pw.protobuf.Empty){} rpc Reboot(pw.protobuf.Empty) returns (pw.protobuf.Empty){} rpc TriggerOta(pw.protobuf.Empty) returns (pw.protobuf.Empty){} + rpc SetOtaMetadataForProvider(MetadataForProvider) returns (pw.protobuf.Empty){} rpc GetDeviceInfo(pw.protobuf.Empty) returns (DeviceInfo){} rpc GetDeviceState(pw.protobuf.Empty) returns (DeviceState){} rpc SetPairingState(PairingState) returns (pw.protobuf.Empty){} diff --git a/examples/common/pigweed/rpc_services/Device.h b/examples/common/pigweed/rpc_services/Device.h index d3d5afd165810d..4a80cb44516236 100644 --- a/examples/common/pigweed/rpc_services/Device.h +++ b/examples/common/pigweed/rpc_services/Device.h @@ -223,7 +223,7 @@ class Device : public pw_rpc::nanopb::Device::Service virtual pw::Status TriggerOta(const pw_protobuf_Empty & request, pw_protobuf_Empty & response) { -#if CONFIG_CHIP_OTA_REQUESTOR +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR chip::DeviceLayer::PlatformMgr().ScheduleWork( [](intptr_t) { chip::OTARequestorInterface * requestor = chip::GetRequestorInstance(); @@ -238,10 +238,33 @@ class Device : public pw_rpc::nanopb::Device::Service }, reinterpret_cast(nullptr)); return pw::OkStatus(); -#else +#else // CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR ChipLogError(AppServer, "Trigger OTA requested, but OTA requestor not compiled in."); return pw::Status::Unimplemented(); -#endif +#endif // CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + } + + virtual pw::Status SetOtaMetadataForProvider(const chip_rpc_MetadataForProvider & request, pw_protobuf_Empty & response) + { +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + chip::OTARequestorInterface * requestor = chip::GetRequestorInstance(); + if (requestor == nullptr) + { + ChipLogError(SoftwareUpdate, "Can't get the CASESessionManager"); + return pw::Status::Unavailable(); + } + else if (sizeof(metadataForProviderBuffer) < request.tlv.size) + { + return pw::Status::ResourceExhausted(); + } + memcpy(metadataForProviderBuffer, request.tlv.bytes, request.tlv.size); + DeviceLayer::StackLock lock; + requestor->SetMetadataForProvider(chip::ByteSpan(metadataForProviderBuffer, request.tlv.size)); + return pw::OkStatus(); +#else // CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + ChipLogError(AppServer, "OTA set metadata for provider requested, but OTA requestor not compiled in."); + return pw::Status::Unimplemented(); +#endif // CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR } virtual pw::Status SetPairingState(const chip_rpc_PairingState & request, pw_protobuf_Empty & response) @@ -415,6 +438,10 @@ class Device : public pw_rpc::nanopb::Device::Service } private: +#if CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR + static constexpr size_t kMaxMetadataForProviderLength = 512; // length defined in chip spec 11.20.6.7 + uint8_t metadataForProviderBuffer[kMaxMetadataForProviderLength]; +#endif // CHIP_DEVICE_CONFIG_ENABLE_OTA_REQUESTOR Internal::CommissionableDataProviderRpcWrapper mCommissionableDataProvider; }; diff --git a/src/app/clusters/ota-requestor/DefaultOTARequestor.cpp b/src/app/clusters/ota-requestor/DefaultOTARequestor.cpp index f31bb2e0c5408a..f96b85ed9b4963 100644 --- a/src/app/clusters/ota-requestor/DefaultOTARequestor.cpp +++ b/src/app/clusters/ota-requestor/DefaultOTARequestor.cpp @@ -767,6 +767,7 @@ CHIP_ERROR DefaultOTARequestor::SendQueryImageRequest(Messaging::ExchangeManager args.location.SetValue(CharSpan("XX", strlen("XX"))); } + args.metadataForProvider = mMetadataForProvider; Controller::OtaSoftwareUpdateProviderCluster cluster(exchangeMgr, sessionHandle, mProviderLocation.Value().endpoint); return cluster.InvokeCommand(args, this, OnQueryImageResponse, OnQueryImageFailure); diff --git a/src/app/clusters/ota-requestor/DefaultOTARequestor.h b/src/app/clusters/ota-requestor/DefaultOTARequestor.h index 9f9902858c3141..938f2be59f671a 100644 --- a/src/app/clusters/ota-requestor/DefaultOTARequestor.h +++ b/src/app/clusters/ota-requestor/DefaultOTARequestor.h @@ -92,6 +92,10 @@ class DefaultOTARequestor : public OTARequestorInterface, public BDXDownloader:: void GetProviderLocation(Optional & providerLocation) override { providerLocation = mProviderLocation; } + // Set the metadata value for the provider to be used in the next query and OTA update process + // NOTE: Does not persist across reboot. + void SetMetadataForProvider(ByteSpan metadataForProvider) override { mMetadataForProvider.SetValue(metadataForProvider); } + // Add a default OTA provider to the cached list CHIP_ERROR AddDefaultOtaProvider(const ProviderLocationType & providerLocation) override; @@ -319,6 +323,7 @@ class DefaultOTARequestor : public OTARequestorInterface, public BDXDownloader:: BDXDownloader * mBdxDownloader = nullptr; // TODO: this should be OTADownloader BDXMessenger mBdxMessenger; // TODO: ideally this is held by the application uint8_t mUpdateTokenBuffer[kMaxUpdateTokenLen]; + Optional mMetadataForProvider; ByteSpan mUpdateToken; uint32_t mCurrentVersion = 0; uint32_t mTargetVersion = 0; diff --git a/src/app/clusters/ota-requestor/OTARequestorInterface.h b/src/app/clusters/ota-requestor/OTARequestorInterface.h index f24563d36c3c79..bd09f833971cc0 100644 --- a/src/app/clusters/ota-requestor/OTARequestorInterface.h +++ b/src/app/clusters/ota-requestor/OTARequestorInterface.h @@ -203,6 +203,9 @@ class OTARequestorInterface // Set the provider location to be used in the next query and OTA update process virtual void SetCurrentProviderLocation(ProviderLocationType providerLocation) = 0; + // Set the metadata value for the provider to be used in the next query and OTA update process + virtual void SetMetadataForProvider(chip::ByteSpan metadataForProvider) = 0; + // If there is an OTA update in progress, returns the provider location for the current OTA update, otherwise, returns the // provider location that was last used virtual void GetProviderLocation(Optional & providerLocation) = 0;