diff --git a/examples/common/pigweed/protos/fabric_bridge_service.proto b/examples/common/pigweed/protos/fabric_bridge_service.proto index 4e01d4ec5c7e78..f1312f22ea0e75 100644 --- a/examples/common/pigweed/protos/fabric_bridge_service.proto +++ b/examples/common/pigweed/protos/fabric_bridge_service.proto @@ -34,9 +34,15 @@ message AdministratorCommissioningChanged { optional uint32 opener_vendor_id = 4; } +message ReachabilityChanged { + ScopedNode id = 1; + bool reachability = 2; +} + service FabricBridge { rpc AddSynchronizedDevice(SynchronizedDevice) returns (pw.protobuf.Empty){} rpc RemoveSynchronizedDevice(SynchronizedDevice) returns (pw.protobuf.Empty){} rpc ActiveChanged(KeepActiveChanged) returns (pw.protobuf.Empty){} rpc AdminCommissioningAttributeChanged(AdministratorCommissioningChanged) returns (pw.protobuf.Empty){} + rpc DeviceReachableChanged(ReachabilityChanged) returns (pw.protobuf.Empty){} } diff --git a/examples/common/pigweed/rpc_services/FabricBridge.h b/examples/common/pigweed/rpc_services/FabricBridge.h index 9bd520278c13b4..9a1dee017e3be6 100644 --- a/examples/common/pigweed/rpc_services/FabricBridge.h +++ b/examples/common/pigweed/rpc_services/FabricBridge.h @@ -54,6 +54,11 @@ class FabricBridge : public pw_rpc::nanopb::FabricBridge::Service { return pw::Status::Unimplemented(); } + + virtual pw::Status DeviceReachableChanged(const chip_rpc_ReachabilityChanged & request, pw_protobuf_Empty & response) + { + return pw::Status::Unimplemented(); + } }; } // namespace rpc 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 526ecfff2157f2..d2c5a64b9ef4b7 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h +++ b/examples/fabric-bridge-app/fabric-bridge-common/include/BridgedDevice.h @@ -54,6 +54,9 @@ class BridgedDevice [[nodiscard]] bool IsReachable() const { return mReachable; } void SetReachable(bool reachable); + // Reachability attribute changed and requires marking attribute as dirty and sending + // event. + void ReachableChanged(bool reachable); void LogActiveChangeEvent(uint32_t promisedActiveDurationMs); 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 7d588112997570..f462d1cce6efd5 100644 --- a/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDevice.cpp +++ b/examples/fabric-bridge-app/fabric-bridge-common/src/BridgedDevice.cpp @@ -65,6 +65,29 @@ void BridgedDevice::SetReachable(bool reachable) } } +void BridgedDevice::ReachableChanged(bool reachable) +{ + EndpointId endpointId = mEndpointId; + bool reachableChanged = (mReachable != reachable); + if (reachableChanged) + { + SetReachable(reachable); + DeviceLayer::SystemLayer().ScheduleLambda([endpointId]() { + MatterReportingAttributeChangeCallback(endpointId, app::Clusters::BridgedDeviceBasicInformation::Id, + app::Clusters::BridgedDeviceBasicInformation::Attributes::Reachable::Id); + + app::Clusters::BridgedDeviceBasicInformation::Events::ReachableChanged::Type event{}; + EventNumber eventNumber = 0; + + CHIP_ERROR err = app::LogEvent(event, endpointId, eventNumber); + if (err != CHIP_NO_ERROR) + { + ChipLogProgress(NotSpecified, "LogEvent for ActiveChanged failed %s", err.AsString()); + } + }); + } +} + void BridgedDevice::SetAdminCommissioningAttributes(const AdminCommissioningAttributes & aAdminCommissioningAttributes) { EndpointId endpointId = mEndpointId; diff --git a/examples/fabric-bridge-app/linux/RpcServer.cpp b/examples/fabric-bridge-app/linux/RpcServer.cpp index 8271cc3c49f041..5fea43c6ef2953 100644 --- a/examples/fabric-bridge-app/linux/RpcServer.cpp +++ b/examples/fabric-bridge-app/linux/RpcServer.cpp @@ -48,6 +48,7 @@ class FabricBridge final : public chip::rpc::FabricBridge pw::Status ActiveChanged(const chip_rpc_KeepActiveChanged & request, pw_protobuf_Empty & response) override; pw::Status AdminCommissioningAttributeChanged(const chip_rpc_AdministratorCommissioningChanged & request, pw_protobuf_Empty & response) override; + pw::Status DeviceReachableChanged(const chip_rpc_ReachabilityChanged & request, pw_protobuf_Empty & response) override; }; pw::Status FabricBridge::AddSynchronizedDevice(const chip_rpc_SynchronizedDevice & request, pw_protobuf_Empty & response) @@ -210,6 +211,26 @@ pw::Status FabricBridge::AdminCommissioningAttributeChanged(const chip_rpc_Admin return pw::OkStatus(); } +pw::Status FabricBridge::DeviceReachableChanged(const chip_rpc_ReachabilityChanged & request, pw_protobuf_Empty & response) +{ + VerifyOrReturnValue(request.has_id, pw::Status::InvalidArgument()); + ScopedNodeId scopedNodeId(request.id.node_id, request.id.fabric_index); + ChipLogProgress(NotSpecified, "Received device reachable changed: Id=[%d:" ChipLogFormatX64 "]", scopedNodeId.GetFabricIndex(), + ChipLogValueX64(scopedNodeId.GetNodeId())); + + auto * device = BridgeDeviceMgr().GetDeviceByScopedNodeId(scopedNodeId); + if (device == nullptr) + { + ChipLogError(NotSpecified, "Could not find bridged device associated with Id=[%d:0x" ChipLogFormatX64 "]", + scopedNodeId.GetFabricIndex(), ChipLogValueX64(scopedNodeId.GetNodeId())); + return pw::Status::NotFound(); + } + + device->ReachableChanged(request.reachability); + + return pw::OkStatus(); +} + FabricBridge fabric_bridge_service; #endif // defined(PW_RPC_FABRIC_BRIDGE_SERVICE) && PW_RPC_FABRIC_BRIDGE_SERVICE