[Telink] Add Amazon ecosystem support (#26753)
* [Telink] Add Thread networks prescanning due to non concurrent radio mode
* [Telink] Fix rotating device id generation by factory data script
* [Telink] Enable rotating device ID by default for Amazon support
* [Telink] Update docker image to 0.7.14
* Restyled by whitespace
* Restyled by clang-format
---------
Co-authored-by: Restyled.io <commits@restyled.io>
diff --git a/.github/workflows/examples-telink.yaml b/.github/workflows/examples-telink.yaml
index bd7b5ab..8bddf9a 100644
--- a/.github/workflows/examples-telink.yaml
+++ b/.github/workflows/examples-telink.yaml
@@ -38,7 +38,7 @@
if: github.actor != 'restyled-io[bot]'
container:
- image: connectedhomeip/chip-build-telink:0.7.11
+ image: connectedhomeip/chip-build-telink:0.7.14
volumes:
- "/tmp/bloat_reports:/tmp/bloat_reports"
diff --git a/config/telink/chip-module/Kconfig b/config/telink/chip-module/Kconfig
index 4d4fb20..97f42e0 100644
--- a/config/telink/chip-module/Kconfig
+++ b/config/telink/chip-module/Kconfig
@@ -60,6 +60,14 @@
bool
default y if CHIP_OTA_REQUESTOR
+config CHIP_ROTATING_DEVICE_ID
+ bool "Generate rotating device ID"
+ default y
+ help
+ Enables the rotating device identifier that provides a non-trackable
+ identifier. The identifier is unique per device and rotates at pre-defined
+ moments.
+
config CHIP_EXAMPLE_DEVICE_INFO_PROVIDER
bool "Include default device information provider build"
default y
diff --git a/scripts/tools/telink/mfg_tool.py b/scripts/tools/telink/mfg_tool.py
index f2940c7..286648c 100644
--- a/scripts/tools/telink/mfg_tool.py
+++ b/scripts/tools/telink/mfg_tool.py
@@ -49,7 +49,7 @@
SHORT_MANUALCODE_LEN = 11
LONG_MANUALCODE_LEN = 21
QRCODE_LEN = 22
-ROTATING_DEVICE_ID_UNIQUE_ID_LEN_BITS = 128
+ROTATING_DEVICE_ID_UNIQUE_ID_LEN = 16
HEX_PREFIX = "hex:"
DEV_SN_CSV_HDR = "Serial Number,\n"
@@ -464,8 +464,7 @@
nvs_memory_append('cert_dclrn', read_der_file(args.cert_dclrn))
if (args.enable_rotating_device_id is True) and (args.rd_id_uid is None):
- nvs_memory_update('rd_uid', binascii.b2a_hex(os.urandom(
- int(ROTATING_DEVICE_ID_UNIQUE_ID_LEN_BITS / 8))).decode('utf-8'))
+ nvs_memory_update('rd_uid', os.urandom(ROTATING_DEVICE_ID_UNIQUE_ID_LEN))
# Generate onboarding data
generate_onboarding_data(args, out_dirs, int(row['Discriminator']), int(row['PIN Code']))
@@ -672,7 +671,7 @@
check_str_range(args.product_name, 1, 32, 'Product name')
check_str_range(args.hw_ver_str, 1, 64, 'Hardware version string')
check_str_range(args.mfg_date, 8, 16, 'Manufacturing date')
- check_str_range(args.rd_id_uid, 32, 32, 'Rotating device Unique id')
+ check_str_range(args.rd_id_uid, 16, 32, 'Rotating device Unique id')
# Validates the attestation related arguments
# DAC key and DAC cert both should be present or none
diff --git a/src/platform/telink/BLEManagerImpl.cpp b/src/platform/telink/BLEManagerImpl.cpp
index 9171184..dd912e5 100644
--- a/src/platform/telink/BLEManagerImpl.cpp
+++ b/src/platform/telink/BLEManagerImpl.cpp
@@ -147,8 +147,9 @@
CHIP_ERROR BLEManagerImpl::_Init(void)
{
- mBLERadioInitialized = false;
- mconId = NULL;
+ mBLERadioInitialized = false;
+ mconId = NULL;
+ mInternalScanCallback = new InternalScanCallback(this);
mServiceMode = ConnectivityManager::kCHIPoBLEServiceMode_Enabled;
mFlags.ClearAll().Set(Flags::kAdvertisingEnabled, CHIP_DEVICE_CONFIG_CHIPOBLE_ENABLE_ADVERTISING_AUTOSTART);
@@ -278,14 +279,27 @@
CHIP_ERROR BLEManagerImpl::StartAdvertising(void)
{
- int err;
-
if (ConnectivityMgr().IsThreadProvisioned())
{
ChipLogProgress(DeviceLayer, "Thread provisioned, can't StartAdvertising");
return CHIP_ERROR_INCORRECT_STATE;
}
+ else if (!mBLERadioInitialized)
+ {
+ ThreadStackMgrImpl().StartThreadScan(mInternalScanCallback);
+ }
+ else
+ {
+ return StartAdvertisingProcess();
+ }
+
+ return CHIP_NO_ERROR;
+}
+
+CHIP_ERROR BLEManagerImpl::StartAdvertisingProcess(void)
+{
+ int err;
if (!mBLERadioInitialized)
{
diff --git a/src/platform/telink/BLEManagerImpl.h b/src/platform/telink/BLEManagerImpl.h
index 731acae..a2fd31f 100644
--- a/src/platform/telink/BLEManagerImpl.h
+++ b/src/platform/telink/BLEManagerImpl.h
@@ -26,6 +26,7 @@
#if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE
+#include <platform/NetworkCommissioning.h>
#include <platform/Zephyr/BLEAdvertisingArbiter.h>
#include <zephyr/bluetooth/bluetooth.h>
@@ -38,6 +39,8 @@
using namespace chip::Ble;
+class InternalScanCallback;
+
/**
* Concrete implementation of the BLEManager singleton object for the Zephyr platforms.
*/
@@ -130,6 +133,8 @@
CHIP_ERROR HandleThreadStateChange(const ChipDeviceEvent * event);
CHIP_ERROR HandleOperationalNetworkEnabled(const ChipDeviceEvent * event);
+ InternalScanCallback * mInternalScanCallback;
+
#if CHIP_ENABLE_ADDITIONAL_DATA_ADVERTISING
CHIP_ERROR PrepareC3CharData(void);
#endif
@@ -165,6 +170,22 @@
/* Switch to IEEE802154 interface. @todo: remove to other module? */
void SwitchToIeee802154(void);
+
+ CHIP_ERROR StartAdvertisingProcess(void);
+};
+
+class InternalScanCallback : public DeviceLayer::NetworkCommissioning::ThreadDriver::ScanCallback
+{
+public:
+ explicit InternalScanCallback(BLEManagerImpl * aBLEManagerImpl) { mBLEManagerImpl = aBLEManagerImpl; }
+ void OnFinished(NetworkCommissioning::Status err, CharSpan debugText,
+ NetworkCommissioning::ThreadScanResponseIterator * networks)
+ {
+ mBLEManagerImpl->StartAdvertisingProcess();
+ };
+
+private:
+ BLEManagerImpl * mBLEManagerImpl;
};
/**
diff --git a/src/platform/telink/ThreadStackManagerImpl.cpp b/src/platform/telink/ThreadStackManagerImpl.cpp
index 09ee1ab..d6657c4 100644
--- a/src/platform/telink/ThreadStackManagerImpl.cpp
+++ b/src/platform/telink/ThreadStackManagerImpl.cpp
@@ -112,5 +112,29 @@
return result;
}
+CHIP_ERROR ThreadStackManagerImpl::_StartThreadScan(NetworkCommissioning::ThreadDriver::ScanCallback * callback)
+{
+ mpScanCallback = callback;
+
+ /* On Telink platform it's not possible to rise Thread network when its used by BLE,
+ so Thread networks scanning performed before start BLE and also available after switch into Thread */
+ if (mRadioBlocked)
+ {
+ if (mpScanCallback != nullptr)
+ {
+ DeviceLayer::SystemLayer().ScheduleLambda([this]() {
+ mpScanCallback->OnFinished(NetworkCommissioning::Status::kSuccess, CharSpan(), &mScanResponseIter);
+ mpScanCallback = nullptr;
+ });
+ }
+ }
+ else
+ {
+ return Internal::GenericThreadStackManagerImpl_OpenThread<ThreadStackManagerImpl>::_StartThreadScan(mpScanCallback);
+ }
+
+ return CHIP_NO_ERROR;
+}
+
} // namespace DeviceLayer
} // namespace chip
diff --git a/src/platform/telink/ThreadStackManagerImpl.h b/src/platform/telink/ThreadStackManagerImpl.h
index c598af1..870ea17 100644
--- a/src/platform/telink/ThreadStackManagerImpl.h
+++ b/src/platform/telink/ThreadStackManagerImpl.h
@@ -78,6 +78,7 @@
void _ProcessThreadActivity() {}
CHIP_ERROR _AttachToThreadNetwork(const Thread::OperationalDataset & dataset,
NetworkCommissioning::Internal::WirelessDriver::ConnectCallback * callback);
+ CHIP_ERROR _StartThreadScan(NetworkCommissioning::ThreadDriver::ScanCallback * callback);
//} // namespace Internal
@@ -92,6 +93,8 @@
// ===== Private members for use by this class only.
bool mRadioBlocked;
bool mReadyToAttach;
+
+ NetworkCommissioning::ThreadDriver::ScanCallback * mpScanCallback;
};
/**