Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Plumbing for CADMIN attribute updates from fabric-admin to fabric-bridge #35222

Merged
merged 8 commits into from
Aug 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions examples/common/pigweed/protos/fabric_bridge_service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,16 @@ message KeepActiveChanged {
uint32 promised_active_duration_ms = 2;
}

message AdministratorCommissioningChanged {
uint64 node_id = 1;
uint32 window_status = 2;
optional uint32 opener_fabric_index = 3;
optional uint32 opener_vendor_id = 4;
}

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){}
}
6 changes: 6 additions & 0 deletions examples/common/pigweed/rpc_services/FabricBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ class FabricBridge : public pw_rpc::nanopb::FabricBridge::Service<FabricBridge>
{
return pw::Status::Unimplemented();
}

virtual pw::Status AdminCommissioningAttributeChanged(const chip_rpc_AdministratorCommissioningChanged & request,
pw_protobuf_Empty & response)
{
return pw::Status::Unimplemented();
}
};

} // namespace rpc
Expand Down
17 changes: 17 additions & 0 deletions examples/fabric-admin/rpc/RpcClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -180,3 +180,20 @@ CHIP_ERROR ActiveChanged(chip::NodeId nodeId, uint32_t promisedActiveDurationMs)

return WaitForResponse(call);
}

CHIP_ERROR AdminCommissioningAttributeChanged(const chip_rpc_AdministratorCommissioningChanged & data)
{
ChipLogProgress(NotSpecified, "AdminCommissioningAttributeChanged");

// 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.AdminCommissioningAttributeChanged(data, RpcCompletedWithEmptyResponse);

if (!call.active())
{
// The RPC call was not sent. This could occur due to, for example, an invalid channel ID. Handle if necessary.
return CHIP_ERROR_INTERNAL;
}

return WaitForResponse(call);
}
11 changes: 11 additions & 0 deletions examples/fabric-admin/rpc/RpcClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,14 @@ CHIP_ERROR RemoveSynchronizedDevice(chip::NodeId nodeId);
* - CHIP_ERROR_INTERNAL: An internal error occurred while activating the RPC call.
*/
CHIP_ERROR ActiveChanged(chip::NodeId nodeId, uint32_t promisedActiveDurationMs);

/**
* @brief CADMIN attribute has changed of one of the bridged devices that was previously added.
*
* @param data information regarding change in AdministratorCommissioning attributes
* @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 AdminCommissioningAttributeChanged(const chip_rpc_AdministratorCommissioningChanged & data);
tehampson marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,8 @@ class BridgedDevice

[[nodiscard]] const BridgedAttributes & GetBridgedAttributes() const { return mAttributes; }
void SetBridgedAttributes(const BridgedAttributes & value) { mAttributes = value; }
// TODO(#35077): Need to allow mAdminCommissioningAttributes to be set from fabric-admin.

void SetAdminCommissioningAttributes(const AdminCommissioningAttributes & aAdminCommissioningAttributes);
const AdminCommissioningAttributes & GetAdminCommissioningAttributes() const { return mAdminCommissioningAttributes; }

/// Convenience method to set just the unique id of a bridged device as it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <cstdio>

#include <app/EventLogging.h>
#include <app/reporting/reporting.h>
#include <platform/CHIPDeviceLayer.h>

namespace {
Expand All @@ -31,6 +32,14 @@ struct ActiveChangeEventWorkData
uint32_t mPromisedActiveDuration;
};

struct ReportAttributeChangedWorkData
{
chip::EndpointId mEndpointId;
bool mWindowChanged = false;
bool mFabricIndexChanged = false;
bool mVendorChanged = false;
};

void ActiveChangeEventWork(intptr_t arg)
{
ActiveChangeEventWorkData * data = reinterpret_cast<ActiveChangeEventWorkData *>(arg);
Expand All @@ -47,6 +56,28 @@ void ActiveChangeEventWork(intptr_t arg)
chip::Platform::Delete(data);
}

void ReportAttributeChangedWork(intptr_t arg)
{
ReportAttributeChangedWorkData * data = reinterpret_cast<ReportAttributeChangedWorkData *>(arg);

if (data->mWindowChanged)
{
MatterReportingAttributeChangeCallback(data->mEndpointId, chip::app::Clusters::AdministratorCommissioning::Id,
chip::app::Clusters::AdministratorCommissioning::Attributes::WindowStatus::Id);
}
if (data->mFabricIndexChanged)
{
MatterReportingAttributeChangeCallback(data->mEndpointId, chip::app::Clusters::AdministratorCommissioning::Id,
chip::app::Clusters::AdministratorCommissioning::Attributes::AdminFabricIndex::Id);
}
if (data->mVendorChanged)
{
MatterReportingAttributeChangeCallback(data->mEndpointId, chip::app::Clusters::AdministratorCommissioning::Id,
chip::app::Clusters::AdministratorCommissioning::Attributes::AdminVendorId::Id);
}
chip::Platform::Delete(data);
}

} // namespace

using namespace chip::app::Clusters::Actions;
Expand Down Expand Up @@ -80,3 +111,18 @@ void BridgedDevice::SetReachable(bool reachable)
ChipLogProgress(NotSpecified, "BridgedDevice[%s]: OFFLINE", mAttributes.uniqueId.c_str());
}
}

void BridgedDevice::SetAdminCommissioningAttributes(const AdminCommissioningAttributes & aAdminCommissioningAttributes)
{
ReportAttributeChangedWorkData * workdata = chip::Platform::New<ReportAttributeChangedWorkData>();

workdata->mEndpointId = mEndpointId;
workdata->mWindowChanged =
(aAdminCommissioningAttributes.commissioningWindowStatus != mAdminCommissioningAttributes.commissioningWindowStatus);
workdata->mFabricIndexChanged =
(aAdminCommissioningAttributes.openerFabricIndex != mAdminCommissioningAttributes.openerFabricIndex);
workdata->mVendorChanged = (aAdminCommissioningAttributes.openerVendorId != mAdminCommissioningAttributes.openerVendorId);

mAdminCommissioningAttributes = aAdminCommissioningAttributes;
chip::DeviceLayer::PlatformMgr().ScheduleWork(ReportAttributeChangedWork, reinterpret_cast<intptr_t>(workdata));
}
40 changes: 40 additions & 0 deletions examples/fabric-bridge-app/linux/RpcServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,8 @@ class FabricBridge final : public chip::rpc::FabricBridge
pw::Status AddSynchronizedDevice(const chip_rpc_SynchronizedDevice & request, pw_protobuf_Empty & response) override;
pw::Status RemoveSynchronizedDevice(const chip_rpc_SynchronizedDevice & request, pw_protobuf_Empty & response) override;
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 FabricBridge::AddSynchronizedDevice(const chip_rpc_SynchronizedDevice & request, pw_protobuf_Empty & response)
Expand Down Expand Up @@ -160,6 +162,44 @@ pw::Status FabricBridge::ActiveChanged(const chip_rpc_KeepActiveChanged & reques
return pw::OkStatus();
}

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));

auto * device = BridgeDeviceMgr().GetDeviceByNodeId(nodeId);
if (device == nullptr)
{
ChipLogError(NotSpecified, "Could not find bridged device associated with nodeId=0x" ChipLogFormatX64,
ChipLogValueX64(nodeId));
return pw::Status::NotFound();
}

BridgedDevice::AdminCommissioningAttributes adminCommissioningAttributes;

uint32_t max_window_status_value =
static_cast<uint32_t>(chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum::kUnknownEnumValue);
VerifyOrReturnValue(request.window_status < max_window_status_value, pw::Status::InvalidArgument());
adminCommissioningAttributes.commissioningWindowStatus =
static_cast<chip::app::Clusters::AdministratorCommissioning::CommissioningWindowStatusEnum>(request.window_status);
if (request.has_opener_fabric_index)
{
VerifyOrReturnValue(request.opener_fabric_index >= chip::kMinValidFabricIndex, pw::Status::InvalidArgument());
VerifyOrReturnValue(request.opener_fabric_index <= chip::kMaxValidFabricIndex, pw::Status::InvalidArgument());
adminCommissioningAttributes.openerFabricIndex = static_cast<FabricIndex>(request.opener_fabric_index);
}

if (request.has_opener_vendor_id)
{
VerifyOrReturnValue(request.opener_vendor_id != chip::VendorId::NotSpecified, pw::Status::InvalidArgument());
adminCommissioningAttributes.openerVendorId = static_cast<chip::VendorId>(request.opener_vendor_id);
}

device->SetAdminCommissioningAttributes(adminCommissioningAttributes);
return pw::OkStatus();
}

FabricBridge fabric_bridge_service;
#endif // defined(PW_RPC_FABRIC_BRIDGE_SERVICE) && PW_RPC_FABRIC_BRIDGE_SERVICE

Expand Down
Loading