[Telink] Implement OnSubscriptionRequested callback for SED examples (#26650)
* [Telink] Add OnSubscriptionRequested callback
* [Telink] Enable CHIP_ICD_SUBSCRIPTION_HANDLING for all SED devices
* [Telink] Move build ICDUtil into libCHIP & CHIP_ICD_SUBSCRIPTION_HANDLING default if PM
* Restyled by gn
* [Telink] Move ICDUtil.h include into cpp file
* Restyled by clang-format
* [Telink] Move ICDUtil.* to src/platform/telink
---------
Co-authored-by: Restyled.io <commits@restyled.io>
diff --git a/config/telink/chip-module/Kconfig b/config/telink/chip-module/Kconfig
index bce2583..4d4fb20 100644
--- a/config/telink/chip-module/Kconfig
+++ b/config/telink/chip-module/Kconfig
@@ -179,3 +179,23 @@
config SHELL_BACKEND_SERIAL_RX_RING_BUFFER_SIZE
int
default 255 if SHELL_BACKEND_SERIAL
+
+config CHIP_ICD_SUBSCRIPTION_HANDLING
+ bool "Enables platform specific handling of ICD subscriptions"
+ default PM
+ help
+ Enables platform specific implementation that handles ICD subscription requests
+ and selects subscription report interval value considering maximum interval preferred
+ by the publisher.
+
+config CHIP_MAX_PREFERRED_SUBSCRIPTION_REPORT_INTERVAL
+ int "Maximum preferred interval of sending subscription reports (s)"
+ default 60
+ help
+ Provides maximum preferred interval to be used by a publisher for negotiation
+ of the final maximum subscription report interval, after receiving a subscription
+ request from the initiator. This value should be selected as a compromise between
+ keeping the power consumption low due to not sending reports too often, and allowing
+ the initiator device to detect the publisher absence reasonably fast due to not sending
+ the reports too rarely. The current algorithm is to select bigger value from the one
+ requested by the initiator and the one preferred by the publisher.
diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp
index c6e455b..c49222d 100644
--- a/examples/platform/telink/common/src/AppTaskCommon.cpp
+++ b/examples/platform/telink/common/src/AppTaskCommon.cpp
@@ -33,6 +33,11 @@
#include "OTAUtil.h"
#endif
+#ifdef CONFIG_CHIP_ICD_SUBSCRIPTION_HANDLING
+#include "ICDUtil.h"
+#include <app/InteractionModelEngine.h>
+#endif
+
LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL);
namespace {
@@ -229,6 +234,10 @@
emberAfEndpointEnableDisable(kNetworkCommissioningEndpointSecondary, false);
#endif
+#ifdef CONFIG_CHIP_ICD_SUBSCRIPTION_HANDLING
+ chip::app::InteractionModelEngine::GetInstance()->RegisterReadHandlerAppCallback(&GetICDUtil());
+#endif
+
// Add CHIP event handler and start CHIP thread.
// Note that all the initialization code should happen prior to this point to avoid data races
// between the main and the CHIP threads.
diff --git a/src/platform/telink/BUILD.gn b/src/platform/telink/BUILD.gn
index 0970bb6..00fe34e 100644
--- a/src/platform/telink/BUILD.gn
+++ b/src/platform/telink/BUILD.gn
@@ -43,6 +43,7 @@
"ConfigurationManagerImpl.h",
"ConnectivityManagerImpl.cpp",
"ConnectivityManagerImpl.h",
+ "ICDUtil.cpp",
"InetPlatformConfig.h",
"KeyValueStoreManagerImpl.h",
"PlatformManagerImpl.h",
@@ -57,6 +58,8 @@
public_deps = [ "${chip_root}/src/platform:platform_base" ]
+ defines = [ "CHIP_ADDRESS_RESOLVE_IMPL_INCLUDE_HEADER=<lib/address_resolve/AddressResolve_DefaultImpl.h>" ]
+
if (chip_enable_factory_data) {
sources += [
"FactoryDataParser.c",
diff --git a/src/platform/telink/ICDUtil.cpp b/src/platform/telink/ICDUtil.cpp
new file mode 100644
index 0000000..fd2130c
--- /dev/null
+++ b/src/platform/telink/ICDUtil.cpp
@@ -0,0 +1,40 @@
+/*
+ *
+ * Copyright (c) 2023 Project CHIP Authors
+ * All rights reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "ICDUtil.h"
+
+ICDUtil ICDUtil::sICDUtil;
+
+CHIP_ERROR ICDUtil::OnSubscriptionRequested(chip::app::ReadHandler & aReadHandler, chip::Transport::SecureSession & aSecureSession)
+{
+ uint16_t agreedMaxInterval = CONFIG_CHIP_MAX_PREFERRED_SUBSCRIPTION_REPORT_INTERVAL;
+ uint16_t requestedMinInterval = 0;
+ uint16_t requestedMaxInterval = 0;
+ aReadHandler.GetReportingIntervals(requestedMinInterval, requestedMaxInterval);
+
+ if (requestedMaxInterval > agreedMaxInterval)
+ {
+ agreedMaxInterval = requestedMaxInterval;
+ }
+ else if (agreedMaxInterval > kSubscriptionMaxIntervalPublisherLimit)
+ {
+ agreedMaxInterval = kSubscriptionMaxIntervalPublisherLimit;
+ }
+
+ return aReadHandler.SetReportingIntervals(agreedMaxInterval);
+}
diff --git a/src/platform/telink/ICDUtil.h b/src/platform/telink/ICDUtil.h
new file mode 100644
index 0000000..33db1e9
--- /dev/null
+++ b/src/platform/telink/ICDUtil.h
@@ -0,0 +1,33 @@
+/*
+ *
+ * Copyright (c) 2023 Project CHIP Authors
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <app/ReadHandler.h>
+
+class ICDUtil : public chip::app::ReadHandler::ApplicationCallback
+{
+ CHIP_ERROR OnSubscriptionRequested(chip::app::ReadHandler & aReadHandler,
+ chip::Transport::SecureSession & aSecureSession) override;
+ friend ICDUtil & GetICDUtil();
+ static ICDUtil sICDUtil;
+};
+
+inline ICDUtil & GetICDUtil()
+{
+ return ICDUtil::sICDUtil;
+}