From a1bafe1e77b775a38023d57a744166553c41ac38 Mon Sep 17 00:00:00 2001 From: Martin Girardot <165289184+Martin-NXP@users.noreply.github.com> Date: Thu, 3 Oct 2024 17:16:37 +0200 Subject: [PATCH 01/22] [NXP] fix on network build issue, add wifi diagnostics status code (#35888) * [NXP][platform][common] Fix wifi onnetwork build issue Signed-off-by: Martin Girardot * [NXP][platform][common] Add wlan status code Signed-off-by: Martin Girardot * Restyled by whitespace * Restyled by clang-format --------- Signed-off-by: Martin Girardot Co-authored-by: Restyled.io --- .../nxp/common/ConnectivityManagerImpl.cpp | 18 +++++++++++++----- .../nxp/common/DiagnosticDataProviderImpl.cpp | 1 + 2 files changed, 14 insertions(+), 5 deletions(-) diff --git a/src/platform/nxp/common/ConnectivityManagerImpl.cpp b/src/platform/nxp/common/ConnectivityManagerImpl.cpp index 938dc07f74..90e3f87671 100644 --- a/src/platform/nxp/common/ConnectivityManagerImpl.cpp +++ b/src/platform/nxp/common/ConnectivityManagerImpl.cpp @@ -75,9 +75,11 @@ using namespace ::chip::System; using namespace ::chip::DeviceLayer::Internal; using namespace ::chip::DeviceLayer::DeviceEventType; +#if !SDK_2_16_100 // Table 9-50 "Status codes" of IEEE 802.11-2020: Unspecified failure // Temporary default status code before SDK API to map wlan_event_reason to IEEE Status codes #define WLAN_REFUSED_REASON_UNSPECIFIED 1 +#endif namespace chip { namespace DeviceLayer { @@ -243,6 +245,12 @@ void ConnectivityManagerImpl::ProcessWlanEvent(enum wlan_event_reason wlanEvent) uint8_t associationFailureCause = chip::to_underlying(chip::app::Clusters::WiFiNetworkDiagnostics::AssociationFailureCauseEnum::kUnknown); +#if SDK_2_16_100 + uint16_t wlan_status_code = wlan_get_status_code(wlanEvent); +#else + uint16_t wlan_status_code = WLAN_REFUSED_REASON_UNSPECIFIED; +#endif + #if CHIP_DETAIL_LOGGING enum wlan_connection_state state; int result; @@ -283,7 +291,7 @@ void ConnectivityManagerImpl::ProcessWlanEvent(enum wlan_event_reason wlanEvent) chip::to_underlying(chip::app::Clusters::WiFiNetworkDiagnostics::AssociationFailureCauseEnum::kAssociationFailed); if (delegate) { - delegate->OnAssociationFailureDetected(associationFailureCause, WLAN_REFUSED_REASON_UNSPECIFIED); + delegate->OnAssociationFailureDetected(associationFailureCause, wlan_status_code); } UpdateInternetConnectivityState(); break; @@ -296,7 +304,7 @@ void ConnectivityManagerImpl::ProcessWlanEvent(enum wlan_event_reason wlanEvent) chip::to_underlying(chip::app::Clusters::WiFiNetworkDiagnostics::AssociationFailureCauseEnum::kSsidNotFound); if (delegate) { - delegate->OnAssociationFailureDetected(associationFailureCause, WLAN_REFUSED_REASON_UNSPECIFIED); + delegate->OnAssociationFailureDetected(associationFailureCause, wlan_status_code); } break; @@ -309,7 +317,7 @@ void ConnectivityManagerImpl::ProcessWlanEvent(enum wlan_event_reason wlanEvent) chip::to_underlying(chip::app::Clusters::WiFiNetworkDiagnostics::AssociationFailureCauseEnum::kAuthenticationFailed); if (delegate) { - delegate->OnAssociationFailureDetected(associationFailureCause, WLAN_REFUSED_REASON_UNSPECIFIED); + delegate->OnAssociationFailureDetected(associationFailureCause, wlan_status_code); } break; @@ -321,7 +329,7 @@ void ConnectivityManagerImpl::ProcessWlanEvent(enum wlan_event_reason wlanEvent) sInstance.OnStationDisconnected(); if (delegate) { - delegate->OnAssociationFailureDetected(associationFailureCause, WLAN_REFUSED_REASON_UNSPECIFIED); + delegate->OnAssociationFailureDetected(associationFailureCause, wlan_status_code); } } break; @@ -332,7 +340,7 @@ void ConnectivityManagerImpl::ProcessWlanEvent(enum wlan_event_reason wlanEvent) sInstance.OnStationDisconnected(); if (delegate) { - delegate->OnAssociationFailureDetected(associationFailureCause, WLAN_REFUSED_REASON_UNSPECIFIED); + delegate->OnAssociationFailureDetected(associationFailureCause, wlan_status_code); } break; diff --git a/src/platform/nxp/common/DiagnosticDataProviderImpl.cpp b/src/platform/nxp/common/DiagnosticDataProviderImpl.cpp index 5158b6ac21..dd10221748 100644 --- a/src/platform/nxp/common/DiagnosticDataProviderImpl.cpp +++ b/src/platform/nxp/common/DiagnosticDataProviderImpl.cpp @@ -26,6 +26,7 @@ #include "DiagnosticDataProviderImpl.h" #include +#include #include #include From 2651245d60c5bd3156b6e8d342298132fa6b4d91 Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 3 Oct 2024 12:30:29 -0400 Subject: [PATCH 02/22] zap regen (#35894) Co-authored-by: Andrei Litvin --- .../chef/devices/rootnode_laundrydryer_01796fe396.matter | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/examples/chef/devices/rootnode_laundrydryer_01796fe396.matter b/examples/chef/devices/rootnode_laundrydryer_01796fe396.matter index 0610fdcbe0..4c5010e278 100644 --- a/examples/chef/devices/rootnode_laundrydryer_01796fe396.matter +++ b/examples/chef/devices/rootnode_laundrydryer_01796fe396.matter @@ -212,6 +212,13 @@ enum TestGlobalEnum : enum8 { kFinalValue = 2; } +enum ThreeLevelAutoEnum : enum8 { + kLow = 0; + kMedium = 1; + kHigh = 2; + kAutomatic = 3; +} + bitmap TestGlobalBitmap : bitmap32 { kFirstBit = 0x1; kSecondBit = 0x2; From cc6c773f62431936fe305848c2a1fd121d24551f Mon Sep 17 00:00:00 2001 From: Andrei Litvin Date: Thu, 3 Oct 2024 13:28:57 -0400 Subject: [PATCH 03/22] Add ability to report endpoint device types in the DataModel::Provider interface (#35861) * Add separate listing for device types * Make unit tests work * Restyle * Fixup include * Fixup include * Add clang-tidy comments * Added a comment about future todo * more comments * Attempt to make the code more readable * Fix cast * Add comment for newly created issue. --------- Co-authored-by: Andrei Litvin --- .../CodegenDataModelProvider.cpp | 103 ++++++++++++++++++ .../CodegenDataModelProvider.h | 11 +- .../tests/TestCodegenModelViaMocks.cpp | 61 +++++++++++ src/app/data-model-provider/MetadataTypes.h | 17 +++ src/app/tests/test-interaction-model-api.cpp | 11 ++ src/app/tests/test-interaction-model-api.h | 3 + src/app/util/attribute-storage.cpp | 8 +- src/app/util/attribute-storage.h | 1 + src/app/util/mock/MockNodeConfig.cpp | 11 +- src/app/util/mock/MockNodeConfig.h | 8 +- src/app/util/mock/attribute-storage.cpp | 22 ++++ .../tests/data_model/DataModelFixtures.cpp | 11 ++ .../tests/data_model/DataModelFixtures.h | 3 + 13 files changed, 260 insertions(+), 10 deletions(-) diff --git a/src/app/codegen-data-model-provider/CodegenDataModelProvider.cpp b/src/app/codegen-data-model-provider/CodegenDataModelProvider.cpp index afba240b41..972e056513 100644 --- a/src/app/codegen-data-model-provider/CodegenDataModelProvider.cpp +++ b/src/app/codegen-data-model-provider/CodegenDataModelProvider.cpp @@ -292,6 +292,57 @@ std::optional EnumeratorCommandFinder::FindCommandEntry return (*id == kInvalidCommandId) ? DataModel::CommandEntry::kInvalid : CommandEntryFrom(path, *id); } +// TODO: DeviceTypeEntry content is IDENTICAL to EmberAfDeviceType, so centralizing +// to a common type is probably better. Need to figure out dependencies since +// this would make ember return datamodel-provider types. +// See: https://github.com/project-chip/connectedhomeip/issues/35889 +DataModel::DeviceTypeEntry DeviceTypeEntryFromEmber(const EmberAfDeviceType & other) +{ + DataModel::DeviceTypeEntry entry; + + entry.deviceTypeId = other.deviceId; + entry.deviceTypeVersion = other.deviceVersion; + + return entry; +} + +// Explicitly compare for identical entries. note that types are different, +// so you must do `a == b` and the `b == a` will not work. +bool operator==(const DataModel::DeviceTypeEntry & a, const EmberAfDeviceType & b) +{ + return (a.deviceTypeId == b.deviceId) && (a.deviceTypeVersion == b.deviceVersion); +} + +/// Find the `index` where one of the following holds: +/// - types[index - 1] == previous OR +/// - index == types.size() // i.e. not found or there is no next +/// +/// hintWherePreviousMayBe represents a search hint where previous may exist. +unsigned FindNextDeviceTypeIndex(Span types, const DataModel::DeviceTypeEntry previous, + unsigned hintWherePreviousMayBe) +{ + if (hintWherePreviousMayBe < types.size()) + { + // this is a valid hint ... see if we are lucky + if (previous == types[hintWherePreviousMayBe]) + { + return hintWherePreviousMayBe + 1; // return the next index + } + } + + // hint was not useful. We have to do a full search + for (unsigned idx = 0; idx < types.size(); idx++) + { + if (previous == types[idx]) + { + return idx + 1; + } + } + + // cast should be safe as we know we do not have that many types + return static_cast(types.size()); +} + const ConcreteCommandPath kInvalidCommandPath(kInvalidEndpointId, kInvalidClusterId, kInvalidCommandId); } // namespace @@ -731,6 +782,58 @@ ConcreteCommandPath CodegenDataModelProvider::NextGeneratedCommand(const Concret return ConcreteCommandPath(before.mEndpointId, before.mClusterId, *commandId); } +std::optional CodegenDataModelProvider::FirstDeviceType(EndpointId endpoint) +{ + // Use the `Index` version even though `emberAfDeviceTypeListFromEndpoint` would work because + // index finding is cached in TryFindEndpointIndex and this avoids an extra `emberAfIndexFromEndpoint` + // during `Next` loops. This avoids O(n^2) on number of indexes when iterating over all device types. + // + // Not actually needed for `First`, however this makes First and Next consistent. + std::optional endpoint_index = TryFindEndpointIndex(endpoint); + if (!endpoint_index.has_value()) + { + return std::nullopt; + } + + CHIP_ERROR err = CHIP_NO_ERROR; + Span deviceTypes = emberAfDeviceTypeListFromEndpointIndex(*endpoint_index, err); + + if (deviceTypes.empty()) + { + return std::nullopt; + } + + // we start at the beginning + mDeviceTypeIterationHint = 0; + return DeviceTypeEntryFromEmber(deviceTypes[0]); +} + +std::optional CodegenDataModelProvider::NextDeviceType(EndpointId endpoint, + const DataModel::DeviceTypeEntry & previous) +{ + // Use the `Index` version even though `emberAfDeviceTypeListFromEndpoint` would work because + // index finding is cached in TryFindEndpointIndex and this avoids an extra `emberAfIndexFromEndpoint` + // during `Next` loops. This avoids O(n^2) on number of indexes when iterating over all device types. + std::optional endpoint_index = TryFindEndpointIndex(endpoint); + if (!endpoint_index.has_value()) + { + return std::nullopt; + } + + CHIP_ERROR err = CHIP_NO_ERROR; + Span deviceTypes = emberAfDeviceTypeListFromEndpointIndex(*endpoint_index, err); + + unsigned idx = FindNextDeviceTypeIndex(deviceTypes, previous, mDeviceTypeIterationHint); + + if (idx >= deviceTypes.size()) + { + return std::nullopt; + } + + mDeviceTypeIterationHint = idx; + return DeviceTypeEntryFromEmber(deviceTypes[idx]); +} + bool CodegenDataModelProvider::EventPathIncludesAccessibleConcretePath(const EventPathParams & path, const Access::SubjectDescriptor & descriptor) { diff --git a/src/app/codegen-data-model-provider/CodegenDataModelProvider.h b/src/app/codegen-data-model-provider/CodegenDataModelProvider.h index 500b491a39..f6d6e4e4ed 100644 --- a/src/app/codegen-data-model-provider/CodegenDataModelProvider.h +++ b/src/app/codegen-data-model-provider/CodegenDataModelProvider.h @@ -98,6 +98,10 @@ class CodegenDataModelProvider : public chip::app::DataModel::Provider EndpointId NextEndpoint(EndpointId before) override; bool EndpointExists(EndpointId endpoint) override; + std::optional FirstDeviceType(EndpointId endpoint) override; + std::optional NextDeviceType(EndpointId endpoint, + const DataModel::DeviceTypeEntry & previous) override; + DataModel::ClusterEntry FirstCluster(EndpointId endpoint) override; DataModel::ClusterEntry NextCluster(const ConcreteClusterPath & before) override; std::optional GetClusterInfo(const ConcreteClusterPath & path) override; @@ -116,9 +120,10 @@ class CodegenDataModelProvider : public chip::app::DataModel::Provider private: // Iteration is often done in a tight loop going through all values. // To avoid N^2 iterations, cache a hint of where something is positioned - uint16_t mEndpointIterationHint = 0; - unsigned mClusterIterationHint = 0; - unsigned mAttributeIterationHint = 0; + uint16_t mEndpointIterationHint = 0; + unsigned mClusterIterationHint = 0; + unsigned mAttributeIterationHint = 0; + unsigned mDeviceTypeIterationHint = 0; EmberCommandListIterator mAcceptedCommandsIterator; EmberCommandListIterator mGeneratedCommandsIterator; diff --git a/src/app/codegen-data-model-provider/tests/TestCodegenModelViaMocks.cpp b/src/app/codegen-data-model-provider/tests/TestCodegenModelViaMocks.cpp index 5314684fc6..3840de9c81 100644 --- a/src/app/codegen-data-model-provider/tests/TestCodegenModelViaMocks.cpp +++ b/src/app/codegen-data-model-provider/tests/TestCodegenModelViaMocks.cpp @@ -63,6 +63,7 @@ #include #include +#include #include using namespace chip; @@ -86,6 +87,15 @@ constexpr EndpointId kEndpointIdThatIsMissing = kMockEndpointMin - 1; constexpr AttributeId kReadOnlyAttributeId = 0x5001; +constexpr DeviceTypeId kDeviceTypeId1 = 123; +constexpr uint8_t kDeviceTypeId1Version = 10; + +constexpr DeviceTypeId kDeviceTypeId2 = 1122; +constexpr uint8_t kDeviceTypeId2Version = 11; + +constexpr DeviceTypeId kDeviceTypeId3 = 3; +constexpr uint8_t kDeviceTypeId3Version = 33; + static_assert(kEndpointIdThatIsMissing != kInvalidEndpointId); static_assert(kEndpointIdThatIsMissing != kMockEndpoint1); static_assert(kEndpointIdThatIsMissing != kMockEndpoint2); @@ -270,6 +280,10 @@ const MockNodeConfig gTestNodeConfig({ MockClusterConfig(MockClusterId(2), { ClusterRevision::Id, FeatureMap::Id, MockAttributeId(1), }), + }, { + { kDeviceTypeId1, kDeviceTypeId1Version}, + { kDeviceTypeId2, kDeviceTypeId2Version}, + { kDeviceTypeId3, kDeviceTypeId3Version}, }), MockEndpointConfig(kMockEndpoint2, { MockClusterConfig(MockClusterId(1), { @@ -296,6 +310,8 @@ const MockNodeConfig gTestNodeConfig({ {11}, /* acceptedCommands */ {4, 6} /* generatedCommands */ ), + }, { + { kDeviceTypeId2, kDeviceTypeId2Version}, }), MockEndpointConfig(kMockEndpoint3, { MockClusterConfig(MockClusterId(1), { @@ -2580,3 +2596,48 @@ TEST(TestCodegenModelViaMocks, EmberWriteInvalidDataType) ASSERT_EQ(model.WriteAttribute(test.GetRequest(), decoder), Status::Failure); ASSERT_TRUE(model.ChangeListener().DirtyList().empty()); } + +TEST(TestCodegenModelViaMocks, DeviceTypeIteration) +{ + UseMockNodeConfig config(gTestNodeConfig); + CodegenDataModelProviderWithContext model; + + // Mock endpoint 1 has 3 device types + std::optional entry = model.FirstDeviceType(kMockEndpoint1); + ASSERT_EQ(entry, + std::make_optional(DeviceTypeEntry{ .deviceTypeId = kDeviceTypeId1, .deviceTypeVersion = kDeviceTypeId1Version })); + // NOLINTNEXTLINE(bugprone-unchecked-optional-access): Assert above that this is not none + entry = model.NextDeviceType(kMockEndpoint1, *entry); + ASSERT_EQ(entry, + std::make_optional(DeviceTypeEntry{ .deviceTypeId = kDeviceTypeId2, .deviceTypeVersion = kDeviceTypeId2Version })); + // NOLINTNEXTLINE(bugprone-unchecked-optional-access): Assert above that this is not none + entry = model.NextDeviceType(kMockEndpoint1, *entry); + ASSERT_EQ(entry, + std::make_optional(DeviceTypeEntry{ .deviceTypeId = kDeviceTypeId3, .deviceTypeVersion = kDeviceTypeId3Version })); + // NOLINTNEXTLINE(bugprone-unchecked-optional-access): Assert above that this is not none + entry = model.NextDeviceType(kMockEndpoint1, *entry); + ASSERT_FALSE(entry.has_value()); + + // Mock endpoint 2 has 1 device types + entry = model.FirstDeviceType(kMockEndpoint2); + ASSERT_EQ(entry, + std::make_optional(DeviceTypeEntry{ .deviceTypeId = kDeviceTypeId2, .deviceTypeVersion = kDeviceTypeId2Version })); + // NOLINTNEXTLINE(bugprone-unchecked-optional-access): Assert above that this is not none + entry = model.NextDeviceType(kMockEndpoint2, *entry); + ASSERT_FALSE(entry.has_value()); + + // out of order query works + entry = std::make_optional(DeviceTypeEntry{ .deviceTypeId = kDeviceTypeId2, .deviceTypeVersion = kDeviceTypeId2Version }); + entry = model.NextDeviceType(kMockEndpoint1, *entry); + ASSERT_EQ(entry, + std::make_optional(DeviceTypeEntry{ .deviceTypeId = kDeviceTypeId3, .deviceTypeVersion = kDeviceTypeId3Version })); + + // invalid query fails + entry = std::make_optional(DeviceTypeEntry{ .deviceTypeId = kDeviceTypeId1, .deviceTypeVersion = kDeviceTypeId1Version }); + entry = model.NextDeviceType(kMockEndpoint2, *entry); + ASSERT_FALSE(entry.has_value()); + + // empty endpoint works + entry = model.FirstDeviceType(kMockEndpoint3); + ASSERT_FALSE(entry.has_value()); +} diff --git a/src/app/data-model-provider/MetadataTypes.h b/src/app/data-model-provider/MetadataTypes.h index 65c89da1c2..a3541faeab 100644 --- a/src/app/data-model-provider/MetadataTypes.h +++ b/src/app/data-model-provider/MetadataTypes.h @@ -105,6 +105,18 @@ struct CommandEntry static const CommandEntry kInvalid; }; +/// Represents a device type that resides on an endpoint +struct DeviceTypeEntry +{ + DeviceTypeId deviceTypeId; + uint8_t deviceTypeVersion; + + bool operator==(const DeviceTypeEntry & other) const + { + return (deviceTypeId == other.deviceTypeId) && (deviceTypeVersion == other.deviceTypeVersion); + } +}; + /// Provides metadata information for a data model /// /// The data model can be viewed as a tree of endpoint/cluster/(attribute+commands+events) @@ -130,6 +142,11 @@ class ProviderMetadataTree virtual EndpointId NextEndpoint(EndpointId before) = 0; virtual bool EndpointExists(EndpointId id); + // This iteration describes device types registered on an endpoint + virtual std::optional FirstDeviceType(EndpointId endpoint) = 0; + virtual std::optional NextDeviceType(EndpointId endpoint, const DeviceTypeEntry & previous) = 0; + + // This iteration will list all clusters on a given endpoint virtual ClusterEntry FirstCluster(EndpointId endpoint) = 0; virtual ClusterEntry NextCluster(const ConcreteClusterPath & before) = 0; virtual std::optional GetClusterInfo(const ConcreteClusterPath & path) = 0; diff --git a/src/app/tests/test-interaction-model-api.cpp b/src/app/tests/test-interaction-model-api.cpp index 5750e098b9..b69c423427 100644 --- a/src/app/tests/test-interaction-model-api.cpp +++ b/src/app/tests/test-interaction-model-api.cpp @@ -216,6 +216,17 @@ EndpointId TestImCustomDataModel::NextEndpoint(EndpointId before) return CodegenDataModelProviderInstance()->NextEndpoint(before); } +std::optional TestImCustomDataModel::FirstDeviceType(EndpointId endpoint) +{ + return std::nullopt; +} + +std::optional TestImCustomDataModel::NextDeviceType(EndpointId endpoint, + const DataModel::DeviceTypeEntry & previous) +{ + return std::nullopt; +} + ClusterEntry TestImCustomDataModel::FirstCluster(EndpointId endpoint) { return CodegenDataModelProviderInstance()->FirstCluster(endpoint); diff --git a/src/app/tests/test-interaction-model-api.h b/src/app/tests/test-interaction-model-api.h index 8523e4b88c..ae5cc63df7 100644 --- a/src/app/tests/test-interaction-model-api.h +++ b/src/app/tests/test-interaction-model-api.h @@ -131,6 +131,9 @@ class TestImCustomDataModel : public DataModel::Provider EndpointId FirstEndpoint() override; EndpointId NextEndpoint(EndpointId before) override; + std::optional FirstDeviceType(EndpointId endpoint) override; + std::optional NextDeviceType(EndpointId endpoint, + const DataModel::DeviceTypeEntry & previous) override; DataModel::ClusterEntry FirstCluster(EndpointId endpoint) override; DataModel::ClusterEntry NextCluster(const ConcreteClusterPath & before) override; std::optional GetClusterInfo(const ConcreteClusterPath & path) override; diff --git a/src/app/util/attribute-storage.cpp b/src/app/util/attribute-storage.cpp index 7247031b07..0d1b3827e8 100644 --- a/src/app/util/attribute-storage.cpp +++ b/src/app/util/attribute-storage.cpp @@ -1007,13 +1007,15 @@ uint8_t emberAfGetClusterCountForEndpoint(EndpointId endpoint) Span emberAfDeviceTypeListFromEndpoint(EndpointId endpoint, CHIP_ERROR & err) { - uint16_t endpointIndex = emberAfIndexFromEndpoint(endpoint); - Span ret; + return emberAfDeviceTypeListFromEndpointIndex(emberAfIndexFromEndpoint(endpoint), err); +} +chip::Span emberAfDeviceTypeListFromEndpointIndex(unsigned endpointIndex, CHIP_ERROR & err) +{ if (endpointIndex == 0xFFFF) { err = CHIP_ERROR_INVALID_ARGUMENT; - return ret; + return Span(); } err = CHIP_NO_ERROR; diff --git a/src/app/util/attribute-storage.h b/src/app/util/attribute-storage.h index 23a9b9b5fd..9d2dcc60bb 100644 --- a/src/app/util/attribute-storage.h +++ b/src/app/util/attribute-storage.h @@ -281,6 +281,7 @@ const EmberAfCluster * emberAfGetNthCluster(chip::EndpointId endpoint, uint8_t n // Retrieve the device type list associated with a specific endpoint. // chip::Span emberAfDeviceTypeListFromEndpoint(chip::EndpointId endpoint, CHIP_ERROR & err); +chip::Span emberAfDeviceTypeListFromEndpointIndex(unsigned endpointIndex, CHIP_ERROR & err); // // Override the device type list current associated with an endpoint with a user-provided list. The buffers backing diff --git a/src/app/util/mock/MockNodeConfig.cpp b/src/app/util/mock/MockNodeConfig.cpp index b48c846e65..c6572ed0ae 100644 --- a/src/app/util/mock/MockNodeConfig.cpp +++ b/src/app/util/mock/MockNodeConfig.cpp @@ -16,10 +16,12 @@ * limitations under the License. */ +#include "app/util/af-types.h" #include #include #include +#include #include #include @@ -174,8 +176,10 @@ const MockAttributeConfig * MockClusterConfig::attributeById(AttributeId attribu return findById(attributes, attributeId, outIndex); } -MockEndpointConfig::MockEndpointConfig(EndpointId aId, std::initializer_list aClusters) : - id(aId), clusters(aClusters), mEmberEndpoint{} +MockEndpointConfig::MockEndpointConfig(EndpointId aId, std::initializer_list aClusters, + std::initializer_list aDeviceTypes) : + id(aId), + clusters(aClusters), mDeviceTypes(aDeviceTypes), mEmberEndpoint{} { VerifyOrDie(aClusters.size() < UINT8_MAX); @@ -189,7 +193,8 @@ MockEndpointConfig::MockEndpointConfig(EndpointId aId, std::initializer_list aClusters = {}); + MockEndpointConfig(EndpointId aId, std::initializer_list aClusters = {}, + std::initializer_list aDeviceTypes = {}); // Endpoint-config is self-referential: mEmberEndpoint.clusters references mEmberClusters.data() MockEndpointConfig(const MockEndpointConfig & other); @@ -109,12 +110,17 @@ struct MockEndpointConfig const MockClusterConfig * clusterById(ClusterId clusterId, ptrdiff_t * outIndex = nullptr) const; const EmberAfEndpointType * emberEndpoint() const { return &mEmberEndpoint; } + Span deviceTypes() const + { + return Span(mDeviceTypes.data(), mDeviceTypes.size()); + } const EndpointId id; const std::vector clusters; private: std::vector mEmberClusters; + std::vector mDeviceTypes; EmberAfEndpointType mEmberEndpoint; }; diff --git a/src/app/util/mock/attribute-storage.cpp b/src/app/util/mock/attribute-storage.cpp index 4447640dc1..256d0a3a88 100644 --- a/src/app/util/mock/attribute-storage.cpp +++ b/src/app/util/mock/attribute-storage.cpp @@ -313,6 +313,28 @@ DataVersion * emberAfDataVersionStorage(const chip::app::ConcreteClusterPath & a return &dataVersion; } +chip::Span emberAfDeviceTypeListFromEndpoint(chip::EndpointId endpointId, CHIP_ERROR & err) +{ + auto endpoint = GetMockNodeConfig().endpointById(endpointId); + + if (endpoint == nullptr) + { + return chip::Span(); + } + + return endpoint->deviceTypes(); +} + +chip::Span emberAfDeviceTypeListFromEndpointIndex(unsigned index, CHIP_ERROR & err) +{ + if (index >= GetMockNodeConfig().endpoints.size()) + { + return chip::Span(); + } + + return GetMockNodeConfig().endpoints[index].deviceTypes(); +} + void emberAfAttributeChanged(EndpointId endpoint, ClusterId clusterId, AttributeId attributeId, AttributesChangedListener * listener) { diff --git a/src/controller/tests/data_model/DataModelFixtures.cpp b/src/controller/tests/data_model/DataModelFixtures.cpp index e30641fc53..a5533dc51d 100644 --- a/src/controller/tests/data_model/DataModelFixtures.cpp +++ b/src/controller/tests/data_model/DataModelFixtures.cpp @@ -679,6 +679,17 @@ EndpointId CustomDataModel::NextEndpoint(EndpointId before) return CodegenDataModelProviderInstance()->NextEndpoint(before); } +std::optional CustomDataModel::FirstDeviceType(EndpointId endpoint) +{ + return std::nullopt; +} + +std::optional CustomDataModel::NextDeviceType(EndpointId endpoint, + const DataModel::DeviceTypeEntry & previous) +{ + return std::nullopt; +} + ClusterEntry CustomDataModel::FirstCluster(EndpointId endpoint) { return CodegenDataModelProviderInstance()->FirstCluster(endpoint); diff --git a/src/controller/tests/data_model/DataModelFixtures.h b/src/controller/tests/data_model/DataModelFixtures.h index 68d2cc1031..bdc251ecb7 100644 --- a/src/controller/tests/data_model/DataModelFixtures.h +++ b/src/controller/tests/data_model/DataModelFixtures.h @@ -129,6 +129,9 @@ class CustomDataModel : public DataModel::Provider EndpointId FirstEndpoint() override; EndpointId NextEndpoint(EndpointId before) override; + std::optional FirstDeviceType(EndpointId endpoint) override; + std::optional NextDeviceType(EndpointId endpoint, + const DataModel::DeviceTypeEntry & previous) override; DataModel::ClusterEntry FirstCluster(EndpointId endpoint) override; DataModel::ClusterEntry NextCluster(const ConcreteClusterPath & before) override; std::optional GetClusterInfo(const ConcreteClusterPath & path) override; From 6bb8645577fe30d2f59a0d10d201373235379bb4 Mon Sep 17 00:00:00 2001 From: Abdul Samad Date: Thu, 3 Oct 2024 14:35:39 -0500 Subject: [PATCH 04/22] [SVE] TC-MCORE-FS-1.3: Bump the DUT timeout for newly added device (#35740) * Bump the DUT timeout for discovering and commissioning newly added device * Update src/python_testing/TC_MCORE_FS_1_3.py --------- Co-authored-by: Andrei Litvin --- src/python_testing/TC_MCORE_FS_1_3.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/python_testing/TC_MCORE_FS_1_3.py b/src/python_testing/TC_MCORE_FS_1_3.py index 79988e5289..49dc89386c 100644 --- a/src/python_testing/TC_MCORE_FS_1_3.py +++ b/src/python_testing/TC_MCORE_FS_1_3.py @@ -197,7 +197,7 @@ async def test_TC_MCORE_FS_1_3(self): device_node_id=th_server_th_node_id) # Wait for the device to appear on the DUT_FSA_BRIDGE. - await asyncio.sleep(2) + await asyncio.sleep(2 if self.is_pics_sdk_ci_only else 30) # Get the list of endpoints on the DUT_FSA_BRIDGE after adding the TH_SERVER_NO_UID. dut_fsa_bridge_endpoints_new = set(await self.read_single_attribute_check_success( From 9ae53c5763b164278cb9df963cf9edb3696670d6 Mon Sep 17 00:00:00 2001 From: Marcos B <15697303+gmarcosb@users.noreply.github.com> Date: Thu, 3 Oct 2024 14:32:50 -0600 Subject: [PATCH 05/22] Camera webrtc provider cluster (#35779) * Generated using ./alchemy zap --attribute="in-progress" WebRTC_Provider.adoc * Update description * Generated using ./scripts/tools/zap_regen_all.py * Restyled by whitespace * Restyled by prettier-json * Re-enerated with updated alchemy supporting cameras domain * Re-enerated using ./scripts/tools/zap_regen_all.py * Re-generated using ./scripts/tools/zap_regen_all.py after some update causing `WITH_AUTORELEASE_POOL` --------- Co-authored-by: Restyled.io --- .github/workflows/tests.yaml | 1 + docs/zap_clusters.md | 1 + scripts/rules.matterlint | 1 + .../chip/webrtc-provider-cluster.xml | 145 ++ .../zcl/zcl-with-test-extensions.json | 22 +- src/app/zap-templates/zcl/zcl.json | 22 +- src/app/zap_cluster_list.json | 2 + .../data_model/controller-clusters.matter | 115 ++ .../chip/devicecontroller/ChipClusters.java | 447 +++++++ .../chip/devicecontroller/ChipStructs.java | 227 ++++ .../devicecontroller/ClusterIDMapping.java | 194 +++ .../devicecontroller/ClusterInfoMapping.java | 338 +++++ .../devicecontroller/ClusterReadMapping.java | 82 ++ .../devicecontroller/ClusterWriteMapping.java | 2 + .../chip/devicecontroller/cluster/files.gni | 2 + ...TransportProviderClusterICEServerStruct.kt | 106 ++ ...sportProviderClusterWebRTCSessionStruct.kt | 115 ++ .../WebRTCTransportProviderCluster.kt | 1097 +++++++++++++++ .../java/matter/controller/cluster/files.gni | 3 + ...TransportProviderClusterICEServerStruct.kt | 106 ++ ...sportProviderClusterWebRTCSessionStruct.kt | 115 ++ .../CHIPAttributeTLVValueDecoder.cpp | 250 ++++ .../CHIPEventTLVValueDecoder.cpp | 10 + .../python/chip/clusters/CHIPClusters.py | 102 ++ .../python/chip/clusters/Objects.py | 369 ++++++ .../MTRAttributeSpecifiedCheck.mm | 33 + .../MTRAttributeTLVValueDecoder.mm | 56 + .../CHIP/zap-generated/MTRBaseClusters.h | 124 ++ .../CHIP/zap-generated/MTRBaseClusters.mm | 377 ++++++ .../CHIP/zap-generated/MTRClusterConstants.h | 19 + .../CHIP/zap-generated/MTRClusterNames.mm | 100 ++ .../CHIP/zap-generated/MTRClusters.h | 44 + .../CHIP/zap-generated/MTRClusters.mm | 174 +++ .../zap-generated/MTRCommandPayloadsObjc.h | 228 ++++ .../zap-generated/MTRCommandPayloadsObjc.mm | 852 ++++++++++++ .../MTRCommandPayloads_Internal.h | 42 + .../zap-generated/MTRCommandTimedCheck.mm | 12 + .../zap-generated/MTREventTLVValueDecoder.mm | 15 + .../CHIP/zap-generated/MTRStructsObjc.h | 19 + .../CHIP/zap-generated/MTRStructsObjc.mm | 81 ++ .../zap-generated/attributes/Accessors.cpp | 773 ++++++++++- .../zap-generated/attributes/Accessors.h | 90 ++ .../app-common/zap-generated/callback.h | 73 + .../zap-generated/cluster-enums-check.h | 37 + .../app-common/zap-generated/cluster-enums.h | 51 + .../zap-generated/cluster-objects.cpp | 496 +++++++ .../zap-generated/cluster-objects.h | 474 +++++++ .../app-common/zap-generated/ids/Attributes.h | 34 + .../app-common/zap-generated/ids/Clusters.h | 3 + .../app-common/zap-generated/ids/Commands.h | 34 + .../zap-generated/cluster/Commands.h | 296 +++++ .../cluster/ComplexArgumentParser.cpp | 113 ++ .../cluster/ComplexArgumentParser.h | 10 + .../cluster/logging/DataModelLogger.cpp | 186 +++ .../cluster/logging/DataModelLogger.h | 12 + .../cluster/logging/EntryToText.cpp | 51 + .../zap-generated/cluster/Commands.h | 1177 +++++++++++++++++ 57 files changed, 9883 insertions(+), 77 deletions(-) create mode 100644 src/app/zap-templates/zcl/data-model/chip/webrtc-provider-cluster.xml create mode 100644 src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WebRTCTransportProviderClusterICEServerStruct.kt create mode 100644 src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WebRTCTransportProviderClusterWebRTCSessionStruct.kt create mode 100644 src/controller/java/generated/java/matter/controller/cluster/clusters/WebRTCTransportProviderCluster.kt create mode 100644 src/controller/java/generated/java/matter/controller/cluster/structs/WebRTCTransportProviderClusterICEServerStruct.kt create mode 100644 src/controller/java/generated/java/matter/controller/cluster/structs/WebRTCTransportProviderClusterWebRTCSessionStruct.kt diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index 180d374b40..e0904bb516 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -198,6 +198,7 @@ jobs: src/app/zap-templates/zcl/data-model/chip/wake-on-lan-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/washer-controls-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/water-heater-management-cluster.xml \ + src/app/zap-templates/zcl/data-model/chip/webrtc-provider-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/wifi-network-diagnostics-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml \ src/app/zap-templates/zcl/data-model/chip/window-covering.xml \ diff --git a/docs/zap_clusters.md b/docs/zap_clusters.md index 94fe851dcd..1250a60b71 100644 --- a/docs/zap_clusters.md +++ b/docs/zap_clusters.md @@ -129,6 +129,7 @@ Generally regenerate using one of: | 1294 | 0x50E | AccountLogin | | 1295 | 0x50F | ContentControl | | 1296 | 0x510 | ContentAppObserver | +| 1363 | 0x553 | WebRTCTransportProvider | | 1366 | 0x556 | Chime | | 1872 | 0x750 | EcosystemInformation | | 1873 | 0x751 | CommissionerControl | diff --git a/scripts/rules.matterlint b/scripts/rules.matterlint index c1e2e48cde..1573cc7065 100644 --- a/scripts/rules.matterlint +++ b/scripts/rules.matterlint @@ -108,6 +108,7 @@ load "../src/app/zap-templates/zcl/data-model/chip/wake-on-lan-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/washer-controls-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/water-heater-management-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/water-heater-mode-cluster.xml"; +load "../src/app/zap-templates/zcl/data-model/chip/webrtc-provider-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/wifi-network-diagnostics-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/wifi-network-management-cluster.xml"; load "../src/app/zap-templates/zcl/data-model/chip/window-covering.xml"; diff --git a/src/app/zap-templates/zcl/data-model/chip/webrtc-provider-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/webrtc-provider-cluster.xml new file mode 100644 index 0000000000..9e338efee7 --- /dev/null +++ b/src/app/zap-templates/zcl/data-model/chip/webrtc-provider-cluster.xml @@ -0,0 +1,145 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WebRTC Transport Provider + 0x0553 + WEBRTC_TRANSPORT_PROVIDER_CLUSTER + The WebRTC transport provider cluster provides a way for stream providers (e.g. Cameras) to stream or receive their data through WebRTC. + true + true + + CurrentSessions + + Requests that the Provider initiates a new session with the Offer / Answer flow in a way that allows for options to be passed and work with devices needing the standby flow. + + + + + + + + + + This command SHALL be generated in response to a SolicitOffer command. + + + + + + + + This command allows an SDP Offer to be set and start a new session. + + + + + + + + + + + + This command contains information about the stream created as a response to the requestor's offer. + + + + + + + This command SHALL be initiated from a Node in response to an Offer that was previously received from a remote peer. + + + + + + This command allows for https://www.rfc-editor.org/rfc/rfc8839#section-4.2.1.2 nominated after the initial Offer / Answer exchange to be added to a session during the gathering phase. + + + + + + This command instructs the stream provider to end the WebRTC session. + + + + + + diff --git a/src/app/zap-templates/zcl/zcl-with-test-extensions.json b/src/app/zap-templates/zcl/zcl-with-test-extensions.json index dbb08dd674..e4c9a18e6c 100644 --- a/src/app/zap-templates/zcl/zcl-with-test-extensions.json +++ b/src/app/zap-templates/zcl/zcl-with-test-extensions.json @@ -131,6 +131,7 @@ "washer-controls-cluster.xml", "water-heater-management-cluster.xml", "water-heater-mode-cluster.xml", + "webrtc-provider-cluster.xml", "wifi-network-diagnostics-cluster.xml", "wifi-network-management-cluster.xml", "window-covering.xml", @@ -286,8 +287,7 @@ "ActiveModeThreshold", "RegisteredClients", "ICDCounter", - "ClientsSupportedPerFabric", - "MaximumCheckInBackOff" + "ClientsSupportedPerFabric" ], "Occupancy Sensing": ["HoldTimeLimits", "HoldTime", "FeatureMap"], "Operational Credentials": [ @@ -416,13 +416,7 @@ "DSTOffsetListMaxSize" ], "Temperature Control": ["SupportedTemperatureLevels"], - "Dishwasher Mode": [ - "SupportedModes", - "CurrentMode", - "StartUpMode", - "OnMode", - "FeatureMap" - ], + "Dishwasher Mode": ["SupportedModes", "CurrentMode", "FeatureMap"], "Microwave Oven Mode": ["SupportedModes", "CurrentMode", "FeatureMap"], "Microwave Oven Control": [ "CookTime", @@ -436,18 +430,10 @@ "WattRating", "FeatureMap" ], - "Laundry Washer Mode": [ - "SupportedModes", - "CurrentMode", - "StartUpMode", - "OnMode", - "FeatureMap" - ], + "Laundry Washer Mode": ["SupportedModes", "CurrentMode", "FeatureMap"], "Refrigerator And Temperature Controlled Cabinet Mode": [ "SupportedModes", "CurrentMode", - "StartUpMode", - "OnMode", "FeatureMap" ], "RVC Clean Mode": ["SupportedModes", "CurrentMode", "FeatureMap"], diff --git a/src/app/zap-templates/zcl/zcl.json b/src/app/zap-templates/zcl/zcl.json index 261a87d842..b306dba223 100644 --- a/src/app/zap-templates/zcl/zcl.json +++ b/src/app/zap-templates/zcl/zcl.json @@ -125,6 +125,7 @@ "washer-controls-cluster.xml", "water-heater-management-cluster.xml", "water-heater-mode-cluster.xml", + "webrtc-provider-cluster.xml", "wifi-network-diagnostics-cluster.xml", "wifi-network-management-cluster.xml", "window-covering.xml", @@ -280,8 +281,7 @@ "ActiveModeThreshold", "RegisteredClients", "ICDCounter", - "ClientsSupportedPerFabric", - "MaximumCheckInBackOff" + "ClientsSupportedPerFabric" ], "Occupancy Sensing": ["HoldTimeLimits", "HoldTime", "FeatureMap"], "Operational Credentials": [ @@ -410,13 +410,7 @@ "DSTOffsetListMaxSize" ], "Temperature Control": ["SupportedTemperatureLevels"], - "Dishwasher Mode": [ - "SupportedModes", - "CurrentMode", - "StartUpMode", - "OnMode", - "FeatureMap" - ], + "Dishwasher Mode": ["SupportedModes", "CurrentMode", "FeatureMap"], "Microwave Oven Mode": ["SupportedModes", "CurrentMode", "FeatureMap"], "Microwave Oven Control": [ "CookTime", @@ -430,18 +424,10 @@ "WattRating", "FeatureMap" ], - "Laundry Washer Mode": [ - "SupportedModes", - "CurrentMode", - "StartUpMode", - "OnMode", - "FeatureMap" - ], + "Laundry Washer Mode": ["SupportedModes", "CurrentMode", "FeatureMap"], "Refrigerator And Temperature Controlled Cabinet Mode": [ "SupportedModes", "CurrentMode", - "StartUpMode", - "OnMode", "FeatureMap" ], "RVC Clean Mode": ["SupportedModes", "CurrentMode", "FeatureMap"], diff --git a/src/app/zap_cluster_list.json b/src/app/zap_cluster_list.json index fa76c0e9a2..c240008e1c 100644 --- a/src/app/zap_cluster_list.json +++ b/src/app/zap_cluster_list.json @@ -131,6 +131,7 @@ "LAUNDRY_DRYER_CONTROLS_CLUSTER": [], "WATER_HEATER_MANAGEMENT_CLUSTER": [], "WATER_HEATER_MODE_CLUSTER": [], + "WEB_RTC_PROVIDER_CLUSTER": [], "WIFI_NETWORK_DIAGNOSTICS_CLUSTER": [], "WINDOW_COVERING_CLUSTER": [] }, @@ -310,6 +311,7 @@ "WAKE_ON_LAN_CLUSTER": ["wake-on-lan-server"], "LAUNDRY_WASHER_CONTROLS_CLUSTER": ["laundry-washer-controls-server"], "LAUNDRY_DRYER_CONTROLS_CLUSTER": ["laundry-dryer-controls-server"], + "WEB_RTC_PROVIDER_CLUSTER": [], "WIFI_NETWORK_DIAGNOSTICS_CLUSTER": ["wifi-network-diagnostics-server"], "WIFI_NETWORK_MANAGEMENT_CLUSTER": ["wifi-network-management-server"], "WINDOW_COVERING_CLUSTER": ["window-covering-server"], diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index 2f7263bb32..7f5d7fda86 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -9415,6 +9415,121 @@ provisional cluster ContentAppObserver = 1296 { command ContentAppMessage(ContentAppMessageRequest): ContentAppMessageResponse = 0; } +/** The WebRTC transport provider cluster provides a way for stream providers (e.g. Cameras) to stream or receive their data through WebRTC. */ +provisional cluster WebRTCTransportProvider = 1363 { + revision 1; + + enum StreamTypeEnum : enum8 { + kInternal = 0; + kRecording = 1; + kAnalysis = 2; + kLiveView = 3; + } + + enum WebRTCEndReasonEnum : enum8 { + kIceFailed = 0; + kIceTimeout = 1; + kUserHangup = 2; + kUserBusy = 3; + kReplaced = 4; + kNoUserMedia = 5; + kInviteTimeout = 6; + kAnsweredElsewhere = 7; + kOutOfResources = 8; + kMediaTimeout = 9; + kLowPower = 10; + kUnknownReason = 11; + } + + bitmap WebRTCMetadataOptions : bitmap8 { + kDataTLV = 0x1; + } + + struct ICEServerStruct { + char_string urls[] = 1; + optional char_string username = 2; + optional char_string credential = 3; + optional int16u caid = 4; + } + + struct WebRTCSessionStruct { + int16u id = 1; + node_id peerNodeID = 2; + fabric_idx peerFabricIndex = 3; + StreamTypeEnum streamType = 4; + nullable int16u videoStreamID = 5; + nullable int16u audioStreamID = 6; + WebRTCMetadataOptions metadataOptions = 7; + } + + readonly attribute WebRTCSessionStruct currentSessions[] = 0; + readonly attribute command_id generatedCommandList[] = 65528; + readonly attribute command_id acceptedCommandList[] = 65529; + readonly attribute event_id eventList[] = 65530; + readonly attribute attrib_id attributeList[] = 65531; + readonly attribute bitmap32 featureMap = 65532; + readonly attribute int16u clusterRevision = 65533; + + request struct SolicitOfferRequest { + StreamTypeEnum streamType = 0; + optional nullable int16u videoStreamID = 1; + optional nullable int16u audioStreamID = 2; + optional ICEServerStruct ICEServers[] = 3; + optional char_string ICETransportPolicy = 4; + optional WebRTCMetadataOptions metadataOptions = 5; + } + + response struct SolicitOfferResponse = 2 { + int16u webRTCSessionID = 0; + boolean deferredOffer = 1; + optional nullable int16u videoStreamID = 2; + optional nullable int16u audioStreamID = 3; + } + + request struct ProvideOfferRequest { + nullable int16u webRTCSessionID = 0; + char_string sdp = 1; + StreamTypeEnum streamType = 2; + optional nullable int16u videoStreamID = 3; + optional nullable int16u audioStreamID = 4; + optional ICEServerStruct ICEServers[] = 5; + optional char_string ICETransportPolicy = 6; + optional WebRTCMetadataOptions metadataOptions = 7; + } + + response struct ProvideOfferResponse = 4 { + int16u webRTCSessionID = 0; + int16u videoStreamID = 1; + int16u audioStreamID = 2; + } + + request struct ProvideAnswerRequest { + int16u webRTCSessionID = 0; + char_string sdp = 1; + } + + request struct ProvideICECandidateRequest { + int16u webRTCSessionID = 0; + char_string ICECandidate = 1; + } + + request struct EndSessionRequest { + int16u webRTCSessionID = 0; + WebRTCEndReasonEnum reason = 1; + } + + /** Requests that the Provider initiates a new session with the Offer / Answer flow in a way that allows for options to be passed and work with devices needing the standby flow. */ + command SolicitOffer(SolicitOfferRequest): SolicitOfferResponse = 1; + /** This command allows an SDP Offer to be set and start a new session. */ + command ProvideOffer(ProvideOfferRequest): ProvideOfferResponse = 3; + /** This command SHALL be initiated from a Node in response to an Offer that was previously received from a remote peer. */ + command ProvideAnswer(ProvideAnswerRequest): DefaultSuccess = 5; + /** This command allows for https://www.rfc-editor.org/rfc/rfc8839#section-4.2.1.2 nominated after the initial Offer / Answer exchange to be added to a session during the gathering phase. */ + command ProvideICECandidate(ProvideICECandidateRequest): DefaultSuccess = 6; + /** This command instructs the stream provider to end the WebRTC session. */ + command EndSession(EndSessionRequest): DefaultSuccess = 7; +} + /** This cluster provides facilities to configure and play Chime sounds, such as those used in a doorbell. */ provisional cluster Chime = 1366 { revision 1; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java index dbc26ae23c..88e4e0fb90 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipClusters.java @@ -59491,6 +59491,453 @@ public void onSuccess(byte[] tlv) { } } + public static class WebRTCTransportProviderCluster extends BaseChipCluster { + public static final long CLUSTER_ID = 1363L; + + private static final long CURRENT_SESSIONS_ATTRIBUTE_ID = 0L; + private static final long GENERATED_COMMAND_LIST_ATTRIBUTE_ID = 65528L; + private static final long ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID = 65529L; + private static final long EVENT_LIST_ATTRIBUTE_ID = 65530L; + private static final long ATTRIBUTE_LIST_ATTRIBUTE_ID = 65531L; + private static final long FEATURE_MAP_ATTRIBUTE_ID = 65532L; + private static final long CLUSTER_REVISION_ATTRIBUTE_ID = 65533L; + + public WebRTCTransportProviderCluster(long devicePtr, int endpointId) { + super(devicePtr, endpointId, CLUSTER_ID); + } + + @Override + @Deprecated + public long initWithDevice(long devicePtr, int endpointId) { + return 0L; + } + + public void solicitOffer(SolicitOfferResponseCallback callback, Integer streamType, @Nullable Optional videoStreamID, @Nullable Optional audioStreamID, Optional> ICEServers, Optional ICETransportPolicy, Optional metadataOptions) { + solicitOffer(callback, streamType, videoStreamID, audioStreamID, ICEServers, ICETransportPolicy, metadataOptions, 0); + } + + public void solicitOffer(SolicitOfferResponseCallback callback, Integer streamType, @Nullable Optional videoStreamID, @Nullable Optional audioStreamID, Optional> ICEServers, Optional ICETransportPolicy, Optional metadataOptions, int timedInvokeTimeoutMs) { + final long commandId = 1L; + + ArrayList elements = new ArrayList<>(); + final long streamTypeFieldID = 0L; + BaseTLVType streamTypetlvValue = new UIntType(streamType); + elements.add(new StructElement(streamTypeFieldID, streamTypetlvValue)); + + final long videoStreamIDFieldID = 1L; + BaseTLVType videoStreamIDtlvValue = videoStreamID != null ? videoStreamID.map((nonOptionalvideoStreamID) -> new UIntType(nonOptionalvideoStreamID)).orElse(new EmptyType()) : new NullType(); + elements.add(new StructElement(videoStreamIDFieldID, videoStreamIDtlvValue)); + + final long audioStreamIDFieldID = 2L; + BaseTLVType audioStreamIDtlvValue = audioStreamID != null ? audioStreamID.map((nonOptionalaudioStreamID) -> new UIntType(nonOptionalaudioStreamID)).orElse(new EmptyType()) : new NullType(); + elements.add(new StructElement(audioStreamIDFieldID, audioStreamIDtlvValue)); + + final long ICEServersFieldID = 3L; + BaseTLVType ICEServerstlvValue = ICEServers.map((nonOptionalICEServers) -> ArrayType.generateArrayType(nonOptionalICEServers, (elementnonOptionalICEServers) -> elementnonOptionalICEServers.encodeTlv())).orElse(new EmptyType()); + elements.add(new StructElement(ICEServersFieldID, ICEServerstlvValue)); + + final long ICETransportPolicyFieldID = 4L; + BaseTLVType ICETransportPolicytlvValue = ICETransportPolicy.map((nonOptionalICETransportPolicy) -> new StringType(nonOptionalICETransportPolicy)).orElse(new EmptyType()); + elements.add(new StructElement(ICETransportPolicyFieldID, ICETransportPolicytlvValue)); + + final long metadataOptionsFieldID = 5L; + BaseTLVType metadataOptionstlvValue = metadataOptions.map((nonOptionalmetadataOptions) -> new UIntType(nonOptionalmetadataOptions)).orElse(new EmptyType()); + elements.add(new StructElement(metadataOptionsFieldID, metadataOptionstlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + final long webRTCSessionIDFieldID = 0L; + Integer webRTCSessionID = null; + final long deferredOfferFieldID = 1L; + Boolean deferredOffer = null; + final long videoStreamIDFieldID = 2L; + @Nullable Optional videoStreamID = null; + final long audioStreamIDFieldID = 3L; + @Nullable Optional audioStreamID = null; + for (StructElement element: invokeStructValue.value()) { + if (element.contextTagNum() == webRTCSessionIDFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + webRTCSessionID = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == deferredOfferFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.Boolean) { + BooleanType castingValue = element.value(BooleanType.class); + deferredOffer = castingValue.value(Boolean.class); + } + } else if (element.contextTagNum() == videoStreamIDFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + videoStreamID = Optional.of(castingValue.value(Integer.class)); + } + } else if (element.contextTagNum() == audioStreamIDFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + audioStreamID = Optional.of(castingValue.value(Integer.class)); + } + } + } + callback.onSuccess(webRTCSessionID, deferredOffer, videoStreamID, audioStreamID); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public void provideOffer(ProvideOfferResponseCallback callback, @Nullable Integer webRTCSessionID, String sdp, Integer streamType, @Nullable Optional videoStreamID, @Nullable Optional audioStreamID, Optional> ICEServers, Optional ICETransportPolicy, Optional metadataOptions) { + provideOffer(callback, webRTCSessionID, sdp, streamType, videoStreamID, audioStreamID, ICEServers, ICETransportPolicy, metadataOptions, 0); + } + + public void provideOffer(ProvideOfferResponseCallback callback, @Nullable Integer webRTCSessionID, String sdp, Integer streamType, @Nullable Optional videoStreamID, @Nullable Optional audioStreamID, Optional> ICEServers, Optional ICETransportPolicy, Optional metadataOptions, int timedInvokeTimeoutMs) { + final long commandId = 3L; + + ArrayList elements = new ArrayList<>(); + final long webRTCSessionIDFieldID = 0L; + BaseTLVType webRTCSessionIDtlvValue = webRTCSessionID != null ? new UIntType(webRTCSessionID) : new NullType(); + elements.add(new StructElement(webRTCSessionIDFieldID, webRTCSessionIDtlvValue)); + + final long sdpFieldID = 1L; + BaseTLVType sdptlvValue = new StringType(sdp); + elements.add(new StructElement(sdpFieldID, sdptlvValue)); + + final long streamTypeFieldID = 2L; + BaseTLVType streamTypetlvValue = new UIntType(streamType); + elements.add(new StructElement(streamTypeFieldID, streamTypetlvValue)); + + final long videoStreamIDFieldID = 3L; + BaseTLVType videoStreamIDtlvValue = videoStreamID != null ? videoStreamID.map((nonOptionalvideoStreamID) -> new UIntType(nonOptionalvideoStreamID)).orElse(new EmptyType()) : new NullType(); + elements.add(new StructElement(videoStreamIDFieldID, videoStreamIDtlvValue)); + + final long audioStreamIDFieldID = 4L; + BaseTLVType audioStreamIDtlvValue = audioStreamID != null ? audioStreamID.map((nonOptionalaudioStreamID) -> new UIntType(nonOptionalaudioStreamID)).orElse(new EmptyType()) : new NullType(); + elements.add(new StructElement(audioStreamIDFieldID, audioStreamIDtlvValue)); + + final long ICEServersFieldID = 5L; + BaseTLVType ICEServerstlvValue = ICEServers.map((nonOptionalICEServers) -> ArrayType.generateArrayType(nonOptionalICEServers, (elementnonOptionalICEServers) -> elementnonOptionalICEServers.encodeTlv())).orElse(new EmptyType()); + elements.add(new StructElement(ICEServersFieldID, ICEServerstlvValue)); + + final long ICETransportPolicyFieldID = 6L; + BaseTLVType ICETransportPolicytlvValue = ICETransportPolicy.map((nonOptionalICETransportPolicy) -> new StringType(nonOptionalICETransportPolicy)).orElse(new EmptyType()); + elements.add(new StructElement(ICETransportPolicyFieldID, ICETransportPolicytlvValue)); + + final long metadataOptionsFieldID = 7L; + BaseTLVType metadataOptionstlvValue = metadataOptions.map((nonOptionalmetadataOptions) -> new UIntType(nonOptionalmetadataOptions)).orElse(new EmptyType()); + elements.add(new StructElement(metadataOptionsFieldID, metadataOptionstlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + final long webRTCSessionIDFieldID = 0L; + Integer webRTCSessionID = null; + final long videoStreamIDFieldID = 1L; + Integer videoStreamID = null; + final long audioStreamIDFieldID = 2L; + Integer audioStreamID = null; + for (StructElement element: invokeStructValue.value()) { + if (element.contextTagNum() == webRTCSessionIDFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + webRTCSessionID = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == videoStreamIDFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + videoStreamID = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == audioStreamIDFieldID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + audioStreamID = castingValue.value(Integer.class); + } + } + } + callback.onSuccess(webRTCSessionID, videoStreamID, audioStreamID); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public void provideAnswer(DefaultClusterCallback callback, Integer webRTCSessionID, String sdp) { + provideAnswer(callback, webRTCSessionID, sdp, 0); + } + + public void provideAnswer(DefaultClusterCallback callback, Integer webRTCSessionID, String sdp, int timedInvokeTimeoutMs) { + final long commandId = 5L; + + ArrayList elements = new ArrayList<>(); + final long webRTCSessionIDFieldID = 0L; + BaseTLVType webRTCSessionIDtlvValue = new UIntType(webRTCSessionID); + elements.add(new StructElement(webRTCSessionIDFieldID, webRTCSessionIDtlvValue)); + + final long sdpFieldID = 1L; + BaseTLVType sdptlvValue = new StringType(sdp); + elements.add(new StructElement(sdpFieldID, sdptlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + callback.onSuccess(); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public void provideICECandidate(DefaultClusterCallback callback, Integer webRTCSessionID, String ICECandidate) { + provideICECandidate(callback, webRTCSessionID, ICECandidate, 0); + } + + public void provideICECandidate(DefaultClusterCallback callback, Integer webRTCSessionID, String ICECandidate, int timedInvokeTimeoutMs) { + final long commandId = 6L; + + ArrayList elements = new ArrayList<>(); + final long webRTCSessionIDFieldID = 0L; + BaseTLVType webRTCSessionIDtlvValue = new UIntType(webRTCSessionID); + elements.add(new StructElement(webRTCSessionIDFieldID, webRTCSessionIDtlvValue)); + + final long ICECandidateFieldID = 1L; + BaseTLVType ICECandidatetlvValue = new StringType(ICECandidate); + elements.add(new StructElement(ICECandidateFieldID, ICECandidatetlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + callback.onSuccess(); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public void endSession(DefaultClusterCallback callback, Integer webRTCSessionID, Integer reason) { + endSession(callback, webRTCSessionID, reason, 0); + } + + public void endSession(DefaultClusterCallback callback, Integer webRTCSessionID, Integer reason, int timedInvokeTimeoutMs) { + final long commandId = 7L; + + ArrayList elements = new ArrayList<>(); + final long webRTCSessionIDFieldID = 0L; + BaseTLVType webRTCSessionIDtlvValue = new UIntType(webRTCSessionID); + elements.add(new StructElement(webRTCSessionIDFieldID, webRTCSessionIDtlvValue)); + + final long reasonFieldID = 1L; + BaseTLVType reasontlvValue = new UIntType(reason); + elements.add(new StructElement(reasonFieldID, reasontlvValue)); + + StructType commandArgs = new StructType(elements); + invoke(new InvokeCallbackImpl(callback) { + @Override + public void onResponse(StructType invokeStructValue) { + callback.onSuccess(); + }}, commandId, commandArgs, timedInvokeTimeoutMs); + } + + public interface SolicitOfferResponseCallback extends BaseClusterCallback { + void onSuccess(Integer webRTCSessionID, Boolean deferredOffer, @Nullable Optional videoStreamID, @Nullable Optional audioStreamID); + } + + public interface ProvideOfferResponseCallback extends BaseClusterCallback { + void onSuccess(Integer webRTCSessionID, Integer videoStreamID, Integer audioStreamID); + } + + public interface CurrentSessionsAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface GeneratedCommandListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface AcceptedCommandListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface EventListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public interface AttributeListAttributeCallback extends BaseAttributeCallback { + void onSuccess(List value); + } + + public void readCurrentSessionsAttribute( + CurrentSessionsAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_SESSIONS_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CURRENT_SESSIONS_ATTRIBUTE_ID, true); + } + + public void subscribeCurrentSessionsAttribute( + CurrentSessionsAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CURRENT_SESSIONS_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CURRENT_SESSIONS_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readGeneratedCommandListAttribute( + GeneratedCommandListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeGeneratedCommandListAttribute( + GeneratedCommandListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, GENERATED_COMMAND_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, GENERATED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readAcceptedCommandListAttribute( + AcceptedCommandListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeAcceptedCommandListAttribute( + AcceptedCommandListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ACCEPTED_COMMAND_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readEventListAttribute( + EventListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, EVENT_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeEventListAttribute( + EventListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, EVENT_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, EVENT_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readAttributeListAttribute( + AttributeListAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ATTRIBUTE_LIST_ATTRIBUTE_ID, true); + } + + public void subscribeAttributeListAttribute( + AttributeListAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, ATTRIBUTE_LIST_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + List value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, ATTRIBUTE_LIST_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readFeatureMapAttribute( + LongAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, FEATURE_MAP_ATTRIBUTE_ID, true); + } + + public void subscribeFeatureMapAttribute( + LongAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, FEATURE_MAP_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Long value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, FEATURE_MAP_ATTRIBUTE_ID, minInterval, maxInterval); + } + + public void readClusterRevisionAttribute( + IntegerAttributeCallback callback) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); + + readAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CLUSTER_REVISION_ATTRIBUTE_ID, true); + } + + public void subscribeClusterRevisionAttribute( + IntegerAttributeCallback callback, int minInterval, int maxInterval) { + ChipAttributePath path = ChipAttributePath.newInstance(endpointId, clusterId, CLUSTER_REVISION_ATTRIBUTE_ID); + + subscribeAttribute(new ReportCallbackImpl(callback, path) { + @Override + public void onSuccess(byte[] tlv) { + Integer value = ChipTLVValueDecoder.decodeAttributeValue(path, tlv); + callback.onSuccess(value); + } + }, CLUSTER_REVISION_ATTRIBUTE_ID, minInterval, maxInterval); + } + } + public static class ChimeCluster extends BaseChipCluster { public static final long CLUSTER_ID = 1366L; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java index dc9a94cae7..4c04d0ec0e 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ChipStructs.java @@ -12724,6 +12724,233 @@ public String toString() { return output.toString(); } } +public static class WebRTCTransportProviderClusterICEServerStruct { + public ArrayList urls; + public Optional username; + public Optional credential; + public Optional caid; + private static final long URLS_ID = 1L; + private static final long USERNAME_ID = 2L; + private static final long CREDENTIAL_ID = 3L; + private static final long CAID_ID = 4L; + + public WebRTCTransportProviderClusterICEServerStruct( + ArrayList urls, + Optional username, + Optional credential, + Optional caid + ) { + this.urls = urls; + this.username = username; + this.credential = credential; + this.caid = caid; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(URLS_ID, ArrayType.generateArrayType(urls, (elementurls) -> new StringType(elementurls)))); + values.add(new StructElement(USERNAME_ID, username.map((nonOptionalusername) -> new StringType(nonOptionalusername)).orElse(new EmptyType()))); + values.add(new StructElement(CREDENTIAL_ID, credential.map((nonOptionalcredential) -> new StringType(nonOptionalcredential)).orElse(new EmptyType()))); + values.add(new StructElement(CAID_ID, caid.map((nonOptionalcaid) -> new UIntType(nonOptionalcaid)).orElse(new EmptyType()))); + + return new StructType(values); + } + + public static WebRTCTransportProviderClusterICEServerStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + ArrayList urls = null; + Optional username = Optional.empty(); + Optional credential = Optional.empty(); + Optional caid = Optional.empty(); + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == URLS_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.Array) { + ArrayType castingValue = element.value(ArrayType.class); + urls = castingValue.map((elementcastingValue) -> elementcastingValue.value(String.class)); + } + } else if (element.contextTagNum() == USERNAME_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + username = Optional.of(castingValue.value(String.class)); + } + } else if (element.contextTagNum() == CREDENTIAL_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.String) { + StringType castingValue = element.value(StringType.class); + credential = Optional.of(castingValue.value(String.class)); + } + } else if (element.contextTagNum() == CAID_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + caid = Optional.of(castingValue.value(Integer.class)); + } + } + } + return new WebRTCTransportProviderClusterICEServerStruct( + urls, + username, + credential, + caid + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("WebRTCTransportProviderClusterICEServerStruct {\n"); + output.append("\turls: "); + output.append(urls); + output.append("\n"); + output.append("\tusername: "); + output.append(username); + output.append("\n"); + output.append("\tcredential: "); + output.append(credential); + output.append("\n"); + output.append("\tcaid: "); + output.append(caid); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} +public static class WebRTCTransportProviderClusterWebRTCSessionStruct { + public Integer id; + public Long peerNodeID; + public Integer peerFabricIndex; + public Integer streamType; + public @Nullable Integer videoStreamID; + public @Nullable Integer audioStreamID; + public Integer metadataOptions; + private static final long ID_ID = 1L; + private static final long PEER_NODE_ID_ID = 2L; + private static final long PEER_FABRIC_INDEX_ID = 3L; + private static final long STREAM_TYPE_ID = 4L; + private static final long VIDEO_STREAM_ID_ID = 5L; + private static final long AUDIO_STREAM_ID_ID = 6L; + private static final long METADATA_OPTIONS_ID = 7L; + + public WebRTCTransportProviderClusterWebRTCSessionStruct( + Integer id, + Long peerNodeID, + Integer peerFabricIndex, + Integer streamType, + @Nullable Integer videoStreamID, + @Nullable Integer audioStreamID, + Integer metadataOptions + ) { + this.id = id; + this.peerNodeID = peerNodeID; + this.peerFabricIndex = peerFabricIndex; + this.streamType = streamType; + this.videoStreamID = videoStreamID; + this.audioStreamID = audioStreamID; + this.metadataOptions = metadataOptions; + } + + public StructType encodeTlv() { + ArrayList values = new ArrayList<>(); + values.add(new StructElement(ID_ID, new UIntType(id))); + values.add(new StructElement(PEER_NODE_ID_ID, new UIntType(peerNodeID))); + values.add(new StructElement(PEER_FABRIC_INDEX_ID, new UIntType(peerFabricIndex))); + values.add(new StructElement(STREAM_TYPE_ID, new UIntType(streamType))); + values.add(new StructElement(VIDEO_STREAM_ID_ID, videoStreamID != null ? new UIntType(videoStreamID) : new NullType())); + values.add(new StructElement(AUDIO_STREAM_ID_ID, audioStreamID != null ? new UIntType(audioStreamID) : new NullType())); + values.add(new StructElement(METADATA_OPTIONS_ID, new UIntType(metadataOptions))); + + return new StructType(values); + } + + public static WebRTCTransportProviderClusterWebRTCSessionStruct decodeTlv(BaseTLVType tlvValue) { + if (tlvValue == null || tlvValue.type() != TLVType.Struct) { + return null; + } + Integer id = null; + Long peerNodeID = null; + Integer peerFabricIndex = null; + Integer streamType = null; + @Nullable Integer videoStreamID = null; + @Nullable Integer audioStreamID = null; + Integer metadataOptions = null; + for (StructElement element: ((StructType)tlvValue).value()) { + if (element.contextTagNum() == ID_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + id = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == PEER_NODE_ID_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + peerNodeID = castingValue.value(Long.class); + } + } else if (element.contextTagNum() == PEER_FABRIC_INDEX_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + peerFabricIndex = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == STREAM_TYPE_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + streamType = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == VIDEO_STREAM_ID_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + videoStreamID = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == AUDIO_STREAM_ID_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + audioStreamID = castingValue.value(Integer.class); + } + } else if (element.contextTagNum() == METADATA_OPTIONS_ID) { + if (element.value(BaseTLVType.class).type() == TLVType.UInt) { + UIntType castingValue = element.value(UIntType.class); + metadataOptions = castingValue.value(Integer.class); + } + } + } + return new WebRTCTransportProviderClusterWebRTCSessionStruct( + id, + peerNodeID, + peerFabricIndex, + streamType, + videoStreamID, + audioStreamID, + metadataOptions + ); + } + + @Override + public String toString() { + StringBuilder output = new StringBuilder(); + output.append("WebRTCTransportProviderClusterWebRTCSessionStruct {\n"); + output.append("\tid: "); + output.append(id); + output.append("\n"); + output.append("\tpeerNodeID: "); + output.append(peerNodeID); + output.append("\n"); + output.append("\tpeerFabricIndex: "); + output.append(peerFabricIndex); + output.append("\n"); + output.append("\tstreamType: "); + output.append(streamType); + output.append("\n"); + output.append("\tvideoStreamID: "); + output.append(videoStreamID); + output.append("\n"); + output.append("\taudioStreamID: "); + output.append(audioStreamID); + output.append("\n"); + output.append("\tmetadataOptions: "); + output.append(metadataOptions); + output.append("\n"); + output.append("}\n"); + return output.toString(); + } +} public static class ChimeClusterChimeSoundStruct { public Integer chimeID; public String name; diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java index 56ed2c4629..af30b0eb34 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterIDMapping.java @@ -379,6 +379,9 @@ public static BaseCluster getCluster(long clusterId) { if (clusterId == ContentAppObserver.ID) { return new ContentAppObserver(); } + if (clusterId == WebRTCTransportProvider.ID) { + return new WebRTCTransportProvider(); + } if (clusterId == Chime.ID) { return new Chime(); } @@ -16881,6 +16884,197 @@ public long getCommandID(String name) throws IllegalArgumentException { return Command.valueOf(name).getID(); } } + public static class WebRTCTransportProvider implements BaseCluster { + public static final long ID = 1363L; + public long getID() { + return ID; + } + + public enum Attribute { + CurrentSessions(0L), + GeneratedCommandList(65528L), + AcceptedCommandList(65529L), + EventList(65530L), + AttributeList(65531L), + FeatureMap(65532L), + ClusterRevision(65533L),; + private final long id; + Attribute(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Attribute value(long id) throws NoSuchFieldError { + for (Attribute attribute : Attribute.values()) { + if (attribute.getID() == id) { + return attribute; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Event {; + private final long id; + Event(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Event value(long id) throws NoSuchFieldError { + for (Event event : Event.values()) { + if (event.getID() == id) { + return event; + } + } + throw new NoSuchFieldError(); + } + } + + public enum Command { + SolicitOffer(1L), + ProvideOffer(3L), + ProvideAnswer(5L), + ProvideICECandidate(6L), + EndSession(7L),; + private final long id; + Command(long id) { + this.id = id; + } + + public long getID() { + return id; + } + + public static Command value(long id) throws NoSuchFieldError { + for (Command command : Command.values()) { + if (command.getID() == id) { + return command; + } + } + throw new NoSuchFieldError(); + } + }public enum SolicitOfferCommandField {StreamType(0),VideoStreamID(1),AudioStreamID(2),ICEServers(3),ICETransportPolicy(4),MetadataOptions(5),; + private final int id; + SolicitOfferCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static SolicitOfferCommandField value(int id) throws NoSuchFieldError { + for (SolicitOfferCommandField field : SolicitOfferCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } + }public enum ProvideOfferCommandField {WebRTCSessionID(0),Sdp(1),StreamType(2),VideoStreamID(3),AudioStreamID(4),ICEServers(5),ICETransportPolicy(6),MetadataOptions(7),; + private final int id; + ProvideOfferCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static ProvideOfferCommandField value(int id) throws NoSuchFieldError { + for (ProvideOfferCommandField field : ProvideOfferCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } + }public enum ProvideAnswerCommandField {WebRTCSessionID(0),Sdp(1),; + private final int id; + ProvideAnswerCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static ProvideAnswerCommandField value(int id) throws NoSuchFieldError { + for (ProvideAnswerCommandField field : ProvideAnswerCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } + }public enum ProvideICECandidateCommandField {WebRTCSessionID(0),ICECandidate(1),; + private final int id; + ProvideICECandidateCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static ProvideICECandidateCommandField value(int id) throws NoSuchFieldError { + for (ProvideICECandidateCommandField field : ProvideICECandidateCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } + }public enum EndSessionCommandField {WebRTCSessionID(0),Reason(1),; + private final int id; + EndSessionCommandField(int id) { + this.id = id; + } + + public int getID() { + return id; + } + public static EndSessionCommandField value(int id) throws NoSuchFieldError { + for (EndSessionCommandField field : EndSessionCommandField.values()) { + if (field.getID() == id) { + return field; + } + } + throw new NoSuchFieldError(); + } + }@Override + public String getAttributeName(long id) throws NoSuchFieldError { + return Attribute.value(id).toString(); + } + + @Override + public String getEventName(long id) throws NoSuchFieldError { + return Event.value(id).toString(); + } + + @Override + public String getCommandName(long id) throws NoSuchFieldError { + return Command.value(id).toString(); + } + + @Override + public long getAttributeID(String name) throws IllegalArgumentException { + return Attribute.valueOf(name).getID(); + } + + @Override + public long getEventID(String name) throws IllegalArgumentException { + return Event.valueOf(name).getID(); + } + + @Override + public long getCommandID(String name) throws IllegalArgumentException { + return Command.valueOf(name).getID(); + } + } public static class Chime implements BaseCluster { public static final long ID = 1366L; public long getID() { diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java index 3025c26852..295ada1c57 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterInfoMapping.java @@ -19994,6 +19994,165 @@ public void onError(Exception ex) { } } + + public static class DelegatedWebRTCTransportProviderClusterSolicitOfferResponseCallback implements ChipClusters.WebRTCTransportProviderCluster.SolicitOfferResponseCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(Integer webRTCSessionID, Boolean deferredOffer, @Nullable Optional videoStreamID, @Nullable Optional audioStreamID) { + Map responseValues = new LinkedHashMap<>(); + + CommandResponseInfo webRTCSessionIDResponseValue = new CommandResponseInfo("webRTCSessionID", "Integer"); + responseValues.put(webRTCSessionIDResponseValue, webRTCSessionID); + CommandResponseInfo deferredOfferResponseValue = new CommandResponseInfo("deferredOffer", "Boolean"); + responseValues.put(deferredOfferResponseValue, deferredOffer); + CommandResponseInfo videoStreamIDResponseValue = new CommandResponseInfo("videoStreamID", "Optional"); + responseValues.put(videoStreamIDResponseValue, videoStreamID); + CommandResponseInfo audioStreamIDResponseValue = new CommandResponseInfo("audioStreamID", "Optional"); + responseValues.put(audioStreamIDResponseValue, audioStreamID); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception error) { + callback.onFailure(error); + } + } + + public static class DelegatedWebRTCTransportProviderClusterProvideOfferResponseCallback implements ChipClusters.WebRTCTransportProviderCluster.ProvideOfferResponseCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(Integer webRTCSessionID, Integer videoStreamID, Integer audioStreamID) { + Map responseValues = new LinkedHashMap<>(); + + CommandResponseInfo webRTCSessionIDResponseValue = new CommandResponseInfo("webRTCSessionID", "Integer"); + responseValues.put(webRTCSessionIDResponseValue, webRTCSessionID); + CommandResponseInfo videoStreamIDResponseValue = new CommandResponseInfo("videoStreamID", "Integer"); + responseValues.put(videoStreamIDResponseValue, videoStreamID); + CommandResponseInfo audioStreamIDResponseValue = new CommandResponseInfo("audioStreamID", "Integer"); + responseValues.put(audioStreamIDResponseValue, audioStreamID); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception error) { + callback.onFailure(error); + } + } + public static class DelegatedWebRTCTransportProviderClusterCurrentSessionsAttributeCallback implements ChipClusters.WebRTCTransportProviderCluster.CurrentSessionsAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedWebRTCTransportProviderClusterGeneratedCommandListAttributeCallback implements ChipClusters.WebRTCTransportProviderCluster.GeneratedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedWebRTCTransportProviderClusterAcceptedCommandListAttributeCallback implements ChipClusters.WebRTCTransportProviderCluster.AcceptedCommandListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedWebRTCTransportProviderClusterEventListAttributeCallback implements ChipClusters.WebRTCTransportProviderCluster.EventListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + + public static class DelegatedWebRTCTransportProviderClusterAttributeListAttributeCallback implements ChipClusters.WebRTCTransportProviderCluster.AttributeListAttributeCallback, DelegatedClusterCallback { + private ClusterCommandCallback callback; + @Override + public void setCallbackDelegate(ClusterCommandCallback callback) { + this.callback = callback; + } + + @Override + public void onSuccess(List valueList) { + Map responseValues = new LinkedHashMap<>(); + CommandResponseInfo commandResponseInfo = new CommandResponseInfo("valueList", "List"); + responseValues.put(commandResponseInfo, valueList); + callback.onSuccess(responseValues); + } + + @Override + public void onError(Exception ex) { + callback.onFailure(ex); + } + } + public static class DelegatedChimeClusterInstalledChimeSoundsAttributeCallback implements ChipClusters.ChimeCluster.InstalledChimeSoundsAttributeCallback, DelegatedClusterCallback { private ClusterCommandCallback callback; @Override @@ -22435,6 +22594,10 @@ public Map initializeClusterMap() { (ptr, endpointId) -> new ChipClusters.ContentAppObserverCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("contentAppObserver", contentAppObserverClusterInfo); + ClusterInfo webRTCTransportProviderClusterInfo = new ClusterInfo( + (ptr, endpointId) -> new ChipClusters.WebRTCTransportProviderCluster(ptr, endpointId), new HashMap<>()); + clusterMap.put("webRTCTransportProvider", webRTCTransportProviderClusterInfo); + ClusterInfo chimeClusterInfo = new ClusterInfo( (ptr, endpointId) -> new ChipClusters.ChimeCluster(ptr, endpointId), new HashMap<>()); clusterMap.put("chime", chimeClusterInfo); @@ -22580,6 +22743,7 @@ public void combineCommand(Map destination, Map> getCommandMap() { commandMap.put("contentAppObserver", contentAppObserverClusterInteractionInfoMap); + Map webRTCTransportProviderClusterInteractionInfoMap = new LinkedHashMap<>(); + + Map webRTCTransportProvidersolicitOfferCommandParams = new LinkedHashMap(); + + CommandParameterInfo webRTCTransportProvidersolicitOfferstreamTypeCommandParameterInfo = new CommandParameterInfo("streamType", Integer.class, Integer.class); + webRTCTransportProvidersolicitOfferCommandParams.put("streamType",webRTCTransportProvidersolicitOfferstreamTypeCommandParameterInfo); + + CommandParameterInfo webRTCTransportProvidersolicitOffervideoStreamIDCommandParameterInfo = new CommandParameterInfo("videoStreamID", Optional.class, Integer.class); + webRTCTransportProvidersolicitOfferCommandParams.put("videoStreamID",webRTCTransportProvidersolicitOffervideoStreamIDCommandParameterInfo); + + CommandParameterInfo webRTCTransportProvidersolicitOfferaudioStreamIDCommandParameterInfo = new CommandParameterInfo("audioStreamID", Optional.class, Integer.class); + webRTCTransportProvidersolicitOfferCommandParams.put("audioStreamID",webRTCTransportProvidersolicitOfferaudioStreamIDCommandParameterInfo); + + + CommandParameterInfo webRTCTransportProvidersolicitOfferICETransportPolicyCommandParameterInfo = new CommandParameterInfo("ICETransportPolicy", Optional.class, String.class); + webRTCTransportProvidersolicitOfferCommandParams.put("ICETransportPolicy",webRTCTransportProvidersolicitOfferICETransportPolicyCommandParameterInfo); + + CommandParameterInfo webRTCTransportProvidersolicitOffermetadataOptionsCommandParameterInfo = new CommandParameterInfo("metadataOptions", Optional.class, Integer.class); + webRTCTransportProvidersolicitOfferCommandParams.put("metadataOptions",webRTCTransportProvidersolicitOffermetadataOptionsCommandParameterInfo); + InteractionInfo webRTCTransportProvidersolicitOfferInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WebRTCTransportProviderCluster) cluster) + .solicitOffer((ChipClusters.WebRTCTransportProviderCluster.SolicitOfferResponseCallback) callback + , (Integer) + commandArguments.get("streamType") + + , (Optional) + commandArguments.get("videoStreamID") + + , (Optional) + commandArguments.get("audioStreamID") + + , (Optional>) + commandArguments.get("ICEServers") + + , (Optional) + commandArguments.get("ICETransportPolicy") + + , (Optional) + commandArguments.get("metadataOptions") + + ); + }, + () -> new DelegatedWebRTCTransportProviderClusterSolicitOfferResponseCallback(), + webRTCTransportProvidersolicitOfferCommandParams + ); + webRTCTransportProviderClusterInteractionInfoMap.put("solicitOffer", webRTCTransportProvidersolicitOfferInteractionInfo); + + Map webRTCTransportProviderprovideOfferCommandParams = new LinkedHashMap(); + + CommandParameterInfo webRTCTransportProviderprovideOfferwebRTCSessionIDCommandParameterInfo = new CommandParameterInfo("webRTCSessionID", Integer.class, Integer.class); + webRTCTransportProviderprovideOfferCommandParams.put("webRTCSessionID",webRTCTransportProviderprovideOfferwebRTCSessionIDCommandParameterInfo); + + CommandParameterInfo webRTCTransportProviderprovideOffersdpCommandParameterInfo = new CommandParameterInfo("sdp", String.class, String.class); + webRTCTransportProviderprovideOfferCommandParams.put("sdp",webRTCTransportProviderprovideOffersdpCommandParameterInfo); + + CommandParameterInfo webRTCTransportProviderprovideOfferstreamTypeCommandParameterInfo = new CommandParameterInfo("streamType", Integer.class, Integer.class); + webRTCTransportProviderprovideOfferCommandParams.put("streamType",webRTCTransportProviderprovideOfferstreamTypeCommandParameterInfo); + + CommandParameterInfo webRTCTransportProviderprovideOffervideoStreamIDCommandParameterInfo = new CommandParameterInfo("videoStreamID", Optional.class, Integer.class); + webRTCTransportProviderprovideOfferCommandParams.put("videoStreamID",webRTCTransportProviderprovideOffervideoStreamIDCommandParameterInfo); + + CommandParameterInfo webRTCTransportProviderprovideOfferaudioStreamIDCommandParameterInfo = new CommandParameterInfo("audioStreamID", Optional.class, Integer.class); + webRTCTransportProviderprovideOfferCommandParams.put("audioStreamID",webRTCTransportProviderprovideOfferaudioStreamIDCommandParameterInfo); + + + CommandParameterInfo webRTCTransportProviderprovideOfferICETransportPolicyCommandParameterInfo = new CommandParameterInfo("ICETransportPolicy", Optional.class, String.class); + webRTCTransportProviderprovideOfferCommandParams.put("ICETransportPolicy",webRTCTransportProviderprovideOfferICETransportPolicyCommandParameterInfo); + + CommandParameterInfo webRTCTransportProviderprovideOffermetadataOptionsCommandParameterInfo = new CommandParameterInfo("metadataOptions", Optional.class, Integer.class); + webRTCTransportProviderprovideOfferCommandParams.put("metadataOptions",webRTCTransportProviderprovideOffermetadataOptionsCommandParameterInfo); + InteractionInfo webRTCTransportProviderprovideOfferInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WebRTCTransportProviderCluster) cluster) + .provideOffer((ChipClusters.WebRTCTransportProviderCluster.ProvideOfferResponseCallback) callback + , (Integer) + commandArguments.get("webRTCSessionID") + + , (String) + commandArguments.get("sdp") + + , (Integer) + commandArguments.get("streamType") + + , (Optional) + commandArguments.get("videoStreamID") + + , (Optional) + commandArguments.get("audioStreamID") + + , (Optional>) + commandArguments.get("ICEServers") + + , (Optional) + commandArguments.get("ICETransportPolicy") + + , (Optional) + commandArguments.get("metadataOptions") + + ); + }, + () -> new DelegatedWebRTCTransportProviderClusterProvideOfferResponseCallback(), + webRTCTransportProviderprovideOfferCommandParams + ); + webRTCTransportProviderClusterInteractionInfoMap.put("provideOffer", webRTCTransportProviderprovideOfferInteractionInfo); + + Map webRTCTransportProviderprovideAnswerCommandParams = new LinkedHashMap(); + + CommandParameterInfo webRTCTransportProviderprovideAnswerwebRTCSessionIDCommandParameterInfo = new CommandParameterInfo("webRTCSessionID", Integer.class, Integer.class); + webRTCTransportProviderprovideAnswerCommandParams.put("webRTCSessionID",webRTCTransportProviderprovideAnswerwebRTCSessionIDCommandParameterInfo); + + CommandParameterInfo webRTCTransportProviderprovideAnswersdpCommandParameterInfo = new CommandParameterInfo("sdp", String.class, String.class); + webRTCTransportProviderprovideAnswerCommandParams.put("sdp",webRTCTransportProviderprovideAnswersdpCommandParameterInfo); + InteractionInfo webRTCTransportProviderprovideAnswerInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WebRTCTransportProviderCluster) cluster) + .provideAnswer((DefaultClusterCallback) callback + , (Integer) + commandArguments.get("webRTCSessionID") + , (String) + commandArguments.get("sdp") + ); + }, + () -> new DelegatedDefaultClusterCallback(), + webRTCTransportProviderprovideAnswerCommandParams + ); + webRTCTransportProviderClusterInteractionInfoMap.put("provideAnswer", webRTCTransportProviderprovideAnswerInteractionInfo); + + Map webRTCTransportProviderprovideICECandidateCommandParams = new LinkedHashMap(); + + CommandParameterInfo webRTCTransportProviderprovideICECandidatewebRTCSessionIDCommandParameterInfo = new CommandParameterInfo("webRTCSessionID", Integer.class, Integer.class); + webRTCTransportProviderprovideICECandidateCommandParams.put("webRTCSessionID",webRTCTransportProviderprovideICECandidatewebRTCSessionIDCommandParameterInfo); + + CommandParameterInfo webRTCTransportProviderprovideICECandidateICECandidateCommandParameterInfo = new CommandParameterInfo("ICECandidate", String.class, String.class); + webRTCTransportProviderprovideICECandidateCommandParams.put("ICECandidate",webRTCTransportProviderprovideICECandidateICECandidateCommandParameterInfo); + InteractionInfo webRTCTransportProviderprovideICECandidateInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WebRTCTransportProviderCluster) cluster) + .provideICECandidate((DefaultClusterCallback) callback + , (Integer) + commandArguments.get("webRTCSessionID") + , (String) + commandArguments.get("ICECandidate") + ); + }, + () -> new DelegatedDefaultClusterCallback(), + webRTCTransportProviderprovideICECandidateCommandParams + ); + webRTCTransportProviderClusterInteractionInfoMap.put("provideICECandidate", webRTCTransportProviderprovideICECandidateInteractionInfo); + + Map webRTCTransportProviderendSessionCommandParams = new LinkedHashMap(); + + CommandParameterInfo webRTCTransportProviderendSessionwebRTCSessionIDCommandParameterInfo = new CommandParameterInfo("webRTCSessionID", Integer.class, Integer.class); + webRTCTransportProviderendSessionCommandParams.put("webRTCSessionID",webRTCTransportProviderendSessionwebRTCSessionIDCommandParameterInfo); + + CommandParameterInfo webRTCTransportProviderendSessionreasonCommandParameterInfo = new CommandParameterInfo("reason", Integer.class, Integer.class); + webRTCTransportProviderendSessionCommandParams.put("reason",webRTCTransportProviderendSessionreasonCommandParameterInfo); + InteractionInfo webRTCTransportProviderendSessionInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WebRTCTransportProviderCluster) cluster) + .endSession((DefaultClusterCallback) callback + , (Integer) + commandArguments.get("webRTCSessionID") + , (Integer) + commandArguments.get("reason") + ); + }, + () -> new DelegatedDefaultClusterCallback(), + webRTCTransportProviderendSessionCommandParams + ); + webRTCTransportProviderClusterInteractionInfoMap.put("endSession", webRTCTransportProviderendSessionInteractionInfo); + + commandMap.put("webRTCTransportProvider", webRTCTransportProviderClusterInteractionInfoMap); + Map chimeClusterInteractionInfoMap = new LinkedHashMap<>(); Map chimeplayChimeSoundCommandParams = new LinkedHashMap(); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java index b4ef81d615..05036e0391 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterReadMapping.java @@ -18236,6 +18236,87 @@ private static Map readContentAppObserverInteractionInf return result; } + private static Map readWebRTCTransportProviderInteractionInfo() { + Map result = new LinkedHashMap<>();Map readWebRTCTransportProviderCurrentSessionsCommandParams = new LinkedHashMap(); + InteractionInfo readWebRTCTransportProviderCurrentSessionsAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WebRTCTransportProviderCluster) cluster).readCurrentSessionsAttribute( + (ChipClusters.WebRTCTransportProviderCluster.CurrentSessionsAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWebRTCTransportProviderClusterCurrentSessionsAttributeCallback(), + readWebRTCTransportProviderCurrentSessionsCommandParams + ); + result.put("readCurrentSessionsAttribute", readWebRTCTransportProviderCurrentSessionsAttributeInteractionInfo); + Map readWebRTCTransportProviderGeneratedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readWebRTCTransportProviderGeneratedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WebRTCTransportProviderCluster) cluster).readGeneratedCommandListAttribute( + (ChipClusters.WebRTCTransportProviderCluster.GeneratedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWebRTCTransportProviderClusterGeneratedCommandListAttributeCallback(), + readWebRTCTransportProviderGeneratedCommandListCommandParams + ); + result.put("readGeneratedCommandListAttribute", readWebRTCTransportProviderGeneratedCommandListAttributeInteractionInfo); + Map readWebRTCTransportProviderAcceptedCommandListCommandParams = new LinkedHashMap(); + InteractionInfo readWebRTCTransportProviderAcceptedCommandListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WebRTCTransportProviderCluster) cluster).readAcceptedCommandListAttribute( + (ChipClusters.WebRTCTransportProviderCluster.AcceptedCommandListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWebRTCTransportProviderClusterAcceptedCommandListAttributeCallback(), + readWebRTCTransportProviderAcceptedCommandListCommandParams + ); + result.put("readAcceptedCommandListAttribute", readWebRTCTransportProviderAcceptedCommandListAttributeInteractionInfo); + Map readWebRTCTransportProviderEventListCommandParams = new LinkedHashMap(); + InteractionInfo readWebRTCTransportProviderEventListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WebRTCTransportProviderCluster) cluster).readEventListAttribute( + (ChipClusters.WebRTCTransportProviderCluster.EventListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWebRTCTransportProviderClusterEventListAttributeCallback(), + readWebRTCTransportProviderEventListCommandParams + ); + result.put("readEventListAttribute", readWebRTCTransportProviderEventListAttributeInteractionInfo); + Map readWebRTCTransportProviderAttributeListCommandParams = new LinkedHashMap(); + InteractionInfo readWebRTCTransportProviderAttributeListAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WebRTCTransportProviderCluster) cluster).readAttributeListAttribute( + (ChipClusters.WebRTCTransportProviderCluster.AttributeListAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedWebRTCTransportProviderClusterAttributeListAttributeCallback(), + readWebRTCTransportProviderAttributeListCommandParams + ); + result.put("readAttributeListAttribute", readWebRTCTransportProviderAttributeListAttributeInteractionInfo); + Map readWebRTCTransportProviderFeatureMapCommandParams = new LinkedHashMap(); + InteractionInfo readWebRTCTransportProviderFeatureMapAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WebRTCTransportProviderCluster) cluster).readFeatureMapAttribute( + (ChipClusters.LongAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedLongAttributeCallback(), + readWebRTCTransportProviderFeatureMapCommandParams + ); + result.put("readFeatureMapAttribute", readWebRTCTransportProviderFeatureMapAttributeInteractionInfo); + Map readWebRTCTransportProviderClusterRevisionCommandParams = new LinkedHashMap(); + InteractionInfo readWebRTCTransportProviderClusterRevisionAttributeInteractionInfo = new InteractionInfo( + (cluster, callback, commandArguments) -> { + ((ChipClusters.WebRTCTransportProviderCluster) cluster).readClusterRevisionAttribute( + (ChipClusters.IntegerAttributeCallback) callback + ); + }, + () -> new ClusterInfoMapping.DelegatedIntegerAttributeCallback(), + readWebRTCTransportProviderClusterRevisionCommandParams + ); + result.put("readClusterRevisionAttribute", readWebRTCTransportProviderClusterRevisionAttributeInteractionInfo); + + return result; + } private static Map readChimeInteractionInfo() { Map result = new LinkedHashMap<>();Map readChimeInstalledChimeSoundsCommandParams = new LinkedHashMap(); InteractionInfo readChimeInstalledChimeSoundsAttributeInteractionInfo = new InteractionInfo( @@ -19789,6 +19870,7 @@ public Map> getReadAttributeMap() { put("accountLogin", readAccountLoginInteractionInfo()); put("contentControl", readContentControlInteractionInfo()); put("contentAppObserver", readContentAppObserverInteractionInfo()); + put("webRTCTransportProvider", readWebRTCTransportProviderInteractionInfo()); put("chime", readChimeInteractionInfo()); put("ecosystemInformation", readEcosystemInformationInteractionInfo()); put("commissionerControl", readCommissionerControlInteractionInfo()); diff --git a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java index fce8cee559..0d561c36e7 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java +++ b/src/controller/java/generated/java/chip/devicecontroller/ClusterWriteMapping.java @@ -3472,6 +3472,8 @@ public Map> getWriteAttributeMap() { writeAttributeMap.put("contentControl", writeContentControlInteractionInfo); Map writeContentAppObserverInteractionInfo = new LinkedHashMap<>(); writeAttributeMap.put("contentAppObserver", writeContentAppObserverInteractionInfo); + Map writeWebRTCTransportProviderInteractionInfo = new LinkedHashMap<>(); + writeAttributeMap.put("webRTCTransportProvider", writeWebRTCTransportProviderInteractionInfo); Map writeChimeInteractionInfo = new LinkedHashMap<>(); Map writeChimeActiveChimeIDCommandParams = new LinkedHashMap(); CommandParameterInfo chimeactiveChimeIDCommandParameterInfo = diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni index 397c26ee3d..6187cfbe7c 100644 --- a/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/files.gni @@ -160,6 +160,8 @@ structs_sources = [ "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WaterHeaterManagementClusterWaterHeaterBoostInfoStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt", "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WaterHeaterModeClusterModeTagStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WebRTCTransportProviderClusterICEServerStruct.kt", + "${chip_root}/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WebRTCTransportProviderClusterWebRTCSessionStruct.kt", ] eventstructs_sources = [ diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WebRTCTransportProviderClusterICEServerStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WebRTCTransportProviderClusterICEServerStruct.kt new file mode 100644 index 0000000000..e98bab2183 --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WebRTCTransportProviderClusterICEServerStruct.kt @@ -0,0 +1,106 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ +package chip.devicecontroller.cluster.structs + +import chip.devicecontroller.cluster.* +import java.util.Optional +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class WebRTCTransportProviderClusterICEServerStruct( + val urls: List, + val username: Optional, + val credential: Optional, + val caid: Optional, +) { + override fun toString(): String = buildString { + append("WebRTCTransportProviderClusterICEServerStruct {\n") + append("\turls : $urls\n") + append("\tusername : $username\n") + append("\tcredential : $credential\n") + append("\tcaid : $caid\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + startArray(ContextSpecificTag(TAG_URLS)) + for (item in urls.iterator()) { + put(AnonymousTag, item) + } + endArray() + if (username.isPresent) { + val optusername = username.get() + put(ContextSpecificTag(TAG_USERNAME), optusername) + } + if (credential.isPresent) { + val optcredential = credential.get() + put(ContextSpecificTag(TAG_CREDENTIAL), optcredential) + } + if (caid.isPresent) { + val optcaid = caid.get() + put(ContextSpecificTag(TAG_CAID), optcaid) + } + endStructure() + } + } + + companion object { + private const val TAG_URLS = 1 + private const val TAG_USERNAME = 2 + private const val TAG_CREDENTIAL = 3 + private const val TAG_CAID = 4 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): WebRTCTransportProviderClusterICEServerStruct { + tlvReader.enterStructure(tlvTag) + val urls = + buildList { + tlvReader.enterArray(ContextSpecificTag(TAG_URLS)) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getString(AnonymousTag)) + } + tlvReader.exitContainer() + } + val username = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_USERNAME))) { + Optional.of(tlvReader.getString(ContextSpecificTag(TAG_USERNAME))) + } else { + Optional.empty() + } + val credential = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_CREDENTIAL))) { + Optional.of(tlvReader.getString(ContextSpecificTag(TAG_CREDENTIAL))) + } else { + Optional.empty() + } + val caid = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_CAID))) { + Optional.of(tlvReader.getUInt(ContextSpecificTag(TAG_CAID))) + } else { + Optional.empty() + } + + tlvReader.exitContainer() + + return WebRTCTransportProviderClusterICEServerStruct(urls, username, credential, caid) + } + } +} diff --git a/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WebRTCTransportProviderClusterWebRTCSessionStruct.kt b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WebRTCTransportProviderClusterWebRTCSessionStruct.kt new file mode 100644 index 0000000000..645c9a779b --- /dev/null +++ b/src/controller/java/generated/java/chip/devicecontroller/cluster/structs/WebRTCTransportProviderClusterWebRTCSessionStruct.kt @@ -0,0 +1,115 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ +package chip.devicecontroller.cluster.structs + +import chip.devicecontroller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class WebRTCTransportProviderClusterWebRTCSessionStruct( + val id: UInt, + val peerNodeID: ULong, + val peerFabricIndex: UInt, + val streamType: UInt, + val videoStreamID: UInt?, + val audioStreamID: UInt?, + val metadataOptions: UInt, +) { + override fun toString(): String = buildString { + append("WebRTCTransportProviderClusterWebRTCSessionStruct {\n") + append("\tid : $id\n") + append("\tpeerNodeID : $peerNodeID\n") + append("\tpeerFabricIndex : $peerFabricIndex\n") + append("\tstreamType : $streamType\n") + append("\tvideoStreamID : $videoStreamID\n") + append("\taudioStreamID : $audioStreamID\n") + append("\tmetadataOptions : $metadataOptions\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_ID), id) + put(ContextSpecificTag(TAG_PEER_NODE_ID), peerNodeID) + put(ContextSpecificTag(TAG_PEER_FABRIC_INDEX), peerFabricIndex) + put(ContextSpecificTag(TAG_STREAM_TYPE), streamType) + if (videoStreamID != null) { + put(ContextSpecificTag(TAG_VIDEO_STREAM_ID), videoStreamID) + } else { + putNull(ContextSpecificTag(TAG_VIDEO_STREAM_ID)) + } + if (audioStreamID != null) { + put(ContextSpecificTag(TAG_AUDIO_STREAM_ID), audioStreamID) + } else { + putNull(ContextSpecificTag(TAG_AUDIO_STREAM_ID)) + } + put(ContextSpecificTag(TAG_METADATA_OPTIONS), metadataOptions) + endStructure() + } + } + + companion object { + private const val TAG_ID = 1 + private const val TAG_PEER_NODE_ID = 2 + private const val TAG_PEER_FABRIC_INDEX = 3 + private const val TAG_STREAM_TYPE = 4 + private const val TAG_VIDEO_STREAM_ID = 5 + private const val TAG_AUDIO_STREAM_ID = 6 + private const val TAG_METADATA_OPTIONS = 7 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): WebRTCTransportProviderClusterWebRTCSessionStruct { + tlvReader.enterStructure(tlvTag) + val id = tlvReader.getUInt(ContextSpecificTag(TAG_ID)) + val peerNodeID = tlvReader.getULong(ContextSpecificTag(TAG_PEER_NODE_ID)) + val peerFabricIndex = tlvReader.getUInt(ContextSpecificTag(TAG_PEER_FABRIC_INDEX)) + val streamType = tlvReader.getUInt(ContextSpecificTag(TAG_STREAM_TYPE)) + val videoStreamID = + if (!tlvReader.isNull()) { + tlvReader.getUInt(ContextSpecificTag(TAG_VIDEO_STREAM_ID)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_VIDEO_STREAM_ID)) + null + } + val audioStreamID = + if (!tlvReader.isNull()) { + tlvReader.getUInt(ContextSpecificTag(TAG_AUDIO_STREAM_ID)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_AUDIO_STREAM_ID)) + null + } + val metadataOptions = tlvReader.getUInt(ContextSpecificTag(TAG_METADATA_OPTIONS)) + + tlvReader.exitContainer() + + return WebRTCTransportProviderClusterWebRTCSessionStruct( + id, + peerNodeID, + peerFabricIndex, + streamType, + videoStreamID, + audioStreamID, + metadataOptions, + ) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/clusters/WebRTCTransportProviderCluster.kt b/src/controller/java/generated/java/matter/controller/cluster/clusters/WebRTCTransportProviderCluster.kt new file mode 100644 index 0000000000..6fee15959f --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/clusters/WebRTCTransportProviderCluster.kt @@ -0,0 +1,1097 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ + +package matter.controller.cluster.clusters + +import java.time.Duration +import java.util.logging.Level +import java.util.logging.Logger +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.transform +import matter.controller.InvokeRequest +import matter.controller.InvokeResponse +import matter.controller.MatterController +import matter.controller.ReadData +import matter.controller.ReadRequest +import matter.controller.SubscribeRequest +import matter.controller.SubscriptionState +import matter.controller.UIntSubscriptionState +import matter.controller.UShortSubscriptionState +import matter.controller.cluster.structs.* +import matter.controller.model.AttributePath +import matter.controller.model.CommandPath +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class WebRTCTransportProviderCluster( + private val controller: MatterController, + private val endpointId: UShort, +) { + class SolicitOfferResponse( + val webRTCSessionID: UShort, + val deferredOffer: Boolean, + val videoStreamID: UShort?, + val audioStreamID: UShort?, + ) + + class ProvideOfferResponse( + val webRTCSessionID: UShort, + val videoStreamID: UShort, + val audioStreamID: UShort, + ) + + class CurrentSessionsAttribute( + val value: List + ) + + sealed class CurrentSessionsAttributeSubscriptionState { + data class Success(val value: List) : + CurrentSessionsAttributeSubscriptionState() + + data class Error(val exception: Exception) : CurrentSessionsAttributeSubscriptionState() + + object SubscriptionEstablished : CurrentSessionsAttributeSubscriptionState() + } + + class GeneratedCommandListAttribute(val value: List) + + sealed class GeneratedCommandListAttributeSubscriptionState { + data class Success(val value: List) : GeneratedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : GeneratedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : GeneratedCommandListAttributeSubscriptionState() + } + + class AcceptedCommandListAttribute(val value: List) + + sealed class AcceptedCommandListAttributeSubscriptionState { + data class Success(val value: List) : AcceptedCommandListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AcceptedCommandListAttributeSubscriptionState() + + object SubscriptionEstablished : AcceptedCommandListAttributeSubscriptionState() + } + + class EventListAttribute(val value: List) + + sealed class EventListAttributeSubscriptionState { + data class Success(val value: List) : EventListAttributeSubscriptionState() + + data class Error(val exception: Exception) : EventListAttributeSubscriptionState() + + object SubscriptionEstablished : EventListAttributeSubscriptionState() + } + + class AttributeListAttribute(val value: List) + + sealed class AttributeListAttributeSubscriptionState { + data class Success(val value: List) : AttributeListAttributeSubscriptionState() + + data class Error(val exception: Exception) : AttributeListAttributeSubscriptionState() + + object SubscriptionEstablished : AttributeListAttributeSubscriptionState() + } + + suspend fun solicitOffer( + streamType: UByte, + videoStreamID: UShort?, + audioStreamID: UShort?, + ICEServers: List?, + ICETransportPolicy: String?, + metadataOptions: UByte?, + timedInvokeTimeout: Duration? = null, + ): SolicitOfferResponse { + val commandId: UInt = 1u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_STREAM_TYPE_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_STREAM_TYPE_REQ), streamType) + + val TAG_VIDEO_STREAM_ID_REQ: Int = 1 + videoStreamID?.let { tlvWriter.put(ContextSpecificTag(TAG_VIDEO_STREAM_ID_REQ), videoStreamID) } + + val TAG_AUDIO_STREAM_ID_REQ: Int = 2 + audioStreamID?.let { tlvWriter.put(ContextSpecificTag(TAG_AUDIO_STREAM_ID_REQ), audioStreamID) } + + val TAG_ICE_SERVERS_REQ: Int = 3 + ICEServers?.let { + tlvWriter.startArray(ContextSpecificTag(TAG_ICE_SERVERS_REQ)) + for (item in ICEServers.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) + } + tlvWriter.endArray() + } + + val TAG_ICE_TRANSPORT_POLICY_REQ: Int = 4 + ICETransportPolicy?.let { + tlvWriter.put(ContextSpecificTag(TAG_ICE_TRANSPORT_POLICY_REQ), ICETransportPolicy) + } + + val TAG_METADATA_OPTIONS_REQ: Int = 5 + metadataOptions?.let { + tlvWriter.put(ContextSpecificTag(TAG_METADATA_OPTIONS_REQ), metadataOptions) + } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout, + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_WEB_RTC_SESSION_ID: Int = 0 + var webRTCSessionID_decoded: UShort? = null + + val TAG_DEFERRED_OFFER: Int = 1 + var deferredOffer_decoded: Boolean? = null + + val TAG_VIDEO_STREAM_ID: Int = 2 + var videoStreamID_decoded: UShort? = null + + val TAG_AUDIO_STREAM_ID: Int = 3 + var audioStreamID_decoded: UShort? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_WEB_RTC_SESSION_ID)) { + webRTCSessionID_decoded = tlvReader.getUShort(tag) + } + + if (tag == ContextSpecificTag(TAG_DEFERRED_OFFER)) { + deferredOffer_decoded = tlvReader.getBoolean(tag) + } + + if (tag == ContextSpecificTag(TAG_VIDEO_STREAM_ID)) { + videoStreamID_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUShort(tag) + } else { + null + } + } else { + tlvReader.getNull(tag) + null + } + } + } + + if (tag == ContextSpecificTag(TAG_AUDIO_STREAM_ID)) { + audioStreamID_decoded = + if (tlvReader.isNull()) { + tlvReader.getNull(tag) + null + } else { + if (!tlvReader.isNull()) { + if (tlvReader.isNextTag(tag)) { + tlvReader.getUShort(tag) + } else { + null + } + } else { + tlvReader.getNull(tag) + null + } + } + } else { + tlvReader.skipElement() + } + } + + if (webRTCSessionID_decoded == null) { + throw IllegalStateException("webRTCSessionID not found in TLV") + } + + if (deferredOffer_decoded == null) { + throw IllegalStateException("deferredOffer not found in TLV") + } + + tlvReader.exitContainer() + + return SolicitOfferResponse( + webRTCSessionID_decoded, + deferredOffer_decoded, + videoStreamID_decoded, + audioStreamID_decoded, + ) + } + + suspend fun provideOffer( + webRTCSessionID: UShort?, + sdp: String, + streamType: UByte, + videoStreamID: UShort?, + audioStreamID: UShort?, + ICEServers: List?, + ICETransportPolicy: String?, + metadataOptions: UByte?, + timedInvokeTimeout: Duration? = null, + ): ProvideOfferResponse { + val commandId: UInt = 3u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_WEB_RTC_SESSION_ID_REQ: Int = 0 + webRTCSessionID?.let { + tlvWriter.put(ContextSpecificTag(TAG_WEB_RTC_SESSION_ID_REQ), webRTCSessionID) + } + + val TAG_SDP_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_SDP_REQ), sdp) + + val TAG_STREAM_TYPE_REQ: Int = 2 + tlvWriter.put(ContextSpecificTag(TAG_STREAM_TYPE_REQ), streamType) + + val TAG_VIDEO_STREAM_ID_REQ: Int = 3 + videoStreamID?.let { tlvWriter.put(ContextSpecificTag(TAG_VIDEO_STREAM_ID_REQ), videoStreamID) } + + val TAG_AUDIO_STREAM_ID_REQ: Int = 4 + audioStreamID?.let { tlvWriter.put(ContextSpecificTag(TAG_AUDIO_STREAM_ID_REQ), audioStreamID) } + + val TAG_ICE_SERVERS_REQ: Int = 5 + ICEServers?.let { + tlvWriter.startArray(ContextSpecificTag(TAG_ICE_SERVERS_REQ)) + for (item in ICEServers.iterator()) { + item.toTlv(AnonymousTag, tlvWriter) + } + tlvWriter.endArray() + } + + val TAG_ICE_TRANSPORT_POLICY_REQ: Int = 6 + ICETransportPolicy?.let { + tlvWriter.put(ContextSpecificTag(TAG_ICE_TRANSPORT_POLICY_REQ), ICETransportPolicy) + } + + val TAG_METADATA_OPTIONS_REQ: Int = 7 + metadataOptions?.let { + tlvWriter.put(ContextSpecificTag(TAG_METADATA_OPTIONS_REQ), metadataOptions) + } + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout, + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + + val tlvReader = TlvReader(response.payload) + tlvReader.enterStructure(AnonymousTag) + val TAG_WEB_RTC_SESSION_ID: Int = 0 + var webRTCSessionID_decoded: UShort? = null + + val TAG_VIDEO_STREAM_ID: Int = 1 + var videoStreamID_decoded: UShort? = null + + val TAG_AUDIO_STREAM_ID: Int = 2 + var audioStreamID_decoded: UShort? = null + + while (!tlvReader.isEndOfContainer()) { + val tag = tlvReader.peekElement().tag + + if (tag == ContextSpecificTag(TAG_WEB_RTC_SESSION_ID)) { + webRTCSessionID_decoded = tlvReader.getUShort(tag) + } + + if (tag == ContextSpecificTag(TAG_VIDEO_STREAM_ID)) { + videoStreamID_decoded = tlvReader.getUShort(tag) + } + + if (tag == ContextSpecificTag(TAG_AUDIO_STREAM_ID)) { + audioStreamID_decoded = tlvReader.getUShort(tag) + } else { + tlvReader.skipElement() + } + } + + if (webRTCSessionID_decoded == null) { + throw IllegalStateException("webRTCSessionID not found in TLV") + } + + if (videoStreamID_decoded == null) { + throw IllegalStateException("videoStreamID not found in TLV") + } + + if (audioStreamID_decoded == null) { + throw IllegalStateException("audioStreamID not found in TLV") + } + + tlvReader.exitContainer() + + return ProvideOfferResponse( + webRTCSessionID_decoded, + videoStreamID_decoded, + audioStreamID_decoded, + ) + } + + suspend fun provideAnswer( + webRTCSessionID: UShort, + sdp: String, + timedInvokeTimeout: Duration? = null, + ) { + val commandId: UInt = 5u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_WEB_RTC_SESSION_ID_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_WEB_RTC_SESSION_ID_REQ), webRTCSessionID) + + val TAG_SDP_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_SDP_REQ), sdp) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout, + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + } + + suspend fun provideICECandidate( + webRTCSessionID: UShort, + ICECandidate: String, + timedInvokeTimeout: Duration? = null, + ) { + val commandId: UInt = 6u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_WEB_RTC_SESSION_ID_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_WEB_RTC_SESSION_ID_REQ), webRTCSessionID) + + val TAG_ICE_CANDIDATE_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_ICE_CANDIDATE_REQ), ICECandidate) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout, + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + } + + suspend fun endSession( + webRTCSessionID: UShort, + reason: UByte, + timedInvokeTimeout: Duration? = null, + ) { + val commandId: UInt = 7u + + val tlvWriter = TlvWriter() + tlvWriter.startStructure(AnonymousTag) + + val TAG_WEB_RTC_SESSION_ID_REQ: Int = 0 + tlvWriter.put(ContextSpecificTag(TAG_WEB_RTC_SESSION_ID_REQ), webRTCSessionID) + + val TAG_REASON_REQ: Int = 1 + tlvWriter.put(ContextSpecificTag(TAG_REASON_REQ), reason) + tlvWriter.endStructure() + + val request: InvokeRequest = + InvokeRequest( + CommandPath(endpointId, clusterId = CLUSTER_ID, commandId), + tlvPayload = tlvWriter.getEncoded(), + timedRequest = timedInvokeTimeout, + ) + + val response: InvokeResponse = controller.invoke(request) + logger.log(Level.FINE, "Invoke command succeeded: ${response}") + } + + suspend fun readCurrentSessionsAttribute(): CurrentSessionsAttribute { + val ATTRIBUTE_ID: UInt = 0u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Currentsessions attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(WebRTCTransportProviderClusterWebRTCSessionStruct.fromTlv(AnonymousTag, tlvReader)) + } + tlvReader.exitContainer() + } + + return CurrentSessionsAttribute(decodedValue) + } + + suspend fun subscribeCurrentSessionsAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 0u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + CurrentSessionsAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Currentsessions attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add( + WebRTCTransportProviderClusterWebRTCSessionStruct.fromTlv(AnonymousTag, tlvReader) + ) + } + tlvReader.exitContainer() + } + + emit(CurrentSessionsAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(CurrentSessionsAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readGeneratedCommandListAttribute(): GeneratedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65528u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Generatedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return GeneratedCommandListAttribute(decodedValue) + } + + suspend fun subscribeGeneratedCommandListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65528u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + GeneratedCommandListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Generatedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(GeneratedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(GeneratedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAcceptedCommandListAttribute(): AcceptedCommandListAttribute { + val ATTRIBUTE_ID: UInt = 65529u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Acceptedcommandlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AcceptedCommandListAttribute(decodedValue) + } + + suspend fun subscribeAcceptedCommandListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65529u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + AcceptedCommandListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Acceptedcommandlist attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AcceptedCommandListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AcceptedCommandListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readEventListAttribute(): EventListAttribute { + val ATTRIBUTE_ID: UInt = 65530u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Eventlist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return EventListAttribute(decodedValue) + } + + suspend fun subscribeEventListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65530u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + EventListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Eventlist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(EventListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(EventListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readAttributeListAttribute(): AttributeListAttribute { + val ATTRIBUTE_ID: UInt = 65531u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Attributelist attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + return AttributeListAttribute(decodedValue) + } + + suspend fun subscribeAttributeListAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65531u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + AttributeListAttributeSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Attributelist attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: List = + buildList { + tlvReader.enterArray(AnonymousTag) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getUInt(AnonymousTag)) + } + tlvReader.exitContainer() + } + + emit(AttributeListAttributeSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(AttributeListAttributeSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readFeatureMapAttribute(): UInt { + val ATTRIBUTE_ID: UInt = 65532u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Featuremap attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeFeatureMapAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65532u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UIntSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { "Featuremap attribute not found in Node State update" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UInt = tlvReader.getUInt(AnonymousTag) + + emit(UIntSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UIntSubscriptionState.SubscriptionEstablished) + } + } + } + } + + suspend fun readClusterRevisionAttribute(): UShort { + val ATTRIBUTE_ID: UInt = 65533u + + val attributePath = + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + + val readRequest = ReadRequest(eventPaths = emptyList(), attributePaths = listOf(attributePath)) + + val response = controller.read(readRequest) + + if (response.successes.isEmpty()) { + logger.log(Level.WARNING, "Read command failed") + throw IllegalStateException("Read command failed with failures: ${response.failures}") + } + + logger.log(Level.FINE, "Read command succeeded") + + val attributeData = + response.successes.filterIsInstance().firstOrNull { + it.path.attributeId == ATTRIBUTE_ID + } + + requireNotNull(attributeData) { "Clusterrevision attribute not found in response" } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + return decodedValue + } + + suspend fun subscribeClusterRevisionAttribute( + minInterval: Int, + maxInterval: Int, + ): Flow { + val ATTRIBUTE_ID: UInt = 65533u + val attributePaths = + listOf( + AttributePath(endpointId = endpointId, clusterId = CLUSTER_ID, attributeId = ATTRIBUTE_ID) + ) + + val subscribeRequest: SubscribeRequest = + SubscribeRequest( + eventPaths = emptyList(), + attributePaths = attributePaths, + minInterval = Duration.ofSeconds(minInterval.toLong()), + maxInterval = Duration.ofSeconds(maxInterval.toLong()), + ) + + return controller.subscribe(subscribeRequest).transform { subscriptionState -> + when (subscriptionState) { + is SubscriptionState.SubscriptionErrorNotification -> { + emit( + UShortSubscriptionState.Error( + Exception( + "Subscription terminated with error code: ${subscriptionState.terminationCause}" + ) + ) + ) + } + is SubscriptionState.NodeStateUpdate -> { + val attributeData = + subscriptionState.updateState.successes + .filterIsInstance() + .firstOrNull { it.path.attributeId == ATTRIBUTE_ID } + + requireNotNull(attributeData) { + "Clusterrevision attribute not found in Node State update" + } + + // Decode the TLV data into the appropriate type + val tlvReader = TlvReader(attributeData.data) + val decodedValue: UShort = tlvReader.getUShort(AnonymousTag) + + emit(UShortSubscriptionState.Success(decodedValue)) + } + SubscriptionState.SubscriptionEstablished -> { + emit(UShortSubscriptionState.SubscriptionEstablished) + } + } + } + } + + companion object { + private val logger = Logger.getLogger(WebRTCTransportProviderCluster::class.java.name) + const val CLUSTER_ID: UInt = 1363u + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/files.gni b/src/controller/java/generated/java/matter/controller/cluster/files.gni index 42e2b95b02..6a7e5b317e 100644 --- a/src/controller/java/generated/java/matter/controller/cluster/files.gni +++ b/src/controller/java/generated/java/matter/controller/cluster/files.gni @@ -160,6 +160,8 @@ matter_structs_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/WaterHeaterManagementClusterWaterHeaterBoostInfoStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/WaterHeaterModeClusterModeOptionStruct.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/WaterHeaterModeClusterModeTagStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/WebRTCTransportProviderClusterICEServerStruct.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/structs/WebRTCTransportProviderClusterWebRTCSessionStruct.kt", ] matter_eventstructs_sources = [ @@ -370,6 +372,7 @@ matter_clusters_sources = [ "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WakeOnLanCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WaterHeaterManagementCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WaterHeaterModeCluster.kt", + "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WebRTCTransportProviderCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WiFiNetworkDiagnosticsCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WiFiNetworkManagementCluster.kt", "${chip_root}/src/controller/java/generated/java/matter/controller/cluster/clusters/WindowCoveringCluster.kt", diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/WebRTCTransportProviderClusterICEServerStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/WebRTCTransportProviderClusterICEServerStruct.kt new file mode 100644 index 0000000000..fd9e75a621 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/WebRTCTransportProviderClusterICEServerStruct.kt @@ -0,0 +1,106 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ +package matter.controller.cluster.structs + +import java.util.Optional +import matter.controller.cluster.* +import matter.tlv.AnonymousTag +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class WebRTCTransportProviderClusterICEServerStruct( + val urls: List, + val username: Optional, + val credential: Optional, + val caid: Optional, +) { + override fun toString(): String = buildString { + append("WebRTCTransportProviderClusterICEServerStruct {\n") + append("\turls : $urls\n") + append("\tusername : $username\n") + append("\tcredential : $credential\n") + append("\tcaid : $caid\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + startArray(ContextSpecificTag(TAG_URLS)) + for (item in urls.iterator()) { + put(AnonymousTag, item) + } + endArray() + if (username.isPresent) { + val optusername = username.get() + put(ContextSpecificTag(TAG_USERNAME), optusername) + } + if (credential.isPresent) { + val optcredential = credential.get() + put(ContextSpecificTag(TAG_CREDENTIAL), optcredential) + } + if (caid.isPresent) { + val optcaid = caid.get() + put(ContextSpecificTag(TAG_CAID), optcaid) + } + endStructure() + } + } + + companion object { + private const val TAG_URLS = 1 + private const val TAG_USERNAME = 2 + private const val TAG_CREDENTIAL = 3 + private const val TAG_CAID = 4 + + fun fromTlv(tlvTag: Tag, tlvReader: TlvReader): WebRTCTransportProviderClusterICEServerStruct { + tlvReader.enterStructure(tlvTag) + val urls = + buildList { + tlvReader.enterArray(ContextSpecificTag(TAG_URLS)) + while (!tlvReader.isEndOfContainer()) { + add(tlvReader.getString(AnonymousTag)) + } + tlvReader.exitContainer() + } + val username = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_USERNAME))) { + Optional.of(tlvReader.getString(ContextSpecificTag(TAG_USERNAME))) + } else { + Optional.empty() + } + val credential = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_CREDENTIAL))) { + Optional.of(tlvReader.getString(ContextSpecificTag(TAG_CREDENTIAL))) + } else { + Optional.empty() + } + val caid = + if (tlvReader.isNextTag(ContextSpecificTag(TAG_CAID))) { + Optional.of(tlvReader.getUShort(ContextSpecificTag(TAG_CAID))) + } else { + Optional.empty() + } + + tlvReader.exitContainer() + + return WebRTCTransportProviderClusterICEServerStruct(urls, username, credential, caid) + } + } +} diff --git a/src/controller/java/generated/java/matter/controller/cluster/structs/WebRTCTransportProviderClusterWebRTCSessionStruct.kt b/src/controller/java/generated/java/matter/controller/cluster/structs/WebRTCTransportProviderClusterWebRTCSessionStruct.kt new file mode 100644 index 0000000000..564f52c520 --- /dev/null +++ b/src/controller/java/generated/java/matter/controller/cluster/structs/WebRTCTransportProviderClusterWebRTCSessionStruct.kt @@ -0,0 +1,115 @@ +/* + * + * Copyright (c) 2023 Project CHIP Authors + * + * 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. + */ +package matter.controller.cluster.structs + +import matter.controller.cluster.* +import matter.tlv.ContextSpecificTag +import matter.tlv.Tag +import matter.tlv.TlvReader +import matter.tlv.TlvWriter + +class WebRTCTransportProviderClusterWebRTCSessionStruct( + val id: UShort, + val peerNodeID: ULong, + val peerFabricIndex: UByte, + val streamType: UByte, + val videoStreamID: UShort?, + val audioStreamID: UShort?, + val metadataOptions: UByte, +) { + override fun toString(): String = buildString { + append("WebRTCTransportProviderClusterWebRTCSessionStruct {\n") + append("\tid : $id\n") + append("\tpeerNodeID : $peerNodeID\n") + append("\tpeerFabricIndex : $peerFabricIndex\n") + append("\tstreamType : $streamType\n") + append("\tvideoStreamID : $videoStreamID\n") + append("\taudioStreamID : $audioStreamID\n") + append("\tmetadataOptions : $metadataOptions\n") + append("}\n") + } + + fun toTlv(tlvTag: Tag, tlvWriter: TlvWriter) { + tlvWriter.apply { + startStructure(tlvTag) + put(ContextSpecificTag(TAG_ID), id) + put(ContextSpecificTag(TAG_PEER_NODE_ID), peerNodeID) + put(ContextSpecificTag(TAG_PEER_FABRIC_INDEX), peerFabricIndex) + put(ContextSpecificTag(TAG_STREAM_TYPE), streamType) + if (videoStreamID != null) { + put(ContextSpecificTag(TAG_VIDEO_STREAM_ID), videoStreamID) + } else { + putNull(ContextSpecificTag(TAG_VIDEO_STREAM_ID)) + } + if (audioStreamID != null) { + put(ContextSpecificTag(TAG_AUDIO_STREAM_ID), audioStreamID) + } else { + putNull(ContextSpecificTag(TAG_AUDIO_STREAM_ID)) + } + put(ContextSpecificTag(TAG_METADATA_OPTIONS), metadataOptions) + endStructure() + } + } + + companion object { + private const val TAG_ID = 1 + private const val TAG_PEER_NODE_ID = 2 + private const val TAG_PEER_FABRIC_INDEX = 3 + private const val TAG_STREAM_TYPE = 4 + private const val TAG_VIDEO_STREAM_ID = 5 + private const val TAG_AUDIO_STREAM_ID = 6 + private const val TAG_METADATA_OPTIONS = 7 + + fun fromTlv( + tlvTag: Tag, + tlvReader: TlvReader, + ): WebRTCTransportProviderClusterWebRTCSessionStruct { + tlvReader.enterStructure(tlvTag) + val id = tlvReader.getUShort(ContextSpecificTag(TAG_ID)) + val peerNodeID = tlvReader.getULong(ContextSpecificTag(TAG_PEER_NODE_ID)) + val peerFabricIndex = tlvReader.getUByte(ContextSpecificTag(TAG_PEER_FABRIC_INDEX)) + val streamType = tlvReader.getUByte(ContextSpecificTag(TAG_STREAM_TYPE)) + val videoStreamID = + if (!tlvReader.isNull()) { + tlvReader.getUShort(ContextSpecificTag(TAG_VIDEO_STREAM_ID)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_VIDEO_STREAM_ID)) + null + } + val audioStreamID = + if (!tlvReader.isNull()) { + tlvReader.getUShort(ContextSpecificTag(TAG_AUDIO_STREAM_ID)) + } else { + tlvReader.getNull(ContextSpecificTag(TAG_AUDIO_STREAM_ID)) + null + } + val metadataOptions = tlvReader.getUByte(ContextSpecificTag(TAG_METADATA_OPTIONS)) + + tlvReader.exitContainer() + + return WebRTCTransportProviderClusterWebRTCSessionStruct( + id, + peerNodeID, + peerFabricIndex, + streamType, + videoStreamID, + audioStreamID, + metadataOptions, + ) + } + } +} diff --git a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp index 0cf7ce8b65..741e40567f 100644 --- a/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPAttributeTLVValueDecoder.cpp @@ -42220,6 +42220,256 @@ jobject DecodeAttributeValue(const app::ConcreteAttributePath & aPath, TLV::TLVR } break; } + case app::Clusters::WebRTCTransportProvider::Id: { + using namespace app::Clusters::WebRTCTransportProvider; + switch (aPath.mAttributeId) + { + case Attributes::CurrentSessions::Id: { + using TypeInfo = Attributes::CurrentSessions::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + jobject newElement_0_id; + std::string newElement_0_idClassName = "java/lang/Integer"; + std::string newElement_0_idCtorSignature = "(I)V"; + jint jninewElement_0_id = static_cast(entry_0.id); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_idClassName.c_str(), newElement_0_idCtorSignature.c_str(), jninewElement_0_id, newElement_0_id); + jobject newElement_0_peerNodeID; + std::string newElement_0_peerNodeIDClassName = "java/lang/Long"; + std::string newElement_0_peerNodeIDCtorSignature = "(J)V"; + jlong jninewElement_0_peerNodeID = static_cast(entry_0.peerNodeID); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_0_peerNodeIDClassName.c_str(), + newElement_0_peerNodeIDCtorSignature.c_str(), + jninewElement_0_peerNodeID, newElement_0_peerNodeID); + jobject newElement_0_peerFabricIndex; + std::string newElement_0_peerFabricIndexClassName = "java/lang/Integer"; + std::string newElement_0_peerFabricIndexCtorSignature = "(I)V"; + jint jninewElement_0_peerFabricIndex = static_cast(entry_0.peerFabricIndex); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_peerFabricIndexClassName.c_str(), newElement_0_peerFabricIndexCtorSignature.c_str(), + jninewElement_0_peerFabricIndex, newElement_0_peerFabricIndex); + jobject newElement_0_streamType; + std::string newElement_0_streamTypeClassName = "java/lang/Integer"; + std::string newElement_0_streamTypeCtorSignature = "(I)V"; + jint jninewElement_0_streamType = static_cast(entry_0.streamType); + chip::JniReferences::GetInstance().CreateBoxedObject(newElement_0_streamTypeClassName.c_str(), + newElement_0_streamTypeCtorSignature.c_str(), + jninewElement_0_streamType, newElement_0_streamType); + jobject newElement_0_videoStreamID; + if (entry_0.videoStreamID.IsNull()) + { + newElement_0_videoStreamID = nullptr; + } + else + { + std::string newElement_0_videoStreamIDClassName = "java/lang/Integer"; + std::string newElement_0_videoStreamIDCtorSignature = "(I)V"; + jint jninewElement_0_videoStreamID = static_cast(entry_0.videoStreamID.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_videoStreamIDClassName.c_str(), newElement_0_videoStreamIDCtorSignature.c_str(), + jninewElement_0_videoStreamID, newElement_0_videoStreamID); + } + jobject newElement_0_audioStreamID; + if (entry_0.audioStreamID.IsNull()) + { + newElement_0_audioStreamID = nullptr; + } + else + { + std::string newElement_0_audioStreamIDClassName = "java/lang/Integer"; + std::string newElement_0_audioStreamIDCtorSignature = "(I)V"; + jint jninewElement_0_audioStreamID = static_cast(entry_0.audioStreamID.Value()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_audioStreamIDClassName.c_str(), newElement_0_audioStreamIDCtorSignature.c_str(), + jninewElement_0_audioStreamID, newElement_0_audioStreamID); + } + jobject newElement_0_metadataOptions; + std::string newElement_0_metadataOptionsClassName = "java/lang/Integer"; + std::string newElement_0_metadataOptionsCtorSignature = "(I)V"; + jint jninewElement_0_metadataOptions = static_cast(entry_0.metadataOptions.Raw()); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0_metadataOptionsClassName.c_str(), newElement_0_metadataOptionsCtorSignature.c_str(), + jninewElement_0_metadataOptions, newElement_0_metadataOptions); + + jclass webRTCSessionStructStructClass_1; + err = chip::JniReferences::GetInstance().GetLocalClassRef( + env, "chip/devicecontroller/ChipStructs$WebRTCTransportProviderClusterWebRTCSessionStruct", + webRTCSessionStructStructClass_1); + if (err != CHIP_NO_ERROR) + { + ChipLogError(Zcl, "Could not find class ChipStructs$WebRTCTransportProviderClusterWebRTCSessionStruct"); + return nullptr; + } + + jmethodID webRTCSessionStructStructCtor_1; + err = chip::JniReferences::GetInstance().FindMethod( + env, webRTCSessionStructStructClass_1, "", + "(Ljava/lang/Integer;Ljava/lang/Long;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/Integer;Ljava/lang/" + "Integer;Ljava/lang/Integer;)V", + &webRTCSessionStructStructCtor_1); + if (err != CHIP_NO_ERROR || webRTCSessionStructStructCtor_1 == nullptr) + { + ChipLogError(Zcl, "Could not find ChipStructs$WebRTCTransportProviderClusterWebRTCSessionStruct constructor"); + return nullptr; + } + + newElement_0 = env->NewObject(webRTCSessionStructStructClass_1, webRTCSessionStructStructCtor_1, newElement_0_id, + newElement_0_peerNodeID, newElement_0_peerFabricIndex, newElement_0_streamType, + newElement_0_videoStreamID, newElement_0_audioStreamID, newElement_0_metadataOptions); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::GeneratedCommandList::Id: { + using TypeInfo = Attributes::GeneratedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AcceptedCommandList::Id: { + using TypeInfo = Attributes::AcceptedCommandList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::EventList::Id: { + using TypeInfo = Attributes::EventList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::AttributeList::Id: { + using TypeInfo = Attributes::AttributeList::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + chip::JniReferences::GetInstance().CreateArrayList(value); + + auto iter_value_0 = cppValue.begin(); + while (iter_value_0.Next()) + { + auto & entry_0 = iter_value_0.GetValue(); + jobject newElement_0; + std::string newElement_0ClassName = "java/lang/Long"; + std::string newElement_0CtorSignature = "(J)V"; + jlong jninewElement_0 = static_cast(entry_0); + chip::JniReferences::GetInstance().CreateBoxedObject( + newElement_0ClassName.c_str(), newElement_0CtorSignature.c_str(), jninewElement_0, newElement_0); + chip::JniReferences::GetInstance().AddToList(value, newElement_0); + } + return value; + } + case Attributes::FeatureMap::Id: { + using TypeInfo = Attributes::FeatureMap::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Long"; + std::string valueCtorSignature = "(J)V"; + jlong jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), + jnivalue, value); + return value; + } + case Attributes::ClusterRevision::Id: { + using TypeInfo = Attributes::ClusterRevision::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = app::DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) + { + return nullptr; + } + jobject value; + std::string valueClassName = "java/lang/Integer"; + std::string valueCtorSignature = "(I)V"; + jint jnivalue = static_cast(cppValue); + chip::JniReferences::GetInstance().CreateBoxedObject(valueClassName.c_str(), valueCtorSignature.c_str(), jnivalue, + value); + return value; + } + default: + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + break; + } + break; + } case app::Clusters::Chime::Id: { using namespace app::Clusters::Chime; switch (aPath.mAttributeId) diff --git a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp index 2dc46ab844..9da4b9690e 100644 --- a/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp +++ b/src/controller/java/zap-generated/CHIPEventTLVValueDecoder.cpp @@ -8248,6 +8248,16 @@ jobject DecodeEventValue(const app::ConcreteEventPath & aPath, TLV::TLVReader & } break; } + case app::Clusters::WebRTCTransportProvider::Id: { + using namespace app::Clusters::WebRTCTransportProvider; + switch (aPath.mEventId) + { + default: + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + break; + } + break; + } case app::Clusters::Chime::Id: { using namespace app::Clusters::Chime; switch (aPath.mEventId) diff --git a/src/controller/python/chip/clusters/CHIPClusters.py b/src/controller/python/chip/clusters/CHIPClusters.py index 1105faa9ca..1df4d9c9f6 100644 --- a/src/controller/python/chip/clusters/CHIPClusters.py +++ b/src/controller/python/chip/clusters/CHIPClusters.py @@ -13029,6 +13029,106 @@ class ChipClusters: }, }, } + _WEB_RTC_TRANSPORT_PROVIDER_CLUSTER_INFO = { + "clusterName": "WebRTCTransportProvider", + "clusterId": 0x00000553, + "commands": { + 0x00000001: { + "commandId": 0x00000001, + "commandName": "SolicitOffer", + "args": { + "streamType": "int", + "videoStreamID": "int", + "audioStreamID": "int", + "ICEServers": "ICEServerStruct", + "ICETransportPolicy": "str", + "metadataOptions": "int", + }, + }, + 0x00000003: { + "commandId": 0x00000003, + "commandName": "ProvideOffer", + "args": { + "webRTCSessionID": "int", + "sdp": "str", + "streamType": "int", + "videoStreamID": "int", + "audioStreamID": "int", + "ICEServers": "ICEServerStruct", + "ICETransportPolicy": "str", + "metadataOptions": "int", + }, + }, + 0x00000005: { + "commandId": 0x00000005, + "commandName": "ProvideAnswer", + "args": { + "webRTCSessionID": "int", + "sdp": "str", + }, + }, + 0x00000006: { + "commandId": 0x00000006, + "commandName": "ProvideICECandidate", + "args": { + "webRTCSessionID": "int", + "ICECandidate": "str", + }, + }, + 0x00000007: { + "commandId": 0x00000007, + "commandName": "EndSession", + "args": { + "webRTCSessionID": "int", + "reason": "int", + }, + }, + }, + "attributes": { + 0x00000000: { + "attributeName": "CurrentSessions", + "attributeId": 0x00000000, + "type": "", + "reportable": True, + }, + 0x0000FFF8: { + "attributeName": "GeneratedCommandList", + "attributeId": 0x0000FFF8, + "type": "int", + "reportable": True, + }, + 0x0000FFF9: { + "attributeName": "AcceptedCommandList", + "attributeId": 0x0000FFF9, + "type": "int", + "reportable": True, + }, + 0x0000FFFA: { + "attributeName": "EventList", + "attributeId": 0x0000FFFA, + "type": "int", + "reportable": True, + }, + 0x0000FFFB: { + "attributeName": "AttributeList", + "attributeId": 0x0000FFFB, + "type": "int", + "reportable": True, + }, + 0x0000FFFC: { + "attributeName": "FeatureMap", + "attributeId": 0x0000FFFC, + "type": "int", + "reportable": True, + }, + 0x0000FFFD: { + "attributeName": "ClusterRevision", + "attributeId": 0x0000FFFD, + "type": "int", + "reportable": True, + }, + }, + } _CHIME_CLUSTER_INFO = { "clusterName": "Chime", "clusterId": 0x00000556, @@ -14347,6 +14447,7 @@ class ChipClusters: 0x0000050E: _ACCOUNT_LOGIN_CLUSTER_INFO, 0x0000050F: _CONTENT_CONTROL_CLUSTER_INFO, 0x00000510: _CONTENT_APP_OBSERVER_CLUSTER_INFO, + 0x00000553: _WEB_RTC_TRANSPORT_PROVIDER_CLUSTER_INFO, 0x00000556: _CHIME_CLUSTER_INFO, 0x00000750: _ECOSYSTEM_INFORMATION_CLUSTER_INFO, 0x00000751: _COMMISSIONER_CONTROL_CLUSTER_INFO, @@ -14473,6 +14574,7 @@ class ChipClusters: "AccountLogin": _ACCOUNT_LOGIN_CLUSTER_INFO, "ContentControl": _CONTENT_CONTROL_CLUSTER_INFO, "ContentAppObserver": _CONTENT_APP_OBSERVER_CLUSTER_INFO, + "WebRTCTransportProvider": _WEB_RTC_TRANSPORT_PROVIDER_CLUSTER_INFO, "Chime": _CHIME_CLUSTER_INFO, "EcosystemInformation": _ECOSYSTEM_INFORMATION_CLUSTER_INFO, "CommissionerControl": _COMMISSIONER_CONTROL_CLUSTER_INFO, diff --git a/src/controller/python/chip/clusters/Objects.py b/src/controller/python/chip/clusters/Objects.py index 9752185e29..b11ad8e725 100644 --- a/src/controller/python/chip/clusters/Objects.py +++ b/src/controller/python/chip/clusters/Objects.py @@ -156,6 +156,7 @@ "AccountLogin", "ContentControl", "ContentAppObserver", + "WebRTCTransportProvider", "Chime", "EcosystemInformation", "CommissionerControl", @@ -46517,6 +46518,374 @@ def attribute_type(cls) -> ClusterObjectFieldDescriptor: value: 'uint' = 0 +@dataclass +class WebRTCTransportProvider(Cluster): + id: typing.ClassVar[int] = 0x00000553 + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="currentSessions", Tag=0x00000000, Type=typing.List[WebRTCTransportProvider.Structs.WebRTCSessionStruct]), + ClusterObjectFieldDescriptor(Label="generatedCommandList", Tag=0x0000FFF8, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="acceptedCommandList", Tag=0x0000FFF9, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="eventList", Tag=0x0000FFFA, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="attributeList", Tag=0x0000FFFB, Type=typing.List[uint]), + ClusterObjectFieldDescriptor(Label="featureMap", Tag=0x0000FFFC, Type=uint), + ClusterObjectFieldDescriptor(Label="clusterRevision", Tag=0x0000FFFD, Type=uint), + ]) + + currentSessions: 'typing.List[WebRTCTransportProvider.Structs.WebRTCSessionStruct]' = None + generatedCommandList: 'typing.List[uint]' = None + acceptedCommandList: 'typing.List[uint]' = None + eventList: 'typing.List[uint]' = None + attributeList: 'typing.List[uint]' = None + featureMap: 'uint' = None + clusterRevision: 'uint' = None + + class Enums: + class StreamTypeEnum(MatterIntEnum): + kInternal = 0x00 + kRecording = 0x01 + kAnalysis = 0x02 + kLiveView = 0x03 + # All received enum values that are not listed above will be mapped + # to kUnknownEnumValue. This is a helper enum value that should only + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. + kUnknownEnumValue = 4, + + class WebRTCEndReasonEnum(MatterIntEnum): + kIceFailed = 0x00 + kIceTimeout = 0x01 + kUserHangup = 0x02 + kUserBusy = 0x03 + kReplaced = 0x04 + kNoUserMedia = 0x05 + kInviteTimeout = 0x06 + kAnsweredElsewhere = 0x07 + kOutOfResources = 0x08 + kMediaTimeout = 0x09 + kLowPower = 0x0A + kUnknownReason = 0x0B + # All received enum values that are not listed above will be mapped + # to kUnknownEnumValue. This is a helper enum value that should only + # be used by code to process how it handles receiving an unknown + # enum value. This specific value should never be transmitted. + kUnknownEnumValue = 12, + + class Bitmaps: + class WebRTCMetadataOptions(IntFlag): + kDataTLV = 0x1 + + class Structs: + @dataclass + class ICEServerStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="urls", Tag=1, Type=typing.List[str]), + ClusterObjectFieldDescriptor(Label="username", Tag=2, Type=typing.Optional[str]), + ClusterObjectFieldDescriptor(Label="credential", Tag=3, Type=typing.Optional[str]), + ClusterObjectFieldDescriptor(Label="caid", Tag=4, Type=typing.Optional[uint]), + ]) + + urls: 'typing.List[str]' = field(default_factory=lambda: []) + username: 'typing.Optional[str]' = None + credential: 'typing.Optional[str]' = None + caid: 'typing.Optional[uint]' = None + + @dataclass + class WebRTCSessionStruct(ClusterObject): + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="id", Tag=1, Type=uint), + ClusterObjectFieldDescriptor(Label="peerNodeID", Tag=2, Type=uint), + ClusterObjectFieldDescriptor(Label="peerFabricIndex", Tag=3, Type=uint), + ClusterObjectFieldDescriptor(Label="streamType", Tag=4, Type=WebRTCTransportProvider.Enums.StreamTypeEnum), + ClusterObjectFieldDescriptor(Label="videoStreamID", Tag=5, Type=typing.Union[Nullable, uint]), + ClusterObjectFieldDescriptor(Label="audioStreamID", Tag=6, Type=typing.Union[Nullable, uint]), + ClusterObjectFieldDescriptor(Label="metadataOptions", Tag=7, Type=uint), + ]) + + id: 'uint' = 0 + peerNodeID: 'uint' = 0 + peerFabricIndex: 'uint' = 0 + streamType: 'WebRTCTransportProvider.Enums.StreamTypeEnum' = 0 + videoStreamID: 'typing.Union[Nullable, uint]' = NullValue + audioStreamID: 'typing.Union[Nullable, uint]' = NullValue + metadataOptions: 'uint' = 0 + + class Commands: + @dataclass + class SolicitOffer(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000553 + command_id: typing.ClassVar[int] = 0x00000001 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = 'SolicitOfferResponse' + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="streamType", Tag=0, Type=WebRTCTransportProvider.Enums.StreamTypeEnum), + ClusterObjectFieldDescriptor(Label="videoStreamID", Tag=1, Type=typing.Union[None, Nullable, uint]), + ClusterObjectFieldDescriptor(Label="audioStreamID", Tag=2, Type=typing.Union[None, Nullable, uint]), + ClusterObjectFieldDescriptor(Label="ICEServers", Tag=3, Type=typing.Optional[typing.List[WebRTCTransportProvider.Structs.ICEServerStruct]]), + ClusterObjectFieldDescriptor(Label="ICETransportPolicy", Tag=4, Type=typing.Optional[str]), + ClusterObjectFieldDescriptor(Label="metadataOptions", Tag=5, Type=typing.Optional[uint]), + ]) + + streamType: 'WebRTCTransportProvider.Enums.StreamTypeEnum' = 0 + videoStreamID: 'typing.Union[None, Nullable, uint]' = None + audioStreamID: 'typing.Union[None, Nullable, uint]' = None + ICEServers: 'typing.Optional[typing.List[WebRTCTransportProvider.Structs.ICEServerStruct]]' = None + ICETransportPolicy: 'typing.Optional[str]' = None + metadataOptions: 'typing.Optional[uint]' = None + + @dataclass + class SolicitOfferResponse(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000553 + command_id: typing.ClassVar[int] = 0x00000002 + is_client: typing.ClassVar[bool] = False + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="webRTCSessionID", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="deferredOffer", Tag=1, Type=bool), + ClusterObjectFieldDescriptor(Label="videoStreamID", Tag=2, Type=typing.Union[None, Nullable, uint]), + ClusterObjectFieldDescriptor(Label="audioStreamID", Tag=3, Type=typing.Union[None, Nullable, uint]), + ]) + + webRTCSessionID: 'uint' = 0 + deferredOffer: 'bool' = False + videoStreamID: 'typing.Union[None, Nullable, uint]' = None + audioStreamID: 'typing.Union[None, Nullable, uint]' = None + + @dataclass + class ProvideOffer(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000553 + command_id: typing.ClassVar[int] = 0x00000003 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = 'ProvideOfferResponse' + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="webRTCSessionID", Tag=0, Type=typing.Union[Nullable, uint]), + ClusterObjectFieldDescriptor(Label="sdp", Tag=1, Type=str), + ClusterObjectFieldDescriptor(Label="streamType", Tag=2, Type=WebRTCTransportProvider.Enums.StreamTypeEnum), + ClusterObjectFieldDescriptor(Label="videoStreamID", Tag=3, Type=typing.Union[None, Nullable, uint]), + ClusterObjectFieldDescriptor(Label="audioStreamID", Tag=4, Type=typing.Union[None, Nullable, uint]), + ClusterObjectFieldDescriptor(Label="ICEServers", Tag=5, Type=typing.Optional[typing.List[WebRTCTransportProvider.Structs.ICEServerStruct]]), + ClusterObjectFieldDescriptor(Label="ICETransportPolicy", Tag=6, Type=typing.Optional[str]), + ClusterObjectFieldDescriptor(Label="metadataOptions", Tag=7, Type=typing.Optional[uint]), + ]) + + webRTCSessionID: 'typing.Union[Nullable, uint]' = NullValue + sdp: 'str' = "" + streamType: 'WebRTCTransportProvider.Enums.StreamTypeEnum' = 0 + videoStreamID: 'typing.Union[None, Nullable, uint]' = None + audioStreamID: 'typing.Union[None, Nullable, uint]' = None + ICEServers: 'typing.Optional[typing.List[WebRTCTransportProvider.Structs.ICEServerStruct]]' = None + ICETransportPolicy: 'typing.Optional[str]' = None + metadataOptions: 'typing.Optional[uint]' = None + + @dataclass + class ProvideOfferResponse(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000553 + command_id: typing.ClassVar[int] = 0x00000004 + is_client: typing.ClassVar[bool] = False + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="webRTCSessionID", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="videoStreamID", Tag=1, Type=uint), + ClusterObjectFieldDescriptor(Label="audioStreamID", Tag=2, Type=uint), + ]) + + webRTCSessionID: 'uint' = 0 + videoStreamID: 'uint' = 0 + audioStreamID: 'uint' = 0 + + @dataclass + class ProvideAnswer(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000553 + command_id: typing.ClassVar[int] = 0x00000005 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="webRTCSessionID", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="sdp", Tag=1, Type=str), + ]) + + webRTCSessionID: 'uint' = 0 + sdp: 'str' = "" + + @dataclass + class ProvideICECandidate(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000553 + command_id: typing.ClassVar[int] = 0x00000006 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="webRTCSessionID", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="ICECandidate", Tag=1, Type=str), + ]) + + webRTCSessionID: 'uint' = 0 + ICECandidate: 'str' = "" + + @dataclass + class EndSession(ClusterCommand): + cluster_id: typing.ClassVar[int] = 0x00000553 + command_id: typing.ClassVar[int] = 0x00000007 + is_client: typing.ClassVar[bool] = True + response_type: typing.ClassVar[str] = None + + @ChipUtility.classproperty + def descriptor(cls) -> ClusterObjectDescriptor: + return ClusterObjectDescriptor( + Fields=[ + ClusterObjectFieldDescriptor(Label="webRTCSessionID", Tag=0, Type=uint), + ClusterObjectFieldDescriptor(Label="reason", Tag=1, Type=WebRTCTransportProvider.Enums.WebRTCEndReasonEnum), + ]) + + webRTCSessionID: 'uint' = 0 + reason: 'WebRTCTransportProvider.Enums.WebRTCEndReasonEnum' = 0 + + class Attributes: + @dataclass + class CurrentSessions(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000553 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x00000000 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[WebRTCTransportProvider.Structs.WebRTCSessionStruct]) + + value: 'typing.List[WebRTCTransportProvider.Structs.WebRTCSessionStruct]' = field(default_factory=lambda: []) + + @dataclass + class GeneratedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000553 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF8 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AcceptedCommandList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000553 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFF9 + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class EventList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000553 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFA + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class AttributeList(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000553 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFB + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=typing.List[uint]) + + value: 'typing.List[uint]' = field(default_factory=lambda: []) + + @dataclass + class FeatureMap(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000553 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFC + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass + class ClusterRevision(ClusterAttributeDescriptor): + @ChipUtility.classproperty + def cluster_id(cls) -> int: + return 0x00000553 + + @ChipUtility.classproperty + def attribute_id(cls) -> int: + return 0x0000FFFD + + @ChipUtility.classproperty + def attribute_type(cls) -> ClusterObjectFieldDescriptor: + return ClusterObjectFieldDescriptor(Type=uint) + + value: 'uint' = 0 + + @dataclass class Chime(Cluster): id: typing.ClassVar[int] = 0x00000556 diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm index 986f9776ba..a2878cf511 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeSpecifiedCheck.mm @@ -5912,6 +5912,36 @@ static BOOL AttributeIsSpecifiedInContentAppObserverCluster(AttributeId aAttribu } } } +static BOOL AttributeIsSpecifiedInWebRTCTransportProviderCluster(AttributeId aAttributeId) +{ + using namespace Clusters::WebRTCTransportProvider; + switch (aAttributeId) { + case Attributes::CurrentSessions::Id: { + return YES; + } + case Attributes::GeneratedCommandList::Id: { + return YES; + } + case Attributes::AcceptedCommandList::Id: { + return YES; + } + case Attributes::EventList::Id: { + return YES; + } + case Attributes::AttributeList::Id: { + return YES; + } + case Attributes::FeatureMap::Id: { + return YES; + } + case Attributes::ClusterRevision::Id: { + return YES; + } + default: { + return NO; + } + } +} static BOOL AttributeIsSpecifiedInChimeCluster(AttributeId aAttributeId) { using namespace Clusters::Chime; @@ -6681,6 +6711,9 @@ BOOL MTRAttributeIsSpecified(ClusterId aClusterId, AttributeId aAttributeId) case Clusters::ContentAppObserver::Id: { return AttributeIsSpecifiedInContentAppObserverCluster(aAttributeId); } + case Clusters::WebRTCTransportProvider::Id: { + return AttributeIsSpecifiedInWebRTCTransportProviderCluster(aAttributeId); + } case Clusters::Chime::Id: { return AttributeIsSpecifiedInChimeCluster(aAttributeId); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm index 630c612e70..ae28957899 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRAttributeTLVValueDecoder.mm @@ -16899,6 +16899,59 @@ static id _Nullable DecodeAttributeValueForContentAppObserverCluster(AttributeId *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; return nil; } +static id _Nullable DecodeAttributeValueForWebRTCTransportProviderCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::WebRTCTransportProvider; + switch (aAttributeId) { + case Attributes::CurrentSessions::Id: { + using TypeInfo = Attributes::CurrentSessions::TypeInfo; + TypeInfo::DecodableType cppValue; + *aError = DataModel::Decode(aReader, cppValue); + if (*aError != CHIP_NO_ERROR) { + return nil; + } + NSArray * _Nonnull value; + { // Scope for our temporary variables + auto * array_0 = [NSMutableArray new]; + auto iter_0 = cppValue.begin(); + while (iter_0.Next()) { + auto & entry_0 = iter_0.GetValue(); + MTRWebRTCTransportProviderClusterWebRTCSessionStruct * newElement_0; + newElement_0 = [MTRWebRTCTransportProviderClusterWebRTCSessionStruct new]; + newElement_0.id = [NSNumber numberWithUnsignedShort:entry_0.id]; + newElement_0.peerNodeID = [NSNumber numberWithUnsignedLongLong:entry_0.peerNodeID]; + newElement_0.peerFabricIndex = [NSNumber numberWithUnsignedChar:entry_0.peerFabricIndex]; + newElement_0.streamType = [NSNumber numberWithUnsignedChar:chip::to_underlying(entry_0.streamType)]; + if (entry_0.videoStreamID.IsNull()) { + newElement_0.videoStreamID = nil; + } else { + newElement_0.videoStreamID = [NSNumber numberWithUnsignedShort:entry_0.videoStreamID.Value()]; + } + if (entry_0.audioStreamID.IsNull()) { + newElement_0.audioStreamID = nil; + } else { + newElement_0.audioStreamID = [NSNumber numberWithUnsignedShort:entry_0.audioStreamID.Value()]; + } + newElement_0.metadataOptions = [NSNumber numberWithUnsignedChar:entry_0.metadataOptions.Raw()]; + [array_0 addObject:newElement_0]; + } + CHIP_ERROR err = iter_0.GetStatus(); + if (err != CHIP_NO_ERROR) { + *aError = err; + return nil; + } + value = array_0; + } + return value; + } + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_ATTRIBUTE_PATH_IB; + return nil; +} static id _Nullable DecodeAttributeValueForChimeCluster(AttributeId aAttributeId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::Chime; @@ -19075,6 +19128,9 @@ id _Nullable MTRDecodeAttributeValue(const ConcreteAttributePath & aPath, TLV::T case Clusters::ContentAppObserver::Id: { return DecodeAttributeValueForContentAppObserverCluster(aPath.mAttributeId, aReader, aError); } + case Clusters::WebRTCTransportProvider::Id: { + return DecodeAttributeValueForWebRTCTransportProviderCluster(aPath.mAttributeId, aReader, aError); + } case Clusters::Chime::Id: { return DecodeAttributeValueForChimeCluster(aPath.mAttributeId, aReader, aError); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h index 7bbdbbee20..36c879b528 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.h @@ -14756,6 +14756,104 @@ MTR_PROVISIONALLY_AVAILABLE @end +/** + * Cluster WebRTC Transport Provider + * + * The WebRTC transport provider cluster provides a way for stream providers (e.g. Cameras) to stream or receive their data through WebRTC. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRBaseClusterWebRTCTransportProvider : MTRGenericBaseCluster + +/** + * Command SolicitOffer + * + * Requests that the Provider initiates a new session with the Offer / Answer flow in a way that allows for options to be passed and work with devices needing the standby flow. + */ +- (void)solicitOfferWithParams:(MTRWebRTCTransportProviderClusterSolicitOfferParams *)params completion:(void (^)(MTRWebRTCTransportProviderClusterSolicitOfferResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +/** + * Command ProvideOffer + * + * This command allows an SDP Offer to be set and start a new session. + */ +- (void)provideOfferWithParams:(MTRWebRTCTransportProviderClusterProvideOfferParams *)params completion:(void (^)(MTRWebRTCTransportProviderClusterProvideOfferResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +/** + * Command ProvideAnswer + * + * This command SHALL be initiated from a Node in response to an Offer that was previously received from a remote peer. + */ +- (void)provideAnswerWithParams:(MTRWebRTCTransportProviderClusterProvideAnswerParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +/** + * Command ProvideICECandidate + * + * This command allows for https://www.rfc-editor.org/rfc/rfc8839#section-4.2.1.2 nominated after the initial Offer / Answer exchange to be added to a session during the gathering phase. + */ +- (void)provideICECandidateWithParams:(MTRWebRTCTransportProviderClusterProvideICECandidateParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +/** + * Command EndSession + * + * This command instructs the stream provider to end the WebRTC session. + */ +- (void)endSessionWithParams:(MTRWebRTCTransportProviderClusterEndSessionParams *)params completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeCurrentSessionsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeCurrentSessionsWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeCurrentSessionsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams *)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler MTR_PROVISIONALLY_AVAILABLE; ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRBaseClusterWebRTCTransportProvider (Availability) + +/** + * For all instance methods (reads, writes, commands) that take a completion, + * the completion will be called on the provided queue. + */ +- (instancetype _Nullable)initWithDevice:(MTRBaseDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + /** * Cluster Chime * @@ -20174,6 +20272,32 @@ typedef NS_ENUM(uint8_t, MTRContentAppObserverStatus) { MTRContentAppObserverStatusUnexpectedData MTR_PROVISIONALLY_AVAILABLE = 0x01, } MTR_PROVISIONALLY_AVAILABLE; +typedef NS_ENUM(uint8_t, MTRWebRTCTransportProviderStreamType) { + MTRWebRTCTransportProviderStreamTypeInternal MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTRWebRTCTransportProviderStreamTypeRecording MTR_PROVISIONALLY_AVAILABLE = 0x01, + MTRWebRTCTransportProviderStreamTypeAnalysis MTR_PROVISIONALLY_AVAILABLE = 0x02, + MTRWebRTCTransportProviderStreamTypeLiveView MTR_PROVISIONALLY_AVAILABLE = 0x03, +} MTR_PROVISIONALLY_AVAILABLE; + +typedef NS_ENUM(uint8_t, MTRWebRTCTransportProviderWebRTCEndReason) { + MTRWebRTCTransportProviderWebRTCEndReasonIceFailed MTR_PROVISIONALLY_AVAILABLE = 0x00, + MTRWebRTCTransportProviderWebRTCEndReasonIceTimeout MTR_PROVISIONALLY_AVAILABLE = 0x01, + MTRWebRTCTransportProviderWebRTCEndReasonUserHangup MTR_PROVISIONALLY_AVAILABLE = 0x02, + MTRWebRTCTransportProviderWebRTCEndReasonUserBusy MTR_PROVISIONALLY_AVAILABLE = 0x03, + MTRWebRTCTransportProviderWebRTCEndReasonReplaced MTR_PROVISIONALLY_AVAILABLE = 0x04, + MTRWebRTCTransportProviderWebRTCEndReasonNoUserMedia MTR_PROVISIONALLY_AVAILABLE = 0x05, + MTRWebRTCTransportProviderWebRTCEndReasonInviteTimeout MTR_PROVISIONALLY_AVAILABLE = 0x06, + MTRWebRTCTransportProviderWebRTCEndReasonAnsweredElsewhere MTR_PROVISIONALLY_AVAILABLE = 0x07, + MTRWebRTCTransportProviderWebRTCEndReasonOutOfResources MTR_PROVISIONALLY_AVAILABLE = 0x08, + MTRWebRTCTransportProviderWebRTCEndReasonMediaTimeout MTR_PROVISIONALLY_AVAILABLE = 0x09, + MTRWebRTCTransportProviderWebRTCEndReasonLowPower MTR_PROVISIONALLY_AVAILABLE = 0x0A, + MTRWebRTCTransportProviderWebRTCEndReasonUnknownReason MTR_PROVISIONALLY_AVAILABLE = 0x0B, +} MTR_PROVISIONALLY_AVAILABLE; + +typedef NS_OPTIONS(uint8_t, MTRWebRTCTransportProviderWebRTCMetadataOptions) { + MTRWebRTCTransportProviderWebRTCMetadataOptionsDataTLV MTR_PROVISIONALLY_AVAILABLE = 0x1, +} MTR_PROVISIONALLY_AVAILABLE; + typedef NS_OPTIONS(uint32_t, MTRCommissionerControlSupportedDeviceCategoryBitmap) { MTRCommissionerControlSupportedDeviceCategoryBitmapFabricSynchronization MTR_PROVISIONALLY_AVAILABLE = 0x1, } MTR_PROVISIONALLY_AVAILABLE; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm index f6899e0920..5bee560bd0 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRBaseClusters.mm @@ -102085,6 +102085,383 @@ + (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheC @end +@implementation MTRBaseClusterWebRTCTransportProvider + +- (void)solicitOfferWithParams:(MTRWebRTCTransportProviderClusterSolicitOfferParams *)params completion:(void (^)(MTRWebRTCTransportProviderClusterSolicitOfferResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRWebRTCTransportProviderClusterSolicitOfferParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = WebRTCTransportProvider::Commands::SolicitOffer::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRWebRTCTransportProviderClusterSolicitOfferResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} +- (void)provideOfferWithParams:(MTRWebRTCTransportProviderClusterProvideOfferParams *)params completion:(void (^)(MTRWebRTCTransportProviderClusterProvideOfferResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRWebRTCTransportProviderClusterProvideOfferParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = WebRTCTransportProvider::Commands::ProvideOffer::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRWebRTCTransportProviderClusterProvideOfferResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} +- (void)provideAnswerWithParams:(MTRWebRTCTransportProviderClusterProvideAnswerParams *)params completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRWebRTCTransportProviderClusterProvideAnswerParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = WebRTCTransportProvider::Commands::ProvideAnswer::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} +- (void)provideICECandidateWithParams:(MTRWebRTCTransportProviderClusterProvideICECandidateParams *)params completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRWebRTCTransportProviderClusterProvideICECandidateParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = WebRTCTransportProvider::Commands::ProvideICECandidate::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} +- (void)endSessionWithParams:(MTRWebRTCTransportProviderClusterEndSessionParams *)params completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRWebRTCTransportProviderClusterEndSessionParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = WebRTCTransportProvider::Commands::EndSession::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)readAttributeCurrentSessionsWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WebRTCTransportProvider::Attributes::CurrentSessions::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeCurrentSessionsWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WebRTCTransportProvider::Attributes::CurrentSessions::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeCurrentSessionsWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WebRTCTransportProvider::Attributes::CurrentSessions::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeGeneratedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WebRTCTransportProvider::Attributes::GeneratedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeGeneratedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WebRTCTransportProvider::Attributes::GeneratedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeGeneratedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WebRTCTransportProvider::Attributes::GeneratedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAcceptedCommandListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WebRTCTransportProvider::Attributes::AcceptedCommandList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAcceptedCommandListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WebRTCTransportProvider::Attributes::AcceptedCommandList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAcceptedCommandListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WebRTCTransportProvider::Attributes::AcceptedCommandList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeEventListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WebRTCTransportProvider::Attributes::EventList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeEventListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WebRTCTransportProvider::Attributes::EventList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeEventListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WebRTCTransportProvider::Attributes::EventList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeAttributeListWithCompletion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WebRTCTransportProvider::Attributes::AttributeList::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeAttributeListWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WebRTCTransportProvider::Attributes::AttributeList::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeAttributeListWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSArray * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WebRTCTransportProvider::Attributes::AttributeList::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeFeatureMapWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WebRTCTransportProvider::Attributes::FeatureMap::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeFeatureMapWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WebRTCTransportProvider::Attributes::FeatureMap::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeFeatureMapWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WebRTCTransportProvider::Attributes::FeatureMap::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +- (void)readAttributeClusterRevisionWithCompletion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WebRTCTransportProvider::Attributes::ClusterRevision::TypeInfo; + [self.device _readKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:nil + queue:self.callbackQueue + completion:completion]; +} + +- (void)subscribeAttributeClusterRevisionWithParams:(MTRSubscribeParams * _Nonnull)params + subscriptionEstablished:(MTRSubscriptionEstablishedHandler _Nullable)subscriptionEstablished + reportHandler:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))reportHandler +{ + using TypeInfo = WebRTCTransportProvider::Attributes::ClusterRevision::TypeInfo; + [self.device _subscribeToKnownAttributeWithEndpointID:self.endpointID + clusterID:@(TypeInfo::GetClusterId()) + attributeID:@(TypeInfo::GetAttributeId()) + params:params + queue:self.callbackQueue + reportHandler:reportHandler + subscriptionEstablished:subscriptionEstablished]; +} + ++ (void)readAttributeClusterRevisionWithClusterStateCache:(MTRClusterStateCacheContainer *)clusterStateCacheContainer endpoint:(NSNumber *)endpoint queue:(dispatch_queue_t)queue completion:(void (^)(NSNumber * _Nullable value, NSError * _Nullable error))completion +{ + using TypeInfo = WebRTCTransportProvider::Attributes::ClusterRevision::TypeInfo; + [clusterStateCacheContainer + _readKnownCachedAttributeWithEndpointID:static_cast([endpoint unsignedShortValue]) + clusterID:TypeInfo::GetClusterId() + attributeID:TypeInfo::GetAttributeId() + queue:queue + completion:completion]; +} + +@end + @implementation MTRBaseClusterChime - (void)playChimeSoundWithCompletion:(MTRStatusCompletion)completion diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h index 2b1d5e5dbf..97e0c30e92 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterConstants.h @@ -197,6 +197,7 @@ typedef NS_ENUM(uint32_t, MTRClusterIDType) { MTRClusterIDTypeAccountLoginID MTR_AVAILABLE(ios(16.4), macos(13.3), watchos(9.4), tvos(16.4)) = 0x0000050E, MTRClusterIDTypeContentControlID MTR_PROVISIONALLY_AVAILABLE = 0x0000050F, MTRClusterIDTypeContentAppObserverID MTR_PROVISIONALLY_AVAILABLE = 0x00000510, + MTRClusterIDTypeWebRTCTransportProviderID MTR_PROVISIONALLY_AVAILABLE = 0x00000553, MTRClusterIDTypeChimeID MTR_PROVISIONALLY_AVAILABLE = 0x00000556, MTRClusterIDTypeEcosystemInformationID MTR_PROVISIONALLY_AVAILABLE = 0x00000750, MTRClusterIDTypeCommissionerControlID MTR_PROVISIONALLY_AVAILABLE = 0x00000751, @@ -4739,6 +4740,15 @@ typedef NS_ENUM(uint32_t, MTRAttributeIDType) { MTRAttributeIDTypeClusterContentAppObserverAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, MTRAttributeIDTypeClusterContentAppObserverAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster WebRTCTransportProvider attributes + MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeCurrentSessionsID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, + MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeGeneratedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeGeneratedCommandListID, + MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeAcceptedCommandListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAcceptedCommandListID, + MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeEventListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeEventListID, + MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeAttributeListID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeAttributeListID, + MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeFeatureMapID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeFeatureMapID, + MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeClusterRevisionID MTR_PROVISIONALLY_AVAILABLE = MTRAttributeIDTypeGlobalAttributeClusterRevisionID, + // Cluster Chime attributes MTRAttributeIDTypeClusterChimeAttributeInstalledChimeSoundsID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRAttributeIDTypeClusterChimeAttributeActiveChimeIDID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, @@ -6943,6 +6953,15 @@ typedef NS_ENUM(uint32_t, MTRCommandIDType) { MTRCommandIDTypeClusterContentAppObserverCommandContentAppMessageID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, MTRCommandIDTypeClusterContentAppObserverCommandContentAppMessageResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + // Cluster WebRTCTransportProvider commands + MTRCommandIDTypeClusterWebRTCTransportProviderCommandSolicitOfferID MTR_PROVISIONALLY_AVAILABLE = 0x00000001, + MTRCommandIDTypeClusterWebRTCTransportProviderCommandSolicitOfferResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000002, + MTRCommandIDTypeClusterWebRTCTransportProviderCommandProvideOfferID MTR_PROVISIONALLY_AVAILABLE = 0x00000003, + MTRCommandIDTypeClusterWebRTCTransportProviderCommandProvideOfferResponseID MTR_PROVISIONALLY_AVAILABLE = 0x00000004, + MTRCommandIDTypeClusterWebRTCTransportProviderCommandProvideAnswerID MTR_PROVISIONALLY_AVAILABLE = 0x00000005, + MTRCommandIDTypeClusterWebRTCTransportProviderCommandProvideICECandidateID MTR_PROVISIONALLY_AVAILABLE = 0x00000006, + MTRCommandIDTypeClusterWebRTCTransportProviderCommandEndSessionID MTR_PROVISIONALLY_AVAILABLE = 0x00000007, + // Cluster Chime commands MTRCommandIDTypeClusterChimeCommandPlayChimeSoundID MTR_PROVISIONALLY_AVAILABLE = 0x00000000, diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm index 51fa18894a..46791f9c12 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusterNames.mm @@ -369,6 +369,9 @@ case MTRClusterIDTypeContentAppObserverID: result = @"ContentAppObserver"; break; + case MTRClusterIDTypeWebRTCTransportProviderID: + result = @"WebRTCTransportProvider"; + break; case MTRClusterIDTypeChimeID: result = @"Chime"; break; @@ -8139,6 +8142,45 @@ } break; + case MTRClusterIDTypeWebRTCTransportProviderID: + + switch (attributeID) { + + // Cluster WebRTCTransportProvider attributes + case MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeCurrentSessionsID: + result = @"CurrentSessions"; + break; + + case MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeGeneratedCommandListID: + result = @"GeneratedCommandList"; + break; + + case MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeAcceptedCommandListID: + result = @"AcceptedCommandList"; + break; + + case MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeEventListID: + result = @"EventList"; + break; + + case MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeAttributeListID: + result = @"AttributeList"; + break; + + case MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeFeatureMapID: + result = @"FeatureMap"; + break; + + case MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeClusterRevisionID: + result = @"ClusterRevision"; + break; + + default: + result = [NSString stringWithFormat:@"", attributeID]; + break; + } + break; + case MTRClusterIDTypeChimeID: switch (attributeID) { @@ -10914,6 +10956,36 @@ } break; + case MTRClusterIDTypeWebRTCTransportProviderID: + + switch (commandID) { + + case MTRCommandIDTypeClusterWebRTCTransportProviderCommandSolicitOfferID: + result = @"SolicitOffer"; + break; + + case MTRCommandIDTypeClusterWebRTCTransportProviderCommandProvideOfferID: + result = @"ProvideOffer"; + break; + + case MTRCommandIDTypeClusterWebRTCTransportProviderCommandProvideAnswerID: + result = @"ProvideAnswer"; + break; + + case MTRCommandIDTypeClusterWebRTCTransportProviderCommandProvideICECandidateID: + result = @"ProvideICECandidate"; + break; + + case MTRCommandIDTypeClusterWebRTCTransportProviderCommandEndSessionID: + result = @"EndSession"; + break; + + default: + result = [NSString stringWithFormat:@"", commandID]; + break; + } + break; + case MTRClusterIDTypeChimeID: switch (commandID) { @@ -12526,6 +12598,24 @@ } break; + case MTRClusterIDTypeWebRTCTransportProviderID: + + switch (commandID) { + + case MTRCommandIDTypeClusterWebRTCTransportProviderCommandSolicitOfferResponseID: + result = @"SolicitOfferResponse"; + break; + + case MTRCommandIDTypeClusterWebRTCTransportProviderCommandProvideOfferResponseID: + result = @"ProvideOfferResponse"; + break; + + default: + result = [NSString stringWithFormat:@"", commandID]; + break; + } + break; + case MTRClusterIDTypeChimeID: switch (commandID) { @@ -14287,6 +14377,16 @@ } break; + case MTRClusterIDTypeWebRTCTransportProviderID: + + switch (eventID) { + + default: + result = [NSString stringWithFormat:@"", eventID]; + break; + } + break; + case MTRClusterIDTypeChimeID: switch (eventID) { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h index 964282c1ce..43a909b7e4 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.h @@ -6824,6 +6824,50 @@ MTR_PROVISIONALLY_AVAILABLE @end +/** + * Cluster WebRTC Transport Provider + * The WebRTC transport provider cluster provides a way for stream providers (e.g. Cameras) to stream or receive their data through WebRTC. + */ +MTR_PROVISIONALLY_AVAILABLE +@interface MTRClusterWebRTCTransportProvider : MTRGenericCluster + +- (void)solicitOfferWithParams:(MTRWebRTCTransportProviderClusterSolicitOfferParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRWebRTCTransportProviderClusterSolicitOfferResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)provideOfferWithParams:(MTRWebRTCTransportProviderClusterProvideOfferParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRWebRTCTransportProviderClusterProvideOfferResponseParams * _Nullable data, NSError * _Nullable error))completion MTR_PROVISIONALLY_AVAILABLE; +- (void)provideAnswerWithParams:(MTRWebRTCTransportProviderClusterProvideAnswerParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)provideICECandidateWithParams:(MTRWebRTCTransportProviderClusterProvideICECandidateParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; +- (void)endSessionWithParams:(MTRWebRTCTransportProviderClusterEndSessionParams *)params expectedValues:(NSArray *> * _Nullable)expectedDataValueDictionaries expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeCurrentSessionsWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params MTR_PROVISIONALLY_AVAILABLE; + +- (instancetype)init NS_UNAVAILABLE; ++ (instancetype)new NS_UNAVAILABLE; + +@end + +@interface MTRClusterWebRTCTransportProvider (Availability) + +/** + * For all instance methods that take a completion (i.e. command invocations), + * the completion will be called on the provided queue. + */ +- (instancetype _Nullable)initWithDevice:(MTRDevice *)device + endpointID:(NSNumber *)endpointID + queue:(dispatch_queue_t)queue MTR_PROVISIONALLY_AVAILABLE; + +@end + /** * Cluster Chime * This cluster provides facilities to configure and play Chime sounds, such as those used in a doorbell. diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm index 0e905297ab..5864634bb6 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRClusters.mm @@ -19549,6 +19549,180 @@ - (void)contentAppMessageWithParams:(MTRContentAppObserverClusterContentAppMessa @end +@implementation MTRClusterWebRTCTransportProvider + +- (void)solicitOfferWithParams:(MTRWebRTCTransportProviderClusterSolicitOfferParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRWebRTCTransportProviderClusterSolicitOfferResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRWebRTCTransportProviderClusterSolicitOfferParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = WebRTCTransportProvider::Commands::SolicitOffer::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRWebRTCTransportProviderClusterSolicitOfferResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)provideOfferWithParams:(MTRWebRTCTransportProviderClusterProvideOfferParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(void (^)(MTRWebRTCTransportProviderClusterProvideOfferResponseParams * _Nullable data, NSError * _Nullable error))completion +{ + if (params == nil) { + params = [[MTRWebRTCTransportProviderClusterProvideOfferParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(response, error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = WebRTCTransportProvider::Commands::ProvideOffer::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:MTRWebRTCTransportProviderClusterProvideOfferResponseParams.class + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)provideAnswerWithParams:(MTRWebRTCTransportProviderClusterProvideAnswerParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRWebRTCTransportProviderClusterProvideAnswerParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = WebRTCTransportProvider::Commands::ProvideAnswer::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)provideICECandidateWithParams:(MTRWebRTCTransportProviderClusterProvideICECandidateParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRWebRTCTransportProviderClusterProvideICECandidateParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = WebRTCTransportProvider::Commands::ProvideICECandidate::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} + +- (void)endSessionWithParams:(MTRWebRTCTransportProviderClusterEndSessionParams *)params expectedValues:(NSArray *> * _Nullable)expectedValues expectedValueInterval:(NSNumber * _Nullable)expectedValueIntervalMs completion:(MTRStatusCompletion)completion +{ + if (params == nil) { + params = [[MTRWebRTCTransportProviderClusterEndSessionParams + alloc] init]; + } + + auto responseHandler = ^(id _Nullable response, NSError * _Nullable error) { + completion(error); + }; + + auto * timedInvokeTimeoutMs = params.timedInvokeTimeoutMs; + + using RequestType = WebRTCTransportProvider::Commands::EndSession::Type; + [self.device _invokeKnownCommandWithEndpointID:self.endpointID + clusterID:@(RequestType::GetClusterId()) + commandID:@(RequestType::GetCommandId()) + commandPayload:params + expectedValues:expectedValues + expectedValueInterval:expectedValueIntervalMs + timedInvokeTimeout:timedInvokeTimeoutMs + serverSideProcessingTimeout:params.serverSideProcessingTimeout + responseClass:nil + queue:self.callbackQueue + completion:responseHandler]; +} + +- (NSDictionary * _Nullable)readAttributeCurrentSessionsWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWebRTCTransportProviderID) attributeID:@(MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeCurrentSessionsID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeGeneratedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWebRTCTransportProviderID) attributeID:@(MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeGeneratedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAcceptedCommandListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWebRTCTransportProviderID) attributeID:@(MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeAcceptedCommandListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeEventListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWebRTCTransportProviderID) attributeID:@(MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeEventListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeAttributeListWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWebRTCTransportProviderID) attributeID:@(MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeAttributeListID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeFeatureMapWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWebRTCTransportProviderID) attributeID:@(MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeFeatureMapID) params:params]; +} + +- (NSDictionary * _Nullable)readAttributeClusterRevisionWithParams:(MTRReadParams * _Nullable)params +{ + return [self.device readAttributeWithEndpointID:self.endpointID clusterID:@(MTRClusterIDTypeWebRTCTransportProviderID) attributeID:@(MTRAttributeIDTypeClusterWebRTCTransportProviderAttributeClusterRevisionID) params:params]; +} + +@end + @implementation MTRClusterChime - (void)playChimeSoundWithExpectedValues:(NSArray *> *)expectedValues expectedValueInterval:(NSNumber *)expectedValueIntervalMs completion:(MTRStatusCompletion)completion diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h index 27a21e0b80..2aeb25d7a6 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.h @@ -10835,6 +10835,234 @@ MTR_PROVISIONALLY_AVAILABLE error:(NSError * __autoreleasing *)error MTR_PROVISIONALLY_AVAILABLE; @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRWebRTCTransportProviderClusterSolicitOfferParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull streamType MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nullable videoStreamID MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nullable audioStreamID MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSArray * _Nullable iceServers MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSString * _Nullable iceTransportPolicy MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nullable metadataOptions MTR_PROVISIONALLY_AVAILABLE; +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRWebRTCTransportProviderClusterSolicitOfferResponseParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull webRTCSessionID MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull deferredOffer MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nullable videoStreamID MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nullable audioStreamID MTR_PROVISIONALLY_AVAILABLE; + +/** + * Initialize an MTRWebRTCTransportProviderClusterSolicitOfferResponseParams with a response-value dictionary + * of the sort that MTRDeviceResponseHandler would receive. + * + * Will return nil and hand out an error if the response-value dictionary is not + * a command data response or is not the right command response. + * + * Will return nil and hand out an error if the data response does not match the known + * schema for this command. + */ +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRWebRTCTransportProviderClusterProvideOfferParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nullable webRTCSessionID MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSString * _Nonnull sdp MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull streamType MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nullable videoStreamID MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nullable audioStreamID MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSArray * _Nullable iceServers MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSString * _Nullable iceTransportPolicy MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nullable metadataOptions MTR_PROVISIONALLY_AVAILABLE; +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRWebRTCTransportProviderClusterProvideOfferResponseParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull webRTCSessionID MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull videoStreamID MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull audioStreamID MTR_PROVISIONALLY_AVAILABLE; + +/** + * Initialize an MTRWebRTCTransportProviderClusterProvideOfferResponseParams with a response-value dictionary + * of the sort that MTRDeviceResponseHandler would receive. + * + * Will return nil and hand out an error if the response-value dictionary is not + * a command data response or is not the right command response. + * + * Will return nil and hand out an error if the data response does not match the known + * schema for this command. + */ +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRWebRTCTransportProviderClusterProvideAnswerParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull webRTCSessionID MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSString * _Nonnull sdp MTR_PROVISIONALLY_AVAILABLE; +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRWebRTCTransportProviderClusterProvideICECandidateParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull webRTCSessionID MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSString * _Nonnull iceCandidate MTR_PROVISIONALLY_AVAILABLE; +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRWebRTCTransportProviderClusterEndSessionParams : NSObject + +@property (nonatomic, copy) NSNumber * _Nonnull webRTCSessionID MTR_PROVISIONALLY_AVAILABLE; + +@property (nonatomic, copy) NSNumber * _Nonnull reason MTR_PROVISIONALLY_AVAILABLE; +/** + * Controls whether the command is a timed command (using Timed Invoke). + * + * If nil (the default value), a regular invoke is done for commands that do + * not require a timed invoke and a timed invoke with some default timed request + * timeout is done for commands that require a timed invoke. + * + * If not nil, a timed invoke is done, with the provided value used as the timed + * request timeout. The value should be chosen small enough to provide the + * desired security properties but large enough that it will allow a round-trip + * from the sever to the client (for the status response and actual invoke + * request) within the timeout window. + * + */ +@property (nonatomic, copy, nullable) NSNumber * timedInvokeTimeoutMs; + +/** + * Controls how much time, in seconds, we will allow for the server to process the command. + * + * The command will then time out if that much time, plus an allowance for retransmits due to network failures, passes. + * + * If nil, the framework will try to select an appropriate timeout value itself. + */ +@property (nonatomic, copy, nullable) NSNumber * serverSideProcessingTimeout; +@end + MTR_PROVISIONALLY_AVAILABLE @interface MTRChimeClusterPlayChimeSoundParams : NSObject /** diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm index 4783d5b330..a922f58315 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloadsObjc.mm @@ -31337,6 +31337,858 @@ - (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::ContentA @end +@implementation MTRWebRTCTransportProviderClusterSolicitOfferParams +- (instancetype)init +{ + if (self = [super init]) { + + _streamType = @(0); + + _videoStreamID = nil; + + _audioStreamID = nil; + + _iceServers = nil; + + _iceTransportPolicy = nil; + + _metadataOptions = nil; + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRWebRTCTransportProviderClusterSolicitOfferParams alloc] init]; + + other.streamType = self.streamType; + other.videoStreamID = self.videoStreamID; + other.audioStreamID = self.audioStreamID; + other.iceServers = self.iceServers; + other.iceTransportPolicy = self.iceTransportPolicy; + other.metadataOptions = self.metadataOptions; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: streamType:%@; videoStreamID:%@; audioStreamID:%@; iceServers:%@; iceTransportPolicy:%@; metadataOptions:%@; >", NSStringFromClass([self class]), _streamType, _videoStreamID, _audioStreamID, _iceServers, _iceTransportPolicy, _metadataOptions]; + return descriptionString; +} + +@end + +@implementation MTRWebRTCTransportProviderClusterSolicitOfferParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::WebRTCTransportProvider::Commands::SolicitOffer::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.streamType = static_cast>(self.streamType.unsignedCharValue); + } + { + if (self.videoStreamID != nil) { + auto & definedValue_0 = encodableStruct.videoStreamID.Emplace(); + if (self.videoStreamID == nil) { + definedValue_0.SetNull(); + } else { + auto & nonNullValue_1 = definedValue_0.SetNonNull(); + nonNullValue_1 = self.videoStreamID.unsignedShortValue; + } + } + } + { + if (self.audioStreamID != nil) { + auto & definedValue_0 = encodableStruct.audioStreamID.Emplace(); + if (self.audioStreamID == nil) { + definedValue_0.SetNull(); + } else { + auto & nonNullValue_1 = definedValue_0.SetNonNull(); + nonNullValue_1 = self.audioStreamID.unsignedShortValue; + } + } + } + { + if (self.iceServers != nil) { + auto & definedValue_0 = encodableStruct.ICEServers.Emplace(); + { + using ListType_1 = std::remove_reference_t; + using ListMemberType_1 = ListMemberTypeGetter::Type; + if (self.iceServers.count != 0) { + auto * listHolder_1 = new ListHolder(self.iceServers.count); + if (listHolder_1 == nullptr || listHolder_1->mList == nullptr) { + return CHIP_ERROR_INVALID_ARGUMENT; + } + listFreer.add(listHolder_1); + for (size_t i_1 = 0; i_1 < self.iceServers.count; ++i_1) { + if (![self.iceServers[i_1] isKindOfClass:[MTRWebRTCTransportProviderClusterICEServerStruct class]]) { + // Wrong kind of value. + return CHIP_ERROR_INVALID_ARGUMENT; + } + auto element_1 = (MTRWebRTCTransportProviderClusterICEServerStruct *) self.iceServers[i_1]; + { + using ListType_3 = std::remove_reference_tmList[i_1].urls)>; + using ListMemberType_3 = ListMemberTypeGetter::Type; + if (element_1.urls.count != 0) { + auto * listHolder_3 = new ListHolder(element_1.urls.count); + if (listHolder_3 == nullptr || listHolder_3->mList == nullptr) { + return CHIP_ERROR_INVALID_ARGUMENT; + } + listFreer.add(listHolder_3); + for (size_t i_3 = 0; i_3 < element_1.urls.count; ++i_3) { + if (![element_1.urls[i_3] isKindOfClass:[NSString class]]) { + // Wrong kind of value. + return CHIP_ERROR_INVALID_ARGUMENT; + } + auto element_3 = (NSString *) element_1.urls[i_3]; + listHolder_3->mList[i_3] = AsCharSpan(element_3); + } + listHolder_1->mList[i_1].urls = ListType_3(listHolder_3->mList, element_1.urls.count); + } else { + listHolder_1->mList[i_1].urls = ListType_3(); + } + } + if (element_1.username != nil) { + auto & definedValue_3 = listHolder_1->mList[i_1].username.Emplace(); + definedValue_3 = AsCharSpan(element_1.username); + } + if (element_1.credential != nil) { + auto & definedValue_3 = listHolder_1->mList[i_1].credential.Emplace(); + definedValue_3 = AsCharSpan(element_1.credential); + } + if (element_1.caid != nil) { + auto & definedValue_3 = listHolder_1->mList[i_1].caid.Emplace(); + definedValue_3 = element_1.caid.unsignedShortValue; + } + } + definedValue_0 = ListType_1(listHolder_1->mList, self.iceServers.count); + } else { + definedValue_0 = ListType_1(); + } + } + } + } + { + if (self.iceTransportPolicy != nil) { + auto & definedValue_0 = encodableStruct.ICETransportPolicy.Emplace(); + definedValue_0 = AsCharSpan(self.iceTransportPolicy); + } + } + { + if (self.metadataOptions != nil) { + auto & definedValue_0 = encodableStruct.metadataOptions.Emplace(); + definedValue_0 = static_cast>(self.metadataOptions.unsignedCharValue); + } + } + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRWebRTCTransportProviderClusterSolicitOfferResponseParams +- (instancetype)init +{ + if (self = [super init]) { + + _webRTCSessionID = @(0); + + _deferredOffer = @(0); + + _videoStreamID = nil; + + _audioStreamID = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRWebRTCTransportProviderClusterSolicitOfferResponseParams alloc] init]; + + other.webRTCSessionID = self.webRTCSessionID; + other.deferredOffer = self.deferredOffer; + other.videoStreamID = self.videoStreamID; + other.audioStreamID = self.audioStreamID; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: webRTCSessionID:%@; deferredOffer:%@; videoStreamID:%@; audioStreamID:%@; >", NSStringFromClass([self class]), _webRTCSessionID, _deferredOffer, _videoStreamID, _audioStreamID]; + return descriptionString; +} + +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error +{ + if (!(self = [super init])) { + return nil; + } + + using DecodableType = chip::app::Clusters::WebRTCTransportProvider::Commands::SolicitOfferResponse::DecodableType; + chip::System::PacketBufferHandle buffer = [MTRBaseDevice _responseDataForCommand:responseValue + clusterID:DecodableType::GetClusterId() + commandID:DecodableType::GetCommandId() + error:error]; + if (buffer.IsNull()) { + return nil; + } + + chip::TLV::TLVReader reader; + reader.Init(buffer->Start(), buffer->DataLength()); + + CHIP_ERROR err = reader.Next(chip::TLV::AnonymousTag()); + if (err == CHIP_NO_ERROR) { + DecodableType decodedStruct; + err = chip::app::DataModel::Decode(reader, decodedStruct); + if (err == CHIP_NO_ERROR) { + err = [self _setFieldsFromDecodableStruct:decodedStruct]; + if (err == CHIP_NO_ERROR) { + return self; + } + } + } + + NSString * errorStr = [NSString stringWithFormat:@"Command payload decoding failed: %s", err.AsString()]; + MTR_LOG_ERROR("%s", errorStr.UTF8String); + if (error != nil) { + NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : NSLocalizedString(errorStr, nil) }; + *error = [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeSchemaMismatch userInfo:userInfo]; + } + return nil; +} + +@end + +@implementation MTRWebRTCTransportProviderClusterSolicitOfferResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::WebRTCTransportProvider::Commands::SolicitOfferResponse::DecodableType &)decodableStruct +{ + { + self.webRTCSessionID = [NSNumber numberWithUnsignedShort:decodableStruct.webRTCSessionID]; + } + { + self.deferredOffer = [NSNumber numberWithBool:decodableStruct.deferredOffer]; + } + { + if (decodableStruct.videoStreamID.HasValue()) { + if (decodableStruct.videoStreamID.Value().IsNull()) { + self.videoStreamID = nil; + } else { + self.videoStreamID = [NSNumber numberWithUnsignedShort:decodableStruct.videoStreamID.Value().Value()]; + } + } else { + self.videoStreamID = nil; + } + } + { + if (decodableStruct.audioStreamID.HasValue()) { + if (decodableStruct.audioStreamID.Value().IsNull()) { + self.audioStreamID = nil; + } else { + self.audioStreamID = [NSNumber numberWithUnsignedShort:decodableStruct.audioStreamID.Value().Value()]; + } + } else { + self.audioStreamID = nil; + } + } + return CHIP_NO_ERROR; +} + +@end + +@implementation MTRWebRTCTransportProviderClusterProvideOfferParams +- (instancetype)init +{ + if (self = [super init]) { + + _webRTCSessionID = nil; + + _sdp = @""; + + _streamType = @(0); + + _videoStreamID = nil; + + _audioStreamID = nil; + + _iceServers = nil; + + _iceTransportPolicy = nil; + + _metadataOptions = nil; + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRWebRTCTransportProviderClusterProvideOfferParams alloc] init]; + + other.webRTCSessionID = self.webRTCSessionID; + other.sdp = self.sdp; + other.streamType = self.streamType; + other.videoStreamID = self.videoStreamID; + other.audioStreamID = self.audioStreamID; + other.iceServers = self.iceServers; + other.iceTransportPolicy = self.iceTransportPolicy; + other.metadataOptions = self.metadataOptions; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: webRTCSessionID:%@; sdp:%@; streamType:%@; videoStreamID:%@; audioStreamID:%@; iceServers:%@; iceTransportPolicy:%@; metadataOptions:%@; >", NSStringFromClass([self class]), _webRTCSessionID, _sdp, _streamType, _videoStreamID, _audioStreamID, _iceServers, _iceTransportPolicy, _metadataOptions]; + return descriptionString; +} + +@end + +@implementation MTRWebRTCTransportProviderClusterProvideOfferParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideOffer::Type encodableStruct; + ListFreer listFreer; + { + if (self.webRTCSessionID == nil) { + encodableStruct.webRTCSessionID.SetNull(); + } else { + auto & nonNullValue_0 = encodableStruct.webRTCSessionID.SetNonNull(); + nonNullValue_0 = self.webRTCSessionID.unsignedShortValue; + } + } + { + encodableStruct.sdp = AsCharSpan(self.sdp); + } + { + encodableStruct.streamType = static_cast>(self.streamType.unsignedCharValue); + } + { + if (self.videoStreamID != nil) { + auto & definedValue_0 = encodableStruct.videoStreamID.Emplace(); + if (self.videoStreamID == nil) { + definedValue_0.SetNull(); + } else { + auto & nonNullValue_1 = definedValue_0.SetNonNull(); + nonNullValue_1 = self.videoStreamID.unsignedShortValue; + } + } + } + { + if (self.audioStreamID != nil) { + auto & definedValue_0 = encodableStruct.audioStreamID.Emplace(); + if (self.audioStreamID == nil) { + definedValue_0.SetNull(); + } else { + auto & nonNullValue_1 = definedValue_0.SetNonNull(); + nonNullValue_1 = self.audioStreamID.unsignedShortValue; + } + } + } + { + if (self.iceServers != nil) { + auto & definedValue_0 = encodableStruct.ICEServers.Emplace(); + { + using ListType_1 = std::remove_reference_t; + using ListMemberType_1 = ListMemberTypeGetter::Type; + if (self.iceServers.count != 0) { + auto * listHolder_1 = new ListHolder(self.iceServers.count); + if (listHolder_1 == nullptr || listHolder_1->mList == nullptr) { + return CHIP_ERROR_INVALID_ARGUMENT; + } + listFreer.add(listHolder_1); + for (size_t i_1 = 0; i_1 < self.iceServers.count; ++i_1) { + if (![self.iceServers[i_1] isKindOfClass:[MTRWebRTCTransportProviderClusterICEServerStruct class]]) { + // Wrong kind of value. + return CHIP_ERROR_INVALID_ARGUMENT; + } + auto element_1 = (MTRWebRTCTransportProviderClusterICEServerStruct *) self.iceServers[i_1]; + { + using ListType_3 = std::remove_reference_tmList[i_1].urls)>; + using ListMemberType_3 = ListMemberTypeGetter::Type; + if (element_1.urls.count != 0) { + auto * listHolder_3 = new ListHolder(element_1.urls.count); + if (listHolder_3 == nullptr || listHolder_3->mList == nullptr) { + return CHIP_ERROR_INVALID_ARGUMENT; + } + listFreer.add(listHolder_3); + for (size_t i_3 = 0; i_3 < element_1.urls.count; ++i_3) { + if (![element_1.urls[i_3] isKindOfClass:[NSString class]]) { + // Wrong kind of value. + return CHIP_ERROR_INVALID_ARGUMENT; + } + auto element_3 = (NSString *) element_1.urls[i_3]; + listHolder_3->mList[i_3] = AsCharSpan(element_3); + } + listHolder_1->mList[i_1].urls = ListType_3(listHolder_3->mList, element_1.urls.count); + } else { + listHolder_1->mList[i_1].urls = ListType_3(); + } + } + if (element_1.username != nil) { + auto & definedValue_3 = listHolder_1->mList[i_1].username.Emplace(); + definedValue_3 = AsCharSpan(element_1.username); + } + if (element_1.credential != nil) { + auto & definedValue_3 = listHolder_1->mList[i_1].credential.Emplace(); + definedValue_3 = AsCharSpan(element_1.credential); + } + if (element_1.caid != nil) { + auto & definedValue_3 = listHolder_1->mList[i_1].caid.Emplace(); + definedValue_3 = element_1.caid.unsignedShortValue; + } + } + definedValue_0 = ListType_1(listHolder_1->mList, self.iceServers.count); + } else { + definedValue_0 = ListType_1(); + } + } + } + } + { + if (self.iceTransportPolicy != nil) { + auto & definedValue_0 = encodableStruct.ICETransportPolicy.Emplace(); + definedValue_0 = AsCharSpan(self.iceTransportPolicy); + } + } + { + if (self.metadataOptions != nil) { + auto & definedValue_0 = encodableStruct.metadataOptions.Emplace(); + definedValue_0 = static_cast>(self.metadataOptions.unsignedCharValue); + } + } + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRWebRTCTransportProviderClusterProvideOfferResponseParams +- (instancetype)init +{ + if (self = [super init]) { + + _webRTCSessionID = @(0); + + _videoStreamID = @(0); + + _audioStreamID = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRWebRTCTransportProviderClusterProvideOfferResponseParams alloc] init]; + + other.webRTCSessionID = self.webRTCSessionID; + other.videoStreamID = self.videoStreamID; + other.audioStreamID = self.audioStreamID; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: webRTCSessionID:%@; videoStreamID:%@; audioStreamID:%@; >", NSStringFromClass([self class]), _webRTCSessionID, _videoStreamID, _audioStreamID]; + return descriptionString; +} + +- (nullable instancetype)initWithResponseValue:(NSDictionary *)responseValue + error:(NSError * __autoreleasing *)error +{ + if (!(self = [super init])) { + return nil; + } + + using DecodableType = chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideOfferResponse::DecodableType; + chip::System::PacketBufferHandle buffer = [MTRBaseDevice _responseDataForCommand:responseValue + clusterID:DecodableType::GetClusterId() + commandID:DecodableType::GetCommandId() + error:error]; + if (buffer.IsNull()) { + return nil; + } + + chip::TLV::TLVReader reader; + reader.Init(buffer->Start(), buffer->DataLength()); + + CHIP_ERROR err = reader.Next(chip::TLV::AnonymousTag()); + if (err == CHIP_NO_ERROR) { + DecodableType decodedStruct; + err = chip::app::DataModel::Decode(reader, decodedStruct); + if (err == CHIP_NO_ERROR) { + err = [self _setFieldsFromDecodableStruct:decodedStruct]; + if (err == CHIP_NO_ERROR) { + return self; + } + } + } + + NSString * errorStr = [NSString stringWithFormat:@"Command payload decoding failed: %s", err.AsString()]; + MTR_LOG_ERROR("%s", errorStr.UTF8String); + if (error != nil) { + NSDictionary * userInfo = @{ NSLocalizedFailureReasonErrorKey : NSLocalizedString(errorStr, nil) }; + *error = [NSError errorWithDomain:MTRErrorDomain code:MTRErrorCodeSchemaMismatch userInfo:userInfo]; + } + return nil; +} + +@end + +@implementation MTRWebRTCTransportProviderClusterProvideOfferResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideOfferResponse::DecodableType &)decodableStruct +{ + { + self.webRTCSessionID = [NSNumber numberWithUnsignedShort:decodableStruct.webRTCSessionID]; + } + { + self.videoStreamID = [NSNumber numberWithUnsignedShort:decodableStruct.videoStreamID]; + } + { + self.audioStreamID = [NSNumber numberWithUnsignedShort:decodableStruct.audioStreamID]; + } + return CHIP_NO_ERROR; +} + +@end + +@implementation MTRWebRTCTransportProviderClusterProvideAnswerParams +- (instancetype)init +{ + if (self = [super init]) { + + _webRTCSessionID = @(0); + + _sdp = @""; + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRWebRTCTransportProviderClusterProvideAnswerParams alloc] init]; + + other.webRTCSessionID = self.webRTCSessionID; + other.sdp = self.sdp; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: webRTCSessionID:%@; sdp:%@; >", NSStringFromClass([self class]), _webRTCSessionID, _sdp]; + return descriptionString; +} + +@end + +@implementation MTRWebRTCTransportProviderClusterProvideAnswerParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideAnswer::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.webRTCSessionID = self.webRTCSessionID.unsignedShortValue; + } + { + encodableStruct.sdp = AsCharSpan(self.sdp); + } + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRWebRTCTransportProviderClusterProvideICECandidateParams +- (instancetype)init +{ + if (self = [super init]) { + + _webRTCSessionID = @(0); + + _iceCandidate = @""; + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRWebRTCTransportProviderClusterProvideICECandidateParams alloc] init]; + + other.webRTCSessionID = self.webRTCSessionID; + other.iceCandidate = self.iceCandidate; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: webRTCSessionID:%@; iceCandidate:%@; >", NSStringFromClass([self class]), _webRTCSessionID, _iceCandidate]; + return descriptionString; +} + +@end + +@implementation MTRWebRTCTransportProviderClusterProvideICECandidateParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideICECandidate::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.webRTCSessionID = self.webRTCSessionID.unsignedShortValue; + } + { + encodableStruct.ICECandidate = AsCharSpan(self.iceCandidate); + } + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + +@implementation MTRWebRTCTransportProviderClusterEndSessionParams +- (instancetype)init +{ + if (self = [super init]) { + + _webRTCSessionID = @(0); + + _reason = @(0); + _timedInvokeTimeoutMs = nil; + _serverSideProcessingTimeout = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone; +{ + auto other = [[MTRWebRTCTransportProviderClusterEndSessionParams alloc] init]; + + other.webRTCSessionID = self.webRTCSessionID; + other.reason = self.reason; + other.timedInvokeTimeoutMs = self.timedInvokeTimeoutMs; + other.serverSideProcessingTimeout = self.serverSideProcessingTimeout; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: webRTCSessionID:%@; reason:%@; >", NSStringFromClass([self class]), _webRTCSessionID, _reason]; + return descriptionString; +} + +@end + +@implementation MTRWebRTCTransportProviderClusterEndSessionParams (InternalMethods) + +- (CHIP_ERROR)_encodeToTLVReader:(chip::System::PacketBufferTLVReader &)reader +{ + chip::app::Clusters::WebRTCTransportProvider::Commands::EndSession::Type encodableStruct; + ListFreer listFreer; + { + encodableStruct.webRTCSessionID = self.webRTCSessionID.unsignedShortValue; + } + { + encodableStruct.reason = static_cast>(self.reason.unsignedCharValue); + } + + auto buffer = chip::System::PacketBufferHandle::New(chip::System::PacketBuffer::kMaxSizeWithoutReserve, 0); + if (buffer.IsNull()) { + return CHIP_ERROR_NO_MEMORY; + } + + chip::System::PacketBufferTLVWriter writer; + // Commands never need chained buffers, since they cannot be chunked. + writer.Init(std::move(buffer), /* useChainedBuffers = */ false); + + ReturnErrorOnFailure(chip::app::DataModel::Encode(writer, chip::TLV::AnonymousTag(), encodableStruct)); + + ReturnErrorOnFailure(writer.Finalize(&buffer)); + + reader.Init(std::move(buffer)); + return reader.Next(chip::TLV::kTLVType_Structure, chip::TLV::AnonymousTag()); +} + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error +{ + chip::System::PacketBufferTLVReader reader; + CHIP_ERROR err = [self _encodeToTLVReader:reader]; + if (err != CHIP_NO_ERROR) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:err]; + } + return nil; + } + + auto decodedObj = MTRDecodeDataValueDictionaryFromCHIPTLV(&reader); + if (decodedObj == nil) { + if (error) { + *error = [MTRError errorForCHIPErrorCode:CHIP_ERROR_INCORRECT_STATE]; + } + } + return decodedObj; +} +@end + @implementation MTRChimeClusterPlayChimeSoundParams - (instancetype)init { diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h index e7c5f23867..144ee696af 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandPayloads_Internal.h @@ -2032,6 +2032,48 @@ NS_ASSUME_NONNULL_BEGIN @end +@interface MTRWebRTCTransportProviderClusterSolicitOfferParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRWebRTCTransportProviderClusterSolicitOfferResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::WebRTCTransportProvider::Commands::SolicitOfferResponse::DecodableType &)decodableStruct; + +@end + +@interface MTRWebRTCTransportProviderClusterProvideOfferParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRWebRTCTransportProviderClusterProvideOfferResponseParams (InternalMethods) + +- (CHIP_ERROR)_setFieldsFromDecodableStruct:(const chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideOfferResponse::DecodableType &)decodableStruct; + +@end + +@interface MTRWebRTCTransportProviderClusterProvideAnswerParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRWebRTCTransportProviderClusterProvideICECandidateParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + +@interface MTRWebRTCTransportProviderClusterEndSessionParams (InternalMethods) + +- (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; + +@end + @interface MTRChimeClusterPlayChimeSoundParams (InternalMethods) - (NSDictionary * _Nullable)_encodeAsDataValue:(NSError * __autoreleasing *)error; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm index 6b5fed7921..91f69fd4e1 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRCommandTimedCheck.mm @@ -1124,6 +1124,15 @@ static BOOL CommandNeedsTimedInvokeInContentAppObserverCluster(AttributeId aAttr } } } +static BOOL CommandNeedsTimedInvokeInWebRTCTransportProviderCluster(AttributeId aAttributeId) +{ + using namespace Clusters::WebRTCTransportProvider; + switch (aAttributeId) { + default: { + return NO; + } + } +} static BOOL CommandNeedsTimedInvokeInChimeCluster(AttributeId aAttributeId) { using namespace Clusters::Chime; @@ -1521,6 +1530,9 @@ BOOL MTRCommandNeedsTimedInvoke(NSNumber * _Nonnull aClusterID, NSNumber * _Nonn case Clusters::ContentAppObserver::Id: { return CommandNeedsTimedInvokeInContentAppObserverCluster(commandID); } + case Clusters::WebRTCTransportProvider::Id: { + return CommandNeedsTimedInvokeInWebRTCTransportProviderCluster(commandID); + } case Clusters::Chime::Id: { return CommandNeedsTimedInvokeInChimeCluster(commandID); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm index d3163c2aa1..5a10da85b1 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTREventTLVValueDecoder.mm @@ -4543,6 +4543,18 @@ static id _Nullable DecodeEventPayloadForContentAppObserverCluster(EventId aEven *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; return nil; } +static id _Nullable DecodeEventPayloadForWebRTCTransportProviderCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) +{ + using namespace Clusters::WebRTCTransportProvider; + switch (aEventId) { + default: { + break; + } + } + + *aError = CHIP_ERROR_IM_MALFORMED_EVENT_PATH_IB; + return nil; +} static id _Nullable DecodeEventPayloadForChimeCluster(EventId aEventId, TLV::TLVReader & aReader, CHIP_ERROR * aError) { using namespace Clusters::Chime; @@ -5145,6 +5157,9 @@ id _Nullable MTRDecodeEventPayload(const ConcreteEventPath & aPath, TLV::TLVRead case Clusters::ContentAppObserver::Id: { return DecodeEventPayloadForContentAppObserverCluster(aPath.mEventId, aReader, aError); } + case Clusters::WebRTCTransportProvider::Id: { + return DecodeEventPayloadForWebRTCTransportProviderCluster(aPath.mEventId, aReader, aError); + } case Clusters::Chime::Id: { return DecodeEventPayloadForChimeCluster(aPath.mEventId, aReader, aError); } diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h index 42ee02b58d..bb93511dbf 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.h @@ -2117,6 +2117,25 @@ MTR_PROVISIONALLY_AVAILABLE @interface MTRContentControlClusterRemainingScreenTimeExpiredEvent : NSObject @end +MTR_PROVISIONALLY_AVAILABLE +@interface MTRWebRTCTransportProviderClusterICEServerStruct : NSObject +@property (nonatomic, copy) NSArray * _Nonnull urls MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSString * _Nullable username MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSString * _Nullable credential MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable caid MTR_PROVISIONALLY_AVAILABLE; +@end + +MTR_PROVISIONALLY_AVAILABLE +@interface MTRWebRTCTransportProviderClusterWebRTCSessionStruct : NSObject +@property (nonatomic, copy) NSNumber * _Nonnull id MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull peerNodeID MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull peerFabricIndex MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull streamType MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable videoStreamID MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nullable audioStreamID MTR_PROVISIONALLY_AVAILABLE; +@property (nonatomic, copy) NSNumber * _Nonnull metadataOptions MTR_PROVISIONALLY_AVAILABLE; +@end + MTR_PROVISIONALLY_AVAILABLE @interface MTRChimeClusterChimeSoundStruct : NSObject @property (nonatomic, copy) NSNumber * _Nonnull chimeID MTR_PROVISIONALLY_AVAILABLE; diff --git a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm index a632603cb5..6ba439eb02 100644 --- a/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm +++ b/src/darwin/Framework/CHIP/zap-generated/MTRStructsObjc.mm @@ -8768,6 +8768,87 @@ - (NSString *)description @end +@implementation MTRWebRTCTransportProviderClusterICEServerStruct +- (instancetype)init +{ + if (self = [super init]) { + + _urls = [NSArray array]; + + _username = nil; + + _credential = nil; + + _caid = nil; + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRWebRTCTransportProviderClusterICEServerStruct alloc] init]; + + other.urls = self.urls; + other.username = self.username; + other.credential = self.credential; + other.caid = self.caid; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: urls:%@; username:%@; credential:%@; caid:%@; >", NSStringFromClass([self class]), _urls, _username, _credential, _caid]; + return descriptionString; +} + +@end + +@implementation MTRWebRTCTransportProviderClusterWebRTCSessionStruct +- (instancetype)init +{ + if (self = [super init]) { + + _id = @(0); + + _peerNodeID = @(0); + + _peerFabricIndex = @(0); + + _streamType = @(0); + + _videoStreamID = nil; + + _audioStreamID = nil; + + _metadataOptions = @(0); + } + return self; +} + +- (id)copyWithZone:(NSZone * _Nullable)zone +{ + auto other = [[MTRWebRTCTransportProviderClusterWebRTCSessionStruct alloc] init]; + + other.id = self.id; + other.peerNodeID = self.peerNodeID; + other.peerFabricIndex = self.peerFabricIndex; + other.streamType = self.streamType; + other.videoStreamID = self.videoStreamID; + other.audioStreamID = self.audioStreamID; + other.metadataOptions = self.metadataOptions; + + return other; +} + +- (NSString *)description +{ + NSString * descriptionString = [NSString stringWithFormat:@"<%@: id:%@; peerNodeID:%@; peerFabricIndex:%@; streamType:%@; videoStreamID:%@; audioStreamID:%@; metadataOptions:%@; >", NSStringFromClass([self class]), _id, _peerNodeID, _peerFabricIndex, _streamType, _videoStreamID, _audioStreamID, _metadataOptions]; + return descriptionString; +} + +@end + @implementation MTRChimeClusterChimeSoundStruct - (instancetype)init { diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp index fa1f9659eb..8d488688d7 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.cpp @@ -9044,6 +9044,53 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, chip::app::Clusters } // namespace OperatingMode +namespace MaximumCheckInBackOff { + +Protocols::InteractionModel::Status Get(EndpointId endpoint, uint32_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::IcdManagement::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::IcdManagement::Id, Id), + EmberAfWriteDataInput(writable, ZCL_INT32U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::IcdManagement::Id, Id, writable, ZCL_INT32U_ATTRIBUTE_TYPE); +} + +} // namespace MaximumCheckInBackOff + namespace FeatureMap { Protocols::InteractionModel::Status Get(EndpointId endpoint, uint32_t * value) @@ -10461,6 +10508,186 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value) namespace LaundryWasherMode { namespace Attributes { +namespace StartUpMode { + +Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::LaundryWasherMode::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (Traits::IsNullValue(temp)) + { + value.SetNull(); + } + else + { + value.SetNonNull() = Traits::StorageToWorking(temp); + } + return status; +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::LaundryWasherMode::Id, Id), + EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::LaundryWasherMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::LaundryWasherMode::Id, Id), + EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); +} + +Protocols::InteractionModel::Status SetNull(EndpointId endpoint) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::LaundryWasherMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty) +{ + if (value.IsNull()) + { + return SetNull(endpoint, markDirty); + } + + return Set(endpoint, value.Value(), markDirty); +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value) +{ + if (value.IsNull()) + { + return SetNull(endpoint); + } + + return Set(endpoint, value.Value()); +} + +} // namespace StartUpMode + +namespace OnMode { + +Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::LaundryWasherMode::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (Traits::IsNullValue(temp)) + { + value.SetNull(); + } + else + { + value.SetNonNull() = Traits::StorageToWorking(temp); + } + return status; +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::LaundryWasherMode::Id, Id), + EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::LaundryWasherMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::LaundryWasherMode::Id, Id), + EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); +} + +Protocols::InteractionModel::Status SetNull(EndpointId endpoint) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::LaundryWasherMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty) +{ + if (value.IsNull()) + { + return SetNull(endpoint, markDirty); + } + + return Set(endpoint, value.Value(), markDirty); +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value) +{ + if (value.IsNull()) + { + return SetNull(endpoint); + } + + return Set(endpoint, value.Value()); +} + +} // namespace OnMode + namespace ClusterRevision { Protocols::InteractionModel::Status Get(EndpointId endpoint, uint16_t * value) @@ -10514,6 +10741,190 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value) namespace RefrigeratorAndTemperatureControlledCabinetMode { namespace Attributes { +namespace StartUpMode { + +Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (Traits::IsNullValue(temp)) + { + value.SetNull(); + } + else + { + value.SetNonNull() = Traits::StorageToWorking(temp); + } + return status; +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id, Id), + EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id, Id, writable, + ZCL_INT8U_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id, Id), + EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); +} + +Protocols::InteractionModel::Status SetNull(EndpointId endpoint) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id, Id, writable, + ZCL_INT8U_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty) +{ + if (value.IsNull()) + { + return SetNull(endpoint, markDirty); + } + + return Set(endpoint, value.Value(), markDirty); +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value) +{ + if (value.IsNull()) + { + return SetNull(endpoint); + } + + return Set(endpoint, value.Value()); +} + +} // namespace StartUpMode + +namespace OnMode { + +Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (Traits::IsNullValue(temp)) + { + value.SetNull(); + } + else + { + value.SetNonNull() = Traits::StorageToWorking(temp); + } + return status; +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id, Id), + EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id, Id, writable, + ZCL_INT8U_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id, Id), + EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); +} + +Protocols::InteractionModel::Status SetNull(EndpointId endpoint) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::RefrigeratorAndTemperatureControlledCabinetMode::Id, Id, writable, + ZCL_INT8U_ATTRIBUTE_TYPE); +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty) +{ + if (value.IsNull()) + { + return SetNull(endpoint, markDirty); + } + + return Set(endpoint, value.Value(), markDirty); +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value) +{ + if (value.IsNull()) + { + return SetNull(endpoint); + } + + return Set(endpoint, value.Value()); +} + +} // namespace OnMode + namespace ClusterRevision { Protocols::InteractionModel::Status Get(EndpointId endpoint, uint16_t * value) @@ -11384,7 +11795,101 @@ Set(EndpointId endpoint, chip::BitMask value) { - using Traits = NumericAttributeTraits>; + using Traits = NumericAttributeTraits>; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::RefrigeratorAlarm::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); +} + +} // namespace Supported + +namespace FeatureMap { + +Protocols::InteractionModel::Status Get(EndpointId endpoint, uint32_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::RefrigeratorAlarm::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::RefrigeratorAlarm::Id, Id), + EmberAfWriteDataInput(writable, ZCL_BITMAP32_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::RefrigeratorAlarm::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); +} + +} // namespace FeatureMap + +namespace ClusterRevision { + +Protocols::InteractionModel::Status Get(EndpointId endpoint, uint16_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::RefrigeratorAlarm::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::RefrigeratorAlarm::Id, Id), + EmberAfWriteDataInput(writable, ZCL_INT16U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value) +{ + using Traits = NumericAttributeTraits; if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) { return Protocols::InteractionModel::Status::ConstraintError; @@ -11392,110 +11897,196 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::RefrigeratorAlarm::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::RefrigeratorAlarm::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); } -} // namespace Supported +} // namespace ClusterRevision -namespace FeatureMap { +} // namespace Attributes +} // namespace RefrigeratorAlarm -Protocols::InteractionModel::Status Get(EndpointId endpoint, uint32_t * value) +namespace DishwasherMode { +namespace Attributes { + +namespace StartUpMode { + +Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value) { - using Traits = NumericAttributeTraits; + using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::RefrigeratorAlarm::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::DishwasherMode::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + if (Traits::IsNullValue(temp)) { - return Protocols::InteractionModel::Status::ConstraintError; + value.SetNull(); + } + else + { + value.SetNonNull() = Traits::StorageToWorking(temp); } - *value = Traits::StorageToWorking(temp); return status; } -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; } Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::RefrigeratorAlarm::Id, Id), - EmberAfWriteDataInput(writable, ZCL_BITMAP32_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); + return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::DishwasherMode::Id, Id), + EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); } -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value) +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value) { - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; } Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::RefrigeratorAlarm::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::DishwasherMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); } -} // namespace FeatureMap +Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::DishwasherMode::Id, Id), + EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); +} -namespace ClusterRevision { +Protocols::InteractionModel::Status SetNull(EndpointId endpoint) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::DishwasherMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); +} -Protocols::InteractionModel::Status Get(EndpointId endpoint, uint16_t * value) +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; + if (value.IsNull()) + { + return SetNull(endpoint, markDirty); + } + + return Set(endpoint, value.Value(), markDirty); +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value) +{ + if (value.IsNull()) + { + return SetNull(endpoint); + } + + return Set(endpoint, value.Value()); +} + +} // namespace StartUpMode + +namespace OnMode { + +Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value) +{ + using Traits = NumericAttributeTraits; Traits::StorageType temp; uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); Protocols::InteractionModel::Status status = - emberAfReadAttribute(endpoint, Clusters::RefrigeratorAlarm::Id, Id, readable, sizeof(temp)); + emberAfReadAttribute(endpoint, Clusters::DishwasherMode::Id, Id, readable, sizeof(temp)); VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); - if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + if (Traits::IsNullValue(temp)) { - return Protocols::InteractionModel::Status::ConstraintError; + value.SetNull(); + } + else + { + value.SetNonNull() = Traits::StorageToWorking(temp); } - *value = Traits::StorageToWorking(temp); return status; } -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty) { - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; } Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::RefrigeratorAlarm::Id, Id), - EmberAfWriteDataInput(writable, ZCL_INT16U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); + return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::DishwasherMode::Id, Id), + EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); } -Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value) +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value) { - using Traits = NumericAttributeTraits; - if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ true, value)) { return Protocols::InteractionModel::Status::ConstraintError; } Traits::StorageType storageValue; Traits::WorkingToStorage(value, storageValue); uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); - return emberAfWriteAttribute(endpoint, Clusters::RefrigeratorAlarm::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); + return emberAfWriteAttribute(endpoint, Clusters::DishwasherMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); } -} // namespace ClusterRevision +Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::DishwasherMode::Id, Id), + EmberAfWriteDataInput(writable, ZCL_INT8U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); +} -} // namespace Attributes -} // namespace RefrigeratorAlarm +Protocols::InteractionModel::Status SetNull(EndpointId endpoint) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType value; + Traits::SetNull(value); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(value); + return emberAfWriteAttribute(endpoint, Clusters::DishwasherMode::Id, Id, writable, ZCL_INT8U_ATTRIBUTE_TYPE); +} -namespace DishwasherMode { -namespace Attributes { +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty) +{ + if (value.IsNull()) + { + return SetNull(endpoint, markDirty); + } + + return Set(endpoint, value.Value(), markDirty); +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value) +{ + if (value.IsNull()) + { + return SetNull(endpoint); + } + + return Set(endpoint, value.Value()); +} + +} // namespace OnMode namespace ClusterRevision { @@ -36667,6 +37258,106 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value) } // namespace Attributes } // namespace ContentAppObserver +namespace WebRTCTransportProvider { +namespace Attributes { + +namespace FeatureMap { + +Protocols::InteractionModel::Status Get(EndpointId endpoint, uint32_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::WebRTCTransportProvider::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::WebRTCTransportProvider::Id, Id), + EmberAfWriteDataInput(writable, ZCL_BITMAP32_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WebRTCTransportProvider::Id, Id, writable, ZCL_BITMAP32_ATTRIBUTE_TYPE); +} + +} // namespace FeatureMap + +namespace ClusterRevision { + +Protocols::InteractionModel::Status Get(EndpointId endpoint, uint16_t * value) +{ + using Traits = NumericAttributeTraits; + Traits::StorageType temp; + uint8_t * readable = Traits::ToAttributeStoreRepresentation(temp); + Protocols::InteractionModel::Status status = + emberAfReadAttribute(endpoint, Clusters::WebRTCTransportProvider::Id, Id, readable, sizeof(temp)); + VerifyOrReturnError(Protocols::InteractionModel::Status::Success == status, status); + if (!Traits::CanRepresentValue(/* isNullable = */ false, temp)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + *value = Traits::StorageToWorking(temp); + return status; +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(ConcreteAttributePath(endpoint, Clusters::WebRTCTransportProvider::Id, Id), + EmberAfWriteDataInput(writable, ZCL_INT16U_ATTRIBUTE_TYPE).SetMarkDirty(markDirty)); +} + +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value) +{ + using Traits = NumericAttributeTraits; + if (!Traits::CanRepresentValue(/* isNullable = */ false, value)) + { + return Protocols::InteractionModel::Status::ConstraintError; + } + Traits::StorageType storageValue; + Traits::WorkingToStorage(value, storageValue); + uint8_t * writable = Traits::ToAttributeStoreRepresentation(storageValue); + return emberAfWriteAttribute(endpoint, Clusters::WebRTCTransportProvider::Id, Id, writable, ZCL_INT16U_ATTRIBUTE_TYPE); +} + +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace WebRTCTransportProvider + namespace Chime { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h index 90d7d65ab7..712f13d790 100644 --- a/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h +++ b/zzz_generated/app-common/app-common/zap-generated/attributes/Accessors.h @@ -1425,6 +1425,12 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, chip::app::Clusters MarkAttributeDirty markDirty); } // namespace OperatingMode +namespace MaximumCheckInBackOff { +Protocols::InteractionModel::Status Get(EndpointId endpoint, uint32_t * value); // int32u +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value); +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty); +} // namespace MaximumCheckInBackOff + namespace FeatureMap { Protocols::InteractionModel::Status Get(EndpointId endpoint, uint32_t * value); // bitmap32 Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value); @@ -1642,6 +1648,28 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value, Mar namespace LaundryWasherMode { namespace Attributes { +namespace StartUpMode { +Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value); // int8u +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value); +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status SetNull(EndpointId endpoint); +Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value); +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty); +} // namespace StartUpMode + +namespace OnMode { +Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value); // int8u +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value); +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status SetNull(EndpointId endpoint); +Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value); +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty); +} // namespace OnMode + namespace ClusterRevision { Protocols::InteractionModel::Status Get(EndpointId endpoint, uint16_t * value); // int16u Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value); @@ -1654,6 +1682,28 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value, Mar namespace RefrigeratorAndTemperatureControlledCabinetMode { namespace Attributes { +namespace StartUpMode { +Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value); // int8u +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value); +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status SetNull(EndpointId endpoint); +Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value); +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty); +} // namespace StartUpMode + +namespace OnMode { +Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value); // int8u +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value); +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status SetNull(EndpointId endpoint); +Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value); +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty); +} // namespace OnMode + namespace ClusterRevision { Protocols::InteractionModel::Status Get(EndpointId endpoint, uint16_t * value); // int16u Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value); @@ -1820,6 +1870,28 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value, Mar namespace DishwasherMode { namespace Attributes { +namespace StartUpMode { +Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value); // int8u +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value); +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status SetNull(EndpointId endpoint); +Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value); +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty); +} // namespace StartUpMode + +namespace OnMode { +Protocols::InteractionModel::Status Get(EndpointId endpoint, DataModel::Nullable & value); // int8u +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value); +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint8_t value, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status SetNull(EndpointId endpoint); +Protocols::InteractionModel::Status SetNull(EndpointId endpoint, MarkAttributeDirty markDirty); +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value); +Protocols::InteractionModel::Status Set(EndpointId endpoint, const chip::app::DataModel::Nullable & value, + MarkAttributeDirty markDirty); +} // namespace OnMode + namespace ClusterRevision { Protocols::InteractionModel::Status Get(EndpointId endpoint, uint16_t * value); // int16u Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value); @@ -5563,6 +5635,24 @@ Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value, Mar } // namespace Attributes } // namespace ContentAppObserver +namespace WebRTCTransportProvider { +namespace Attributes { + +namespace FeatureMap { +Protocols::InteractionModel::Status Get(EndpointId endpoint, uint32_t * value); // bitmap32 +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value); +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint32_t value, MarkAttributeDirty markDirty); +} // namespace FeatureMap + +namespace ClusterRevision { +Protocols::InteractionModel::Status Get(EndpointId endpoint, uint16_t * value); // int16u +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value); +Protocols::InteractionModel::Status Set(EndpointId endpoint, uint16_t value, MarkAttributeDirty markDirty); +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace WebRTCTransportProvider + namespace Chime { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/callback.h b/zzz_generated/app-common/app-common/zap-generated/callback.h index 59e11e3d5e..791d9c0ca8 100644 --- a/zzz_generated/app-common/app-common/zap-generated/callback.h +++ b/zzz_generated/app-common/app-common/zap-generated/callback.h @@ -618,6 +618,11 @@ void emberAfContentControlClusterInitCallback(chip::EndpointId endpoint); */ void emberAfContentAppObserverClusterInitCallback(chip::EndpointId endpoint); +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfWebRTCTransportProviderClusterInitCallback(chip::EndpointId endpoint); + /** * @param endpoint Endpoint that is being initialized */ @@ -5172,6 +5177,44 @@ chip::Protocols::InteractionModel::Status MatterContentAppObserverClusterServerP */ void emberAfContentAppObserverClusterServerTickCallback(chip::EndpointId endpoint); +// +// WebRTC Transport Provider Cluster +// + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfWebRTCTransportProviderClusterServerInitCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being shutdown + */ +void MatterWebRTCTransportProviderClusterServerShutdownCallback(chip::EndpointId endpoint); + +/** + * @param endpoint Endpoint that is being initialized + */ +void emberAfWebRTCTransportProviderClusterClientInitCallback(chip::EndpointId endpoint); + +/** + * @param attributePath Concrete attribute path that changed + */ +void MatterWebRTCTransportProviderClusterServerAttributeChangedCallback(const chip::app::ConcreteAttributePath & attributePath); + +/** + * @param attributePath Concrete attribute path to be changed + * @param attributeType Attribute type + * @param size Attribute size + * @param value Attribute value + */ +chip::Protocols::InteractionModel::Status MatterWebRTCTransportProviderClusterServerPreAttributeChangedCallback( + const chip::app::ConcreteAttributePath & attributePath, EmberAfAttributeType attributeType, uint16_t size, uint8_t * value); + +/** + * @param endpoint Endpoint that is being served + */ +void emberAfWebRTCTransportProviderClusterServerTickCallback(chip::EndpointId endpoint); + // // Chime Cluster // @@ -6601,6 +6644,36 @@ bool emberAfContentControlClusterSetScheduledContentRatingThresholdCallback( bool emberAfContentAppObserverClusterContentAppMessageCallback( chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, const chip::app::Clusters::ContentAppObserver::Commands::ContentAppMessage::DecodableType & commandData); +/** + * @brief WebRTC Transport Provider Cluster SolicitOffer Command callback (from client) + */ +bool emberAfWebRTCTransportProviderClusterSolicitOfferCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::WebRTCTransportProvider::Commands::SolicitOffer::DecodableType & commandData); +/** + * @brief WebRTC Transport Provider Cluster ProvideOffer Command callback (from client) + */ +bool emberAfWebRTCTransportProviderClusterProvideOfferCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideOffer::DecodableType & commandData); +/** + * @brief WebRTC Transport Provider Cluster ProvideAnswer Command callback (from client) + */ +bool emberAfWebRTCTransportProviderClusterProvideAnswerCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideAnswer::DecodableType & commandData); +/** + * @brief WebRTC Transport Provider Cluster ProvideICECandidate Command callback (from client) + */ +bool emberAfWebRTCTransportProviderClusterProvideICECandidateCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideICECandidate::DecodableType & commandData); +/** + * @brief WebRTC Transport Provider Cluster EndSession Command callback (from client) + */ +bool emberAfWebRTCTransportProviderClusterEndSessionCallback( + chip::app::CommandHandler * commandObj, const chip::app::ConcreteCommandPath & commandPath, + const chip::app::Clusters::WebRTCTransportProvider::Commands::EndSession::DecodableType & commandData); /** * @brief Chime Cluster PlayChimeSound Command callback (from client) */ diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h index 5d0c77b3cf..006c91ef14 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums-check.h @@ -388,6 +388,20 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(Globals::RelativePositi } } +static auto __attribute__((unused)) EnsureKnownEnumValue(detail::StreamTypeEnum val) +{ + using EnumType = detail::StreamTypeEnum; + switch (val) + { + case EnumType::kInternal: + case EnumType::kRecording: + case EnumType::kAnalysis: + case EnumType::kLiveView: + return val; + default: + return EnumType::kUnknownEnumValue; + } +} static auto __attribute__((unused)) EnsureKnownEnumValue(Globals::TestGlobalEnum val) { using EnumType = Globals::TestGlobalEnum; @@ -417,6 +431,29 @@ static auto __attribute__((unused)) EnsureKnownEnumValue(Globals::ThreeLevelAuto } } +static auto __attribute__((unused)) EnsureKnownEnumValue(detail::WebRTCEndReasonEnum val) +{ + using EnumType = detail::WebRTCEndReasonEnum; + switch (val) + { + case EnumType::kIceFailed: + case EnumType::kIceTimeout: + case EnumType::kUserHangup: + case EnumType::kUserBusy: + case EnumType::kReplaced: + case EnumType::kNoUserMedia: + case EnumType::kInviteTimeout: + case EnumType::kAnsweredElsewhere: + case EnumType::kOutOfResources: + case EnumType::kMediaTimeout: + case EnumType::kLowPower: + case EnumType::kUnknownReason: + return val; + default: + return EnumType::kUnknownEnumValue; + } +} + static auto __attribute__((unused)) EnsureKnownEnumValue(Identify::EffectIdentifierEnum val) { using EnumType = Identify::EffectIdentifierEnum; diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h index 13cbd2f2fd..8a53e03c83 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-enums.h @@ -139,8 +139,50 @@ enum class ProductIdentifierTypeEnum : uint8_t kUnknownEnumValue = 5, }; +// Enum for StreamTypeEnum +enum class StreamTypeEnum : uint8_t +{ + kInternal = 0x00, + kRecording = 0x01, + kAnalysis = 0x02, + kLiveView = 0x03, + // All received enum values that are not listed above will be mapped + // to kUnknownEnumValue. This is a helper enum value that should only + // be used by code to process how it handles receiving and unknown + // enum value. This specific should never be transmitted. + kUnknownEnumValue = 4, +}; + +// Enum for WebRTCEndReasonEnum +enum class WebRTCEndReasonEnum : uint8_t +{ + kIceFailed = 0x00, + kIceTimeout = 0x01, + kUserHangup = 0x02, + kUserBusy = 0x03, + kReplaced = 0x04, + kNoUserMedia = 0x05, + kInviteTimeout = 0x06, + kAnsweredElsewhere = 0x07, + kOutOfResources = 0x08, + kMediaTimeout = 0x09, + kLowPower = 0x0A, + kUnknownReason = 0x0B, + // All received enum values that are not listed above will be mapped + // to kUnknownEnumValue. This is a helper enum value that should only + // be used by code to process how it handles receiving and unknown + // enum value. This specific should never be transmitted. + kUnknownEnumValue = 12, +}; + // Bitmaps shared across multiple clusters. +// Bitmap for WebRTCMetadataOptions +enum class WebRTCMetadataOptions : uint8_t +{ + kDataTLV = 0x1, +}; + } // namespace detail namespace Globals { @@ -5406,6 +5448,15 @@ enum class StatusEnum : uint8_t }; } // namespace ContentAppObserver +namespace WebRTCTransportProvider { + +using StreamTypeEnum = Clusters::detail::StreamTypeEnum; + +using WebRTCEndReasonEnum = Clusters::detail::WebRTCEndReasonEnum; + +using WebRTCMetadataOptions = Clusters::detail::WebRTCMetadataOptions; +} // namespace WebRTCTransportProvider + namespace Chime {} // namespace Chime namespace EcosystemInformation {} // namespace EcosystemInformation diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp index 9612ff6aef..7999de734b 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.cpp @@ -422,6 +422,57 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } // namespace ErrorStateStruct +namespace ICEServerStruct { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kUrls), urls); + encoder.Encode(to_underlying(Fields::kUsername), username); + encoder.Encode(to_underlying(Fields::kCredential), credential); + encoder.Encode(to_underlying(Fields::kCaid), caid); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kUrls)) + { + err = DataModel::Decode(reader, urls); + } + else if (__context_tag == to_underlying(Fields::kUsername)) + { + err = DataModel::Decode(reader, username); + } + else if (__context_tag == to_underlying(Fields::kCredential)) + { + err = DataModel::Decode(reader, credential); + } + else if (__context_tag == to_underlying(Fields::kCaid)) + { + err = DataModel::Decode(reader, caid); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} + +} // namespace ICEServerStruct + namespace LabelStruct { CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const { @@ -503,6 +554,72 @@ CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) } } // namespace OperationalStateStruct + +namespace WebRTCSessionStruct { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kId), id); + encoder.Encode(to_underlying(Fields::kPeerNodeID), peerNodeID); + encoder.Encode(to_underlying(Fields::kPeerFabricIndex), peerFabricIndex); + encoder.Encode(to_underlying(Fields::kStreamType), streamType); + encoder.Encode(to_underlying(Fields::kVideoStreamID), videoStreamID); + encoder.Encode(to_underlying(Fields::kAudioStreamID), audioStreamID); + encoder.Encode(to_underlying(Fields::kMetadataOptions), metadataOptions); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kId)) + { + err = DataModel::Decode(reader, id); + } + else if (__context_tag == to_underlying(Fields::kPeerNodeID)) + { + err = DataModel::Decode(reader, peerNodeID); + } + else if (__context_tag == to_underlying(Fields::kPeerFabricIndex)) + { + err = DataModel::Decode(reader, peerFabricIndex); + } + else if (__context_tag == to_underlying(Fields::kStreamType)) + { + err = DataModel::Decode(reader, streamType); + } + else if (__context_tag == to_underlying(Fields::kVideoStreamID)) + { + err = DataModel::Decode(reader, videoStreamID); + } + else if (__context_tag == to_underlying(Fields::kAudioStreamID)) + { + err = DataModel::Decode(reader, audioStreamID); + } + else if (__context_tag == to_underlying(Fields::kMetadataOptions)) + { + err = DataModel::Decode(reader, metadataOptions); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} + +} // namespace WebRTCSessionStruct } // namespace Structs } // namespace detail @@ -28476,6 +28593,378 @@ CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const Concre namespace Events {} // namespace Events } // namespace ContentAppObserver +namespace WebRTCTransportProvider { +namespace Structs {} // namespace Structs + +namespace Commands { +namespace SolicitOffer { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kStreamType), streamType); + encoder.Encode(to_underlying(Fields::kVideoStreamID), videoStreamID); + encoder.Encode(to_underlying(Fields::kAudioStreamID), audioStreamID); + encoder.Encode(to_underlying(Fields::kICEServers), ICEServers); + encoder.Encode(to_underlying(Fields::kICETransportPolicy), ICETransportPolicy); + encoder.Encode(to_underlying(Fields::kMetadataOptions), metadataOptions); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kStreamType)) + { + err = DataModel::Decode(reader, streamType); + } + else if (__context_tag == to_underlying(Fields::kVideoStreamID)) + { + err = DataModel::Decode(reader, videoStreamID); + } + else if (__context_tag == to_underlying(Fields::kAudioStreamID)) + { + err = DataModel::Decode(reader, audioStreamID); + } + else if (__context_tag == to_underlying(Fields::kICEServers)) + { + err = DataModel::Decode(reader, ICEServers); + } + else if (__context_tag == to_underlying(Fields::kICETransportPolicy)) + { + err = DataModel::Decode(reader, ICETransportPolicy); + } + else if (__context_tag == to_underlying(Fields::kMetadataOptions)) + { + err = DataModel::Decode(reader, metadataOptions); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace SolicitOffer. +namespace SolicitOfferResponse { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kWebRTCSessionID), webRTCSessionID); + encoder.Encode(to_underlying(Fields::kDeferredOffer), deferredOffer); + encoder.Encode(to_underlying(Fields::kVideoStreamID), videoStreamID); + encoder.Encode(to_underlying(Fields::kAudioStreamID), audioStreamID); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kWebRTCSessionID)) + { + err = DataModel::Decode(reader, webRTCSessionID); + } + else if (__context_tag == to_underlying(Fields::kDeferredOffer)) + { + err = DataModel::Decode(reader, deferredOffer); + } + else if (__context_tag == to_underlying(Fields::kVideoStreamID)) + { + err = DataModel::Decode(reader, videoStreamID); + } + else if (__context_tag == to_underlying(Fields::kAudioStreamID)) + { + err = DataModel::Decode(reader, audioStreamID); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace SolicitOfferResponse. +namespace ProvideOffer { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kWebRTCSessionID), webRTCSessionID); + encoder.Encode(to_underlying(Fields::kSdp), sdp); + encoder.Encode(to_underlying(Fields::kStreamType), streamType); + encoder.Encode(to_underlying(Fields::kVideoStreamID), videoStreamID); + encoder.Encode(to_underlying(Fields::kAudioStreamID), audioStreamID); + encoder.Encode(to_underlying(Fields::kICEServers), ICEServers); + encoder.Encode(to_underlying(Fields::kICETransportPolicy), ICETransportPolicy); + encoder.Encode(to_underlying(Fields::kMetadataOptions), metadataOptions); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kWebRTCSessionID)) + { + err = DataModel::Decode(reader, webRTCSessionID); + } + else if (__context_tag == to_underlying(Fields::kSdp)) + { + err = DataModel::Decode(reader, sdp); + } + else if (__context_tag == to_underlying(Fields::kStreamType)) + { + err = DataModel::Decode(reader, streamType); + } + else if (__context_tag == to_underlying(Fields::kVideoStreamID)) + { + err = DataModel::Decode(reader, videoStreamID); + } + else if (__context_tag == to_underlying(Fields::kAudioStreamID)) + { + err = DataModel::Decode(reader, audioStreamID); + } + else if (__context_tag == to_underlying(Fields::kICEServers)) + { + err = DataModel::Decode(reader, ICEServers); + } + else if (__context_tag == to_underlying(Fields::kICETransportPolicy)) + { + err = DataModel::Decode(reader, ICETransportPolicy); + } + else if (__context_tag == to_underlying(Fields::kMetadataOptions)) + { + err = DataModel::Decode(reader, metadataOptions); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace ProvideOffer. +namespace ProvideOfferResponse { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kWebRTCSessionID), webRTCSessionID); + encoder.Encode(to_underlying(Fields::kVideoStreamID), videoStreamID); + encoder.Encode(to_underlying(Fields::kAudioStreamID), audioStreamID); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kWebRTCSessionID)) + { + err = DataModel::Decode(reader, webRTCSessionID); + } + else if (__context_tag == to_underlying(Fields::kVideoStreamID)) + { + err = DataModel::Decode(reader, videoStreamID); + } + else if (__context_tag == to_underlying(Fields::kAudioStreamID)) + { + err = DataModel::Decode(reader, audioStreamID); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace ProvideOfferResponse. +namespace ProvideAnswer { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kWebRTCSessionID), webRTCSessionID); + encoder.Encode(to_underlying(Fields::kSdp), sdp); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kWebRTCSessionID)) + { + err = DataModel::Decode(reader, webRTCSessionID); + } + else if (__context_tag == to_underlying(Fields::kSdp)) + { + err = DataModel::Decode(reader, sdp); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace ProvideAnswer. +namespace ProvideICECandidate { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kWebRTCSessionID), webRTCSessionID); + encoder.Encode(to_underlying(Fields::kICECandidate), ICECandidate); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kWebRTCSessionID)) + { + err = DataModel::Decode(reader, webRTCSessionID); + } + else if (__context_tag == to_underlying(Fields::kICECandidate)) + { + err = DataModel::Decode(reader, ICECandidate); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace ProvideICECandidate. +namespace EndSession { +CHIP_ERROR Type::Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const +{ + DataModel::WrappedStructEncoder encoder{ aWriter, aTag }; + encoder.Encode(to_underlying(Fields::kWebRTCSessionID), webRTCSessionID); + encoder.Encode(to_underlying(Fields::kReason), reason); + return encoder.Finalize(); +} + +CHIP_ERROR DecodableType::Decode(TLV::TLVReader & reader) +{ + detail::StructDecodeIterator __iterator(reader); + while (true) + { + auto __element = __iterator.Next(); + if (std::holds_alternative(__element)) + { + return std::get(__element); + } + + CHIP_ERROR err = CHIP_NO_ERROR; + const uint8_t __context_tag = std::get(__element); + + if (__context_tag == to_underlying(Fields::kWebRTCSessionID)) + { + err = DataModel::Decode(reader, webRTCSessionID); + } + else if (__context_tag == to_underlying(Fields::kReason)) + { + err = DataModel::Decode(reader, reason); + } + else + { + } + + ReturnErrorOnFailure(err); + } +} +} // namespace EndSession. +} // namespace Commands + +namespace Attributes { +CHIP_ERROR TypeInfo::DecodableType::Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path) +{ + switch (path.mAttributeId) + { + case Attributes::CurrentSessions::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, currentSessions); + case Attributes::GeneratedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, generatedCommandList); + case Attributes::AcceptedCommandList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, acceptedCommandList); + case Attributes::EventList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, eventList); + case Attributes::AttributeList::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, attributeList); + case Attributes::FeatureMap::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, featureMap); + case Attributes::ClusterRevision::TypeInfo::GetAttributeId(): + return DataModel::Decode(reader, clusterRevision); + default: + return CHIP_NO_ERROR; + } +} +} // namespace Attributes + +namespace Events {} // namespace Events + +} // namespace WebRTCTransportProvider namespace Chime { namespace Structs { @@ -32499,6 +32988,13 @@ bool CommandIsFabricScoped(ClusterId aCluster, CommandId aCommand) return false; } } + case Clusters::WebRTCTransportProvider::Id: { + switch (aCommand) + { + default: + return false; + } + } case Clusters::Chime::Id: { switch (aCommand) { diff --git a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h index 0cdb5fd2b2..2917e4c924 100644 --- a/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h +++ b/zzz_generated/app-common/app-common/zap-generated/cluster-objects.h @@ -244,6 +244,42 @@ struct Type using DecodableType = Type; } // namespace ErrorStateStruct +namespace ICEServerStruct { +enum class Fields : uint8_t +{ + kUrls = 1, + kUsername = 2, + kCredential = 3, + kCaid = 4, +}; + +struct Type +{ +public: + DataModel::List urls; + Optional username; + Optional credential; + Optional caid; + + static constexpr bool kIsFabricScoped = false; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; +}; + +struct DecodableType +{ +public: + DataModel::DecodableList urls; + Optional username; + Optional credential; + Optional caid; + + CHIP_ERROR Decode(TLV::TLVReader & reader); + + static constexpr bool kIsFabricScoped = false; +}; + +} // namespace ICEServerStruct namespace LabelStruct { enum class Fields : uint8_t { @@ -290,6 +326,39 @@ struct Type using DecodableType = Type; } // namespace OperationalStateStruct +namespace WebRTCSessionStruct { +enum class Fields : uint8_t +{ + kId = 1, + kPeerNodeID = 2, + kPeerFabricIndex = 3, + kStreamType = 4, + kVideoStreamID = 5, + kAudioStreamID = 6, + kMetadataOptions = 7, +}; + +struct Type +{ +public: + uint16_t id = static_cast(0); + chip::NodeId peerNodeID = static_cast(0); + chip::FabricIndex peerFabricIndex = static_cast(0); + StreamTypeEnum streamType = static_cast(0); + DataModel::Nullable videoStreamID; + DataModel::Nullable audioStreamID; + chip::BitMask metadataOptions = static_cast>(0); + + CHIP_ERROR Decode(TLV::TLVReader & reader); + + static constexpr bool kIsFabricScoped = false; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; +}; + +using DecodableType = Type; + +} // namespace WebRTCSessionStruct } // namespace Structs } // namespace detail @@ -41196,6 +41265,411 @@ struct TypeInfo }; } // namespace Attributes } // namespace ContentAppObserver +namespace WebRTCTransportProvider { +namespace Structs { +namespace ICEServerStruct = Clusters::detail::Structs::ICEServerStruct; +namespace WebRTCSessionStruct = Clusters::detail::Structs::WebRTCSessionStruct; +} // namespace Structs + +namespace Commands { +// Forward-declarations so we can reference these later. + +namespace SolicitOffer { +struct Type; +struct DecodableType; +} // namespace SolicitOffer + +namespace SolicitOfferResponse { +struct Type; +struct DecodableType; +} // namespace SolicitOfferResponse + +namespace ProvideOffer { +struct Type; +struct DecodableType; +} // namespace ProvideOffer + +namespace ProvideOfferResponse { +struct Type; +struct DecodableType; +} // namespace ProvideOfferResponse + +namespace ProvideAnswer { +struct Type; +struct DecodableType; +} // namespace ProvideAnswer + +namespace ProvideICECandidate { +struct Type; +struct DecodableType; +} // namespace ProvideICECandidate + +namespace EndSession { +struct Type; +struct DecodableType; +} // namespace EndSession + +} // namespace Commands + +namespace Commands { +namespace SolicitOffer { +enum class Fields : uint8_t +{ + kStreamType = 0, + kVideoStreamID = 1, + kAudioStreamID = 2, + kICEServers = 3, + kICETransportPolicy = 4, + kMetadataOptions = 5, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::SolicitOffer::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } + + StreamTypeEnum streamType = static_cast(0); + Optional> videoStreamID; + Optional> audioStreamID; + Optional> ICEServers; + Optional ICETransportPolicy; + Optional> metadataOptions; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = Clusters::WebRTCTransportProvider::Commands::SolicitOfferResponse::DecodableType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::SolicitOffer::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } + + StreamTypeEnum streamType = static_cast(0); + Optional> videoStreamID; + Optional> audioStreamID; + Optional> ICEServers; + Optional ICETransportPolicy; + Optional> metadataOptions; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace SolicitOffer +namespace SolicitOfferResponse { +enum class Fields : uint8_t +{ + kWebRTCSessionID = 0, + kDeferredOffer = 1, + kVideoStreamID = 2, + kAudioStreamID = 3, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::SolicitOfferResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } + + uint16_t webRTCSessionID = static_cast(0); + bool deferredOffer = static_cast(0); + Optional> videoStreamID; + Optional> audioStreamID; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::SolicitOfferResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } + + uint16_t webRTCSessionID = static_cast(0); + bool deferredOffer = static_cast(0); + Optional> videoStreamID; + Optional> audioStreamID; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace SolicitOfferResponse +namespace ProvideOffer { +enum class Fields : uint8_t +{ + kWebRTCSessionID = 0, + kSdp = 1, + kStreamType = 2, + kVideoStreamID = 3, + kAudioStreamID = 4, + kICEServers = 5, + kICETransportPolicy = 6, + kMetadataOptions = 7, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::ProvideOffer::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } + + DataModel::Nullable webRTCSessionID; + chip::CharSpan sdp; + StreamTypeEnum streamType = static_cast(0); + Optional> videoStreamID; + Optional> audioStreamID; + Optional> ICEServers; + Optional ICETransportPolicy; + Optional> metadataOptions; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = Clusters::WebRTCTransportProvider::Commands::ProvideOfferResponse::DecodableType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::ProvideOffer::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } + + DataModel::Nullable webRTCSessionID; + chip::CharSpan sdp; + StreamTypeEnum streamType = static_cast(0); + Optional> videoStreamID; + Optional> audioStreamID; + Optional> ICEServers; + Optional ICETransportPolicy; + Optional> metadataOptions; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace ProvideOffer +namespace ProvideOfferResponse { +enum class Fields : uint8_t +{ + kWebRTCSessionID = 0, + kVideoStreamID = 1, + kAudioStreamID = 2, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::ProvideOfferResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } + + uint16_t webRTCSessionID = static_cast(0); + uint16_t videoStreamID = static_cast(0); + uint16_t audioStreamID = static_cast(0); + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::ProvideOfferResponse::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } + + uint16_t webRTCSessionID = static_cast(0); + uint16_t videoStreamID = static_cast(0); + uint16_t audioStreamID = static_cast(0); + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace ProvideOfferResponse +namespace ProvideAnswer { +enum class Fields : uint8_t +{ + kWebRTCSessionID = 0, + kSdp = 1, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::ProvideAnswer::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } + + uint16_t webRTCSessionID = static_cast(0); + chip::CharSpan sdp; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::ProvideAnswer::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } + + uint16_t webRTCSessionID = static_cast(0); + chip::CharSpan sdp; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace ProvideAnswer +namespace ProvideICECandidate { +enum class Fields : uint8_t +{ + kWebRTCSessionID = 0, + kICECandidate = 1, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::ProvideICECandidate::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } + + uint16_t webRTCSessionID = static_cast(0); + chip::CharSpan ICECandidate; + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::ProvideICECandidate::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } + + uint16_t webRTCSessionID = static_cast(0); + chip::CharSpan ICECandidate; + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace ProvideICECandidate +namespace EndSession { +enum class Fields : uint8_t +{ + kWebRTCSessionID = 0, + kReason = 1, +}; + +struct Type +{ +public: + // Use GetCommandId instead of commandId directly to avoid naming conflict with CommandIdentification in ExecutionOfACommand + static constexpr CommandId GetCommandId() { return Commands::EndSession::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } + + uint16_t webRTCSessionID = static_cast(0); + WebRTCEndReasonEnum reason = static_cast(0); + + CHIP_ERROR Encode(TLV::TLVWriter & aWriter, TLV::Tag aTag) const; + + using ResponseType = DataModel::NullObjectType; + + static constexpr bool MustUseTimedInvoke() { return false; } +}; + +struct DecodableType +{ +public: + static constexpr CommandId GetCommandId() { return Commands::EndSession::Id; } + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } + + uint16_t webRTCSessionID = static_cast(0); + WebRTCEndReasonEnum reason = static_cast(0); + CHIP_ERROR Decode(TLV::TLVReader & reader); +}; +}; // namespace EndSession +} // namespace Commands + +namespace Attributes { + +namespace CurrentSessions { +struct TypeInfo +{ + using Type = chip::app::DataModel::List; + using DecodableType = chip::app::DataModel::DecodableList< + chip::app::Clusters::WebRTCTransportProvider::Structs::WebRTCSessionStruct::DecodableType>; + using DecodableArgType = const chip::app::DataModel::DecodableList< + chip::app::Clusters::WebRTCTransportProvider::Structs::WebRTCSessionStruct::DecodableType> &; + + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } + static constexpr AttributeId GetAttributeId() { return Attributes::CurrentSessions::Id; } + static constexpr bool MustUseTimedWrite() { return false; } +}; +} // namespace CurrentSessions +namespace GeneratedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::GeneratedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } +}; +} // namespace GeneratedCommandList +namespace AcceptedCommandList { +struct TypeInfo : public Clusters::Globals::Attributes::AcceptedCommandList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } +}; +} // namespace AcceptedCommandList +namespace EventList { +struct TypeInfo : public Clusters::Globals::Attributes::EventList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } +}; +} // namespace EventList +namespace AttributeList { +struct TypeInfo : public Clusters::Globals::Attributes::AttributeList::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } +}; +} // namespace AttributeList +namespace FeatureMap { +struct TypeInfo : public Clusters::Globals::Attributes::FeatureMap::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } +}; +} // namespace FeatureMap +namespace ClusterRevision { +struct TypeInfo : public Clusters::Globals::Attributes::ClusterRevision::TypeInfo +{ + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } +}; +} // namespace ClusterRevision + +struct TypeInfo +{ + struct DecodableType + { + static constexpr ClusterId GetClusterId() { return Clusters::WebRTCTransportProvider::Id; } + + CHIP_ERROR Decode(TLV::TLVReader & reader, const ConcreteAttributePath & path); + + Attributes::CurrentSessions::TypeInfo::DecodableType currentSessions; + Attributes::GeneratedCommandList::TypeInfo::DecodableType generatedCommandList; + Attributes::AcceptedCommandList::TypeInfo::DecodableType acceptedCommandList; + Attributes::EventList::TypeInfo::DecodableType eventList; + Attributes::AttributeList::TypeInfo::DecodableType attributeList; + Attributes::FeatureMap::TypeInfo::DecodableType featureMap = static_cast(0); + Attributes::ClusterRevision::TypeInfo::DecodableType clusterRevision = static_cast(0); + }; +}; +} // namespace Attributes +} // namespace WebRTCTransportProvider namespace Chime { namespace Structs { namespace ChimeSoundStruct { diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h index 059dcab2de..ca40e31b73 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Attributes.h @@ -7313,6 +7313,40 @@ static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; } // namespace Attributes } // namespace ContentAppObserver +namespace WebRTCTransportProvider { +namespace Attributes { + +namespace CurrentSessions { +static constexpr AttributeId Id = 0x00000000; +} // namespace CurrentSessions + +namespace GeneratedCommandList { +static constexpr AttributeId Id = Globals::Attributes::GeneratedCommandList::Id; +} // namespace GeneratedCommandList + +namespace AcceptedCommandList { +static constexpr AttributeId Id = Globals::Attributes::AcceptedCommandList::Id; +} // namespace AcceptedCommandList + +namespace EventList { +static constexpr AttributeId Id = Globals::Attributes::EventList::Id; +} // namespace EventList + +namespace AttributeList { +static constexpr AttributeId Id = Globals::Attributes::AttributeList::Id; +} // namespace AttributeList + +namespace FeatureMap { +static constexpr AttributeId Id = Globals::Attributes::FeatureMap::Id; +} // namespace FeatureMap + +namespace ClusterRevision { +static constexpr AttributeId Id = Globals::Attributes::ClusterRevision::Id; +} // namespace ClusterRevision + +} // namespace Attributes +} // namespace WebRTCTransportProvider + namespace Chime { namespace Attributes { diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h b/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h index 688110cd99..9c0523e865 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Clusters.h @@ -376,6 +376,9 @@ static constexpr ClusterId Id = 0x0000050F; namespace ContentAppObserver { static constexpr ClusterId Id = 0x00000510; } // namespace ContentAppObserver +namespace WebRTCTransportProvider { +static constexpr ClusterId Id = 0x00000553; +} // namespace WebRTCTransportProvider namespace Chime { static constexpr ClusterId Id = 0x00000556; } // namespace Chime diff --git a/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h b/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h index b6c40f70d2..49e738a1ac 100644 --- a/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h +++ b/zzz_generated/app-common/app-common/zap-generated/ids/Commands.h @@ -1803,6 +1803,40 @@ static constexpr CommandId Id = 0x00000001; } // namespace Commands } // namespace ContentAppObserver +namespace WebRTCTransportProvider { +namespace Commands { + +namespace SolicitOffer { +static constexpr CommandId Id = 0x00000001; +} // namespace SolicitOffer + +namespace SolicitOfferResponse { +static constexpr CommandId Id = 0x00000002; +} // namespace SolicitOfferResponse + +namespace ProvideOffer { +static constexpr CommandId Id = 0x00000003; +} // namespace ProvideOffer + +namespace ProvideOfferResponse { +static constexpr CommandId Id = 0x00000004; +} // namespace ProvideOfferResponse + +namespace ProvideAnswer { +static constexpr CommandId Id = 0x00000005; +} // namespace ProvideAnswer + +namespace ProvideICECandidate { +static constexpr CommandId Id = 0x00000006; +} // namespace ProvideICECandidate + +namespace EndSession { +static constexpr CommandId Id = 0x00000007; +} // namespace EndSession + +} // namespace Commands +} // namespace WebRTCTransportProvider + namespace Chime { namespace Commands { diff --git a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h index 90f59169fa..4d2c793f47 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/Commands.h @@ -152,6 +152,7 @@ | AccountLogin | 0x050E | | ContentControl | 0x050F | | ContentAppObserver | 0x0510 | +| WebRTCTransportProvider | 0x0553 | | Chime | 0x0556 | | EcosystemInformation | 0x0750 | | CommissionerControl | 0x0751 | @@ -13646,6 +13647,239 @@ class ContentAppObserverContentAppMessage : public ClusterCommand chip::app::Clusters::ContentAppObserver::Commands::ContentAppMessage::Type mRequest; }; +/*----------------------------------------------------------------------------*\ +| Cluster WebRTCTransportProvider | 0x0553 | +|------------------------------------------------------------------------------| +| Commands: | | +| * SolicitOffer | 0x01 | +| * ProvideOffer | 0x03 | +| * ProvideAnswer | 0x05 | +| * ProvideICECandidate | 0x06 | +| * EndSession | 0x07 | +|------------------------------------------------------------------------------| +| Attributes: | | +| * CurrentSessions | 0x0000 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +\*----------------------------------------------------------------------------*/ + +/* + * Command SolicitOffer + */ +class WebRTCTransportProviderSolicitOffer : public ClusterCommand +{ +public: + WebRTCTransportProviderSolicitOffer(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("solicit-offer", credsIssuerConfig), mComplex_ICEServers(&mRequest.ICEServers) + { + AddArgument("StreamType", 0, UINT8_MAX, &mRequest.streamType); + AddArgument("VideoStreamID", 0, UINT16_MAX, &mRequest.videoStreamID); + AddArgument("AudioStreamID", 0, UINT16_MAX, &mRequest.audioStreamID); + AddArgument("ICEServers", &mComplex_ICEServers, "", Argument::kOptional); + AddArgument("ICETransportPolicy", &mRequest.ICETransportPolicy); + AddArgument("MetadataOptions", 0, UINT8_MAX, &mRequest.metadataOptions); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WebRTCTransportProvider::Commands::SolicitOffer::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WebRTCTransportProvider::Commands::SolicitOffer::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::WebRTCTransportProvider::Commands::SolicitOffer::Type mRequest; + TypedComplexArgument>> + mComplex_ICEServers; +}; + +/* + * Command ProvideOffer + */ +class WebRTCTransportProviderProvideOffer : public ClusterCommand +{ +public: + WebRTCTransportProviderProvideOffer(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("provide-offer", credsIssuerConfig), mComplex_ICEServers(&mRequest.ICEServers) + { + AddArgument("WebRTCSessionID", 0, UINT16_MAX, &mRequest.webRTCSessionID); + AddArgument("Sdp", &mRequest.sdp); + AddArgument("StreamType", 0, UINT8_MAX, &mRequest.streamType); + AddArgument("VideoStreamID", 0, UINT16_MAX, &mRequest.videoStreamID); + AddArgument("AudioStreamID", 0, UINT16_MAX, &mRequest.audioStreamID); + AddArgument("ICEServers", &mComplex_ICEServers, "", Argument::kOptional); + AddArgument("ICETransportPolicy", &mRequest.ICETransportPolicy); + AddArgument("MetadataOptions", 0, UINT8_MAX, &mRequest.metadataOptions); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideOffer::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideOffer::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideOffer::Type mRequest; + TypedComplexArgument>> + mComplex_ICEServers; +}; + +/* + * Command ProvideAnswer + */ +class WebRTCTransportProviderProvideAnswer : public ClusterCommand +{ +public: + WebRTCTransportProviderProvideAnswer(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("provide-answer", credsIssuerConfig) + { + AddArgument("WebRTCSessionID", 0, UINT16_MAX, &mRequest.webRTCSessionID); + AddArgument("Sdp", &mRequest.sdp); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideAnswer::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideAnswer::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideAnswer::Type mRequest; +}; + +/* + * Command ProvideICECandidate + */ +class WebRTCTransportProviderProvideICECandidate : public ClusterCommand +{ +public: + WebRTCTransportProviderProvideICECandidate(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("provide-icecandidate", credsIssuerConfig) + { + AddArgument("WebRTCSessionID", 0, UINT16_MAX, &mRequest.webRTCSessionID); + AddArgument("ICECandidate", &mRequest.ICECandidate); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideICECandidate::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideICECandidate::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideICECandidate::Type mRequest; +}; + +/* + * Command EndSession + */ +class WebRTCTransportProviderEndSession : public ClusterCommand +{ +public: + WebRTCTransportProviderEndSession(CredentialIssuerCommands * credsIssuerConfig) : + ClusterCommand("end-session", credsIssuerConfig) + { + AddArgument("WebRTCSessionID", 0, UINT16_MAX, &mRequest.webRTCSessionID); + AddArgument("Reason", 0, UINT8_MAX, &mRequest.reason); + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(chip::DeviceProxy * device, std::vector endpointIds) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WebRTCTransportProvider::Commands::EndSession::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, + commandId, endpointIds.at(0)); + return ClusterCommand::SendCommand(device, endpointIds.at(0), clusterId, commandId, mRequest); + } + + CHIP_ERROR SendGroupCommand(chip::GroupId groupId, chip::FabricIndex fabricIndex) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WebRTCTransportProvider::Commands::EndSession::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on Group %u", clusterId, commandId, + groupId); + + return ClusterCommand::SendGroupCommand(groupId, fabricIndex, clusterId, commandId, mRequest); + } + +private: + chip::app::Clusters::WebRTCTransportProvider::Commands::EndSession::Type mRequest; +}; + /*----------------------------------------------------------------------------*\ | Cluster Chime | 0x0556 | |------------------------------------------------------------------------------| @@ -26223,6 +26457,67 @@ void registerClusterContentAppObserver(Commands & commands, CredentialIssuerComm commands.RegisterCluster(clusterName, clusterCommands); } +void registerClusterWebRTCTransportProvider(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) +{ + using namespace chip::app::Clusters::WebRTCTransportProvider; + + const char * clusterName = "WebRTCTransportProvider"; + + commands_list clusterCommands = { + // + // Commands + // + make_unique(Id, credsIssuerConfig), // + make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // + make_unique(credsIssuerConfig), // + // + // Attributes + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "current-sessions", Attributes::CurrentSessions::Id, credsIssuerConfig), // + make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + make_unique>(Id, credsIssuerConfig), // + make_unique>>( + Id, "current-sessions", Attributes::CurrentSessions::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "generated-command-list", Attributes::GeneratedCommandList::Id, WriteCommandType::kForceWrite, + credsIssuerConfig), // + make_unique>>( + Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "event-list", Attributes::EventList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>>( + Id, "attribute-list", Attributes::AttributeList::Id, WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "feature-map", 0, UINT32_MAX, Attributes::FeatureMap::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique>(Id, "cluster-revision", 0, UINT16_MAX, Attributes::ClusterRevision::Id, + WriteCommandType::kForceWrite, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, "current-sessions", Attributes::CurrentSessions::Id, credsIssuerConfig), // + make_unique(Id, "generated-command-list", Attributes::GeneratedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "accepted-command-list", Attributes::AcceptedCommandList::Id, credsIssuerConfig), // + make_unique(Id, "event-list", Attributes::EventList::Id, credsIssuerConfig), // + make_unique(Id, "attribute-list", Attributes::AttributeList::Id, credsIssuerConfig), // + make_unique(Id, "feature-map", Attributes::FeatureMap::Id, credsIssuerConfig), // + make_unique(Id, "cluster-revision", Attributes::ClusterRevision::Id, credsIssuerConfig), // + // + // Events + // + make_unique(Id, credsIssuerConfig), // + make_unique(Id, credsIssuerConfig), // + }; + + commands.RegisterCluster(clusterName, clusterCommands); +} void registerClusterChime(Commands & commands, CredentialIssuerCommands * credsIssuerConfig) { using namespace chip::app::Clusters::Chime; @@ -27151,6 +27446,7 @@ void registerClusters(Commands & commands, CredentialIssuerCommands * credsIssue registerClusterAccountLogin(commands, credsIssuerConfig); registerClusterContentControl(commands, credsIssuerConfig); registerClusterContentAppObserver(commands, credsIssuerConfig); + registerClusterWebRTCTransportProvider(commands, credsIssuerConfig); registerClusterChime(commands, credsIssuerConfig); registerClusterEcosystemInformation(commands, credsIssuerConfig); registerClusterCommissionerControl(commands, credsIssuerConfig); diff --git a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp index 159b3bdc5f..76313bf47a 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.cpp @@ -430,6 +430,53 @@ void ComplexArgumentParser::Finalize(chip::app::Clusters::detail::Structs::Error ComplexArgumentParser::Finalize(request.errorStateDetails); } +CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::detail::Structs::ICEServerStruct::Type & request, + Json::Value & value) +{ + VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT); + + // Copy to track which members we already processed. + Json::Value valueCopy(value); + + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("ICEServerStruct.urls", "urls", value.isMember("urls"))); + + char labelWithMember[kMaxLabelLength]; + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "urls"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.urls, value["urls"])); + valueCopy.removeMember("urls"); + + if (value.isMember("username")) + { + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "username"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.username, value["username"])); + } + valueCopy.removeMember("username"); + + if (value.isMember("credential")) + { + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "credential"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.credential, value["credential"])); + } + valueCopy.removeMember("credential"); + + if (value.isMember("caid")) + { + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "caid"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.caid, value["caid"])); + } + valueCopy.removeMember("caid"); + + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); +} + +void ComplexArgumentParser::Finalize(chip::app::Clusters::detail::Structs::ICEServerStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.urls); + ComplexArgumentParser::Finalize(request.username); + ComplexArgumentParser::Finalize(request.credential); + ComplexArgumentParser::Finalize(request.caid); +} + CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::detail::Structs::LabelStruct::Type & request, Json::Value & value) { @@ -493,6 +540,72 @@ void ComplexArgumentParser::Finalize(chip::app::Clusters::detail::Structs::Opera ComplexArgumentParser::Finalize(request.operationalStateLabel); } +CHIP_ERROR ComplexArgumentParser::Setup(const char * label, + chip::app::Clusters::detail::Structs::WebRTCSessionStruct::Type & request, + Json::Value & value) +{ + VerifyOrReturnError(value.isObject(), CHIP_ERROR_INVALID_ARGUMENT); + + // Copy to track which members we already processed. + Json::Value valueCopy(value); + + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("WebRTCSessionStruct.id", "id", value.isMember("id"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("WebRTCSessionStruct.peerNodeID", "peerNodeID", value.isMember("peerNodeID"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("WebRTCSessionStruct.peerFabricIndex", "peerFabricIndex", + value.isMember("peerFabricIndex"))); + ReturnErrorOnFailure( + ComplexArgumentParser::EnsureMemberExist("WebRTCSessionStruct.streamType", "streamType", value.isMember("streamType"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("WebRTCSessionStruct.videoStreamID", "videoStreamID", + value.isMember("videoStreamID"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("WebRTCSessionStruct.audioStreamID", "audioStreamID", + value.isMember("audioStreamID"))); + ReturnErrorOnFailure(ComplexArgumentParser::EnsureMemberExist("WebRTCSessionStruct.metadataOptions", "metadataOptions", + value.isMember("metadataOptions"))); + + char labelWithMember[kMaxLabelLength]; + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "id"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.id, value["id"])); + valueCopy.removeMember("id"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "peerNodeID"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.peerNodeID, value["peerNodeID"])); + valueCopy.removeMember("peerNodeID"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "peerFabricIndex"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.peerFabricIndex, value["peerFabricIndex"])); + valueCopy.removeMember("peerFabricIndex"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "streamType"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.streamType, value["streamType"])); + valueCopy.removeMember("streamType"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "videoStreamID"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.videoStreamID, value["videoStreamID"])); + valueCopy.removeMember("videoStreamID"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "audioStreamID"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.audioStreamID, value["audioStreamID"])); + valueCopy.removeMember("audioStreamID"); + + snprintf(labelWithMember, sizeof(labelWithMember), "%s.%s", label, "metadataOptions"); + ReturnErrorOnFailure(ComplexArgumentParser::Setup(labelWithMember, request.metadataOptions, value["metadataOptions"])); + valueCopy.removeMember("metadataOptions"); + + return ComplexArgumentParser::EnsureNoMembersRemaining(label, valueCopy); +} + +void ComplexArgumentParser::Finalize(chip::app::Clusters::detail::Structs::WebRTCSessionStruct::Type & request) +{ + ComplexArgumentParser::Finalize(request.id); + ComplexArgumentParser::Finalize(request.peerNodeID); + ComplexArgumentParser::Finalize(request.peerFabricIndex); + ComplexArgumentParser::Finalize(request.streamType); + ComplexArgumentParser::Finalize(request.videoStreamID); + ComplexArgumentParser::Finalize(request.audioStreamID); + ComplexArgumentParser::Finalize(request.metadataOptions); +} + CHIP_ERROR ComplexArgumentParser::Setup(const char * label, chip::app::Clusters::Descriptor::Structs::SemanticTagStruct::Type & request, Json::Value & value) diff --git a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h index 90898850e7..777f61afb9 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/ComplexArgumentParser.h @@ -72,6 +72,11 @@ static CHIP_ERROR Setup(const char * label, chip::app::Clusters::detail::Structs static void Finalize(chip::app::Clusters::detail::Structs::ErrorStateStruct::Type & request); +static CHIP_ERROR Setup(const char * label, chip::app::Clusters::detail::Structs::ICEServerStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::detail::Structs::ICEServerStruct::Type & request); + static CHIP_ERROR Setup(const char * label, chip::app::Clusters::detail::Structs::LabelStruct::Type & request, Json::Value & value); static void Finalize(chip::app::Clusters::detail::Structs::LabelStruct::Type & request); @@ -81,6 +86,11 @@ static CHIP_ERROR Setup(const char * label, chip::app::Clusters::detail::Structs static void Finalize(chip::app::Clusters::detail::Structs::OperationalStateStruct::Type & request); +static CHIP_ERROR Setup(const char * label, chip::app::Clusters::detail::Structs::WebRTCSessionStruct::Type & request, + Json::Value & value); + +static void Finalize(chip::app::Clusters::detail::Structs::WebRTCSessionStruct::Type & request); + static CHIP_ERROR Setup(const char * label, chip::app::Clusters::Descriptor::Structs::SemanticTagStruct::Type & request, Json::Value & value); diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp index 842863af83..479deb7799 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.cpp @@ -374,6 +374,47 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, return CHIP_NO_ERROR; } +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const chip::app::Clusters::detail::Structs::ICEServerStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("Urls", indent + 1, value.urls); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Urls'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Username", indent + 1, value.username); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Username'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Credential", indent + 1, value.credential); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Credential'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("Caid", indent + 1, value.caid); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Caid'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const chip::app::Clusters::detail::Structs::LabelStruct::DecodableType & value) { @@ -424,6 +465,71 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, return CHIP_NO_ERROR; } +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const chip::app::Clusters::detail::Structs::WebRTCSessionStruct::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + { + CHIP_ERROR err = LogValue("Id", indent + 1, value.id); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'Id'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("PeerNodeID", indent + 1, value.peerNodeID); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'PeerNodeID'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("PeerFabricIndex", indent + 1, value.peerFabricIndex); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'PeerFabricIndex'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("StreamType", indent + 1, value.streamType); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'StreamType'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("VideoStreamID", indent + 1, value.videoStreamID); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'VideoStreamID'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("AudioStreamID", indent + 1, value.audioStreamID); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'AudioStreamID'"); + return err; + } + } + { + CHIP_ERROR err = LogValue("MetadataOptions", indent + 1, value.metadataOptions); + if (err != CHIP_NO_ERROR) + { + DataModelLogger::LogString(indent + 1, "Struct truncated due to invalid value for 'MetadataOptions'"); + return err; + } + } + DataModelLogger::LogString(indent, "}"); + + return CHIP_NO_ERROR; +} + CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const chip::app::Clusters::Descriptor::Structs::SemanticTagStruct::DecodableType & value) { @@ -8741,6 +8847,27 @@ CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, DataModelLogger::LogString(indent, "}"); return CHIP_NO_ERROR; } +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const WebRTCTransportProvider::Commands::SolicitOfferResponse::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + ReturnErrorOnFailure(DataModelLogger::LogValue("webRTCSessionID", indent + 1, value.webRTCSessionID)); + ReturnErrorOnFailure(DataModelLogger::LogValue("deferredOffer", indent + 1, value.deferredOffer)); + ReturnErrorOnFailure(DataModelLogger::LogValue("videoStreamID", indent + 1, value.videoStreamID)); + ReturnErrorOnFailure(DataModelLogger::LogValue("audioStreamID", indent + 1, value.audioStreamID)); + DataModelLogger::LogString(indent, "}"); + return CHIP_NO_ERROR; +} +CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, + const WebRTCTransportProvider::Commands::ProvideOfferResponse::DecodableType & value) +{ + DataModelLogger::LogString(label, indent, "{"); + ReturnErrorOnFailure(DataModelLogger::LogValue("webRTCSessionID", indent + 1, value.webRTCSessionID)); + ReturnErrorOnFailure(DataModelLogger::LogValue("videoStreamID", indent + 1, value.videoStreamID)); + ReturnErrorOnFailure(DataModelLogger::LogValue("audioStreamID", indent + 1, value.audioStreamID)); + DataModelLogger::LogString(indent, "}"); + return CHIP_NO_ERROR; +} CHIP_ERROR DataModelLogger::LogValue(const char * label, size_t indent, const CommissionerControl::Commands::ReverseOpenCommissioningWindow::DecodableType & value) { @@ -17943,6 +18070,49 @@ CHIP_ERROR DataModelLogger::LogAttribute(const chip::app::ConcreteDataAttributeP } break; } + case WebRTCTransportProvider::Id: { + switch (path.mAttributeId) + { + case WebRTCTransportProvider::Attributes::CurrentSessions::Id: { + chip::app::DataModel::DecodableList< + chip::app::Clusters::WebRTCTransportProvider::Structs::WebRTCSessionStruct::DecodableType> + value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("CurrentSessions", 1, value); + } + case WebRTCTransportProvider::Attributes::GeneratedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogGeneratedCommandId("GeneratedCommandList", 1, value, WebRTCTransportProvider::Id); + } + case WebRTCTransportProvider::Attributes::AcceptedCommandList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogAcceptedCommandId("AcceptedCommandList", 1, value, WebRTCTransportProvider::Id); + } + case WebRTCTransportProvider::Attributes::EventList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("EventList", 1, value); + } + case WebRTCTransportProvider::Attributes::AttributeList::Id: { + chip::app::DataModel::DecodableList value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogAttributeId("AttributeList", 1, value, WebRTCTransportProvider::Id); + } + case WebRTCTransportProvider::Attributes::FeatureMap::Id: { + uint32_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("FeatureMap", 1, value); + } + case WebRTCTransportProvider::Attributes::ClusterRevision::Id: { + uint16_t value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ClusterRevision", 1, value); + } + } + break; + } case Chime::Id: { switch (path.mAttributeId) { @@ -19250,6 +19420,22 @@ CHIP_ERROR DataModelLogger::LogCommand(const chip::app::ConcreteCommandPath & pa } break; } + case WebRTCTransportProvider::Id: { + switch (path.mCommandId) + { + case WebRTCTransportProvider::Commands::SolicitOfferResponse::Id: { + WebRTCTransportProvider::Commands::SolicitOfferResponse::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("SolicitOfferResponse", 1, value); + } + case WebRTCTransportProvider::Commands::ProvideOfferResponse::Id: { + WebRTCTransportProvider::Commands::ProvideOfferResponse::DecodableType value; + ReturnErrorOnFailure(chip::app::DataModel::Decode(*data, value)); + return DataModelLogger::LogValue("ProvideOfferResponse", 1, value); + } + } + break; + } case CommissionerControl::Id: { switch (path.mCommandId) { diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h index f880614eeb..05432564bf 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/DataModelLogger.h @@ -50,12 +50,18 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::detail::Structs::ErrorStateStruct::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::detail::Structs::ICEServerStruct::DecodableType & value); + static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::detail::Structs::LabelStruct::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::detail::Structs::OperationalStateStruct::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, + const chip::app::Clusters::detail::Structs::WebRTCSessionStruct::DecodableType & value); + static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::Descriptor::Structs::SemanticTagStruct::DecodableType & value); @@ -848,6 +854,12 @@ static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::ContentAppObserver::Commands::ContentAppMessageResponse::DecodableType & value); static CHIP_ERROR +LogValue(const char * label, size_t indent, + const chip::app::Clusters::WebRTCTransportProvider::Commands::SolicitOfferResponse::DecodableType & value); +static CHIP_ERROR +LogValue(const char * label, size_t indent, + const chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideOfferResponse::DecodableType & value); +static CHIP_ERROR LogValue(const char * label, size_t indent, const chip::app::Clusters::CommissionerControl::Commands::ReverseOpenCommissioningWindow::DecodableType & value); static CHIP_ERROR LogValue(const char * label, size_t indent, diff --git a/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp b/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp index 47b4b54f81..f9e3e9d6e5 100644 --- a/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp +++ b/zzz_generated/chip-tool/zap-generated/cluster/logging/EntryToText.cpp @@ -259,6 +259,8 @@ char const * ClusterIdToText(chip::ClusterId id) return "ContentControl"; case chip::app::Clusters::ContentAppObserver::Id: return "ContentAppObserver"; + case chip::app::Clusters::WebRTCTransportProvider::Id: + return "WebRTCTransportProvider"; case chip::app::Clusters::Chime::Id: return "Chime"; case chip::app::Clusters::EcosystemInformation::Id: @@ -4377,6 +4379,27 @@ char const * AttributeIdToText(chip::ClusterId cluster, chip::AttributeId id) return "Unknown"; } } + case chip::app::Clusters::WebRTCTransportProvider::Id: { + switch (id) + { + case chip::app::Clusters::WebRTCTransportProvider::Attributes::CurrentSessions::Id: + return "CurrentSessions"; + case chip::app::Clusters::WebRTCTransportProvider::Attributes::GeneratedCommandList::Id: + return "GeneratedCommandList"; + case chip::app::Clusters::WebRTCTransportProvider::Attributes::AcceptedCommandList::Id: + return "AcceptedCommandList"; + case chip::app::Clusters::WebRTCTransportProvider::Attributes::EventList::Id: + return "EventList"; + case chip::app::Clusters::WebRTCTransportProvider::Attributes::AttributeList::Id: + return "AttributeList"; + case chip::app::Clusters::WebRTCTransportProvider::Attributes::FeatureMap::Id: + return "FeatureMap"; + case chip::app::Clusters::WebRTCTransportProvider::Attributes::ClusterRevision::Id: + return "ClusterRevision"; + default: + return "Unknown"; + } + } case chip::app::Clusters::Chime::Id: { switch (id) { @@ -5728,6 +5751,23 @@ char const * AcceptedCommandIdToText(chip::ClusterId cluster, chip::CommandId id return "Unknown"; } } + case chip::app::Clusters::WebRTCTransportProvider::Id: { + switch (id) + { + case chip::app::Clusters::WebRTCTransportProvider::Commands::SolicitOffer::Id: + return "SolicitOffer"; + case chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideOffer::Id: + return "ProvideOffer"; + case chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideAnswer::Id: + return "ProvideAnswer"; + case chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideICECandidate::Id: + return "ProvideICECandidate"; + case chip::app::Clusters::WebRTCTransportProvider::Commands::EndSession::Id: + return "EndSession"; + default: + return "Unknown"; + } + } case chip::app::Clusters::Chime::Id: { switch (id) { @@ -6260,6 +6300,17 @@ char const * GeneratedCommandIdToText(chip::ClusterId cluster, chip::CommandId i return "Unknown"; } } + case chip::app::Clusters::WebRTCTransportProvider::Id: { + switch (id) + { + case chip::app::Clusters::WebRTCTransportProvider::Commands::SolicitOfferResponse::Id: + return "SolicitOfferResponse"; + case chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideOfferResponse::Id: + return "ProvideOfferResponse"; + default: + return "Unknown"; + } + } case chip::app::Clusters::CommissionerControl::Id: { switch (id) { diff --git a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h index d82bd114c2..329e0b8546 100644 --- a/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h +++ b/zzz_generated/darwin-framework-tool/zap-generated/cluster/Commands.h @@ -154,6 +154,7 @@ | AccountLogin | 0x050E | | ContentControl | 0x050F | | ContentAppObserver | 0x0510 | +| WebRTCTransportProvider | 0x0553 | | Chime | 0x0556 | | EcosystemInformation | 0x0750 | | CommissionerControl | 0x0751 | @@ -160029,6 +160030,1121 @@ class SubscribeAttributeContentAppObserverClusterRevision : public SubscribeAttr } }; +#endif // MTR_ENABLE_PROVISIONAL +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/*----------------------------------------------------------------------------*\ +| Cluster WebRTCTransportProvider | 0x0553 | +|------------------------------------------------------------------------------| +| Commands: | | +| * SolicitOffer | 0x01 | +| * ProvideOffer | 0x03 | +| * ProvideAnswer | 0x05 | +| * ProvideICECandidate | 0x06 | +| * EndSession | 0x07 | +|------------------------------------------------------------------------------| +| Attributes: | | +| * CurrentSessions | 0x0000 | +| * GeneratedCommandList | 0xFFF8 | +| * AcceptedCommandList | 0xFFF9 | +| * EventList | 0xFFFA | +| * AttributeList | 0xFFFB | +| * FeatureMap | 0xFFFC | +| * ClusterRevision | 0xFFFD | +|------------------------------------------------------------------------------| +| Events: | | +\*----------------------------------------------------------------------------*/ + +#if MTR_ENABLE_PROVISIONAL +/* + * Command SolicitOffer + */ +class WebRTCTransportProviderSolicitOffer : public ClusterCommand { +public: + WebRTCTransportProviderSolicitOffer() + : ClusterCommand("solicit-offer") + , mComplex_ICEServers(&mRequest.ICEServers) + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("StreamType", 0, UINT8_MAX, &mRequest.streamType); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("VideoStreamID", 0, UINT16_MAX, &mRequest.videoStreamID); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("AudioStreamID", 0, UINT16_MAX, &mRequest.audioStreamID); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("ICEServers", &mComplex_ICEServers); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("ICETransportPolicy", &mRequest.ICETransportPolicy); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("MetadataOptions", 0, UINT8_MAX, &mRequest.metadataOptions); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WebRTCTransportProvider::Commands::SolicitOffer::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + __auto_type * cluster = [[MTRBaseClusterWebRTCTransportProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWebRTCTransportProviderClusterSolicitOfferParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + params.streamType = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.streamType)]; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.videoStreamID.HasValue()) { + if (mRequest.videoStreamID.Value().IsNull()) { + params.videoStreamID = nil; + } else { + params.videoStreamID = [NSNumber numberWithUnsignedShort:mRequest.videoStreamID.Value().Value()]; + } + } else { + params.videoStreamID = nil; + } +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.audioStreamID.HasValue()) { + if (mRequest.audioStreamID.Value().IsNull()) { + params.audioStreamID = nil; + } else { + params.audioStreamID = [NSNumber numberWithUnsignedShort:mRequest.audioStreamID.Value().Value()]; + } + } else { + params.audioStreamID = nil; + } +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.ICEServers.HasValue()) { + { // Scope for our temporary variables + auto * array_1 = [NSMutableArray new]; + for (auto & entry_1 : mRequest.ICEServers.Value()) { + MTRWebRTCTransportProviderClusterICEServerStruct * newElement_1; + newElement_1 = [MTRWebRTCTransportProviderClusterICEServerStruct new]; + { // Scope for our temporary variables + auto * array_3 = [NSMutableArray new]; + for (auto & entry_3 : entry_1.urls) { + NSString * newElement_3; + newElement_3 = [[NSString alloc] initWithBytes:entry_3.data() length:entry_3.size() encoding:NSUTF8StringEncoding]; + [array_3 addObject:newElement_3]; + } + newElement_1.urls = array_3; + } + if (entry_1.username.HasValue()) { + newElement_1.username = [[NSString alloc] initWithBytes:entry_1.username.Value().data() length:entry_1.username.Value().size() encoding:NSUTF8StringEncoding]; + } else { + newElement_1.username = nil; + } + if (entry_1.credential.HasValue()) { + newElement_1.credential = [[NSString alloc] initWithBytes:entry_1.credential.Value().data() length:entry_1.credential.Value().size() encoding:NSUTF8StringEncoding]; + } else { + newElement_1.credential = nil; + } + if (entry_1.caid.HasValue()) { + newElement_1.caid = [NSNumber numberWithUnsignedShort:entry_1.caid.Value()]; + } else { + newElement_1.caid = nil; + } + [array_1 addObject:newElement_1]; + } + params.iceServers = array_1; + } + } else { + params.iceServers = nil; + } +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.ICETransportPolicy.HasValue()) { + params.iceTransportPolicy = [[NSString alloc] initWithBytes:mRequest.ICETransportPolicy.Value().data() length:mRequest.ICETransportPolicy.Value().size() encoding:NSUTF8StringEncoding]; + } else { + params.iceTransportPolicy = nil; + } +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.metadataOptions.HasValue()) { + params.metadataOptions = [NSNumber numberWithUnsignedChar:mRequest.metadataOptions.Value().Raw()]; + } else { + params.metadataOptions = nil; + } +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster solicitOfferWithParams:params completion: + ^(MTRWebRTCTransportProviderClusterSolicitOfferResponseParams * _Nullable values, NSError * _Nullable error) { + NSLog(@"Values: %@", values); + if (error == nil) { + constexpr chip::CommandId responseId = chip::app::Clusters::WebRTCTransportProvider::Commands::SolicitOfferResponse::Id; + RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); + } + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + constexpr chip::CommandId responseId = chip::app::Clusters::WebRTCTransportProvider::Commands::SolicitOfferResponse::Id; + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::WebRTCTransportProvider::Commands::SolicitOffer::Type mRequest; + TypedComplexArgument>> mComplex_ICEServers; +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/* + * Command ProvideOffer + */ +class WebRTCTransportProviderProvideOffer : public ClusterCommand { +public: + WebRTCTransportProviderProvideOffer() + : ClusterCommand("provide-offer") + , mComplex_ICEServers(&mRequest.ICEServers) + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("WebRTCSessionID", 0, UINT16_MAX, &mRequest.webRTCSessionID); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("Sdp", &mRequest.sdp); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("StreamType", 0, UINT8_MAX, &mRequest.streamType); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("VideoStreamID", 0, UINT16_MAX, &mRequest.videoStreamID); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("AudioStreamID", 0, UINT16_MAX, &mRequest.audioStreamID); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("ICEServers", &mComplex_ICEServers); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("ICETransportPolicy", &mRequest.ICETransportPolicy); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("MetadataOptions", 0, UINT8_MAX, &mRequest.metadataOptions); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideOffer::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + __auto_type * cluster = [[MTRBaseClusterWebRTCTransportProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWebRTCTransportProviderClusterProvideOfferParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + if (mRequest.webRTCSessionID.IsNull()) { + params.webRTCSessionID = nil; + } else { + params.webRTCSessionID = [NSNumber numberWithUnsignedShort:mRequest.webRTCSessionID.Value()]; + } +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + params.sdp = [[NSString alloc] initWithBytes:mRequest.sdp.data() length:mRequest.sdp.size() encoding:NSUTF8StringEncoding]; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + params.streamType = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.streamType)]; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.videoStreamID.HasValue()) { + if (mRequest.videoStreamID.Value().IsNull()) { + params.videoStreamID = nil; + } else { + params.videoStreamID = [NSNumber numberWithUnsignedShort:mRequest.videoStreamID.Value().Value()]; + } + } else { + params.videoStreamID = nil; + } +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.audioStreamID.HasValue()) { + if (mRequest.audioStreamID.Value().IsNull()) { + params.audioStreamID = nil; + } else { + params.audioStreamID = [NSNumber numberWithUnsignedShort:mRequest.audioStreamID.Value().Value()]; + } + } else { + params.audioStreamID = nil; + } +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.ICEServers.HasValue()) { + { // Scope for our temporary variables + auto * array_1 = [NSMutableArray new]; + for (auto & entry_1 : mRequest.ICEServers.Value()) { + MTRWebRTCTransportProviderClusterICEServerStruct * newElement_1; + newElement_1 = [MTRWebRTCTransportProviderClusterICEServerStruct new]; + { // Scope for our temporary variables + auto * array_3 = [NSMutableArray new]; + for (auto & entry_3 : entry_1.urls) { + NSString * newElement_3; + newElement_3 = [[NSString alloc] initWithBytes:entry_3.data() length:entry_3.size() encoding:NSUTF8StringEncoding]; + [array_3 addObject:newElement_3]; + } + newElement_1.urls = array_3; + } + if (entry_1.username.HasValue()) { + newElement_1.username = [[NSString alloc] initWithBytes:entry_1.username.Value().data() length:entry_1.username.Value().size() encoding:NSUTF8StringEncoding]; + } else { + newElement_1.username = nil; + } + if (entry_1.credential.HasValue()) { + newElement_1.credential = [[NSString alloc] initWithBytes:entry_1.credential.Value().data() length:entry_1.credential.Value().size() encoding:NSUTF8StringEncoding]; + } else { + newElement_1.credential = nil; + } + if (entry_1.caid.HasValue()) { + newElement_1.caid = [NSNumber numberWithUnsignedShort:entry_1.caid.Value()]; + } else { + newElement_1.caid = nil; + } + [array_1 addObject:newElement_1]; + } + params.iceServers = array_1; + } + } else { + params.iceServers = nil; + } +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.ICETransportPolicy.HasValue()) { + params.iceTransportPolicy = [[NSString alloc] initWithBytes:mRequest.ICETransportPolicy.Value().data() length:mRequest.ICETransportPolicy.Value().size() encoding:NSUTF8StringEncoding]; + } else { + params.iceTransportPolicy = nil; + } +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + if (mRequest.metadataOptions.HasValue()) { + params.metadataOptions = [NSNumber numberWithUnsignedChar:mRequest.metadataOptions.Value().Raw()]; + } else { + params.metadataOptions = nil; + } +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster provideOfferWithParams:params completion: + ^(MTRWebRTCTransportProviderClusterProvideOfferResponseParams * _Nullable values, NSError * _Nullable error) { + NSLog(@"Values: %@", values); + if (error == nil) { + constexpr chip::CommandId responseId = chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideOfferResponse::Id; + RemoteDataModelLogger::LogCommandAsJSON(@(endpointId), @(clusterId), @(responseId), values); + } + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + constexpr chip::CommandId responseId = chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideOfferResponse::Id; + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(responseId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideOffer::Type mRequest; + TypedComplexArgument>> mComplex_ICEServers; +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/* + * Command ProvideAnswer + */ +class WebRTCTransportProviderProvideAnswer : public ClusterCommand { +public: + WebRTCTransportProviderProvideAnswer() + : ClusterCommand("provide-answer") + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("WebRTCSessionID", 0, UINT16_MAX, &mRequest.webRTCSessionID); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("Sdp", &mRequest.sdp); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideAnswer::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + __auto_type * cluster = [[MTRBaseClusterWebRTCTransportProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWebRTCTransportProviderClusterProvideAnswerParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + params.webRTCSessionID = [NSNumber numberWithUnsignedShort:mRequest.webRTCSessionID]; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + params.sdp = [[NSString alloc] initWithBytes:mRequest.sdp.data() length:mRequest.sdp.size() encoding:NSUTF8StringEncoding]; +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster provideAnswerWithParams:params completion: + ^(NSError * _Nullable error) { + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(commandId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideAnswer::Type mRequest; +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/* + * Command ProvideICECandidate + */ +class WebRTCTransportProviderProvideICECandidate : public ClusterCommand { +public: + WebRTCTransportProviderProvideICECandidate() + : ClusterCommand("provide-icecandidate") + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("WebRTCSessionID", 0, UINT16_MAX, &mRequest.webRTCSessionID); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("ICECandidate", &mRequest.ICECandidate); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideICECandidate::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + __auto_type * cluster = [[MTRBaseClusterWebRTCTransportProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWebRTCTransportProviderClusterProvideICECandidateParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + params.webRTCSessionID = [NSNumber numberWithUnsignedShort:mRequest.webRTCSessionID]; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + params.iceCandidate = [[NSString alloc] initWithBytes:mRequest.ICECandidate.data() length:mRequest.ICECandidate.size() encoding:NSUTF8StringEncoding]; +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster provideICECandidateWithParams:params completion: + ^(NSError * _Nullable error) { + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(commandId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::WebRTCTransportProvider::Commands::ProvideICECandidate::Type mRequest; +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL +/* + * Command EndSession + */ +class WebRTCTransportProviderEndSession : public ClusterCommand { +public: + WebRTCTransportProviderEndSession() + : ClusterCommand("end-session") + { +#if MTR_ENABLE_PROVISIONAL + AddArgument("WebRTCSessionID", 0, UINT16_MAX, &mRequest.webRTCSessionID); +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + AddArgument("Reason", 0, UINT8_MAX, &mRequest.reason); +#endif // MTR_ENABLE_PROVISIONAL + ClusterCommand::AddArguments(); + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId commandId = chip::app::Clusters::WebRTCTransportProvider::Commands::EndSession::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") command (0x%08" PRIX32 ") on endpoint %u", clusterId, commandId, endpointId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + __auto_type * cluster = [[MTRBaseClusterWebRTCTransportProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRWebRTCTransportProviderClusterEndSessionParams alloc] init]; + params.timedInvokeTimeoutMs = mTimedInteractionTimeoutMs.HasValue() ? [NSNumber numberWithUnsignedShort:mTimedInteractionTimeoutMs.Value()] : nil; +#if MTR_ENABLE_PROVISIONAL + params.webRTCSessionID = [NSNumber numberWithUnsignedShort:mRequest.webRTCSessionID]; +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + params.reason = [NSNumber numberWithUnsignedChar:chip::to_underlying(mRequest.reason)]; +#endif // MTR_ENABLE_PROVISIONAL + uint16_t repeatCount = mRepeatCount.ValueOr(1); + uint16_t __block responsesNeeded = repeatCount; + while (repeatCount--) { + [cluster endSessionWithParams:params completion: + ^(NSError * _Nullable error) { + responsesNeeded--; + if (error != nil) { + mError = error; + LogNSError("Error", error); + RemoteDataModelLogger::LogCommandErrorAsJSON(@(endpointId), @(clusterId), @(commandId), error); + } + if (responsesNeeded == 0) { + SetCommandExitStatus(mError); + } + }]; + } + return CHIP_NO_ERROR; + } + +private: + chip::app::Clusters::WebRTCTransportProvider::Commands::EndSession::Type mRequest; +}; + +#endif // MTR_ENABLE_PROVISIONAL + +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute CurrentSessions + */ +class ReadWebRTCTransportProviderCurrentSessions : public ReadAttribute { +public: + ReadWebRTCTransportProviderCurrentSessions() + : ReadAttribute("current-sessions") + { + } + + ~ReadWebRTCTransportProviderCurrentSessions() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WebRTCTransportProvider::Attributes::CurrentSessions::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + __auto_type * cluster = [[MTRBaseClusterWebRTCTransportProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeCurrentSessionsWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WebRTCTransportProvider.CurrentSessions response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WebRTCTransportProvider CurrentSessions read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWebRTCTransportProviderCurrentSessions : public SubscribeAttribute { +public: + SubscribeAttributeWebRTCTransportProviderCurrentSessions() + : SubscribeAttribute("current-sessions") + { + } + + ~SubscribeAttributeWebRTCTransportProviderCurrentSessions() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WebRTCTransportProvider::Attributes::CurrentSessions::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + __auto_type * cluster = [[MTRBaseClusterWebRTCTransportProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeCurrentSessionsWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WebRTCTransportProvider.CurrentSessions response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute GeneratedCommandList + */ +class ReadWebRTCTransportProviderGeneratedCommandList : public ReadAttribute { +public: + ReadWebRTCTransportProviderGeneratedCommandList() + : ReadAttribute("generated-command-list") + { + } + + ~ReadWebRTCTransportProviderGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WebRTCTransportProvider::Attributes::GeneratedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + __auto_type * cluster = [[MTRBaseClusterWebRTCTransportProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeGeneratedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WebRTCTransportProvider.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WebRTCTransportProvider GeneratedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWebRTCTransportProviderGeneratedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeWebRTCTransportProviderGeneratedCommandList() + : SubscribeAttribute("generated-command-list") + { + } + + ~SubscribeAttributeWebRTCTransportProviderGeneratedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WebRTCTransportProvider::Attributes::GeneratedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + __auto_type * cluster = [[MTRBaseClusterWebRTCTransportProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeGeneratedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WebRTCTransportProvider.GeneratedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute AcceptedCommandList + */ +class ReadWebRTCTransportProviderAcceptedCommandList : public ReadAttribute { +public: + ReadWebRTCTransportProviderAcceptedCommandList() + : ReadAttribute("accepted-command-list") + { + } + + ~ReadWebRTCTransportProviderAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WebRTCTransportProvider::Attributes::AcceptedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + __auto_type * cluster = [[MTRBaseClusterWebRTCTransportProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAcceptedCommandListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WebRTCTransportProvider.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WebRTCTransportProvider AcceptedCommandList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWebRTCTransportProviderAcceptedCommandList : public SubscribeAttribute { +public: + SubscribeAttributeWebRTCTransportProviderAcceptedCommandList() + : SubscribeAttribute("accepted-command-list") + { + } + + ~SubscribeAttributeWebRTCTransportProviderAcceptedCommandList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WebRTCTransportProvider::Attributes::AcceptedCommandList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + __auto_type * cluster = [[MTRBaseClusterWebRTCTransportProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeAcceptedCommandListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WebRTCTransportProvider.AcceptedCommandList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute EventList + */ +class ReadWebRTCTransportProviderEventList : public ReadAttribute { +public: + ReadWebRTCTransportProviderEventList() + : ReadAttribute("event-list") + { + } + + ~ReadWebRTCTransportProviderEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WebRTCTransportProvider::Attributes::EventList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + __auto_type * cluster = [[MTRBaseClusterWebRTCTransportProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeEventListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WebRTCTransportProvider.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WebRTCTransportProvider EventList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWebRTCTransportProviderEventList : public SubscribeAttribute { +public: + SubscribeAttributeWebRTCTransportProviderEventList() + : SubscribeAttribute("event-list") + { + } + + ~SubscribeAttributeWebRTCTransportProviderEventList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WebRTCTransportProvider::Attributes::EventList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + __auto_type * cluster = [[MTRBaseClusterWebRTCTransportProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeEventListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WebRTCTransportProvider.EventList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute AttributeList + */ +class ReadWebRTCTransportProviderAttributeList : public ReadAttribute { +public: + ReadWebRTCTransportProviderAttributeList() + : ReadAttribute("attribute-list") + { + } + + ~ReadWebRTCTransportProviderAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WebRTCTransportProvider::Attributes::AttributeList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + __auto_type * cluster = [[MTRBaseClusterWebRTCTransportProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeAttributeListWithCompletion:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WebRTCTransportProvider.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WebRTCTransportProvider AttributeList read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWebRTCTransportProviderAttributeList : public SubscribeAttribute { +public: + SubscribeAttributeWebRTCTransportProviderAttributeList() + : SubscribeAttribute("attribute-list") + { + } + + ~SubscribeAttributeWebRTCTransportProviderAttributeList() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WebRTCTransportProvider::Attributes::AttributeList::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + __auto_type * cluster = [[MTRBaseClusterWebRTCTransportProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeAttributeListWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSArray * _Nullable value, NSError * _Nullable error) { + NSLog(@"WebRTCTransportProvider.AttributeList response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute FeatureMap + */ +class ReadWebRTCTransportProviderFeatureMap : public ReadAttribute { +public: + ReadWebRTCTransportProviderFeatureMap() + : ReadAttribute("feature-map") + { + } + + ~ReadWebRTCTransportProviderFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WebRTCTransportProvider::Attributes::FeatureMap::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + __auto_type * cluster = [[MTRBaseClusterWebRTCTransportProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeFeatureMapWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WebRTCTransportProvider.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WebRTCTransportProvider FeatureMap read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWebRTCTransportProviderFeatureMap : public SubscribeAttribute { +public: + SubscribeAttributeWebRTCTransportProviderFeatureMap() + : SubscribeAttribute("feature-map") + { + } + + ~SubscribeAttributeWebRTCTransportProviderFeatureMap() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WebRTCTransportProvider::Attributes::FeatureMap::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + __auto_type * cluster = [[MTRBaseClusterWebRTCTransportProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeFeatureMapWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WebRTCTransportProvider.FeatureMap response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + +/* + * Attribute ClusterRevision + */ +class ReadWebRTCTransportProviderClusterRevision : public ReadAttribute { +public: + ReadWebRTCTransportProviderClusterRevision() + : ReadAttribute("cluster-revision") + { + } + + ~ReadWebRTCTransportProviderClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::AttributeId attributeId = chip::app::Clusters::WebRTCTransportProvider::Attributes::ClusterRevision::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReadAttribute (0x%08" PRIX32 ") on endpoint %u", endpointId, clusterId, attributeId); + + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + __auto_type * cluster = [[MTRBaseClusterWebRTCTransportProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + [cluster readAttributeClusterRevisionWithCompletion:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WebRTCTransportProvider.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + LogNSError("WebRTCTransportProvider ClusterRevision read Error", error); + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + return CHIP_NO_ERROR; + } +}; + +class SubscribeAttributeWebRTCTransportProviderClusterRevision : public SubscribeAttribute { +public: + SubscribeAttributeWebRTCTransportProviderClusterRevision() + : SubscribeAttribute("cluster-revision") + { + } + + ~SubscribeAttributeWebRTCTransportProviderClusterRevision() + { + } + + CHIP_ERROR SendCommand(MTRBaseDevice * device, chip::EndpointId endpointId) override + { + constexpr chip::ClusterId clusterId = chip::app::Clusters::WebRTCTransportProvider::Id; + constexpr chip::CommandId attributeId = chip::app::Clusters::WebRTCTransportProvider::Attributes::ClusterRevision::Id; + + ChipLogProgress(chipTool, "Sending cluster (0x%08" PRIX32 ") ReportAttribute (0x%08" PRIX32 ") on endpoint %u", clusterId, attributeId, endpointId); + dispatch_queue_t callbackQueue = dispatch_queue_create("com.chip.command", DISPATCH_QUEUE_SERIAL_WITH_AUTORELEASE_POOL); + __auto_type * cluster = [[MTRBaseClusterWebRTCTransportProvider alloc] initWithDevice:device endpointID:@(endpointId) queue:callbackQueue]; + __auto_type * params = [[MTRSubscribeParams alloc] initWithMinInterval:@(mMinInterval) maxInterval:@(mMaxInterval)]; + if (mKeepSubscriptions.HasValue()) { + params.replaceExistingSubscriptions = !mKeepSubscriptions.Value(); + } + if (mFabricFiltered.HasValue()) { + params.filterByFabric = mFabricFiltered.Value(); + } + if (mAutoResubscribe.HasValue()) { + params.resubscribeAutomatically = mAutoResubscribe.Value(); + } + [cluster subscribeAttributeClusterRevisionWithParams:params + subscriptionEstablished:^() { mSubscriptionEstablished = YES; } + reportHandler:^(NSNumber * _Nullable value, NSError * _Nullable error) { + NSLog(@"WebRTCTransportProvider.ClusterRevision response %@", [value description]); + if (error == nil) { + RemoteDataModelLogger::LogAttributeAsJSON(@(endpointId), @(clusterId), @(attributeId), value); + } else { + RemoteDataModelLogger::LogAttributeErrorAsJSON(@(endpointId), @(clusterId), @(attributeId), error); + } + SetCommandExitStatus(error); + }]; + + return CHIP_NO_ERROR; + } +}; + #endif // MTR_ENABLE_PROVISIONAL #endif // MTR_ENABLE_PROVISIONAL #if MTR_ENABLE_PROVISIONAL @@ -183935,6 +185051,66 @@ void registerClusterContentAppObserver(Commands & commands) commands.RegisterCluster(clusterName, clusterCommands); #endif // MTR_ENABLE_PROVISIONAL } +void registerClusterWebRTCTransportProvider(Commands & commands) +{ +#if MTR_ENABLE_PROVISIONAL + using namespace chip::app::Clusters::WebRTCTransportProvider; + + const char * clusterName = "WebRTCTransportProvider"; + + commands_list clusterCommands = { + make_unique(Id), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL + make_unique(Id), // + make_unique(Id), // + make_unique(Id), // +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL +#if MTR_ENABLE_PROVISIONAL + make_unique(), // + make_unique(), // +#endif // MTR_ENABLE_PROVISIONAL + }; + + commands.RegisterCluster(clusterName, clusterCommands); +#endif // MTR_ENABLE_PROVISIONAL +} void registerClusterChime(Commands & commands) { #if MTR_ENABLE_PROVISIONAL @@ -184633,6 +185809,7 @@ void registerClusters(Commands & commands) registerClusterAccountLogin(commands); registerClusterContentControl(commands); registerClusterContentAppObserver(commands); + registerClusterWebRTCTransportProvider(commands); registerClusterChime(commands); registerClusterEcosystemInformation(commands); registerClusterCommissionerControl(commands); From dc3fcc8ba210da2552a11bc38e44416a5274758a Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Thu, 3 Oct 2024 17:16:41 -0700 Subject: [PATCH 06/22] [Fabric-Admin] Refactor to use API methods instead of PushCommand (2/3) (#35867) * Refactor to use API methods instead of PushCommand for pairing * Restyled by whitespace * Restyled by clang-format * Schedule work on the Matter thread * Update examples/fabric-admin/device_manager/PairingManager.cpp Co-authored-by: Terence Hampson * Update examples/fabric-admin/device_manager/PairingManager.cpp Co-authored-by: Terence Hampson * Update examples/fabric-admin/device_manager/PairingManager.cpp Co-authored-by: Terence Hampson * Update examples/fabric-admin/device_manager/PairingManager.cpp Co-authored-by: Terence Hampson * Address review comments * Cleanup CCTRL attestation logic from PairingCommand --------- Co-authored-by: Restyled.io Co-authored-by: Terence Hampson --- .../commands/common/CHIPCommand.cpp | 2 +- .../commands/common/CHIPCommand.h | 3 +- .../fabric-sync/FabricSyncCommand.cpp | 46 +- .../commands/fabric-sync/FabricSyncCommand.h | 2 - .../commands/pairing/PairingCommand.cpp | 111 +--- .../commands/pairing/PairingCommand.h | 27 - .../device_manager/DeviceManager.cpp | 70 +-- .../device_manager/DeviceManager.h | 2 +- .../device_manager/PairingManager.cpp | 534 +++++++++++++++++- .../device_manager/PairingManager.h | 156 ++++- 10 files changed, 711 insertions(+), 242 deletions(-) diff --git a/examples/fabric-admin/commands/common/CHIPCommand.cpp b/examples/fabric-admin/commands/common/CHIPCommand.cpp index b18eb9f2de..c23ea82f20 100644 --- a/examples/fabric-admin/commands/common/CHIPCommand.cpp +++ b/examples/fabric-admin/commands/common/CHIPCommand.cpp @@ -182,7 +182,7 @@ CHIP_ERROR CHIPCommand::MaybeSetUpStack() mCredIssuerCmds->SetCredentialIssuerOption(CredentialIssuerCommands::CredentialIssuerOptions::kAllowTestCdSigningKey, allowTestCdSigningKey); - PairingManager::Instance().Init(&CurrentCommissioner()); + ReturnLogErrorOnFailure(PairingManager::Instance().Init(&CurrentCommissioner(), mCredIssuerCmds)); return CHIP_NO_ERROR; } diff --git a/examples/fabric-admin/commands/common/CHIPCommand.h b/examples/fabric-admin/commands/common/CHIPCommand.h index abd68f6344..79d1fcb0fe 100644 --- a/examples/fabric-admin/commands/common/CHIPCommand.h +++ b/examples/fabric-admin/commands/common/CHIPCommand.h @@ -120,6 +120,8 @@ class CHIPCommand : public Command StopWaiting(); } + static chip::app::DefaultICDClientStorage sICDClientStorage; + protected: // Will be called in a setting in which it's safe to touch the CHIP // stack. The rules for Run() are as follows: @@ -167,7 +169,6 @@ class CHIPCommand : public Command static chip::Crypto::RawKeySessionKeystore sSessionKeystore; static chip::Credentials::GroupDataProviderImpl sGroupDataProvider; - static chip::app::DefaultICDClientStorage sICDClientStorage; static chip::app::CheckInHandler sCheckInHandler; CredentialIssuerCommands * mCredIssuerCmds; diff --git a/examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.cpp b/examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.cpp index 6e1b198ad9..c8d9f3da96 100644 --- a/examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.cpp +++ b/examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.cpp @@ -94,15 +94,8 @@ CHIP_ERROR FabricSyncAddBridgeCommand::RunCommand(NodeId remoteId) return CHIP_NO_ERROR; } - PairingCommand * pairingCommand = static_cast(CommandMgr().GetCommandByName("pairing", "already-discovered")); + PairingManager::Instance().SetCommissioningDelegate(this); - if (pairingCommand == nullptr) - { - ChipLogError(NotSpecified, "Pairing already-discovered command is not available"); - return CHIP_ERROR_NOT_IMPLEMENTED; - } - - pairingCommand->RegisterCommissioningDelegate(this); mBridgeNodeId = remoteId; DeviceMgr().PairRemoteFabricBridge(remoteId, mSetupPINCode, reinterpret_cast(mRemoteAddr.data()), mRemotePort); @@ -146,16 +139,7 @@ CHIP_ERROR FabricSyncRemoveBridgeCommand::RunCommand() mBridgeNodeId = bridgeNodeId; - PairingCommand * pairingCommand = static_cast(CommandMgr().GetCommandByName("pairing", "unpair")); - - if (pairingCommand == nullptr) - { - ChipLogError(NotSpecified, "Pairing unpair command is not available"); - return CHIP_ERROR_NOT_IMPLEMENTED; - } - - pairingCommand->RegisterPairingDelegate(this); - + PairingManager::Instance().SetPairingDelegate(this); DeviceMgr().UnpairRemoteFabricBridge(); return CHIP_NO_ERROR; @@ -203,10 +187,7 @@ CHIP_ERROR FabricSyncAddLocalBridgeCommand::RunCommand(NodeId deviceId) return CHIP_NO_ERROR; } - PairingCommand * pairingCommand = static_cast(CommandMgr().GetCommandByName("pairing", "already-discovered")); - VerifyOrDie(pairingCommand != nullptr); - - pairingCommand->RegisterCommissioningDelegate(this); + PairingManager::Instance().SetCommissioningDelegate(this); mLocalBridgeNodeId = deviceId; if (mSetupPINCode.HasValue()) @@ -259,16 +240,7 @@ CHIP_ERROR FabricSyncRemoveLocalBridgeCommand::RunCommand() mLocalBridgeNodeId = bridgeNodeId; - PairingCommand * pairingCommand = static_cast(CommandMgr().GetCommandByName("pairing", "unpair")); - - if (pairingCommand == nullptr) - { - ChipLogError(NotSpecified, "Pairing unpair command is not available"); - return CHIP_ERROR_NOT_IMPLEMENTED; - } - - pairingCommand->RegisterPairingDelegate(this); - + PairingManager::Instance().SetPairingDelegate(this); DeviceMgr().UnpairLocalFabricBridge(); return CHIP_NO_ERROR; @@ -287,15 +259,7 @@ void FabricSyncDeviceCommand::OnCommissioningWindowOpened(NodeId deviceId, CHIP_ { NodeId nodeId = DeviceMgr().GetNextAvailableNodeId(); - PairingCommand * pairingCommand = static_cast(CommandMgr().GetCommandByName("pairing", "code")); - - if (pairingCommand == nullptr) - { - ChipLogError(NotSpecified, "Pairing code command is not available"); - return; - } - - pairingCommand->RegisterCommissioningDelegate(this); + PairingManager::Instance().SetCommissioningDelegate(this); mAssignedNodeId = nodeId; usleep(kCommissionPrepareTimeMs * 1000); diff --git a/examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.h b/examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.h index e80f101338..16ee40e5b4 100644 --- a/examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.h +++ b/examples/fabric-admin/commands/fabric-sync/FabricSyncCommand.h @@ -19,12 +19,10 @@ #pragma once #include -#include #include // Constants constexpr uint32_t kCommissionPrepareTimeMs = 500; -constexpr uint16_t kMaxManualCodeLength = 21; class FabricSyncAddBridgeCommand : public CHIPCommand, public CommissioningDelegate { diff --git a/examples/fabric-admin/commands/pairing/PairingCommand.cpp b/examples/fabric-admin/commands/pairing/PairingCommand.cpp index 12a6a28f08..37578472b7 100644 --- a/examples/fabric-admin/commands/pairing/PairingCommand.cpp +++ b/examples/fabric-admin/commands/pairing/PairingCommand.cpp @@ -30,7 +30,6 @@ #include #include #include -#include #include @@ -41,28 +40,6 @@ using namespace ::chip; using namespace ::chip::Controller; -namespace { - -CHIP_ERROR GetPayload(const char * setUpCode, SetupPayload & payload) -{ - VerifyOrReturnValue(setUpCode, CHIP_ERROR_INVALID_ARGUMENT); - bool isQRCode = strncmp(setUpCode, kQRCodePrefix, strlen(kQRCodePrefix)) == 0; - if (isQRCode) - { - ReturnErrorOnFailure(QRCodeSetupPayloadParser(setUpCode).populatePayload(payload)); - VerifyOrReturnError(payload.isValidQRCodePayload(), CHIP_ERROR_INVALID_ARGUMENT); - } - else - { - ReturnErrorOnFailure(ManualSetupPayloadParser(setUpCode).populatePayload(payload)); - VerifyOrReturnError(payload.isValidManualCode(), CHIP_ERROR_INVALID_ARGUMENT); - } - - return CHIP_NO_ERROR; -} - -} // namespace - CHIP_ERROR PairingCommand::RunCommand() { CurrentCommissioner().RegisterPairingDelegate(this); @@ -128,7 +105,10 @@ CommissioningParameters PairingCommand::GetCommissioningParameters() { auto params = CommissioningParameters(); params.SetSkipCommissioningComplete(mSkipCommissioningComplete.ValueOr(false)); - params.SetDeviceAttestationDelegate(this); + if (mBypassAttestationVerifier.ValueOr(false)) + { + params.SetDeviceAttestationDelegate(this); + } switch (mNetworkType) { @@ -442,12 +422,6 @@ void PairingCommand::OnCommissioningComplete(NodeId nodeId, CHIP_ERROR err) ChipLogProgress(NotSpecified, "Device commissioning Failure: %s", ErrorStr(err)); } - if (mCommissioningDelegate) - { - mCommissioningDelegate->OnCommissioningComplete(nodeId, err); - this->UnregisterCommissioningDelegate(); - } - SetCommandExitStatus(err); } @@ -576,13 +550,6 @@ void PairingCommand::OnCurrentFabricRemove(void * context, NodeId nodeId, CHIP_E ChipLogProgress(NotSpecified, "Device unpair Failure: " ChipLogFormatX64 " %s", ChipLogValueX64(nodeId), ErrorStr(err)); } - PairingDelegate * pairingDelegate = command->GetPairingDelegate(); - if (pairingDelegate) - { - pairingDelegate->OnDeviceRemoved(nodeId, err); - command->UnregisterPairingDelegate(); - } - command->SetCommandExitStatus(err); } @@ -592,77 +559,13 @@ Optional PairingCommand::FailSafeExpiryTimeoutSecs() const return Optional(); } -bool PairingCommand::ShouldWaitAfterDeviceAttestation() -{ - // If there is a vendor ID and product ID, request OnDeviceAttestationCompleted(). - // Currently this is added in the case that the example is performing reverse commissioning, - // but it would be an improvement to store that explicitly. - // TODO: Issue #35297 - [Fabric Sync] Improve where we get VID and PID when validating CCTRL CommissionNode command - SetupPayload payload; - CHIP_ERROR err = GetPayload(mOnboardingPayload, payload); - return err == CHIP_NO_ERROR && (payload.vendorID != 0 || payload.productID != 0); -} - void PairingCommand::OnDeviceAttestationCompleted(Controller::DeviceCommissioner * deviceCommissioner, DeviceProxy * device, const Credentials::DeviceAttestationVerifier::AttestationDeviceInfo & info, Credentials::AttestationVerificationResult attestationResult) { - SetupPayload payload; - CHIP_ERROR parse_error = GetPayload(mOnboardingPayload, payload); - if (parse_error == CHIP_NO_ERROR && (payload.vendorID != 0 || payload.productID != 0)) - { - if (payload.vendorID == 0 || payload.productID == 0) - { - ChipLogProgress(NotSpecified, - "Failed validation: vendorID or productID must not be 0." - "Requested VID: %u, Requested PID: %u.", - payload.vendorID, payload.productID); - deviceCommissioner->ContinueCommissioningAfterDeviceAttestation( - device, Credentials::AttestationVerificationResult::kInvalidArgument); - return; - } - - if (payload.vendorID != info.BasicInformationVendorId() || payload.productID != info.BasicInformationProductId()) - { - ChipLogProgress(NotSpecified, - "Failed validation of vendorID or productID." - "Requested VID: %u, Requested PID: %u," - "Detected VID: %u, Detected PID %u.", - payload.vendorID, payload.productID, info.BasicInformationVendorId(), info.BasicInformationProductId()); - deviceCommissioner->ContinueCommissioningAfterDeviceAttestation( - device, - payload.vendorID == info.BasicInformationVendorId() - ? Credentials::AttestationVerificationResult::kDacProductIdMismatch - : Credentials::AttestationVerificationResult::kDacVendorIdMismatch); - return; - } - - // NOTE: This will log errors even if the attestion was successful. - auto err = deviceCommissioner->ContinueCommissioningAfterDeviceAttestation(device, attestationResult); - if (CHIP_NO_ERROR != err) - { - SetCommandExitStatus(err); - } - return; - } - - // OnDeviceAttestationCompleted() is called if ShouldWaitAfterDeviceAttestation() returns true - // or if there is an attestation error. The conditions for ShouldWaitAfterDeviceAttestation() have - // already been checked, so the call to OnDeviceAttestationCompleted() was an error. - if (mBypassAttestationVerifier.ValueOr(false)) - { - // Bypass attestation verification, continue with success - auto err = deviceCommissioner->ContinueCommissioningAfterDeviceAttestation( - device, Credentials::AttestationVerificationResult::kSuccess); - if (CHIP_NO_ERROR != err) - { - SetCommandExitStatus(err); - } - return; - } - - // Don't bypass attestation, continue with error. - auto err = deviceCommissioner->ContinueCommissioningAfterDeviceAttestation(device, attestationResult); + // Bypass attestation verification, continue with success + auto err = deviceCommissioner->ContinueCommissioningAfterDeviceAttestation( + device, Credentials::AttestationVerificationResult::kSuccess); if (CHIP_NO_ERROR != err) { SetCommandExitStatus(err); diff --git a/examples/fabric-admin/commands/pairing/PairingCommand.h b/examples/fabric-admin/commands/pairing/PairingCommand.h index 73e717b937..aafd8888dc 100644 --- a/examples/fabric-admin/commands/pairing/PairingCommand.h +++ b/examples/fabric-admin/commands/pairing/PairingCommand.h @@ -45,20 +45,6 @@ enum class PairingNetworkType Thread, }; -class CommissioningDelegate -{ -public: - virtual void OnCommissioningComplete(chip::NodeId deviceId, CHIP_ERROR err) = 0; - virtual ~CommissioningDelegate() = default; -}; - -class PairingDelegate -{ -public: - virtual void OnDeviceRemoved(chip::NodeId deviceId, CHIP_ERROR err) = 0; - virtual ~PairingDelegate() = default; -}; - class PairingCommand : public CHIPCommand, public chip::Controller::DevicePairingDelegate, public chip::Controller::DeviceDiscoveryDelegate, @@ -221,20 +207,10 @@ class PairingCommand : public CHIPCommand, /////////// DeviceAttestationDelegate Interface ///////// chip::Optional FailSafeExpiryTimeoutSecs() const override; - bool ShouldWaitAfterDeviceAttestation() override; void OnDeviceAttestationCompleted(chip::Controller::DeviceCommissioner * deviceCommissioner, chip::DeviceProxy * device, const chip::Credentials::DeviceAttestationVerifier::AttestationDeviceInfo & info, chip::Credentials::AttestationVerificationResult attestationResult) override; - /////////// CommissioningDelegate ///////// - void RegisterCommissioningDelegate(CommissioningDelegate * delegate) { mCommissioningDelegate = delegate; } - void UnregisterCommissioningDelegate() { mCommissioningDelegate = nullptr; } - - /////////// PairingDelegate ///////// - void RegisterPairingDelegate(PairingDelegate * delegate) { mPairingDelegate = delegate; } - void UnregisterPairingDelegate() { mPairingDelegate = nullptr; } - PairingDelegate * GetPairingDelegate() { return mPairingDelegate; } - private: CHIP_ERROR RunInternal(NodeId remoteId); CHIP_ERROR Pair(NodeId remoteId, PeerAddress address); @@ -290,9 +266,6 @@ class PairingCommand : public CHIPCommand, chip::Platform::UniquePtr mCurrentFabricRemover; chip::Callback::Callback mCurrentFabricRemoveCallback; - CommissioningDelegate * mCommissioningDelegate = nullptr; - PairingDelegate * mPairingDelegate = nullptr; - static void OnCurrentFabricRemove(void * context, NodeId remoteNodeId, CHIP_ERROR status); void PersistIcdInfo(); }; diff --git a/examples/fabric-admin/device_manager/DeviceManager.cpp b/examples/fabric-admin/device_manager/DeviceManager.cpp index f34a8443fe..4f7b1c7755 100644 --- a/examples/fabric-admin/device_manager/DeviceManager.cpp +++ b/examples/fabric-admin/device_manager/DeviceManager.cpp @@ -20,7 +20,6 @@ #include #include -#include #include #include @@ -153,52 +152,42 @@ void DeviceManager::OpenRemoteDeviceCommissioningWindow(EndpointId remoteEndpoin void DeviceManager::PairRemoteFabricBridge(NodeId nodeId, uint32_t setupPINCode, const char * deviceRemoteIp, uint16_t deviceRemotePort) { - StringBuilder commandBuilder; - - commandBuilder.Add("pairing already-discovered "); - commandBuilder.AddFormat("%lu %d %s %d", nodeId, setupPINCode, deviceRemoteIp, deviceRemotePort); - - PushCommand(commandBuilder.c_str()); + if (PairingManager::Instance().PairDevice(nodeId, setupPINCode, deviceRemoteIp, deviceRemotePort) != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to pair remote fabric bridge " ChipLogFormatX64, ChipLogValueX64(nodeId)); + } } void DeviceManager::PairRemoteDevice(NodeId nodeId, const char * payload) { - StringBuilder commandBuilder; - - commandBuilder.Add("pairing code "); - commandBuilder.AddFormat("%lu %s", nodeId, payload); - - PushCommand(commandBuilder.c_str()); + if (PairingManager::Instance().PairDeviceWithCode(nodeId, payload) != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to pair remote device " ChipLogFormatX64, ChipLogValueX64(nodeId)); + } } void DeviceManager::PairLocalFabricBridge(NodeId nodeId) { - StringBuilder commandBuilder; - - commandBuilder.Add("pairing already-discovered "); - commandBuilder.AddFormat("%lu %d ::1 %d", nodeId, mLocalBridgeSetupPinCode, mLocalBridgePort); - - PushCommand(commandBuilder.c_str()); + if (PairingManager::Instance().PairDevice(nodeId, mLocalBridgeSetupPinCode, "::1", mLocalBridgePort) != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to pair local fabric bridge " ChipLogFormatX64, ChipLogValueX64(nodeId)); + } } void DeviceManager::UnpairRemoteFabricBridge() { - StringBuilder commandBuilder; - - commandBuilder.Add("pairing unpair "); - commandBuilder.AddFormat("%lu", mRemoteBridgeNodeId); - - PushCommand(commandBuilder.c_str()); + if (PairingManager::Instance().UnpairDevice(mRemoteBridgeNodeId) != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to unpair remote bridge device " ChipLogFormatX64, ChipLogValueX64(mRemoteBridgeNodeId)); + } } void DeviceManager::UnpairLocalFabricBridge() { - StringBuilder commandBuilder; - - commandBuilder.Add("pairing unpair "); - commandBuilder.AddFormat("%lu", mLocalBridgeNodeId); - - PushCommand(commandBuilder.c_str()); + if (PairingManager::Instance().UnpairDevice(mLocalBridgeNodeId) != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to unpair local bridge device " ChipLogFormatX64, ChipLogValueX64(mLocalBridgeNodeId)); + } } void DeviceManager::SubscribeRemoteFabricBridge() @@ -390,20 +379,15 @@ void DeviceManager::HandleAttributePartsListUpdate(TLV::TLVReader & data) if (mAutoSyncEnabled) { - StringBuilder commandBuilder; - commandBuilder.Add("pairing unpair "); - commandBuilder.AddFormat("%lu", device->GetNodeId()); - - PairingCommand * pairingCommand = static_cast(CommandMgr().GetCommandByName("pairing", "unpair")); - - if (pairingCommand == nullptr) + NodeId nodeId = device->GetNodeId(); + if (PairingManager::Instance().UnpairDevice(nodeId) != CHIP_NO_ERROR) { - ChipLogError(NotSpecified, "Pairing code command is not available"); - return; + ChipLogError(NotSpecified, "Failed to unpair device " ChipLogFormatX64, ChipLogValueX64(nodeId)); + } + else + { + PairingManager::Instance().SetPairingDelegate(this); } - - pairingCommand->RegisterPairingDelegate(this); - PushCommand(commandBuilder.c_str()); } } } diff --git a/examples/fabric-admin/device_manager/DeviceManager.h b/examples/fabric-admin/device_manager/DeviceManager.h index 939329be82..5e43e78e3a 100644 --- a/examples/fabric-admin/device_manager/DeviceManager.h +++ b/examples/fabric-admin/device_manager/DeviceManager.h @@ -19,7 +19,7 @@ #pragma once #include -#include +#include #include #include diff --git a/examples/fabric-admin/device_manager/PairingManager.cpp b/examples/fabric-admin/device_manager/PairingManager.cpp index aa56af4bc6..c46a0ca000 100644 --- a/examples/fabric-admin/device_manager/PairingManager.cpp +++ b/examples/fabric-admin/device_manager/PairingManager.cpp @@ -18,21 +18,100 @@ #include "PairingManager.h" -#include -#include -#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#if defined(PW_RPC_ENABLED) +#include +#endif using namespace ::chip; +using namespace ::chip::Controller; + +namespace { + +CHIP_ERROR GetPayload(const char * setUpCode, SetupPayload & payload) +{ + VerifyOrReturnValue(setUpCode, CHIP_ERROR_INVALID_ARGUMENT); + bool isQRCode = strncmp(setUpCode, kQRCodePrefix, strlen(kQRCodePrefix)) == 0; + if (isQRCode) + { + ReturnErrorOnFailure(QRCodeSetupPayloadParser(setUpCode).populatePayload(payload)); + VerifyOrReturnError(payload.isValidQRCodePayload(), CHIP_ERROR_INVALID_ARGUMENT); + } + else + { + ReturnErrorOnFailure(ManualSetupPayloadParser(setUpCode).populatePayload(payload)); + VerifyOrReturnError(payload.isValidManualCode(), CHIP_ERROR_INVALID_ARGUMENT); + } + + return CHIP_NO_ERROR; +} + +bool ParseAddressWithInterface(const char * addressString, Inet::IPAddress & address, Inet::InterfaceId & interfaceId) +{ + struct addrinfo hints; + struct addrinfo * result; + int ret; + + memset(&hints, 0, sizeof(hints)); + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + ret = getaddrinfo(addressString, nullptr, &hints, &result); + if (ret < 0) + { + ChipLogError(NotSpecified, "Invalid address: %s", addressString); + return false; + } + + if (result->ai_family == AF_INET6) + { + struct sockaddr_in6 * addr = reinterpret_cast(result->ai_addr); + address = Inet::IPAddress::FromSockAddr(*addr); + interfaceId = Inet::InterfaceId(addr->sin6_scope_id); + } +#if INET_CONFIG_ENABLE_IPV4 + else if (result->ai_family == AF_INET) + { + address = Inet::IPAddress::FromSockAddr(*reinterpret_cast(result->ai_addr)); + interfaceId = Inet::InterfaceId::Null(); + } +#endif // INET_CONFIG_ENABLE_IPV4 + else + { + ChipLogError(NotSpecified, "Unsupported address: %s", addressString); + freeaddrinfo(result); + return false; + } + + freeaddrinfo(result); + return true; +} + +} // namespace PairingManager::PairingManager() : mOnOpenCommissioningWindowCallback(OnOpenCommissioningWindowResponse, this), - mOnOpenCommissioningWindowVerifierCallback(OnOpenCommissioningWindowVerifierResponse, this) + mOnOpenCommissioningWindowVerifierCallback(OnOpenCommissioningWindowVerifierResponse, this), + mCurrentFabricRemoveCallback(OnCurrentFabricRemove, this) {} -void PairingManager::Init(Controller::DeviceCommissioner * commissioner) +CHIP_ERROR PairingManager::Init(Controller::DeviceCommissioner * commissioner, CredentialIssuerCommands * credIssuerCmds) { - VerifyOrDie(mCommissioner == nullptr); - mCommissioner = commissioner; + VerifyOrReturnError(commissioner != nullptr, CHIP_ERROR_INCORRECT_STATE); + VerifyOrReturnError(credIssuerCmds != nullptr, CHIP_ERROR_INCORRECT_STATE); + + mCommissioner = commissioner; + mCredIssuerCmds = credIssuerCmds; + + return CHIP_NO_ERROR; } CHIP_ERROR PairingManager::OpenCommissioningWindow(NodeId nodeId, EndpointId endpointId, uint16_t commissioningTimeoutSec, @@ -168,3 +247,444 @@ void PairingManager::OnOpenCommissioningWindowVerifierResponse(void * context, N // Reset the window opener once the window operation is complete self->mWindowOpener.reset(); } + +void PairingManager::OnStatusUpdate(DevicePairingDelegate::Status status) +{ + switch (status) + { + case DevicePairingDelegate::Status::SecurePairingSuccess: + ChipLogProgress(NotSpecified, "CASE establishment successful"); + break; + case DevicePairingDelegate::Status::SecurePairingFailed: + ChipLogError(NotSpecified, "Secure Pairing Failed"); + break; + } +} + +void PairingManager::OnPairingComplete(CHIP_ERROR err) +{ + if (err == CHIP_NO_ERROR) + { + ChipLogProgress(NotSpecified, "PASE establishment successful"); + } + else + { + ChipLogProgress(NotSpecified, "Pairing Failure: %s", ErrorStr(err)); + } +} + +void PairingManager::OnPairingDeleted(CHIP_ERROR err) +{ + if (err == CHIP_NO_ERROR) + { + ChipLogProgress(NotSpecified, "Pairing Deleted Success"); + } + else + { + ChipLogProgress(NotSpecified, "Pairing Deleted Failure: %s", ErrorStr(err)); + } +} + +void PairingManager::OnCommissioningComplete(NodeId nodeId, CHIP_ERROR err) +{ + if (err == CHIP_NO_ERROR) + { + // print to console + fprintf(stderr, "New device with Node ID: " ChipLogFormatX64 "has been successfully added.\n", ChipLogValueX64(nodeId)); + + // mCommissioner has a lifetime that is the entire life of the application itself + // so it is safe to provide to StartDeviceSynchronization. + DeviceSynchronizer::Instance().StartDeviceSynchronization(mCommissioner, nodeId, mDeviceIsICD); + } + else + { + // When ICD device commissioning fails, the ICDClientInfo stored in OnICDRegistrationComplete needs to be removed. + if (mDeviceIsICD) + { + CHIP_ERROR deleteEntryError = + CHIPCommand::sICDClientStorage.DeleteEntry(ScopedNodeId(nodeId, mCommissioner->GetFabricIndex())); + if (deleteEntryError != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to delete ICD entry: %s", ErrorStr(err)); + } + } + ChipLogProgress(NotSpecified, "Device commissioning Failure: %s", ErrorStr(err)); + } + + if (mCommissioningDelegate) + { + mCommissioningDelegate->OnCommissioningComplete(nodeId, err); + SetCommissioningDelegate(nullptr); + } +} + +void PairingManager::OnReadCommissioningInfo(const Controller::ReadCommissioningInfo & info) +{ + ChipLogProgress(AppServer, "OnReadCommissioningInfo - vendorId=0x%04X productId=0x%04X", info.basic.vendorId, + info.basic.productId); + + // The string in CharSpan received from the device is not null-terminated, we use std::string here for coping and + // appending a null-terminator at the end of the string. + std::string userActiveModeTriggerInstruction; + + // Note: the callback doesn't own the buffer, should make a copy if it will be used it later. + if (info.icd.userActiveModeTriggerInstruction.size() != 0) + { + userActiveModeTriggerInstruction = + std::string(info.icd.userActiveModeTriggerInstruction.data(), info.icd.userActiveModeTriggerInstruction.size()); + } + + if (info.icd.userActiveModeTriggerHint.HasAny()) + { + ChipLogProgress(AppServer, "OnReadCommissioningInfo - LIT UserActiveModeTriggerHint=0x%08x", + info.icd.userActiveModeTriggerHint.Raw()); + ChipLogProgress(AppServer, "OnReadCommissioningInfo - LIT UserActiveModeTriggerInstruction=%s", + userActiveModeTriggerInstruction.c_str()); + } + ChipLogProgress(AppServer, "OnReadCommissioningInfo ICD - IdleModeDuration=%u activeModeDuration=%u activeModeThreshold=%u", + info.icd.idleModeDuration, info.icd.activeModeDuration, info.icd.activeModeThreshold); +} + +void PairingManager::OnICDRegistrationComplete(ScopedNodeId nodeId, uint32_t icdCounter) +{ + char icdSymmetricKeyHex[Crypto::kAES_CCM128_Key_Length * 2 + 1]; + + Encoding::BytesToHex(mICDSymmetricKey.Value().data(), mICDSymmetricKey.Value().size(), icdSymmetricKeyHex, + sizeof(icdSymmetricKeyHex), Encoding::HexFlags::kNullTerminate); + + app::ICDClientInfo clientInfo; + clientInfo.peer_node = nodeId; + clientInfo.monitored_subject = mICDMonitoredSubject.Value(); + clientInfo.start_icd_counter = icdCounter; + + CHIP_ERROR err = CHIPCommand::sICDClientStorage.SetKey(clientInfo, mICDSymmetricKey.Value()); + if (err == CHIP_NO_ERROR) + { + err = CHIPCommand::sICDClientStorage.StoreEntry(clientInfo); + } + + if (err != CHIP_NO_ERROR) + { + CHIPCommand::sICDClientStorage.RemoveKey(clientInfo); + ChipLogError(NotSpecified, "Failed to persist symmetric key for " ChipLogFormatX64 ": %s", + ChipLogValueX64(nodeId.GetNodeId()), err.AsString()); + return; + } + + mDeviceIsICD = true; + + ChipLogProgress(NotSpecified, "Saved ICD Symmetric key for " ChipLogFormatX64, ChipLogValueX64(nodeId.GetNodeId())); + ChipLogProgress(NotSpecified, + "ICD Registration Complete for device " ChipLogFormatX64 " / Check-In NodeID: " ChipLogFormatX64 + " / Monitored Subject: " ChipLogFormatX64 " / Symmetric Key: %s / ICDCounter %u", + ChipLogValueX64(nodeId.GetNodeId()), ChipLogValueX64(mICDCheckInNodeId.Value()), + ChipLogValueX64(mICDMonitoredSubject.Value()), icdSymmetricKeyHex, icdCounter); +} + +void PairingManager::OnICDStayActiveComplete(ScopedNodeId deviceId, uint32_t promisedActiveDuration) +{ + ChipLogProgress(NotSpecified, "ICD Stay Active Complete for device " ChipLogFormatX64 " / promisedActiveDuration: %u", + ChipLogValueX64(deviceId.GetNodeId()), promisedActiveDuration); +} + +void PairingManager::OnDiscoveredDevice(const Dnssd::CommissionNodeData & nodeData) +{ + // Ignore nodes with closed commissioning window + VerifyOrReturn(nodeData.commissioningMode != 0); + + auto & resolutionData = nodeData; + + const uint16_t port = resolutionData.port; + char buf[Inet::IPAddress::kMaxStringLength]; + resolutionData.ipAddress[0].ToString(buf); + ChipLogProgress(NotSpecified, "Discovered Device: %s:%u", buf, port); + + // Stop Mdns discovery. + auto err = mCommissioner->StopCommissionableDiscovery(); + + // Some platforms does not implement a mechanism to stop mdns browse, so + // we just ignore CHIP_ERROR_NOT_IMPLEMENTED instead of bailing out. + if (CHIP_NO_ERROR != err && CHIP_ERROR_NOT_IMPLEMENTED != err) + { + return; + } + + mCommissioner->RegisterDeviceDiscoveryDelegate(nullptr); + + auto interfaceId = resolutionData.ipAddress[0].IsIPv6LinkLocal() ? resolutionData.interfaceId : Inet::InterfaceId::Null(); + auto peerAddress = Transport::PeerAddress::UDP(resolutionData.ipAddress[0], port, interfaceId); + err = Pair(mNodeId, peerAddress); + if (CHIP_NO_ERROR != err) + { + ChipLogProgress(NotSpecified, "Failed to pair device: " ChipLogFormatX64 " %s", ChipLogValueX64(mNodeId), ErrorStr(err)); + } +} + +Optional PairingManager::FailSafeExpiryTimeoutSecs() const +{ + // No manual input, so do not need to extend. + return Optional(); +} + +bool PairingManager::ShouldWaitAfterDeviceAttestation() +{ + // If there is a vendor ID and product ID, request OnDeviceAttestationCompleted(). + // Currently this is added in the case that the example is performing reverse commissioning, + // but it would be an improvement to store that explicitly. + // TODO: Issue #35297 - [Fabric Sync] Improve where we get VID and PID when validating CCTRL CommissionNode command + SetupPayload payload; + CHIP_ERROR err = GetPayload(mOnboardingPayload, payload); + return err == CHIP_NO_ERROR && (payload.vendorID != 0 || payload.productID != 0); +} + +void PairingManager::OnDeviceAttestationCompleted(Controller::DeviceCommissioner * deviceCommissioner, DeviceProxy * device, + const Credentials::DeviceAttestationVerifier::AttestationDeviceInfo & info, + Credentials::AttestationVerificationResult attestationResult) +{ + SetupPayload payload; + CHIP_ERROR parse_error = GetPayload(mOnboardingPayload, payload); + if (parse_error == CHIP_NO_ERROR && (payload.vendorID != 0 || payload.productID != 0)) + { + if (payload.vendorID == 0 || payload.productID == 0) + { + ChipLogProgress(NotSpecified, + "Failed validation: vendorID or productID must not be 0." + "Requested VID: %u, Requested PID: %u.", + payload.vendorID, payload.productID); + deviceCommissioner->ContinueCommissioningAfterDeviceAttestation( + device, Credentials::AttestationVerificationResult::kInvalidArgument); + return; + } + + if (payload.vendorID != info.BasicInformationVendorId() || payload.productID != info.BasicInformationProductId()) + { + ChipLogProgress(NotSpecified, + "Failed validation of vendorID or productID." + "Requested VID: %u, Requested PID: %u," + "Detected VID: %u, Detected PID %u.", + payload.vendorID, payload.productID, info.BasicInformationVendorId(), info.BasicInformationProductId()); + deviceCommissioner->ContinueCommissioningAfterDeviceAttestation( + device, + payload.vendorID == info.BasicInformationVendorId() + ? Credentials::AttestationVerificationResult::kDacProductIdMismatch + : Credentials::AttestationVerificationResult::kDacVendorIdMismatch); + return; + } + + // NOTE: This will log errors even if the attestion was successful. + CHIP_ERROR err = deviceCommissioner->ContinueCommissioningAfterDeviceAttestation(device, attestationResult); + if (CHIP_NO_ERROR != err) + { + ChipLogError(NotSpecified, "Failed to continue commissioning after device attestation, error: %s", ErrorStr(err)); + } + return; + } + + // Don't bypass attestation, continue with error. + CHIP_ERROR err = deviceCommissioner->ContinueCommissioningAfterDeviceAttestation(device, attestationResult); + if (CHIP_NO_ERROR != err) + { + ChipLogError(NotSpecified, "Failed to continue commissioning after device attestation, error: %s", ErrorStr(err)); + } +} + +CommissioningParameters PairingManager::GetCommissioningParameters() +{ + auto params = CommissioningParameters(); + params.SetSkipCommissioningComplete(false); + params.SetDeviceAttestationDelegate(this); + + if (mICDRegistration.ValueOr(false)) + { + params.SetICDRegistrationStrategy(ICDRegistrationStrategy::kBeforeComplete); + + if (!mICDSymmetricKey.HasValue()) + { + Crypto::DRBG_get_bytes(mRandomGeneratedICDSymmetricKey, sizeof(mRandomGeneratedICDSymmetricKey)); + mICDSymmetricKey.SetValue(ByteSpan(mRandomGeneratedICDSymmetricKey)); + } + if (!mICDCheckInNodeId.HasValue()) + { + mICDCheckInNodeId.SetValue(mCommissioner->GetNodeId()); + } + if (!mICDMonitoredSubject.HasValue()) + { + mICDMonitoredSubject.SetValue(mICDCheckInNodeId.Value()); + } + if (!mICDClientType.HasValue()) + { + mICDClientType.SetValue(app::Clusters::IcdManagement::ClientTypeEnum::kPermanent); + } + // These Optionals must have values now. + // The commissioner will verify these values. + params.SetICDSymmetricKey(mICDSymmetricKey.Value()); + if (mICDStayActiveDurationMsec.HasValue()) + { + params.SetICDStayActiveDurationMsec(mICDStayActiveDurationMsec.Value()); + } + params.SetICDCheckInNodeId(mICDCheckInNodeId.Value()); + params.SetICDMonitoredSubject(mICDMonitoredSubject.Value()); + params.SetICDClientType(mICDClientType.Value()); + } + + return params; +} + +CHIP_ERROR PairingManager::Pair(NodeId remoteId, Transport::PeerAddress address) +{ + auto params = RendezvousParameters().SetSetupPINCode(mSetupPINCode).SetDiscriminator(mDiscriminator).SetPeerAddress(address); + + CHIP_ERROR err = CHIP_NO_ERROR; + auto commissioningParams = GetCommissioningParameters(); + err = CurrentCommissioner().PairDevice(remoteId, params, commissioningParams); + + return err; +} + +void PairingManager::OnCurrentFabricRemove(void * context, NodeId nodeId, CHIP_ERROR err) +{ + PairingManager * self = reinterpret_cast(context); + VerifyOrReturn(self != nullptr, ChipLogError(NotSpecified, "OnCurrentFabricRemove: context is null")); + + if (err == CHIP_NO_ERROR) + { + // print to console + fprintf(stderr, "Device with Node ID: " ChipLogFormatX64 "has been successfully removed.\n", ChipLogValueX64(nodeId)); + +#if defined(PW_RPC_ENABLED) + FabricIndex fabricIndex = self->CurrentCommissioner().GetFabricIndex(); + app::InteractionModelEngine::GetInstance()->ShutdownSubscriptions(fabricIndex, nodeId); + ScopedNodeId scopedNodeId(nodeId, fabricIndex); + RemoveSynchronizedDevice(scopedNodeId); +#endif + } + else + { + ChipLogProgress(NotSpecified, "Device unpair Failure: " ChipLogFormatX64 " %s", ChipLogValueX64(nodeId), ErrorStr(err)); + } +} + +void PairingManager::InitPairingCommand() +{ + mCommissioner->RegisterPairingDelegate(this); + // Clear the CATs in OperationalCredentialsIssuer + mCredIssuerCmds->SetCredentialIssuerCATValues(kUndefinedCATs); + mDeviceIsICD = false; +} + +CHIP_ERROR PairingManager::PairDeviceWithCode(NodeId nodeId, const char * payload) +{ + if (payload == nullptr || strlen(payload) > kMaxManualCodeLength + 1) + { + ChipLogError(NotSpecified, "PairDeviceWithCode failed: Invalid pairing payload"); + return CHIP_ERROR_INVALID_STRING_LENGTH; + } + + auto params = Platform::MakeUnique(); + VerifyOrReturnError(params != nullptr, CHIP_ERROR_NO_MEMORY); + + params->nodeId = nodeId; + Platform::CopyString(params->payloadBuffer, sizeof(params->payloadBuffer), payload); + + // Schedule work on the Matter thread + return DeviceLayer::PlatformMgr().ScheduleWork(OnPairDeviceWithCode, reinterpret_cast(params.release())); +} + +void PairingManager::OnPairDeviceWithCode(intptr_t context) +{ + Platform::UniquePtr params(reinterpret_cast(context)); + PairingManager & self = PairingManager::Instance(); + + self.InitPairingCommand(); + + CommissioningParameters commissioningParams = self.GetCommissioningParameters(); + auto discoveryType = DiscoveryType::kDiscoveryNetworkOnly; + + self.mNodeId = params->nodeId; + self.mOnboardingPayload = params->payloadBuffer; + + CHIP_ERROR err = self.mCommissioner->PairDevice(params->nodeId, params->payloadBuffer, commissioningParams, discoveryType); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to pair device with code, error: %s", ErrorStr(err)); + } +} + +CHIP_ERROR PairingManager::PairDevice(chip::NodeId nodeId, uint32_t setupPINCode, const char * deviceRemoteIp, + uint16_t deviceRemotePort) +{ + if (deviceRemoteIp == nullptr || strlen(deviceRemoteIp) > Inet::IPAddress::kMaxStringLength) + { + ChipLogError(NotSpecified, "PairDevice failed: Invalid device remote IP address"); + return CHIP_ERROR_INVALID_STRING_LENGTH; + } + + auto params = Platform::MakeUnique(); + VerifyOrReturnError(params != nullptr, CHIP_ERROR_NO_MEMORY); + + params->nodeId = nodeId; + params->setupPINCode = setupPINCode; + params->deviceRemotePort = deviceRemotePort; + + Platform::CopyString(params->ipAddrBuffer, sizeof(params->ipAddrBuffer), deviceRemoteIp); + + // Schedule work on the Matter thread + return DeviceLayer::PlatformMgr().ScheduleWork(OnPairDevice, reinterpret_cast(params.release())); +} + +void PairingManager::OnPairDevice(intptr_t context) +{ + Platform::UniquePtr params(reinterpret_cast(context)); + PairingManager & self = PairingManager::Instance(); + + self.InitPairingCommand(); + self.mSetupPINCode = params->setupPINCode; + + Inet::IPAddress address; + Inet::InterfaceId interfaceId; + + if (!ParseAddressWithInterface(params->ipAddrBuffer, address, interfaceId)) + { + ChipLogError(NotSpecified, "Invalid IP address: %s", params->ipAddrBuffer); + return; + } + + CHIP_ERROR err = self.Pair(params->nodeId, Transport::PeerAddress::UDP(address, params->deviceRemotePort, interfaceId)); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to pair device, error: %s", ErrorStr(err)); + } +} + +CHIP_ERROR PairingManager::UnpairDevice(NodeId nodeId) +{ + auto params = Platform::MakeUnique(); + VerifyOrReturnError(params != nullptr, CHIP_ERROR_NO_MEMORY); + + params->nodeId = nodeId; + + // Schedule work on the Matter thread + return DeviceLayer::PlatformMgr().ScheduleWork(OnUnpairDevice, reinterpret_cast(params.release())); +} + +void PairingManager::OnUnpairDevice(intptr_t context) +{ + Platform::UniquePtr params(reinterpret_cast(context)); + PairingManager & self = PairingManager::Instance(); + + self.InitPairingCommand(); + + self.mCurrentFabricRemover = Platform::MakeUnique(self.mCommissioner); + + if (!self.mCurrentFabricRemover) + { + ChipLogError(NotSpecified, "Failed to unpair device, mCurrentFabricRemover is null"); + return; + } + + CHIP_ERROR err = self.mCurrentFabricRemover->RemoveCurrentFabric(params->nodeId, &self.mCurrentFabricRemoveCallback); + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to unpair device, error: %s", ErrorStr(err)); + } +} diff --git a/examples/fabric-admin/device_manager/PairingManager.h b/examples/fabric-admin/device_manager/PairingManager.h index de1c0887f3..563d129079 100644 --- a/examples/fabric-admin/device_manager/PairingManager.h +++ b/examples/fabric-admin/device_manager/PairingManager.h @@ -18,10 +18,16 @@ #pragma once +#include #include +#include #include +#include #include +// Constants +constexpr uint16_t kMaxManualCodeLength = 22; + class CommissioningWindowDelegate { public: @@ -29,6 +35,20 @@ class CommissioningWindowDelegate virtual ~CommissioningWindowDelegate() = default; }; +class CommissioningDelegate +{ +public: + virtual void OnCommissioningComplete(chip::NodeId deviceId, CHIP_ERROR err) = 0; + virtual ~CommissioningDelegate() = default; +}; + +class PairingDelegate +{ +public: + virtual void OnDeviceRemoved(chip::NodeId deviceId, CHIP_ERROR err) = 0; + virtual ~PairingDelegate() = default; +}; + /** * The PairingManager class is responsible for managing the commissioning and pairing process * of Matter devices. PairingManager is designed to be used as a singleton, meaning that there @@ -49,7 +69,9 @@ class CommissioningWindowDelegate * manager.OpenCommissioningWindow(); * @endcode */ -class PairingManager +class PairingManager : public chip::Controller::DevicePairingDelegate, + public chip::Controller::DeviceDiscoveryDelegate, + public chip::Credentials::DeviceAttestationDelegate { public: static PairingManager & Instance() @@ -58,7 +80,14 @@ class PairingManager return instance; } - void Init(chip::Controller::DeviceCommissioner * commissioner); + CHIP_ERROR Init(chip::Controller::DeviceCommissioner * commissioner, CredentialIssuerCommands * credIssuerCmds); + + void SetOpenCommissioningWindowDelegate(CommissioningWindowDelegate * delegate) { mCommissioningWindowDelegate = delegate; } + void SetCommissioningDelegate(CommissioningDelegate * delegate) { mCommissioningDelegate = delegate; } + void SetPairingDelegate(PairingDelegate * delegate) { mPairingDelegate = delegate; } + PairingDelegate * GetPairingDelegate() { return mPairingDelegate; } + + chip::Controller::DeviceCommissioner & CurrentCommissioner() { return *mCommissioner; }; /** * Opens a commissioning window on the specified node and endpoint. @@ -79,16 +108,38 @@ class PairingManager uint32_t iterations, uint16_t discriminator, const chip::ByteSpan & salt, const chip::ByteSpan & verifier); - void SetOpenCommissioningWindowDelegate(CommissioningWindowDelegate * delegate) { mCommissioningWindowDelegate = delegate; } + /** + * Pairs a device using a setup code payload. + * + * @param nodeId The target node ID for pairing. + * @param payload The setup code payload, which typically contains device-specific pairing information. + * + * @return CHIP_NO_ERROR on successful initiation of the pairing process, or an appropriate CHIP_ERROR if pairing fails. + */ + CHIP_ERROR PairDeviceWithCode(chip::NodeId nodeId, const char * payload); -private: - PairingManager(); - PairingManager(const PairingManager &) = delete; - PairingManager & operator=(const PairingManager &) = delete; + /** + * Pairs a device using its setup PIN code and remote IP address. + * + * @param nodeId The target node ID for pairing. + * @param setupPINCode The setup PIN code for the device, used for establishing a secure connection. + * @param deviceRemoteIp The IP address of the remote device. + * @param deviceRemotePort The port number on which the device is listening for pairing requests. + * + * @return CHIP_NO_ERROR if the pairing process is initiated successfully, or an appropriate CHIP_ERROR if pairing fails. + */ + CHIP_ERROR PairDevice(chip::NodeId nodeId, uint32_t setupPINCode, const char * deviceRemoteIp, uint16_t deviceRemotePort); - chip::Controller::DeviceCommissioner * mCommissioner = nullptr; + /** + * Unpairs a device with the specified node ID. + * + * @param nodeId The node ID of the device to be unpaired. + * + * @return CHIP_NO_ERROR if the device is successfully unpaired, or an appropriate CHIP_ERROR if the process fails. + */ + CHIP_ERROR UnpairDevice(chip::NodeId nodeId); - /////////// Open Commissioning Window Command Interface ///////// +private: struct CommissioningWindowParams { chip::NodeId nodeId; @@ -103,7 +154,84 @@ class PairingManager chip::ByteSpan salt; }; + struct PairDeviceWithCodeParams + { + chip::NodeId nodeId; + char payloadBuffer[kMaxManualCodeLength + 1]; + }; + + struct PairDeviceParams + { + chip::NodeId nodeId; + uint32_t setupPINCode; + uint16_t deviceRemotePort; + char ipAddrBuffer[chip::Inet::IPAddress::kMaxStringLength]; + }; + + struct UnpairDeviceParams + { + chip::NodeId nodeId; + }; + + // Constructors + PairingManager(); + PairingManager(const PairingManager &) = delete; + PairingManager & operator=(const PairingManager &) = delete; + + // Private member functions (static and non-static) + chip::Controller::CommissioningParameters GetCommissioningParameters(); + void InitPairingCommand(); + CHIP_ERROR Pair(chip::NodeId remoteId, chip::Transport::PeerAddress address); + + /////////// DevicePairingDelegate Interface ///////// + void OnStatusUpdate(chip::Controller::DevicePairingDelegate::Status status) override; + void OnPairingComplete(CHIP_ERROR error) override; + void OnPairingDeleted(CHIP_ERROR error) override; + void OnReadCommissioningInfo(const chip::Controller::ReadCommissioningInfo & info) override; + void OnCommissioningComplete(chip::NodeId deviceId, CHIP_ERROR error) override; + void OnICDRegistrationComplete(chip::ScopedNodeId deviceId, uint32_t icdCounter) override; + void OnICDStayActiveComplete(chip::ScopedNodeId deviceId, uint32_t promisedActiveDuration) override; + + /////////// DeviceDiscoveryDelegate Interface ///////// + void OnDiscoveredDevice(const chip::Dnssd::CommissionNodeData & nodeData) override; + + /////////// DeviceAttestationDelegate Interface ///////// + chip::Optional FailSafeExpiryTimeoutSecs() const override; + bool ShouldWaitAfterDeviceAttestation() override; + void OnDeviceAttestationCompleted(chip::Controller::DeviceCommissioner * deviceCommissioner, chip::DeviceProxy * device, + const chip::Credentials::DeviceAttestationVerifier::AttestationDeviceInfo & info, + chip::Credentials::AttestationVerificationResult attestationResult) override; + + static void OnOpenCommissioningWindow(intptr_t context); + static void OnOpenCommissioningWindowResponse(void * context, chip::NodeId deviceId, CHIP_ERROR status, + chip::SetupPayload payload); + static void OnOpenCommissioningWindowVerifierResponse(void * context, chip::NodeId deviceId, CHIP_ERROR status); + static void OnCurrentFabricRemove(void * context, chip::NodeId remoteNodeId, CHIP_ERROR status); + static void OnPairDeviceWithCode(intptr_t context); + static void OnPairDevice(intptr_t context); + static void OnUnpairDevice(intptr_t context); + + // Private data members + chip::Controller::DeviceCommissioner * mCommissioner = nullptr; + CredentialIssuerCommands * mCredIssuerCmds = nullptr; + CommissioningWindowDelegate * mCommissioningWindowDelegate = nullptr; + CommissioningDelegate * mCommissioningDelegate = nullptr; + PairingDelegate * mPairingDelegate = nullptr; + + chip::NodeId mNodeId = chip::kUndefinedNodeId; + uint16_t mDiscriminator = 0; + uint32_t mSetupPINCode = 0; + const char * mOnboardingPayload = nullptr; + bool mDeviceIsICD = false; + uint8_t mRandomGeneratedICDSymmetricKey[chip::Crypto::kAES_CCM128_Key_Length]; + + chip::Optional mICDRegistration; + chip::Optional mICDCheckInNodeId; + chip::Optional mICDClientType; + chip::Optional mICDSymmetricKey; + chip::Optional mICDMonitoredSubject; + chip::Optional mICDStayActiveDurationMsec; /** * Holds the unique_ptr to the current CommissioningWindowOpener. @@ -111,12 +239,10 @@ class PairingManager * The pointer is reset when the commissioning window is closed or when an error occurs. */ chip::Platform::UniquePtr mWindowOpener; - - static void OnOpenCommissioningWindow(intptr_t context); - static void OnOpenCommissioningWindowResponse(void * context, chip::NodeId deviceId, CHIP_ERROR status, - chip::SetupPayload payload); - static void OnOpenCommissioningWindowVerifierResponse(void * context, chip::NodeId deviceId, CHIP_ERROR status); - chip::Callback::Callback mOnOpenCommissioningWindowCallback; chip::Callback::Callback mOnOpenCommissioningWindowVerifierCallback; + + // For Unpair + chip::Platform::UniquePtr mCurrentFabricRemover; + chip::Callback::Callback mCurrentFabricRemoveCallback; }; From a3b5eaa49edd72c189d2818df3e9fbb1fd3bddf3 Mon Sep 17 00:00:00 2001 From: Justin Wood Date: Thu, 3 Oct 2024 18:38:21 -0700 Subject: [PATCH 07/22] Removing dead XPC methods (#35904) * Removing dead XPC methods * Restyled by clang-format --------- Co-authored-by: Restyled.io --- src/darwin/Framework/CHIP/MTRDeviceController.mm | 2 +- src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm | 3 --- src/darwin/Framework/CHIP/XPC Protocol/MTRXPCServerProtocol.h | 1 - 3 files changed, 1 insertion(+), 5 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRDeviceController.mm b/src/darwin/Framework/CHIP/MTRDeviceController.mm index 690f0e4ba8..a1872c3020 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController.mm @@ -315,7 +315,7 @@ - (void)_controllerResumed - (void)shutdown { - MTR_ABSTRACT_METHOD(); + // Subclass hook; nothing to do. } - (NSNumber *)controllerNodeID diff --git a/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm b/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm index 2945334b3b..6d45de6d01 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm @@ -342,9 +342,6 @@ - (MTRDevice *)_setupDeviceForNodeID:(NSNumber *)nodeID prefetchedClusterData:(N //- (oneway void)deviceController:(NSUUID *)controller openPairingWindow:(uint64_t)deviceID duration:(NSUInteger)duration withReply:(void(^)(NSError * _Nullable error))reply; //- (oneway void)deviceController:(NSUUID *)controller openPairingWindowWithPIN:(uint64_t)deviceID duration:(NSUInteger)duration discriminator:(NSUInteger)discriminator setupPIN:(NSUInteger)setupPIN withReply:(void(^)(NSError * _Nullable error))reply; -MTR_DEVICECONTROLLER_SIMPLE_REMOTE_XPC_COMMAND(shutdown, shutdownDeviceController - : self.uniqueIdentifier) - #pragma mark - MTRDeviceProtocol Client // All pass through, we could do some fancy redirection here based on protocol, but that's that for another day diff --git a/src/darwin/Framework/CHIP/XPC Protocol/MTRXPCServerProtocol.h b/src/darwin/Framework/CHIP/XPC Protocol/MTRXPCServerProtocol.h index bd7d0e6df0..b404056c96 100644 --- a/src/darwin/Framework/CHIP/XPC Protocol/MTRXPCServerProtocol.h +++ b/src/darwin/Framework/CHIP/XPC Protocol/MTRXPCServerProtocol.h @@ -59,7 +59,6 @@ MTR_NEWLY_AVAILABLE // - (oneway void)deviceController:(NSUUID *)controller addServerEndpoint:(MTRServerEndpoint *)endpoint withReply:(void (^)(BOOL success))reply; // - (oneway void)deviceController:(NSUUID *)controller removeServerEndpoint:(MTRServerEndpoint *)endpoint; -- (oneway void)deviceController:(NSUUID *)controller shutdownDeviceController:(NSUUID *)controller; - (oneway void)deviceController:(NSUUID *)controller registerNodeID:(NSNumber *)nodeID; - (oneway void)deviceController:(NSUUID *)controller unregisterNodeID:(NSNumber *)nodeID; From 965a3774dfcd0de0ef194acfdabcf7b42dcdaccb Mon Sep 17 00:00:00 2001 From: Nivi Sarkar <55898241+nivi-apple@users.noreply.github.com> Date: Thu, 3 Oct 2024 19:10:24 -0700 Subject: [PATCH 08/22] Add debug messages to the delegate callbacks for test033_TestMTRDeviceDeviceConfigurationChanged (#35906) --- src/darwin/Framework/CHIPTests/MTRDeviceTests.m | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m index cb2acf2db2..8a3188cbeb 100644 --- a/src/darwin/Framework/CHIPTests/MTRDeviceTests.m +++ b/src/darwin/Framework/CHIPTests/MTRDeviceTests.m @@ -3283,6 +3283,7 @@ - (void)checkAttributeReportTriggersConfigurationChanged:(MTRAttributeIDType)att // Check if the received attribute report matches the injected attribute report. delegate.onAttributeDataReceived = ^(NSArray *> * attributeReport) { + NSLog(@"checkAttributeReportTriggersConfigurationChanged: onAttributeDataReceived called"); attributeReportsReceived += attributeReport.count; XCTAssert(attributeReportsReceived > 0, @"%@", description); for (NSDictionary * attributeDict in attributeReport) { @@ -3309,12 +3310,14 @@ - (void)checkAttributeReportTriggersConfigurationChanged:(MTRAttributeIDType)att }; delegate.onReportEnd = ^() { + NSLog(@"checkAttributeReportTriggersConfigurationChanged: onReportEnd called"); [gotAttributeReportEndExpectation fulfill]; }; __block BOOL wasOnDeviceConfigurationChangedCallbackCalled = NO; delegate.onDeviceConfigurationChanged = ^() { + NSLog(@"checkAttributeReportTriggersConfigurationChanged: onDeviceConfigurationChanged called"); [deviceConfigurationChangedExpectation fulfill]; wasOnDeviceConfigurationChangedCallbackCalled = YES; }; @@ -3365,6 +3368,7 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged __block NSNumber * endpointForPowerSourceConfigurationSources; delegate.onAttributeDataReceived = ^(NSArray *> * attributeReport) { + NSLog(@"test033_TestMTRDeviceDeviceConfigurationChanged: onAttributeDataReceived called"); attributeReportsReceived += attributeReport.count; XCTAssert(attributeReportsReceived > 0); @@ -3423,6 +3427,7 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged }; delegate.onReportEnd = ^() { + NSLog(@"test033_TestMTRDeviceDeviceConfigurationChanged: onReportEnd called"); XCTAssertNotNil(dataVersionForDescriptor); XCTAssertNotNil(dataVersionForOvenCavityOperationalState); XCTAssertNotNil(dataVersionForIdentify); @@ -3660,16 +3665,19 @@ - (void)test033_TestMTRDeviceDeviceConfigurationChanged XCTestExpectation * gotAttributeReportWithMultipleAttributesEndExpectation = [self expectationWithDescription:@"Attribute report with multiple attributes has ended"]; XCTestExpectation * deviceConfigurationChangedExpectationForAttributeReportWithMultipleAttributes = [self expectationWithDescription:@"Device configuration changed was receieved due to an attribute report with multiple attributes "]; delegate.onAttributeDataReceived = ^(NSArray *> * attributeReport) { + NSLog(@"test033_TestMTRDeviceDeviceConfigurationChanged: onAttributeDataReceived called with multiple attributes"); attributeReportsReceived += attributeReport.count; XCTAssert(attributeReportsReceived > 0); [gotAttributeReportWithMultipleAttributesExpectation fulfill]; }; delegate.onReportEnd = ^() { + NSLog(@"test033_TestMTRDeviceDeviceConfigurationChanged: onReportEnd called with multiple attributes"); [gotAttributeReportWithMultipleAttributesEndExpectation fulfill]; }; delegate.onDeviceConfigurationChanged = ^() { + NSLog(@"test033_TestMTRDeviceDeviceConfigurationChanged: onDeviceConfigurationChanged called for testing with multiple attributes"); [deviceConfigurationChangedExpectationForAttributeReportWithMultipleAttributes fulfill]; }; From 3ffe083cc042085386744293d7c65349cc5074e7 Mon Sep 17 00:00:00 2001 From: Justin Wood Date: Thu, 3 Oct 2024 22:59:27 -0700 Subject: [PATCH 09/22] Fixing exception with calling into a dead XPC object (#35908) * Fixing exception with calling into a dead XPC object * Fixing white space * Restyled by whitespace * Restyled by clang-format --------- Co-authored-by: Restyled.io --- .../Framework/CHIP/MTRDefines_Internal.h | 61 +++++++++++-------- .../Framework/CHIP/MTRDeviceController_XPC.mm | 56 ++++++++++++----- src/darwin/Framework/CHIP/MTRDevice_XPC.mm | 30 +++++---- 3 files changed, 96 insertions(+), 51 deletions(-) diff --git a/src/darwin/Framework/CHIP/MTRDefines_Internal.h b/src/darwin/Framework/CHIP/MTRDefines_Internal.h index 5a450ece8e..71a03aa091 100644 --- a/src/darwin/Framework/CHIP/MTRDefines_Internal.h +++ b/src/darwin/Framework/CHIP/MTRDefines_Internal.h @@ -67,22 +67,26 @@ typedef struct {} variable_hidden_by_mtr_hide; #pragma mark - XPC Defines -#define MTR_SIMPLE_REMOTE_XPC_GETTER(XPC_CONNECTION, NAME, TYPE, DEFAULT_VALUE, GETTER_NAME, PREFIX) \ - \ - -(TYPE) NAME \ - { \ - __block TYPE outValue = DEFAULT_VALUE; \ - \ - NSXPCConnection * xpcConnection = XPC_CONNECTION; \ - \ - [[xpcConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { \ - MTR_LOG_ERROR("Error: %@", error); \ - }] PREFIX \ - GETTER_NAME:^(TYPE returnValue) { \ - outValue = returnValue; \ - }]; \ - \ - return outValue; \ +#define MTR_SIMPLE_REMOTE_XPC_GETTER(XPC_CONNECTION, NAME, TYPE, DEFAULT_VALUE, GETTER_NAME, PREFIX) \ + \ + -(TYPE) NAME \ + { \ + __block TYPE outValue = DEFAULT_VALUE; \ + \ + NSXPCConnection * xpcConnection = XPC_CONNECTION; \ + \ + @try { \ + [[xpcConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { \ + MTR_LOG_ERROR("Error: %@", error); \ + }] PREFIX \ + GETTER_NAME:^(TYPE returnValue) { \ + outValue = returnValue; \ + }]; \ + } @catch (NSException * exception) { \ + MTR_LOG_ERROR("Exception sending XPC messsage: %@", exception); \ + outValue = DEFAULT_VALUE; \ + } \ + return outValue; \ } #define MTR_SIMPLE_REMOTE_XPC_COMMAND(XPC_CONNECTION, METHOD_SIGNATURE, ADDITIONAL_ARGUMENTS, PREFIX) \ @@ -91,9 +95,13 @@ typedef struct {} variable_hidden_by_mtr_hide; { \ NSXPCConnection * xpcConnection = XPC_CONNECTION; \ \ - [[xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { \ - MTR_LOG_ERROR("Error: %@", error); \ - }] PREFIX ADDITIONAL_ARGUMENTS]; \ + @try { \ + [[xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { \ + MTR_LOG_ERROR("Error: %@", error); \ + }] PREFIX ADDITIONAL_ARGUMENTS]; \ + } @catch (NSException * exception) { \ + MTR_LOG_ERROR("Exception sending XPC messsage: %@", exception); \ + } \ } #define MTR_COMPLEX_REMOTE_XPC_GETTER(XPC_CONNECTION, SIGNATURE, TYPE, DEFAULT_VALUE, ADDITIONAL_ARGUMENTS, PREFIX) \ @@ -103,11 +111,16 @@ typedef struct {} variable_hidden_by_mtr_hide; \ NSXPCConnection * xpcConnection = XPC_CONNECTION; \ \ - [[xpcConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { \ - MTR_LOG_ERROR("Error: %@", error); \ - }] PREFIX ADDITIONAL_ARGUMENTS:^(TYPE returnValue) { \ - outValue = returnValue; \ - }]; \ + @try { \ + [[xpcConnection synchronousRemoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { \ + MTR_LOG_ERROR("Error: %@", error); \ + }] PREFIX ADDITIONAL_ARGUMENTS:^(TYPE returnValue) { \ + outValue = returnValue; \ + }]; \ + } @catch (NSException * exception) { \ + MTR_LOG_ERROR("Exception sending XPC messsage: %@", exception); \ + outValue = DEFAULT_VALUE; \ + } \ \ return outValue; \ } diff --git a/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm b/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm index 6d45de6d01..45c675121e 100644 --- a/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm +++ b/src/darwin/Framework/CHIP/MTRDeviceController_XPC.mm @@ -44,6 +44,45 @@ @interface MTRDeviceController_XPC () @implementation MTRDeviceController_XPC +#pragma mark - Device Node ID Commands + +- (void)_registerNodeID:(NSNumber *)nodeID +{ + @try { + [[self.xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + MTR_LOG_ERROR("Register node error: %@ nodeID: %@", error, nodeID); + }] deviceController:self.uniqueIdentifier registerNodeID:nodeID]; + } @catch (NSException * exception) { + MTR_LOG_ERROR("Exception registering nodeID: %@", exception); + } +} + +- (void)_unregisterNodeID:(NSNumber *)nodeID +{ + @try { + [[self.xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + MTR_LOG_ERROR("Unregister node error: %@ nodeID: %@", error, nodeID); + }] deviceController:self.uniqueIdentifier unregisterNodeID:nodeID]; + } @catch (NSException * exception) { + MTR_LOG_ERROR("Exception registering nodeID: %@", exception); + } +} + +- (void)_checkinWithContext:(NSDictionary *)context +{ + @try { + if (!context) + context = [NSDictionary dictionary]; + + [[self.xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + MTR_LOG_ERROR("Checkin error: %@", error); + }] deviceController:self.uniqueIdentifier checkInWithContext:context]; + } @catch (NSException * exception) { + MTR_LOG_ERROR("Exception registering nodeID: %@", exception); + } +} + +#pragma mark - XPC + (NSMutableSet *)_allowedClasses { static NSArray * sBaseAllowedClasses = @[ @@ -202,9 +241,7 @@ - (BOOL)_setupXPCConnection MTR_LOG("%@ Activating new XPC connection", self); [self.xpcConnection activate]; - [[self.xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { - MTR_LOG_ERROR("Checkin error: %@", error); - }] deviceController:self.uniqueIdentifier checkInWithContext:[NSDictionary dictionary]]; + [self _checkinWithContext:[NSDictionary dictionary]]; // FIXME: Trying to kick all the MTRDevices attached to this controller to re-establish connections // This state needs to be stored properly and re-established at connnection time @@ -212,12 +249,7 @@ - (BOOL)_setupXPCConnection MTR_LOG("%@ Starting existing NodeID Registration", self); for (NSNumber * nodeID in [self.nodeIDToDeviceMap keyEnumerator]) { MTR_LOG("%@ => Registering nodeID: %@", self, nodeID); - mtr_weakify(self); - - [[self.xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { - mtr_strongify(self); - MTR_LOG_ERROR("%@ Registration error for device nodeID: %@ : %@", self, nodeID, error); - }] deviceController:self.uniqueIdentifier registerNodeID:nodeID]; + [self _registerNodeID:nodeID]; } MTR_LOG("%@ Done existing NodeID Registration", self); @@ -308,11 +340,7 @@ - (MTRDevice *)_setupDeviceForNodeID:(NSNumber *)nodeID prefetchedClusterData:(N [self.nodeIDToDeviceMap setObject:deviceToReturn forKey:nodeID]; MTR_LOG("%s: returning XPC device for node id %@", __PRETTY_FUNCTION__, nodeID); - mtr_weakify(self); - [[self.xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { - mtr_strongify(self); - MTR_LOG_ERROR("%@ Registration error for device nodeID: %@ : %@", self, nodeID, error); - }] deviceController:self.uniqueIdentifier registerNodeID:nodeID]; + [self _registerNodeID:nodeID]; return deviceToReturn; } diff --git a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm index 7806546768..d7a4574f91 100644 --- a/src/darwin/Framework/CHIP/MTRDevice_XPC.mm +++ b/src/darwin/Framework/CHIP/MTRDevice_XPC.mm @@ -249,19 +249,23 @@ - (void)_invokeCommandWithEndpointID:(NSNumber *)endpointID { NSXPCConnection * xpcConnection = [(MTRDeviceController_XPC *) [self deviceController] xpcConnection]; - [[xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { - MTR_LOG_ERROR("Error: %@", error); - }] deviceController:[[self deviceController] uniqueIdentifier] - nodeID:[self nodeID] - invokeCommandWithEndpointID:endpointID - clusterID:clusterID - commandID:commandID - commandFields:commandFields - expectedValues:expectedValues - expectedValueInterval:expectedValueInterval - timedInvokeTimeout:timeout - serverSideProcessingTimeout:serverSideProcessingTimeout - completion:completion]; + @try { + [[xpcConnection remoteObjectProxyWithErrorHandler:^(NSError * _Nonnull error) { + MTR_LOG_ERROR("Error: %@", error); + }] deviceController:[[self deviceController] uniqueIdentifier] + nodeID:[self nodeID] + invokeCommandWithEndpointID:endpointID + clusterID:clusterID + commandID:commandID + commandFields:commandFields + expectedValues:expectedValues + expectedValueInterval:expectedValueInterval + timedInvokeTimeout:timeout + serverSideProcessingTimeout:serverSideProcessingTimeout + completion:completion]; + } @catch (NSException * exception) { + MTR_LOG_ERROR("Exception sending XPC messsage: %@", exception); + } } // Not Supported via XPC From 79fcb911b7b55730e3d91a800c4a5704bc7553cd Mon Sep 17 00:00:00 2001 From: Sergio Soares Date: Fri, 4 Oct 2024 02:18:50 -0400 Subject: [PATCH 10/22] lighting-app: Remove OccupancySensing Server (#35893) * lighting-app: Remove OccupancySensing Server This change removes the OccupancySensing server from this app as this is against the spec and causes test_TC_IDM_10_1 to fail. With this change, now TC_DeviceBasicComposition.py passes for this example app. * Remove OccupancySensing server from ESP32 example app --- .../lighting-app/esp32/main/CMakeLists.txt | 1 - .../lighting-common/lighting-app.matter | 72 ------------ .../lighting-common/lighting-app.zap | 104 ++---------------- 3 files changed, 7 insertions(+), 170 deletions(-) diff --git a/examples/lighting-app/esp32/main/CMakeLists.txt b/examples/lighting-app/esp32/main/CMakeLists.txt index 8b2a2fdce3..d3dc3421cc 100644 --- a/examples/lighting-app/esp32/main/CMakeLists.txt +++ b/examples/lighting-app/esp32/main/CMakeLists.txt @@ -51,7 +51,6 @@ set(SRC_DIRS_LIST "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/time-format-localization-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/level-control" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/network-commissioning" - "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/occupancy-sensor-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/on-off-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/operational-credentials-server" "${CMAKE_SOURCE_DIR}/third_party/connectedhomeip/src/app/clusters/ota-requestor" diff --git a/examples/lighting-app/lighting-common/lighting-app.matter b/examples/lighting-app/lighting-common/lighting-app.matter index 3ebe017c3d..011d11fc33 100644 --- a/examples/lighting-app/lighting-common/lighting-app.matter +++ b/examples/lighting-app/lighting-common/lighting-app.matter @@ -2576,70 +2576,6 @@ cluster ColorControl = 768 { command StepColorTemperature(StepColorTemperatureRequest): DefaultSuccess = 76; } -/** The server cluster provides an interface to occupancy sensing functionality based on one or more sensing modalities, including configuration and provision of notifications of occupancy status. */ -cluster OccupancySensing = 1030 { - revision 5; - - enum OccupancySensorTypeEnum : enum8 { - kPIR = 0; - kUltrasonic = 1; - kPIRAndUltrasonic = 2; - kPhysicalContact = 3; - } - - bitmap Feature : bitmap32 { - kOther = 0x1; - kPassiveInfrared = 0x2; - kUltrasonic = 0x4; - kPhysicalContact = 0x8; - kActiveInfrared = 0x10; - kRadar = 0x20; - kRFSensing = 0x40; - kVision = 0x80; - } - - bitmap OccupancyBitmap : bitmap8 { - kOccupied = 0x1; - } - - bitmap OccupancySensorTypeBitmap : bitmap8 { - kPIR = 0x1; - kUltrasonic = 0x2; - kPhysicalContact = 0x4; - } - - struct HoldTimeLimitsStruct { - int16u holdTimeMin = 0; - int16u holdTimeMax = 1; - int16u holdTimeDefault = 2; - } - - info event OccupancyChanged = 0 { - OccupancyBitmap occupancy = 0; - } - - readonly attribute OccupancyBitmap occupancy = 0; - readonly attribute OccupancySensorTypeEnum occupancySensorType = 1; - readonly attribute OccupancySensorTypeBitmap occupancySensorTypeBitmap = 2; - attribute access(write: manage) optional int16u holdTime = 3; - readonly attribute optional HoldTimeLimitsStruct holdTimeLimits = 4; - attribute access(write: manage) optional int16u PIROccupiedToUnoccupiedDelay = 16; - attribute access(write: manage) optional int16u PIRUnoccupiedToOccupiedDelay = 17; - attribute access(write: manage) optional int8u PIRUnoccupiedToOccupiedThreshold = 18; - attribute access(write: manage) optional int16u ultrasonicOccupiedToUnoccupiedDelay = 32; - attribute access(write: manage) optional int16u ultrasonicUnoccupiedToOccupiedDelay = 33; - attribute access(write: manage) optional int8u ultrasonicUnoccupiedToOccupiedThreshold = 34; - attribute access(write: manage) optional int16u physicalContactOccupiedToUnoccupiedDelay = 48; - attribute access(write: manage) optional int16u physicalContactUnoccupiedToOccupiedDelay = 49; - attribute access(write: manage) optional int8u physicalContactUnoccupiedToOccupiedThreshold = 50; - readonly attribute command_id generatedCommandList[] = 65528; - readonly attribute command_id acceptedCommandList[] = 65529; - readonly attribute event_id eventList[] = 65530; - readonly attribute attrib_id attributeList[] = 65531; - readonly attribute bitmap32 featureMap = 65532; - readonly attribute int16u clusterRevision = 65533; -} - endpoint 0 { device type ma_rootdevice = 22, version 1; @@ -3127,14 +3063,6 @@ endpoint 1 { handle command MoveColorTemperature; handle command StepColorTemperature; } - - server cluster OccupancySensing { - ram attribute occupancy; - ram attribute occupancySensorType; - ram attribute occupancySensorTypeBitmap; - callback attribute featureMap; - ram attribute clusterRevision default = 5; - } } diff --git a/examples/lighting-app/lighting-common/lighting-app.zap b/examples/lighting-app/lighting-common/lighting-app.zap index b7928f3b96..b04b233712 100644 --- a/examples/lighting-app/lighting-common/lighting-app.zap +++ b/examples/lighting-app/lighting-common/lighting-app.zap @@ -19,18 +19,18 @@ "package": [ { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/zcl/zcl.json", - "type": "zcl-properties", + "path": "../../../src/app/zap-templates/app-templates.json", + "type": "gen-templates-json", "category": "matter", - "version": 1, - "description": "Matter SDK ZCL data" + "version": "chip-v1" }, { "pathRelativity": "relativeToZap", - "path": "../../../src/app/zap-templates/app-templates.json", - "type": "gen-templates-json", + "path": "../../../src/app/zap-templates/zcl/zcl.json", + "type": "zcl-properties", "category": "matter", - "version": "chip-v1" + "version": 1, + "description": "Matter SDK ZCL data" } ], "endpointTypes": [ @@ -5638,96 +5638,6 @@ "reportableChange": 0 } ] - }, - { - "name": "Occupancy Sensing", - "code": 1030, - "mfgCode": null, - "define": "OCCUPANCY_SENSING_CLUSTER", - "side": "server", - "enabled": 1, - "attributes": [ - { - "name": "Occupancy", - "code": 0, - "mfgCode": null, - "side": "server", - "type": "OccupancyBitmap", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - }, - { - "name": "OccupancySensorType", - "code": 1, - "mfgCode": null, - "side": "server", - "type": "OccupancySensorTypeEnum", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - }, - { - "name": "OccupancySensorTypeBitmap", - "code": 2, - "mfgCode": null, - "side": "server", - "type": "OccupancySensorTypeBitmap", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "", - "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - }, - { - "name": "FeatureMap", - "code": 65532, - "mfgCode": null, - "side": "server", - "type": "bitmap32", - "included": 1, - "storageOption": "External", - "singleton": 0, - "bounded": 0, - "defaultValue": null, - "reportable": 1, - "minInterval": 1, - "maxInterval": 65534, - "reportableChange": 0 - }, - { - "name": "ClusterRevision", - "code": 65533, - "mfgCode": null, - "side": "server", - "type": "int16u", - "included": 1, - "storageOption": "RAM", - "singleton": 0, - "bounded": 0, - "defaultValue": "5", - "reportable": 1, - "minInterval": 0, - "maxInterval": 65344, - "reportableChange": 0 - } - ] } ] } From 27b5f3ab32805b990586c0ced648f874cad71b5d Mon Sep 17 00:00:00 2001 From: Vatsal Ghelani <152916324+vatsalghelani-csa@users.noreply.github.com> Date: Fri, 4 Oct 2024 02:46:20 -0400 Subject: [PATCH 11/22] Fix duplicate CI runs for both push and pull_request events (#35880) * Update darwin-tests.yaml * Update examples-cc13xx_26xx.yaml * Update examples-linux-tv-casting-app.yaml * Update examples-nxp.yaml * Update chef.yaml * Update cirque.yaml * Update darwin.yaml * Update examples-ameba.yaml * Update examples-asr.yaml * Update examples-efr32.yaml * Update examples-esp32.yaml * Update examples-linux-imx.yaml * Update examples-linux-standalone.yaml * Update examples-mw320.yaml * Update examples-nrfconnect.yaml * Update examples-qpg.yaml * Update examples-stm32.yaml * Update examples-tizen.yaml * Update gradle-wrapper-validation.yml * Update spell.yml * Update tests.yaml * Update zap_templates.yaml * Update build.yaml * Update examples-bouffalolab.yaml * Update examples-cc32xx.yaml * Update examples-infineon.yaml * Update examples-linux-arm.yaml * Update examples-telink.yaml * Update full-android.yaml * Update java-tests.yaml * Update lint.yml * Update minimal-build.yaml * Update qemu.yaml * Update unit_integration_test.yaml * Update example-tv-casting-darwin.yaml * Update examples-nuttx.yaml * Update doxygen.yaml * Update build.yaml * Update chef.yaml * Update cirque.yaml * Update darwin-tests.yaml * Update darwin.yaml * Update doxygen.yaml * Update example-tv-casting-darwin.yaml * Update examples-ameba.yaml * Update examples-asr.yaml * Update examples-bouffalolab.yaml * Update examples-cc13xx_26xx.yaml * Update examples-cc32xx.yaml * Update examples-efr32.yaml * Update examples-esp32.yaml * Update examples-infineon.yaml * Update examples-linux-arm.yaml * Update examples-linux-imx.yaml * Update examples-linux-standalone.yaml * Update examples-linux-tv-casting-app.yaml * Update examples-mw320.yaml * Update examples-nrfconnect.yaml * Update examples-nuttx.yaml * Update examples-nxp.yaml * Update examples-qpg.yaml * Update examples-stm32.yaml * Update examples-telink.yaml * Update examples-tizen.yaml * Update full-android.yaml * Update gradle-wrapper-validation.yml * Update java-tests.yaml * Update lint.yml * Update minimal-build.yaml * Update qemu.yaml * Update spell.yml * Update tests.yaml * Update unit_integration_test.yaml * Update zap_templates.yaml * Put back the original efr32 workflow to check runs * Update examples-efr32.yaml --------- Co-authored-by: Andrei Litvin --- .github/workflows/build.yaml | 5 +++-- .github/workflows/chef.yaml | 5 +++-- .github/workflows/cirque.yaml | 5 +++-- .github/workflows/darwin-tests.yaml | 5 +++-- .github/workflows/darwin.yaml | 5 +++-- .github/workflows/doxygen.yaml | 3 +++ .github/workflows/example-tv-casting-darwin.yaml | 5 +++-- .github/workflows/examples-ameba.yaml | 5 +++-- .github/workflows/examples-asr.yaml | 5 +++-- .github/workflows/examples-bouffalolab.yaml | 5 +++-- .github/workflows/examples-cc13xx_26xx.yaml | 5 +++-- .github/workflows/examples-cc32xx.yaml | 5 +++-- .github/workflows/examples-efr32.yaml | 5 +++-- .github/workflows/examples-esp32.yaml | 5 +++-- .github/workflows/examples-infineon.yaml | 5 +++-- .github/workflows/examples-linux-arm.yaml | 5 +++-- .github/workflows/examples-linux-imx.yaml | 5 +++-- .github/workflows/examples-linux-standalone.yaml | 5 +++-- .github/workflows/examples-linux-tv-casting-app.yaml | 5 +++-- .github/workflows/examples-mw320.yaml | 5 +++-- .github/workflows/examples-nrfconnect.yaml | 5 +++-- .github/workflows/examples-nuttx.yaml | 3 +++ .github/workflows/examples-nxp.yaml | 5 +++-- .github/workflows/examples-qpg.yaml | 5 +++-- .github/workflows/examples-stm32.yaml | 5 +++-- .github/workflows/examples-telink.yaml | 5 +++-- .github/workflows/examples-tizen.yaml | 5 +++-- .github/workflows/full-android.yaml | 5 +++-- .github/workflows/gradle-wrapper-validation.yml | 5 +++-- .github/workflows/java-tests.yaml | 5 +++-- .github/workflows/lint.yml | 5 +++-- .github/workflows/minimal-build.yaml | 5 +++-- .github/workflows/qemu.yaml | 5 +++-- .github/workflows/spell.yml | 5 +++-- .github/workflows/tests.yaml | 5 +++-- .github/workflows/unit_integration_test.yaml | 5 +++-- .github/workflows/zap_templates.yaml | 5 +++-- 37 files changed, 111 insertions(+), 70 deletions(-) diff --git a/.github/workflows/build.yaml b/.github/workflows/build.yaml index 490d7e79d7..f14a16f5e0 100644 --- a/.github/workflows/build.yaml +++ b/.github/workflows/build.yaml @@ -16,8 +16,9 @@ name: Builds on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: workflow_dispatch: diff --git a/.github/workflows/chef.yaml b/.github/workflows/chef.yaml index ca3f42e47c..a1e5907cb9 100644 --- a/.github/workflows/chef.yaml +++ b/.github/workflows/chef.yaml @@ -16,8 +16,9 @@ name: Build Chef CI examples on all platforms on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: diff --git a/.github/workflows/cirque.yaml b/.github/workflows/cirque.yaml index 6fe17c3558..083b350629 100644 --- a/.github/workflows/cirque.yaml +++ b/.github/workflows/cirque.yaml @@ -16,8 +16,9 @@ name: Cirque on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: workflow_dispatch: diff --git a/.github/workflows/darwin-tests.yaml b/.github/workflows/darwin-tests.yaml index 6178273668..1ddc9e9fbc 100644 --- a/.github/workflows/darwin-tests.yaml +++ b/.github/workflows/darwin-tests.yaml @@ -16,8 +16,9 @@ name: Darwin Tests on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: workflow_dispatch: diff --git a/.github/workflows/darwin.yaml b/.github/workflows/darwin.yaml index 4c25026840..bc4441a84f 100644 --- a/.github/workflows/darwin.yaml +++ b/.github/workflows/darwin.yaml @@ -16,8 +16,9 @@ name: Darwin on: push: - branches-ignore: - - "dependabot/**" + branches: + - master + - 'v*-branch' pull_request: merge_group: workflow_dispatch: diff --git a/.github/workflows/doxygen.yaml b/.github/workflows/doxygen.yaml index e255ddce53..9dc5bbab1a 100644 --- a/.github/workflows/doxygen.yaml +++ b/.github/workflows/doxygen.yaml @@ -16,6 +16,9 @@ name: Doxygen on: push: + branches: + - master + - 'v*-branch' paths: - "**.do[xc]" - "**.c[cs]?" diff --git a/.github/workflows/example-tv-casting-darwin.yaml b/.github/workflows/example-tv-casting-darwin.yaml index d8b7b7895e..1528d87c44 100644 --- a/.github/workflows/example-tv-casting-darwin.yaml +++ b/.github/workflows/example-tv-casting-darwin.yaml @@ -16,8 +16,9 @@ name: TV Casting Example - Darwin on: push: - branches-ignore: - - "dependabot/**" + branches: + - master + - 'v*-branch' pull_request: merge_group: workflow_dispatch: diff --git a/.github/workflows/examples-ameba.yaml b/.github/workflows/examples-ameba.yaml index c2bb69cd6f..1c87787cf6 100644 --- a/.github/workflows/examples-ameba.yaml +++ b/.github/workflows/examples-ameba.yaml @@ -16,8 +16,9 @@ name: Build example - Ameba on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: diff --git a/.github/workflows/examples-asr.yaml b/.github/workflows/examples-asr.yaml index 531709a302..7597ef1783 100644 --- a/.github/workflows/examples-asr.yaml +++ b/.github/workflows/examples-asr.yaml @@ -16,8 +16,9 @@ name: Build example - ASR on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: diff --git a/.github/workflows/examples-bouffalolab.yaml b/.github/workflows/examples-bouffalolab.yaml index 3ff00c6c3e..9a6989881e 100644 --- a/.github/workflows/examples-bouffalolab.yaml +++ b/.github/workflows/examples-bouffalolab.yaml @@ -16,8 +16,9 @@ name: Build example - BouffaloLab on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: workflow_dispatch: diff --git a/.github/workflows/examples-cc13xx_26xx.yaml b/.github/workflows/examples-cc13xx_26xx.yaml index 80184cb4b4..31988e6638 100644 --- a/.github/workflows/examples-cc13xx_26xx.yaml +++ b/.github/workflows/examples-cc13xx_26xx.yaml @@ -16,8 +16,9 @@ name: Build example - TI CC13XX_26XX on: push: - branches-ignore: - - "dependabot/**" + branches: + - master + - 'v*-branch' pull_request: merge_group: diff --git a/.github/workflows/examples-cc32xx.yaml b/.github/workflows/examples-cc32xx.yaml index 537621bcf3..24edcb3fa9 100644 --- a/.github/workflows/examples-cc32xx.yaml +++ b/.github/workflows/examples-cc32xx.yaml @@ -17,8 +17,9 @@ name: Build example - TI CC32XX on: workflow_dispatch: push: - branches-ignore: - - "dependabot/**" + branches: + - master + - 'v*-branch' pull_request: merge_group: diff --git a/.github/workflows/examples-efr32.yaml b/.github/workflows/examples-efr32.yaml index 498a250dc9..6d28635597 100644 --- a/.github/workflows/examples-efr32.yaml +++ b/.github/workflows/examples-efr32.yaml @@ -16,8 +16,9 @@ name: Build example - EFR32 on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: diff --git a/.github/workflows/examples-esp32.yaml b/.github/workflows/examples-esp32.yaml index dc1446a93f..a2dca96dc6 100644 --- a/.github/workflows/examples-esp32.yaml +++ b/.github/workflows/examples-esp32.yaml @@ -16,8 +16,9 @@ name: Build example - ESP32 on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: diff --git a/.github/workflows/examples-infineon.yaml b/.github/workflows/examples-infineon.yaml index 9a3b4191c0..ada44f1557 100644 --- a/.github/workflows/examples-infineon.yaml +++ b/.github/workflows/examples-infineon.yaml @@ -16,8 +16,9 @@ name: Build example - Infineon on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: workflow_dispatch: diff --git a/.github/workflows/examples-linux-arm.yaml b/.github/workflows/examples-linux-arm.yaml index f93e295011..ee226b12dc 100644 --- a/.github/workflows/examples-linux-arm.yaml +++ b/.github/workflows/examples-linux-arm.yaml @@ -16,8 +16,9 @@ name: Build example - Linux ARM on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: diff --git a/.github/workflows/examples-linux-imx.yaml b/.github/workflows/examples-linux-imx.yaml index f964f07f1e..d2f1014eb5 100644 --- a/.github/workflows/examples-linux-imx.yaml +++ b/.github/workflows/examples-linux-imx.yaml @@ -16,8 +16,9 @@ name: Build example - i.MX Linux on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: diff --git a/.github/workflows/examples-linux-standalone.yaml b/.github/workflows/examples-linux-standalone.yaml index ff3762c211..83b82369ba 100644 --- a/.github/workflows/examples-linux-standalone.yaml +++ b/.github/workflows/examples-linux-standalone.yaml @@ -16,8 +16,9 @@ name: Build example - Linux Standalone on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: diff --git a/.github/workflows/examples-linux-tv-casting-app.yaml b/.github/workflows/examples-linux-tv-casting-app.yaml index 64000e45f4..e2617aeec7 100644 --- a/.github/workflows/examples-linux-tv-casting-app.yaml +++ b/.github/workflows/examples-linux-tv-casting-app.yaml @@ -16,8 +16,9 @@ name: Test TV Casting Example on: push: - branches-ignore: - - "dependabot/**" + branches: + - master + - 'v*-branch' pull_request: merge_group: diff --git a/.github/workflows/examples-mw320.yaml b/.github/workflows/examples-mw320.yaml index 45daa41dce..8f76321a0c 100644 --- a/.github/workflows/examples-mw320.yaml +++ b/.github/workflows/examples-mw320.yaml @@ -16,8 +16,9 @@ name: Build example - MW320 on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: diff --git a/.github/workflows/examples-nrfconnect.yaml b/.github/workflows/examples-nrfconnect.yaml index 19fdeca62d..d781087fc8 100644 --- a/.github/workflows/examples-nrfconnect.yaml +++ b/.github/workflows/examples-nrfconnect.yaml @@ -16,8 +16,9 @@ name: Build example - nRF Connect SDK on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: diff --git a/.github/workflows/examples-nuttx.yaml b/.github/workflows/examples-nuttx.yaml index 6006cea181..f1f682e008 100644 --- a/.github/workflows/examples-nuttx.yaml +++ b/.github/workflows/examples-nuttx.yaml @@ -16,6 +16,9 @@ name: Build example - NuttX on: push: + branches: + - master + - 'v*-branch' pull_request: merge_group: workflow_dispatch: diff --git a/.github/workflows/examples-nxp.yaml b/.github/workflows/examples-nxp.yaml index c03b9a118c..6354718f25 100644 --- a/.github/workflows/examples-nxp.yaml +++ b/.github/workflows/examples-nxp.yaml @@ -16,8 +16,9 @@ name: Build example - NXP on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: diff --git a/.github/workflows/examples-qpg.yaml b/.github/workflows/examples-qpg.yaml index e0cf4c6ecf..312c493292 100644 --- a/.github/workflows/examples-qpg.yaml +++ b/.github/workflows/examples-qpg.yaml @@ -16,8 +16,9 @@ name: Build example - QPG on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: diff --git a/.github/workflows/examples-stm32.yaml b/.github/workflows/examples-stm32.yaml index c0bc9af19a..2e8f857673 100644 --- a/.github/workflows/examples-stm32.yaml +++ b/.github/workflows/examples-stm32.yaml @@ -16,8 +16,9 @@ name: Build example - stm32 on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: diff --git a/.github/workflows/examples-telink.yaml b/.github/workflows/examples-telink.yaml index 757f11254b..64b3d6bb7c 100644 --- a/.github/workflows/examples-telink.yaml +++ b/.github/workflows/examples-telink.yaml @@ -16,8 +16,9 @@ name: Build example - Telink on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: diff --git a/.github/workflows/examples-tizen.yaml b/.github/workflows/examples-tizen.yaml index 8c6024ee1f..f0e4dfb3a2 100644 --- a/.github/workflows/examples-tizen.yaml +++ b/.github/workflows/examples-tizen.yaml @@ -16,8 +16,9 @@ name: Build example - Tizen on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: diff --git a/.github/workflows/full-android.yaml b/.github/workflows/full-android.yaml index 54561c68e2..c3871ad881 100644 --- a/.github/workflows/full-android.yaml +++ b/.github/workflows/full-android.yaml @@ -16,8 +16,9 @@ name: Full builds - Android on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' workflow_dispatch: concurrency: diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml index ab3f499423..ba0ade69c9 100644 --- a/.github/workflows/gradle-wrapper-validation.yml +++ b/.github/workflows/gradle-wrapper-validation.yml @@ -1,8 +1,9 @@ name: "Validate Gradle Wrapper" on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: jobs: diff --git a/.github/workflows/java-tests.yaml b/.github/workflows/java-tests.yaml index cc6dbc9060..abf2e75027 100644 --- a/.github/workflows/java-tests.yaml +++ b/.github/workflows/java-tests.yaml @@ -16,8 +16,9 @@ name: Java Tests on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: workflow_dispatch: diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index ddcfed3607..a914e5ae36 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -16,8 +16,9 @@ name: Lint Code Base on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: workflow_dispatch: diff --git a/.github/workflows/minimal-build.yaml b/.github/workflows/minimal-build.yaml index 5e364f32d6..dae8a2b8ce 100644 --- a/.github/workflows/minimal-build.yaml +++ b/.github/workflows/minimal-build.yaml @@ -16,8 +16,9 @@ name: Minimal Build (Linux / configure) on: push: - branches-ignore: - - "dependabot/**" + branches: + - master + - 'v*-branch' pull_request: merge_group: diff --git a/.github/workflows/qemu.yaml b/.github/workflows/qemu.yaml index f21903dd9f..b3115f2ff3 100644 --- a/.github/workflows/qemu.yaml +++ b/.github/workflows/qemu.yaml @@ -16,8 +16,9 @@ name: QEMU on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: diff --git a/.github/workflows/spell.yml b/.github/workflows/spell.yml index f37a0e2871..fa0fc222c8 100644 --- a/.github/workflows/spell.yml +++ b/.github/workflows/spell.yml @@ -16,8 +16,9 @@ name: Run misspell on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' paths: - "**.md" - ".github/.wordlist.txt" diff --git a/.github/workflows/tests.yaml b/.github/workflows/tests.yaml index e0904bb516..04aa91020a 100644 --- a/.github/workflows/tests.yaml +++ b/.github/workflows/tests.yaml @@ -16,8 +16,9 @@ name: Tests on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: workflow_dispatch: diff --git a/.github/workflows/unit_integration_test.yaml b/.github/workflows/unit_integration_test.yaml index e593630fa5..b51dfaa8fc 100644 --- a/.github/workflows/unit_integration_test.yaml +++ b/.github/workflows/unit_integration_test.yaml @@ -16,8 +16,9 @@ name: Unit / Integration Tests on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: diff --git a/.github/workflows/zap_templates.yaml b/.github/workflows/zap_templates.yaml index 45a3611691..717f8ca956 100644 --- a/.github/workflows/zap_templates.yaml +++ b/.github/workflows/zap_templates.yaml @@ -16,8 +16,9 @@ name: ZAP on: push: - branches-ignore: - - 'dependabot/**' + branches: + - master + - 'v*-branch' pull_request: merge_group: From 22c488bd5fac61fc0eea60ec7d227e3a49544231 Mon Sep 17 00:00:00 2001 From: Harshith-GRL <145322529+Harshith-GRL@users.noreply.github.com> Date: Fri, 4 Oct 2024 17:49:22 +0530 Subject: [PATCH 12/22] AutoRelockTime wait will happen when Pics is enabled (#35891) Co-authored-by: cjandhyala <68604034+cjandhyala@users.noreply.github.com> --- src/python_testing/drlk_2_x_common.py | 28 ++++++++++++++------------- 1 file changed, 15 insertions(+), 13 deletions(-) diff --git a/src/python_testing/drlk_2_x_common.py b/src/python_testing/drlk_2_x_common.py index 044128d0d3..92c0ab23ce 100644 --- a/src/python_testing/drlk_2_x_common.py +++ b/src/python_testing/drlk_2_x_common.py @@ -313,19 +313,21 @@ async def run_drlk_test_common(self, lockUnlockCommand, lockUnlockCmdRspPICS, lo autoRelockTime_dut = await self.read_drlk_attribute_expect_success(attribute=attributes.AutoRelockTime) logging.info("AutoRelockTime value is %s" % (autoRelockTime_dut)) - if self.check_pics(lockUnlockCmdRspPICS): - self.print_step("17", "Send %s with valid Pincode and verify success" % lockUnlockText) - command = lockUnlockCommand(PINCode=pin_code) - await self.send_drlk_cmd_expect_success(command=command) - # Add additional wait time buffer for motor movement, etc. - time.sleep(autoRelockTime_dut + 5) - - if self.check_pics("DRLK.S.A0000"): - self.print_step("18", "TH reads LockState attribute after AutoRelockTime Expires") - lockstate_dut = await self.read_drlk_attribute_expect_success(attribute=attributes.LockState) - logging.info("Current LockState is %s" % (lockstate_dut)) - asserts.assert_equal(lockstate_dut, Clusters.DoorLock.Enums.DlLockState.kLocked, - "LockState expected to be value==Locked") + if self.check_pics(lockUnlockCmdRspPICS): + self.print_step("17", "Send %s with valid Pincode and verify success" % lockUnlockText) + command = lockUnlockCommand(PINCode=pin_code) + await self.send_drlk_cmd_expect_success(command=command) + + if self.check_pics("DRLK.S.A0000"): + self.print_step("18", "TH reads LockState attribute after AutoRelockTime Expires") + # Add additional wait time buffer for motor movement, etc. + time.sleep(autoRelockTime_dut + 5) + lockstate_dut = await self.read_drlk_attribute_expect_success(attribute=attributes.LockState) + logging.info("Current LockState is %s" % (lockstate_dut)) + asserts.assert_equal(lockstate_dut, Clusters.DoorLock.Enums.DlLockState.kLocked, + "LockState expected to be value==Locked") + else: + logging.info("Steps 15 to 18 are Skipped as the PICs DRLK.S.A0023 not enabled") await self.cleanup_users_and_credentials(user_clear_step="20", clear_credential_step="19", credentials=credential, userIndex=1) From 6f728a5c95654f41b9417f02e8871ed9ed6627ca Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Fri, 4 Oct 2024 05:44:59 -0700 Subject: [PATCH 13/22] Remove provisional status of Fabric Sync bits to align with the spec (#35912) --- .../fabric-bridge-common/fabric-bridge-app.matter | 2 +- .../zcl/data-model/chip/bridged-device-basic-information.xml | 2 +- .../zcl/data-model/chip/commissioner-control-cluster.xml | 2 +- .../zcl/data-model/chip/ecosystem-information-cluster.xml | 2 +- src/controller/data_model/controller-clusters.matter | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter b/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter index ed7b86037f..57ce56efc3 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter +++ b/examples/fabric-bridge-app/fabric-bridge-common/fabric-bridge-app.matter @@ -1697,7 +1697,7 @@ cluster GroupKeyManagement = 63 { } /** Supports the ability for clients to request the commissioning of themselves or other nodes onto a fabric which the cluster server can commission onto. */ -provisional cluster CommissionerControl = 1873 { +cluster CommissionerControl = 1873 { revision 1; bitmap SupportedDeviceCategoryBitmap : bitmap32 { diff --git a/src/app/zap-templates/zcl/data-model/chip/bridged-device-basic-information.xml b/src/app/zap-templates/zcl/data-model/chip/bridged-device-basic-information.xml index bc1d61e643..39a2e2c258 100644 --- a/src/app/zap-templates/zcl/data-model/chip/bridged-device-basic-information.xml +++ b/src/app/zap-templates/zcl/data-model/chip/bridged-device-basic-information.xml @@ -95,7 +95,7 @@ limitations under the License. UniqueID ProductAppearance - + The server SHALL attempt to keep the devices specified active for StayActiveDuration milliseconds when they are next active. diff --git a/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml index abfd85dde2..dcfb1dfa70 100644 --- a/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/commissioner-control-cluster.xml @@ -21,7 +21,7 @@ limitations under the License. - + General Commissioner Control 0x0751 diff --git a/src/app/zap-templates/zcl/data-model/chip/ecosystem-information-cluster.xml b/src/app/zap-templates/zcl/data-model/chip/ecosystem-information-cluster.xml index cf84a7e229..73ae522365 100644 --- a/src/app/zap-templates/zcl/data-model/chip/ecosystem-information-cluster.xml +++ b/src/app/zap-templates/zcl/data-model/chip/ecosystem-information-cluster.xml @@ -16,7 +16,7 @@ limitations under the License. --> - + diff --git a/src/controller/data_model/controller-clusters.matter b/src/controller/data_model/controller-clusters.matter index 7f5d7fda86..c222fa904e 100644 --- a/src/controller/data_model/controller-clusters.matter +++ b/src/controller/data_model/controller-clusters.matter @@ -9590,7 +9590,7 @@ provisional cluster EcosystemInformation = 1872 { } /** Supports the ability for clients to request the commissioning of themselves or other nodes onto a fabric which the cluster server can commission onto. */ -provisional cluster CommissionerControl = 1873 { +cluster CommissionerControl = 1873 { revision 1; bitmap SupportedDeviceCategoryBitmap : bitmap32 { From 3d882e9e999e5318e5bfd453374db8ee2392912f Mon Sep 17 00:00:00 2001 From: chirag-silabs <100861685+chirag-silabs@users.noreply.github.com> Date: Fri, 4 Oct 2024 18:15:43 +0530 Subject: [PATCH 14/22] fixing the additional advertising on the 91x (#35913) --- src/platform/silabs/rs911x/BLEManagerImpl.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/platform/silabs/rs911x/BLEManagerImpl.cpp b/src/platform/silabs/rs911x/BLEManagerImpl.cpp index 841fc1a4b6..44b2a17199 100644 --- a/src/platform/silabs/rs911x/BLEManagerImpl.cpp +++ b/src/platform/silabs/rs911x/BLEManagerImpl.cpp @@ -145,7 +145,7 @@ void BLEManagerImpl::ProcessEvent(SilabsBleWrapper::BleEvent_t inEvent) #if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING if (inEvent.eventData->rsi_ble_read_req->type == 0) { - BLEMgrImpl().HandleC3ReadRequest(&inEvent.eventData); + BLEMgrImpl().HandleC3ReadRequest(inEvent.eventData); } #endif // CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING } @@ -999,7 +999,7 @@ CHIP_ERROR BLEManagerImpl::EncodeAdditionalDataTlv() void BLEManagerImpl::HandleC3ReadRequest(SilabsBleWrapper::sl_wfx_msg_t * evt) { - sl_status_t ret = rsi_ble_gatt_read_response(evt->rsi_ble_read_req.dev_addr, GATT_READ_RESP, evt->rsi_ble_read_req.handle, + sl_status_t ret = rsi_ble_gatt_read_response(evt->rsi_ble_read_req->dev_addr, GATT_READ_RESP, evt->rsi_ble_read_req->handle, GATT_READ_ZERO_OFFSET, sInstance.c3AdditionalDataBufferHandle->DataLength(), sInstance.c3AdditionalDataBufferHandle->Start()); if (ret != SL_STATUS_OK) From 33b1f2294a17b65de98bda508945be2daa9adf33 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Fri, 4 Oct 2024 05:46:06 -0700 Subject: [PATCH 15/22] Remove legacy thread for RPC test (#35909) --- examples/fabric-bridge-app/linux/main.cpp | 37 ----------------------- 1 file changed, 37 deletions(-) diff --git a/examples/fabric-bridge-app/linux/main.cpp b/examples/fabric-bridge-app/linux/main.cpp index 2a79363712..3e93c9878f 100644 --- a/examples/fabric-bridge-app/linux/main.cpp +++ b/examples/fabric-bridge-app/linux/main.cpp @@ -16,10 +16,6 @@ * limitations under the License. */ -#include -#include -#include - #include #include "BridgedAdministratorCommissioning.h" @@ -55,8 +51,6 @@ using namespace chip::app::Clusters::BridgedDeviceBasicInformation; namespace { -constexpr uint16_t kPollIntervalMs = 100; - #if defined(PW_RPC_FABRIC_BRIDGE_SERVICE) && PW_RPC_FABRIC_BRIDGE_SERVICE constexpr uint16_t kRetryIntervalS = 3; #endif @@ -103,33 +97,6 @@ bool HandleCustomOption(const char * aProgram, ArgParser::OptionSet * aOptions, ArgParser::OptionSet sProgramCustomOptions = { HandleCustomOption, sProgramCustomOptionDefs, "GENERAL OPTIONS", sProgramCustomOptionHelp }; -bool KeyboardHit() -{ - int bytesWaiting; - ioctl(0, FIONREAD, &bytesWaiting); - return bytesWaiting > 0; -} - -void BridgePollingThread() -{ - while (true) - { - if (KeyboardHit()) - { - int ch = getchar(); - if (ch == 'e') - { - ChipLogProgress(NotSpecified, "Exiting....."); - exit(0); - } - continue; - } - - // Sleep to avoid tight loop reading commands - usleep(kPollIntervalMs * 1000); - } -} - #if defined(PW_RPC_FABRIC_BRIDGE_SERVICE) && PW_RPC_FABRIC_BRIDGE_SERVICE void AttemptRpcClientConnect(System::Layer * systemLayer, void * appState) { @@ -292,10 +259,6 @@ void ApplicationInit() AttemptRpcClientConnect(&DeviceLayer::SystemLayer(), nullptr); #endif - // Start a thread for bridge polling - std::thread pollingThread(BridgePollingThread); - pollingThread.detach(); - BridgeDeviceMgr().Init(); VerifyOrDie(gBridgedAdministratorCommissioning.Init() == CHIP_NO_ERROR); From ad57f01eef92dd8e5b46c8d07d7e23f3c5f46504 Mon Sep 17 00:00:00 2001 From: mkardous-silabs <84793247+mkardous-silabs@users.noreply.github.com> Date: Fri, 4 Oct 2024 08:46:33 -0400 Subject: [PATCH 16/22] Fix empty report feedback loop (#35899) --- src/app/reporting/ReportScheduler.h | 1 + src/app/reporting/SynchronizedReportSchedulerImpl.cpp | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/app/reporting/ReportScheduler.h b/src/app/reporting/ReportScheduler.h index f0e6ce3ff8..d6425e3481 100644 --- a/src/app/reporting/ReportScheduler.h +++ b/src/app/reporting/ReportScheduler.h @@ -150,6 +150,7 @@ class ReportScheduler : public ReadHandler::Observer, public ICDStateObserver IsEngineRunScheduled())); } + bool CanStartReporting() const { return mReadHandler->CanStartReporting(); } bool IsChunkedReport() const { return mReadHandler->IsChunkedReport(); } bool IsEngineRunScheduled() const { return mFlags.Has(ReadHandlerNodeFlags::EngineRunScheduled); } void SetEngineRunScheduled(bool aEngineRunScheduled) diff --git a/src/app/reporting/SynchronizedReportSchedulerImpl.cpp b/src/app/reporting/SynchronizedReportSchedulerImpl.cpp index a402f32b9b..6d04e2b57d 100644 --- a/src/app/reporting/SynchronizedReportSchedulerImpl.cpp +++ b/src/app/reporting/SynchronizedReportSchedulerImpl.cpp @@ -183,7 +183,7 @@ void SynchronizedReportSchedulerImpl::TimerFired() VerifyOrReturn(mNodesPool.Allocated()); mNodesPool.ForEachActiveObject([now, &firedEarly](ReadHandlerNode * node) { - if (node->GetMinTimestamp() <= now) + if (node->GetMinTimestamp() <= now && node->CanStartReporting()) { // Since this handler can now report whenever it wants to, mark it as allowed to report if any other handler is // reporting using the CanBeSynced flag. From 5cf80d760b40afa61fabc7c79b8dcf2af3a3cbf3 Mon Sep 17 00:00:00 2001 From: Yufeng Wang Date: Fri, 4 Oct 2024 05:47:27 -0700 Subject: [PATCH 17/22] Cleanup extra namespace prefix (#35911) --- .../OpenCommissioningWindowCommand.cpp | 2 +- .../commands/pairing/PairingCommand.cpp | 47 +++++++++---------- .../commands/pairing/PairingCommand.h | 14 +++--- 3 files changed, 31 insertions(+), 32 deletions(-) diff --git a/examples/chip-tool/commands/pairing/OpenCommissioningWindowCommand.cpp b/examples/chip-tool/commands/pairing/OpenCommissioningWindowCommand.cpp index bc80e568b2..8d04ca7b94 100644 --- a/examples/chip-tool/commands/pairing/OpenCommissioningWindowCommand.cpp +++ b/examples/chip-tool/commands/pairing/OpenCommissioningWindowCommand.cpp @@ -49,7 +49,7 @@ CHIP_ERROR OpenCommissioningWindowCommand::RunCommand() } void OpenCommissioningWindowCommand::OnOpenCommissioningWindowResponse(void * context, NodeId remoteId, CHIP_ERROR err, - chip::SetupPayload payload) + SetupPayload payload) { LogErrorOnFailure(err); diff --git a/examples/chip-tool/commands/pairing/PairingCommand.cpp b/examples/chip-tool/commands/pairing/PairingCommand.cpp index b9034cc128..7e762bd690 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.cpp +++ b/examples/chip-tool/commands/pairing/PairingCommand.cpp @@ -151,7 +151,7 @@ CommissioningParameters PairingCommand::GetCommissioningParameters() if (!mICDSymmetricKey.HasValue()) { - chip::Crypto::DRBG_get_bytes(mRandomGeneratedICDSymmetricKey, sizeof(mRandomGeneratedICDSymmetricKey)); + Crypto::DRBG_get_bytes(mRandomGeneratedICDSymmetricKey, sizeof(mRandomGeneratedICDSymmetricKey)); mICDSymmetricKey.SetValue(ByteSpan(mRandomGeneratedICDSymmetricKey)); } if (!mICDCheckInNodeId.HasValue()) @@ -289,7 +289,7 @@ CHIP_ERROR PairingCommand::PairWithMdnsOrBleByIndexWithCode(NodeId remoteId, uin // There is no device with this index that has some resolution data. This could simply // be because the device is a ble device. In this case let's fall back to looking for // a device with this index and some RendezvousParameters. - chip::SetupPayload payload; + SetupPayload payload; bool isQRCode = strncmp(mOnboardingPayload, kQRCodePrefix, strlen(kQRCodePrefix)) == 0; if (isQRCode) { @@ -329,21 +329,21 @@ CHIP_ERROR PairingCommand::PairWithMdns(NodeId remoteId) Dnssd::DiscoveryFilter filter(mFilterType); switch (mFilterType) { - case chip::Dnssd::DiscoveryFilterType::kNone: + case Dnssd::DiscoveryFilterType::kNone: break; - case chip::Dnssd::DiscoveryFilterType::kShortDiscriminator: - case chip::Dnssd::DiscoveryFilterType::kLongDiscriminator: - case chip::Dnssd::DiscoveryFilterType::kCompressedFabricId: - case chip::Dnssd::DiscoveryFilterType::kVendorId: - case chip::Dnssd::DiscoveryFilterType::kDeviceType: + case Dnssd::DiscoveryFilterType::kShortDiscriminator: + case Dnssd::DiscoveryFilterType::kLongDiscriminator: + case Dnssd::DiscoveryFilterType::kCompressedFabricId: + case Dnssd::DiscoveryFilterType::kVendorId: + case Dnssd::DiscoveryFilterType::kDeviceType: filter.code = mDiscoveryFilterCode; break; - case chip::Dnssd::DiscoveryFilterType::kCommissioningMode: + case Dnssd::DiscoveryFilterType::kCommissioningMode: break; - case chip::Dnssd::DiscoveryFilterType::kCommissioner: + case Dnssd::DiscoveryFilterType::kCommissioner: filter.code = 1; break; - case chip::Dnssd::DiscoveryFilterType::kInstanceName: + case Dnssd::DiscoveryFilterType::kInstanceName: filter.code = 0; filter.instanceName = mDiscoveryFilterInstanceName; break; @@ -463,13 +463,13 @@ void PairingCommand::OnReadCommissioningInfo(const Controller::ReadCommissioning void PairingCommand::OnICDRegistrationComplete(ScopedNodeId nodeId, uint32_t icdCounter) { - char icdSymmetricKeyHex[chip::Crypto::kAES_CCM128_Key_Length * 2 + 1]; + char icdSymmetricKeyHex[Crypto::kAES_CCM128_Key_Length * 2 + 1]; - chip::Encoding::BytesToHex(mICDSymmetricKey.Value().data(), mICDSymmetricKey.Value().size(), icdSymmetricKeyHex, - sizeof(icdSymmetricKeyHex), chip::Encoding::HexFlags::kNullTerminate); + Encoding::BytesToHex(mICDSymmetricKey.Value().data(), mICDSymmetricKey.Value().size(), icdSymmetricKeyHex, + sizeof(icdSymmetricKeyHex), Encoding::HexFlags::kNullTerminate); app::ICDClientInfo clientInfo; - clientInfo.check_in_node = chip::ScopedNodeId(mICDCheckInNodeId.Value(), nodeId.GetFabricIndex()); + clientInfo.check_in_node = ScopedNodeId(mICDCheckInNodeId.Value(), nodeId.GetFabricIndex()); clientInfo.peer_node = nodeId; clientInfo.monitored_subject = mICDMonitoredSubject.Value(); clientInfo.start_icd_counter = icdCounter; @@ -505,7 +505,7 @@ void PairingCommand::OnICDStayActiveComplete(ScopedNodeId deviceId, uint32_t pro ChipLogValueX64(deviceId.GetNodeId()), promisedActiveDuration); } -void PairingCommand::OnDiscoveredDevice(const chip::Dnssd::CommissionNodeData & nodeData) +void PairingCommand::OnDiscoveredDevice(const Dnssd::CommissionNodeData & nodeData) { // Ignore nodes with closed commissioning window VerifyOrReturn(nodeData.commissioningMode != 0); @@ -513,7 +513,7 @@ void PairingCommand::OnDiscoveredDevice(const chip::Dnssd::CommissionNodeData & auto & resolutionData = nodeData; const uint16_t port = resolutionData.port; - char buf[chip::Inet::IPAddress::kMaxStringLength]; + char buf[Inet::IPAddress::kMaxStringLength]; resolutionData.ipAddress[0].ToString(buf); ChipLogProgress(chipTool, "Discovered Device: %s:%u", buf, port); @@ -556,20 +556,19 @@ void PairingCommand::OnCurrentFabricRemove(void * context, NodeId nodeId, CHIP_E command->SetCommandExitStatus(err); } -chip::Optional PairingCommand::FailSafeExpiryTimeoutSecs() const +Optional PairingCommand::FailSafeExpiryTimeoutSecs() const { // We don't need to set additional failsafe timeout as we don't ask the final user if he wants to continue - return chip::Optional(); + return Optional(); } -void PairingCommand::OnDeviceAttestationCompleted(chip::Controller::DeviceCommissioner * deviceCommissioner, - chip::DeviceProxy * device, - const chip::Credentials::DeviceAttestationVerifier::AttestationDeviceInfo & info, - chip::Credentials::AttestationVerificationResult attestationResult) +void PairingCommand::OnDeviceAttestationCompleted(Controller::DeviceCommissioner * deviceCommissioner, DeviceProxy * device, + const Credentials::DeviceAttestationVerifier::AttestationDeviceInfo & info, + Credentials::AttestationVerificationResult attestationResult) { // Bypass attestation verification, continue with success auto err = deviceCommissioner->ContinueCommissioningAfterDeviceAttestation( - device, chip::Credentials::AttestationVerificationResult::kSuccess); + device, Credentials::AttestationVerificationResult::kSuccess); if (CHIP_NO_ERROR != err) { SetCommandExitStatus(err); diff --git a/examples/chip-tool/commands/pairing/PairingCommand.h b/examples/chip-tool/commands/pairing/PairingCommand.h index 9965b663ec..66c45d5dfe 100644 --- a/examples/chip-tool/commands/pairing/PairingCommand.h +++ b/examples/chip-tool/commands/pairing/PairingCommand.h @@ -244,7 +244,7 @@ class PairingCommand : public CHIPCommand, const PairingNetworkType mNetworkType; const chip::Dnssd::DiscoveryFilterType mFilterType; Command::AddressWithInterface mRemoteAddr; - NodeId mNodeId; + NodeId mNodeId = chip::kUndefinedNodeId; chip::Optional mTimeout; chip::Optional mDiscoverOnce; chip::Optional mUseOnlyOnNetworkDiscovery; @@ -266,7 +266,7 @@ class PairingCommand : public CHIPCommand, TypedComplexArgument> mComplex_DSTOffsets; - uint16_t mRemotePort; + uint16_t mRemotePort = 0; // mDiscriminator is only used for some situations, but in those situations // it's mandatory. Track whether we're actually using it; the cases that do // will emplace this optional. @@ -275,15 +275,15 @@ class PairingCommand : public CHIPCommand, // it's mandatory. Track whether we're actually using it; the cases that do // will emplace this optional. std::optional mSetupPINCode; - uint16_t mIndex; + uint16_t mIndex = 0; chip::ByteSpan mOperationalDataset; chip::ByteSpan mSSID; chip::ByteSpan mPassword; - char * mOnboardingPayload; - uint64_t mDiscoveryFilterCode; - char * mDiscoveryFilterInstanceName; + char * mOnboardingPayload = nullptr; + uint64_t mDiscoveryFilterCode = 0; + char * mDiscoveryFilterInstanceName = nullptr; - bool mDeviceIsICD; + bool mDeviceIsICD = false; uint8_t mRandomGeneratedICDSymmetricKey[chip::Crypto::kAES_CCM128_Key_Length]; // For unpair From 78f489d7d5cb5f8c48120d8a18e14efb8fe01d11 Mon Sep 17 00:00:00 2001 From: Kenneth Fu <80622799+fuxiaoming-lumi@users.noreply.github.com> Date: Fri, 4 Oct 2024 20:48:08 +0800 Subject: [PATCH 18/22] [Silabs] Enabling custom board support for matter (#35809) * [Silabs] Enabling custom board support for matter * Restyled to Make Pretty * Streamline printing to make pretty * Put the assert at the end and add silabs board descriptions * Restyled --- third_party/silabs/silabs_board.gni | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/third_party/silabs/silabs_board.gni b/third_party/silabs/silabs_board.gni index 7e4f3fff9b..213417976d 100644 --- a/third_party/silabs/silabs_board.gni +++ b/third_party/silabs/silabs_board.gni @@ -13,9 +13,17 @@ # limitations under the License. declare_args() { - # EFR32 board used + # Silabs wireless starter kit plug-in boards featuring specific mcu family and mcu model. + # Find more information at https://www.silabs.com/development-tools/wireless. + # A board tailored for specific mcu family and mcu model can be created with "CUSTOM". silabs_board = "" + # Silabs mcu family used + silabs_family = "" + + # Silabs mcu model used + silabs_mcu = "" + # LCD is enabled by default # Boards BRD4166A, BRD2601B, BRD2703A and BRD4319A do not have a LCD so they disable it explicitly disable_lcd = false @@ -150,6 +158,12 @@ if (silabs_board == "BRD4338A" || silabs_board == "BRD2605A") { # ThunderBoards don't have a LCD, show_qr_code = false disable_lcd = true + + # Custom Board ---------- +} else if (silabs_board == "CUSTOM") { + print("Using custom board configuration") + print("silabs_family:", silabs_family) + print("silabs_mcu:", silabs_mcu) } else { assert( false, @@ -168,5 +182,9 @@ declare_args() { sl_uart_log_output = wifi_soc } +# Silabs mcu family and mcu model must be specified +assert(silabs_family != "", "Must specify silabs_family") +assert(silabs_mcu != "", "Must specify silabs_mcu") + # qr code cannot be true if lcd is disabled assert(!(disable_lcd && show_qr_code)) From 8e0b710c78040d760c0331c3496dbd681dc69c8f Mon Sep 17 00:00:00 2001 From: mkardous-silabs <84793247+mkardous-silabs@users.noreply.github.com> Date: Tue, 8 Oct 2024 08:58:22 -0400 Subject: [PATCH 19/22] [ICD] Make optional spec checks mandatory with the launch of LongIdleTime ICDs (#35956) (#35960) * Remove optional spec check * Add static_assert for the slow poll config for SIT ICDs * Add missing include * fix restyler error * fix spacing * Remove client build flag since it is not used --- config/esp32/components/chip/CMakeLists.txt | 3 --- config/esp32/components/chip/Kconfig | 9 +------ config/nrfconnect/chip-module/CMakeLists.txt | 1 - .../enabling_icd_on_ti_devices.md | 3 --- .../contact-sensor-app/nxp/k32w0/args.gni | 1 - .../contact-sensor-app/nxp/k32w1/args.gni | 1 - .../contact-sensor-app/nxp/mcxw71/args.gni | 1 - .../silabs/build_for_wifi_args.gni | 1 - examples/lit-icd-app/silabs/openthread.gni | 1 - examples/lock-app/nxp/k32w1/args.gni | 1 - examples/lock-app/nxp/mcxw71/args.gni | 1 - .../silabs/build_for_wifi_args.gni | 1 - .../smoke-co-alarm-app/silabs/openthread.gni | 1 - src/app/icd/icd.gni | 8 ------ src/app/icd/server/BUILD.gn | 1 - src/app/icd/server/ICDConfigurationData.cpp | 8 +++--- src/app/icd/server/ICDConfigurationData.h | 26 +++++++++++-------- src/app/icd/server/ICDManager.cpp | 3 --- 18 files changed, 20 insertions(+), 51 deletions(-) diff --git a/config/esp32/components/chip/CMakeLists.txt b/config/esp32/components/chip/CMakeLists.txt index f7685cf760..fde62765dd 100644 --- a/config/esp32/components/chip/CMakeLists.txt +++ b/config/esp32/components/chip/CMakeLists.txt @@ -143,9 +143,6 @@ endif() if(CONFIG_ENABLE_ICD_SERVER) chip_gn_arg_append("chip_enable_icd_server" "true") - if(CONFIG_ICD_ENFORCE_SIT_SLOW_POLL_LIMIT) - chip_gn_arg_append("icd_enforce_sit_slow_poll_limit" "true") - endif() if(CONFIG_ICD_REPORT_ON_ACTIVE_MODE) chip_gn_arg_append("chip_icd_report_on_active_mode" "true") endif() diff --git a/config/esp32/components/chip/Kconfig b/config/esp32/components/chip/Kconfig index 5c36284f07..c61ac770a6 100644 --- a/config/esp32/components/chip/Kconfig +++ b/config/esp32/components/chip/Kconfig @@ -32,7 +32,7 @@ menu "CHIP Core" default 8 help The maximum number of simultaneously active CHIP exchange contexts. - + An exchange context object is used to track the state of an ongoing CHIP message exchange (conversation) with a peer, e.g. a cloud service, a mobile application, or another device. @@ -410,13 +410,6 @@ menu "CHIP Device Layer" help Enables or Disables ICD server - config ICD_ENFORCE_SIT_SLOW_POLL_LIMIT - bool "Enforce SIT Slow Polling Max value to 15 seconds" - depends on ENABLE_ICD_SERVER - default n - help - Set to true to enforce SIT Slow Polling Max value to 15seconds - config ICD_REPORT_ON_ACTIVE_MODE bool "Emit a report on entering active mode" depends on ENABLE_ICD_SERVER diff --git a/config/nrfconnect/chip-module/CMakeLists.txt b/config/nrfconnect/chip-module/CMakeLists.txt index 3896ed6be7..b3180fdc1b 100644 --- a/config/nrfconnect/chip-module/CMakeLists.txt +++ b/config/nrfconnect/chip-module/CMakeLists.txt @@ -156,7 +156,6 @@ if (CONFIG_CHIP_ENABLE_ICD_SUPPORT) matter_add_gn_arg_bool ("chip_enable_icd_checkin" CONFIG_CHIP_ICD_CHECK_IN_SUPPORT) matter_add_gn_arg_bool ("chip_enable_icd_user_active_mode_trigger" CONFIG_CHIP_ICD_UAT_SUPPORT) matter_add_gn_arg_bool ("chip_enable_icd_dsls" CONFIG_CHIP_ICD_DSLS_SUPPORT) - matter_add_gn_arg_bool ("icd_enforce_sit_slow_poll_limit" TRUE) endif() if (CONFIG_CHIP_FACTORY_DATA OR CONFIG_CHIP_FACTORY_DATA_CUSTOM_BACKEND) diff --git a/docs/guides/ti/matter-users-guide/enabling_icd_on_ti_devices.md b/docs/guides/ti/matter-users-guide/enabling_icd_on_ti_devices.md index 50495a601e..b024b90b40 100644 --- a/docs/guides/ti/matter-users-guide/enabling_icd_on_ti_devices.md +++ b/docs/guides/ti/matter-users-guide/enabling_icd_on_ti_devices.md @@ -24,9 +24,6 @@ Trigger Support, set the following parameter to true: chip_enable_icd_lit = true ``` -TI examples have only been tested with the ICD Server configuration. To enable -the client configuration, set `chip_enable_icd_client` to true. - Persistent subscriptions allow devices to attempt resuming existing subscriptions following a device reset. To enable persistent subscriptions, set the following parameter to true: diff --git a/examples/contact-sensor-app/nxp/k32w0/args.gni b/examples/contact-sensor-app/nxp/k32w0/args.gni index 1709f1da73..f4b68ae740 100644 --- a/examples/contact-sensor-app/nxp/k32w0/args.gni +++ b/examples/contact-sensor-app/nxp/k32w0/args.gni @@ -28,7 +28,6 @@ chip_generate_link_map_file = true chip_enable_icd_server = true chip_enable_icd_lit = false -icd_enforce_sit_slow_poll_limit = true chip_persist_subscriptions = true chip_subscription_timeout_resumption = true diff --git a/examples/contact-sensor-app/nxp/k32w1/args.gni b/examples/contact-sensor-app/nxp/k32w1/args.gni index 98372f4b82..e5654bdbc7 100644 --- a/examples/contact-sensor-app/nxp/k32w1/args.gni +++ b/examples/contact-sensor-app/nxp/k32w1/args.gni @@ -32,7 +32,6 @@ chip_with_lwip = false chip_enable_icd_server = true chip_enable_icd_lit = false chip_enable_icd_dsls = false -icd_enforce_sit_slow_poll_limit = true chip_persist_subscriptions = true chip_subscription_timeout_resumption = true diff --git a/examples/contact-sensor-app/nxp/mcxw71/args.gni b/examples/contact-sensor-app/nxp/mcxw71/args.gni index 72634a2308..6e6015933d 100644 --- a/examples/contact-sensor-app/nxp/mcxw71/args.gni +++ b/examples/contact-sensor-app/nxp/mcxw71/args.gni @@ -30,7 +30,6 @@ chip_with_lwip = false chip_enable_icd_server = true chip_enable_icd_lit = false -icd_enforce_sit_slow_poll_limit = true chip_persist_subscriptions = true chip_subscription_timeout_resumption = true diff --git a/examples/lit-icd-app/silabs/build_for_wifi_args.gni b/examples/lit-icd-app/silabs/build_for_wifi_args.gni index 56cd70b217..6ef009e906 100644 --- a/examples/lit-icd-app/silabs/build_for_wifi_args.gni +++ b/examples/lit-icd-app/silabs/build_for_wifi_args.gni @@ -29,7 +29,6 @@ sl_enable_test_event_trigger = true chip_enable_icd_server = true chip_subscription_timeout_resumption = false sl_use_subscription_syncing = true -icd_enforce_sit_slow_poll_limit = true chip_enable_icd_lit = true # ICD Matter Configuration flags diff --git a/examples/lit-icd-app/silabs/openthread.gni b/examples/lit-icd-app/silabs/openthread.gni index b12529c2ca..e84e7be8ed 100644 --- a/examples/lit-icd-app/silabs/openthread.gni +++ b/examples/lit-icd-app/silabs/openthread.gni @@ -32,7 +32,6 @@ sl_enable_test_event_trigger = true chip_enable_icd_server = true chip_subscription_timeout_resumption = false sl_use_subscription_syncing = true -icd_enforce_sit_slow_poll_limit = true chip_icd_report_on_active_mode = true chip_enable_icd_lit = true diff --git a/examples/lock-app/nxp/k32w1/args.gni b/examples/lock-app/nxp/k32w1/args.gni index e0c41d1e34..b7a2d790ef 100644 --- a/examples/lock-app/nxp/k32w1/args.gni +++ b/examples/lock-app/nxp/k32w1/args.gni @@ -30,7 +30,6 @@ chip_with_lwip = false chip_enable_icd_server = true chip_enable_icd_lit = false -icd_enforce_sit_slow_poll_limit = true chip_persist_subscriptions = true chip_subscription_timeout_resumption = true diff --git a/examples/lock-app/nxp/mcxw71/args.gni b/examples/lock-app/nxp/mcxw71/args.gni index 761b050b80..1a0940c96a 100644 --- a/examples/lock-app/nxp/mcxw71/args.gni +++ b/examples/lock-app/nxp/mcxw71/args.gni @@ -30,7 +30,6 @@ chip_with_lwip = false chip_enable_icd_server = true chip_enable_icd_lit = false -icd_enforce_sit_slow_poll_limit = true chip_persist_subscriptions = true chip_subscription_timeout_resumption = true diff --git a/examples/smoke-co-alarm-app/silabs/build_for_wifi_args.gni b/examples/smoke-co-alarm-app/silabs/build_for_wifi_args.gni index 0619082413..e5097f8a1d 100644 --- a/examples/smoke-co-alarm-app/silabs/build_for_wifi_args.gni +++ b/examples/smoke-co-alarm-app/silabs/build_for_wifi_args.gni @@ -28,7 +28,6 @@ sl_enable_test_event_trigger = true chip_enable_icd_server = true chip_subscription_timeout_resumption = false sl_use_subscription_syncing = true -icd_enforce_sit_slow_poll_limit = true chip_enable_icd_lit = true # ICD Matter Configuration flags diff --git a/examples/smoke-co-alarm-app/silabs/openthread.gni b/examples/smoke-co-alarm-app/silabs/openthread.gni index 845b2220b4..f2a7ab6ed7 100644 --- a/examples/smoke-co-alarm-app/silabs/openthread.gni +++ b/examples/smoke-co-alarm-app/silabs/openthread.gni @@ -32,7 +32,6 @@ sl_enable_test_event_trigger = true chip_enable_icd_server = true chip_subscription_timeout_resumption = false sl_use_subscription_syncing = true -icd_enforce_sit_slow_poll_limit = true chip_icd_report_on_active_mode = true chip_enable_icd_lit = true diff --git a/src/app/icd/icd.gni b/src/app/icd/icd.gni index ed3fd0518f..b7fef896f5 100644 --- a/src/app/icd/icd.gni +++ b/src/app/icd/icd.gni @@ -14,23 +14,15 @@ declare_args() { # Matter SDK Configuration flag to enable ICD server functionality - # TODO - Add Specifics when the design is refined chip_enable_icd_server = false chip_enable_icd_lit = false - # Matter SDK Configuration flag to enable ICD client functionality - # TODO - Add Specifics when the design is refined - chip_enable_icd_client = false - # Matter SDK Configuration flag to make the ICD manager emit a report on entering active mode chip_icd_report_on_active_mode = false icd_max_notification_subscribers = 1 - # Set to true to enforce SIT Slow Polling Max value to 15seconds (spec 9.16.1.5) - icd_enforce_sit_slow_poll_limit = false - # Set to true if device supports dynamic switching from SIT to LIT operating modes (DSLS) chip_enable_icd_dsls = false } diff --git a/src/app/icd/server/BUILD.gn b/src/app/icd/server/BUILD.gn index e1967c23f5..bef9a0730a 100644 --- a/src/app/icd/server/BUILD.gn +++ b/src/app/icd/server/BUILD.gn @@ -39,7 +39,6 @@ buildconfig_header("icd-server-buildconfig") { "CHIP_CONFIG_ENABLE_ICD_DSLS=${chip_enable_icd_dsls}", "ICD_REPORT_ON_ENTER_ACTIVE_MODE=${chip_icd_report_on_active_mode}", "ICD_MAX_NOTIFICATION_SUBSCRIBERS=${icd_max_notification_subscribers}", - "ICD_ENFORCE_SIT_SLOW_POLL_LIMIT=${icd_enforce_sit_slow_poll_limit}", ] visibility = [ ":icd-server-config" ] diff --git a/src/app/icd/server/ICDConfigurationData.cpp b/src/app/icd/server/ICDConfigurationData.cpp index cfd2325671..44d78bfadf 100644 --- a/src/app/icd/server/ICDConfigurationData.cpp +++ b/src/app/icd/server/ICDConfigurationData.cpp @@ -16,7 +16,6 @@ */ #include "ICDConfigurationData.h" -#include #include namespace chip { @@ -25,15 +24,16 @@ ICDConfigurationData ICDConfigurationData::instance; System::Clock::Milliseconds32 ICDConfigurationData::GetSlowPollingInterval() { -#if ICD_ENFORCE_SIT_SLOW_POLL_LIMIT - // When in SIT mode, the slow poll interval SHOULDN'T be greater than the SIT mode polling threshold, per spec. +#if CHIP_CONFIG_ENABLE_ICD_LIT + // When in SIT mode, the slow poll interval SHALL NOT be greater than the SIT mode polling threshold, per spec. // This is important for ICD device configured for LIT operation but currently operating as a SIT // due to a lack of client registration if (mICDMode == ICDMode::SIT && mSlowPollingInterval > kSITPollingThreshold) { return kSITPollingThreshold; } -#endif +#endif // CHIP_CONFIG_ENABLE_ICD_LIT + return mSlowPollingInterval; } diff --git a/src/app/icd/server/ICDConfigurationData.h b/src/app/icd/server/ICDConfigurationData.h index 0d6e17e55e..4d2597ef26 100644 --- a/src/app/icd/server/ICDConfigurationData.h +++ b/src/app/icd/server/ICDConfigurationData.h @@ -17,6 +17,7 @@ #pragma once +#include #include #include #include @@ -77,14 +78,11 @@ class ICDConfigurationData System::Clock::Seconds32 GetMaximumCheckInBackoff() { return mMaximumCheckInBackOff; } /** - * If ICD_ENFORCE_SIT_SLOW_POLL_LIMIT is set to 0, function will always return the configured Slow Polling interval - * (CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL). - * - * If ICD_ENFORCE_SIT_SLOW_POLL_LIMIT is set to 1, the returned value will depend on the devices operating mode. + * The returned value will depend on the devices operating mode. * If ICDMode == SIT && the configured slow poll interval is superior to the maximum threshold (15s), the function will return - * the threshold (15s). If ICDMode == SIT but the configured slow poll interval is equal or inferior to the threshold, the - * function will the return the configured slow poll interval. If ICDMode == LIT, the function will return the configured slow - * poll interval. + * the threshold kSITPollingThreshold (<= 15s). If ICDMode == SIT but the configured slow poll interval is equal or inferior to + * the threshold, the function will the return the configured slow poll interval. If ICDMode == LIT, the function will return + * the configured slow poll interval. * * @return System::Clock::Milliseconds32 */ @@ -158,12 +156,18 @@ class ICDConfigurationData "Spec requires the MaximumCheckInBackOff to be equal or superior to the IdleModeDuration"); System::Clock::Seconds32 mMaximumCheckInBackOff = System::Clock::Seconds32(CHIP_CONFIG_ICD_MAXIMUM_CHECK_IN_BACKOFF_SEC); - // SIT ICDs should have a SlowPollingThreshold shorter than or equal to 15s (spec 9.16.1.5) - static_assert((CHIP_DEVICE_CONFIG_ICD_SIT_SLOW_POLL_LIMIT).count() <= 15000, + // SIT ICDs SHALL have a SlowPollingThreshold shorter than or equal to 15s (spec 9.16.1.5) + static constexpr System::Clock::Milliseconds32 kSitIcdSlowPollMaximum = System::Clock::Milliseconds32(15000); + static_assert((CHIP_DEVICE_CONFIG_ICD_SIT_SLOW_POLL_LIMIT).count() <= kSitIcdSlowPollMaximum.count(), "Spec requires the maximum slow poll interval for the SIT device to be smaller or equal than 15 s."); static constexpr System::Clock::Milliseconds32 kSITPollingThreshold = CHIP_DEVICE_CONFIG_ICD_SIT_SLOW_POLL_LIMIT; - System::Clock::Milliseconds32 mSlowPollingInterval = CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL; - System::Clock::Milliseconds32 mFastPollingInterval = CHIP_DEVICE_CONFIG_ICD_FAST_POLL_INTERVAL; + +#if CHIP_CONFIG_ENABLE_ICD_LIT == 0 + static_assert((CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL <= kSitIcdSlowPollMaximum), + "LIT support is required for slow polling intervals superior to 15 seconds"); +#endif + System::Clock::Milliseconds32 mSlowPollingInterval = CHIP_DEVICE_CONFIG_ICD_SLOW_POLL_INTERVAL; + System::Clock::Milliseconds32 mFastPollingInterval = CHIP_DEVICE_CONFIG_ICD_FAST_POLL_INTERVAL; ICDMode mICDMode = ICDMode::SIT; }; diff --git a/src/app/icd/server/ICDManager.cpp b/src/app/icd/server/ICDManager.cpp index 3e89af1e16..ba349b22b9 100644 --- a/src/app/icd/server/ICDManager.cpp +++ b/src/app/icd/server/ICDManager.cpp @@ -80,9 +80,6 @@ void ICDManager::Init() VerifyOrDieWithMsg(ICDConfigurationData::GetInstance().GetMinLitActiveModeThreshold() <= ICDConfigurationData::GetInstance().GetActiveModeThreshold(), AppServer, "The minimum ActiveModeThreshold value for a LIT ICD is 5 seconds."); - // Disabling check until LIT support is compelte - // VerifyOrDieWithMsg((GetSlowPollingInterval() <= GetSITPollingThreshold()) , AppServer, - // "LIT support is required for slow polling intervals superior to 15 seconds"); } #endif // CHIP_CONFIG_ENABLE_ICD_LIT From 3ff8a03a30998b0fbee9afeed9ed31e6480cf54e Mon Sep 17 00:00:00 2001 From: mkardous-silabs <84793247+mkardous-silabs@users.noreply.github.com> Date: Tue, 8 Oct 2024 14:14:48 -0400 Subject: [PATCH 20/22] Add missing feature map bit (#35915) (#35966) * Add missing feature map bit * Generation Co-authored-by: Andrei Litvin --- .../light-switch-common/light-switch-app.matter | 2 +- .../light-switch-app/light-switch-common/light-switch-app.zap | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/light-switch-app/light-switch-common/light-switch-app.matter b/examples/light-switch-app/light-switch-common/light-switch-app.matter index 947a24740f..e2fea1bdb8 100644 --- a/examples/light-switch-app/light-switch-common/light-switch-app.matter +++ b/examples/light-switch-app/light-switch-common/light-switch-app.matter @@ -3222,7 +3222,7 @@ endpoint 2 { callback attribute generatedCommandList; callback attribute acceptedCommandList; callback attribute attributeList; - ram attribute featureMap default = 2; + ram attribute featureMap default = 6; ram attribute clusterRevision default = 2; } } diff --git a/examples/light-switch-app/light-switch-common/light-switch-app.zap b/examples/light-switch-app/light-switch-common/light-switch-app.zap index 89f718140f..595b0d8f83 100644 --- a/examples/light-switch-app/light-switch-common/light-switch-app.zap +++ b/examples/light-switch-app/light-switch-common/light-switch-app.zap @@ -5587,7 +5587,7 @@ "storageOption": "RAM", "singleton": 0, "bounded": 0, - "defaultValue": "2", + "defaultValue": "6", "reportable": 1, "minInterval": 1, "maxInterval": 65534, From a0845c83a447675f8dd160ed5b5277ac7ec9942e Mon Sep 17 00:00:00 2001 From: lpbeliveau-silabs <112982107+lpbeliveau-silabs@users.noreply.github.com> Date: Wed, 9 Oct 2024 09:30:03 -0400 Subject: [PATCH 21/22] [SL-TEMP] Bugfix temporary em req removal (#43) * Added the temporary fix to remove ot em1 commit a1b548882d3c5988048ea98b85b6558210181550 Author: lpbeliveau-silabs Date: Thu Oct 3 17:48:35 2024 -0400 Added the line to disable the em1 req from OT Moved the EM req requirement removal to AppInit * Added ifdef to ignore fix on gn builds --- examples/platform/silabs/MatterConfig.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/examples/platform/silabs/MatterConfig.cpp b/examples/platform/silabs/MatterConfig.cpp index 20f73ab681..2ca0cfa107 100644 --- a/examples/platform/silabs/MatterConfig.cpp +++ b/examples/platform/silabs/MatterConfig.cpp @@ -79,6 +79,13 @@ static chip::DeviceLayer::Internal::Efr32PsaOperationalKeystore gOperationalKeys #include +#if CHIP_ENABLE_OPENTHREAD && (SL_MATTER_GN_BUILD == 0) +// SLC-FIX +// TODO: Remove the Power Manager include when OT does not add an EM1 req at init +#define CURRENT_MODULE_NAME "OPENTHREAD" +#include "sl_power_manager.h" +#endif + /********************************************************** * Defines *********************************************************/ @@ -183,6 +190,12 @@ void ApplicationStart(void * unused) void SilabsMatterConfig::AppInit() { + #if CHIP_ENABLE_OPENTHREAD && (SL_MATTER_GN_BUILD == 0) + // SLC-FIX + // TODO: Remove the Power Manager remove req when OT does not add an EM1 req at init + sl_power_manager_remove_em_requirement(SL_POWER_MANAGER_EM1); + #endif + GetPlatform().Init(); sMainTaskHandle = osThreadNew(ApplicationStart, nullptr, &kMainTaskAttr); SILABS_LOG("Starting scheduler"); From 0b2a8911b1b46263674389401f93b71f284fb63f Mon Sep 17 00:00:00 2001 From: mkardous-silabs <84793247+mkardous-silabs@users.noreply.github.com> Date: Wed, 9 Oct 2024 11:06:51 -0400 Subject: [PATCH 22/22] [Silabs] Refactor Sensor code (#35979) (#35992) * Refactor Sensor and LCD code * Address review comments --- examples/platform/silabs/Si70xxSensor.cpp | 67 +++++++++++++++++++ examples/platform/silabs/Si70xxSensor.h | 48 +++++++++++++ examples/platform/silabs/SiWx917/BUILD.gn | 7 ++ .../platform/silabs/TemperatureSensor.cpp | 62 ----------------- examples/platform/silabs/TemperatureSensor.h | 28 -------- examples/platform/silabs/display/demo-ui.c | 1 - examples/platform/silabs/display/lcd.h | 3 +- examples/platform/silabs/efr32/BUILD.gn | 7 ++ examples/thermostat/silabs/BUILD.gn | 28 -------- .../thermostat/silabs/src/SensorManager.cpp | 42 ++++++------ third_party/silabs/efr32_sdk.gni | 27 ++++++++ third_party/silabs/matter_support | 2 +- third_party/silabs/silabs_board.gni | 15 +++++ 13 files changed, 196 insertions(+), 141 deletions(-) create mode 100644 examples/platform/silabs/Si70xxSensor.cpp create mode 100644 examples/platform/silabs/Si70xxSensor.h delete mode 100644 examples/platform/silabs/TemperatureSensor.cpp delete mode 100644 examples/platform/silabs/TemperatureSensor.h diff --git a/examples/platform/silabs/Si70xxSensor.cpp b/examples/platform/silabs/Si70xxSensor.cpp new file mode 100644 index 0000000000..0b03ca040f --- /dev/null +++ b/examples/platform/silabs/Si70xxSensor.cpp @@ -0,0 +1,67 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * 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 "sl_board_control.h" +#include "sl_i2cspm_instances.h" +#include "sl_si70xx.h" +#include +#include + +namespace { + +constexpr uint16_t kSensorTemperatureOffset = 475; +bool initialized = false; + +} // namespace + +namespace Si70xxSensor { + +sl_status_t Init() +{ + sl_status_t status = SL_STATUS_OK; + + status = sl_board_enable_sensor(SL_BOARD_SENSOR_RHT); + VerifyOrReturnError(status == SL_STATUS_OK, status); + + status = sl_si70xx_init(sl_i2cspm_sensor, SI7021_ADDR); + VerifyOrReturnError(status == SL_STATUS_OK, status); + + initialized = true; + return status; +} + +sl_status_t GetSensorData(uint16_t & relativeHumidity, int16_t & temperature) +{ + VerifyOrReturnError(initialized, SL_STATUS_NOT_INITIALIZED); + + sl_status_t status = SL_STATUS_OK; + int32_t tempTemperature = 0; + uint32_t tempHumidity = 0; + + status = sl_si70xx_measure_rh_and_temp(sl_i2cspm_sensor, SI7021_ADDR, &tempHumidity, &tempTemperature); + VerifyOrReturnError(status == SL_STATUS_OK, status); + + // Sensor precision is milliX. We need to reduce to change the precision to centiX to fit with the cluster attributes presicion. + temperature = static_cast(tempTemperature / 10) - kSensorTemperatureOffset; + relativeHumidity = static_cast(tempHumidity / 10); + + return status; +} + +}; // namespace Si70xxSensor diff --git a/examples/platform/silabs/Si70xxSensor.h b/examples/platform/silabs/Si70xxSensor.h new file mode 100644 index 0000000000..8dc31a8daf --- /dev/null +++ b/examples/platform/silabs/Si70xxSensor.h @@ -0,0 +1,48 @@ +/* + * + * Copyright (c) 2020 Project CHIP Authors + * Copyright (c) 2019 Google LLC. + * 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 "sl_status.h" +#include + +namespace Si70xxSensor { + +/** + * @brief Initialises the Si70xx Sensor. + * + * @return sl_status_t SL_STATUS_OK if there were no errors occured during initialisation. + * Error if an underlying platform error occured + */ +sl_status_t Init(); + +/** + * @brief Reads Humidity and temperature values from the Si70xx sensor. + * The init function must be called before calling the GetSensorData. + * + * @param[out] relativeHumidity Relative humidity percentage in centi-pourcentage (1000 == 10.00%) + * @param[out] temperature Ambiant temperature in centi-celsium (1000 == 10.00C) + * + * @return sl_status_t SL_STATUS_OK if there were no errors occured during initialisation. + * SL_STATUS_NOT_INITIALIZED if the sensor was not initialised + * Error if an underlying platform error occured + */ +sl_status_t GetSensorData(uint16_t & relativeHumidity, int16_t & temperature); + +}; // namespace Si70xxSensor diff --git a/examples/platform/silabs/SiWx917/BUILD.gn b/examples/platform/silabs/SiWx917/BUILD.gn index 156fb38e49..cf7b7aedbf 100644 --- a/examples/platform/silabs/SiWx917/BUILD.gn +++ b/examples/platform/silabs/SiWx917/BUILD.gn @@ -252,6 +252,13 @@ source_set("siwx917-common") { public_deps += [ ":test-event-trigger" ] } + if (sl_enable_si70xx_sensor) { + sources += [ + "${silabs_common_plat_dir}/Si70xxSensor.cpp", + "${silabs_common_plat_dir}/Si70xxSensor.h", + ] + } + if (app_data_model != "") { public_deps += [ app_data_model ] } diff --git a/examples/platform/silabs/TemperatureSensor.cpp b/examples/platform/silabs/TemperatureSensor.cpp deleted file mode 100644 index d7e13e1993..0000000000 --- a/examples/platform/silabs/TemperatureSensor.cpp +++ /dev/null @@ -1,62 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * Copyright (c) 2019 Google LLC. - * 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 "TemperatureSensor.h" - -#include "sl_board_control.h" -#include "sl_i2cspm_instances.h" -#include "sl_si70xx.h" - -namespace TemperatureSensor { -constexpr uint16_t kSensorTemperatureOffset = 800; -static bool initialized = false; - -sl_status_t Init() -{ - sl_status_t status; - sl_i2cspm_t * rht_sensor = sl_i2cspm_sensor; - (void) sl_board_enable_sensor(SL_BOARD_SENSOR_RHT); - - status = sl_si70xx_init(rht_sensor, SI7021_ADDR); - initialized = (SL_STATUS_OK == status); - return status; -} - -sl_status_t GetTemp(uint32_t * relativeHumidity, int16_t * temperature) -{ - if (!initialized) - { - return SL_STATUS_NOT_INITIALIZED; - } - - // Sensor resolution 0.001 C - // DataModel resolution 0.01 C - sl_status_t status; - sl_i2cspm_t * rht_sensor = sl_i2cspm_sensor; - int32_t temp = 0; - status = sl_si70xx_measure_rh_and_temp(rht_sensor, SI7021_ADDR, relativeHumidity, &temp); - - if (temperature != nullptr) - { - *temperature = static_cast(temp / 10) - kSensorTemperatureOffset; - } - - return status; -} -}; // namespace TemperatureSensor diff --git a/examples/platform/silabs/TemperatureSensor.h b/examples/platform/silabs/TemperatureSensor.h deleted file mode 100644 index 116287e9a3..0000000000 --- a/examples/platform/silabs/TemperatureSensor.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * - * Copyright (c) 2020 Project CHIP Authors - * Copyright (c) 2019 Google LLC. - * 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 "sl_status.h" -#include - -namespace TemperatureSensor { -sl_status_t Init(); -sl_status_t GetTemp(uint32_t * relativeHumidity, int16_t * temperature); -}; // namespace TemperatureSensor diff --git a/examples/platform/silabs/display/demo-ui.c b/examples/platform/silabs/display/demo-ui.c index e0fe37ec9c..d909cb1f88 100644 --- a/examples/platform/silabs/display/demo-ui.c +++ b/examples/platform/silabs/display/demo-ui.c @@ -167,6 +167,5 @@ void demoUIClearMainScreen(uint8_t * name) { GLIB_clear(&glibContext); demoUIDisplayHeader((char *) name); - demoUIDisplayApp(false); demoUIDisplayProtocols(); } diff --git a/examples/platform/silabs/display/lcd.h b/examples/platform/silabs/display/lcd.h index b62664c9b4..61fa816743 100644 --- a/examples/platform/silabs/display/lcd.h +++ b/examples/platform/silabs/display/lcd.h @@ -65,6 +65,7 @@ class SilabsLCD int DrawPixel(void * pContext, int32_t x, int32_t y); int Update(void); void WriteDemoUI(bool state); + void WriteDemoUI(); void SetCustomUI(customUICB cb); void GetScreen(Screen_e & screen); @@ -85,8 +86,6 @@ class SilabsLCD bool protocol1 = false; /* data */ } DemoState_t; - void WriteDemoUI(); - #ifdef QR_CODE_ENABLED void WriteQRCode(); void LCDFillRect(uint8_t x, uint8_t y, uint8_t w, uint8_t h); diff --git a/examples/platform/silabs/efr32/BUILD.gn b/examples/platform/silabs/efr32/BUILD.gn index 91cd2c1a0a..f5c79a2252 100644 --- a/examples/platform/silabs/efr32/BUILD.gn +++ b/examples/platform/silabs/efr32/BUILD.gn @@ -308,6 +308,13 @@ source_set("efr32-common") { public_deps += [ ":test-event-trigger" ] } + if (sl_enable_si70xx_sensor) { + sources += [ + "${silabs_common_plat_dir}/Si70xxSensor.cpp", + "${silabs_common_plat_dir}/Si70xxSensor.h", + ] + } + if (app_data_model != "") { public_deps += [ app_data_model ] } diff --git a/examples/thermostat/silabs/BUILD.gn b/examples/thermostat/silabs/BUILD.gn index 75b2f75c15..f51ee14825 100644 --- a/examples/thermostat/silabs/BUILD.gn +++ b/examples/thermostat/silabs/BUILD.gn @@ -47,10 +47,6 @@ import("${examples_common_plat_dir}/args.gni") declare_args() { # Dump memory usage at link time. chip_print_memory_usage = false - - # Enable the temperature sensor - # Some boards do not have a temperature sensor - use_temp_sensor = false } if (wifi_soc) { @@ -112,19 +108,6 @@ if (wifi_soc) { "PW_RPC_ENABLED", ] } - - if (use_temp_sensor) { - include_dirs += [ - "${efr32_sdk_root}/platform/driver/i2cspm/inc", - "${efr32_sdk_root}/app/bluetooth/common/sensor_rht", - "${efr32_sdk_root}/app/bluetooth/common/sensor_rht/config", - "${efr32_sdk_root}/hardware/driver/si70xx/inc", - "${efr32_sdk_root}/app/bluetooth/common/sensor_select", - "${efr32_sdk_root}/platform/common/config", - ] - - defines += [ "USE_TEMP_SENSOR" ] - } } } @@ -141,17 +124,6 @@ silabs_executable("thermostat_app") { "src/ZclCallbacks.cpp", ] - if (use_temp_sensor) { - sources += [ - "${efr32_sdk_root}/hardware/driver/si70xx/src/sl_si70xx.c", - "${efr32_sdk_root}/platform/common/src/sl_status.c", - "${efr32_sdk_root}/platform/driver/i2cspm/src/sl_i2cspm.c", - "${efr32_sdk_root}/platform/emlib/src/em_i2c.c", - "${examples_common_plat_dir}/TemperatureSensor.cpp", - "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen/sl_i2cspm_init.c", - ] - } - if (!disable_lcd) { sources += [ "src/ThermostatUI.cpp" ] } diff --git a/examples/thermostat/silabs/src/SensorManager.cpp b/examples/thermostat/silabs/src/SensorManager.cpp index abecd899d5..3522e9f5a3 100644 --- a/examples/thermostat/silabs/src/SensorManager.cpp +++ b/examples/thermostat/silabs/src/SensorManager.cpp @@ -26,14 +26,15 @@ #include "AppEvent.h" #include "AppTask.h" -#ifdef USE_TEMP_SENSOR -#include "TemperatureSensor.h" -#endif +#if defined(SL_MATTER_USE_SI70XX_SENSOR) && SL_MATTER_USE_SI70XX_SENSOR +#include "Si70xxSensor.h" +#endif // defined(SL_MATTER_USE_SI70XX_SENSOR) && SL_MATTER_USE_SI70XX_SENSOR /********************************************************** * Defines and Constants *********************************************************/ using namespace chip; +using namespace chip::app; using namespace ::chip::DeviceLayer; constexpr EndpointId kThermostatEndpoint = 1; @@ -45,10 +46,10 @@ constexpr uint16_t kMinTemperatureDelta = 50; // 0.5 degree Celcius *********************************************************/ SensorManager SensorManager::sSensorManager; -#ifndef USE_TEMP_SENSOR +#if !(defined(SL_MATTER_USE_SI70XX_SENSOR) && (SL_MATTER_USE_SI70XX_SENSOR)) constexpr uint16_t kSimulatedReadingFrequency = (60000 / kSensorTImerPeriodMs); // Change Simulated number at each minutes static int16_t mSimulatedTemp[] = { 2300, 2400, 2800, 2550, 2200, 2125, 2100, 2600, 1800, 2700 }; -#endif +#endif // !(defined(SL_MATTER_USE_SI70XX_SENSOR) && (SL_MATTER_USE_SI70XX_SENSOR)) CHIP_ERROR SensorManager::Init() { @@ -61,13 +62,13 @@ CHIP_ERROR SensorManager::Init() return APP_ERROR_CREATE_TIMER_FAILED; } -#ifdef USE_TEMP_SENSOR - if (SL_STATUS_OK != TemperatureSensor::Init()) +#if defined(SL_MATTER_USE_SI70XX_SENSOR) && SL_MATTER_USE_SI70XX_SENSOR + if (SL_STATUS_OK != Si70xxSensor::Init()) { SILABS_LOG("Failed to Init Sensor"); return CHIP_ERROR_INTERNAL; } -#endif +#endif // defined(SL_MATTER_USE_SI70XX_SENSOR) && SL_MATTER_USE_SI70XX_SENSOR // Update Temp immediatly at bootup SensorTimerEventHandler(nullptr); @@ -81,19 +82,20 @@ void SensorManager::SensorTimerEventHandler(void * arg) int16_t temperature = 0; static int16_t lastTemperature = 0; -#ifdef USE_TEMP_SENSOR +#if defined(SL_MATTER_USE_SI70XX_SENSOR) && SL_MATTER_USE_SI70XX_SENSOR int32_t tempSum = 0; - uint32_t humidity = 0; + uint16_t humidity = 0; for (uint8_t i = 0; i < 100; i++) { - if (SL_STATUS_OK != TemperatureSensor::GetTemp(&humidity, &temperature)) + if (SL_STATUS_OK != Si70xxSensor::GetSensorData(humidity, temperature)) { SILABS_LOG("Failed to read Temperature !!!"); } tempSum += temperature; } temperature = static_cast(tempSum / 100); + #else static uint8_t nbOfRepetition = 0; static uint8_t simulatedIndex = 0; @@ -109,18 +111,20 @@ void SensorManager::SensorTimerEventHandler(void * arg) simulatedIndex++; nbOfRepetition = 0; } -#endif // USE_TEMP_SENSOR +#endif // defined(SL_MATTER_USE_SI70XX_SENSOR) && SL_MATTER_USE_SI70XX_SENSOR SILABS_LOG("Sensor Temp is : %d", temperature); + MarkAttributeDirty reportState = MarkAttributeDirty::kNo; if ((temperature >= (lastTemperature + kMinTemperatureDelta)) || temperature <= (lastTemperature - kMinTemperatureDelta)) { - lastTemperature = temperature; - PlatformMgr().LockChipStack(); - // The SensorMagager shouldn't be aware of the Endpoint ID TODO Fix this. - // TODO Per Spec we should also apply the Offset stored in the same cluster before saving the temp - - app::Clusters::Thermostat::Attributes::LocalTemperature::Set(kThermostatEndpoint, temperature); - PlatformMgr().UnlockChipStack(); + reportState = MarkAttributeDirty::kIfChanged; } + + lastTemperature = temperature; + PlatformMgr().LockChipStack(); + // The SensorMagager shouldn't be aware of the Endpoint ID TODO Fix this. + // TODO Per Spec we should also apply the Offset stored in the same cluster before saving the temp + app::Clusters::Thermostat::Attributes::LocalTemperature::Set(kThermostatEndpoint, temperature, reportState); + PlatformMgr().UnlockChipStack(); } diff --git a/third_party/silabs/efr32_sdk.gni b/third_party/silabs/efr32_sdk.gni index 470c812505..146077372f 100644 --- a/third_party/silabs/efr32_sdk.gni +++ b/third_party/silabs/efr32_sdk.gni @@ -415,6 +415,17 @@ template("efr32_sdk") { _include_dirs += [ "${chip_root}/third_party/silabs/mqtt/stack" ] } + if (sl_enable_si70xx_sensor) { + _include_dirs += [ + "${efr32_sdk_root}/platform/driver/i2cspm/inc", + "${efr32_sdk_root}/app/bluetooth/common/sensor_rht", + "${efr32_sdk_root}/app/bluetooth/common/sensor_rht/config", + "${efr32_sdk_root}/hardware/driver/si70xx/inc", + "${efr32_sdk_root}/app/bluetooth/common/sensor_select", + "${efr32_sdk_root}/platform/common/config", + ] + } + # Note that we're setting the mbedTLS and PSA configuration files through a # define. This means the build system by default does not pick up changes in # the content of these, only when changing the filename itself. @@ -672,6 +683,12 @@ template("efr32_sdk") { defines += [ "CHIP_CONFIG_SYNCHRONOUS_REPORTS_ENABLED=1" ] } + if (sl_enable_si70xx_sensor) { + defines += [ "SL_MATTER_USE_SI70XX_SENSOR=1" ] + } else { + defines += [ "SL_MATTER_USE_SI70XX_SENSOR=0" ] + } + cflags = [] foreach(include_dir, _include_dirs) { cflags += [ "-isystem" + rebase_path(include_dir, root_build_dir) ] @@ -1068,6 +1085,16 @@ template("efr32_sdk") { ] } + if (sl_enable_si70xx_sensor) { + sources += [ + "${efr32_sdk_root}/hardware/driver/si70xx/src/sl_si70xx.c", + "${efr32_sdk_root}/platform/common/src/sl_status.c", + "${efr32_sdk_root}/platform/driver/i2cspm/src/sl_i2cspm.c", + "${efr32_sdk_root}/platform/emlib/src/em_i2c.c", + "${sdk_support_root}/matter/efr32/${silabs_family}/${silabs_board}/autogen/sl_i2cspm_init.c", + ] + } + public_deps = [ ":efr32_mbedtls_config", "${segger_rtt_root}:segger_rtt", diff --git a/third_party/silabs/matter_support b/third_party/silabs/matter_support index c3e993cea4..841d43db7e 160000 --- a/third_party/silabs/matter_support +++ b/third_party/silabs/matter_support @@ -1 +1 @@ -Subproject commit c3e993cea4aad32adc178fe487afb66822f0b42d +Subproject commit 841d43db7e86877636cd73b5244da4c34d38d544 diff --git a/third_party/silabs/silabs_board.gni b/third_party/silabs/silabs_board.gni index 213417976d..03b2ea7cb6 100644 --- a/third_party/silabs/silabs_board.gni +++ b/third_party/silabs/silabs_board.gni @@ -53,6 +53,9 @@ declare_args() { # Self-provision enabled use_provision_channel = false + + # Temperature Sensor support + sl_enable_si70xx_sensor = false } declare_args() { @@ -75,6 +78,9 @@ if (silabs_board == "BRD4338A" || silabs_board == "BRD2605A") { silabs_mcu = "SiWG917M111MGTBA" wifi_soc = true + assert(!sl_enable_si70xx_sensor, + "${silabs_board} does not support the si90xx sensor!") + # EFR32 MG24 series ---------- } else if (silabs_board == "BRD4186A" || silabs_board == "BRD4187A") { variant = string_replace(silabs_board, "A", "C") @@ -104,6 +110,9 @@ if (silabs_board == "BRD4338A" || silabs_board == "BRD2605A") { show_qr_code = false disable_lcd = true + assert(!sl_enable_si70xx_sensor, + "${silabs_board} does not support the si90xx sensor!") + # EFR32 MG24 Modules series ---------- } else if (silabs_board == "BRD4316A") { silabs_family = "mgm24" @@ -128,6 +137,9 @@ if (silabs_board == "BRD4338A" || silabs_board == "BRD2605A") { use_external_flash = false show_qr_code = false disable_lcd = true + + assert(!sl_enable_si70xx_sensor, + "${silabs_board} does not support the si90xx sensor!") } else if (silabs_board == "BRD2704A") { silabs_family = "mgm24" silabs_mcu = "MGM240PB32VNA" @@ -137,6 +149,9 @@ if (silabs_board == "BRD4338A" || silabs_board == "BRD2605A") { use_external_flash = false show_qr_code = false disable_lcd = true + + assert(!sl_enable_si70xx_sensor, + "${silabs_board} does not support the si90xx sensor!") } else if (silabs_board == "BRD4318A") { silabs_family = "mgm24" silabs_mcu = "MGM240SD22VNA"