Skip to content

Commit 9132067

Browse files
mkardous-silabsbzbarsky-apple
authored andcommitted
[ICD] Add default ICD Behavior to readhandler when establishing a subscription (#28375)
* add default ICD behavior to readhandler * Add comments * Update src/app/ReadHandler.cpp Co-authored-by: Boris Zbarsky <[email protected]> * move check to top * Add ICD unit tests for ReadHandler * check to avoid division by 0 * fix dependency chain * restyle * remove deps for manager srcs --------- Co-authored-by: Boris Zbarsky <[email protected]>
1 parent 4b982ec commit 9132067

File tree

8 files changed

+468
-8
lines changed

8 files changed

+468
-8
lines changed

src/app/ReadHandler.cpp

+51
Original file line numberDiff line numberDiff line change
@@ -713,6 +713,57 @@ CHIP_ERROR ReadHandler::ProcessSubscribeRequest(System::PacketBufferHandle && aP
713713
ReturnErrorOnFailure(subscribeRequestParser.GetMaxIntervalCeilingSeconds(&mMaxInterval));
714714
VerifyOrReturnError(mMinIntervalFloorSeconds <= mMaxInterval, CHIP_ERROR_INVALID_ARGUMENT);
715715

716+
#if CHIP_CONFIG_ENABLE_ICD_SERVER
717+
718+
// Default behavior for ICDs where the wanted MaxInterval for a subscription is the IdleModeInterval
719+
// defined in the ICD Management Cluster.
720+
// Behavior can be changed with the OnSubscriptionRequested function defined in the application callbacks
721+
722+
// Default Behavior Steps :
723+
// If MinInterval > IdleModeInterval, try to set the MaxInterval to the first interval of IdleModeIntervals above the
724+
// MinInterval.
725+
// If the next interval is greater than the MaxIntervalCeiling, use the MaxIntervalCeiling.
726+
// Otherwise, use IdleModeInterval as MaxInterval
727+
728+
// GetPublisherSelectedIntervalLimit() returns the IdleModeInterval if the device is an ICD
729+
uint32_t decidedMaxInterval = GetPublisherSelectedIntervalLimit();
730+
731+
// Check if the PublisherSelectedIntervalLimit is 0. If so, set decidedMaxInterval to MaxIntervalCeiling
732+
if (decidedMaxInterval == 0)
733+
{
734+
decidedMaxInterval = mMaxInterval;
735+
}
736+
737+
// If requestedMinInterval is greater than the IdleTimeInterval, select next active up time as max interval
738+
if (mMinIntervalFloorSeconds > decidedMaxInterval)
739+
{
740+
uint16_t ratio = mMinIntervalFloorSeconds / static_cast<uint16_t>(decidedMaxInterval);
741+
if (mMinIntervalFloorSeconds % decidedMaxInterval)
742+
{
743+
ratio++;
744+
}
745+
746+
decidedMaxInterval *= ratio;
747+
}
748+
749+
// Verify that decidedMaxInterval is an acceptable value (overflow)
750+
if (decidedMaxInterval > System::Clock::Seconds16::max().count())
751+
{
752+
decidedMaxInterval = System::Clock::Seconds16::max().count();
753+
}
754+
755+
// Verify that the decidedMaxInterval respects MAX(GetPublisherSelectedIntervalLimit(), MaxIntervalCeiling)
756+
uint16_t maximumMaxInterval = std::max(GetPublisherSelectedIntervalLimit(), mMaxInterval);
757+
if (decidedMaxInterval > maximumMaxInterval)
758+
{
759+
decidedMaxInterval = maximumMaxInterval;
760+
}
761+
762+
// Set max interval of the subscription
763+
mMaxInterval = static_cast<uint16_t>(decidedMaxInterval);
764+
765+
#endif // CHIP_CONFIG_ENABLE_ICD_SERVER
766+
716767
//
717768
// Notify the application (if requested) of the impending subscription and check whether we should still proceed to set it up.
718769
// This also provides the application an opportunity to modify the negotiated min/max intervals set above.

src/app/icd/BUILD.gn

+2-2
Original file line numberDiff line numberDiff line change
@@ -29,11 +29,11 @@ source_set("manager-srcs") {
2929
"ICDManager.h",
3030
]
3131

32-
deps = [
32+
public_deps = [
3333
":cluster-srcs",
3434
":observer-srcs",
35+
"${chip_root}/src/credentials:credentials",
3536
]
36-
public_deps = [ "${chip_root}/src/credentials:credentials" ]
3737
}
3838

3939
# ICD management cluster source-set is broken out of the main source-set to enable unit tests

src/app/tests/BUILD.gn

+5-2
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import("//build_overrides/chip.gni")
1717
import("//build_overrides/nlunit_test.gni")
1818

1919
import("${chip_root}/build/chip/chip_test_suite.gni")
20+
import("${chip_root}/src/app/icd/icd.gni")
2021
import("${chip_root}/src/platform/device.gni")
2122

2223
static_library("helpers") {
@@ -186,7 +187,6 @@ chip_test_suite("tests") {
186187
":time-sync-data-provider-test-srcs",
187188
"${chip_root}/src/app",
188189
"${chip_root}/src/app/common:cluster-objects",
189-
"${chip_root}/src/app/icd:cluster-srcs",
190190
"${chip_root}/src/app/icd:manager-srcs",
191191
"${chip_root}/src/app/tests:helpers",
192192
"${chip_root}/src/app/util/mock:mock_ember",
@@ -195,7 +195,10 @@ chip_test_suite("tests") {
195195
"${nlunit_test_root}:nlunit-test",
196196
]
197197

198-
if (chip_config_network_layer_ble &&
198+
# Do not run TestCommissionManager when running ICD specific unit tests.
199+
# ICDManager has a dependency on the Accessors.h file which causes a link error
200+
# when building the TestCommissionManager
201+
if (!chip_enable_icd_server && chip_config_network_layer_ble &&
199202
(chip_device_platform == "linux" || chip_device_platform == "darwin")) {
200203
test_sources += [ "TestCommissionManager.cpp" ]
201204
public_deps += [ "${chip_root}/src/app/server" ]

0 commit comments

Comments
 (0)