diff --git a/examples/common/pigweed/BUILD.gn b/examples/common/pigweed/BUILD.gn index a7b7d97da32ba6..646b6456107f95 100644 --- a/examples/common/pigweed/BUILD.gn +++ b/examples/common/pigweed/BUILD.gn @@ -80,10 +80,19 @@ pw_proto_library("button_service") { prefix = "button_service" } +pw_proto_library("fabric_sync_common") { + sources = [ "protos/fabric_sync_common.proto" ] + strip_prefix = "protos" + prefix = "fabric_sync_common" +} + pw_proto_library("fabric_admin_service") { sources = [ "protos/fabric_admin_service.proto" ] inputs = [ "protos/fabric_admin_service.options" ] - deps = [ "$dir_pw_protobuf:common_protos" ] + deps = [ + ":fabric_sync_common", + "$dir_pw_protobuf:common_protos", + ] strip_prefix = "protos" prefix = "fabric_admin_service" } @@ -91,7 +100,10 @@ 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" ] + deps = [ + ":fabric_sync_common", + "$dir_pw_protobuf:common_protos", + ] strip_prefix = "protos" prefix = "fabric_bridge_service" } diff --git a/examples/common/pigweed/protos/fabric_admin_service.proto b/examples/common/pigweed/protos/fabric_admin_service.proto index 4d7b2075a2ed44..19fb76ecadf5ae 100644 --- a/examples/common/pigweed/protos/fabric_admin_service.proto +++ b/examples/common/pigweed/protos/fabric_admin_service.proto @@ -1,12 +1,13 @@ syntax = "proto3"; import 'pw_protobuf_protos/common.proto'; +import 'fabric_sync_common/fabric_sync_common.proto'; package chip.rpc; // Define the message for a synchronized end device with necessary fields message DeviceCommissioningWindowInfo { - uint64 node_id = 1; + ScopedNode id = 1; uint32 commissioning_timeout = 2; uint32 discriminator = 3; uint32 iterations = 4; @@ -25,7 +26,7 @@ message DeviceCommissioningInfo { } message KeepActiveParameters { - uint64 node_id = 1; + ScopedNode id = 1; uint32 stay_active_duration_ms = 2; uint32 timeout_ms = 3; } diff --git a/examples/common/pigweed/protos/fabric_bridge_service.proto b/examples/common/pigweed/protos/fabric_bridge_service.proto index 1c699e6942b358..4e01d4ec5c7e78 100644 --- a/examples/common/pigweed/protos/fabric_bridge_service.proto +++ b/examples/common/pigweed/protos/fabric_bridge_service.proto @@ -1,12 +1,13 @@ syntax = "proto3"; import 'pw_protobuf_protos/common.proto'; +import 'fabric_sync_common/fabric_sync_common.proto'; package chip.rpc; // Define the message for a synchronized end device with necessary fields message SynchronizedDevice { - uint64 node_id = 1; + ScopedNode id = 1; optional string unique_id = 2; optional string vendor_name = 3; @@ -22,12 +23,12 @@ message SynchronizedDevice { } message KeepActiveChanged { - uint64 node_id = 1; + ScopedNode id = 1; uint32 promised_active_duration_ms = 2; } message AdministratorCommissioningChanged { - uint64 node_id = 1; + ScopedNode id = 1; uint32 window_status = 2; optional uint32 opener_fabric_index = 3; optional uint32 opener_vendor_id = 4; diff --git a/examples/common/pigweed/protos/fabric_sync_common.proto b/examples/common/pigweed/protos/fabric_sync_common.proto new file mode 100644 index 00000000000000..95aa87cee147fa --- /dev/null +++ b/examples/common/pigweed/protos/fabric_sync_common.proto @@ -0,0 +1,6 @@ +syntax = "proto3"; + +message ScopedNode { + uint64 node_id = 1; + uint32 fabric_index = 2; +} diff --git a/examples/common/pigweed/rpc_console/py/BUILD.gn b/examples/common/pigweed/rpc_console/py/BUILD.gn index db9f22fe45fff9..01c8bd8293f06e 100644 --- a/examples/common/pigweed/rpc_console/py/BUILD.gn +++ b/examples/common/pigweed/rpc_console/py/BUILD.gn @@ -48,6 +48,7 @@ pw_python_package("chip_rpc") { "${chip_root}/examples/common/pigweed:echo_service.python", "${chip_root}/examples/common/pigweed:fabric_admin_service.python", "${chip_root}/examples/common/pigweed:fabric_bridge_service.python", + "${chip_root}/examples/common/pigweed:fabric_sync_common.python", "${chip_root}/examples/common/pigweed:lighting_service.python", "${chip_root}/examples/common/pigweed:locking_service.python", "${chip_root}/examples/common/pigweed:ot_cli_service.python", diff --git a/examples/fabric-admin/commands/pairing/PairingCommand.cpp b/examples/fabric-admin/commands/pairing/PairingCommand.cpp index 2e1cec184c2e3e..12a6a28f08aee7 100644 --- a/examples/fabric-admin/commands/pairing/PairingCommand.cpp +++ b/examples/fabric-admin/commands/pairing/PairingCommand.cpp @@ -567,7 +567,8 @@ void PairingCommand::OnCurrentFabricRemove(void * context, NodeId nodeId, CHIP_E #if defined(PW_RPC_ENABLED) app::InteractionModelEngine::GetInstance()->ShutdownSubscriptions(command->CurrentCommissioner().GetFabricIndex(), nodeId); - RemoveSynchronizedDevice(nodeId); + ScopedNodeId scopedNodeId(nodeId, command->CurrentCommissioner().GetFabricIndex()); + RemoveSynchronizedDevice(scopedNodeId); #endif } else diff --git a/examples/fabric-admin/device_manager/DeviceSubscription.cpp b/examples/fabric-admin/device_manager/DeviceSubscription.cpp index c41f73e0464cd3..a5625707a5363b 100644 --- a/examples/fabric-admin/device_manager/DeviceSubscription.cpp +++ b/examples/fabric-admin/device_manager/DeviceSubscription.cpp @@ -215,8 +215,10 @@ CHIP_ERROR DeviceSubscription::StartSubscription(OnDoneCallback onDoneCallback, mNodeId = nodeId; #if defined(PW_RPC_ENABLED) - mCurrentAdministratorCommissioningAttributes = chip_rpc_AdministratorCommissioningChanged_init_default; - mCurrentAdministratorCommissioningAttributes.node_id = nodeId; + mCurrentAdministratorCommissioningAttributes = chip_rpc_AdministratorCommissioningChanged_init_default; + mCurrentAdministratorCommissioningAttributes.has_id = true; + mCurrentAdministratorCommissioningAttributes.id.node_id = nodeId; + mCurrentAdministratorCommissioningAttributes.id.fabric_index = controller.GetFabricIndex(); mCurrentAdministratorCommissioningAttributes.window_status = static_cast(Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kWindowNotOpen); #endif diff --git a/examples/fabric-admin/device_manager/DeviceSynchronization.cpp b/examples/fabric-admin/device_manager/DeviceSynchronization.cpp index e70a968d726280..ec350239d7be38 100644 --- a/examples/fabric-admin/device_manager/DeviceSynchronization.cpp +++ b/examples/fabric-admin/device_manager/DeviceSynchronization.cpp @@ -205,10 +205,12 @@ void DeviceSynchronizer::StartDeviceSynchronization(Controller::DeviceController mNodeId = nodeId; #if defined(PW_RPC_ENABLED) - mCurrentDeviceData = chip_rpc_SynchronizedDevice_init_default; - mCurrentDeviceData.node_id = nodeId; - mCurrentDeviceData.has_is_icd = true; - mCurrentDeviceData.is_icd = deviceIsIcd; + mCurrentDeviceData = chip_rpc_SynchronizedDevice_init_default; + mCurrentDeviceData.has_id = true; + mCurrentDeviceData.id.node_id = nodeId; + mCurrentDeviceData.id.fabric_index = controller->GetFabricIndex(); + mCurrentDeviceData.has_is_icd = true; + mCurrentDeviceData.is_icd = deviceIsIcd; #endif ReturnOnFailure(controller->GetConnectedDevice(nodeId, &mOnDeviceConnectedCallback, &mOnDeviceConnectionFailureCallback)); diff --git a/examples/fabric-admin/rpc/RpcClient.cpp b/examples/fabric-admin/rpc/RpcClient.cpp index 9d094a6e102566..e33dd0472e6fe2 100644 --- a/examples/fabric-admin/rpc/RpcClient.cpp +++ b/examples/fabric-admin/rpc/RpcClient.cpp @@ -144,12 +144,14 @@ CHIP_ERROR AddSynchronizedDevice(const chip_rpc_SynchronizedDevice & data) return WaitForResponse(call); } -CHIP_ERROR RemoveSynchronizedDevice(NodeId nodeId) +CHIP_ERROR RemoveSynchronizedDevice(ScopedNodeId scopedNodeId) { ChipLogProgress(NotSpecified, "RemoveSynchronizedDevice"); chip_rpc_SynchronizedDevice device = chip_rpc_SynchronizedDevice_init_default; - device.node_id = nodeId; + device.has_id = true; + device.id.node_id = scopedNodeId.GetNodeId(); + device.id.fabric_index = scopedNodeId.GetFabricIndex(); // 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. @@ -164,12 +166,14 @@ CHIP_ERROR RemoveSynchronizedDevice(NodeId nodeId) return WaitForResponse(call); } -CHIP_ERROR ActiveChanged(NodeId nodeId, uint32_t promisedActiveDurationMs) +CHIP_ERROR ActiveChanged(ScopedNodeId scopedNodeId, uint32_t promisedActiveDurationMs) { ChipLogProgress(NotSpecified, "ActiveChanged"); chip_rpc_KeepActiveChanged parameters; - parameters.node_id = nodeId; + parameters.has_id = true; + parameters.id.node_id = scopedNodeId.GetNodeId(); + parameters.id.fabric_index = scopedNodeId.GetFabricIndex(); parameters.promised_active_duration_ms = promisedActiveDurationMs; // The RPC call is kept alive until it completes. When a response is received, it will be logged by the handler diff --git a/examples/fabric-admin/rpc/RpcClient.h b/examples/fabric-admin/rpc/RpcClient.h index 41d37cf85191b8..da6a82115a3cd2 100644 --- a/examples/fabric-admin/rpc/RpcClient.h +++ b/examples/fabric-admin/rpc/RpcClient.h @@ -18,6 +18,7 @@ #pragma once +#include #include #include "fabric_bridge_service/fabric_bridge_service.rpc.pb.h" @@ -57,25 +58,25 @@ CHIP_ERROR AddSynchronizedDevice(const chip_rpc_SynchronizedDevice & data); * It logs the progress and checks if a `RemoveSynchronizedDevice` 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 removed. + * @param scopedNodeId The Scoped Node ID of the device to be removed. * @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 RemoveSynchronizedDevice(chip::NodeId nodeId); +CHIP_ERROR RemoveSynchronizedDevice(chip::ScopedNodeId scopedNodeId); /** * @brief Received StayActiveResponse on behalf of client that previously called KeepActive * - * @param nodeId The Node ID of the device we recieved a StayActiveResponse. + * @param scopedNodeId The Scoped Node ID of the device we recieved a StayActiveResponse. * @param promisedActiveDurationMs the computed duration (in milliseconds) that the ICD intends to stay active for. * @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 ActiveChanged(chip::NodeId nodeId, uint32_t promisedActiveDurationMs); +CHIP_ERROR ActiveChanged(chip::ScopedNodeId scopedNodeId, uint32_t promisedActiveDurationMs); /** * @brief CADMIN attribute has changed of one of the bridged devices that was previously added. diff --git a/examples/fabric-admin/rpc/RpcServer.cpp b/examples/fabric-admin/rpc/RpcServer.cpp index d5e072305fe0dc..d68eb11786086e 100644 --- a/examples/fabric-admin/rpc/RpcServer.cpp +++ b/examples/fabric-admin/rpc/RpcServer.cpp @@ -42,6 +42,17 @@ namespace { #if defined(PW_RPC_FABRIC_ADMIN_SERVICE) && PW_RPC_FABRIC_ADMIN_SERVICE +struct ScopedNodeIdHasher +{ + std::size_t operator()(const chip::ScopedNodeId & scopedNodeId) const + { + std::size_t h1 = std::hash{}(scopedNodeId.GetFabricIndex()); + std::size_t h2 = std::hash{}(scopedNodeId.GetNodeId()); + // Bitshifting h2 reduces collisions when fabricIndex == nodeId. + return h1 ^ (h2 << 1); + } +}; + class FabricAdmin final : public rpc::FabricAdmin, public IcdManager::Delegate { public: @@ -49,22 +60,22 @@ class FabricAdmin final : public rpc::FabricAdmin, public IcdManager::Delegate { // Accessing mPendingCheckIn should only be done while holding ChipStackLock assertChipStackLockedByCurrentThread(); - NodeId nodeId = clientInfo.peer_node.GetNodeId(); - auto it = mPendingCheckIn.find(nodeId); + ScopedNodeId scopedNodeId = clientInfo.peer_node; + auto it = mPendingCheckIn.find(scopedNodeId); VerifyOrReturn(it != mPendingCheckIn.end()); KeepActiveDataForCheckIn checkInData = it->second; // Removed from pending map as check-in from this node has occured and we will handle the pending KeepActive // request. - mPendingCheckIn.erase(nodeId); + mPendingCheckIn.erase(scopedNodeId); auto timeNow = System::SystemClock().GetMonotonicTimestamp(); if (timeNow > checkInData.mRequestExpiryTimestamp) { - ChipLogError( - NotSpecified, - "ICD check-in for device we have been waiting, came after KeepActive expiry. Reqeust dropped for Node ID: 0x%lx", - nodeId); + ChipLogError(NotSpecified, + "ICD check-in for device we have been waiting, came after KeepActive expiry. Request dropped for ID: " + "[%d:0x " ChipLogFormatX64 "]", + scopedNodeId.GetFabricIndex(), ChipLogValueX64(scopedNodeId.GetNodeId())); return; } @@ -74,7 +85,7 @@ class FabricAdmin final : public rpc::FabricAdmin, public IcdManager::Delegate // there is no mechanism for us to communicate with the client that sent out the KeepActive // command that there was a failure, we simply fail silently. After spec issue is // addressed, we can implement what spec defines here. - auto onDone = [=](uint32_t promisedActiveDuration) { ActiveChanged(nodeId, promisedActiveDuration); }; + auto onDone = [=](uint32_t promisedActiveDuration) { ActiveChanged(scopedNodeId, promisedActiveDuration); }; CHIP_ERROR err = StayActiveSender::SendStayActiveCommand(checkInData.mStayActiveDurationMs, clientInfo.peer_node, app::InteractionModelEngine::GetInstance(), onDone); if (err != CHIP_NO_ERROR) @@ -86,7 +97,10 @@ class FabricAdmin final : public rpc::FabricAdmin, public IcdManager::Delegate pw::Status OpenCommissioningWindow(const chip_rpc_DeviceCommissioningWindowInfo & request, chip_rpc_OperationStatus & response) override { - NodeId nodeId = request.node_id; + VerifyOrReturnValue(request.has_id, pw::Status::InvalidArgument()); + // TODO(#35875): OpenDeviceCommissioningWindow uses the same controller every time and doesn't currently accept + // FabricIndex. For now we are dropping fabric index from the scoped node id. + NodeId nodeId = request.id.node_id; uint32_t commissioningTimeoutSec = request.commissioning_timeout; uint32_t iterations = request.iterations; uint16_t discriminator = request.discriminator; @@ -149,18 +163,19 @@ class FabricAdmin final : public rpc::FabricAdmin, public IcdManager::Delegate pw::Status KeepActive(const chip_rpc_KeepActiveParameters & request, pw_protobuf_Empty & response) override { - ChipLogProgress(NotSpecified, "Received KeepActive request: 0x%lx, %u", request.node_id, request.stay_active_duration_ms); - // TODO(#33221): We should really be using ScopedNode, but that requires larger fix in communication between - // fabric-admin and fabric-bridge. For now we make the assumption that there is only one fabric used by - // fabric-admin. + VerifyOrReturnValue(request.has_id, pw::Status::InvalidArgument()); + ScopedNodeId scopedNodeId(request.id.node_id, request.id.fabric_index); + ChipLogProgress(NotSpecified, "Received KeepActive request: Id[%d, 0x" ChipLogFormatX64 "], %u", + scopedNodeId.GetFabricIndex(), ChipLogValueX64(scopedNodeId.GetNodeId()), request.stay_active_duration_ms); + KeepActiveWorkData * data = - Platform::New(this, request.node_id, request.stay_active_duration_ms, request.timeout_ms); + Platform::New(this, scopedNodeId, request.stay_active_duration_ms, request.timeout_ms); VerifyOrReturnValue(data, pw::Status::Internal()); DeviceLayer::PlatformMgr().ScheduleWork(KeepActiveWork, reinterpret_cast(data)); return pw::OkStatus(); } - void ScheduleSendingKeepActiveOnCheckIn(NodeId nodeId, uint32_t stayActiveDurationMs, uint32_t timeoutMs) + void ScheduleSendingKeepActiveOnCheckIn(ScopedNodeId scopedNodeId, uint32_t stayActiveDurationMs, uint32_t timeoutMs) { // Accessing mPendingCheckIn should only be done while holding ChipStackLock assertChipStackLockedByCurrentThread(); @@ -170,14 +185,14 @@ class FabricAdmin final : public rpc::FabricAdmin, public IcdManager::Delegate KeepActiveDataForCheckIn checkInData = { .mStayActiveDurationMs = stayActiveDurationMs, .mRequestExpiryTimestamp = expiryTimestamp }; - auto it = mPendingCheckIn.find(nodeId); + auto it = mPendingCheckIn.find(scopedNodeId); if (it != mPendingCheckIn.end()) { checkInData.mStayActiveDurationMs = std::max(checkInData.mStayActiveDurationMs, it->second.mStayActiveDurationMs); checkInData.mRequestExpiryTimestamp = std::max(checkInData.mRequestExpiryTimestamp, it->second.mRequestExpiryTimestamp); } - mPendingCheckIn[nodeId] = checkInData; + mPendingCheckIn[scopedNodeId] = checkInData; } private: @@ -189,12 +204,14 @@ class FabricAdmin final : public rpc::FabricAdmin, public IcdManager::Delegate struct KeepActiveWorkData { - KeepActiveWorkData(FabricAdmin * fabricAdmin, NodeId nodeId, uint32_t stayActiveDurationMs, uint32_t timeoutMs) : - mFabricAdmin(fabricAdmin), mNodeId(nodeId), mStayActiveDurationMs(stayActiveDurationMs), mTimeoutMs(timeoutMs) + KeepActiveWorkData(FabricAdmin * fabricAdmin, ScopedNodeId scopedNodeId, uint32_t stayActiveDurationMs, + uint32_t timeoutMs) : + mFabricAdmin(fabricAdmin), + mScopedNodeId(scopedNodeId), mStayActiveDurationMs(stayActiveDurationMs), mTimeoutMs(timeoutMs) {} FabricAdmin * mFabricAdmin; - NodeId mNodeId; + ScopedNodeId mScopedNodeId; uint32_t mStayActiveDurationMs; uint32_t mTimeoutMs; }; @@ -202,14 +219,14 @@ class FabricAdmin final : public rpc::FabricAdmin, public IcdManager::Delegate static void KeepActiveWork(intptr_t arg) { KeepActiveWorkData * data = reinterpret_cast(arg); - data->mFabricAdmin->ScheduleSendingKeepActiveOnCheckIn(data->mNodeId, data->mStayActiveDurationMs, data->mTimeoutMs); + data->mFabricAdmin->ScheduleSendingKeepActiveOnCheckIn(data->mScopedNodeId, data->mStayActiveDurationMs, data->mTimeoutMs); Platform::Delete(data); } // Modifications to mPendingCheckIn should be done on the MatterEventLoop thread // otherwise we would need a mutex protecting this data to prevent race as this // data is accessible by both RPC thread and Matter eventloop. - std::unordered_map mPendingCheckIn; + std::unordered_map mPendingCheckIn; }; FabricAdmin fabric_admin_service; 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 0de35ecbfa32e8..526ecfff2157f2 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h +++ b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h @@ -49,7 +49,7 @@ class BridgedDevice std::optional openerVendorId = std::nullopt; }; - BridgedDevice(chip::NodeId nodeId); + BridgedDevice(chip::ScopedNodeId scopedNodeId); virtual ~BridgedDevice() = default; [[nodiscard]] bool IsReachable() const { return mReachable; } @@ -62,7 +62,7 @@ class BridgedDevice inline void SetEndpointId(chip::EndpointId id) { mEndpointId = id; }; inline chip::EndpointId GetEndpointId() { return mEndpointId; }; - inline chip::NodeId GetNodeId() { return mNodeId; }; + inline chip::ScopedNodeId GetScopedNodeId() { return mScopedNodeId; }; inline void SetParentEndpointId(chip::EndpointId id) { mParentEndpointId = id; }; inline chip::EndpointId GetParentEndpointId() { return mParentEndpointId; }; @@ -80,7 +80,7 @@ class BridgedDevice bool mReachable = false; bool mIsIcd = false; - chip::NodeId mNodeId = 0; + chip::ScopedNodeId mScopedNodeId; chip::EndpointId mEndpointId = 0; chip::EndpointId mParentEndpointId = 0; 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 ac28d31edf507c..127898fc5b2fab 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDeviceManager.h +++ b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDeviceManager.h @@ -82,28 +82,27 @@ class BridgedDeviceManager BridgedDevice * GetDevice(chip::EndpointId endpointId) const; /** - * @brief Gets a device from its NodeId. + * @brief Gets a device from its ScopedNodeId. * * This function iterates through the available devices and returns the device that matches the - * specified NodeId. If no device matches the NodeId, it returns nullptr. + * specified ScopedNodeId. If no device matches the ScopedNodeId, it returns nullptr. * - * @param nodeId The NodeId of the device to be retrieved. + * @param scopedNodeId The ScopedNodeId of the device to be retrieved. * @return BridgedDevice* A pointer to the device if found, nullptr otherwise. */ - BridgedDevice * GetDeviceByNodeId(chip::NodeId nodeId) const; + BridgedDevice * GetDeviceByScopedNodeId(chip::ScopedNodeId scopedNodeId) const; /** - * @brief Removes a device from a dynamic endpoint by its NodeId. + * @brief Removes a device from a dynamic endpoint by its ScopedNodeId. * - * This function attempts to remove a device from a dynamic endpoint by iterating through the - * available endpoints and checking if the device matches the specified NodeId. If the device is - * found, it clears the dynamic endpoint, logs the removal, and returns the index of the removed - * endpoint. If the device is not found, it returns -1. + * This function attempts to remove a device and the associated dynamic endpoint by iterating through + * the available device and checking if the device matches the specified ScopedNodeId. If the device is + * found, it removes the dynamic endpoint. * - * @param nodeId The NodeId of the device to be removed. - * @return int The index of the removed dynamic endpoint if successful, -1 otherwise. + * @param scopedNodeId The ScopedNodeId of the device to be removed. + * @return unsigned of the index of the removed dynamic endpoint if successful, nullopt otherwise. */ - std::optional RemoveDeviceByNodeId(chip::NodeId nodeId); + std::optional RemoveDeviceByScopedNodeId(chip::ScopedNodeId scopedNodeId); /** * Finds the device with the given unique id (if any) 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 27364976d121f5..02bdfbdbcbf75f 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDevice.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDevice.cpp @@ -82,11 +82,11 @@ void ReportAttributeChangedWork(intptr_t arg) using namespace chip::app::Clusters::Actions; -BridgedDevice::BridgedDevice(chip::NodeId nodeId) +BridgedDevice::BridgedDevice(chip::ScopedNodeId scopedNodeId) { - mReachable = false; - mNodeId = nodeId; - mEndpointId = chip::kInvalidEndpointId; + mReachable = false; + mScopedNodeId = scopedNodeId; + mEndpointId = chip::kInvalidEndpointId; } void BridgedDevice::LogActiveChangeEvent(uint32_t promisedActiveDurationMs) 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 7101918f9f5385..0265f912027ca0 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDeviceManager.cpp @@ -220,8 +220,9 @@ std::optional BridgedDeviceManager::AddDeviceEndpoint(std::unique_ptr< 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); + ChipLogProgress(NotSpecified, "Added device with Id=[%d:0x" ChipLogFormatX64 "] to dynamic endpoint %d (index=%d)", + dev->GetScopedNodeId().GetFabricIndex(), ChipLogValueX64(dev->GetScopedNodeId().GetNodeId()), + mCurrentEndpointId, index); mDevices[index] = std::move(dev); return index; } @@ -314,11 +315,11 @@ BridgedDevice * BridgedDeviceManager::GetDeviceByUniqueId(const std::string & id return nullptr; } -BridgedDevice * BridgedDeviceManager::GetDeviceByNodeId(chip::NodeId nodeId) const +BridgedDevice * BridgedDeviceManager::GetDeviceByScopedNodeId(chip::ScopedNodeId scopedNodeId) const { for (uint8_t index = 0; index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; ++index) { - if (mDevices[index] && mDevices[index]->GetNodeId() == nodeId) + if (mDevices[index] && mDevices[index]->GetScopedNodeId() == scopedNodeId) { return mDevices[index].get(); } @@ -326,17 +327,17 @@ BridgedDevice * BridgedDeviceManager::GetDeviceByNodeId(chip::NodeId nodeId) con return nullptr; } -std::optional BridgedDeviceManager::RemoveDeviceByNodeId(chip::NodeId nodeId) +std::optional BridgedDeviceManager::RemoveDeviceByScopedNodeId(chip::ScopedNodeId scopedNodeId) { for (unsigned index = 0; index < CHIP_DEVICE_CONFIG_DYNAMIC_ENDPOINT_COUNT; ++index) { - if (mDevices[index] && mDevices[index]->GetNodeId() == nodeId) + if (mDevices[index] && mDevices[index]->GetScopedNodeId() == scopedNodeId) { DeviceLayer::StackLock lock; EndpointId ep = emberAfClearDynamicEndpoint(index); mDevices[index] = nullptr; - ChipLogProgress(NotSpecified, "Removed device with NodeId=0x" ChipLogFormatX64 " from dynamic endpoint %d (index=%d)", - ChipLogValueX64(nodeId), ep, index); + ChipLogProgress(NotSpecified, "Removed device with Id=[%d:0x" ChipLogFormatX64 "] from dynamic endpoint %d (index=%d)", + scopedNodeId.GetFabricIndex(), ChipLogValueX64(scopedNodeId.GetNodeId()), ep, index); return index; } } diff --git a/examples/fabric-bridge-app/linux/RpcClient.cpp b/examples/fabric-bridge-app/linux/RpcClient.cpp index 3ef88e8ed7fec5..732fdf8aa1bf80 100644 --- a/examples/fabric-bridge-app/linux/RpcClient.cpp +++ b/examples/fabric-bridge-app/linux/RpcClient.cpp @@ -119,7 +119,8 @@ CHIP_ERROR StartRpcClient() CHIP_ERROR OpenCommissioningWindow(chip_rpc_DeviceCommissioningWindowInfo device) { - ChipLogProgress(NotSpecified, "OpenCommissioningWindow with Node Id 0x" ChipLogFormatX64, ChipLogValueX64(device.node_id)); + ChipLogProgress(NotSpecified, "OpenCommissioningWindow with Id=[%d:0x" ChipLogFormatX64 "]", device.id.fabric_index, + ChipLogValueX64(device.id.node_id)); // 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. @@ -135,22 +136,12 @@ CHIP_ERROR OpenCommissioningWindow(chip_rpc_DeviceCommissioningWindowInfo device } CHIP_ERROR -OpenCommissioningWindow(chip::Controller::CommissioningWindowPasscodeParams params) +OpenCommissioningWindow(chip::Controller::CommissioningWindowVerifierParams params, chip::FabricIndex fabricIndex) { chip_rpc_DeviceCommissioningWindowInfo device; - device.node_id = params.GetNodeId(); - device.commissioning_timeout = params.GetTimeout().count(); - device.discriminator = params.GetDiscriminator(); - device.iterations = params.GetIteration(); - - return OpenCommissioningWindow(device); -} - -CHIP_ERROR -OpenCommissioningWindow(chip::Controller::CommissioningWindowVerifierParams params) -{ - chip_rpc_DeviceCommissioningWindowInfo device; - device.node_id = params.GetNodeId(); + device.has_id = true; + device.id.node_id = params.GetNodeId(); + device.id.fabric_index = fabricIndex; device.commissioning_timeout = params.GetTimeout().count(); device.discriminator = params.GetDiscriminator(); device.iterations = params.GetIteration(); @@ -193,10 +184,12 @@ CommissionNode(chip::Controller::CommissioningWindowPasscodeParams params, Vendo return WaitForResponse(call); } -CHIP_ERROR KeepActive(chip::NodeId nodeId, uint32_t stayActiveDurationMs, uint32_t timeoutMs) +CHIP_ERROR KeepActive(chip::ScopedNodeId scopedNodeId, uint32_t stayActiveDurationMs, uint32_t timeoutMs) { chip_rpc_KeepActiveParameters params; - params.node_id = nodeId; + params.has_id = true; + params.id.node_id = scopedNodeId.GetNodeId(); + params.id.fabric_index = scopedNodeId.GetFabricIndex(); params.stay_active_duration_ms = stayActiveDurationMs; params.timeout_ms = timeoutMs; diff --git a/examples/fabric-bridge-app/linux/RpcServer.cpp b/examples/fabric-bridge-app/linux/RpcServer.cpp index bc8eed5c3dd9f0..8271cc3c49f041 100644 --- a/examples/fabric-bridge-app/linux/RpcServer.cpp +++ b/examples/fabric-bridge-app/linux/RpcServer.cpp @@ -52,10 +52,12 @@ class FabricBridge final : public chip::rpc::FabricBridge pw::Status FabricBridge::AddSynchronizedDevice(const chip_rpc_SynchronizedDevice & request, pw_protobuf_Empty & response) { - NodeId nodeId = request.node_id; - ChipLogProgress(NotSpecified, "Received AddSynchronizedDevice: " ChipLogFormatX64, ChipLogValueX64(nodeId)); + VerifyOrReturnValue(request.has_id, pw::Status::InvalidArgument()); + ScopedNodeId scopedNodeId(request.id.node_id, request.id.fabric_index); + ChipLogProgress(NotSpecified, "Received AddSynchronizedDevice: Id=[%d:" ChipLogFormatX64 "]", scopedNodeId.GetFabricIndex(), + ChipLogValueX64(scopedNodeId.GetNodeId())); - auto device = std::make_unique(nodeId); + auto device = std::make_unique(scopedNodeId); device->SetReachable(true); BridgedDevice::BridgedAttributes attributes; @@ -116,11 +118,12 @@ pw::Status FabricBridge::AddSynchronizedDevice(const chip_rpc_SynchronizedDevice auto result = BridgeDeviceMgr().AddDeviceEndpoint(std::move(device), 1 /* parentEndpointId */); if (!result.has_value()) { - ChipLogError(NotSpecified, "Failed to add device with nodeId=0x" ChipLogFormatX64, ChipLogValueX64(nodeId)); + ChipLogError(NotSpecified, "Failed to add device with Id=[%d:0x" ChipLogFormatX64 "]", scopedNodeId.GetFabricIndex(), + ChipLogValueX64(scopedNodeId.GetNodeId())); return pw::Status::Unknown(); } - BridgedDevice * addedDevice = BridgeDeviceMgr().GetDeviceByNodeId(nodeId); + BridgedDevice * addedDevice = BridgeDeviceMgr().GetDeviceByScopedNodeId(scopedNodeId); VerifyOrDie(addedDevice); CHIP_ERROR err = EcosystemInformation::EcosystemInformationServer::Instance().AddEcosystemInformationClusterToEndpoint( @@ -132,13 +135,16 @@ pw::Status FabricBridge::AddSynchronizedDevice(const chip_rpc_SynchronizedDevice pw::Status FabricBridge::RemoveSynchronizedDevice(const chip_rpc_SynchronizedDevice & request, pw_protobuf_Empty & response) { - NodeId nodeId = request.node_id; - ChipLogProgress(NotSpecified, "Received RemoveSynchronizedDevice: " ChipLogFormatX64, ChipLogValueX64(nodeId)); + VerifyOrReturnValue(request.has_id, pw::Status::InvalidArgument()); + ScopedNodeId scopedNodeId(request.id.node_id, request.id.fabric_index); + ChipLogProgress(NotSpecified, "Received RemoveSynchronizedDevice: Id=[%d:" ChipLogFormatX64 "]", scopedNodeId.GetFabricIndex(), + ChipLogValueX64(scopedNodeId.GetNodeId())); - auto removed_idx = BridgeDeviceMgr().RemoveDeviceByNodeId(nodeId); + auto removed_idx = BridgeDeviceMgr().RemoveDeviceByScopedNodeId(scopedNodeId); if (!removed_idx.has_value()) { - ChipLogError(NotSpecified, "Failed to remove device with nodeId=0x" ChipLogFormatX64, ChipLogValueX64(nodeId)); + ChipLogError(NotSpecified, "Failed to remove device with Id=[%d:0x" ChipLogFormatX64 "]", scopedNodeId.GetFabricIndex(), + ChipLogValueX64(scopedNodeId.GetNodeId())); return pw::Status::NotFound(); } @@ -147,14 +153,16 @@ pw::Status FabricBridge::RemoveSynchronizedDevice(const chip_rpc_SynchronizedDev pw::Status FabricBridge::ActiveChanged(const chip_rpc_KeepActiveChanged & request, pw_protobuf_Empty & response) { - NodeId nodeId = request.node_id; - ChipLogProgress(NotSpecified, "Received ActiveChanged: " ChipLogFormatX64, ChipLogValueX64(nodeId)); + VerifyOrReturnValue(request.has_id, pw::Status::InvalidArgument()); + ScopedNodeId scopedNodeId(request.id.node_id, request.id.fabric_index); + ChipLogProgress(NotSpecified, "Received ActiveChanged: Id=[%d:" ChipLogFormatX64 "]", scopedNodeId.GetFabricIndex(), + ChipLogValueX64(scopedNodeId.GetNodeId())); - auto * device = BridgeDeviceMgr().GetDeviceByNodeId(nodeId); + auto * device = BridgeDeviceMgr().GetDeviceByScopedNodeId(scopedNodeId); if (device == nullptr) { - ChipLogError(NotSpecified, "Could not find bridged device associated with nodeId=0x" ChipLogFormatX64, - ChipLogValueX64(nodeId)); + ChipLogError(NotSpecified, "Could not find bridged device associated with Id=[%d:0x" ChipLogFormatX64 "]", + scopedNodeId.GetFabricIndex(), ChipLogValueX64(scopedNodeId.GetNodeId())); return pw::Status::NotFound(); } @@ -165,14 +173,16 @@ pw::Status FabricBridge::ActiveChanged(const chip_rpc_KeepActiveChanged & reques pw::Status FabricBridge::AdminCommissioningAttributeChanged(const chip_rpc_AdministratorCommissioningChanged & request, pw_protobuf_Empty & response) { - NodeId nodeId = request.node_id; - ChipLogProgress(NotSpecified, "Received CADMIN attribut change: " ChipLogFormatX64, ChipLogValueX64(nodeId)); + VerifyOrReturnValue(request.has_id, pw::Status::InvalidArgument()); + ScopedNodeId scopedNodeId(request.id.node_id, request.id.fabric_index); + ChipLogProgress(NotSpecified, "Received CADMIN attribute change: Id=[%d:" ChipLogFormatX64 "]", scopedNodeId.GetFabricIndex(), + ChipLogValueX64(scopedNodeId.GetNodeId())); - auto * device = BridgeDeviceMgr().GetDeviceByNodeId(nodeId); + auto * device = BridgeDeviceMgr().GetDeviceByScopedNodeId(scopedNodeId); if (device == nullptr) { - ChipLogError(NotSpecified, "Could not find bridged device associated with nodeId=0x" ChipLogFormatX64, - ChipLogValueX64(nodeId)); + ChipLogError(NotSpecified, "Could not find bridged device associated with Id=[%d:0x" ChipLogFormatX64 "]", + scopedNodeId.GetFabricIndex(), ChipLogValueX64(scopedNodeId.GetNodeId())); return pw::Status::NotFound(); } diff --git a/examples/fabric-bridge-app/linux/include/CommissionerControl.h b/examples/fabric-bridge-app/linux/include/CommissionerControl.h index 61779e41919f3e..1188d9a796a4c5 100644 --- a/examples/fabric-bridge-app/linux/include/CommissionerControl.h +++ b/examples/fabric-bridge-app/linux/include/CommissionerControl.h @@ -30,6 +30,7 @@ class CommissionerControlDelegate : public Delegate { public: CHIP_ERROR HandleCommissioningApprovalRequest(const CommissioningApprovalRequest & request) override; + // TODO(#35627) clientNodeId should move towards ScopedNodeId. CHIP_ERROR ValidateCommissionNodeCommand(NodeId clientNodeId, uint64_t requestId) override; CHIP_ERROR GetCommissioningWindowParams(CommissioningWindowParams & outParams) override; CHIP_ERROR HandleCommissionNode(const CommissioningWindowParams & params) override; diff --git a/examples/fabric-bridge-app/linux/include/RpcClient.h b/examples/fabric-bridge-app/linux/include/RpcClient.h index 2455bc56c8400f..1ede84ff446ecd 100644 --- a/examples/fabric-bridge-app/linux/include/RpcClient.h +++ b/examples/fabric-bridge-app/linux/include/RpcClient.h @@ -19,6 +19,7 @@ #pragma once #include +#include #include /** @@ -37,18 +38,6 @@ void SetRpcRemoteServerPort(uint16_t port); */ CHIP_ERROR StartRpcClient(); -/** - * Opens a commissioning window for a specified node using setup PIN (passcode). - * - * @param params Params for opening the commissioning window using passcode. - * @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 commissioning window is currently in progress. - * - CHIP_ERROR_INTERNAL: An internal error occurred. - */ -CHIP_ERROR -OpenCommissioningWindow(chip::Controller::CommissioningWindowPasscodeParams params); - /** * Opens a commissioning window for a specified node using pre-computed PAKE passcode verifier. * @@ -59,7 +48,7 @@ OpenCommissioningWindow(chip::Controller::CommissioningWindowPasscodeParams para * - CHIP_ERROR_INTERNAL: An internal error occurred. */ CHIP_ERROR -OpenCommissioningWindow(chip::Controller::CommissioningWindowVerifierParams params); +OpenCommissioningWindow(chip::Controller::CommissioningWindowVerifierParams params, chip::FabricIndex fabricIndex); /** * Commission a node using the specified parameters. @@ -80,4 +69,4 @@ OpenCommissioningWindow(chip::Controller::CommissioningWindowVerifierParams para CHIP_ERROR CommissionNode(chip::Controller::CommissioningWindowPasscodeParams params, chip::VendorId vendorId, uint16_t productId); -CHIP_ERROR KeepActive(chip::NodeId nodeId, uint32_t stayActiveDurationMs, uint32_t timeoutMs); +CHIP_ERROR KeepActive(chip::ScopedNodeId scopedNodeId, uint32_t stayActiveDurationMs, uint32_t timeoutMs); diff --git a/examples/fabric-bridge-app/linux/main.cpp b/examples/fabric-bridge-app/linux/main.cpp index d08673ad12a7a6..2a793637128f27 100644 --- a/examples/fabric-bridge-app/linux/main.cpp +++ b/examples/fabric-bridge-app/linux/main.cpp @@ -122,20 +122,6 @@ void BridgePollingThread() ChipLogProgress(NotSpecified, "Exiting....."); exit(0); } -#if defined(PW_RPC_FABRIC_BRIDGE_SERVICE) && PW_RPC_FABRIC_BRIDGE_SERVICE - else if (ch == 'o') - { - CHIP_ERROR err = OpenCommissioningWindow(Controller::CommissioningWindowPasscodeParams() - .SetNodeId(0x1234) - .SetTimeout(300) - .SetDiscriminator(3840) - .SetIteration(1000)); - if (err != CHIP_NO_ERROR) - { - ChipLogError(NotSpecified, "Failed to call OpenCommissioningWindow RPC: %" CHIP_ERROR_FORMAT, err.Format()); - } - } -#endif // defined(PW_RPC_FABRIC_BRIDGE_SERVICE) && PW_RPC_FABRIC_BRIDGE_SERVICE continue; } @@ -201,19 +187,20 @@ void AdministratorCommissioningCommandHandler::InvokeCommand(HandlerContext & ha // TODO: issues:#33784, need to make OpenCommissioningWindow synchronous if (device != nullptr && OpenCommissioningWindow(Controller::CommissioningWindowVerifierParams() - .SetNodeId(device->GetNodeId()) + .SetNodeId(device->GetScopedNodeId().GetNodeId()) .SetTimeout(commandData.commissioningTimeout) .SetDiscriminator(commandData.discriminator) .SetIteration(commandData.iterations) .SetSalt(commandData.salt) - .SetVerifier(commandData.PAKEPasscodeVerifier)) == CHIP_NO_ERROR) + .SetVerifier(commandData.PAKEPasscodeVerifier), + device->GetScopedNodeId().GetFabricIndex()) == CHIP_NO_ERROR) { ChipLogProgress(NotSpecified, "Commissioning window is now open"); status = Status::Success; } else { - ChipLogProgress(NotSpecified, "Commissioning window is failed to open"); + ChipLogProgress(NotSpecified, "Commissioning window failed to open"); } #else ChipLogProgress(NotSpecified, "Commissioning window failed to open: PW_RPC_FABRIC_BRIDGE_SERVICE not defined"); @@ -268,7 +255,7 @@ void BridgedDeviceInformationCommandHandler::InvokeCommand(HandlerContext & hand Status status = Status::Failure; #if defined(PW_RPC_FABRIC_BRIDGE_SERVICE) && PW_RPC_FABRIC_BRIDGE_SERVICE - if (KeepActive(device->GetNodeId(), commandData.stayActiveDuration, commandData.timeoutMs) == CHIP_NO_ERROR) + if (KeepActive(device->GetScopedNodeId(), commandData.stayActiveDuration, commandData.timeoutMs) == CHIP_NO_ERROR) { ChipLogProgress(NotSpecified, "KeepActive successfully processed"); status = Status::Success;