From 48a03630b329d7e5d55d8f1efde5f25e69d18d39 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Tue, 6 Aug 2024 16:48:19 -0400 Subject: [PATCH 01/41] Add extra attributes to the bridged device basic info structures, remove nonsense comments --- .../src/BridgedDeviceManager.cpp | 52 +++++++++++++------ 1 file changed, 37 insertions(+), 15 deletions(-) diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp index 170b39cd2c94e2..f6f43ea6edd796 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp @@ -45,8 +45,13 @@ using namespace chip::app::Clusters; namespace { -constexpr uint8_t kMaxRetries = 10; -constexpr int kNodeLabelSize = 32; +constexpr uint8_t kMaxRetries = 10; +constexpr int kNodeLabelSize = 32; +constexpr int kUniqueIdSize = 32; +constexpr int kVendorNameSize = 32; +constexpr int kProductNameSize = 32; +constexpr int kHardwareVersionSize = 32; +constexpr int kSoftwareVersionSize = 32; // Current ZCL implementation of Struct uses a max-size array of 254 bytes constexpr int kDescriptorAttributeArraySize = 254; @@ -76,27 +81,44 @@ constexpr int kDescriptorAttributeArraySize = 254; // - Bridged Device Basic Information // - Administrator Commissioning +// clang-format off // Declare Descriptor cluster attributes DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(descriptorAttrs) -DECLARE_DYNAMIC_ATTRIBUTE(Descriptor::Attributes::DeviceTypeList::Id, ARRAY, kDescriptorAttributeArraySize, 0), /* device list */ - DECLARE_DYNAMIC_ATTRIBUTE(Descriptor::Attributes::ServerList::Id, ARRAY, kDescriptorAttributeArraySize, 0), /* server list */ - DECLARE_DYNAMIC_ATTRIBUTE(Descriptor::Attributes::ClientList::Id, ARRAY, kDescriptorAttributeArraySize, 0), /* client list */ - DECLARE_DYNAMIC_ATTRIBUTE(Descriptor::Attributes::PartsList::Id, ARRAY, kDescriptorAttributeArraySize, 0), /* parts list */ - DECLARE_DYNAMIC_ATTRIBUTE_LIST_END(); + DECLARE_DYNAMIC_ATTRIBUTE(Descriptor::Attributes::DeviceTypeList::Id, ARRAY, kDescriptorAttributeArraySize, 0), /* device list */ + DECLARE_DYNAMIC_ATTRIBUTE(Descriptor::Attributes::ServerList::Id, ARRAY, kDescriptorAttributeArraySize, 0), /* server list */ + DECLARE_DYNAMIC_ATTRIBUTE(Descriptor::Attributes::ClientList::Id, ARRAY, kDescriptorAttributeArraySize, 0), /* client list */ + DECLARE_DYNAMIC_ATTRIBUTE(Descriptor::Attributes::PartsList::Id, ARRAY, kDescriptorAttributeArraySize, 0), /* parts list */ +DECLARE_DYNAMIC_ATTRIBUTE_LIST_END(); // Declare Bridged Device Basic Information cluster attributes DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(bridgedDeviceBasicAttrs) -DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::NodeLabel::Id, CHAR_STRING, kNodeLabelSize, 0), /* NodeLabel */ - DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::Reachable::Id, BOOLEAN, 1, 0), /* Reachable */ - DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::FeatureMap::Id, BITMAP32, 4, 0), /* feature map */ - DECLARE_DYNAMIC_ATTRIBUTE_LIST_END(); + // The attributes below are MANDATORY in the Bridged Device Information Cluster + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::Reachable::Id, BOOLEAN, 1, 0), + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::UniqueID::Id, CHAR_STRING, kUniqueIdSize, 0), + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::FeatureMap::Id, BITMAP32, 4, 0), + + // The attributes below are OPTIONAL in the bridged device, however they are MANDATORY in the BasicInformation cluster + // so they can always be provided if desired + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::VendorName::Id, CHAR_STRING, kVendorNameSize, 0), + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::VendorID::Id, INT16U, 2, 0), + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::ProductName::Id, CHAR_STRING, kProductNameSize, 0), + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::ProductID::Id, INT16U, 2, 0), + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::NodeLabel::Id, CHAR_STRING, kNodeLabelSize, 0), + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::HardwareVersion::Id, INT16U, 2, 0), + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::HardwareVersionString::Id, CHAR_STRING, + kHardwareVersionSize, 0), + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::SoftwareVersion::Id, INT16U, 2, 0), + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::SoftwareVersionString::Id, CHAR_STRING, + kSoftwareVersionSize, 0), +DECLARE_DYNAMIC_ATTRIBUTE_LIST_END(); // Declare Administrator Commissioning cluster attributes DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(AdministratorCommissioningAttrs) -DECLARE_DYNAMIC_ATTRIBUTE(AdministratorCommissioning::Attributes::WindowStatus::Id, ENUM8, 1, 0), /* NodeLabel */ - DECLARE_DYNAMIC_ATTRIBUTE(AdministratorCommissioning::Attributes::AdminFabricIndex::Id, FABRIC_IDX, 1, 0), /* Reachable */ - DECLARE_DYNAMIC_ATTRIBUTE(AdministratorCommissioning::Attributes::AdminVendorId::Id, VENDOR_ID, 2, 0), /* Reachable */ - DECLARE_DYNAMIC_ATTRIBUTE_LIST_END(); + DECLARE_DYNAMIC_ATTRIBUTE(AdministratorCommissioning::Attributes::WindowStatus::Id, ENUM8, 1, 0), + DECLARE_DYNAMIC_ATTRIBUTE(AdministratorCommissioning::Attributes::AdminFabricIndex::Id, FABRIC_IDX, 1, 0), + DECLARE_DYNAMIC_ATTRIBUTE(AdministratorCommissioning::Attributes::AdminVendorId::Id, VENDOR_ID, 2, 0), +DECLARE_DYNAMIC_ATTRIBUTE_LIST_END(); +// clang-format on constexpr CommandId administratorCommissioningCommands[] = { app::Clusters::AdministratorCommissioning::Commands::OpenCommissioningWindow::Id, From c37cd56e3a9dad5f8daad39b09a8de00771aa26b Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 08:37:08 -0400 Subject: [PATCH 02/41] Make use of AAI for BridgedDeviceBasicInformation cluster --- .../fabric-bridge-common/BUILD.gn | 3 +- .../BridgedDeviceBasicInformationImpl.h | 32 +++++++ .../src/BridgedDeviceBasicInformationImpl.cpp | 78 ++++++++++++++++ .../fabric-bridge-common/src/ZCLCallbacks.cpp | 91 ------------------- examples/fabric-bridge-app/linux/main.cpp | 4 + 5 files changed, 116 insertions(+), 92 deletions(-) create mode 100644 examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDeviceBasicInformationImpl.h create mode 100644 examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceBasicInformationImpl.cpp delete mode 100644 examples/fabric-bridge-app/fabric-bridge-common/src/ZCLCallbacks.cpp diff --git a/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn b/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn index 10cb48c31c584e..855bb48f77a53e 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn +++ b/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn @@ -29,12 +29,13 @@ source_set("fabric-bridge-lib") { public_configs = [ ":config" ] sources = [ + "include/BridgedDeviceBasicInformationImpl.h", "include/BridgedDevice.h", "include/BridgedDeviceManager.h", "include/CHIPProjectAppConfig.h", + "src/BridgedDeviceBasicInformationImpl.cpp", "src/BridgedDevice.cpp", "src/BridgedDeviceManager.cpp", - "src/ZCLCallbacks.cpp", ] deps = [ diff --git a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDeviceBasicInformationImpl.h b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDeviceBasicInformationImpl.h new file mode 100644 index 00000000000000..23403438ab2be8 --- /dev/null +++ b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDeviceBasicInformationImpl.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2024 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. + */ +#pragma once + +#include <app-common/zap-generated/ids/Clusters.h> +#include <app/AttributeAccessInterface.h> + +class BridgedDeviceBasicInformationImpl : public chip::app::AttributeAccessInterface +{ +public: + BridgedDeviceBasicInformationImpl() : + chip::app::AttributeAccessInterface(chip::NullOptional /* endpointId */, + chip::app::Clusters::BridgedDeviceBasicInformation::Id) + {} + + // AttributeAccessInterface implementation + CHIP_ERROR Read(const chip::app::ConcreteReadAttributePath & path, chip::app::AttributeValueEncoder & encoder) override; + CHIP_ERROR Write(const chip::app::ConcreteDataAttributePath & path, chip::app::AttributeValueDecoder & decoder) override; +}; diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceBasicInformationImpl.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceBasicInformationImpl.cpp new file mode 100644 index 00000000000000..cf35230dc1e155 --- /dev/null +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceBasicInformationImpl.cpp @@ -0,0 +1,78 @@ +/* + * Copyright (c) 2024 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. + */ +#include "BridgedDeviceBasicInformationImpl.h" + +#include "BridgedDeviceManager.h" + +#include <app-common/zap-generated/cluster-objects.h> +#include <app-common/zap-generated/ids/Attributes.h> +#include <app-common/zap-generated/ids/Clusters.h> + +#include <app/AttributeAccessInterfaceRegistry.h> + +static constexpr unsigned kBridgedDeviceBasicInformationClusterRevision = 2; +static constexpr unsigned kBridgedDeviceBasicInformationFeatureMap = 0; + +using namespace ::chip; +using namespace ::chip::app; +using namespace ::chip::app::Clusters; + +CHIP_ERROR BridgedDeviceBasicInformationImpl::Read(const ConcreteReadAttributePath & path, AttributeValueEncoder & encoder) +{ + // Registration is done for the bridged device basic information only + VerifyOrDie(path.mClusterId == app::Clusters::BridgedDeviceBasicInformation::Id); + + BridgedDevice * dev = BridgeDeviceMgr().GetDevice(path.mEndpointId); + VerifyOrReturnError(dev != nullptr, CHIP_ERROR_NOT_FOUND); + + switch (path.mAttributeId) + { + case BasicInformation::Attributes::Reachable::Id: + encoder.Encode(dev->IsReachable()); + break; + case BasicInformation::Attributes::NodeLabel::Id: + encoder.Encode(CharSpan::fromCharString(dev->GetName())); + break; + case BasicInformation::Attributes::ClusterRevision::Id: + encoder.Encode(kBridgedDeviceBasicInformationClusterRevision); + break; + case BasicInformation::Attributes::FeatureMap::Id: + encoder.Encode(kBridgedDeviceBasicInformationFeatureMap); + break; + default: + return CHIP_ERROR_INVALID_ARGUMENT; + } + return CHIP_NO_ERROR; +} + +CHIP_ERROR BridgedDeviceBasicInformationImpl::Write(const ConcreteDataAttributePath & path, AttributeValueDecoder & decoder) +{ + VerifyOrDie(path.mClusterId == app::Clusters::BridgedDeviceBasicInformation::Id); + + BridgedDevice * dev = BridgeDeviceMgr().GetDevice(path.mEndpointId); + VerifyOrReturnError(dev != nullptr, CHIP_ERROR_NOT_FOUND); + + if (!dev->IsReachable()) + { + return CHIP_ERROR_NOT_CONNECTED; + } + + ChipLogProgress(NotSpecified, "Bridged device basic information attempt to write attribute: ep=%d", path.mAttributeId); + + // nothing writable right now ... + + return CHIP_ERROR_INVALID_ARGUMENT; +} diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/ZCLCallbacks.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/ZCLCallbacks.cpp deleted file mode 100644 index 9a0467be4e27e8..00000000000000 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/ZCLCallbacks.cpp +++ /dev/null @@ -1,91 +0,0 @@ -/* - * - * Copyright (c) 2024 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. - */ - -#include "BridgedDeviceManager.h" - -#include <app-common/zap-generated/cluster-objects.h> -#include <app-common/zap-generated/ids/Attributes.h> -#include <app-common/zap-generated/ids/Clusters.h> -#include <lib/support/ZclString.h> - -using namespace ::chip; -using namespace ::chip::app::Clusters; - -#define ZCL_DESCRIPTOR_CLUSTER_REVISION (1u) -#define ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_CLUSTER_REVISION (2u) -#define ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_FEATURE_MAP (0u) - -// External attribute read callback function -Protocols::InteractionModel::Status emberAfExternalAttributeReadCallback(EndpointId endpoint, ClusterId clusterId, - const EmberAfAttributeMetadata * attributeMetadata, - uint8_t * buffer, uint16_t maxReadLength) -{ - AttributeId attributeId = attributeMetadata->attributeId; - - BridgedDevice * dev = BridgeDeviceMgr().GetDevice(endpoint); - if (dev != nullptr && clusterId == app::Clusters::BridgedDeviceBasicInformation::Id) - { - using namespace app::Clusters::BridgedDeviceBasicInformation::Attributes; - ChipLogProgress(NotSpecified, "HandleReadBridgedDeviceBasicAttribute: attrId=%d, maxReadLength=%d", attributeId, - maxReadLength); - - if ((attributeId == Reachable::Id) && (maxReadLength == 1)) - { - *buffer = dev->IsReachable() ? 1 : 0; - } - else if ((attributeId == NodeLabel::Id) && (maxReadLength == 32)) - { - MutableByteSpan zclNameSpan(buffer, maxReadLength); - MakeZclCharString(zclNameSpan, dev->GetName()); - } - else if ((attributeId == ClusterRevision::Id) && (maxReadLength == 2)) - { - uint16_t rev = ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_CLUSTER_REVISION; - memcpy(buffer, &rev, sizeof(rev)); - } - else if ((attributeId == FeatureMap::Id) && (maxReadLength == 4)) - { - uint32_t featureMap = ZCL_BRIDGED_DEVICE_BASIC_INFORMATION_FEATURE_MAP; - memcpy(buffer, &featureMap, sizeof(featureMap)); - } - else - { - return Protocols::InteractionModel::Status::Failure; - } - return Protocols::InteractionModel::Status::Success; - } - - return Protocols::InteractionModel::Status::Failure; -} - -// External attribute write callback function -Protocols::InteractionModel::Status emberAfExternalAttributeWriteCallback(EndpointId endpoint, ClusterId clusterId, - const EmberAfAttributeMetadata * attributeMetadata, - uint8_t * buffer) -{ - uint16_t endpointIndex = emberAfGetDynamicIndexFromEndpoint(endpoint); - Protocols::InteractionModel::Status ret = Protocols::InteractionModel::Status::Failure; - - BridgedDevice * dev = BridgeDeviceMgr().GetDevice(endpointIndex); - if (dev != nullptr && dev->IsReachable()) - { - ChipLogProgress(NotSpecified, "emberAfExternalAttributeWriteCallback: ep=%d, clusterId=%d", endpoint, clusterId); - ret = Protocols::InteractionModel::Status::Success; - } - - return ret; -} diff --git a/examples/fabric-bridge-app/linux/main.cpp b/examples/fabric-bridge-app/linux/main.cpp index c708b256727520..24ad4aa9a1690c 100644 --- a/examples/fabric-bridge-app/linux/main.cpp +++ b/examples/fabric-bridge-app/linux/main.cpp @@ -19,6 +19,7 @@ #include <AppMain.h> #include "BridgedDevice.h" +#include "BridgedDeviceBasicInformationImpl.h" #include "BridgedDeviceManager.h" #include "CommissionableInit.h" @@ -48,6 +49,8 @@ constexpr uint16_t kPollIntervalMs = 100; constexpr uint16_t kRetryIntervalS = 3; #endif +BridgedDeviceBasicInformationImpl gBridgedDeviceBasicInformationAttributes; + bool KeyboardHit() { int bytesWaiting; @@ -175,6 +178,7 @@ void ApplicationInit() ChipLogDetail(NotSpecified, "Fabric-Bridge: ApplicationInit()"); CommandHandlerInterfaceRegistry::RegisterCommandHandler(&gAdministratorCommissioningCommandHandler); + registerAttributeAccessOverride(&gBridgedDeviceBasicInformationAttributes); #if defined(PW_RPC_FABRIC_BRIDGE_SERVICE) && PW_RPC_FABRIC_BRIDGE_SERVICE InitRpcServer(kFabricBridgeServerPort); From 530691d30c1b5948350275d06bfb73e8081bf81d Mon Sep 17 00:00:00 2001 From: "Restyled.io" <commits@restyled.io> Date: Wed, 7 Aug 2024 12:40:00 +0000 Subject: [PATCH 03/41] Restyled by gn --- examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn b/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn index 855bb48f77a53e..60bf58115e416f 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn +++ b/examples/fabric-bridge-app/fabric-bridge-common/BUILD.gn @@ -29,12 +29,12 @@ source_set("fabric-bridge-lib") { public_configs = [ ":config" ] sources = [ - "include/BridgedDeviceBasicInformationImpl.h", "include/BridgedDevice.h", + "include/BridgedDeviceBasicInformationImpl.h", "include/BridgedDeviceManager.h", "include/CHIPProjectAppConfig.h", - "src/BridgedDeviceBasicInformationImpl.cpp", "src/BridgedDevice.cpp", + "src/BridgedDeviceBasicInformationImpl.cpp", "src/BridgedDeviceManager.cpp", ] From a7240c827c3f45901cf940b652b9749b3a790b8a Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 08:55:04 -0400 Subject: [PATCH 04/41] Fix sizes for software version --- .../fabric-bridge-common/src/BridgedDeviceManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp index f6f43ea6edd796..7e78baa7ded548 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp @@ -107,7 +107,7 @@ DECLARE_DYNAMIC_ATTRIBUTE_LIST_BEGIN(bridgedDeviceBasicAttrs) DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::HardwareVersion::Id, INT16U, 2, 0), DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::HardwareVersionString::Id, CHAR_STRING, kHardwareVersionSize, 0), - DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::SoftwareVersion::Id, INT16U, 2, 0), + DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::SoftwareVersion::Id, INT32U, 4, 0), DECLARE_DYNAMIC_ATTRIBUTE(BridgedDeviceBasicInformation::Attributes::SoftwareVersionString::Id, CHAR_STRING, kSoftwareVersionSize, 0), DECLARE_DYNAMIC_ATTRIBUTE_LIST_END(); From eb9585402efa3f8e59cfac662d5aae352e45f1f8 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 08:55:48 -0400 Subject: [PATCH 05/41] Update the synchronized device proto to have more data in it --- examples/common/pigweed/BUILD.gn | 1 + .../pigweed/protos/fabric_bridge_service.options | 6 ++++++ .../common/pigweed/protos/fabric_bridge_service.proto | 11 +++++++++++ 3 files changed, 18 insertions(+) create mode 100644 examples/common/pigweed/protos/fabric_bridge_service.options diff --git a/examples/common/pigweed/BUILD.gn b/examples/common/pigweed/BUILD.gn index 6252f86e637890..a7b7d97da32ba6 100644 --- a/examples/common/pigweed/BUILD.gn +++ b/examples/common/pigweed/BUILD.gn @@ -90,6 +90,7 @@ pw_proto_library("fabric_admin_service") { pw_proto_library("fabric_bridge_service") { sources = [ "protos/fabric_bridge_service.proto" ] + inputs = [ "protos/fabric_bridge_service.options" ] deps = [ "$dir_pw_protobuf:common_protos" ] strip_prefix = "protos" prefix = "fabric_bridge_service" diff --git a/examples/common/pigweed/protos/fabric_bridge_service.options b/examples/common/pigweed/protos/fabric_bridge_service.options new file mode 100644 index 00000000000000..d5ad57e57d6447 --- /dev/null +++ b/examples/common/pigweed/protos/fabric_bridge_service.options @@ -0,0 +1,6 @@ +chip.rpc.SynchronizedDevice.unique_id max_size:32 +chip.rpc.SynchronizedDevice.vendor_name max_size:32 +chip.rpc.SynchronizedDevice.product_name max_size:32 +chip.rpc.SynchronizedDevice.node_label max_size:32 +chip.rpc.SynchronizedDevice.hardware_version_string max_size:32 +chip.rpc.SynchronizedDevice.software_version_string max_size:32 diff --git a/examples/common/pigweed/protos/fabric_bridge_service.proto b/examples/common/pigweed/protos/fabric_bridge_service.proto index 10e5ccf888583d..120bfdb88ccfcc 100644 --- a/examples/common/pigweed/protos/fabric_bridge_service.proto +++ b/examples/common/pigweed/protos/fabric_bridge_service.proto @@ -7,6 +7,17 @@ package chip.rpc; // Define the message for a synchronized end device with necessary fields message SynchronizedDevice { uint64 node_id = 1; + + string unique_id = 2; + string vendor_name = 3; + uint32 vendor_id = 4; + string product_name = 5; + uint32 product_id = 6; + string node_label = 7; + uint32 hardware_version = 8; + string hardware_version_string = 9; + uint32 software_version = 10; + string software_version_string = 11; } service FabricBridge { From 1356b1f44fd1652436979b682412b55cfa87aae6 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 09:10:04 -0400 Subject: [PATCH 06/41] Switch to unique ptr in the registry, making sure memory management works (fixed memory leak on remove device) --- .../include/BridgedDeviceManager.h | 9 ++- .../src/BridgedDeviceManager.cpp | 76 +++++++++---------- .../fabric-bridge-app/linux/RpcServer.cpp | 7 +- 3 files changed, 45 insertions(+), 47 deletions(-) diff --git a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDeviceManager.h b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDeviceManager.h index 8411ec656f9803..134ab308f000b2 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDeviceManager.h +++ b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDeviceManager.h @@ -22,6 +22,8 @@ #include "BridgedDevice.h" +#include <memory> + class BridgedDeviceManager { public: @@ -45,9 +47,10 @@ class BridgedDeviceManager * * @param dev A pointer to the device to be added. * @param parentEndpointId The parent endpoint ID. Defaults to an invalid endpoint ID. - * @return int The index of the dynamic endpoint if successful, -1 otherwise. + * @return int The index of the dynamic endpoint if successful, nullopt otherwise */ - int AddDeviceEndpoint(BridgedDevice * dev, chip::EndpointId parentEndpointId = chip::kInvalidEndpointId); + std::optional<unsigned> AddDeviceEndpoint(std::unique_ptr<BridgedDevice> dev, + chip::EndpointId parentEndpointId = chip::kInvalidEndpointId); /** * @brief Removes a device from a dynamic endpoint. @@ -104,7 +107,7 @@ class BridgedDeviceManager chip::EndpointId mCurrentEndpointId; chip::EndpointId mFirstDynamicEndpointId; - BridgedDevice * mDevices[CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT + 1]; + std::unique_ptr<BridgedDevice> mDevices[CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT + 1]; }; /** diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp index f6f43ea6edd796..4ad555dbdd886a 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp @@ -33,6 +33,7 @@ #include <lib/support/ZclString.h> #include <cstdio> +#include <optional> #include <string> using namespace chip; @@ -147,60 +148,55 @@ BridgedDeviceManager BridgedDeviceManager::sInstance; void BridgedDeviceManager::Init() { - memset(mDevices, 0, sizeof(mDevices)); mFirstDynamicEndpointId = static_cast<chip::EndpointId>( static_cast<int>(emberAfEndpointFromIndex(static_cast<uint16_t>(emberAfFixedEndpointCount() - 1))) + 1); mCurrentEndpointId = mFirstDynamicEndpointId; } -int BridgedDeviceManager::AddDeviceEndpoint(BridgedDevice * dev, chip::EndpointId parentEndpointId) +std::optional<unsigned> BridgedDeviceManager::AddDeviceEndpoint(std::unique_ptr<BridgedDevice> dev, + chip::EndpointId parentEndpointId) { - uint8_t index = 0; EmberAfEndpointType * ep = &sBridgedNodeEndpoint; const chip::Span<const EmberAfDeviceType> & deviceTypeList = Span<const EmberAfDeviceType>(sBridgedDeviceTypes); const chip::Span<chip::DataVersion> & dataVersionStorage = Span<DataVersion>(sBridgedNodeDataVersions); - while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) + for (unsigned index = 0; index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; index++) { - if (nullptr == mDevices[index]) + if (mDevices[index]) + { + continue; + } + + for (int retryCount = 0; retryCount < kMaxRetries; retryCount++) { - mDevices[index] = dev; - CHIP_ERROR err; - int retryCount = 0; - while (retryCount < kMaxRetries) + DeviceLayer::StackLock lock; + dev->SetEndpointId(mCurrentEndpointId); + dev->SetParentEndpointId(parentEndpointId); + CHIP_ERROR err = + emberAfSetDynamicEndpoint(index, mCurrentEndpointId, ep, dataVersionStorage, deviceTypeList, parentEndpointId); + if (err == CHIP_NO_ERROR) { - DeviceLayer::StackLock lock; - dev->SetEndpointId(mCurrentEndpointId); - dev->SetParentEndpointId(parentEndpointId); - err = - emberAfSetDynamicEndpoint(index, mCurrentEndpointId, ep, dataVersionStorage, deviceTypeList, parentEndpointId); - if (err == CHIP_NO_ERROR) - { - ChipLogProgress(NotSpecified, - "Added device with nodeId=0x" ChipLogFormatX64 " to dynamic endpoint %d (index=%d)", - ChipLogValueX64(dev->GetNodeId()), mCurrentEndpointId, index); - return index; - } - if (err != CHIP_ERROR_ENDPOINT_EXISTS) - { - mDevices[index] = nullptr; - return -1; // Return error as endpoint addition failed due to an error other than endpoint already exists - } - // Increment the endpoint ID and handle wrap condition - if (++mCurrentEndpointId < mFirstDynamicEndpointId) - { - mCurrentEndpointId = mFirstDynamicEndpointId; - } - retryCount++; + ChipLogProgress(NotSpecified, "Added device with nodeId=0x" ChipLogFormatX64 " to dynamic endpoint %d (index=%d)", + ChipLogValueX64(dev->GetNodeId()), mCurrentEndpointId, index); + mDevices[index] = std::move(dev); + return index; + } + if (err != CHIP_ERROR_ENDPOINT_EXISTS) + { + return std::nullopt; // Return error as endpoint addition failed due to an error other than endpoint already exists + } + // Increment the endpoint ID and handle wrap condition + if (++mCurrentEndpointId < mFirstDynamicEndpointId) + { + mCurrentEndpointId = mFirstDynamicEndpointId; } - ChipLogError(NotSpecified, "Failed to add dynamic endpoint after %d retries", kMaxRetries); - mDevices[index] = nullptr; - return -1; // Return error as all retries are exhausted } - index++; + ChipLogError(NotSpecified, "Failed to add dynamic endpoint after %d retries", kMaxRetries); + return std::nullopt; // Return error as all retries are exhausted } + ChipLogProgress(NotSpecified, "Failed to add dynamic endpoint: No endpoints available!"); - return -1; + return std::nullopt; } int BridgedDeviceManager::RemoveDeviceEndpoint(BridgedDevice * dev) @@ -208,7 +204,7 @@ int BridgedDeviceManager::RemoveDeviceEndpoint(BridgedDevice * dev) uint8_t index = 0; while (index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT) { - if (mDevices[index] == dev) + if (mDevices[index].get() == dev) { DeviceLayer::StackLock lock; // Silence complaints about unused ep when progress logging @@ -229,7 +225,7 @@ BridgedDevice * BridgedDeviceManager::GetDevice(chip::EndpointId endpointId) con { if (mDevices[index] && mDevices[index]->GetEndpointId() == endpointId) { - return mDevices[index]; + return mDevices[index].get(); } } return nullptr; @@ -241,7 +237,7 @@ BridgedDevice * BridgedDeviceManager::GetDeviceByNodeId(chip::NodeId nodeId) con { if (mDevices[index] && mDevices[index]->GetNodeId() == nodeId) { - return mDevices[index]; + return mDevices[index].get(); } } return nullptr; diff --git a/examples/fabric-bridge-app/linux/RpcServer.cpp b/examples/fabric-bridge-app/linux/RpcServer.cpp index 76fe8f84653d39..20730c3f98071b 100644 --- a/examples/fabric-bridge-app/linux/RpcServer.cpp +++ b/examples/fabric-bridge-app/linux/RpcServer.cpp @@ -51,13 +51,12 @@ pw::Status FabricBridge::AddSynchronizedDevice(const chip_rpc_SynchronizedDevice NodeId nodeId = request.node_id; ChipLogProgress(NotSpecified, "Received AddSynchronizedDevice: " ChipLogFormatX64, ChipLogValueX64(nodeId)); - BridgedDevice * device = new BridgedDevice(nodeId); + auto device = std::make_unique<BridgedDevice>(nodeId); device->SetReachable(true); - int result = BridgeDeviceMgr().AddDeviceEndpoint(device, 1); - if (result == -1) + auto result = BridgeDeviceMgr().AddDeviceEndpoint(std::move(device), 1 /* parentEndpointId */); + if (!result.has_value()) { - delete device; ChipLogError(NotSpecified, "Failed to add device with nodeId=0x" ChipLogFormatX64, ChipLogValueX64(nodeId)); return pw::Status::Unknown(); } From 3d063059db6499bfbf87f7259ce087298d5fef57 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 09:12:18 -0400 Subject: [PATCH 07/41] Use more std::optional --- .../fabric-bridge-common/include/BridgedDeviceManager.h | 2 +- .../fabric-bridge-common/src/BridgedDeviceManager.cpp | 6 +++--- examples/fabric-bridge-app/linux/RpcServer.cpp | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDeviceManager.h b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDeviceManager.h index 134ab308f000b2..6c2829a8a4bb38 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDeviceManager.h +++ b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDeviceManager.h @@ -98,7 +98,7 @@ class BridgedDeviceManager * @param nodeId The NodeId of the device to be removed. * @return int The index of the removed dynamic endpoint if successful, -1 otherwise. */ - int RemoveDeviceByNodeId(chip::NodeId nodeId); + std::optional<unsigned> RemoveDeviceByNodeId(chip::NodeId nodeId); private: friend BridgedDeviceManager & BridgeDeviceMgr(); diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp index 4ad555dbdd886a..10b6055b3d635b 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp @@ -243,9 +243,9 @@ BridgedDevice * BridgedDeviceManager::GetDeviceByNodeId(chip::NodeId nodeId) con return nullptr; } -int BridgedDeviceManager::RemoveDeviceByNodeId(chip::NodeId nodeId) +std::optional<unsigned> BridgedDeviceManager::RemoveDeviceByNodeId(chip::NodeId nodeId) { - for (uint8_t index = 0; index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; ++index) + for (unsigned index = 0; index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; ++index) { if (mDevices[index] && mDevices[index]->GetNodeId() == nodeId) { @@ -257,5 +257,5 @@ int BridgedDeviceManager::RemoveDeviceByNodeId(chip::NodeId nodeId) return index; } } - return -1; + return std::nullopt; } diff --git a/examples/fabric-bridge-app/linux/RpcServer.cpp b/examples/fabric-bridge-app/linux/RpcServer.cpp index 20730c3f98071b..b04ec3b3c35187 100644 --- a/examples/fabric-bridge-app/linux/RpcServer.cpp +++ b/examples/fabric-bridge-app/linux/RpcServer.cpp @@ -69,8 +69,8 @@ pw::Status FabricBridge::RemoveSynchronizedDevice(const chip_rpc_SynchronizedDev NodeId nodeId = request.node_id; ChipLogProgress(NotSpecified, "Received RemoveSynchronizedDevice: " ChipLogFormatX64, ChipLogValueX64(nodeId)); - int removed_idx = BridgeDeviceMgr().RemoveDeviceByNodeId(nodeId); - if (removed_idx < 0) + auto removed_idx = BridgeDeviceMgr().RemoveDeviceByNodeId(nodeId); + if (!removed_idx.has_value()) { ChipLogError(NotSpecified, "Failed to remove device with nodeId=0x" ChipLogFormatX64, ChipLogValueX64(nodeId)); return pw::Status::NotFound(); From ece219b382e45eacf1d14a52cc14abcbd68072f7 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 09:12:57 -0400 Subject: [PATCH 08/41] Bump revision to 4 --- .../src/BridgedDeviceBasicInformationImpl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceBasicInformationImpl.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceBasicInformationImpl.cpp index cf35230dc1e155..62630d730b4355 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceBasicInformationImpl.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceBasicInformationImpl.cpp @@ -23,7 +23,7 @@ #include <app/AttributeAccessInterfaceRegistry.h> -static constexpr unsigned kBridgedDeviceBasicInformationClusterRevision = 2; +static constexpr unsigned kBridgedDeviceBasicInformationClusterRevision = 4; static constexpr unsigned kBridgedDeviceBasicInformationFeatureMap = 0; using namespace ::chip; From 9f20d0fedebcec541d912bfeb241debabe8d9aee Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 09:29:10 -0400 Subject: [PATCH 09/41] Forward attributes from the create call into the bridged device --- .../include/BridgedDevice.h | 28 +++++++++++++------ .../src/BridgedDevice.cpp | 10 ++----- .../src/BridgedDeviceBasicInformationImpl.cpp | 2 +- .../src/BridgedDeviceManager.cpp | 3 +- .../fabric-bridge-app/linux/RpcServer.cpp | 15 ++++++++++ 5 files changed, 40 insertions(+), 18 deletions(-) diff --git a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h index a237d93d133eb7..78c5caa79aa316 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h +++ b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h @@ -30,31 +30,43 @@ class BridgedDevice { public: - static const int kDeviceNameSize = 32; + /// Defines all attributes that we keep track of for a bridged device + struct BridgedAttributes + { + std::string uniqueId; + std::string vendorName; + uint16_t vendorId = 0; + std::string productName; + uint16_t productId = 0; + std::string nodeLabel; + uint16_t hardwareVersion = 0; + std::string hardwareVersionString; + uint32_t softwareVersion = 0; + std::string softwareVersionString; + }; BridgedDevice(chip::NodeId nodeId); virtual ~BridgedDevice() {} bool IsReachable(); void SetReachable(bool reachable); - void SetName(const char * name); - void SetLocation(std::string location) { mLocation = location; }; + inline void SetEndpointId(chip::EndpointId id) { mEndpointId = id; }; inline chip::EndpointId GetEndpointId() { return mEndpointId; }; inline chip::NodeId GetNodeId() { return mNodeId; }; inline void SetParentEndpointId(chip::EndpointId id) { mParentEndpointId = id; }; inline chip::EndpointId GetParentEndpointId() { return mParentEndpointId; }; - inline char * GetName() { return mName; }; - inline std::string GetLocation() { return mLocation; }; - inline std::string GetZone() { return mZone; }; - inline void SetZone(std::string zone) { mZone = zone; }; + + const BridgedAttributes & GetBridgedAttributes() const { return mAttributes; } + void SetBridgedAttributes(const BridgedAttributes& value) { mAttributes = value; } protected: bool mReachable; - char mName[kDeviceNameSize]; std::string mLocation; chip::NodeId mNodeId; chip::EndpointId mEndpointId; chip::EndpointId mParentEndpointId; std::string mZone; + + BridgedAttributes mAttributes; }; diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDevice.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDevice.cpp index d641f3743d43f0..48729ac86195ed 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDevice.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDevice.cpp @@ -43,17 +43,11 @@ void BridgedDevice::SetReachable(bool reachable) if (reachable) { - ChipLogProgress(NotSpecified, "BridgedDevice[%s]: ONLINE", mName); + ChipLogProgress(NotSpecified, "BridgedDevice[%s]: ONLINE", mAttributes.uniqueId.c_str()); } else { - ChipLogProgress(NotSpecified, "BridgedDevice[%s]: OFFLINE", mName); + ChipLogProgress(NotSpecified, "BridgedDevice[%s]: OFFLINE", mAttributes.uniqueId.c_str()); } } -void BridgedDevice::SetName(const char * name) -{ - ChipLogProgress(NotSpecified, "BridgedDevice[%s]: New Name=\"%s\"", mName, name); - - chip::Platform::CopyString(mName, name); -} diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceBasicInformationImpl.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceBasicInformationImpl.cpp index 62630d730b4355..7127f8704008e2 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceBasicInformationImpl.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceBasicInformationImpl.cpp @@ -44,7 +44,7 @@ CHIP_ERROR BridgedDeviceBasicInformationImpl::Read(const ConcreteReadAttributePa encoder.Encode(dev->IsReachable()); break; case BasicInformation::Attributes::NodeLabel::Id: - encoder.Encode(CharSpan::fromCharString(dev->GetName())); + encoder.Encode(CharSpan::fromCharString(dev->GetBridgedAttributes().nodeLabel.c_str())); break; case BasicInformation::Attributes::ClusterRevision::Id: encoder.Encode(kBridgedDeviceBasicInformationClusterRevision); diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp index 674f973d3562f0..bb6c3577648a7a 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp @@ -211,7 +211,8 @@ int BridgedDeviceManager::RemoveDeviceEndpoint(BridgedDevice * dev) // disabled. [[maybe_unused]] EndpointId ep = emberAfClearDynamicEndpoint(index); mDevices[index] = nullptr; - ChipLogProgress(NotSpecified, "Removed device %s from dynamic endpoint %d (index=%d)", dev->GetName(), ep, index); + ChipLogProgress(NotSpecified, "Removed device %s from dynamic endpoint %d (index=%d)", + dev->GetBridgedAttributes().uniqueId.c_str(), ep, index); return index; } index++; diff --git a/examples/fabric-bridge-app/linux/RpcServer.cpp b/examples/fabric-bridge-app/linux/RpcServer.cpp index b04ec3b3c35187..20361e8984c6d4 100644 --- a/examples/fabric-bridge-app/linux/RpcServer.cpp +++ b/examples/fabric-bridge-app/linux/RpcServer.cpp @@ -54,6 +54,21 @@ pw::Status FabricBridge::AddSynchronizedDevice(const chip_rpc_SynchronizedDevice auto device = std::make_unique<BridgedDevice>(nodeId); device->SetReachable(true); + BridgedDevice::BridgedAttributes attributes; + + attributes.uniqueId = request.unique_id; + attributes.vendorName = request.vendor_name; + attributes.vendorId = request.vendor_id; + attributes.productName = request.product_name; + attributes.productId = request.product_id; + attributes.nodeLabel = request.node_label; + attributes.hardwareVersion = request.hardware_version; + attributes.hardwareVersionString = request.hardware_version_string; + attributes.softwareVersion = request.software_version; + attributes.softwareVersionString = request.software_version_string; + + device->SetBridgedAttributes(attributes); + auto result = BridgeDeviceMgr().AddDeviceEndpoint(std::move(device), 1 /* parentEndpointId */); if (!result.has_value()) { From 5a1cb33d2f0483b832b1bcf20ac593078184cdab Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 09:33:26 -0400 Subject: [PATCH 10/41] Make attribute mapping actually work --- .../src/BridgedDeviceBasicInformationImpl.cpp | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceBasicInformationImpl.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceBasicInformationImpl.cpp index 7127f8704008e2..c088935df30c59 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceBasicInformationImpl.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceBasicInformationImpl.cpp @@ -52,6 +52,33 @@ CHIP_ERROR BridgedDeviceBasicInformationImpl::Read(const ConcreteReadAttributePa case BasicInformation::Attributes::FeatureMap::Id: encoder.Encode(kBridgedDeviceBasicInformationFeatureMap); break; + case BasicInformation::Attributes::UniqueID::Id: + encoder.Encode(CharSpan::fromCharString(dev->GetBridgedAttributes().uniqueId.c_str())); + break; + case BasicInformation::Attributes::VendorName::Id: + encoder.Encode(CharSpan::fromCharString(dev->GetBridgedAttributes().vendorName.c_str())); + break; + case BasicInformation::Attributes::VendorID::Id: + encoder.Encode(dev->GetBridgedAttributes().vendorId); + break; + case BasicInformation::Attributes::ProductName::Id: + encoder.Encode(CharSpan::fromCharString(dev->GetBridgedAttributes().productName.c_str())); + break; + case BasicInformation::Attributes::ProductID::Id: + encoder.Encode(dev->GetBridgedAttributes().productId); + break; + case BasicInformation::Attributes::HardwareVersion::Id: + encoder.Encode(dev->GetBridgedAttributes().hardwareVersion); + break; + case BasicInformation::Attributes::HardwareVersionString::Id: + encoder.Encode(CharSpan::fromCharString(dev->GetBridgedAttributes().hardwareVersionString.c_str())); + break; + case BasicInformation::Attributes::SoftwareVersion::Id: + encoder.Encode(dev->GetBridgedAttributes().softwareVersion); + break; + case BasicInformation::Attributes::SoftwareVersionString::Id: + encoder.Encode(CharSpan::fromCharString(dev->GetBridgedAttributes().softwareVersionString.c_str())); + break; default: return CHIP_ERROR_INVALID_ARGUMENT; } From 4475143d03d2e3c0463161859fb877af06586d8d Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 09:33:43 -0400 Subject: [PATCH 11/41] Restyle --- .../fabric-bridge-common/include/BridgedDevice.h | 2 +- .../fabric-bridge-common/src/BridgedDevice.cpp | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h index 78c5caa79aa316..e57219f7751b76 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h +++ b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h @@ -58,7 +58,7 @@ class BridgedDevice inline chip::EndpointId GetParentEndpointId() { return mParentEndpointId; }; const BridgedAttributes & GetBridgedAttributes() const { return mAttributes; } - void SetBridgedAttributes(const BridgedAttributes& value) { mAttributes = value; } + void SetBridgedAttributes(const BridgedAttributes & value) { mAttributes = value; } protected: bool mReachable; diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDevice.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDevice.cpp index 48729ac86195ed..425bb4da32e896 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDevice.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDevice.cpp @@ -50,4 +50,3 @@ void BridgedDevice::SetReachable(bool reachable) ChipLogProgress(NotSpecified, "BridgedDevice[%s]: OFFLINE", mAttributes.uniqueId.c_str()); } } - From 152d2259abfb9a7457381f53420b2489dfdf05e1 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 10:03:16 -0400 Subject: [PATCH 12/41] Ensure unique IDs are generated --- .../include/BridgedDevice.h | 13 +++-- .../include/BridgedDeviceManager.h | 17 ++++++- .../src/BridgedDeviceManager.cpp | 49 +++++++++++++++++++ 3 files changed, 71 insertions(+), 8 deletions(-) diff --git a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h index e57219f7751b76..97aef059482fbd 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h +++ b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h @@ -20,12 +20,7 @@ #include <app/util/attribute-storage.h> -#include <stdbool.h> -#include <stdint.h> - -#include <functional> #include <string> -#include <vector> class BridgedDevice { @@ -46,7 +41,7 @@ class BridgedDevice }; BridgedDevice(chip::NodeId nodeId); - virtual ~BridgedDevice() {} + virtual ~BridgedDevice() = default; bool IsReachable(); void SetReachable(bool reachable); @@ -57,9 +52,13 @@ class BridgedDevice inline void SetParentEndpointId(chip::EndpointId id) { mParentEndpointId = id; }; inline chip::EndpointId GetParentEndpointId() { return mParentEndpointId; }; - const BridgedAttributes & GetBridgedAttributes() const { return mAttributes; } + [[nodiscard]] const BridgedAttributes & GetBridgedAttributes() const { return mAttributes; } void SetBridgedAttributes(const BridgedAttributes & value) { mAttributes = value; } + /// Convenience method to set just the unique id of a bridged device as it + /// is one of the few attributes that is not always bulk-set + void SetUniqueId(const std::string &value) { mAttributes.uniqueId = value; } + protected: bool mReachable; std::string mLocation; diff --git a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDeviceManager.h b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDeviceManager.h index 6c2829a8a4bb38..ac28d31edf507c 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDeviceManager.h +++ b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDeviceManager.h @@ -43,7 +43,12 @@ class BridgedDeviceManager * This function attempts to add a device to a dynamic endpoint. It tries to find an available * endpoint slot and retries the addition process up to a specified maximum number of times if * the endpoint already exists. If the addition is successful, it returns the index of the - * dynamic endpoint; otherwise, it returns -1. + * dynamic endpoint; + * + * Ensures that the device has a unique id: + * - device MUST set its unique id if any BEFORE calling this method + * - if no unique id (i.e. empty string), a new unique id will be generated + * - Add will fail if the unique id is not unique * * @param dev A pointer to the device to be added. * @param parentEndpointId The parent endpoint ID. Defaults to an invalid endpoint ID. @@ -100,9 +105,19 @@ class BridgedDeviceManager */ std::optional<unsigned> RemoveDeviceByNodeId(chip::NodeId nodeId); + /** + * Finds the device with the given unique id (if any) + */ + BridgedDevice * GetDeviceByUniqueId(const std::string & id); + private: friend BridgedDeviceManager & BridgeDeviceMgr(); + /** + * Creates a new unique ID that is not used by any other mDevice + */ + std::string GenerateUniqueId(); + static BridgedDeviceManager sInstance; chip::EndpointId mCurrentEndpointId; diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp index bb6c3577648a7a..ea873aa8ef4b27 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp @@ -29,6 +29,7 @@ #include <app/util/attribute-storage.h> #include <app/util/endpoint-config-api.h> #include <app/util/util.h> +#include <crypto/RandUtils.h> #include <lib/support/CHIPMem.h> #include <lib/support/ZclString.h> @@ -160,6 +161,16 @@ std::optional<unsigned> BridgedDeviceManager::AddDeviceEndpoint(std::unique_ptr< const chip::Span<const EmberAfDeviceType> & deviceTypeList = Span<const EmberAfDeviceType>(sBridgedDeviceTypes); const chip::Span<chip::DataVersion> & dataVersionStorage = Span<DataVersion>(sBridgedNodeDataVersions); + if (dev->GetBridgedAttributes().uniqueId.empty()) + { + dev->SetUniqueId(GenerateUniqueId()); + } + else if (GetDeviceByUniqueId(dev->GetBridgedAttributes().uniqueId) != nullptr) + { + ChipLogProgress(NotSpecified, "A device with unique id '%s' already exists", dev->GetBridgedAttributes().uniqueId.c_str()); + return std::nullopt; + } + for (unsigned index = 0; index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; index++) { if (mDevices[index]) @@ -232,6 +243,44 @@ BridgedDevice * BridgedDeviceManager::GetDevice(chip::EndpointId endpointId) con return nullptr; } +std::string BridgedDeviceManager::GenerateUniqueId() +{ + char rand_buffer[kUniqueIdSize + 1]; + memset(rand_buffer, 0, sizeof(rand_buffer)); + + static const char kRandCharChoices[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"; + + while (true) + { + /// for nice viewing, prefix the generated value + memcpy(rand_buffer, "GEN-", 4); + for (unsigned idx = 4; idx < kUniqueIdSize; idx++) + { + rand_buffer[idx] = kRandCharChoices[Crypto::GetRandU8() % (sizeof(kRandCharChoices) - 1)]; + } + + // we know zero-terminated due to the memset + std::string uniqueIdChoice = rand_buffer; + + if (!GetDeviceByUniqueId(uniqueIdChoice)) + { + return uniqueIdChoice; + } + } +} + +BridgedDevice * BridgedDeviceManager::GetDeviceByUniqueId(const std::string & id) +{ + for (uint8_t index = 0; index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; ++index) + { + if (mDevices[index] && mDevices[index]->GetBridgedAttributes().uniqueId == id) + { + return mDevices[index].get(); + } + } + return nullptr; +} + BridgedDevice * BridgedDeviceManager::GetDeviceByNodeId(chip::NodeId nodeId) const { for (uint8_t index = 0; index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; ++index) From c6877c887ca85daf8c5e8840d481a72c9353464c Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 10:03:31 -0400 Subject: [PATCH 13/41] Restyle --- .../fabric-bridge-common/include/BridgedDevice.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h index 97aef059482fbd..cde2055473e44a 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h +++ b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h @@ -57,7 +57,7 @@ class BridgedDevice /// Convenience method to set just the unique id of a bridged device as it /// is one of the few attributes that is not always bulk-set - void SetUniqueId(const std::string &value) { mAttributes.uniqueId = value; } + void SetUniqueId(const std::string & value) { mAttributes.uniqueId = value; } protected: bool mReachable; From 28c8bb3d9f935668f75bfb7db94e8dd7b7430485 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 10:12:07 -0400 Subject: [PATCH 14/41] Increase size to 33 to allow for a null terminator --- .../pigweed/protos/fabric_bridge_service.options | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/common/pigweed/protos/fabric_bridge_service.options b/examples/common/pigweed/protos/fabric_bridge_service.options index d5ad57e57d6447..b52b5cc7367f14 100644 --- a/examples/common/pigweed/protos/fabric_bridge_service.options +++ b/examples/common/pigweed/protos/fabric_bridge_service.options @@ -1,6 +1,6 @@ -chip.rpc.SynchronizedDevice.unique_id max_size:32 -chip.rpc.SynchronizedDevice.vendor_name max_size:32 -chip.rpc.SynchronizedDevice.product_name max_size:32 -chip.rpc.SynchronizedDevice.node_label max_size:32 -chip.rpc.SynchronizedDevice.hardware_version_string max_size:32 -chip.rpc.SynchronizedDevice.software_version_string max_size:32 +chip.rpc.SynchronizedDevice.unique_id max_size:33 +chip.rpc.SynchronizedDevice.vendor_name max_size:33 +chip.rpc.SynchronizedDevice.product_name max_size:33 +chip.rpc.SynchronizedDevice.node_label max_size:33 +chip.rpc.SynchronizedDevice.hardware_version_string max_size:33 +chip.rpc.SynchronizedDevice.software_version_string max_size:33 From 23d61ebeed93af772c3231005b7aa52aa0fa7fff Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 10:15:47 -0400 Subject: [PATCH 15/41] make sure that the rpc structures are initialized --- examples/fabric-admin/rpc/RpcClient.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/fabric-admin/rpc/RpcClient.cpp b/examples/fabric-admin/rpc/RpcClient.cpp index 00ca1204cc1f19..2e992f7b0b2081 100644 --- a/examples/fabric-admin/rpc/RpcClient.cpp +++ b/examples/fabric-admin/rpc/RpcClient.cpp @@ -117,7 +117,7 @@ CHIP_ERROR AddSynchronizedDevice(chip::NodeId nodeId) { ChipLogProgress(NotSpecified, "AddSynchronizedDevice"); - chip_rpc_SynchronizedDevice device; + chip_rpc_SynchronizedDevice device = chip_rpc_SynchronizedDevice_init_default; device.node_id = nodeId; // The RPC call is kept alive until it completes. When a response is received, it will be logged by the handler @@ -137,7 +137,7 @@ CHIP_ERROR RemoveSynchronizedDevice(chip::NodeId nodeId) { ChipLogProgress(NotSpecified, "RemoveSynchronizedDevice"); - chip_rpc_SynchronizedDevice device; + chip_rpc_SynchronizedDevice device = chip_rpc_SynchronizedDevice_init_default; device.node_id = nodeId; // The RPC call is kept alive until it completes. When a response is received, it will be logged by the handler From 6628f5cb41bc561a3d868ec37c3ec886ddb46e35 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 10:17:19 -0400 Subject: [PATCH 16/41] Restyle --- examples/fabric-admin/rpc/RpcClient.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/fabric-admin/rpc/RpcClient.cpp b/examples/fabric-admin/rpc/RpcClient.cpp index 2e992f7b0b2081..9166f482c4cd7e 100644 --- a/examples/fabric-admin/rpc/RpcClient.cpp +++ b/examples/fabric-admin/rpc/RpcClient.cpp @@ -118,7 +118,7 @@ CHIP_ERROR AddSynchronizedDevice(chip::NodeId nodeId) ChipLogProgress(NotSpecified, "AddSynchronizedDevice"); chip_rpc_SynchronizedDevice device = chip_rpc_SynchronizedDevice_init_default; - device.node_id = nodeId; + device.node_id = nodeId; // The RPC call is kept alive until it completes. When a response is received, it will be logged by the handler // function and the call will complete. @@ -138,7 +138,7 @@ CHIP_ERROR RemoveSynchronizedDevice(chip::NodeId nodeId) ChipLogProgress(NotSpecified, "RemoveSynchronizedDevice"); chip_rpc_SynchronizedDevice device = chip_rpc_SynchronizedDevice_init_default; - device.node_id = nodeId; + device.node_id = nodeId; // The RPC call is kept alive until it completes. When a response is received, it will be logged by the handler // function and the call will complete. From 33f25174ade8cac014b52dce8d3274bdcae2e69b Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 10:20:12 -0400 Subject: [PATCH 17/41] Add some fake data to test moving the data around --- examples/fabric-admin/rpc/RpcClient.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/examples/fabric-admin/rpc/RpcClient.cpp b/examples/fabric-admin/rpc/RpcClient.cpp index 9166f482c4cd7e..57e668d127f3cd 100644 --- a/examples/fabric-admin/rpc/RpcClient.cpp +++ b/examples/fabric-admin/rpc/RpcClient.cpp @@ -120,6 +120,17 @@ CHIP_ERROR AddSynchronizedDevice(chip::NodeId nodeId) chip_rpc_SynchronizedDevice device = chip_rpc_SynchronizedDevice_init_default; device.node_id = nodeId; + // TODO: fill this with real data. For now we just add things for testing + strcpy(device.vendor_name, "Test Vendor"); + device.vendor_id = 123; + strcpy(device.product_name, "Test Product"); + device.product_id = 234; + strcpy(device.node_label, "Device Label"); + device.hardware_version = 11; + strcpy(device.hardware_version_string, "Hardware"); + device.software_version = 22; + strcpy(device.software_version_string, "Test 1.4.22"); + // The RPC call is kept alive until it completes. When a response is received, it will be logged by the handler // function and the call will complete. auto call = fabricBridgeClient.AddSynchronizedDevice(device, OnAddDeviceResponseCompleted); From fbb42acc44edd12b7929d7431bc03d583c7bc042 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 10:48:21 -0400 Subject: [PATCH 18/41] Remove unused members that were likely just copied over --- .../fabric-bridge-common/include/BridgedDevice.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h index cde2055473e44a..5c09cfa04d2521 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h +++ b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h @@ -61,11 +61,9 @@ class BridgedDevice protected: bool mReachable; - std::string mLocation; chip::NodeId mNodeId; chip::EndpointId mEndpointId; chip::EndpointId mParentEndpointId; - std::string mZone; BridgedAttributes mAttributes; }; From 4abba221fa516472d9ed076428add324ddc7dc03 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 11:01:23 -0400 Subject: [PATCH 19/41] make the attributes optional --- .../protos/fabric_bridge_service.proto | 20 +++---- examples/fabric-admin/rpc/RpcClient.cpp | 17 ++++++ .../fabric-bridge-app/linux/RpcServer.cpp | 59 +++++++++++++++---- 3 files changed, 76 insertions(+), 20 deletions(-) diff --git a/examples/common/pigweed/protos/fabric_bridge_service.proto b/examples/common/pigweed/protos/fabric_bridge_service.proto index 120bfdb88ccfcc..f2e4fd2f32fe53 100644 --- a/examples/common/pigweed/protos/fabric_bridge_service.proto +++ b/examples/common/pigweed/protos/fabric_bridge_service.proto @@ -8,16 +8,16 @@ package chip.rpc; message SynchronizedDevice { uint64 node_id = 1; - string unique_id = 2; - string vendor_name = 3; - uint32 vendor_id = 4; - string product_name = 5; - uint32 product_id = 6; - string node_label = 7; - uint32 hardware_version = 8; - string hardware_version_string = 9; - uint32 software_version = 10; - string software_version_string = 11; + optional string unique_id = 2; + optional string vendor_name = 3; + optional uint32 vendor_id = 4; + optional string product_name = 5; + optional uint32 product_id = 6; + optional string node_label = 7; + optional uint32 hardware_version = 8; + optional string hardware_version_string = 9; + optional uint32 software_version = 10; + optional string software_version_string = 11; } service FabricBridge { diff --git a/examples/fabric-admin/rpc/RpcClient.cpp b/examples/fabric-admin/rpc/RpcClient.cpp index 57e668d127f3cd..18a170723e9ede 100644 --- a/examples/fabric-admin/rpc/RpcClient.cpp +++ b/examples/fabric-admin/rpc/RpcClient.cpp @@ -122,14 +122,31 @@ CHIP_ERROR AddSynchronizedDevice(chip::NodeId nodeId) // TODO: fill this with real data. For now we just add things for testing strcpy(device.vendor_name, "Test Vendor"); + device.has_vendor_name = true; + device.vendor_id = 123; + device.has_vendor_id = true; + strcpy(device.product_name, "Test Product"); + device.has_product_name = true; + device.product_id = 234; + device.has_product_id = true; + strcpy(device.node_label, "Device Label"); + device.has_node_label = true; + device.hardware_version = 11; + device.has_hardware_version = true; + strcpy(device.hardware_version_string, "Hardware"); + device.has_hardware_version_string = true; + device.software_version = 22; + device.has_software_version = true; + strcpy(device.software_version_string, "Test 1.4.22"); + device.has_software_version_string = true; // The RPC call is kept alive until it completes. When a response is received, it will be logged by the handler // function and the call will complete. diff --git a/examples/fabric-bridge-app/linux/RpcServer.cpp b/examples/fabric-bridge-app/linux/RpcServer.cpp index 20361e8984c6d4..aae7e239b694ef 100644 --- a/examples/fabric-bridge-app/linux/RpcServer.cpp +++ b/examples/fabric-bridge-app/linux/RpcServer.cpp @@ -56,16 +56,55 @@ pw::Status FabricBridge::AddSynchronizedDevice(const chip_rpc_SynchronizedDevice BridgedDevice::BridgedAttributes attributes; - attributes.uniqueId = request.unique_id; - attributes.vendorName = request.vendor_name; - attributes.vendorId = request.vendor_id; - attributes.productName = request.product_name; - attributes.productId = request.product_id; - attributes.nodeLabel = request.node_label; - attributes.hardwareVersion = request.hardware_version; - attributes.hardwareVersionString = request.hardware_version_string; - attributes.softwareVersion = request.software_version; - attributes.softwareVersionString = request.software_version_string; + if (request.has_unique_id) + { + attributes.uniqueId = request.unique_id; + } + + if (request.has_vendor_name) + { + attributes.vendorName = request.vendor_name; + } + + if (request.has_vendor_id) + { + attributes.vendorId = request.vendor_id; + } + + if (request.has_product_name) + { + attributes.productName = request.product_name; + } + + if (request.has_product_id) + { + attributes.productId = request.product_id; + } + + if (request.has_node_label) + { + attributes.nodeLabel = request.node_label; + } + + if (request.has_hardware_version) + { + attributes.hardwareVersion = request.hardware_version; + } + + if (request.has_hardware_version_string) + { + attributes.hardwareVersionString = request.hardware_version_string; + } + + if (request.has_software_version) + { + attributes.softwareVersion = request.software_version; + } + + if (request.has_software_version_string) + { + attributes.softwareVersionString = request.software_version_string; + } device->SetBridgedAttributes(attributes); From fab3b061e1dc0c324b0d3de2982d413a3097d1f8 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 12:15:48 -0400 Subject: [PATCH 20/41] Prepare some device sync data - reading the basic info cluster --- examples/fabric-admin/BUILD.gn | 2 ++ examples/fabric-admin/commands/pairing/PairingCommand.cpp | 7 ++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/examples/fabric-admin/BUILD.gn b/examples/fabric-admin/BUILD.gn index be8313d7a944ac..7fbd13e07183ed 100644 --- a/examples/fabric-admin/BUILD.gn +++ b/examples/fabric-admin/BUILD.gn @@ -72,6 +72,8 @@ static_library("fabric-admin-utils") { "commands/common/RemoteDataModelLogger.cpp", "commands/common/RemoteDataModelLogger.h", "commands/fabric-sync/FabricSyncCommand.cpp", + "commands/pairing/DeviceSynchronization.cpp", + "commands/pairing/DeviceSynchronization.h", "commands/pairing/OpenCommissioningWindowCommand.cpp", "commands/pairing/OpenCommissioningWindowCommand.h", "commands/pairing/PairingCommand.cpp", diff --git a/examples/fabric-admin/commands/pairing/PairingCommand.cpp b/examples/fabric-admin/commands/pairing/PairingCommand.cpp index 521325a796dce0..7ca7855d181b26 100644 --- a/examples/fabric-admin/commands/pairing/PairingCommand.cpp +++ b/examples/fabric-admin/commands/pairing/PairingCommand.cpp @@ -18,7 +18,10 @@ #include "PairingCommand.h" +#include <app-common/zap-generated/ids/Clusters.h> #include <commands/common/DeviceScanner.h> +#include <commands/interactive/InteractiveCommands.h> +#include <commands/pairing/DeviceSynchronization.h> #include <controller/ExampleOperationalCredentialsIssuer.h> #include <crypto/CHIPCryptoPAL.h> #include <lib/core/CHIPSafeCasts.h> @@ -400,10 +403,8 @@ void PairingCommand::OnCommissioningComplete(NodeId nodeId, CHIP_ERROR err) { // print to console fprintf(stderr, "New device with Node ID: 0x%lx has been successfully added.\n", nodeId); + DeviceSynchronizer::Instance().StartDeviceSynchronization(ScopedNodeId(mNodeId, CurrentCommissioner().GetFabricIndex())); -#if defined(PW_RPC_ENABLED) - AddSynchronizedDevice(nodeId); -#endif } else { From f2d353eff4081f394b9c288f2362c9e9e5a37588 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 12:26:15 -0400 Subject: [PATCH 21/41] Prepare some device sync data - reading the basic info cluster --- examples/fabric-admin/commands/pairing/PairingCommand.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/examples/fabric-admin/commands/pairing/PairingCommand.cpp b/examples/fabric-admin/commands/pairing/PairingCommand.cpp index 7ca7855d181b26..40a9f7aab74b5b 100644 --- a/examples/fabric-admin/commands/pairing/PairingCommand.cpp +++ b/examples/fabric-admin/commands/pairing/PairingCommand.cpp @@ -403,8 +403,7 @@ void PairingCommand::OnCommissioningComplete(NodeId nodeId, CHIP_ERROR err) { // print to console fprintf(stderr, "New device with Node ID: 0x%lx has been successfully added.\n", nodeId); - DeviceSynchronizer::Instance().StartDeviceSynchronization(ScopedNodeId(mNodeId, CurrentCommissioner().GetFabricIndex())); - + DeviceSynchronizer::Instance().StartDeviceSynchronization(CurrentCommissioner(), mNodeId); } else { From 0d0ddae872d1fe25e143f1379b626a2efc146343 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 12:50:26 -0400 Subject: [PATCH 22/41] Full implementation of forwarding data --- .../protos/fabric_bridge_service.proto | 1 + .../commands/pairing/PairingCommand.cpp | 2 +- examples/fabric-admin/rpc/RpcClient.cpp | 44 ++----------------- examples/fabric-admin/rpc/RpcClient.h | 5 ++- 4 files changed, 8 insertions(+), 44 deletions(-) diff --git a/examples/common/pigweed/protos/fabric_bridge_service.proto b/examples/common/pigweed/protos/fabric_bridge_service.proto index f2e4fd2f32fe53..e0370dd278c7a2 100644 --- a/examples/common/pigweed/protos/fabric_bridge_service.proto +++ b/examples/common/pigweed/protos/fabric_bridge_service.proto @@ -18,6 +18,7 @@ message SynchronizedDevice { optional string hardware_version_string = 9; optional uint32 software_version = 10; optional string software_version_string = 11; + optional bool is_icd = 12; } service FabricBridge { diff --git a/examples/fabric-admin/commands/pairing/PairingCommand.cpp b/examples/fabric-admin/commands/pairing/PairingCommand.cpp index 40a9f7aab74b5b..21b023f423ed84 100644 --- a/examples/fabric-admin/commands/pairing/PairingCommand.cpp +++ b/examples/fabric-admin/commands/pairing/PairingCommand.cpp @@ -403,7 +403,7 @@ void PairingCommand::OnCommissioningComplete(NodeId nodeId, CHIP_ERROR err) { // print to console fprintf(stderr, "New device with Node ID: 0x%lx has been successfully added.\n", nodeId); - DeviceSynchronizer::Instance().StartDeviceSynchronization(CurrentCommissioner(), mNodeId); + DeviceSynchronizer::Instance().StartDeviceSynchronization(CurrentCommissioner(), mNodeId, mDeviceIsICD); } else { diff --git a/examples/fabric-admin/rpc/RpcClient.cpp b/examples/fabric-admin/rpc/RpcClient.cpp index 18a170723e9ede..54282eba414230 100644 --- a/examples/fabric-admin/rpc/RpcClient.cpp +++ b/examples/fabric-admin/rpc/RpcClient.cpp @@ -22,16 +22,9 @@ #include <chrono> #include <condition_variable> #include <mutex> -#include <string> -#include <thread> +#include "fabric_bridge_service/fabric_bridge_service.pb.h" #include "fabric_bridge_service/fabric_bridge_service.rpc.pb.h" -#include "pw_assert/check.h" -#include "pw_hdlc/decoder.h" -#include "pw_hdlc/default_addresses.h" -#include "pw_hdlc/rpc_channel.h" -#include "pw_rpc/client.h" -#include "pw_stream/socket_stream.h" using namespace chip; @@ -113,44 +106,13 @@ CHIP_ERROR InitRpcClient(uint16_t rpcServerPort) return rpc::client::StartPacketProcessing(); } -CHIP_ERROR AddSynchronizedDevice(chip::NodeId nodeId) +CHIP_ERROR AddSynchronizedDevice(const chip_rpc_SynchronizedDevice &data) { ChipLogProgress(NotSpecified, "AddSynchronizedDevice"); - chip_rpc_SynchronizedDevice device = chip_rpc_SynchronizedDevice_init_default; - device.node_id = nodeId; - - // TODO: fill this with real data. For now we just add things for testing - strcpy(device.vendor_name, "Test Vendor"); - device.has_vendor_name = true; - - device.vendor_id = 123; - device.has_vendor_id = true; - - strcpy(device.product_name, "Test Product"); - device.has_product_name = true; - - device.product_id = 234; - device.has_product_id = true; - - strcpy(device.node_label, "Device Label"); - device.has_node_label = true; - - device.hardware_version = 11; - device.has_hardware_version = true; - - strcpy(device.hardware_version_string, "Hardware"); - device.has_hardware_version_string = true; - - device.software_version = 22; - device.has_software_version = true; - - strcpy(device.software_version_string, "Test 1.4.22"); - device.has_software_version_string = true; - // The RPC call is kept alive until it completes. When a response is received, it will be logged by the handler // function and the call will complete. - auto call = fabricBridgeClient.AddSynchronizedDevice(device, OnAddDeviceResponseCompleted); + auto call = fabricBridgeClient.AddSynchronizedDevice(data, OnAddDeviceResponseCompleted); if (!call.active()) { diff --git a/examples/fabric-admin/rpc/RpcClient.h b/examples/fabric-admin/rpc/RpcClient.h index a1754b3846d508..a5bd833ad5d5b3 100644 --- a/examples/fabric-admin/rpc/RpcClient.h +++ b/examples/fabric-admin/rpc/RpcClient.h @@ -20,6 +20,8 @@ #include <platform/CHIPDeviceLayer.h> +#include "fabric_bridge_service/fabric_bridge_service.rpc.pb.h" + constexpr uint16_t kFabricBridgeServerPort = 33002; /** @@ -39,13 +41,12 @@ CHIP_ERROR InitRpcClient(uint16_t rpcServerPort); * It logs the progress and checks if an `AddSynchronizedDevice` operation is already in progress. * If an operation is in progress, it returns `CHIP_ERROR_BUSY`. * - * @param nodeId The Node ID of the device to be added. * @return CHIP_ERROR An error code indicating the success or failure of the operation. * - CHIP_NO_ERROR: The RPC command was successfully processed. * - CHIP_ERROR_BUSY: Another operation is currently in progress. * - CHIP_ERROR_INTERNAL: An internal error occurred while activating the RPC call. */ -CHIP_ERROR AddSynchronizedDevice(chip::NodeId nodeId); +CHIP_ERROR AddSynchronizedDevice(const chip_rpc_SynchronizedDevice & data); /** * @brief Removes a synchronized device from the RPC client. From a4bc1b8d0c82976436431ca42dcfb095a592da38 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 12:50:37 -0400 Subject: [PATCH 23/41] Restyle --- examples/fabric-admin/rpc/RpcClient.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fabric-admin/rpc/RpcClient.cpp b/examples/fabric-admin/rpc/RpcClient.cpp index 54282eba414230..f7892abd61172a 100644 --- a/examples/fabric-admin/rpc/RpcClient.cpp +++ b/examples/fabric-admin/rpc/RpcClient.cpp @@ -106,7 +106,7 @@ CHIP_ERROR InitRpcClient(uint16_t rpcServerPort) return rpc::client::StartPacketProcessing(); } -CHIP_ERROR AddSynchronizedDevice(const chip_rpc_SynchronizedDevice &data) +CHIP_ERROR AddSynchronizedDevice(const chip_rpc_SynchronizedDevice & data) { ChipLogProgress(NotSpecified, "AddSynchronizedDevice"); From ff840277a074de73c525150b432138c5406db828 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 12:53:01 -0400 Subject: [PATCH 24/41] Add missing file --- .../pairing/DeviceSynchronization.cpp | 179 ++++++++++++++++++ .../commands/pairing/DeviceSynchronization.h | 69 +++++++ 2 files changed, 248 insertions(+) create mode 100644 examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp create mode 100644 examples/fabric-admin/commands/pairing/DeviceSynchronization.h diff --git a/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp b/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp new file mode 100644 index 00000000000000..d9dad2a8e14e7e --- /dev/null +++ b/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#include "DeviceSynchronization.h" +#include "rpc/RpcClient.h" + +#include <app/InteractionModelEngine.h> +#include <app/server/Server.h> + +#include <app-common/zap-generated/ids/Attributes.h> +#include <app-common/zap-generated/ids/Clusters.h> + +using namespace ::chip; +using namespace ::chip::app; +using chip::app::ReadClient; + +namespace { + +void OnDeviceConnectedWrapper(void * context, Messaging::ExchangeManager & exchangeMgr, const SessionHandle & sessionHandle) +{ + reinterpret_cast<DeviceSynchronizer *>(context)->OnDeviceConnected(exchangeMgr, sessionHandle); +} + +void OnDeviceConnectionFailureWrapper(void * context, const ScopedNodeId & peerId, CHIP_ERROR error) +{ + reinterpret_cast<DeviceSynchronizer *>(context)->OnDeviceConnectionFailure(peerId, error); +} + +bool SuccessOrLog(CHIP_ERROR err, const char * name) +{ + if (err == CHIP_NO_ERROR) + { + return true; + } + + ChipLogError(NotSpecified, "Failed to read %s: %" CHIP_ERROR_FORMAT, name, err.Format()); + + return false; +} + +} // namespace + +DeviceSynchronizer & DeviceSynchronizer::Instance() +{ + static DeviceSynchronizer instance; + return instance; +} + +DeviceSynchronizer::DeviceSynchronizer() : + mOnDeviceConnectedCallback(OnDeviceConnectedWrapper, this), + mOnDeviceConnectionFailureCallback(OnDeviceConnectionFailureWrapper, this) +{} + +void DeviceSynchronizer::OnAttributeData(const ConcreteDataAttributePath & path, TLV::TLVReader * data, const StatusIB & status) +{ + VerifyOrDie(path.mEndpointId == kRootEndpointId); + VerifyOrDie(path.mClusterId == Clusters::BasicInformation::Id); + + ChipLogProgress(NotSpecified, "Attribute data"); + path.LogPath(); + + switch (path.mAttributeId) + { + case Clusters::BasicInformation::Attributes::UniqueID::Id: + mCurrentDeviceData.has_unique_id = + SuccessOrLog(data->GetString(mCurrentDeviceData.unique_id, sizeof(mCurrentDeviceData.unique_id)), "UniqueId"); + break; + case Clusters::BasicInformation::Attributes::VendorName::Id: + mCurrentDeviceData.has_vendor_name = + SuccessOrLog(data->GetString(mCurrentDeviceData.vendor_name, sizeof(mCurrentDeviceData.vendor_name)), "VendorName"); + break; + case Clusters::BasicInformation::Attributes::VendorID::Id: + mCurrentDeviceData.has_vendor_id = SuccessOrLog(data->Get(mCurrentDeviceData.vendor_id), "VendorID"); + break; + case Clusters::BasicInformation::Attributes::ProductName::Id: + mCurrentDeviceData.has_product_name = + SuccessOrLog(data->GetString(mCurrentDeviceData.product_name, sizeof(mCurrentDeviceData.product_name)), "ProductName"); + break; + case Clusters::BasicInformation::Attributes::ProductID::Id: + mCurrentDeviceData.has_product_id = SuccessOrLog(data->Get(mCurrentDeviceData.product_id), "ProductID"); + break; + case Clusters::BasicInformation::Attributes::NodeLabel::Id: + mCurrentDeviceData.has_node_label = + SuccessOrLog(data->GetString(mCurrentDeviceData.node_label, sizeof(mCurrentDeviceData.node_label)), "NodeLabel"); + break; + case Clusters::BasicInformation::Attributes::HardwareVersion::Id: + mCurrentDeviceData.has_hardware_version = SuccessOrLog(data->Get(mCurrentDeviceData.hardware_version), "HardwareVersion"); + break; + case Clusters::BasicInformation::Attributes::HardwareVersionString::Id: + mCurrentDeviceData.has_hardware_version_string = SuccessOrLog( + data->GetString(mCurrentDeviceData.hardware_version_string, sizeof(mCurrentDeviceData.hardware_version_string)), + "HardwareVersionString"); + break; + case Clusters::BasicInformation::Attributes::SoftwareVersion::Id: + mCurrentDeviceData.has_software_version = SuccessOrLog(data->Get(mCurrentDeviceData.software_version), "HardwareVersion"); + break; + case Clusters::BasicInformation::Attributes::SoftwareVersionString::Id: + mCurrentDeviceData.has_software_version_string = SuccessOrLog( + data->GetString(mCurrentDeviceData.software_version_string, sizeof(mCurrentDeviceData.software_version_string)), + "SoftwareVersionString"); + break; + default: + ChipLogProgress(NotSpecified, "Attribute data not processed"); + break; + } +} + +void DeviceSynchronizer::OnReportEnd() +{ + // Report end is at the end of all attributes (success) + AddSynchronizedDevice(mCurrentDeviceData); +} + +void DeviceSynchronizer::OnDone(chip::app::ReadClient * apReadClient) +{ + // Nothing to do: error reported on OnError or report ended called. +} + +void DeviceSynchronizer::OnError(CHIP_ERROR error) +{ + ChipLogProgress(NotSpecified, "Error fetching device data: %" CHIP_ERROR_FORMAT, error.Format()); +} + +void DeviceSynchronizer::OnDeviceConnected(chip::Messaging::ExchangeManager & exchangeMgr, + const chip::SessionHandle & sessionHandle) +{ + if (!mClient) + { + mClient = std::make_unique<ReadClient>(app::InteractionModelEngine::GetInstance(), &exchangeMgr /* echangeMgr */, + *this /* callback */, ReadClient::InteractionType::Read); + VerifyOrDie(mClient); + } + + AttributePathParams readPaths[1]; + readPaths[0] = AttributePathParams(kRootEndpointId, Clusters::BasicInformation::Id); + + ReadPrepareParams readParams(sessionHandle); + + readParams.mpAttributePathParamsList = readPaths; + readParams.mAttributePathParamsListSize = 1; + + CHIP_ERROR err = mClient->SendRequest(readParams); + + if (err != CHIP_NO_ERROR) + { + ChipLogError(NotSpecified, "Failed to issue read for BasicInformation data"); + } +} + +void DeviceSynchronizer::OnDeviceConnectionFailure(const chip::ScopedNodeId & peerId, CHIP_ERROR error) +{ + ChipLogError(NotSpecified, "Device Sync failed to connect to " ChipLogFormatX64, ChipLogValueX64(peerId.GetNodeId())); +} + +void DeviceSynchronizer::StartDeviceSynchronization(chip::Controller::DeviceController & controller, chip::NodeId nodeId, bool deviceIsIcd) +{ + mCurrentDeviceData = chip_rpc_SynchronizedDevice_init_default; + mCurrentDeviceData.node_id = nodeId; + mCurrentDeviceData.has_is_icd = true; + mCurrentDeviceData.is_icd = deviceIsIcd; + + + controller.GetConnectedDevice(nodeId, &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback); +} diff --git a/examples/fabric-admin/commands/pairing/DeviceSynchronization.h b/examples/fabric-admin/commands/pairing/DeviceSynchronization.h new file mode 100644 index 00000000000000..e2c341b53f0845 --- /dev/null +++ b/examples/fabric-admin/commands/pairing/DeviceSynchronization.h @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2024 Project CHIP Authors + * All rights reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ +#pragma once + +#include <app/ReadClient.h> +#include <controller/CHIPDeviceController.h> +#include <lib/core/DataModelTypes.h> + +#include <memory> + +#include "fabric_bridge_service/fabric_bridge_service.pb.h" +#include "fabric_bridge_service/fabric_bridge_service.rpc.pb.h" + +/// Ensures that device data is synchronized to the remove fabric bridge. +/// +/// Includes a state machine that: +/// - initiates a "read basic information data" command to fetch basic information +/// - upon receiving such information, ensures that synchronized device data is sent +/// to the remote end. +class DeviceSynchronizer : public chip::app::ReadClient::Callback +{ +public: + DeviceSynchronizer(); + + /// Usually called after commissioning is complete, initiates a + /// read of required data from the remote node ID and then will synchronize + /// the device towards the fabric bridge + void StartDeviceSynchronization(chip::Controller::DeviceController & controller, chip::NodeId nodeId, bool deviceIsIcd); + + /////////////////////////////////////////////////////////////// + // ReadClient::Callback implementation + /////////////////////////////////////////////////////////////// + void OnAttributeData(const chip::app::ConcreteDataAttributePath & path, chip::TLV::TLVReader * data, + const chip::app::StatusIB & status) override; + void OnReportEnd() override; + void OnError(CHIP_ERROR error) override; + void OnDone(chip::app::ReadClient * apReadClient) override; + + /////////////////////////////////////////////////////////////// + // callbacks for CASE session establishment + /////////////////////////////////////////////////////////////// + void OnDeviceConnected(chip::Messaging::ExchangeManager & exchangeMgr, const chip::SessionHandle & sessionHandle); + void OnDeviceConnectionFailure(const chip::ScopedNodeId & peerId, CHIP_ERROR error); + + static DeviceSynchronizer & Instance(); + +private: + std::unique_ptr<chip::app::ReadClient> mClient; + + chip::Callback::Callback<chip::OnDeviceConnected> mOnDeviceConnectedCallback; + chip::Callback::Callback<chip::OnDeviceConnectionFailure> mOnDeviceConnectionFailureCallback; + + chip_rpc_SynchronizedDevice mCurrentDeviceData = chip_rpc_SynchronizedDevice_init_default; +}; From c60afe61461bbca5ab90fbef610bae9e2379db11 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 12:53:12 -0400 Subject: [PATCH 25/41] Restyle --- .../commands/pairing/DeviceSynchronization.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp b/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp index d9dad2a8e14e7e..8c0aae730a6274 100644 --- a/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp +++ b/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp @@ -126,7 +126,7 @@ void DeviceSynchronizer::OnReportEnd() AddSynchronizedDevice(mCurrentDeviceData); } -void DeviceSynchronizer::OnDone(chip::app::ReadClient * apReadClient) +void DeviceSynchronizer::OnDone(chip::app::ReadClient * apReadClient) { // Nothing to do: error reported on OnError or report ended called. } @@ -167,13 +167,13 @@ void DeviceSynchronizer::OnDeviceConnectionFailure(const chip::ScopedNodeId & pe ChipLogError(NotSpecified, "Device Sync failed to connect to " ChipLogFormatX64, ChipLogValueX64(peerId.GetNodeId())); } -void DeviceSynchronizer::StartDeviceSynchronization(chip::Controller::DeviceController & controller, chip::NodeId nodeId, bool deviceIsIcd) +void DeviceSynchronizer::StartDeviceSynchronization(chip::Controller::DeviceController & controller, chip::NodeId nodeId, + bool deviceIsIcd) { - mCurrentDeviceData = chip_rpc_SynchronizedDevice_init_default; - mCurrentDeviceData.node_id = nodeId; + mCurrentDeviceData = chip_rpc_SynchronizedDevice_init_default; + mCurrentDeviceData.node_id = nodeId; mCurrentDeviceData.has_is_icd = true; - mCurrentDeviceData.is_icd = deviceIsIcd; - + mCurrentDeviceData.is_icd = deviceIsIcd; controller.GetConnectedDevice(nodeId, &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback); } From 348030af9759a4fa6fe8625876950618ac88b662 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 12:56:22 -0400 Subject: [PATCH 26/41] reset readclient, since this may reset the exchange manager ... seems cleaner --- .../commands/pairing/DeviceSynchronization.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp b/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp index 8c0aae730a6274..514b23a03ae162 100644 --- a/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp +++ b/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp @@ -139,12 +139,8 @@ void DeviceSynchronizer::OnError(CHIP_ERROR error) void DeviceSynchronizer::OnDeviceConnected(chip::Messaging::ExchangeManager & exchangeMgr, const chip::SessionHandle & sessionHandle) { - if (!mClient) - { - mClient = std::make_unique<ReadClient>(app::InteractionModelEngine::GetInstance(), &exchangeMgr /* echangeMgr */, - *this /* callback */, ReadClient::InteractionType::Read); - VerifyOrDie(mClient); - } + mClient = std::make_unique<ReadClient>(app::InteractionModelEngine::GetInstance(), &exchangeMgr /* echangeMgr */, + *this /* callback */, ReadClient::InteractionType::Read); AttributePathParams readPaths[1]; readPaths[0] = AttributePathParams(kRootEndpointId, Clusters::BasicInformation::Id); From 471941c2ad365943bfe9a94250bafc0eb5d7b68c Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 12:56:52 -0400 Subject: [PATCH 27/41] Add the verifyOrDie --- examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp b/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp index 514b23a03ae162..d6f4d3d01f1c6b 100644 --- a/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp +++ b/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp @@ -141,6 +141,7 @@ void DeviceSynchronizer::OnDeviceConnected(chip::Messaging::ExchangeManager & ex { mClient = std::make_unique<ReadClient>(app::InteractionModelEngine::GetInstance(), &exchangeMgr /* echangeMgr */, *this /* callback */, ReadClient::InteractionType::Read); + VerifyOrDie(mClient); AttributePathParams readPaths[1]; readPaths[0] = AttributePathParams(kRootEndpointId, Clusters::BasicInformation::Id); From f9465eb57335030b325f2e197fd2266113bb98c5 Mon Sep 17 00:00:00 2001 From: "Restyled.io" <commits@restyled.io> Date: Wed, 7 Aug 2024 16:59:25 +0000 Subject: [PATCH 28/41] Restyled by clang-format --- examples/fabric-admin/rpc/RpcClient.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/fabric-admin/rpc/RpcClient.cpp b/examples/fabric-admin/rpc/RpcClient.cpp index 18a170723e9ede..816ea04691d71b 100644 --- a/examples/fabric-admin/rpc/RpcClient.cpp +++ b/examples/fabric-admin/rpc/RpcClient.cpp @@ -124,25 +124,25 @@ CHIP_ERROR AddSynchronizedDevice(chip::NodeId nodeId) strcpy(device.vendor_name, "Test Vendor"); device.has_vendor_name = true; - device.vendor_id = 123; + device.vendor_id = 123; device.has_vendor_id = true; strcpy(device.product_name, "Test Product"); device.has_product_name = true; - device.product_id = 234; + device.product_id = 234; device.has_product_id = true; strcpy(device.node_label, "Device Label"); device.has_node_label = true; - device.hardware_version = 11; + device.hardware_version = 11; device.has_hardware_version = true; strcpy(device.hardware_version_string, "Hardware"); device.has_hardware_version_string = true; - device.software_version = 22; + device.software_version = 22; device.has_software_version = true; strcpy(device.software_version_string, "Test 1.4.22"); From c256b3b72fe86243c3cc9b4210ac93ff5661daac Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 13:16:49 -0400 Subject: [PATCH 29/41] Fix string size for HW and software versions --- examples/common/pigweed/protos/fabric_bridge_service.options | 4 ++-- .../fabric-bridge-common/src/BridgedDeviceManager.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/examples/common/pigweed/protos/fabric_bridge_service.options b/examples/common/pigweed/protos/fabric_bridge_service.options index b52b5cc7367f14..a095d85788eb1c 100644 --- a/examples/common/pigweed/protos/fabric_bridge_service.options +++ b/examples/common/pigweed/protos/fabric_bridge_service.options @@ -2,5 +2,5 @@ chip.rpc.SynchronizedDevice.unique_id max_size:33 chip.rpc.SynchronizedDevice.vendor_name max_size:33 chip.rpc.SynchronizedDevice.product_name max_size:33 chip.rpc.SynchronizedDevice.node_label max_size:33 -chip.rpc.SynchronizedDevice.hardware_version_string max_size:33 -chip.rpc.SynchronizedDevice.software_version_string max_size:33 +chip.rpc.SynchronizedDevice.hardware_version_string max_size:65 +chip.rpc.SynchronizedDevice.software_version_string max_size:65 diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp index ea873aa8ef4b27..2bdfc8a2c3e54a 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp @@ -52,8 +52,8 @@ constexpr int kNodeLabelSize = 32; constexpr int kUniqueIdSize = 32; constexpr int kVendorNameSize = 32; constexpr int kProductNameSize = 32; -constexpr int kHardwareVersionSize = 32; -constexpr int kSoftwareVersionSize = 32; +constexpr int kHardwareVersionSize = 64; +constexpr int kSoftwareVersionSize = 64; // Current ZCL implementation of Struct uses a max-size array of 254 bytes constexpr int kDescriptorAttributeArraySize = 254; From e0156e4cf51004a4e832d8d08b0ae1a10c05ac8f Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 14:33:00 -0400 Subject: [PATCH 30/41] Move ICD support: set separate commands, handle feature mask --- .../include/BridgedDevice.h | 15 ++++++--- .../src/BridgedDevice.cpp | 7 ----- .../src/BridgedDeviceBasicInformationImpl.cpp | 10 +++--- .../src/BridgedDeviceManager.cpp | 31 ++++++++++++++++--- .../fabric-bridge-app/linux/RpcServer.cpp | 1 + 5 files changed, 44 insertions(+), 20 deletions(-) diff --git a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h index 5c09cfa04d2521..fdb3bb1b9b56cb 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h +++ b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h @@ -43,9 +43,12 @@ class BridgedDevice BridgedDevice(chip::NodeId nodeId); virtual ~BridgedDevice() = default; - bool IsReachable(); + [[nodiscard]] bool IsReachable() const { return mReachable; } void SetReachable(bool reachable); + [[nodiscard]] bool IsIcd() const { return mIsIcd; } + void SetIcd(bool icd) { mIsIcd = icd; } + inline void SetEndpointId(chip::EndpointId id) { mEndpointId = id; }; inline chip::EndpointId GetEndpointId() { return mEndpointId; }; inline chip::NodeId GetNodeId() { return mNodeId; }; @@ -60,10 +63,12 @@ class BridgedDevice void SetUniqueId(const std::string & value) { mAttributes.uniqueId = value; } protected: - bool mReachable; - chip::NodeId mNodeId; - chip::EndpointId mEndpointId; - chip::EndpointId mParentEndpointId; + bool mReachable = false; + bool mIsIcd = false; + + chip::NodeId mNodeId = 0; + chip::EndpointId mEndpointId = 0; + chip::EndpointId mParentEndpointId = 0; BridgedAttributes mAttributes; }; diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDevice.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDevice.cpp index 425bb4da32e896..dfc8bf69d45984 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDevice.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDevice.cpp @@ -21,8 +21,6 @@ #include <cstdio> #include <platform/CHIPDeviceLayer.h> -#include <string> - using namespace chip::app::Clusters::Actions; BridgedDevice::BridgedDevice(chip::NodeId nodeId) @@ -32,11 +30,6 @@ BridgedDevice::BridgedDevice(chip::NodeId nodeId) mEndpointId = chip::kInvalidEndpointId; } -bool BridgedDevice::IsReachable() -{ - return mReachable; -} - void BridgedDevice::SetReachable(bool reachable) { mReachable = reachable; diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceBasicInformationImpl.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceBasicInformationImpl.cpp index c088935df30c59..7fa48a4a158ddd 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceBasicInformationImpl.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceBasicInformationImpl.cpp @@ -24,7 +24,6 @@ #include <app/AttributeAccessInterfaceRegistry.h> static constexpr unsigned kBridgedDeviceBasicInformationClusterRevision = 4; -static constexpr unsigned kBridgedDeviceBasicInformationFeatureMap = 0; using namespace ::chip; using namespace ::chip::app; @@ -49,9 +48,12 @@ CHIP_ERROR BridgedDeviceBasicInformationImpl::Read(const ConcreteReadAttributePa case BasicInformation::Attributes::ClusterRevision::Id: encoder.Encode(kBridgedDeviceBasicInformationClusterRevision); break; - case BasicInformation::Attributes::FeatureMap::Id: - encoder.Encode(kBridgedDeviceBasicInformationFeatureMap); - break; + case BasicInformation::Attributes::FeatureMap::Id: { + BitMask<Clusters::BridgedDeviceBasicInformation::Feature> features; + features.Set(Clusters::BridgedDeviceBasicInformation::Feature::kBridgedICDSupport, dev->IsIcd()); + encoder.Encode(features); + } + break; case BasicInformation::Attributes::UniqueID::Id: encoder.Encode(CharSpan::fromCharString(dev->GetBridgedAttributes().uniqueId.c_str())); break; diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp index ea873aa8ef4b27..bebf315ed8ad7f 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp @@ -129,15 +129,35 @@ constexpr CommandId administratorCommissioningCommands[] = { kInvalidCommandId, }; +constexpr CommandId icdBridgedDeviceCommands[] = { + app::Clusters::BridgedDeviceBasicInformation::Commands::KeepActive::Id, + kInvalidCommandId, +}; + +// clang-format off // Declare Cluster List for Bridged Node endpoint DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(bridgedNodeClusters) -DECLARE_DYNAMIC_CLUSTER(Descriptor::Id, descriptorAttrs, ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr), + DECLARE_DYNAMIC_CLUSTER(Descriptor::Id, descriptorAttrs, ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr), DECLARE_DYNAMIC_CLUSTER(BridgedDeviceBasicInformation::Id, bridgedDeviceBasicAttrs, ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr), DECLARE_DYNAMIC_CLUSTER(AdministratorCommissioning::Id, AdministratorCommissioningAttrs, ZAP_CLUSTER_MASK(SERVER), - administratorCommissioningCommands, nullptr) DECLARE_DYNAMIC_CLUSTER_LIST_END; + administratorCommissioningCommands, nullptr) +DECLARE_DYNAMIC_CLUSTER_LIST_END; + +DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(icdBridgedNodeClusters) + DECLARE_DYNAMIC_CLUSTER(Descriptor::Id, descriptorAttrs, ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr), + DECLARE_DYNAMIC_CLUSTER(BridgedDeviceBasicInformation::Id, bridgedDeviceBasicAttrs, ZAP_CLUSTER_MASK(SERVER), + icdBridgedDeviceCommands, nullptr), + DECLARE_DYNAMIC_CLUSTER(AdministratorCommissioning::Id, AdministratorCommissioningAttrs, ZAP_CLUSTER_MASK(SERVER), + administratorCommissioningCommands, nullptr) +DECLARE_DYNAMIC_CLUSTER_LIST_END; +// clang-format on // Declare Bridged Node endpoint DECLARE_DYNAMIC_ENDPOINT(sBridgedNodeEndpoint, bridgedNodeClusters); +DECLARE_DYNAMIC_ENDPOINT(sIcdBridgedNodeEndpoint, icdBridgedNodeClusters); + +// TODO: this is a single version array, however we may have many +// different clusters that are independent. DataVersion sBridgedNodeDataVersions[ArraySize(bridgedNodeClusters)]; const EmberAfDeviceType sBridgedDeviceTypes[] = { { DEVICE_TYPE_BRIDGED_NODE, DEVICE_VERSION_DEFAULT } }; @@ -157,9 +177,12 @@ void BridgedDeviceManager::Init() std::optional<unsigned> BridgedDeviceManager::AddDeviceEndpoint(std::unique_ptr<BridgedDevice> dev, chip::EndpointId parentEndpointId) { - EmberAfEndpointType * ep = &sBridgedNodeEndpoint; + EmberAfEndpointType * ep = dev->IsIcd() ? &sIcdBridgedNodeEndpoint : &sBridgedNodeEndpoint; + const chip::Span<const EmberAfDeviceType> & deviceTypeList = Span<const EmberAfDeviceType>(sBridgedDeviceTypes); - const chip::Span<chip::DataVersion> & dataVersionStorage = Span<DataVersion>(sBridgedNodeDataVersions); + + // TODO: this shares data version among different clusters, which seems incorrect + const chip::Span<chip::DataVersion> & dataVersionStorage = Span<DataVersion>(sBridgedNodeDataVersions); if (dev->GetBridgedAttributes().uniqueId.empty()) { diff --git a/examples/fabric-bridge-app/linux/RpcServer.cpp b/examples/fabric-bridge-app/linux/RpcServer.cpp index aae7e239b694ef..840135d6d2b4d0 100644 --- a/examples/fabric-bridge-app/linux/RpcServer.cpp +++ b/examples/fabric-bridge-app/linux/RpcServer.cpp @@ -107,6 +107,7 @@ pw::Status FabricBridge::AddSynchronizedDevice(const chip_rpc_SynchronizedDevice } device->SetBridgedAttributes(attributes); + device->SetIcd(request.has_is_icd && request.is_icd); auto result = BridgeDeviceMgr().AddDeviceEndpoint(std::move(device), 1 /* parentEndpointId */); if (!result.has_value()) From 3d78200397a193d42b5e7a76f84f2825dbcbe74d Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 14:33:22 -0400 Subject: [PATCH 31/41] Restyle --- .../fabric-bridge-common/src/BridgedDeviceManager.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp index bebf315ed8ad7f..67bcf0ac5b2752 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp @@ -145,7 +145,7 @@ DECLARE_DYNAMIC_CLUSTER_LIST_END; DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(icdBridgedNodeClusters) DECLARE_DYNAMIC_CLUSTER(Descriptor::Id, descriptorAttrs, ZAP_CLUSTER_MASK(SERVER), nullptr, nullptr), - DECLARE_DYNAMIC_CLUSTER(BridgedDeviceBasicInformation::Id, bridgedDeviceBasicAttrs, ZAP_CLUSTER_MASK(SERVER), + DECLARE_DYNAMIC_CLUSTER(BridgedDeviceBasicInformation::Id, bridgedDeviceBasicAttrs, ZAP_CLUSTER_MASK(SERVER), icdBridgedDeviceCommands, nullptr), DECLARE_DYNAMIC_CLUSTER(AdministratorCommissioning::Id, AdministratorCommissioningAttrs, ZAP_CLUSTER_MASK(SERVER), administratorCommissioningCommands, nullptr) From f2841eb96eb392d72f08d97072623e5f7662db94 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 19:38:45 -0400 Subject: [PATCH 32/41] Remove some of the spammier logs --- .../fabric-admin/commands/pairing/DeviceSynchronization.cpp | 4 ---- 1 file changed, 4 deletions(-) diff --git a/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp b/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp index d6f4d3d01f1c6b..b512daa42469cb 100644 --- a/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp +++ b/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp @@ -71,9 +71,6 @@ void DeviceSynchronizer::OnAttributeData(const ConcreteDataAttributePath & path, VerifyOrDie(path.mEndpointId == kRootEndpointId); VerifyOrDie(path.mClusterId == Clusters::BasicInformation::Id); - ChipLogProgress(NotSpecified, "Attribute data"); - path.LogPath(); - switch (path.mAttributeId) { case Clusters::BasicInformation::Attributes::UniqueID::Id: @@ -115,7 +112,6 @@ void DeviceSynchronizer::OnAttributeData(const ConcreteDataAttributePath & path, "SoftwareVersionString"); break; default: - ChipLogProgress(NotSpecified, "Attribute data not processed"); break; } } From dc75ac56a5f7721e377079ebfdfb595d5ca9bb50 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andy314@gmail.com> Date: Wed, 7 Aug 2024 19:40:15 -0400 Subject: [PATCH 33/41] Enfore RPC enabling for synchronized device addition --- .../fabric-admin/commands/pairing/DeviceSynchronization.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp b/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp index b512daa42469cb..90f9e1eaa06619 100644 --- a/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp +++ b/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp @@ -119,7 +119,11 @@ void DeviceSynchronizer::OnAttributeData(const ConcreteDataAttributePath & path, void DeviceSynchronizer::OnReportEnd() { // Report end is at the end of all attributes (success) +#if defined(PW_RPC_ENABLED) AddSynchronizedDevice(mCurrentDeviceData); +#else + ChipLogError(NotSpecified, "Cannot synchronize device with fabric bridge: RPC not enabled"); +#endif } void DeviceSynchronizer::OnDone(chip::app::ReadClient * apReadClient) From 2501d42410bfa1f9361c33a0767fbcb17b0b2a15 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andreilitvin@google.com> Date: Thu, 8 Aug 2024 08:26:26 -0400 Subject: [PATCH 34/41] Add device sync in progress tracking --- .../commands/pairing/DeviceSynchronization.cpp | 10 ++++++++++ .../commands/pairing/DeviceSynchronization.h | 1 + third_party/nxp/nxp_matter_support | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp b/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp index 90f9e1eaa06619..a7f236bf02c971 100644 --- a/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp +++ b/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp @@ -124,6 +124,7 @@ void DeviceSynchronizer::OnReportEnd() #else ChipLogError(NotSpecified, "Cannot synchronize device with fabric bridge: RPC not enabled"); #endif + mDeviceSyncInProcess = false; } void DeviceSynchronizer::OnDone(chip::app::ReadClient * apReadClient) @@ -134,6 +135,7 @@ void DeviceSynchronizer::OnDone(chip::app::ReadClient * apReadClient) void DeviceSynchronizer::OnError(CHIP_ERROR error) { ChipLogProgress(NotSpecified, "Error fetching device data: %" CHIP_ERROR_FORMAT, error.Format()); + mDeviceSyncInProcess = false; } void DeviceSynchronizer::OnDeviceConnected(chip::Messaging::ExchangeManager & exchangeMgr, @@ -167,10 +169,18 @@ void DeviceSynchronizer::OnDeviceConnectionFailure(const chip::ScopedNodeId & pe void DeviceSynchronizer::StartDeviceSynchronization(chip::Controller::DeviceController & controller, chip::NodeId nodeId, bool deviceIsIcd) { + if (mDeviceSyncInProcess) + { + ChipLogError(NotSpecified, "Device Sync NOT POSSIBLE: another sync is in progress"); + return; + } + mCurrentDeviceData = chip_rpc_SynchronizedDevice_init_default; mCurrentDeviceData.node_id = nodeId; mCurrentDeviceData.has_is_icd = true; mCurrentDeviceData.is_icd = deviceIsIcd; + mDeviceSyncInProcess = true; + controller.GetConnectedDevice(nodeId, &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback); } diff --git a/examples/fabric-admin/commands/pairing/DeviceSynchronization.h b/examples/fabric-admin/commands/pairing/DeviceSynchronization.h index e2c341b53f0845..48972370691207 100644 --- a/examples/fabric-admin/commands/pairing/DeviceSynchronization.h +++ b/examples/fabric-admin/commands/pairing/DeviceSynchronization.h @@ -65,5 +65,6 @@ class DeviceSynchronizer : public chip::app::ReadClient::Callback chip::Callback::Callback<chip::OnDeviceConnected> mOnDeviceConnectedCallback; chip::Callback::Callback<chip::OnDeviceConnectionFailure> mOnDeviceConnectionFailureCallback; + bool mDeviceSyncInProcess = false; chip_rpc_SynchronizedDevice mCurrentDeviceData = chip_rpc_SynchronizedDevice_init_default; }; diff --git a/third_party/nxp/nxp_matter_support b/third_party/nxp/nxp_matter_support index e6deaf56001387..ac504a0cc38963 160000 --- a/third_party/nxp/nxp_matter_support +++ b/third_party/nxp/nxp_matter_support @@ -1 +1 @@ -Subproject commit e6deaf5600138763ea68418e34bc62a02d1aef0d +Subproject commit ac504a0cc389632c0e26b4f04e65914d3a9ba8bd From 9ff1c0d89c718deeee3e8c5f5b334f3c455d739e Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andreilitvin@google.com> Date: Thu, 8 Aug 2024 08:27:42 -0400 Subject: [PATCH 35/41] Undo submodule update --- third_party/nxp/nxp_matter_support | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/nxp/nxp_matter_support b/third_party/nxp/nxp_matter_support index ac504a0cc38963..e6deaf56001387 160000 --- a/third_party/nxp/nxp_matter_support +++ b/third_party/nxp/nxp_matter_support @@ -1 +1 @@ -Subproject commit ac504a0cc389632c0e26b4f04e65914d3a9ba8bd +Subproject commit e6deaf5600138763ea68418e34bc62a02d1aef0d From 46b75f2c503a940252186ec74da7b7620c960573 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andreilitvin@google.com> Date: Thu, 8 Aug 2024 08:48:19 -0400 Subject: [PATCH 36/41] Fix up device sync progress tracking to better handle errors --- .../fabric-admin/commands/pairing/DeviceSynchronization.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp b/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp index a7f236bf02c971..3974761fdc4bc2 100644 --- a/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp +++ b/examples/fabric-admin/commands/pairing/DeviceSynchronization.cpp @@ -124,18 +124,17 @@ void DeviceSynchronizer::OnReportEnd() #else ChipLogError(NotSpecified, "Cannot synchronize device with fabric bridge: RPC not enabled"); #endif - mDeviceSyncInProcess = false; } void DeviceSynchronizer::OnDone(chip::app::ReadClient * apReadClient) { // Nothing to do: error reported on OnError or report ended called. + mDeviceSyncInProcess = false; } void DeviceSynchronizer::OnError(CHIP_ERROR error) { ChipLogProgress(NotSpecified, "Error fetching device data: %" CHIP_ERROR_FORMAT, error.Format()); - mDeviceSyncInProcess = false; } void DeviceSynchronizer::OnDeviceConnected(chip::Messaging::ExchangeManager & exchangeMgr, @@ -158,12 +157,14 @@ void DeviceSynchronizer::OnDeviceConnected(chip::Messaging::ExchangeManager & ex if (err != CHIP_NO_ERROR) { ChipLogError(NotSpecified, "Failed to issue read for BasicInformation data"); + mDeviceSyncInProcess = false; } } void DeviceSynchronizer::OnDeviceConnectionFailure(const chip::ScopedNodeId & peerId, CHIP_ERROR error) { ChipLogError(NotSpecified, "Device Sync failed to connect to " ChipLogFormatX64, ChipLogValueX64(peerId.GetNodeId())); + mDeviceSyncInProcess = false; } void DeviceSynchronizer::StartDeviceSynchronization(chip::Controller::DeviceController & controller, chip::NodeId nodeId, From 4ae53d009c18be23016e6026595a9a08ca76f950 Mon Sep 17 00:00:00 2001 From: "Restyled.io" <commits@restyled.io> Date: Thu, 8 Aug 2024 12:48:42 +0000 Subject: [PATCH 37/41] Restyled by clang-format --- examples/fabric-admin/commands/pairing/DeviceSynchronization.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/fabric-admin/commands/pairing/DeviceSynchronization.h b/examples/fabric-admin/commands/pairing/DeviceSynchronization.h index 48972370691207..16c0e264928639 100644 --- a/examples/fabric-admin/commands/pairing/DeviceSynchronization.h +++ b/examples/fabric-admin/commands/pairing/DeviceSynchronization.h @@ -65,6 +65,6 @@ class DeviceSynchronizer : public chip::app::ReadClient::Callback chip::Callback::Callback<chip::OnDeviceConnected> mOnDeviceConnectedCallback; chip::Callback::Callback<chip::OnDeviceConnectionFailure> mOnDeviceConnectionFailureCallback; - bool mDeviceSyncInProcess = false; + bool mDeviceSyncInProcess = false; chip_rpc_SynchronizedDevice mCurrentDeviceData = chip_rpc_SynchronizedDevice_init_default; }; From a59fef76b86c5866c1c1c6e938fe0300232c6fb4 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andreilitvin@google.com> Date: Thu, 8 Aug 2024 11:19:55 -0400 Subject: [PATCH 38/41] Fix typo --- examples/fabric-admin/commands/pairing/DeviceSynchronization.h | 2 +- third_party/bouffalolab/repo | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/fabric-admin/commands/pairing/DeviceSynchronization.h b/examples/fabric-admin/commands/pairing/DeviceSynchronization.h index 16c0e264928639..6aca23f31cbeaa 100644 --- a/examples/fabric-admin/commands/pairing/DeviceSynchronization.h +++ b/examples/fabric-admin/commands/pairing/DeviceSynchronization.h @@ -26,7 +26,7 @@ #include "fabric_bridge_service/fabric_bridge_service.pb.h" #include "fabric_bridge_service/fabric_bridge_service.rpc.pb.h" -/// Ensures that device data is synchronized to the remove fabric bridge. +/// Ensures that device data is synchronized to the remote fabric bridge. /// /// Includes a state machine that: /// - initiates a "read basic information data" command to fetch basic information diff --git a/third_party/bouffalolab/repo b/third_party/bouffalolab/repo index 51a4f451b67a33..07ac148f70e1e3 160000 --- a/third_party/bouffalolab/repo +++ b/third_party/bouffalolab/repo @@ -1 +1 @@ -Subproject commit 51a4f451b67a33d07f11cc55e4dbd8ff5d374eb0 +Subproject commit 07ac148f70e1e3773f0ba0fa5ccad00bdf40e4d9 From 29e2dcd492511c5cef1efb42c64e31f68e77775e Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andreilitvin@google.com> Date: Thu, 8 Aug 2024 11:21:30 -0400 Subject: [PATCH 39/41] Undo submodule update --- third_party/bouffalolab/repo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/third_party/bouffalolab/repo b/third_party/bouffalolab/repo index 07ac148f70e1e3..51a4f451b67a33 160000 --- a/third_party/bouffalolab/repo +++ b/third_party/bouffalolab/repo @@ -1 +1 @@ -Subproject commit 07ac148f70e1e3773f0ba0fa5ccad00bdf40e4d9 +Subproject commit 51a4f451b67a33d07f11cc55e4dbd8ff5d374eb0 From c4064f068b5fb431939c6eba6a6b5b073bdc2d11 Mon Sep 17 00:00:00 2001 From: Andrei Litvin <andreilitvin@google.com> Date: Thu, 8 Aug 2024 12:49:52 -0400 Subject: [PATCH 40/41] Fix merge --- .../fabric-bridge-common/include/BridgedDevice.h | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h index b7730e8176bab5..3dab8d3b16b2d6 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h +++ b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h @@ -65,25 +65,12 @@ class BridgedDevice void SetUniqueId(const std::string & value) { mAttributes.uniqueId = value; } protected: -<<<<<<< HEAD bool mReachable = false; bool mIsIcd = false; chip::NodeId mNodeId = 0; chip::EndpointId mEndpointId = 0; chip::EndpointId mParentEndpointId = 0; -||||||| a315c91a2d - bool mReachable; - chip::NodeId mNodeId; - chip::EndpointId mEndpointId; - chip::EndpointId mParentEndpointId; -======= - bool mReachable; - bool mIsIcd = false; - chip::NodeId mNodeId; - chip::EndpointId mEndpointId; - chip::EndpointId mParentEndpointId; ->>>>>>> master BridgedAttributes mAttributes; }; From efcb58a92ff4657b5fe6445d7b2ffc7af7c52cf1 Mon Sep 17 00:00:00 2001 From: "Restyled.io" <commits@restyled.io> Date: Thu, 8 Aug 2024 16:50:24 +0000 Subject: [PATCH 41/41] Restyled by clang-format --- .../fabric-bridge-common/src/BridgedDeviceManager.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp index 0657e40993655b..8db44c3e8bfd9b 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp @@ -141,7 +141,6 @@ constexpr CommandId administratorCommissioningCommands[] = { kInvalidCommandId, }; - // clang-format off // Declare Cluster List for Bridged Node endpoint DECLARE_DYNAMIC_CLUSTER_LIST_BEGIN(bridgedNodeClusters)