diff --git a/.github/workflows/chef.yaml b/.github/workflows/chef.yaml index 77c1a21be6b388..b3d3f7f3a90f7c 100644 --- a/.github/workflows/chef.yaml +++ b/.github/workflows/chef.yaml @@ -98,7 +98,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-telink:54 + image: ghcr.io/project-chip/chip-build-telink:57 options: --user root steps: @@ -110,7 +110,7 @@ jobs: platform: telink # - name: Update Zephyr to specific revision (for developers purpose) # shell: bash - # run: scripts/run_in_build_env.sh "python3 scripts/tools/telink/update_zephyr.py 0e8032dfef7e02498f34ba0b5d5d2df71a62adb1" + # run: scripts/run_in_build_env.sh "python3 scripts/tools/telink/update_zephyr.py ab81a585fca6a83b30e1f4e58a021113d6a3acb8" - name: CI Examples Telink shell: bash run: | diff --git a/.github/workflows/examples-telink.yaml b/.github/workflows/examples-telink.yaml index 6c836294381a0f..15926e99cd470c 100644 --- a/.github/workflows/examples-telink.yaml +++ b/.github/workflows/examples-telink.yaml @@ -38,7 +38,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: ghcr.io/project-chip/chip-build-telink:54 + image: ghcr.io/project-chip/chip-build-telink:57 volumes: - "/tmp/bloat_reports:/tmp/bloat_reports" @@ -57,7 +57,7 @@ jobs: gh-context: ${{ toJson(github) }} # - name: Update Zephyr to specific revision (for developers purpose) - # run: scripts/run_in_build_env.sh "python3 scripts/tools/telink/update_zephyr.py 0e8032dfef7e02498f34ba0b5d5d2df71a62adb1" + # run: scripts/run_in_build_env.sh "python3 scripts/tools/telink/update_zephyr.py ab81a585fca6a83b30e1f4e58a021113d6a3acb8" - name: Build example Telink (B92 retention) Air Quality Sensor App run: | diff --git a/config/telink/chip-module/CMakeLists.txt b/config/telink/chip-module/CMakeLists.txt index 0f2e4edce0f8d1..f8986e7a954fb4 100644 --- a/config/telink/chip-module/CMakeLists.txt +++ b/config/telink/chip-module/CMakeLists.txt @@ -95,39 +95,40 @@ matter_add_gn_arg_bool ("chip_logging" CONFIG_LOG) matter_add_gn_arg_bool ("chip_enable_openthread" CONFIG_NET_L2_OPENTHREAD) matter_add_gn_arg_bool ("chip_openthread_ftd" CONFIG_OPENTHREAD_FTD) matter_add_gn_arg_bool ("chip_config_network_layer_ble" CONFIG_BT) -matter_add_gn_arg_bool ("chip_inet_config_enable_ipv4" CONFIG_NET_IPV4) +matter_add_gn_arg_bool ("chip_inet_config_enable_ipv4" CONFIG_CHIP_IPV4) matter_add_gn_arg_bool ("chip_enable_nfc" CONFIG_CHIP_NFC_COMMISSIONING) matter_add_gn_arg_bool ("chip_enable_ota_requestor" CONFIG_CHIP_OTA_REQUESTOR) -matter_add_gn_arg_bool ("chip_inet_config_enable_tcp_endpoint" CONFIG_CHIP_BUILD_TESTS) +matter_add_gn_arg_bool ("chip_inet_config_enable_tcp_endpoint" FALSE) matter_add_gn_arg_bool ("chip_error_logging" CONFIG_MATTER_LOG_LEVEL GREATER_EQUAL 1) matter_add_gn_arg_bool ("chip_progress_logging" CONFIG_MATTER_LOG_LEVEL GREATER_EQUAL 3) matter_add_gn_arg_bool ("chip_detail_logging" CONFIG_MATTER_LOG_LEVEL GREATER_EQUAL 4) matter_add_gn_arg_bool ("chip_automation_logging" FALSE) matter_add_gn_arg_bool ("chip_enable_wifi" CONFIG_WIFI_W91) matter_add_gn_arg_bool ("chip_enable_icd_server" CONFIG_CHIP_ENABLE_ICD_SUPPORT) +matter_add_gn_arg_bool ("chip_enable_factory_data" CONFIG_CHIP_FACTORY_DATA) +matter_add_gn_arg_bool ("chip_mdns_minimal" CONFIG_WIFI_W91) +matter_add_gn_arg_bool ("chip_mdns_platform" CONFIG_NET_L2_OPENTHREAD) if (CONFIG_CHIP_ENABLE_ICD_SUPPORT) - matter_add_gn_arg_bool ("chip_enable_icd_lit" CONFIG_CHIP_ICD_LIT_SUPPORT) - matter_add_gn_arg_bool ("chip_enable_icd_checkin" CONFIG_CHIP_ICD_CHECK_IN_SUPPORT) - matter_add_gn_arg_bool ("chip_enable_icd_user_active_mode_trigger" CONFIG_CHIP_ICD_UAT_SUPPORT) + matter_add_gn_arg_bool ("chip_enable_icd_lit" CONFIG_CHIP_ICD_LIT_SUPPORT) + matter_add_gn_arg_bool ("chip_enable_icd_checkin" CONFIG_CHIP_ICD_CHECK_IN_SUPPORT) + matter_add_gn_arg_bool ("chip_enable_icd_user_active_mode_trigger" CONFIG_CHIP_ICD_UAT_SUPPORT) endif() -if (CONFIG_CHIP_FACTORY_DATA) - matter_add_gn_arg_bool ("chip_use_transitional_commissionable_data_provider" "false") - matter_add_gn_arg_bool ("chip_enable_factory_data" "true") -elseif (CONFIG_CHIP_FACTORY_DATA_CUSTOM_BACKEND) - matter_add_gn_arg_bool ("chip_use_transitional_commissionable_data_provider" "false") +if (CONFIG_CHIP_FACTORY_DATA OR CONFIG_CHIP_FACTORY_DATA_CUSTOM_BACKEND) + matter_add_gn_arg_bool("chip_use_transitional_commissionable_data_provider" FALSE) + matter_add_gn_arg_bool("chip_use_transitional_device_instance_info_provider" FALSE) endif() if (CONFIG_CHIP_ROTATING_DEVICE_ID) - matter_add_gn_arg_bool("chip_enable_rotating_device_id" "true") - matter_add_gn_arg_bool("chip_enable_additional_data_advertising" "true") + matter_add_gn_arg_bool("chip_enable_rotating_device_id" TRUE) + matter_add_gn_arg_bool("chip_enable_additional_data_advertising" TRUE) endif() -if (CONFIG_NET_L2_OPENTHREAD) - matter_add_gn_arg_string("chip_mdns" "platform") -elseif(CONFIG_WIFI_W91) +if(CONFIG_WIFI_W91) matter_add_gn_arg_string("chip_mdns" "minimal") +elseif (CONFIG_NET_L2_OPENTHREAD) + matter_add_gn_arg_string("chip_mdns" "platform") else() matter_add_gn_arg_string("chip_mdns" "none") endif() diff --git a/config/telink/chip-module/Kconfig b/config/telink/chip-module/Kconfig index 4444cc8e9e44ed..46dc36b8973d77 100644 --- a/config/telink/chip-module/Kconfig +++ b/config/telink/chip-module/Kconfig @@ -178,9 +178,18 @@ config CHIP_LOG_SIZE_OPTIMIZATION full configuration enabled by this option in the platform/telink/CHIPPlatformConfig.h file. +config CHIP_IPV4 + bool "IPv4 support for Matter" + default n + depends on NET_IPV4 + help + If disabled, it allows to build Telink SDK application + with IPv4 support independently of the Matter stack still + running over IPv6. + config CHIP_BUTTON_MANAGER_IRQ_MODE bool "Use GPIO in an IRQ mode instead of polling the GPIO" - default PM || BOARD_TLSR9118BDK40D + default PM help Use GPIO in an IRQ mode to avoid button polling loop and extend the battery lifetime by waking up by GPIO event. GPIO events are working only with GPIO IRQ. This option changes button matrix configuration. diff --git a/config/telink/chip-module/Kconfig.defaults b/config/telink/chip-module/Kconfig.defaults index e6554774187a18..ea5a6822b74cb5 100644 --- a/config/telink/chip-module/Kconfig.defaults +++ b/config/telink/chip-module/Kconfig.defaults @@ -34,11 +34,11 @@ choice LOG_MODE endchoice choice MATTER_LOG_LEVEL_CHOICE - default MATTER_LOG_LEVEL_INF + default MATTER_LOG_LEVEL_DBG endchoice config CHIP_APP_LOG_LEVEL - default 3 # info + default 4 # debug config LOG_DEFAULT_LEVEL default 1 # error @@ -108,7 +108,6 @@ config GPIO # Bluetooth Low Energy configs config BT - default n if BOARD_TLSR9118BDK40D default y if BT @@ -138,10 +137,12 @@ config BT_BUF_ACL_TX_SIZE default 251 config BT_RX_STACK_SIZE - default 810 + default 810 if BT_B9X + default 2048 if BT_W91 config BT_HCI_TX_STACK_SIZE - default 640 + default 640 if BT_B9X + default 2048 if BT_W91 config BT_DEVICE_NAME_GATT_WRITABLE bool @@ -300,13 +301,32 @@ config CHIP_WIFI select WIFI_W91 select WIFI select NET_STATISTICS - select NET_L2_ETHERNET select NET_IPV6_ND # enable Neighbor Discovery to handle Router Advertisements select NET_IPV6_NBR_CACHE select NET_STATISTICS_USER_API +# select NET_IPV4 # TODO: remove IPv4 when IPv6 will be ready (see CHIP_IPV4) +# select NET_CONFIG_NEED_IPV4 +# select NET_DHCPV4 if CHIP_WIFI +config DEFAULT_WIFI_SSID + string "Default WiFi SSID" + depends on CHIP_WIFI + default "" + help + The SSID of network to connect to if no WiFi station configuration exists in NV storage + at the time the device boots. + This option is for testing only and should be disabled in production releases + +config DEFAULT_WIFI_PASSWORD + string "Default WiFi Password" + depends on CHIP_WIFI + default "" + help + The password for the default WiFi network. + This option is for testing only and should be disabled in production releases. + config CHIP_WIFI_CONNECTION_RECOVERY_MINIMUM_INTERVAL int "Define the minimum connection recovery time interval in milliseconds" depends on CHIP_WIFI diff --git a/examples/platform/telink/common/include/AppTaskCommon.h b/examples/platform/telink/common/include/AppTaskCommon.h index b1e5ad356692bb..ff3f7bf174a939 100644 --- a/examples/platform/telink/common/include/AppTaskCommon.h +++ b/examples/platform/telink/common/include/AppTaskCommon.h @@ -76,6 +76,7 @@ class AppTaskCommon { kButtonId_ExampleAction = 1, kButtonId_FactoryReset, + kButtonId_StartWiFi, kButtonId_StartThread, kButtonId_StartBleAdv } ButtonId; @@ -102,9 +103,12 @@ class AppTaskCommon static void StartBleAdvButtonEventHandler(void); static void StartBleAdvHandler(AppEvent * aEvent); -#if !CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE && CHIP_DEVICE_CONFIG_ENABLE_THREAD +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD static void StartThreadButtonEventHandler(void); static void StartThreadHandler(AppEvent * aEvent); +#elif CHIP_DEVICE_CONFIG_ENABLE_WIFI + static void StartWiFiButtonEventHandler(void); + static void StartWiFiHandler(AppEvent * aEvent); #endif static void ExampleActionButtonEventHandler(void); diff --git a/examples/platform/telink/common/src/AppTaskCommon.cpp b/examples/platform/telink/common/src/AppTaskCommon.cpp index 96bb3ca87463dc..59ad41b3c45bde 100644 --- a/examples/platform/telink/common/src/AppTaskCommon.cpp +++ b/examples/platform/telink/common/src/AppTaskCommon.cpp @@ -24,7 +24,12 @@ #include "LEDManager.h" #include "PWMManager.h" +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD #include "ThreadUtil.h" +#elif CHIP_DEVICE_CONFIG_ENABLE_WIFI +#include +#include +#endif #include #include @@ -74,7 +79,7 @@ uint8_t sFactoryResetCntr = 0; bool sIsCommissioningFailed = false; bool sIsNetworkProvisioned = false; bool sIsNetworkEnabled = false; -bool sIsThreadAttached = false; +bool sIsNetworkAttached = false; bool sHaveBLEConnections = false; #if APP_SET_DEVICE_INFO_PROVIDER @@ -213,13 +218,16 @@ CHIP_ERROR AppTaskCommon::StartApp(void) AppEvent event = {}; -#if !CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE && CHIP_DEVICE_CONFIG_ENABLE_THREAD +#if !CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD StartThreadButtonEventHandler(); +#elif CHIP_DEVICE_CONFIG_ENABLE_WIFI + StartWiFiButtonEventHandler(); #endif +#endif /* CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE */ #ifdef CONFIG_BOOTLOADER_MCUBOOT - if (!chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned() && - !chip::DeviceLayer::ConnectivityMgr().IsWiFiStationProvisioned()) + if (!sIsNetworkProvisioned) { LOG_INF("Confirm image."); OtaConfirmNewImage(); @@ -359,10 +367,14 @@ void AppTaskCommon::ButtonEventHandler(ButtonId_t btnId, bool btnPressed) case kButtonId_FactoryReset: FactoryResetButtonEventHandler(); break; -#if !CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD case kButtonId_StartThread: StartThreadButtonEventHandler(); break; +#elif CHIP_DEVICE_CONFIG_ENABLE_WIFI + case kButtonId_StartWiFi: + StartWiFiButtonEventHandler(); + break; #endif case kButtonId_StartBleAdv: StartBleAdvButtonEventHandler(); @@ -433,8 +445,10 @@ void AppTaskCommon::LinkButtons(ButtonManager & buttonManager) buttonManager.addCallback(FactoryResetButtonEventHandler, 0, true); buttonManager.addCallback(ExampleActionButtonEventHandler, 1, true); buttonManager.addCallback(StartBleAdvButtonEventHandler, 2, true); -#if !CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE && CHIP_DEVICE_CONFIG_ENABLE_THREAD +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD buttonManager.addCallback(StartThreadButtonEventHandler, 3, true); +#elif CHIP_DEVICE_CONFIG_ENABLE_WIFI + buttonManager.addCallback(StartWiFiButtonEventHandler, 3, true); #endif } @@ -442,7 +456,7 @@ void AppTaskCommon::UpdateStatusLED() { if (sIsNetworkProvisioned && sIsNetworkEnabled) { - if (sIsThreadAttached) + if (sIsNetworkAttached) { LedManager::getInstance().setLed(LedManager::EAppLed_Status, 950, 50); } @@ -506,8 +520,8 @@ void AppTaskCommon::StartBleAdvHandler(AppEvent * aEvent) { LOG_INF("StartBleAdvHandler"); - // Don't allow on starting Matter service BLE advertising after Thread provisioning. - if (ConnectivityMgr().IsThreadProvisioned()) + // Disable manual Matter service BLE advertising after device provisioning. + if (sIsNetworkProvisioned) { LOG_INF("Device already commissioned"); return; @@ -578,7 +592,7 @@ void AppTaskCommon::FactoryResetTimerEventHandler(AppEvent * aEvent) LOG_INF("Factory Reset Trigger Counter is cleared"); } -#if !CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE && CHIP_DEVICE_CONFIG_ENABLE_THREAD +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD void AppTaskCommon::StartThreadButtonEventHandler(void) { AppEvent event; @@ -592,7 +606,7 @@ void AppTaskCommon::StartThreadButtonEventHandler(void) void AppTaskCommon::StartThreadHandler(AppEvent * aEvent) { LOG_INF("StartThreadHandler"); - if (!chip::DeviceLayer::ConnectivityMgr().IsThreadProvisioned()) + if (!sIsNetworkProvisioned) { // Switch context from BLE to Thread #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE @@ -609,6 +623,37 @@ void AppTaskCommon::StartThreadHandler(AppEvent * aEvent) LOG_INF("Device already commissioned"); } } + +#elif CHIP_DEVICE_CONFIG_ENABLE_WIFI +void AppTaskCommon::StartWiFiButtonEventHandler(void) +{ + AppEvent event; + + event.Type = AppEvent::kEventType_Button; + event.ButtonEvent.Action = kButtonPushEvent; + event.Handler = StartWiFiHandler; + GetAppTask().PostEvent(&event); +} + +void AppTaskCommon::StartWiFiHandler(AppEvent * aEvent) +{ + LOG_INF("StartWiFiHandler"); + + if (!strlen(CONFIG_DEFAULT_WIFI_SSID) || !strlen(CONFIG_DEFAULT_WIFI_PASSWORD)) + { + LOG_ERR("default WiFi SSID/Password are not set"); + } + + if (!sIsNetworkProvisioned) + { + net_if_up(InetUtils::GetWiFiInterface()); + NetworkCommissioning::TelinkWiFiDriver().StartDefaultWiFiNetwork(); + } + else + { + LOG_INF("Device already commissioned"); + } +} #endif void AppTaskCommon::ExampleActionButtonEventHandler(void) @@ -673,11 +718,12 @@ void AppTaskCommon::ChipEventHandler(const ChipDeviceEvent * event, intptr_t /* case DeviceEventType::kThreadStateChange: sIsNetworkProvisioned = ConnectivityMgr().IsThreadProvisioned(); sIsNetworkEnabled = ConnectivityMgr().IsThreadEnabled(); - sIsThreadAttached = ConnectivityMgr().IsThreadAttached(); + sIsNetworkAttached = ConnectivityMgr().IsThreadAttached(); #elif CHIP_DEVICE_CONFIG_ENABLE_WIFI case DeviceEventType::kWiFiConnectivityChange: sIsNetworkProvisioned = ConnectivityMgr().IsWiFiStationProvisioned(); sIsNetworkEnabled = ConnectivityMgr().IsWiFiStationEnabled(); + sIsNetworkAttached = ConnectivityMgr().IsWiFiStationConnected(); #if CONFIG_CHIP_OTA_REQUESTOR if (event->WiFiConnectivityChange.Result == kConnectivity_Established) { diff --git a/examples/platform/telink/common/src/mainCommon.cpp b/examples/platform/telink/common/src/mainCommon.cpp index 7018adaa1b8c7c..583d61c0082c57 100644 --- a/examples/platform/telink/common/src/mainCommon.cpp +++ b/examples/platform/telink/common/src/mainCommon.cpp @@ -167,7 +167,8 @@ int main(void) #elif CHIP_DEVICE_CONFIG_ENABLE_WIFI sWiFiCommissioningInstance.Init(); #else - return CHIP_ERROR_INTERNAL; + err = CHIP_ERROR_INTERNAL; + goto exit; #endif /* CHIP_DEVICE_CONFIG_ENABLE_THREAD */ err = GetAppTask().StartApp(); diff --git a/examples/platform/telink/util/include/ThreadUtil.h b/examples/platform/telink/util/include/ThreadUtil.h index df5e8d2eb147ba..429d114647b4d1 100644 --- a/examples/platform/telink/util/include/ThreadUtil.h +++ b/examples/platform/telink/util/include/ThreadUtil.h @@ -19,6 +19,6 @@ #include "AppConfig.h" -#if !CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE && CHIP_DEVICE_CONFIG_ENABLE_THREAD +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD void StartDefaultThreadNetwork(void); #endif diff --git a/src/platform/telink/BLEManagerImpl.cpp b/src/platform/telink/BLEManagerImpl.cpp index 0d48b8b43cf0f7..55125cc07ef0be 100644 --- a/src/platform/telink/BLEManagerImpl.cpp +++ b/src/platform/telink/BLEManagerImpl.cpp @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2020-2022 Project CHIP Authors + * Copyright (c) 2020-2024 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. @@ -46,7 +46,7 @@ #include extern "C" { -#include +extern __attribute__((noinline)) void telink_bt_blc_mac_init(uint8_t * bt_mac); } #if defined(CONFIG_PM) && !defined(CONFIG_CHIP_ENABLE_PM_DURING_BLE) @@ -117,7 +117,7 @@ CHIP_ERROR InitBLEMACAddress() int error = 0; bt_addr_le_t addr; - b9x_bt_blc_mac_init(addr.a.val); + telink_bt_blc_mac_init(addr.a.val); if (BT_ADDR_IS_STATIC(&addr.a)) // in case of Random static address, create a new id { @@ -284,22 +284,26 @@ inline CHIP_ERROR BLEManagerImpl::PrepareAdvertisingRequest(void) CHIP_ERROR BLEManagerImpl::StartAdvertising(void) { + CHIP_ERROR err = CHIP_NO_ERROR; + +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD if (ConnectivityMgr().IsThreadProvisioned()) { - ChipLogProgress(DeviceLayer, "Thread provisioned, can't StartAdvertising"); + ChipLogProgress(DeviceLayer, "Device provisioned, can't StartAdvertising"); - return CHIP_ERROR_INCORRECT_STATE; + err = CHIP_ERROR_INCORRECT_STATE; } else if (!mBLERadioInitialized) { ThreadStackMgrImpl().StartThreadScan(mInternalScanCallback); } else +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD { - return StartAdvertisingProcess(); + err = StartAdvertisingProcess(); } - return CHIP_NO_ERROR; + return err; } CHIP_ERROR BLEManagerImpl::StartAdvertisingProcess(void) @@ -308,11 +312,13 @@ CHIP_ERROR BLEManagerImpl::StartAdvertisingProcess(void) if (!mBLERadioInitialized) { - /* Switch off Thread */ +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + // Deinit Thread ThreadStackMgrImpl().SetThreadEnabled(false); ThreadStackMgrImpl().SetRadioBlocked(true); +#endif - /* Init BLE stack */ + // Init BLE err = bt_enable(NULL); VerifyOrReturnError(err == 0, MapErrorZephyr(err)); @@ -379,12 +385,14 @@ CHIP_ERROR BLEManagerImpl::StartAdvertisingProcess(void) CHIP_ERROR BLEManagerImpl::StopAdvertising(void) { +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD if (ConnectivityMgr().IsThreadProvisioned()) { - ChipLogProgress(DeviceLayer, "Thread provisioned, StopAdvertising done"); + ChipLogProgress(DeviceLayer, "Device provisioned, StopAdvertising done"); return CHIP_ERROR_INCORRECT_STATE; } +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD ReturnErrorOnFailure(System::MapErrorZephyr(bt_le_adv_stop())); @@ -655,6 +663,7 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) err = HandleTXCharComplete(event); break; +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD case DeviceEventType::kThreadStateChange: err = HandleThreadStateChange(event); break; @@ -666,6 +675,7 @@ void BLEManagerImpl::_OnPlatformEvent(const ChipDeviceEvent * event) case DeviceEventType::kOperationalNetworkEnabled: err = HandleOperationalNetworkEnabled(event); break; +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD default: break; @@ -893,6 +903,7 @@ ssize_t BLEManagerImpl::HandleC3Read(struct bt_conn * conId, const struct bt_gat } #endif +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD CHIP_ERROR BLEManagerImpl::HandleOperationalNetworkEnabled(const ChipDeviceEvent * event) { ChipLogDetail(DeviceLayer, "HandleOperationalNetworkEnabled"); @@ -936,12 +947,11 @@ CHIP_ERROR BLEManagerImpl::HandleBleConnectionClosed(const ChipDeviceEvent * eve return CHIP_NO_ERROR; } -/* @todo: move to RadioSwitch module */ void BLEManagerImpl::SwitchToIeee802154(void) { - ChipLogProgress(DeviceLayer, "SwitchToIeee802154"); + ChipLogProgress(DeviceLayer, "Switch context from BLE to Thread"); - /* Deinit BLE stack */ + // Deinit BLE bt_disable(); mBLERadioInitialized = false; @@ -949,10 +959,11 @@ void BLEManagerImpl::SwitchToIeee802154(void) pm_policy_state_lock_put(PM_STATE_SUSPEND_TO_IDLE, PM_ALL_SUBSTATES); #endif - /* Init IEEE802154 */ + // Init Thread ThreadStackMgrImpl().SetRadioBlocked(false); ThreadStackMgrImpl().SetThreadEnabled(true); } +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD } // namespace Internal } // namespace DeviceLayer diff --git a/src/platform/telink/BLEManagerImpl.h b/src/platform/telink/BLEManagerImpl.h index 3a2c5d6ca0ed41..38ef878cee7171 100644 --- a/src/platform/telink/BLEManagerImpl.h +++ b/src/platform/telink/BLEManagerImpl.h @@ -1,6 +1,6 @@ /* * - * Copyright (c) 2022 Project CHIP Authors + * Copyright (c) 2022-2024 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. @@ -120,14 +120,16 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla CHIP_ERROR HandleBleConnectionClosed(const ChipDeviceEvent * event); /* - @todo WORKAROUND: Due to abscense of non-cuncurrent mode in Matter + WORKAROUND: Due to abscense of non-cuncurrent mode in Matter we are emulating connection to Thread with this events and manually disconnect BLE ass soon as OperationalNetworkEnabled occures. This functionality shall be removed as soon as non-cuncurrent mode would be implemented */ +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD CHIP_ERROR HandleThreadStateChange(const ChipDeviceEvent * event); CHIP_ERROR HandleOperationalNetworkEnabled(const ChipDeviceEvent * event); +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD InternalScanCallback * mInternalScanCallback; @@ -164,8 +166,10 @@ class BLEManagerImpl final : public BLEManager, private BleLayer, private BlePla static ssize_t HandleC3Read(struct bt_conn * conn, const struct bt_gatt_attr * attr, void * buf, uint16_t len, uint16_t offset); #endif - /* Switch to IEEE802154 interface. @todo: remove to other module? */ +#if CHIP_DEVICE_CONFIG_ENABLE_THREAD + // Switch context from BLE to Thread void SwitchToIeee802154(void); +#endif // CHIP_DEVICE_CONFIG_ENABLE_THREAD CHIP_ERROR StartAdvertisingProcess(void); }; diff --git a/src/platform/telink/BUILD.gn b/src/platform/telink/BUILD.gn index 787b45ca7c06eb..4d97b41bc2f0ef 100644 --- a/src/platform/telink/BUILD.gn +++ b/src/platform/telink/BUILD.gn @@ -45,8 +45,6 @@ static_library("telink") { "ConnectivityManagerImpl.h", "InetPlatformConfig.h", "KeyValueStoreManagerImpl.h", - "NFCManagerImpl.cpp", - "NFCManagerImpl.h", "PlatformManagerImpl.h", "SystemPlatformConfig.h", ] @@ -83,7 +81,7 @@ static_library("telink") { "ThreadStackManagerImpl.h", ] - if (chip_mdns == "platform") { + if (chip_mdns_platform) { sources += [ "../OpenThread/DnssdImpl.cpp", "../OpenThread/OpenThreadDnssdImpl.cpp", @@ -104,6 +102,13 @@ static_library("telink") { ] } + if (chip_enable_nfc) { + sources += [ + "NFCManagerImpl.cpp", + "NFCManagerImpl.h", + ] + } + if (chip_enable_ota_requestor) { sources += [ "OTAImageProcessorImpl.cpp", diff --git a/src/platform/telink/CHIPPlatformConfig.h b/src/platform/telink/CHIPPlatformConfig.h index 1bb4ab7b07203d..edd68b95380a84 100644 --- a/src/platform/telink/CHIPPlatformConfig.h +++ b/src/platform/telink/CHIPPlatformConfig.h @@ -102,11 +102,7 @@ #define CHIP_CONFIG_MAX_FABRICS 5 #endif -#ifndef CONFIG_CHIP_LOG_SIZE_OPTIMIZATION -#define CONFIG_CHIP_LOG_SIZE_OPTIMIZATION 0 -#endif - -#if CONFIG_CHIP_LOG_SIZE_OPTIMIZATION +#ifdef CONFIG_CHIP_LOG_SIZE_OPTIMIZATION // Disable some of the too detailed log modules to save flash #define CHIP_CONFIG_LOG_MODULE_ExchangeManager_DETAIL 0 #define CHIP_CONFIG_LOG_MODULE_Crypto_DETAIL 0 @@ -129,7 +125,6 @@ #define CHIP_CONFIG_LOG_MODULE_AppServer_DETAIL 0 #define CHIP_CONFIG_LOG_MODULE_Support_DETAIL 0 #define CHIP_CONFIG_LOG_MODULE_Support_PROGRESS 0 -#define CHIP_CONFIG_LOG_MODULE_DeviceLayer_DETAIL 0 #endif #ifndef CHIP_CONFIG_ICD_IDLE_MODE_DURATION_SEC diff --git a/src/platform/telink/NFCManagerImpl.cpp b/src/platform/telink/NFCManagerImpl.cpp index bb40b55305da73..084b297dfb8c46 100644 --- a/src/platform/telink/NFCManagerImpl.cpp +++ b/src/platform/telink/NFCManagerImpl.cpp @@ -17,7 +17,6 @@ #include -#if CHIP_DEVICE_CONFIG_ENABLE_NFC #include #include @@ -102,4 +101,3 @@ CHIP_ERROR NFCManagerImpl::_StopTagEmulation() } // namespace DeviceLayer } // namespace chip -#endif diff --git a/src/platform/telink/ThreadStackManagerImpl.h b/src/platform/telink/ThreadStackManagerImpl.h index b06e33d9f5e0b2..fd3dc6330f2fe7 100644 --- a/src/platform/telink/ThreadStackManagerImpl.h +++ b/src/platform/telink/ThreadStackManagerImpl.h @@ -39,7 +39,7 @@ class ThreadStackManager; class ThreadStackManagerImpl; /** - * Concrete implementation of the ThreadStackManager singleton object for nRF Connect platforms. + * Concrete implementation of the ThreadStackManager singleton object for Telink platforms. */ class ThreadStackManagerImpl final : public ThreadStackManager, public Internal::GenericThreadStackManagerImpl_OpenThread @@ -118,7 +118,7 @@ inline ThreadStackManager & ThreadStackMgr(void) * Returns the platform-specific implementation of the ThreadStackManager singleton object. * * chip applications can use this to gain access to features of the ThreadStackManager - * that are specific to nRF Connect platforms. + * that are specific to Telink platforms. */ inline ThreadStackManagerImpl & ThreadStackMgrImpl(void) { diff --git a/src/platform/telink/args.gni b/src/platform/telink/args.gni index 8a0a79b3a59761..23d446dd82bc64 100644 --- a/src/platform/telink/args.gni +++ b/src/platform/telink/args.gni @@ -12,10 +12,6 @@ # See the License for the specific language governing permissions and # limitations under the License. -chip_device_platform = "telink" - -chip_inet_config_enable_ipv4 = false - declare_args() { # Enable factory data support chip_enable_factory_data = false diff --git a/src/platform/telink/tlsr9118bdk40d_3m_flash.overlay b/src/platform/telink/tlsr9118bdk40d_3m_flash.overlay index 3e42145fb44370..02cd3b6582c8e0 100644 --- a/src/platform/telink/tlsr9118bdk40d_3m_flash.overlay +++ b/src/platform/telink/tlsr9118bdk40d_3m_flash.overlay @@ -7,6 +7,7 @@ /delete-node/ partition@88000; /delete-node/ partition@f0000; /delete-node/ partition@f4000; + /delete-node/ partition@fe000; boot_partition: partition@0 { label = "mcuboot"; reg = <0x00000000 0x20000>; @@ -27,7 +28,7 @@ label = "image-1"; reg = <0x118000 0xe8000>; }; - reserved_partition: partition@200000 { + vendor_partition: partition@200000 { label = "vendor-data"; reg = <0x200000 0x100000>; }; diff --git a/src/platform/telink/wifi/ConnectivityManagerImplWiFi.cpp b/src/platform/telink/wifi/ConnectivityManagerImplWiFi.cpp index 3fefcf709e1b9b..5bef79bb22fdc5 100644 --- a/src/platform/telink/wifi/ConnectivityManagerImplWiFi.cpp +++ b/src/platform/telink/wifi/ConnectivityManagerImplWiFi.cpp @@ -29,7 +29,6 @@ using namespace ::chip; using namespace ::chip::Inet; using namespace ::chip::System; -using namespace ::chip::TLV; namespace chip { namespace DeviceLayer { diff --git a/src/platform/telink/wifi/TelinkWiFiDriver.cpp b/src/platform/telink/wifi/TelinkWiFiDriver.cpp index d6b47053839e35..f6c19a2c1f3030 100644 --- a/src/platform/telink/wifi/TelinkWiFiDriver.cpp +++ b/src/platform/telink/wifi/TelinkWiFiDriver.cpp @@ -122,7 +122,22 @@ void TelinkWiFiDriver::OnNetworkStatusChanged(Status status) if (mpNetworkStatusChangeCallback) { - mpNetworkStatusChangeCallback->OnNetworkingStatusChange(status, NullOptional, NullOptional); + const uint8_t * ssid{}; + size_t ssidLen{}; + WiFiManager::WiFiInfo wifiInfo; + + if (CHIP_NO_ERROR == WiFiManager::Instance().GetWiFiInfo(wifiInfo)) + { + ssid = wifiInfo.mSsid; + ssidLen = wifiInfo.mSsidLen; + } + else + { + ssid = WiFiManager::Instance().GetWantedNetwork().ssid; + ssidLen = WiFiManager::Instance().GetWantedNetwork().ssidLen; + } + mpNetworkStatusChangeCallback->OnNetworkingStatusChange(status, MakeOptional(ByteSpan(wifiInfo.mSsid, wifiInfo.mSsidLen)), + NullOptional); } if (mpConnectCallback) @@ -249,11 +264,10 @@ void TelinkWiFiDriver::LoadFromStorage() mStagingNetwork = network; } -void TelinkWiFiDriver::OnScanWiFiNetworkDone(WiFiManager::WiFiRequestStatus status) +void TelinkWiFiDriver::OnScanWiFiNetworkDone(const WiFiManager::ScanDoneStatus & status) { VerifyOrReturn(mScanCallback != nullptr); - mScanCallback->OnFinished(status == WiFiManager::WiFiRequestStatus::SUCCESS ? Status::kSuccess : Status::kUnknownError, - CharSpan(), &mScanResponseIterator); + mScanCallback->OnFinished(status ? Status::kUnknownError : Status::kSuccess, CharSpan(), &mScanResponseIterator); mScanCallback = nullptr; } @@ -267,7 +281,7 @@ void TelinkWiFiDriver::ScanNetworks(ByteSpan ssid, WiFiDriver::ScanCallback * ca mScanCallback = callback; CHIP_ERROR error = WiFiManager::Instance().Scan( ssid, [](const WiFiScanResponse & response) { Instance().OnScanWiFiNetworkResult(response); }, - [](WiFiManager::WiFiRequestStatus status) { Instance().OnScanWiFiNetworkDone(status); }); + [](const WiFiManager::ScanDoneStatus & status) { Instance().OnScanWiFiNetworkDone(status); }); if (error != CHIP_NO_ERROR) { @@ -276,6 +290,27 @@ void TelinkWiFiDriver::ScanNetworks(ByteSpan ssid, WiFiDriver::ScanCallback * ca } } +uint32_t TelinkWiFiDriver::GetSupportedWiFiBandsMask() const +{ + uint32_t bands = static_cast(1UL << chip::to_underlying(WiFiBandEnum::k2g4)); + return bands; +} + +void TelinkWiFiDriver::StartDefaultWiFiNetwork(void) +{ + chip::ByteSpan ssidSpan = ByteSpan(Uint8::from_const_char(CONFIG_DEFAULT_WIFI_SSID), strlen(CONFIG_DEFAULT_WIFI_SSID)); + chip::ByteSpan passwordSpan = + ByteSpan(Uint8::from_const_char(CONFIG_DEFAULT_WIFI_PASSWORD), strlen(CONFIG_DEFAULT_WIFI_PASSWORD)); + + char debugBuffer[1] = { 0 }; + MutableCharSpan debugText(debugBuffer, 0); + uint8_t outNetworkIndex = 0; + + AddOrUpdateNetwork(ssidSpan, passwordSpan, debugText, outNetworkIndex); + CommitConfiguration(); + RevertConfiguration(); +} + } // namespace NetworkCommissioning } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/telink/wifi/TelinkWiFiDriver.h b/src/platform/telink/wifi/TelinkWiFiDriver.h index b9f9b6374c42e3..9c5b1e61d1f0e1 100644 --- a/src/platform/telink/wifi/TelinkWiFiDriver.h +++ b/src/platform/telink/wifi/TelinkWiFiDriver.h @@ -86,6 +86,7 @@ class TelinkWiFiDriver final : public WiFiDriver Status AddOrUpdateNetwork(ByteSpan ssid, ByteSpan credentials, MutableCharSpan & outDebugText, uint8_t & outNetworkIndex) override; void ScanNetworks(ByteSpan ssid, ScanCallback * callback) override; + uint32_t GetSupportedWiFiBandsMask() const override; static TelinkWiFiDriver & Instance() { @@ -95,7 +96,9 @@ class TelinkWiFiDriver final : public WiFiDriver void OnNetworkStatusChanged(Status status); void OnScanWiFiNetworkResult(const WiFiScanResponse & result); - void OnScanWiFiNetworkDone(WiFiManager::WiFiRequestStatus status); + void OnScanWiFiNetworkDone(const WiFiManager::ScanDoneStatus & status); + + void StartDefaultWiFiNetwork(void); private: void LoadFromStorage(); diff --git a/src/platform/telink/wifi/WiFiManager.cpp b/src/platform/telink/wifi/WiFiManager.cpp index 88195fdbee2ab8..50ea5cf5682089 100644 --- a/src/platform/telink/wifi/WiFiManager.cpp +++ b/src/platform/telink/wifi/WiFiManager.cpp @@ -23,8 +23,6 @@ #include "WiFiManager.h" #include -#include -#include #include #include #include @@ -127,27 +125,44 @@ const Map { WIFI_STATE_GROUP_HANDSHAKE, WiFiManager::StationStatus::PROVISIONING }, { WIFI_STATE_COMPLETED, WiFiManager::StationStatus::FULLY_PROVISIONED } }); -const Map - WiFiManager::sEventHandlerMap({ { NET_EVENT_WIFI_SCAN_RESULT, WiFiManager::ScanResultHandler }, - { NET_EVENT_WIFI_SCAN_DONE, WiFiManager::ScanDoneHandler }, - { NET_EVENT_WIFI_CONNECT_RESULT, WiFiManager::ConnectHandler }, - { NET_EVENT_WIFI_DISCONNECT_RESULT, WiFiManager::DisconnectHandler } }); +const Map WiFiManager::sEventHandlerMap({ + { NET_EVENT_WIFI_SCAN_RESULT, WiFiManager::ScanResultHandler }, + { NET_EVENT_WIFI_SCAN_DONE, WiFiManager::ScanDoneHandler }, + { NET_EVENT_WIFI_CONNECT_RESULT, WiFiManager::ConnectHandler }, + { NET_EVENT_WIFI_DISCONNECT_RESULT, WiFiManager::DisconnectHandler }, +}); void WiFiManager::WifiMgmtEventHandler(net_mgmt_event_callback * cb, uint32_t mgmtEvent, net_if * iface) { - if (0 == strcmp(iface->if_dev->dev->name, "wlan0")) + if (iface == Instance().mNetIf) { Platform::UniquePtr eventData(new uint8_t[cb->info_length]); VerifyOrReturn(eventData); memcpy(eventData.get(), cb->info, cb->info_length); - sEventHandlerMap[mgmtEvent](std::move(eventData)); + sEventHandlerMap[mgmtEvent](std::move(eventData), cb->info_length); + } +} + +void WiFiManager::IPv6MgmtEventHandler(net_mgmt_event_callback * cb, uint32_t mgmtEvent, net_if * iface) +{ + if (((mgmtEvent == NET_EVENT_IPV6_ADDR_ADD) || (mgmtEvent == NET_EVENT_IPV6_ADDR_DEL)) && cb->info) + { + IPv6AddressChangeHandler(cb->info); } } CHIP_ERROR WiFiManager::Init() { + mNetIf = InetUtils::GetWiFiInterface(); + VerifyOrReturnError(mNetIf != nullptr, INET_ERROR_UNKNOWN_INTERFACE); + + net_if_down(mNetIf); // block netif auto start + net_mgmt_init_event_callback(&mWiFiMgmtClbk, WifiMgmtEventHandler, kWifiManagementEvents); + net_mgmt_init_event_callback(&mIPv6MgmtClbk, IPv6MgmtEventHandler, kIPv6ManagementEvents); + net_mgmt_add_event_callback(&mWiFiMgmtClbk); + net_mgmt_add_event_callback(&mIPv6MgmtClbk); ChipLogDetail(DeviceLayer, "WiFiManager has been initialized"); @@ -156,9 +171,6 @@ CHIP_ERROR WiFiManager::Init() CHIP_ERROR WiFiManager::Scan(const ByteSpan & ssid, ScanResultCallback resultCallback, ScanDoneCallback doneCallback, bool internalScan) { - net_if * iface = InetUtils::GetInterface(); - VerifyOrReturnError(nullptr != iface, CHIP_ERROR_INTERNAL); - mInternalScan = internalScan; mScanResultCallback = resultCallback; mScanDoneCallback = doneCallback; @@ -166,7 +178,7 @@ CHIP_ERROR WiFiManager::Scan(const ByteSpan & ssid, ScanResultCallback resultCal mWiFiState = WIFI_STATE_SCANNING; mSsidFound = false; - if (0 != net_mgmt(NET_REQUEST_WIFI_SCAN, iface, NULL, 0)) + if (0 != net_mgmt(NET_REQUEST_WIFI_SCAN, mNetIf, NULL, 0)) { ChipLogError(DeviceLayer, "Scan request failed"); return CHIP_ERROR_INTERNAL; @@ -207,11 +219,8 @@ CHIP_ERROR WiFiManager::Connect(const ByteSpan & ssid, const ByteSpan & credenti CHIP_ERROR WiFiManager::Disconnect() { - net_if * iface = InetUtils::GetInterface(); - VerifyOrReturnError(nullptr != iface, CHIP_ERROR_INTERNAL); - mApplicationDisconnectRequested = true; - int status = net_mgmt(NET_REQUEST_WIFI_DISCONNECT, iface, NULL, 0); + int status = net_mgmt(NET_REQUEST_WIFI_DISCONNECT, mNetIf, NULL, 0); if (status) { @@ -236,11 +245,9 @@ CHIP_ERROR WiFiManager::Disconnect() CHIP_ERROR WiFiManager::GetWiFiInfo(WiFiInfo & info) const { - net_if * iface = InetUtils::GetInterface(); - VerifyOrReturnError(nullptr != iface, CHIP_ERROR_INTERNAL); - struct wifi_iface_status status = { 0 }; + wifi_iface_status status = { 0 }; - if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &status, sizeof(struct wifi_iface_status))) + if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, mNetIf, &status, sizeof(wifi_iface_status))) { ChipLogError(DeviceLayer, "Status request failed"); return CHIP_ERROR_INTERNAL; @@ -265,7 +272,7 @@ CHIP_ERROR WiFiManager::GetWiFiInfo(WiFiInfo & info) const CHIP_ERROR WiFiManager::GetNetworkStatistics(NetworkStatistics & stats) const { net_stats_wifi data{}; - net_mgmt(NET_REQUEST_STATS_GET_WIFI, InetUtils::GetInterface(), &data, sizeof(data)); + net_mgmt(NET_REQUEST_STATS_GET_WIFI, mNetIf, &data, sizeof(data)); stats.mPacketMulticastRxCount = data.multicast.rx; stats.mPacketMulticastTxCount = data.multicast.tx; @@ -277,10 +284,13 @@ CHIP_ERROR WiFiManager::GetNetworkStatistics(NetworkStatistics & stats) const return CHIP_NO_ERROR; } -void WiFiManager::ScanResultHandler(Platform::UniquePtr data) +void WiFiManager::ScanResultHandler(Platform::UniquePtr data, size_t length) { + // Validate that input data size matches the expected one. + VerifyOrReturn(length == sizeof(wifi_scan_result)); + // Contrary to other handlers, offload accumulating of the scan results from the CHIP thread to the caller's thread - const struct wifi_scan_result * scanResult = reinterpret_cast(data.get()); + const wifi_scan_result * scanResult = reinterpret_cast(data.get()); if (Instance().mInternalScan && Instance().mWantedNetwork.GetSsidSpan().data_equal(ByteSpan(scanResult->ssid, scanResult->ssid_length))) @@ -311,6 +321,7 @@ void WiFiManager::ScanResultHandler(Platform::UniquePtr data) Instance().mWiFiParams.mParams.timeout = Instance().mHandling.mConnectionTimeout.count(); Instance().mWiFiParams.mParams.channel = WIFI_CHANNEL_ANY; Instance().mWiFiParams.mRssi = scanResult->rssi; + Instance().mWiFiParams.mParams.band = WIFI_FREQ_BAND_UNKNOWN; Instance().mSsidFound = true; } } @@ -321,26 +332,29 @@ void WiFiManager::ScanResultHandler(Platform::UniquePtr data) } } -void WiFiManager::ScanDoneHandler(Platform::UniquePtr data) +void WiFiManager::ScanDoneHandler(Platform::UniquePtr data, size_t length) { + // Validate that input data size matches the expected one. + VerifyOrReturn(length == sizeof(wifi_status)); + CHIP_ERROR err = SystemLayer().ScheduleLambda([capturedData = data.get()] { Platform::UniquePtr safePtr(capturedData); - uint8_t * rawData = safePtr.get(); - const wifi_status * status = reinterpret_cast(rawData); - WiFiRequestStatus requestStatus = static_cast(status->status); + uint8_t * rawData = safePtr.get(); + const wifi_status * status = reinterpret_cast(rawData); + ScanDoneStatus scanDoneStatus = status->status; - if (requestStatus == WiFiRequestStatus::FAILURE) + if (scanDoneStatus) { - ChipLogError(DeviceLayer, "Wi-Fi scan finalization failure (%d)", status->status); + ChipLogError(DeviceLayer, "Wi-Fi scan finalization failure (%d)", scanDoneStatus); } else { - ChipLogProgress(DeviceLayer, "Wi-Fi scan done (%d)", status->status); + ChipLogProgress(DeviceLayer, "Wi-Fi scan done"); } if (Instance().mScanDoneCallback && !Instance().mInternalScan) { - Instance().mScanDoneCallback(requestStatus); + Instance().mScanDoneCallback(scanDoneStatus); // restore the connection state from before the scan request was issued Instance().mWiFiState = Instance().mCachedWiFiState; return; @@ -356,13 +370,13 @@ void WiFiManager::ScanDoneHandler(Platform::UniquePtr data) ChipLogProgress(DeviceLayer, "Starting connection recover: re-scanning... (next attempt in %d ms)", currentTimeout.count()); DeviceLayer::SystemLayer().StartTimer(currentTimeout, Recover, nullptr); + return; } Instance().mWiFiState = WIFI_STATE_ASSOCIATING; - net_if * iface = InetUtils::GetInterface(); - VerifyOrReturn(nullptr != iface, CHIP_ERROR_INTERNAL); - if (net_mgmt(NET_REQUEST_WIFI_CONNECT, iface, &(Instance().mWiFiParams.mParams), sizeof(wifi_connect_req_params))) + if (net_mgmt(NET_REQUEST_WIFI_CONNECT, Instance().mNetIf, &(Instance().mWiFiParams.mParams), + sizeof(wifi_connect_req_params))) { ChipLogError(DeviceLayer, "Connection request failed"); if (Instance().mHandling.mOnConnectionFailed) @@ -387,25 +401,24 @@ void WiFiManager::ScanDoneHandler(Platform::UniquePtr data) void WiFiManager::SendRouterSolicitation(System::Layer * layer, void * param) { - net_if * iface = InetUtils::GetInterface(); - if (iface && iface->if_dev->link_addr.type == NET_LINK_ETHERNET) + net_if_start_rs(Instance().mNetIf); + Instance().mRouterSolicitationCounter++; + if (Instance().mRouterSolicitationCounter < kRouterSolicitationMaxCount) { - net_if_start_rs(iface); - Instance().mRouterSolicitationCounter++; - if (Instance().mRouterSolicitationCounter < kRouterSolicitationMaxCount) - { - DeviceLayer::SystemLayer().StartTimer(System::Clock::Milliseconds32(kRouterSolicitationIntervalMs), - SendRouterSolicitation, nullptr); - } - else - { - Instance().mRouterSolicitationCounter = 0; - } + DeviceLayer::SystemLayer().StartTimer(System::Clock::Milliseconds32(kRouterSolicitationIntervalMs), SendRouterSolicitation, + nullptr); + } + else + { + Instance().mRouterSolicitationCounter = 0; } } -void WiFiManager::ConnectHandler(Platform::UniquePtr data) +void WiFiManager::ConnectHandler(Platform::UniquePtr data, size_t length) { + // Validate that input data size matches the expected one. + VerifyOrReturn(length == sizeof(wifi_status)); + CHIP_ERROR err = SystemLayer().ScheduleLambda([capturedData = data.get()] { Platform::UniquePtr safePtr(capturedData); uint8_t * rawData = safePtr.get(); @@ -457,13 +470,41 @@ void WiFiManager::ConnectHandler(Platform::UniquePtr data) } } -void WiFiManager::DisconnectHandler(Platform::UniquePtr) +void WiFiManager::DisconnectHandler(Platform::UniquePtr data, size_t length) { - SystemLayer().ScheduleLambda([] { + // Validate that input data size matches the expected one. + VerifyOrReturn(length == sizeof(wifi_status)); + + CHIP_ERROR err = SystemLayer().ScheduleLambda([] { ChipLogProgress(DeviceLayer, "WiFi station disconnected"); Instance().mWiFiState = WIFI_STATE_DISCONNECTED; Instance().PostConnectivityStatusChange(kConnectivity_Lost); }); + + if (CHIP_NO_ERROR == err) + { + // the ownership has been transferred to the worker thread - release the buffer + data.release(); + } +} + +void WiFiManager::IPv6AddressChangeHandler(const void * data) +{ + const in6_addr * addr = reinterpret_cast(data); + + // Filter out link-local addresses that are not routable outside of a local network. + if (!net_ipv6_is_ll_addr(addr)) + { + // This is needed to send mDNS queries containing updated IPv6 addresses. + ChipDeviceEvent event; + event.Type = DeviceEventType::kDnssdRestartNeeded; + + CHIP_ERROR error = PlatformMgr().PostEvent(&event); + if (error != CHIP_NO_ERROR) + { + ChipLogError(DeviceLayer, "Cannot post event: %" CHIP_ERROR_FORMAT, error.Format()); + } + } } WiFiManager::StationStatus WiFiManager::GetStationStatus() const @@ -529,11 +570,10 @@ System::Clock::Milliseconds32 WiFiManager::CalculateNextRecoveryTime() CHIP_ERROR WiFiManager::SetLowPowerMode(bool onoff) { - net_if * iface = InetUtils::GetInterface(); - VerifyOrReturnError(nullptr != iface, CHIP_ERROR_INTERNAL); + VerifyOrReturnError(nullptr != mNetIf, CHIP_ERROR_INTERNAL); wifi_ps_config currentConfig{}; - if (net_mgmt(NET_REQUEST_WIFI_PS_CONFIG, iface, ¤tConfig, sizeof(currentConfig))) + if (net_mgmt(NET_REQUEST_WIFI_PS_CONFIG, mNetIf, ¤tConfig, sizeof(currentConfig))) { ChipLogError(DeviceLayer, "Get current low power mode config request failed"); return CHIP_ERROR_INTERNAL; @@ -543,7 +583,7 @@ CHIP_ERROR WiFiManager::SetLowPowerMode(bool onoff) (currentConfig.ps_params.enabled == WIFI_PS_DISABLED && onoff == true)) { wifi_ps_params params{ .enabled = onoff ? WIFI_PS_ENABLED : WIFI_PS_DISABLED }; - if (net_mgmt(NET_REQUEST_WIFI_PS, iface, ¶ms, sizeof(params))) + if (net_mgmt(NET_REQUEST_WIFI_PS, mNetIf, ¶ms, sizeof(params))) { ChipLogError(DeviceLayer, "Set low power mode request failed"); return CHIP_ERROR_INTERNAL; diff --git a/src/platform/telink/wifi/WiFiManager.h b/src/platform/telink/wifi/WiFiManager.h index f48d8f9b372469..49c9496f5d13be 100644 --- a/src/platform/telink/wifi/WiFiManager.h +++ b/src/platform/telink/wifi/WiFiManager.h @@ -90,8 +90,9 @@ class WiFiManager TERMINATED = 2 }; + using ScanDoneStatus = decltype(wifi_status::status); using ScanResultCallback = void (*)(const NetworkCommissioning::WiFiScanResponse &); - using ScanDoneCallback = void (*)(WiFiRequestStatus); + using ScanDoneCallback = void (*)(const ScanDoneStatus &); using ConnectionCallback = void (*)(); enum class StationStatus : uint8_t @@ -177,12 +178,13 @@ class WiFiManager CHIP_ERROR ClearStationProvisioningData(); CHIP_ERROR Disconnect(); CHIP_ERROR GetWiFiInfo(WiFiInfo & info) const; + const WiFiNetwork & GetWantedNetwork() const { return mWantedNetwork; } CHIP_ERROR GetNetworkStatistics(NetworkStatistics & stats) const; void AbortConnectionRecovery(); CHIP_ERROR SetLowPowerMode(bool onoff); private: - using NetEventHandler = void (*)(Platform::UniquePtr); + using NetEventHandler = void (*)(Platform::UniquePtr, size_t); struct ConnectionParams { @@ -193,14 +195,18 @@ class WiFiManager constexpr static uint32_t kWifiManagementEvents = NET_EVENT_WIFI_SCAN_RESULT | NET_EVENT_WIFI_SCAN_DONE | NET_EVENT_WIFI_CONNECT_RESULT | NET_EVENT_WIFI_DISCONNECT_RESULT | NET_EVENT_WIFI_IFACE_STATUS; + constexpr static uint32_t kIPv6ManagementEvents = NET_EVENT_IPV6_ADDR_ADD | NET_EVENT_IPV6_ADDR_DEL; + // Event handling static void WifiMgmtEventHandler(net_mgmt_event_callback * cb, uint32_t mgmtEvent, net_if * iface); - static void ScanResultHandler(Platform::UniquePtr data); - static void ScanDoneHandler(Platform::UniquePtr data); - static void ConnectHandler(Platform::UniquePtr data); - static void DisconnectHandler(Platform::UniquePtr data); + static void IPv6MgmtEventHandler(net_mgmt_event_callback * cb, uint32_t mgmtEvent, net_if * iface); + static void ScanResultHandler(Platform::UniquePtr data, size_t length); + static void ScanDoneHandler(Platform::UniquePtr data, size_t length); + static void ConnectHandler(Platform::UniquePtr data, size_t length); + static void DisconnectHandler(Platform::UniquePtr data, size_t length); static void PostConnectivityStatusChange(ConnectivityChange changeType); static void SendRouterSolicitation(System::Layer * layer, void * param); + static void IPv6AddressChangeHandler(const void * data); // Connection Recovery feature // This feature allows re-scanning and re-connecting the connection to the known network after @@ -215,11 +221,13 @@ class WiFiManager void ResetRecoveryTime(); System::Clock::Milliseconds32 CalculateNextRecoveryTime(); + net_if * mNetIf{ nullptr }; ConnectionParams mWiFiParams{}; - ConnectionHandling mHandling; + ConnectionHandling mHandling{}; wifi_iface_state mWiFiState; wifi_iface_state mCachedWiFiState; net_mgmt_event_callback mWiFiMgmtClbk{}; + net_mgmt_event_callback mIPv6MgmtClbk{}; ScanResultCallback mScanResultCallback{ nullptr }; ScanDoneCallback mScanDoneCallback{ nullptr }; WiFiNetwork mWantedNetwork{};