[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;
 };
 
 /**