Skip to content

Commit e37a112

Browse files
[ICD][Server][Checkin]Try to Send check-in message if allowed when subscription goes away in LIT (project-chip#41147) (project-chip#41575)
* Send out check-in message when report timesout * Restyled by whitespace * Restyled by clang-format * fix comment * store subject descriptor in read handler * check session is valid before reading subject descriptor from it * address comments * address comments * Restyled by whitespace * Restyled by clang-format * fix missing macro --------- Co-authored-by: Restyled.io <[email protected]>
1 parent 79d891d commit e37a112

File tree

7 files changed

+101
-9
lines changed

7 files changed

+101
-9
lines changed

src/app/ReadHandler.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,6 @@ CHIP_ERROR ReadHandler::OnStatusResponse(Messaging::ExchangeContext * apExchange
250250
err = SendSubscribeResponse();
251251

252252
SetStateFlag(ReadHandlerFlags::ActiveSubscription);
253-
254253
auto * appCallback = mManagementCallback.GetAppCallback();
255254
if (appCallback)
256255
{
@@ -411,6 +410,31 @@ void ReadHandler::OnResponseTimeout(Messaging::ExchangeContext * apExchangeConte
411410
{
412411
ChipLogError(DataManagement, "Time out! failed to receive status response from Exchange: " ChipLogFormatExchange,
413412
ChipLogValueExchange(apExchangeContext));
413+
#if CHIP_CONFIG_ENABLE_ICD_SERVER && CHIP_CONFIG_ENABLE_ICD_CIP && CHIP_CONFIG_ENABLE_ICD_CHECK_IN_ON_REPORT_TIMEOUT
414+
switch (mState)
415+
{
416+
case HandlerState::AwaitingReportResponse:
417+
if (IsType(InteractionType::Subscribe) && !IsPriming())
418+
{
419+
// Trigger check-in message when a non-priming subscription report times out.
420+
ChipLogError(DataManagement, "Trigger check-in message when non-priming subscription report times out");
421+
if (mSessionHandle)
422+
{
423+
chip::app::ICDNotifier::GetInstance().NotifySendCheckIn(GetSubjectDescriptor());
424+
}
425+
else
426+
{
427+
ChipLogError(DataManagement, "Failed to get subject descriptor for sending check-in message on report timeout");
428+
}
429+
}
430+
break;
431+
case HandlerState::CanStartReporting:
432+
case HandlerState::Idle:
433+
default:
434+
break;
435+
}
436+
#endif // CHIP_CONFIG_ENABLE_ICD_CIP && CHIP_CONFIG_ENABLE_ICD_SERVER
437+
414438
#if CHIP_CONFIG_PERSIST_SUBSCRIPTIONS
415439
Close(CloseOptions::kKeepPersistedSubscription);
416440
#else

src/app/icd/icd.gni

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@ declare_args() {
1616
# Matter SDK Configuration flag to enable ICD server functionality
1717
chip_enable_icd_server = false
1818

19+
# Enable the ICD server check-in on report timeout
20+
chip_enable_icd_checkin_on_report_timeout = true
21+
1922
chip_enable_icd_lit = false
2023

2124
# Matter SDK Configuration flag to make the ICD manager emit a report on entering active mode

src/app/icd/server/BUILD.gn

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ buildconfig_header("icd-server-buildconfig") {
4343
"CHIP_CONFIG_ENABLE_ICD_DSLS=${chip_enable_icd_dsls}",
4444
"ICD_REPORT_ON_ENTER_ACTIVE_MODE=${chip_icd_report_on_active_mode}",
4545
"ICD_MAX_NOTIFICATION_SUBSCRIBERS=${icd_max_notification_subscribers}",
46+
"CHIP_CONFIG_ENABLE_ICD_CHECK_IN_ON_REPORT_TIMEOUT=${chip_enable_icd_checkin_on_report_timeout}",
4647
]
4748

4849
visibility = [ ":icd-server-config" ]
@@ -66,6 +67,7 @@ source_set("notifier") {
6667

6768
deps = [
6869
":icd-server-config",
70+
"${chip_root}/src/access:types",
6971
"${chip_root}/src/lib/core",
7072
]
7173
}

src/app/icd/server/ICDManager.cpp

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,10 @@ uint32_t ICDManager::StayActiveRequest(uint32_t stayActiveDuration)
136136
}
137137

138138
#if CHIP_CONFIG_ENABLE_ICD_CIP
139-
void ICDManager::SendCheckInMsgs()
139+
void ICDManager::SendCheckInMsgs(Optional<Access::SubjectDescriptor> specificSubject)
140140
{
141141
#if !(CONFIG_BUILD_FOR_HOST_UNIT_TEST)
142+
VerifyOrDie(SupportsFeature(Feature::kCheckInProtocolSupport));
142143
VerifyOrDie(mStorage != nullptr);
143144
VerifyOrDie(mFabricTable != nullptr);
144145

@@ -173,7 +174,13 @@ void ICDManager::SendCheckInMsgs()
173174
continue;
174175
}
175176

176-
if (!ShouldCheckInMsgsBeSentAtActiveModeFunction(entry.fabricIndex, entry.monitoredSubject))
177+
if (specificSubject.HasValue() && !ShouldSendCheckInMessageForSpecificSubject(entry, specificSubject.Value()))
178+
{
179+
continue;
180+
}
181+
182+
if (!specificSubject.HasValue() &&
183+
!ShouldCheckInMsgsBeSentAtActiveModeFunction(entry.fabricIndex, entry.monitoredSubject))
177184
{
178185
continue;
179186
}
@@ -209,6 +216,24 @@ void ICDManager::SendCheckInMsgs()
209216
#endif // !(CONFIG_BUILD_FOR_HOST_UNIT_TEST)
210217
}
211218

219+
bool ICDManager::ShouldSendCheckInMessageForSpecificSubject(const ICDMonitoringEntry & entry,
220+
const Access::SubjectDescriptor & specificSubject)
221+
{
222+
if (specificSubject.fabricIndex != entry.fabricIndex)
223+
{
224+
return false;
225+
}
226+
227+
if (specificSubject.cats.CheckSubjectAgainstCATs(entry.monitoredSubject) || entry.monitoredSubject == specificSubject.subject)
228+
{
229+
ChipLogProgress(AppServer, "Proceed to send Check-In msg for specific subject: " ChipLogFormatX64,
230+
ChipLogValueX64(specificSubject.subject));
231+
return true;
232+
}
233+
234+
return false;
235+
}
236+
212237
bool ICDManager::CheckInMessagesWouldBeSent(const std::function<ShouldCheckInMsgsBeSentFunction> & shouldCheckInMsgsBeSentFunction)
213238
{
214239
VerifyOrReturnValue(shouldCheckInMsgsBeSentFunction, false);
@@ -479,10 +504,7 @@ void ICDManager::UpdateOperationState(OperationalState state)
479504
}
480505

481506
#if CHIP_CONFIG_ENABLE_ICD_CIP
482-
if (SupportsFeature(Feature::kCheckInProtocolSupport))
483-
{
484-
SendCheckInMsgs();
485-
}
507+
SendCheckInMsgs();
486508
#endif // CHIP_CONFIG_ENABLE_ICD_CIP
487509

488510
postObserverEvent(ObserverEventType::EnterActiveMode);
@@ -661,6 +683,14 @@ void ICDManager::OnSubscriptionReport()
661683
this->UpdateOperationState(OperationalState::ActiveMode);
662684
}
663685

686+
#if CHIP_CONFIG_ENABLE_ICD_SERVER && CHIP_CONFIG_ENABLE_ICD_CIP && CHIP_CONFIG_ENABLE_ICD_CHECK_IN_ON_REPORT_TIMEOUT
687+
void ICDManager::OnSendCheckIn(const Access::SubjectDescriptor & subject)
688+
{
689+
ChipLogProgress(AppServer, "Received OnSendCheckIn for subject: " ChipLogFormatX64, ChipLogValueX64(subject.subject));
690+
SendCheckInMsgs(MakeOptional(subject));
691+
}
692+
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && CHIP_CONFIG_ENABLE_ICD_CIP && CHIP_CONFIG_ENABLE_ICD_CHECK_IN_ON_REPORT_TIMEOUT
693+
664694
void ICDManager::ExtendActiveMode(Milliseconds16 extendDuration)
665695
{
666696
DeviceLayer::SystemLayer().ExtendTimerTo(extendDuration, OnActiveModeDone, this);

src/app/icd/server/ICDManager.h

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -249,6 +249,10 @@ class ICDManager : public ICDListener, public TestEventTriggerHandler
249249
void OnICDManagementServerEvent(ICDManagementEvents event) override;
250250
void OnSubscriptionReport() override;
251251

252+
#if CHIP_CONFIG_ENABLE_ICD_SERVER && CHIP_CONFIG_ENABLE_ICD_CIP && CHIP_CONFIG_ENABLE_ICD_CHECK_IN_ON_REPORT_TIMEOUT
253+
void OnSendCheckIn(const Access::SubjectDescriptor & subject) override;
254+
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && CHIP_CONFIG_ENABLE_ICD_CIP && CHIP_CONFIG_ENABLE_ICD_CHECK_IN_ON_REPORT_TIMEOUT
255+
252256
private:
253257
// TODO : Once <gtest/gtest_prod.h> can be included, use FRIEND_TEST for the friend class.
254258
friend class TestICDManager_TestShouldCheckInMsgsBeSentAtActiveModeFunction_Test;
@@ -334,7 +338,9 @@ class ICDManager : public ICDListener, public TestEventTriggerHandler
334338
* ShouldCheckInMsgsBeSentAtActiveModeFunction. If we should, we allocate an ICDCheckInSender which tries to send a
335339
* Check-In message to the registered client.
336340
*/
337-
void SendCheckInMsgs();
341+
void SendCheckInMsgs(Optional<Access::SubjectDescriptor> specificSubject = Optional<Access::SubjectDescriptor>());
342+
bool ShouldSendCheckInMessageForSpecificSubject(const ICDMonitoringEntry & entry,
343+
const Access::SubjectDescriptor & specificSubject);
338344

339345
/**
340346
* @brief See function implementation in .cpp for details on this function.

src/app/icd/server/ICDNotifier.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,5 +135,18 @@ void ICDNotifier::NotifySubscriptionReport()
135135
}
136136
}
137137

138+
#if CHIP_CONFIG_ENABLE_ICD_SERVER && CHIP_CONFIG_ENABLE_ICD_CIP && CHIP_CONFIG_ENABLE_ICD_CHECK_IN_ON_REPORT_TIMEOUT
139+
void ICDNotifier::NotifySendCheckIn(const chip::Access::SubjectDescriptor & subject)
140+
{
141+
for (auto subscriber : mSubscribers)
142+
{
143+
if (subscriber != nullptr)
144+
{
145+
subscriber->OnSendCheckIn(subject);
146+
}
147+
}
148+
}
149+
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && CHIP_CONFIG_ENABLE_ICD_CIP && CHIP_CONFIG_ENABLE_ICD_CHECK_IN_ON_REPORT_TIMEOUT
150+
138151
} // namespace app
139152
} // namespace chip

src/app/icd/server/ICDNotifier.h

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,10 @@
1616
*/
1717
#pragma once
1818

19+
#include <access/SubjectDescriptor.h>
1920
#include <app/icd/server/ICDServerConfig.h>
2021
#include <lib/core/CHIPError.h>
2122
#include <lib/support/BitFlags.h>
22-
2323
namespace chip {
2424
namespace app {
2525

@@ -106,6 +106,16 @@ class ICDListener
106106
* It informs the subscriber that a subscription report data is being sent.
107107
*/
108108
virtual void OnSubscriptionReport() = 0;
109+
110+
#if CHIP_CONFIG_ENABLE_ICD_SERVER && CHIP_CONFIG_ENABLE_ICD_CIP && CHIP_CONFIG_ENABLE_ICD_CHECK_IN_ON_REPORT_TIMEOUT
111+
/**
112+
* @brief This function is called for all subscribers of the ICDNotifier when it calls NotifySendCheckIn.
113+
* It informs the subscriber that a Check-In message needs to be sent for the provided subject.
114+
*
115+
* @param subject : The subject descriptor for which the Check-In message needs to be sent.
116+
*/
117+
virtual void OnSendCheckIn(const chip::Access::SubjectDescriptor & subject) = 0;
118+
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && CHIP_CONFIG_ENABLE_ICD_CIP && CHIP_CONFIG_ENABLE_ICD_CHECK_IN_ON_REPORT_TIMEOUT
109119
};
110120

111121
class ICDNotifier
@@ -130,6 +140,10 @@ class ICDNotifier
130140
void NotifyICDManagementEvent(ICDListener::ICDManagementEvents event);
131141
void NotifySubscriptionReport();
132142

143+
#if CHIP_CONFIG_ENABLE_ICD_SERVER && CHIP_CONFIG_ENABLE_ICD_CIP && CHIP_CONFIG_ENABLE_ICD_CHECK_IN_ON_REPORT_TIMEOUT
144+
void NotifySendCheckIn(const chip::Access::SubjectDescriptor & subject);
145+
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER && CHIP_CONFIG_ENABLE_ICD_CIP && CHIP_CONFIG_ENABLE_ICD_CHECK_IN_ON_REPORT_TIMEOUT
146+
133147
inline void BroadcastActiveRequest(ICDListener::KeepActiveFlags request, bool notify)
134148
{
135149
(notify) ? NotifyActiveRequestNotification(request) : NotifyActiveRequestWithdrawal(request);

0 commit comments

Comments
 (0)