@@ -47,20 +47,32 @@ class FabricAdmin final : public rpc::FabricAdmin, public IcdManager::Delegate
47
47
public:
48
48
void OnCheckInCompleted (const chip::app::ICDClientInfo & clientInfo) override
49
49
{
50
- chip::NodeId nodeId = clientInfo.peer_node .GetNodeId ();
51
- auto it = mPendingKeepActiveTimesMs .find (nodeId);
52
- VerifyOrReturn (it != mPendingKeepActiveTimesMs .end ());
53
- // TODO(#33221): We also need a mechanism here to drop KeepActive
54
- // request if they were recieved over 60 mins ago.
55
- uint32_t stayActiveDurationMs = it->second ;
50
+ // Needs for accessing mPendingCheckIn
51
+ assertChipStackLockedByCurrentThread ();
52
+ NodeId nodeId = clientInfo.peer_node .GetNodeId ();
53
+ auto it = mPendingCheckIn .find (nodeId);
54
+ VerifyOrReturn (it != mPendingCheckIn .end ());
55
+
56
+ KeepActiveDataForCheckIn checkInData = it->second ;
57
+ // Removed from pending map as check-in from this node has occured and we will handle the pending KeepActive
58
+ // request.
59
+ mPendingCheckIn .erase (nodeId);
60
+
61
+ auto timeNow = System::SystemClock ().GetMonotonicTimestamp ();
62
+ if (timeNow > checkInData.mRequestExpiryTimestamp )
63
+ {
64
+ ChipLogError (
65
+ NotSpecified,
66
+ " ICD check-in for device we have been waiting, came after KeepActive expiry. Reqeust dropped for Node ID: 0x%lx" ,
67
+ nodeId);
68
+ return ;
69
+ }
56
70
57
71
// TODO(#33221): If there is a failure in sending the message this request just gets dropped.
58
72
// Work to see if there should be update to spec on whether some sort of failure later on
59
73
// Should be indicated in some manner, or identify a better recovery mechanism here.
60
- mPendingKeepActiveTimesMs .erase (nodeId);
61
-
62
74
auto onDone = [=](uint32_t promisedActiveDuration) { ActiveChanged (nodeId, promisedActiveDuration); };
63
- CHIP_ERROR err = StayActiveSender::SendStayActiveCommand (stayActiveDurationMs , clientInfo.peer_node ,
75
+ CHIP_ERROR err = StayActiveSender::SendStayActiveCommand (checkInData. mStayActiveDurationMs , clientInfo.peer_node ,
64
76
chip::app::InteractionModelEngine::GetInstance (), onDone);
65
77
if (err != CHIP_NO_ERROR)
66
78
{
@@ -147,10 +159,24 @@ class FabricAdmin final : public rpc::FabricAdmin, public IcdManager::Delegate
147
159
148
160
void ScheduleSendingKeepActiveOnCheckIn (chip::NodeId nodeId, uint32_t stayActiveDurationMs)
149
161
{
150
- mPendingKeepActiveTimesMs [nodeId] = stayActiveDurationMs;
162
+ // Needs for accessing mPendingCheckIn
163
+ assertChipStackLockedByCurrentThread ();
164
+
165
+ auto timeNow = System::SystemClock ().GetMonotonicTimestamp ();
166
+ // Spec says we should expire the request 60 mins after we get it
167
+ System::Clock::Timestamp expiryTimestamp = timeNow + System::Clock::Seconds64 (60 * 60 );
168
+ KeepActiveDataForCheckIn checkInData = { .mStayActiveDurationMs = stayActiveDurationMs,
169
+ .mRequestExpiryTimestamp = expiryTimestamp };
170
+ mPendingCheckIn [nodeId] = checkInData;
151
171
}
152
172
153
173
private:
174
+ struct KeepActiveDataForCheckIn
175
+ {
176
+ uint32_t mStayActiveDurationMs = 0 ;
177
+ System::Clock::Timestamp mRequestExpiryTimestamp ;
178
+ };
179
+
154
180
struct KeepActiveWorkData
155
181
{
156
182
KeepActiveWorkData (FabricAdmin * fabricAdmin, chip::NodeId nodeId, uint32_t stayActiveDurationMs) :
@@ -169,8 +195,10 @@ class FabricAdmin final : public rpc::FabricAdmin, public IcdManager::Delegate
169
195
chip::Platform::Delete (data);
170
196
}
171
197
172
- // Modifications to mPendingKeepActiveTimesMs should be done on the MatterEventLoop thread
173
- std::map<chip::NodeId, uint32_t > mPendingKeepActiveTimesMs ;
198
+ // Modifications to mPendingCheckIn should be done on the MatterEventLoop thread
199
+ // otherwise we would need a mutex protecting this data to prevent race as this
200
+ // data is accessible by both RPC thread and Matter eventloop.
201
+ std::unordered_map<NodeId, KeepActiveDataForCheckIn> mPendingCheckIn ;
174
202
};
175
203
176
204
FabricAdmin fabric_admin_service;
0 commit comments