Skip to content

Commit

Permalink
Add plumbing in FS example for TimeoutMs parameter in KeepActive (pro…
Browse files Browse the repository at this point in the history
…ject-chip#35174)


---------

Co-authored-by: Restyled.io <commits@restyled.io>
Co-authored-by: Yufeng Wang <yufengwang@google.com>
  • Loading branch information
3 people authored Aug 27, 2024
1 parent 4d4fcb3 commit 611347e
Show file tree
Hide file tree
Showing 5 changed files with 37 additions and 19 deletions.
1 change: 1 addition & 0 deletions examples/common/pigweed/protos/fabric_admin_service.proto
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ message DeviceCommissioningInfo {
message KeepActiveParameters {
uint64 node_id = 1;
uint32 stay_active_duration_ms = 2;
uint32 timeout_ms = 3;
}

// Define the response message to convey the status of the operation
Expand Down
27 changes: 18 additions & 9 deletions examples/fabric-admin/rpc/RpcServer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -151,23 +151,31 @@ class FabricAdmin final : public rpc::FabricAdmin, public IcdManager::Delegate
// 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.
KeepActiveWorkData * data = chip::Platform::New<KeepActiveWorkData>(this, request.node_id, request.stay_active_duration_ms);
KeepActiveWorkData * data =
Platform::New<KeepActiveWorkData>(this, request.node_id, request.stay_active_duration_ms, request.timeout_ms);
VerifyOrReturnValue(data, pw::Status::Internal());
chip::DeviceLayer::PlatformMgr().ScheduleWork(KeepActiveWork, reinterpret_cast<intptr_t>(data));
return pw::OkStatus();
}

void ScheduleSendingKeepActiveOnCheckIn(chip::NodeId nodeId, uint32_t stayActiveDurationMs)
void ScheduleSendingKeepActiveOnCheckIn(NodeId nodeId, uint32_t stayActiveDurationMs, uint32_t timeoutMs)
{
// Needs for accessing mPendingCheckIn
assertChipStackLockedByCurrentThread();

auto timeNow = System::SystemClock().GetMonotonicTimestamp();
// Spec says we should expire the request 60 mins after we get it
System::Clock::Timestamp expiryTimestamp = timeNow + System::Clock::Seconds64(60 * 60);
auto timeNow = System::SystemClock().GetMonotonicTimestamp();
System::Clock::Timestamp expiryTimestamp = timeNow + System::Clock::Milliseconds64(timeoutMs);
KeepActiveDataForCheckIn checkInData = { .mStayActiveDurationMs = stayActiveDurationMs,
.mRequestExpiryTimestamp = expiryTimestamp };
mPendingCheckIn[nodeId] = checkInData;

auto it = mPendingCheckIn.find(nodeId);
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;
}

private:
Expand All @@ -179,19 +187,20 @@ class FabricAdmin final : public rpc::FabricAdmin, public IcdManager::Delegate

struct KeepActiveWorkData
{
KeepActiveWorkData(FabricAdmin * fabricAdmin, chip::NodeId nodeId, uint32_t stayActiveDurationMs) :
mFabricAdmin(fabricAdmin), mNodeId(nodeId), mStayActiveDurationMs(stayActiveDurationMs)
KeepActiveWorkData(FabricAdmin * fabricAdmin, NodeId nodeId, uint32_t stayActiveDurationMs, uint32_t timeoutMs) :
mFabricAdmin(fabricAdmin), mNodeId(nodeId), mStayActiveDurationMs(stayActiveDurationMs), mTimeoutMs(timeoutMs)
{}

FabricAdmin * mFabricAdmin;
chip::NodeId mNodeId;
uint32_t mStayActiveDurationMs;
uint32_t mTimeoutMs;
};

static void KeepActiveWork(intptr_t arg)
{
KeepActiveWorkData * data = reinterpret_cast<KeepActiveWorkData *>(arg);
data->mFabricAdmin->ScheduleSendingKeepActiveOnCheckIn(data->mNodeId, data->mStayActiveDurationMs);
data->mFabricAdmin->ScheduleSendingKeepActiveOnCheckIn(data->mNodeId, data->mStayActiveDurationMs, data->mTimeoutMs);
chip::Platform::Delete(data);
}

Expand Down
3 changes: 2 additions & 1 deletion examples/fabric-bridge-app/linux/RpcClient.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,12 @@ CommissionNode(chip::Controller::CommissioningWindowPasscodeParams params, Vendo
return WaitForResponse(call);
}

CHIP_ERROR KeepActive(chip::NodeId nodeId, uint32_t stayActiveDurationMs)
CHIP_ERROR KeepActive(chip::NodeId nodeId, uint32_t stayActiveDurationMs, uint32_t timeoutMs)
{
chip_rpc_KeepActiveParameters params;
params.node_id = nodeId;
params.stay_active_duration_ms = stayActiveDurationMs;
params.timeout_ms = timeoutMs;

// 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.
Expand Down
2 changes: 1 addition & 1 deletion examples/fabric-bridge-app/linux/include/RpcClient.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,4 +76,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);
CHIP_ERROR KeepActive(chip::NodeId nodeId, uint32_t stayActiveDurationMs, uint32_t timeoutMs);
23 changes: 15 additions & 8 deletions examples/fabric-bridge-app/linux/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -199,27 +199,34 @@ void BridgedDeviceInformationCommandHandler::InvokeCommand(HandlerContext & hand
EndpointId endpointId = handlerContext.mRequestPath.mEndpointId;
ChipLogProgress(NotSpecified, "Received command to KeepActive on Endpoint: %d", endpointId);

BridgedDevice * device = BridgeDeviceMgr().GetDevice(endpointId);

handlerContext.SetCommandHandled();

if (device == nullptr || !device->IsIcd())
BridgedDeviceBasicInformation::Commands::KeepActive::DecodableType commandData;
if (DataModel::Decode(handlerContext.mPayload, commandData) != CHIP_NO_ERROR)
{
handlerContext.mCommandHandler.AddStatus(handlerContext.mRequestPath, Status::Failure);
handlerContext.mCommandHandler.AddStatus(handlerContext.mRequestPath, Status::InvalidCommand);
return;
}

BridgedDeviceBasicInformation::Commands::KeepActive::DecodableType commandData;
if (DataModel::Decode(handlerContext.mPayload, commandData) != CHIP_NO_ERROR)
const uint32_t kMinTimeoutMs = 30 * 1000;
const uint32_t kMaxTimeoutMs = 60 * 60 * 1000;
if (commandData.timeoutMs < kMinTimeoutMs || commandData.timeoutMs > kMaxTimeoutMs)
{
handlerContext.mCommandHandler.AddStatus(handlerContext.mRequestPath, Status::InvalidCommand);
handlerContext.mCommandHandler.AddStatus(handlerContext.mRequestPath, Status::ConstraintError);
return;
}

BridgedDevice * device = BridgeDeviceMgr().GetDevice(endpointId);
if (device == nullptr || !device->IsIcd())
{
handlerContext.mCommandHandler.AddStatus(handlerContext.mRequestPath, Status::Failure);
return;
}

Status status = Status::Failure;

#if defined(PW_RPC_FABRIC_BRIDGE_SERVICE) && PW_RPC_FABRIC_BRIDGE_SERVICE
if (KeepActive(device->GetNodeId(), commandData.stayActiveDuration) == CHIP_NO_ERROR)
if (KeepActive(device->GetNodeId(), commandData.stayActiveDuration, commandData.timeoutMs) == CHIP_NO_ERROR)
{
ChipLogProgress(NotSpecified, "KeepActive successfully processed");
status = Status::Success;
Expand Down

0 comments on commit 611347e

Please sign in to comment.