diff --git a/config/nrfconnect/chip-module/CMakeLists.txt b/config/nrfconnect/chip-module/CMakeLists.txt index 70edc0c7087865..ed844c2d503ad3 100644 --- a/config/nrfconnect/chip-module/CMakeLists.txt +++ b/config/nrfconnect/chip-module/CMakeLists.txt @@ -219,6 +219,7 @@ chip_gn_arg_bool ("chip_progress_logging" CONFIG_MATTER_LOG_LE chip_gn_arg_bool ("chip_detail_logging" CONFIG_MATTER_LOG_LEVEL GREATER_EQUAL 4) chip_gn_arg_bool ("chip_automation_logging" "false") chip_gn_arg_bool ("chip_malloc_sys_heap" CONFIG_CHIP_MALLOC_SYS_HEAP) +chip_gn_arg_bool ("chip_enable_wifi" CONFIG_WIFI_NRF700X) if (CONFIG_CHIP_FACTORY_DATA) chip_gn_arg_bool ("chip_use_transitional_commissionable_data_provider" "false") @@ -232,8 +233,12 @@ if (CONFIG_CHIP_ROTATING_DEVICE_ID) chip_gn_arg_bool("chip_enable_additional_data_advertising" "true") endif() -if (CONFIG_CHIP_ENABLE_DNSSD_SRP) +if (CONFIG_NET_L2_OPENTHREAD) chip_gn_arg_string("chip_mdns" "platform") +elseif(CONFIG_WIFI_NRF700X) + chip_gn_arg_string("chip_mdns" "minimal") +else() + chip_gn_arg_string("chip_mdns" "none") endif() if (CHIP_PROJECT_CONFIG) diff --git a/config/nrfconnect/chip-module/Kconfig.defaults b/config/nrfconnect/chip-module/Kconfig.defaults index 4addc9b469c8ac..aaccab5331f92a 100644 --- a/config/nrfconnect/chip-module/Kconfig.defaults +++ b/config/nrfconnect/chip-module/Kconfig.defaults @@ -40,6 +40,22 @@ config LOG_DEFAULT_LEVEL endif +config FLASH + bool + default y + +config SETTINGS + bool + default y + +config NVS + bool + default y + +config FLASH_MAP + bool + default y + config PRINTK_SYNC bool default y @@ -198,20 +214,88 @@ config NVS_LOOKUP_CACHE bool default y +# Enable OpenThread + +config NET_L2_OPENTHREAD + bool + default y if !WIFI_NRF700X + +if NET_L2_OPENTHREAD + +config OPENTHREAD_PANID + int + default 4660 + +config OPENTHREAD_CHANNEL + int + default 15 + +config OPENTHREAD_NETWORK_NAME + string + default "OpenThread" + +config OPENTHREAD_XPANID + string + default "11:11:11:11:22:22:22:22" + # Increase the default RX stack size config IEEE802154_NRF5_RX_STACK_SIZE int default 1024 -# Enable OpenThread +endif -config NET_L2_OPENTHREAD +if CHIP_WIFI + +config MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG bool - default y + default n + +config SYSTEM_WORKQUEUE_STACK_SIZE + int + default 1120 + +# align these numbers to match the OpenThread config +config NET_IF_UNICAST_IPV6_ADDR_COUNT + int + default 6 + +config NET_IF_MCAST_IPV6_ADDR_COUNT + int + default 8 + +config NET_SOCKETS_POSIX_NAMES + bool + default n + +config MBEDTLS_SSL_OUT_CONTENT_LEN + int + default 900 + +config CHIP_ENABLE_DNSSD_SRP + bool + default n + +# options managed by IP4/IP6 simultaneous support +# aligned here to match OpenThread config +config NET_MAX_ROUTERS + int + default 1 + +config NET_MAX_CONN + int + default 4 + +config SHELL_STACK_SIZE + int + default 2616 + +config HEAP_MEM_POOL_SIZE + int + default 200000 + +endif -choice OPENTHREAD_STACK_VERSION - default OPENTHREAD_THREAD_VERSION_1_3 -endchoice # Enable mbedTLS from nrf_security library diff --git a/config/nrfconnect/chip-module/Kconfig.features b/config/nrfconnect/chip-module/Kconfig.features index b63983a11e9e3f..bf8adfc1742b3b 100644 --- a/config/nrfconnect/chip-module/Kconfig.features +++ b/config/nrfconnect/chip-module/Kconfig.features @@ -19,6 +19,27 @@ if CHIP +config CHIP_WIFI + bool "Enable nrfconnect Wi-Fi support" + default y if SHIELD_NRF7002_EK || BOARD_NRF7002DK_NRF5340_CPUAPP + select WIFI_NRF700X + select WIFI + select WPA_SUPP + imply NORDIC_SECURITY_BACKEND + imply MBEDTLS_ENTROPY_C + imply MBEDTLS_PSA_CRYPTO_C + imply NET_STATISTICS + imply NET_L2_ETHERNET + imply NET_PKT_TXTIME + imply NET_PKT_TIMESTAMP + imply MBEDTLS_PROMPTLESS + imply BUILD_OUTPUT_META + imply USE_DT_CODE_PARTITION # might be removed when the OTA is enabled + imply NET_IPV6_ND # enable Neighbor Discovery to handle Router Advertisements + imply NET_IPV6_NBR_CACHE + imply NET_STATISTICS_IPV6 + imply NET_STATISTICS_USER_API + config CHIP_QSPI_NOR bool "Enable QSPI NOR feature set" help diff --git a/examples/all-clusters-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/all-clusters-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay index 5be8b8fd5f736f..9b117f0fc954a5 100644 --- a/examples/all-clusters-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/examples/all-clusters-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -69,9 +69,6 @@ &adc { status = "disabled"; }; -&gpio1 { - status = "disabled"; -}; &i2c1 { status = "disabled"; }; diff --git a/examples/all-clusters-app/nrfconnect/main/AppTask.cpp b/examples/all-clusters-app/nrfconnect/main/AppTask.cpp index be4a44dc8a2985..e044729e24277b 100644 --- a/examples/all-clusters-app/nrfconnect/main/AppTask.cpp +++ b/examples/all-clusters-app/nrfconnect/main/AppTask.cpp @@ -142,6 +142,7 @@ CHIP_ERROR AppTask::Init() return err; } +#if defined(CONFIG_NET_L2_OPENTHREAD) err = ThreadStackMgr().InitThreadStack(); if (err != CHIP_NO_ERROR) { @@ -159,6 +160,7 @@ CHIP_ERROR AppTask::Init() LOG_ERR("ConnectivityMgr().SetThreadDeviceType() failed"); return err; } +#endif // Initialize LEDs LEDWidget::InitGpio(); diff --git a/examples/all-clusters-minimal-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/all-clusters-minimal-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay index 5be8b8fd5f736f..9b117f0fc954a5 100644 --- a/examples/all-clusters-minimal-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/examples/all-clusters-minimal-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -69,9 +69,6 @@ &adc { status = "disabled"; }; -&gpio1 { - status = "disabled"; -}; &i2c1 { status = "disabled"; }; diff --git a/examples/chef/nrfconnect/CMakeLists.txt b/examples/chef/nrfconnect/CMakeLists.txt index 81ab4e81285132..c488260d78f10a 100644 --- a/examples/chef/nrfconnect/CMakeLists.txt +++ b/examples/chef/nrfconnect/CMakeLists.txt @@ -88,7 +88,7 @@ target_sources(app PRIVATE ${CHEF}/common/stubs.cpp ${GEN_DIR}/callback-stub.cpp ${GEN_DIR}/IMClusterCommandHandler.cpp - ${NRFCONNECT_COMMON}/util/ThreadUtil.cpp + $<$:${NRFCONNECT_COMMON}/util/ThreadUtil.cpp> ) message(STATUS ${CHEF}/devices/${SAMPLE_NAME}.zap) diff --git a/examples/chef/nrfconnect/main.cpp b/examples/chef/nrfconnect/main.cpp index 81a69255ba58dc..e8430e1dbe4c18 100644 --- a/examples/chef/nrfconnect/main.cpp +++ b/examples/chef/nrfconnect/main.cpp @@ -79,7 +79,8 @@ CHIP_ERROR main() #if CHIP_DEVICE_CONFIG_ENABLE_WPA ConnectivityManagerImpl().StartWiFiManagement(); #endif -#if CHIP_ENABLE_OPENTHREAD + +#if defined(CHIP_ENABLE_OPENTHREAD) err = ThreadStackMgr().InitThreadStack(); if (err != CHIP_NO_ERROR) { @@ -97,7 +98,9 @@ CHIP_ERROR main() ChipLogError(AppServer, "ConnectivityMgr().SetThreadDeviceType() failed"); return err; } -#endif /* CHIP_ENABLE_OPENTHREAD */ +#elif !defined(CONFIG_WIFI_NRF700X) + return CHIP_ERROR_INTERNAL; +#endif // Device Attestation & Onboarding codes chip::Credentials::SetDeviceAttestationCredentialsProvider(chip::Credentials::Examples::GetExampleDACProvider()); diff --git a/examples/chef/nrfconnect/prj.conf b/examples/chef/nrfconnect/prj.conf index e43fdf593a7388..ad695dfca53211 100644 --- a/examples/chef/nrfconnect/prj.conf +++ b/examples/chef/nrfconnect/prj.conf @@ -28,12 +28,6 @@ CONFIG_PWM=y # OpenThread configs CONFIG_OPENTHREAD_NORDIC_LIBRARY_FTD=y -# Default OpenThread network settings -CONFIG_OPENTHREAD_PANID=4660 -CONFIG_OPENTHREAD_CHANNEL=15 -CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread" -CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" - # Bluetooth overrides CONFIG_BT_DEVICE_NAME="MatterLight" diff --git a/examples/light-switch-app/nrfconnect/CMakeLists.txt b/examples/light-switch-app/nrfconnect/CMakeLists.txt index 10cfa5f2fdf39b..ef51158f106f6e 100644 --- a/examples/light-switch-app/nrfconnect/CMakeLists.txt +++ b/examples/light-switch-app/nrfconnect/CMakeLists.txt @@ -61,7 +61,7 @@ target_sources(app PRIVATE ${GEN_DIR}/light-switch-app/zap-generated/callback-stub.cpp ${GEN_DIR}/light-switch-app/zap-generated/IMClusterCommandHandler.cpp ${NRFCONNECT_COMMON}/util/LEDWidget.cpp - ${NRFCONNECT_COMMON}/util/ThreadUtil.cpp) + $<$:${NRFCONNECT_COMMON}/util/ThreadUtil.cpp>) if(CONFIG_CHIP_OTA_REQUESTOR) diff --git a/examples/light-switch-app/nrfconnect/main/AppTask.cpp b/examples/light-switch-app/nrfconnect/main/AppTask.cpp index 8ca5fac1429403..cd4ff8b1f99b5a 100644 --- a/examples/light-switch-app/nrfconnect/main/AppTask.cpp +++ b/examples/light-switch-app/nrfconnect/main/AppTask.cpp @@ -20,7 +20,9 @@ #include "AppConfig.h" #include "LEDWidget.h" #include "LightSwitch.h" +#ifdef CONFIG_NET_L2_OPENTHREAD #include "ThreadUtil.h" +#endif #include #include @@ -114,6 +116,7 @@ CHIP_ERROR AppTask::Init() return err; } +#if defined(CONFIG_NET_L2_OPENTHREAD) err = ThreadStackMgr().InitThreadStack(); if (err != CHIP_NO_ERROR) { @@ -131,6 +134,9 @@ CHIP_ERROR AppTask::Init() LOG_ERR("ConnectivityMgr().SetThreadDeviceType() failed: %s", ErrorStr(err)); return err; } +#elif !defined(CONFIG_WIFI_NRF700X) + return CHIP_ERROR_INTERNAL; +#endif LightSwitch::GetInstance().Init(kLightDimmerSwitchEndpointId, kLightGenericSwitchEndpointId); diff --git a/examples/lighting-app/nrfconnect/CMakeLists.txt b/examples/lighting-app/nrfconnect/CMakeLists.txt index 4ef71fea088ba9..110e163a29657b 100644 --- a/examples/lighting-app/nrfconnect/CMakeLists.txt +++ b/examples/lighting-app/nrfconnect/CMakeLists.txt @@ -62,7 +62,7 @@ target_sources(app PRIVATE ${GEN_DIR}/lighting-app/zap-generated/IMClusterCommandHandler.cpp ${NRFCONNECT_COMMON}/util/LEDWidget.cpp ${NRFCONNECT_COMMON}/util/PWMDevice.cpp - ${NRFCONNECT_COMMON}/util/ThreadUtil.cpp) + $<$:${NRFCONNECT_COMMON}/util/ThreadUtil.cpp>) chip_configure_data_model(app INCLUDE_SERVER diff --git a/examples/lighting-app/nrfconnect/main/AppTask.cpp b/examples/lighting-app/nrfconnect/main/AppTask.cpp index a2cb35de24fadb..5670cc55f3a0d1 100644 --- a/examples/lighting-app/nrfconnect/main/AppTask.cpp +++ b/examples/lighting-app/nrfconnect/main/AppTask.cpp @@ -22,7 +22,9 @@ #include "AppEvent.h" #include "LEDWidget.h" #include "PWMDevice.h" +#ifdef CONFIG_NET_L2_OPENTHREAD #include "ThreadUtil.h" +#endif #include #include @@ -113,6 +115,7 @@ CHIP_ERROR AppTask::Init() return err; } +#if defined(CONFIG_NET_L2_OPENTHREAD) err = ThreadStackMgr().InitThreadStack(); if (err != CHIP_NO_ERROR) { @@ -127,6 +130,9 @@ CHIP_ERROR AppTask::Init() LOG_ERR("ConnectivityMgr().SetThreadDeviceType() failed"); return err; } +#elif !defined(CONFIG_WIFI_NRF700X) + return CHIP_ERROR_INTERNAL; +#endif // Initialize LEDs LEDWidget::InitGpio(); @@ -270,6 +276,7 @@ void AppTask::ButtonEventHandler(uint32_t button_state, uint32_t has_changed) sAppTask.PostEvent(&button_event); } +#ifdef CONFIG_NET_L2_OPENTHREAD if (THREAD_START_BUTTON_MASK & button_state & has_changed) { button_event.ButtonEvent.PinNo = THREAD_START_BUTTON; @@ -277,6 +284,7 @@ void AppTask::ButtonEventHandler(uint32_t button_state, uint32_t has_changed) button_event.Handler = StartThreadHandler; sAppTask.PostEvent(&button_event); } +#endif if (BLE_ADVERTISEMENT_START_BUTTON_MASK & button_state & has_changed) { @@ -399,6 +407,7 @@ void AppTask::FunctionHandler(AppEvent * aEvent) } } +#ifdef CONFIG_NET_L2_OPENTHREAD void AppTask::StartThreadHandler(AppEvent * aEvent) { if (aEvent->ButtonEvent.PinNo != THREAD_START_BUTTON) @@ -414,6 +423,7 @@ void AppTask::StartThreadHandler(AppEvent * aEvent) LOG_INF("Device is commissioned to a Thread network."); } } +#endif void AppTask::StartBLEAdvertisementHandler(AppEvent *) { diff --git a/examples/lighting-app/nrfconnect/main/include/AppTask.h b/examples/lighting-app/nrfconnect/main/include/AppTask.h index 3c76f131f632fc..e2b9fea9ebdb65 100644 --- a/examples/lighting-app/nrfconnect/main/include/AppTask.h +++ b/examples/lighting-app/nrfconnect/main/include/AppTask.h @@ -74,7 +74,9 @@ class AppTask static void UpdateLedStateEventHandler(AppEvent * aEvent); static void FunctionTimerEventHandler(AppEvent * aEvent); static void FunctionHandler(AppEvent * aEvent); +#ifdef CONFIG_NET_L2_OPENTHREAD static void StartThreadHandler(AppEvent * aEvent); +#endif static void LightingActionEventHandler(AppEvent * aEvent); static void StartBLEAdvertisementHandler(AppEvent * aEvent); diff --git a/examples/lighting-app/nrfconnect/prj.conf b/examples/lighting-app/nrfconnect/prj.conf index 3ed8923012d0bf..4bbb8a5a2a7076 100644 --- a/examples/lighting-app/nrfconnect/prj.conf +++ b/examples/lighting-app/nrfconnect/prj.conf @@ -28,12 +28,6 @@ CONFIG_PWM=y # OpenThread configs CONFIG_OPENTHREAD_NORDIC_LIBRARY_FTD=y -# Default OpenThread network settings -CONFIG_OPENTHREAD_PANID=4660 -CONFIG_OPENTHREAD_CHANNEL=15 -CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread" -CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" - # Bluetooth overrides CONFIG_BT_DEVICE_NAME="MatterLight" diff --git a/examples/lighting-app/nrfconnect/prj_no_dfu.conf b/examples/lighting-app/nrfconnect/prj_no_dfu.conf index 306b2de46dc463..0e286be102e3fc 100644 --- a/examples/lighting-app/nrfconnect/prj_no_dfu.conf +++ b/examples/lighting-app/nrfconnect/prj_no_dfu.conf @@ -28,12 +28,6 @@ CONFIG_PWM=y # OpenThread configs CONFIG_OPENTHREAD_NORDIC_LIBRARY_FTD=y -# Default OpenThread network settings -CONFIG_OPENTHREAD_PANID=4660 -CONFIG_OPENTHREAD_CHANNEL=15 -CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread" -CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" - # Bluetooth overrides CONFIG_BT_DEVICE_NAME="MatterLight" diff --git a/examples/lighting-app/nrfconnect/prj_release.conf b/examples/lighting-app/nrfconnect/prj_release.conf index 107bc57ee258bc..d5302def6aa3bd 100644 --- a/examples/lighting-app/nrfconnect/prj_release.conf +++ b/examples/lighting-app/nrfconnect/prj_release.conf @@ -28,12 +28,6 @@ CONFIG_PWM=y # OpenThread configs CONFIG_OPENTHREAD_NORDIC_LIBRARY_FTD=y -# Default OpenThread network settings -CONFIG_OPENTHREAD_PANID=4660 -CONFIG_OPENTHREAD_CHANNEL=15 -CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread" -CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" - # Bluetooth overrides CONFIG_BT_DEVICE_NAME="MatterLight" diff --git a/examples/lock-app/nrfconnect/CMakeLists.txt b/examples/lock-app/nrfconnect/CMakeLists.txt index 567ca8ea075188..0eb2f3e88c86a0 100644 --- a/examples/lock-app/nrfconnect/CMakeLists.txt +++ b/examples/lock-app/nrfconnect/CMakeLists.txt @@ -59,7 +59,7 @@ target_sources(app PRIVATE ${GEN_DIR}/lock-app/zap-generated/callback-stub.cpp ${GEN_DIR}/lock-app/zap-generated/IMClusterCommandHandler.cpp ${NRFCONNECT_COMMON}/util/LEDWidget.cpp - ${NRFCONNECT_COMMON}/util/ThreadUtil.cpp) + $<$:${NRFCONNECT_COMMON}/util/ThreadUtil.cpp>) chip_configure_data_model(app INCLUDE_SERVER diff --git a/examples/lock-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/lock-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay index 330f40f03f8f29..09dd9064767019 100644 --- a/examples/lock-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/examples/lock-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -69,9 +69,6 @@ &adc { status = "disabled"; }; -&gpio1 { - status = "disabled"; -}; &i2c1 { status = "disabled"; }; diff --git a/examples/lock-app/nrfconnect/main/AppTask.cpp b/examples/lock-app/nrfconnect/main/AppTask.cpp index ff6cb1f6a7850d..6a083f7d31fc3e 100644 --- a/examples/lock-app/nrfconnect/main/AppTask.cpp +++ b/examples/lock-app/nrfconnect/main/AppTask.cpp @@ -20,7 +20,9 @@ #include "AppConfig.h" #include "BoltLockManager.h" #include "LEDWidget.h" +#ifdef CONFIG_NET_L2_OPENTHREAD #include "ThreadUtil.h" +#endif #include #include @@ -104,6 +106,7 @@ CHIP_ERROR AppTask::Init() return err; } +#if defined(CONFIG_NET_L2_OPENTHREAD) err = ThreadStackMgr().InitThreadStack(); if (err != CHIP_NO_ERROR) { @@ -121,6 +124,9 @@ CHIP_ERROR AppTask::Init() LOG_ERR("ConnectivityMgr().SetThreadDeviceType() failed"); return err; } +#else + return CHIP_ERROR_INTERNAL; +#endif // Initialize LEDs LEDWidget::InitGpio(); @@ -249,6 +255,7 @@ void AppTask::ButtonEventHandler(uint32_t button_state, uint32_t has_changed) sAppTask.PostEvent(&button_event); } +#ifdef CONFIG_NET_L2_OPENTHREAD if (THREAD_START_BUTTON_MASK & button_state & has_changed) { button_event.ButtonEvent.PinNo = THREAD_START_BUTTON; @@ -256,6 +263,7 @@ void AppTask::ButtonEventHandler(uint32_t button_state, uint32_t has_changed) button_event.Handler = StartThreadHandler; sAppTask.PostEvent(&button_event); } +#endif if (BLE_ADVERTISEMENT_START_BUTTON_MASK & button_state & has_changed) { @@ -373,6 +381,7 @@ void AppTask::FunctionHandler(AppEvent * aEvent) } } +#ifdef CONFIG_NET_L2_OPENTHREAD void AppTask::StartThreadHandler(AppEvent * aEvent) { if (aEvent->ButtonEvent.PinNo != THREAD_START_BUTTON) @@ -388,6 +397,7 @@ void AppTask::StartThreadHandler(AppEvent * aEvent) LOG_INF("Device is commissioned to a Thread network."); } } +#endif void AppTask::StartBLEAdvertisementHandler(AppEvent *) { diff --git a/examples/lock-app/nrfconnect/main/include/AppTask.h b/examples/lock-app/nrfconnect/main/include/AppTask.h index 8e57d8c166ca7f..9c7dafe79b6ea4 100644 --- a/examples/lock-app/nrfconnect/main/include/AppTask.h +++ b/examples/lock-app/nrfconnect/main/include/AppTask.h @@ -59,7 +59,9 @@ class AppTask static void UpdateLedStateEventHandler(AppEvent * aEvent); static void FunctionTimerEventHandler(AppEvent * aEvent); static void FunctionHandler(AppEvent * aEvent); +#ifdef CONFIG_NET_L2_OPENTHREAD static void StartThreadHandler(AppEvent * aEvent); +#endif static void LockActionEventHandler(AppEvent * aEvent); static void StartBLEAdvertisementHandler(AppEvent * aEvent); diff --git a/examples/lock-app/nrfconnect/prj.conf b/examples/lock-app/nrfconnect/prj.conf index 1f0e9486749356..e6d757137db86a 100644 --- a/examples/lock-app/nrfconnect/prj.conf +++ b/examples/lock-app/nrfconnect/prj.conf @@ -30,12 +30,6 @@ CONFIG_OPENTHREAD_MTD=y CONFIG_OPENTHREAD_FTD=n CONFIG_CHIP_ENABLE_SLEEPY_END_DEVICE_SUPPORT=y -# Default OpenThread network settings -CONFIG_OPENTHREAD_PANID=4660 -CONFIG_OPENTHREAD_CHANNEL=15 -CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread" -CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" - # Bluetooth overrides CONFIG_BT_DEVICE_NAME="MatterLock" diff --git a/examples/lock-app/nrfconnect/prj_no_dfu.conf b/examples/lock-app/nrfconnect/prj_no_dfu.conf index 1f12e983ffc10d..9b0339d336b4e1 100644 --- a/examples/lock-app/nrfconnect/prj_no_dfu.conf +++ b/examples/lock-app/nrfconnect/prj_no_dfu.conf @@ -30,12 +30,6 @@ CONFIG_OPENTHREAD_MTD=y CONFIG_OPENTHREAD_FTD=n CONFIG_CHIP_ENABLE_SLEEPY_END_DEVICE_SUPPORT=y -# Default OpenThread network settings -CONFIG_OPENTHREAD_PANID=4660 -CONFIG_OPENTHREAD_CHANNEL=15 -CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread" -CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" - # Bluetooth overrides CONFIG_BT_DEVICE_NAME="MatterLock" diff --git a/examples/lock-app/nrfconnect/prj_release.conf b/examples/lock-app/nrfconnect/prj_release.conf index 7a87388e0112de..a71e97536cfd6c 100644 --- a/examples/lock-app/nrfconnect/prj_release.conf +++ b/examples/lock-app/nrfconnect/prj_release.conf @@ -30,12 +30,6 @@ CONFIG_OPENTHREAD_MTD=y CONFIG_OPENTHREAD_FTD=n CONFIG_CHIP_ENABLE_SLEEPY_END_DEVICE_SUPPORT=y -# Default OpenThread network settings -CONFIG_OPENTHREAD_PANID=4660 -CONFIG_OPENTHREAD_CHANNEL=15 -CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread" -CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" - # Bluetooth overrides CONFIG_BT_DEVICE_NAME="MatterLock" diff --git a/examples/pump-app/nrfconnect/CMakeLists.txt b/examples/pump-app/nrfconnect/CMakeLists.txt index 760569a05d5b72..72df94daa42bfb 100644 --- a/examples/pump-app/nrfconnect/CMakeLists.txt +++ b/examples/pump-app/nrfconnect/CMakeLists.txt @@ -59,7 +59,7 @@ target_sources(app PRIVATE ${GEN_DIR}/pump-app/zap-generated/callback-stub.cpp ${GEN_DIR}/pump-app/zap-generated/IMClusterCommandHandler.cpp ${NRFCONNECT_COMMON}/util/LEDWidget.cpp - ${NRFCONNECT_COMMON}/util/ThreadUtil.cpp) + $<$:${NRFCONNECT_COMMON}/util/ThreadUtil.cpp>) chip_configure_data_model(app INCLUDE_SERVER diff --git a/examples/pump-app/nrfconnect/main/AppTask.cpp b/examples/pump-app/nrfconnect/main/AppTask.cpp index 887c0a16931188..3d12826be956f0 100644 --- a/examples/pump-app/nrfconnect/main/AppTask.cpp +++ b/examples/pump-app/nrfconnect/main/AppTask.cpp @@ -105,6 +105,7 @@ CHIP_ERROR AppTask::Init() return err; } +#if defined(CONFIG_NET_L2_OPENTHREAD) err = ThreadStackMgr().InitThreadStack(); if (err != CHIP_NO_ERROR) { @@ -118,6 +119,9 @@ CHIP_ERROR AppTask::Init() LOG_ERR("ConnectivityMgr().SetThreadDeviceType() failed"); return err; } +#elif !defined(CONFIG_WIFI_NRF700X) + return CHIP_ERROR_INTERNAL; +#endif // Initialize LEDs LEDWidget::InitGpio(); diff --git a/examples/pump-app/nrfconnect/main/include/AppTask.h b/examples/pump-app/nrfconnect/main/include/AppTask.h index 25545ee9507f54..ce8ba48d50057c 100644 --- a/examples/pump-app/nrfconnect/main/include/AppTask.h +++ b/examples/pump-app/nrfconnect/main/include/AppTask.h @@ -61,7 +61,9 @@ class AppTask static void UpdateLedStateEventHandler(AppEvent * aEvent); static void FunctionTimerEventHandler(AppEvent * aEvent); static void FunctionHandler(AppEvent * aEvent); +#ifdef CONFIG_NET_L2_OPENTHREAD static void StartThreadHandler(AppEvent * aEvent); +#endif static void StartActionEventHandler(AppEvent * aEvent); static void StartBLEAdvertisementHandler(AppEvent * aEvent); diff --git a/examples/pump-app/nrfconnect/prj_no_dfu.conf b/examples/pump-app/nrfconnect/prj_no_dfu.conf index 42f2b343331368..8c102a90dc41d4 100644 --- a/examples/pump-app/nrfconnect/prj_no_dfu.conf +++ b/examples/pump-app/nrfconnect/prj_no_dfu.conf @@ -29,12 +29,6 @@ CONFIG_OPENTHREAD_NORDIC_LIBRARY_MTD=y CONFIG_OPENTHREAD_MTD=y CONFIG_OPENTHREAD_FTD=n -# Default OpenThread network settings -CONFIG_OPENTHREAD_PANID=4660 -CONFIG_OPENTHREAD_CHANNEL=15 -CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread" -CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" - # Bluetooth overrides CONFIG_BT_DEVICE_NAME="MatterPump" diff --git a/examples/pump-app/nrfconnect/prj_release.conf b/examples/pump-app/nrfconnect/prj_release.conf index 14411f310dbbd6..01c70c0217c02e 100644 --- a/examples/pump-app/nrfconnect/prj_release.conf +++ b/examples/pump-app/nrfconnect/prj_release.conf @@ -29,12 +29,6 @@ CONFIG_OPENTHREAD_NORDIC_LIBRARY_MTD=y CONFIG_OPENTHREAD_MTD=y CONFIG_OPENTHREAD_FTD=n -# Default OpenThread network settings -CONFIG_OPENTHREAD_PANID=4660 -CONFIG_OPENTHREAD_CHANNEL=15 -CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread" -CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" - # Bluetooth overrides CONFIG_BT_DEVICE_NAME="MatterPump" diff --git a/examples/pump-controller-app/nrfconnect/CMakeLists.txt b/examples/pump-controller-app/nrfconnect/CMakeLists.txt index 4426954b3ef6a7..1bc468bec12125 100644 --- a/examples/pump-controller-app/nrfconnect/CMakeLists.txt +++ b/examples/pump-controller-app/nrfconnect/CMakeLists.txt @@ -59,7 +59,7 @@ target_sources(app PRIVATE ${GEN_DIR}/pump-controller-app/zap-generated/callback-stub.cpp ${GEN_DIR}/pump-controller-app/zap-generated/IMClusterCommandHandler.cpp ${NRFCONNECT_COMMON}/util/LEDWidget.cpp - ${NRFCONNECT_COMMON}/util/ThreadUtil.cpp) + $<$:${NRFCONNECT_COMMON}/util/ThreadUtil.cpp>) chip_configure_data_model(app INCLUDE_SERVER diff --git a/examples/pump-controller-app/nrfconnect/main/AppTask.cpp b/examples/pump-controller-app/nrfconnect/main/AppTask.cpp index 898ffcc0892a1b..8c51f4dbc47939 100644 --- a/examples/pump-controller-app/nrfconnect/main/AppTask.cpp +++ b/examples/pump-controller-app/nrfconnect/main/AppTask.cpp @@ -20,7 +20,9 @@ #include "AppConfig.h" #include "LEDWidget.h" #include "PumpManager.h" +#ifdef CONFIG_NET_L2_OPENTHREAD #include "ThreadUtil.h" +#endif #include #include @@ -102,6 +104,7 @@ CHIP_ERROR AppTask::Init() return err; } +#if defined(CONFIG_NET_L2_OPENTHREAD) err = ThreadStackMgr().InitThreadStack(); if (err != CHIP_NO_ERROR) { @@ -115,6 +118,9 @@ CHIP_ERROR AppTask::Init() LOG_ERR("ConnectivityMgr().SetThreadDeviceType() failed"); return err; } +#elif !defined(CONFIG_WIFI_NRF700X) + return CHIP_ERROR_INTERNAL; +#endif // Initialize LEDs LEDWidget::InitGpio(); @@ -249,6 +255,7 @@ void AppTask::ButtonEventHandler(uint32_t button_state, uint32_t has_changed) sAppTask.PostEvent(&button_event); } +#ifdef CONFIG_NET_L2_OPENTHREAD if (THREAD_START_BUTTON_MASK & button_state & has_changed) { button_event.ButtonEvent.PinNo = THREAD_START_BUTTON; @@ -256,6 +263,7 @@ void AppTask::ButtonEventHandler(uint32_t button_state, uint32_t has_changed) button_event.Handler = StartThreadHandler; sAppTask.PostEvent(&button_event); } +#endif if (BLE_ADVERTISEMENT_START_BUTTON_MASK & button_state & has_changed) { @@ -371,6 +379,7 @@ void AppTask::FunctionHandler(AppEvent * aEvent) } } +#ifdef CONFIG_NET_L2_OPENTHREAD void AppTask::StartThreadHandler(AppEvent * aEvent) { if (aEvent->ButtonEvent.PinNo != THREAD_START_BUTTON) @@ -386,6 +395,7 @@ void AppTask::StartThreadHandler(AppEvent * aEvent) LOG_INF("Device is commissioned to a Thread network."); } } +#endif void AppTask::StartBLEAdvertisementHandler(AppEvent *) { diff --git a/examples/pump-controller-app/nrfconnect/main/include/AppTask.h b/examples/pump-controller-app/nrfconnect/main/include/AppTask.h index 25545ee9507f54..ce8ba48d50057c 100644 --- a/examples/pump-controller-app/nrfconnect/main/include/AppTask.h +++ b/examples/pump-controller-app/nrfconnect/main/include/AppTask.h @@ -61,7 +61,9 @@ class AppTask static void UpdateLedStateEventHandler(AppEvent * aEvent); static void FunctionTimerEventHandler(AppEvent * aEvent); static void FunctionHandler(AppEvent * aEvent); +#ifdef CONFIG_NET_L2_OPENTHREAD static void StartThreadHandler(AppEvent * aEvent); +#endif static void StartActionEventHandler(AppEvent * aEvent); static void StartBLEAdvertisementHandler(AppEvent * aEvent); diff --git a/examples/pump-controller-app/nrfconnect/prj_no_dfu.conf b/examples/pump-controller-app/nrfconnect/prj_no_dfu.conf index 41caec932ada47..f946af99d95204 100644 --- a/examples/pump-controller-app/nrfconnect/prj_no_dfu.conf +++ b/examples/pump-controller-app/nrfconnect/prj_no_dfu.conf @@ -29,12 +29,6 @@ CONFIG_OPENTHREAD_NORDIC_LIBRARY_MTD=y CONFIG_OPENTHREAD_MTD=y CONFIG_OPENTHREAD_FTD=n -# Default OpenThread network settings -CONFIG_OPENTHREAD_PANID=4660 -CONFIG_OPENTHREAD_CHANNEL=15 -CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread" -CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" - # Bluetooth overrides CONFIG_BT_DEVICE_NAME="MatterPumpCtrl" diff --git a/examples/pump-controller-app/nrfconnect/prj_release.conf b/examples/pump-controller-app/nrfconnect/prj_release.conf index e816f9c097442f..bf7f1a452896de 100644 --- a/examples/pump-controller-app/nrfconnect/prj_release.conf +++ b/examples/pump-controller-app/nrfconnect/prj_release.conf @@ -29,12 +29,6 @@ CONFIG_OPENTHREAD_NORDIC_LIBRARY_MTD=y CONFIG_OPENTHREAD_MTD=y CONFIG_OPENTHREAD_FTD=n -# Default OpenThread network settings -CONFIG_OPENTHREAD_PANID=4660 -CONFIG_OPENTHREAD_CHANNEL=15 -CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread" -CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" - # Bluetooth overrides CONFIG_BT_DEVICE_NAME="MatterPumpCtrl" diff --git a/examples/window-app/nrfconnect/CMakeLists.txt b/examples/window-app/nrfconnect/CMakeLists.txt index 038b7485d8b4ab..329bb0c39b3f91 100644 --- a/examples/window-app/nrfconnect/CMakeLists.txt +++ b/examples/window-app/nrfconnect/CMakeLists.txt @@ -62,7 +62,7 @@ target_sources(app PRIVATE ${GEN_DIR}/window-app/zap-generated/IMClusterCommandHandler.cpp ${NRFCONNECT_COMMON}/util/LEDWidget.cpp ${NRFCONNECT_COMMON}/util/PWMDevice.cpp - ${NRFCONNECT_COMMON}/util/ThreadUtil.cpp) + $<$:${NRFCONNECT_COMMON}/util/ThreadUtil.cpp>) chip_configure_data_model(app INCLUDE_SERVER diff --git a/examples/window-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/window-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay index 4b450586a3baa5..bfa3462724d40e 100644 --- a/examples/window-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/examples/window-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -88,9 +88,6 @@ &adc { status = "disabled"; }; -&gpio1 { - status = "disabled"; -}; &i2c1 { status = "disabled"; }; diff --git a/examples/window-app/nrfconnect/main/AppTask.cpp b/examples/window-app/nrfconnect/main/AppTask.cpp index 65b6b3f6857212..8a6fb07fda6175 100644 --- a/examples/window-app/nrfconnect/main/AppTask.cpp +++ b/examples/window-app/nrfconnect/main/AppTask.cpp @@ -105,6 +105,7 @@ CHIP_ERROR AppTask::Init() return err; } +#if defined(CONFIG_NET_L2_OPENTHREAD) err = ThreadStackMgr().InitThreadStack(); if (err != CHIP_NO_ERROR) { @@ -125,6 +126,9 @@ CHIP_ERROR AppTask::Init() LOG_ERR("ConnectivityMgr().SetThreadDeviceType() failed"); return err; } +#elif !defined(CONFIG_WIFI_NRF700X) + return CHIP_ERROR_INTERNAL; +#endif // Initialize LEDs LEDWidget::InitGpio(); diff --git a/examples/window-app/nrfconnect/prj.conf b/examples/window-app/nrfconnect/prj.conf index 13b2d97966ad84..bb8601bf9c5dbf 100644 --- a/examples/window-app/nrfconnect/prj.conf +++ b/examples/window-app/nrfconnect/prj.conf @@ -34,12 +34,6 @@ CONFIG_CHIP_THREAD_SSED=y CONFIG_CHIP_SED_IDLE_INTERVAL=500 CONFIG_CHIP_SED_ACTIVE_INTERVAL=500 -# Default OpenThread network settings -CONFIG_OPENTHREAD_PANID=4660 -CONFIG_OPENTHREAD_CHANNEL=15 -CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread" -CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" - # Bluetooth overrides CONFIG_BT_DEVICE_NAME="MatterWinCov" diff --git a/examples/window-app/nrfconnect/prj_no_dfu.conf b/examples/window-app/nrfconnect/prj_no_dfu.conf index 8f5d7b9aa6c946..f2787a7619fe73 100644 --- a/examples/window-app/nrfconnect/prj_no_dfu.conf +++ b/examples/window-app/nrfconnect/prj_no_dfu.conf @@ -23,6 +23,7 @@ CONFIG_STD_CPP14=y # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y +CONFIG_PWM=y # OpenThread configs CONFIG_OPENTHREAD_NORDIC_LIBRARY_MTD=y @@ -33,12 +34,6 @@ CONFIG_CHIP_THREAD_SSED=y CONFIG_CHIP_SED_IDLE_INTERVAL=500 CONFIG_CHIP_SED_ACTIVE_INTERVAL=500 -# Default OpenThread network settings -CONFIG_OPENTHREAD_PANID=4660 -CONFIG_OPENTHREAD_CHANNEL=15 -CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread" -CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" - # Bluetooth overrides CONFIG_BT_DEVICE_NAME="MatterWinCov" diff --git a/examples/window-app/nrfconnect/prj_release.conf b/examples/window-app/nrfconnect/prj_release.conf index 05feca0b601e74..caf0ee1a5be1e9 100644 --- a/examples/window-app/nrfconnect/prj_release.conf +++ b/examples/window-app/nrfconnect/prj_release.conf @@ -23,6 +23,7 @@ CONFIG_STD_CPP14=y # Add support for LEDs and buttons on Nordic development kits CONFIG_DK_LIBRARY=y +CONFIG_PWM=y # OpenThread configs CONFIG_OPENTHREAD_NORDIC_LIBRARY_MTD=y @@ -33,12 +34,6 @@ CONFIG_CHIP_THREAD_SSED=y CONFIG_CHIP_SED_IDLE_INTERVAL=500 CONFIG_CHIP_SED_ACTIVE_INTERVAL=500 -# Default OpenThread network settings -CONFIG_OPENTHREAD_PANID=4660 -CONFIG_OPENTHREAD_CHANNEL=15 -CONFIG_OPENTHREAD_NETWORK_NAME="OpenThread" -CONFIG_OPENTHREAD_XPANID="11:11:11:11:22:22:22:22" - # Bluetooth overrides CONFIG_BT_DEVICE_NAME="MatterWinCov" diff --git a/src/include/platform/internal/GenericConnectivityManagerImpl.h b/src/include/platform/internal/GenericConnectivityManagerImpl.h index 6315c25a701b51..a56e92d17d0d8d 100644 --- a/src/include/platform/internal/GenericConnectivityManagerImpl.h +++ b/src/include/platform/internal/GenericConnectivityManagerImpl.h @@ -33,7 +33,7 @@ namespace Internal { * * This template contains implementations of select features from the ConnectivityManager abstract * interface that are suitable for use on all platforms. It is intended to be inherited (directly - * or indirectly) by the ConfigurationManagerImpl class, which also appears as the template's ImplClass + * or indirectly) by the ConnectivityManagerImpl class, which also appears as the template's ImplClass * parameter. */ template diff --git a/src/inet/InetConfig.h b/src/inet/InetConfig.h index d209328fde87a5..0631a7e14f77da 100644 --- a/src/inet/InetConfig.h +++ b/src/inet/InetConfig.h @@ -250,4 +250,26 @@ #ifndef INET_CONFIG_IP_MULTICAST_HOP_LIMIT #define INET_CONFIG_IP_MULTICAST_HOP_LIMIT (64) #endif // INET_CONFIG_IP_MULTICAST_HOP_LIMIT + +/** + * @def INET_CONFIG_UDP_SOCKET_PKTINFO + * + * @brief + * Use IP_PKTINFO and IPV6_PKTINFO control messages to specify the network + * interface and the source address of a sent UDP packet. + * + * @details + * When this flag is set, the socket-based implementation of UDP endpoints + * requires that IP_PKTINFO and IPV6_PKTINFO be supported. Otherwise, it is + * left to the operating system to select the network interface and the + * source address. + */ +#ifndef INET_CONFIG_UDP_SOCKET_PKTINFO +#ifndef __ZEPHYR__ +#define INET_CONFIG_UDP_SOCKET_PKTINFO 1 +#else +#define INET_CONFIG_UDP_SOCKET_PKTINFO 0 +#endif +#endif // INET_CONFIG_UDP_SOCKET_PKTINFO + // clang-format on diff --git a/src/inet/UDPEndPointImplSockets.cpp b/src/inet/UDPEndPointImplSockets.cpp index a9e078cc5f48fd..e2985a07a67547 100644 --- a/src/inet/UDPEndPointImplSockets.cpp +++ b/src/inet/UDPEndPointImplSockets.cpp @@ -61,7 +61,7 @@ #define INET_IPV6_ADD_MEMBERSHIP IPV6_ADD_MEMBERSHIP #elif defined(IPV6_JOIN_GROUP) #define INET_IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP -#elif !__ZEPHYR__ +#elif !CHIP_SYSTEM_CONFIG_USE_PLATFORM_MULTICAST_API #error \ "Neither IPV6_ADD_MEMBERSHIP nor IPV6_JOIN_GROUP are defined which are required for generalized IPv6 multicast group support." #endif // IPV6_ADD_MEMBERSHIP @@ -70,7 +70,7 @@ #define INET_IPV6_DROP_MEMBERSHIP IPV6_DROP_MEMBERSHIP #elif defined(IPV6_LEAVE_GROUP) #define INET_IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP -#elif !__ZEPHYR__ +#elif !CHIP_SYSTEM_CONFIG_USE_PLATFORM_MULTICAST_API #error \ "Neither IPV6_DROP_MEMBERSHIP nor IPV6_LEAVE_GROUP are defined which are required for generalized IPv6 multicast group support." #endif // IPV6_DROP_MEMBERSHIP @@ -329,6 +329,7 @@ CHIP_ERROR UDPEndPointImplSockets::SendMsgImpl(const IPPacketInfo * aPktInfo, Sy intf = mBoundIntfId; } +#if INET_CONFIG_UDP_SOCKET_PKTINFO // If the packet should be sent over a specific interface, or with a specific source // address, construct an IP_PKTINFO/IPV6_PKTINFO "control message" to that effect // add add it to the message header. If the local OS doesn't support IP_PKTINFO/IPV6_PKTINFO @@ -393,6 +394,7 @@ CHIP_ERROR UDPEndPointImplSockets::SendMsgImpl(const IPPacketInfo * aPktInfo, Sy return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; #endif // !(defined(IP_PKTINFO) && defined(IPV6_PKTINFO)) } +#endif // INET_CONFIG_UDP_SOCKET_PKTINFO // Send IP packet. const ssize_t lenSent = sendmsg(mSocket, &msgHeader, 0); @@ -557,7 +559,8 @@ void UDPEndPointImplSockets::HandlePendingIO(System::SocketEvents events) System::PacketBufferHandle lBuffer; lPacketInfo.Clear(); - lPacketInfo.DestPort = mBoundPort; + lPacketInfo.DestPort = mBoundPort; + lPacketInfo.Interface = mBoundIntfId; lBuffer = System::PacketBufferHandle::New(System::PacketBuffer::kMaxSizeWithoutReserve, 0); diff --git a/src/platform/Zephyr/BUILD.gn b/src/platform/Zephyr/BUILD.gn index c4f2820b4da8df..f57307e1db7eed 100644 --- a/src/platform/Zephyr/BUILD.gn +++ b/src/platform/Zephyr/BUILD.gn @@ -39,6 +39,8 @@ static_library("Zephyr") { "DiagnosticDataProviderImpl.cpp", "DiagnosticDataProviderImpl.h", "InetPlatformConfig.h", + "InetUtils.cpp", + "InetUtils.h", "KeyValueStoreManagerImpl.cpp", "KeyValueStoreManagerImpl.h", "Logging.cpp", diff --git a/src/platform/Zephyr/ConfigurationManagerImpl.cpp b/src/platform/Zephyr/ConfigurationManagerImpl.cpp index bd19057e65d3bf..fb5f7b3153f003 100644 --- a/src/platform/Zephyr/ConfigurationManagerImpl.cpp +++ b/src/platform/Zephyr/ConfigurationManagerImpl.cpp @@ -27,8 +27,11 @@ #include #include + #include +#include "InetUtils.h" + #include #include @@ -180,6 +183,21 @@ void ConfigurationManagerImpl::DoFactoryReset(intptr_t arg) PlatformMgr().Shutdown(); } +CHIP_ERROR ConfigurationManagerImpl::GetPrimaryWiFiMACAddress(uint8_t * buf) +{ +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI + const net_if * const iface = InetUtils::GetInterface(); + VerifyOrReturnError(iface != nullptr && iface->if_dev != nullptr, CHIP_ERROR_INTERNAL); + + const auto linkAddrStruct = iface->if_dev->link_addr; + memcpy(buf, linkAddrStruct.addr, linkAddrStruct.len); + + return CHIP_NO_ERROR; +#else + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +#endif +} + ConfigurationManager & ConfigurationMgrImpl() { return ConfigurationManagerImpl::GetDefaultInstance(); diff --git a/src/platform/Zephyr/ConfigurationManagerImpl.h b/src/platform/Zephyr/ConfigurationManagerImpl.h index 166237fba32d81..87f9e30335b8fc 100644 --- a/src/platform/Zephyr/ConfigurationManagerImpl.h +++ b/src/platform/Zephyr/ConfigurationManagerImpl.h @@ -94,11 +94,6 @@ inline CHIP_ERROR ConfigurationManagerImpl::WritePersistedStorageValue(::chip::P return Internal::ZephyrConfig::WriteConfigValueCounter(key, value); } -inline CHIP_ERROR ConfigurationManagerImpl::GetPrimaryWiFiMACAddress(uint8_t * /* buf */) -{ - return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; -} - /** * Returns the platform-specific implementation of the ConfigurationManager object. * diff --git a/src/platform/Zephyr/DiagnosticDataProviderImpl.cpp b/src/platform/Zephyr/DiagnosticDataProviderImpl.cpp index 6aebf3d2c8a583..1366e1189ab53c 100644 --- a/src/platform/Zephyr/DiagnosticDataProviderImpl.cpp +++ b/src/platform/Zephyr/DiagnosticDataProviderImpl.cpp @@ -109,7 +109,7 @@ DiagnosticDataProviderImpl & DiagnosticDataProviderImpl::GetDefaultInstance() return sInstance; } -inline DiagnosticDataProviderImpl::DiagnosticDataProviderImpl() : mBootReason(DetermineBootReason()) +DiagnosticDataProviderImpl::DiagnosticDataProviderImpl() : mBootReason(DetermineBootReason()) { ChipLogDetail(DeviceLayer, "Boot reason: %u", static_cast(mBootReason)); } @@ -321,10 +321,5 @@ void DiagnosticDataProviderImpl::ReleaseNetworkInterfaces(NetworkInterface * net } } -DiagnosticDataProvider & GetDiagnosticDataProviderImpl() -{ - return DiagnosticDataProviderImpl::GetDefaultInstance(); -} - } // namespace DeviceLayer } // namespace chip diff --git a/src/platform/Zephyr/DiagnosticDataProviderImpl.h b/src/platform/Zephyr/DiagnosticDataProviderImpl.h index 2b46051d27b125..69bbae5bf04471 100644 --- a/src/platform/Zephyr/DiagnosticDataProviderImpl.h +++ b/src/platform/Zephyr/DiagnosticDataProviderImpl.h @@ -52,9 +52,10 @@ class DiagnosticDataProviderImpl : public DiagnosticDataProvider CHIP_ERROR GetNetworkInterfaces(NetworkInterface ** netifpp) override; void ReleaseNetworkInterfaces(NetworkInterface * netifp) override; -private: +protected: DiagnosticDataProviderImpl(); +private: const BootReasonType mBootReason; }; diff --git a/src/platform/Zephyr/DiagnosticDataProviderImplGetter.cpp b/src/platform/Zephyr/DiagnosticDataProviderImplGetter.cpp new file mode 100644 index 00000000000000..6b920d1661ffc3 --- /dev/null +++ b/src/platform/Zephyr/DiagnosticDataProviderImplGetter.cpp @@ -0,0 +1,29 @@ +/* + * + * Copyright (c) 2022 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. + */ + +#include "DiagnosticDataProviderImpl.h" + +namespace chip { +namespace DeviceLayer { + +DiagnosticDataProvider & GetDiagnosticDataProviderImpl() +{ + return DiagnosticDataProviderImpl::GetDefaultInstance(); +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/Zephyr/InetUtils.cpp b/src/platform/Zephyr/InetUtils.cpp new file mode 100644 index 00000000000000..1133acb89d8e8d --- /dev/null +++ b/src/platform/Zephyr/InetUtils.cpp @@ -0,0 +1,37 @@ +/* + * + * Copyright (c) 2022 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. + */ + +#include "InetUtils.h" + +namespace InetUtils { + +in6_addr ToZephyrAddr(const chip::Inet::IPAddress & address) +{ + in6_addr zephyrAddr; + + static_assert(sizeof(zephyrAddr.s6_addr) == sizeof(address.Addr), "Unexpected address size"); + memcpy(zephyrAddr.s6_addr, address.Addr, sizeof(address.Addr)); + + return zephyrAddr; +} + +net_if * GetInterface(chip::Inet::InterfaceId ifaceId) +{ + return ifaceId.IsPresent() ? net_if_get_by_index(ifaceId.GetPlatformInterface()) : net_if_get_default(); +} + +} // namespace InetUtils diff --git a/src/platform/Zephyr/InetUtils.h b/src/platform/Zephyr/InetUtils.h new file mode 100644 index 00000000000000..cb45f38c72ff3e --- /dev/null +++ b/src/platform/Zephyr/InetUtils.h @@ -0,0 +1,25 @@ +/* + * + * Copyright (c) 2022 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. + */ + +#include + +namespace InetUtils { + +in6_addr ToZephyrAddr(const chip::Inet::IPAddress & address); +net_if * GetInterface(chip::Inet::InterfaceId ifaceId = chip::Inet::InterfaceId::Null()); + +} // namespace InetUtils diff --git a/src/platform/nrfconnect/BUILD.gn b/src/platform/nrfconnect/BUILD.gn index 928c3c045b4725..0bb0babe605f94 100644 --- a/src/platform/nrfconnect/BUILD.gn +++ b/src/platform/nrfconnect/BUILD.gn @@ -26,6 +26,8 @@ static_library("nrfconnect") { "../Zephyr/ConfigurationManagerImpl.cpp", "../Zephyr/DiagnosticDataProviderImpl.cpp", "../Zephyr/DiagnosticDataProviderImpl.h", + "../Zephyr/InetUtils.cpp", + "../Zephyr/InetUtils.h", "../Zephyr/KeyValueStoreManagerImpl.cpp", "../Zephyr/Logging.cpp", "../Zephyr/PlatformManagerImpl.cpp", @@ -43,6 +45,8 @@ static_library("nrfconnect") { "ConnectivityManagerImpl.h", "DeviceNetworkProvisioningDelegateImpl.cpp", "DeviceNetworkProvisioningDelegateImpl.h", + "DiagnosticDataProviderImplNrf.cpp", + "DiagnosticDataProviderImplNrf.h", "InetPlatformConfig.h", "KeyValueStoreManagerImpl.h", "PlatformManagerImpl.h", @@ -79,6 +83,17 @@ static_library("nrfconnect") { } } + if (chip_enable_wifi) { + sources += [ + "wifi/ConnectivityManagerImplWiFi.cpp", + "wifi/ConnectivityManagerImplWiFi.h", + "wifi/NrfWiFiDriver.cpp", + "wifi/NrfWiFiDriver.h", + "wifi/WiFiManager.cpp", + "wifi/WiFiManager.h", + ] + } + if (chip_enable_nfc) { sources += [ "../Zephyr/NFCManagerImpl.cpp", diff --git a/src/platform/nrfconnect/CHIPDevicePlatformConfig.h b/src/platform/nrfconnect/CHIPDevicePlatformConfig.h index 087b06bdcabbc5..694de5b273d72d 100644 --- a/src/platform/nrfconnect/CHIPDevicePlatformConfig.h +++ b/src/platform/nrfconnect/CHIPDevicePlatformConfig.h @@ -87,10 +87,17 @@ #define CHIP_DEVICE_CONFIG_DEVICE_SOFTWARE_VERSION_STRING CONFIG_CHIP_DEVICE_SOFTWARE_VERSION_STRING #endif +#define CHIP_DEVICE_CONFIG_ENABLE_THREAD CONFIG_NET_L2_OPENTHREAD + +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI CONFIG_WIFI_NRF700X + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION 1 +#define CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP 0 +#else #define CHIP_DEVICE_CONFIG_ENABLE_WIFI_STATION 0 #define CHIP_DEVICE_CONFIG_ENABLE_WIFI_AP 0 - -#define CHIP_DEVICE_CONFIG_ENABLE_THREAD CONFIG_NET_L2_OPENTHREAD +#endif #define CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE CONFIG_BT diff --git a/src/platform/nrfconnect/ConnectivityManagerImpl.cpp b/src/platform/nrfconnect/ConnectivityManagerImpl.cpp index c5029f37a67862..555f65e8473031 100644 --- a/src/platform/nrfconnect/ConnectivityManagerImpl.cpp +++ b/src/platform/nrfconnect/ConnectivityManagerImpl.cpp @@ -51,7 +51,9 @@ CHIP_ERROR ConnectivityManagerImpl::_Init() #if CHIP_DEVICE_CONFIG_ENABLE_THREAD GenericConnectivityManagerImpl_Thread::_Init(); #endif - +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI + InitWiFi(); +#endif return CHIP_NO_ERROR; } diff --git a/src/platform/nrfconnect/ConnectivityManagerImpl.h b/src/platform/nrfconnect/ConnectivityManagerImpl.h index 4c003f23a4861a..8ea6c2d76b6561 100644 --- a/src/platform/nrfconnect/ConnectivityManagerImpl.h +++ b/src/platform/nrfconnect/ConnectivityManagerImpl.h @@ -28,12 +28,18 @@ #else #include #endif + #if CHIP_DEVICE_CONFIG_ENABLE_THREAD #include #else #include #endif + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI +#include "wifi/ConnectivityManagerImplWiFi.h" +#else #include +#endif #include @@ -65,7 +71,11 @@ class ConnectivityManagerImpl final : public ConnectivityManager, #else public Internal::GenericConnectivityManagerImpl_NoThread, #endif +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI + public ConnectivityManagerImplWiFi +#else public Internal::GenericConnectivityManagerImpl_NoWiFi +#endif { // Allow the ConnectivityManager interface class to delegate method calls to // the implementation methods provided by this class. @@ -100,7 +110,7 @@ inline ConnectivityManager & ConnectivityMgr(void) * Returns the platform-specific implementation of the ConnectivityManager singleton object. * * chip applications can use this to gain access to features of the ConnectivityManager - * that are specific to the ESP32 platform. + * that are specific to the nrfconnect platform. */ inline ConnectivityManagerImpl & ConnectivityMgrImpl(void) { diff --git a/src/platform/nrfconnect/DiagnosticDataProviderImplNrf.cpp b/src/platform/nrfconnect/DiagnosticDataProviderImplNrf.cpp new file mode 100644 index 00000000000000..5f7bc1a6702b4e --- /dev/null +++ b/src/platform/nrfconnect/DiagnosticDataProviderImplNrf.cpp @@ -0,0 +1,136 @@ +/* + * + * Copyright (c) 2022 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. + */ + +/** + * @file + * Provides an implementation of the DiagnosticDataProvider object + * for nrfconnect platform. + */ + +#include "DiagnosticDataProviderImplNrf.h" + +#ifdef CONFIG_WIFI_NRF700X +#include +#endif + +namespace chip { +namespace DeviceLayer { + +DiagnosticDataProvider & GetDiagnosticDataProviderImpl() +{ + return DiagnosticDataProviderImplNrf::GetDefaultInstance(); +} + +DiagnosticDataProviderImplNrf & DiagnosticDataProviderImplNrf::GetDefaultInstance() +{ + static DiagnosticDataProviderImplNrf sInstance; + return sInstance; +} + +#ifdef CONFIG_WIFI_NRF700X +CHIP_ERROR DiagnosticDataProviderImplNrf::GetWiFiBssId(ByteSpan & value) +{ + WiFiManager::WiFiInfo info; + CHIP_ERROR err = WiFiManager::Instance().GetWiFiInfo(info); + value = info.mBssId; + return err; +} + +CHIP_ERROR DiagnosticDataProviderImplNrf::GetWiFiSecurityType(uint8_t & securityType) +{ + WiFiManager::WiFiInfo info; + CHIP_ERROR err = WiFiManager::Instance().GetWiFiInfo(info); + securityType = info.mSecurityType; + return err; +} + +CHIP_ERROR DiagnosticDataProviderImplNrf::GetWiFiVersion(uint8_t & wiFiVersion) +{ + WiFiManager::WiFiInfo info; + CHIP_ERROR err = WiFiManager::Instance().GetWiFiInfo(info); + wiFiVersion = info.mWiFiVersion; + return err; +} + +CHIP_ERROR DiagnosticDataProviderImplNrf::GetWiFiChannelNumber(uint16_t & channelNumber) +{ + WiFiManager::WiFiInfo info; + CHIP_ERROR err = WiFiManager::Instance().GetWiFiInfo(info); + channelNumber = info.mChannel; + (void) err; + // above will return 0 until the wpa_supplicant driver API implementation is refined + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR DiagnosticDataProviderImplNrf::GetWiFiRssi(int8_t & rssi) +{ + WiFiManager::WiFiInfo info; + CHIP_ERROR err = WiFiManager::Instance().GetWiFiInfo(info); + rssi = info.mRssi; + (void) err; + // above will return -128 until the wpa_supplicant driver API implementation is refined + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +// below will be implemented when the WiFi driver exposes Zephyr NET_STATISTICS API +CHIP_ERROR DiagnosticDataProviderImplNrf::GetWiFiBeaconLostCount(uint32_t & beaconLostCount) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR DiagnosticDataProviderImplNrf::GetWiFiBeaconRxCount(uint32_t & beaconRxCount) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR DiagnosticDataProviderImplNrf::GetWiFiPacketMulticastRxCount(uint32_t & packetMulticastRxCount) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} +CHIP_ERROR DiagnosticDataProviderImplNrf::GetWiFiPacketMulticastTxCount(uint32_t & packetMulticastTxCount) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR DiagnosticDataProviderImplNrf::GetWiFiPacketUnicastRxCount(uint32_t & packetUnicastRxCount) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR DiagnosticDataProviderImplNrf::GetWiFiPacketUnicastTxCount(uint32_t & packetUnicastTxCount) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR DiagnosticDataProviderImplNrf::GetWiFiCurrentMaxRate(uint64_t & currentMaxRate) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR DiagnosticDataProviderImplNrf::GetWiFiOverrunCount(uint64_t & overrunCount) +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} + +CHIP_ERROR DiagnosticDataProviderImplNrf::ResetWiFiNetworkDiagnosticsCounts() +{ + return CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE; +} +#endif + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nrfconnect/DiagnosticDataProviderImplNrf.h b/src/platform/nrfconnect/DiagnosticDataProviderImplNrf.h new file mode 100644 index 00000000000000..3b770e627428e8 --- /dev/null +++ b/src/platform/nrfconnect/DiagnosticDataProviderImplNrf.h @@ -0,0 +1,60 @@ +/* + * + * Copyright (c) 2022 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. + */ + +/** + * @file + * Provides an implementation of the DiagnosticDataProvider object + * for nrfconnect platform. + */ + +#pragma once + +#include + +namespace chip { +namespace DeviceLayer { + +class DiagnosticDataProviderImplNrf : public DiagnosticDataProviderImpl +{ +public: +#ifdef CONFIG_WIFI_NRF700X + CHIP_ERROR GetWiFiBssId(ByteSpan & value) override; + CHIP_ERROR GetWiFiSecurityType(uint8_t & securityType) override; + CHIP_ERROR GetWiFiVersion(uint8_t & wiFiVersion) override; + CHIP_ERROR GetWiFiChannelNumber(uint16_t & channelNumber) override; + CHIP_ERROR GetWiFiRssi(int8_t & rssi) override; + CHIP_ERROR GetWiFiBeaconLostCount(uint32_t & beaconLostCount) override; + CHIP_ERROR GetWiFiBeaconRxCount(uint32_t & beaconRxCount) override; + CHIP_ERROR GetWiFiPacketMulticastRxCount(uint32_t & packetMulticastRxCount) override; + CHIP_ERROR GetWiFiPacketMulticastTxCount(uint32_t & packetMulticastTxCount) override; + CHIP_ERROR GetWiFiPacketUnicastRxCount(uint32_t & packetUnicastRxCount) override; + CHIP_ERROR GetWiFiPacketUnicastTxCount(uint32_t & packetUnicastTxCount) override; + CHIP_ERROR GetWiFiCurrentMaxRate(uint64_t & currentMaxRate) override; + CHIP_ERROR GetWiFiOverrunCount(uint64_t & overrunCount) override; + CHIP_ERROR ResetWiFiNetworkDiagnosticsCounts() override; +#endif + + static DiagnosticDataProviderImplNrf & GetDefaultInstance(); + +private: + DiagnosticDataProviderImplNrf() = default; +}; + +DiagnosticDataProvider & GetDiagnosticDataProviderImpl(); + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.cpp b/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.cpp new file mode 100644 index 00000000000000..6f925126c79f14 --- /dev/null +++ b/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.cpp @@ -0,0 +1,233 @@ +/* + * + * Copyright (c) 2022 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. + */ +/* this file behaves like a config.h, comes first */ +#include + +#include +#include + +#include +#include +#include +#include + +#include "ConnectivityManagerImplWiFi.h" +#include "WiFiManager.h" + +#if CHIP_DEVICE_CONFIG_ENABLE_WIFI + +using namespace ::chip; +using namespace ::chip::Inet; +using namespace ::chip::System; +using namespace ::chip::TLV; + +namespace chip { +namespace DeviceLayer { + +CHIP_ERROR ConnectivityManagerImplWiFi::InitWiFi() +{ + return WiFiManager::Instance().Init(); +} + +ConnectivityManager::WiFiStationMode ConnectivityManagerImplWiFi::_GetWiFiStationMode(void) +{ + if (mStationMode != ConnectivityManager::WiFiStationMode::kWiFiStationMode_ApplicationControlled) + { + mStationMode = (WiFiManager::StationStatus::DISABLED == WiFiManager().Instance().GetStationStatus()) + ? ConnectivityManager::WiFiStationMode::kWiFiStationMode_Disabled + : ConnectivityManager::WiFiStationMode::kWiFiStationMode_Enabled; + } + return mStationMode; +} + +CHIP_ERROR ConnectivityManagerImplWiFi::_SetWiFiStationMode(ConnectivityManager::WiFiStationMode aMode) +{ + VerifyOrReturnError(ConnectivityManager::WiFiStationMode::kWiFiStationMode_NotSupported != aMode, + CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE); + + if (aMode != mStationMode) + { + mStationMode = aMode; + if (mStationMode != ConnectivityManager::WiFiStationMode::kWiFiStationMode_ApplicationControlled) + { + bool doEnable{ ConnectivityManager::WiFiStationMode::kWiFiStationMode_Enabled == mStationMode }; + // TODO: when the connection/disconnection callback API is provided + // below calls should be used as a base of disconnect callback + if (doEnable) + { + OnStationConnected(); + } + else + { + OnStationDisconnected(); + } + } + } + + return CHIP_NO_ERROR; +} + +bool ConnectivityManagerImplWiFi::_IsWiFiStationEnabled(void) +{ + return (WiFiManager::StationStatus::DISABLED <= WiFiManager().Instance().GetStationStatus()); +} + +bool ConnectivityManagerImplWiFi::_IsWiFiStationApplicationControlled(void) +{ + return (ConnectivityManager::WiFiStationMode::kWiFiStationMode_ApplicationControlled == mStationMode); +} + +bool ConnectivityManagerImplWiFi::_IsWiFiStationConnected(void) +{ + return (WiFiManager::StationStatus::FULLY_PROVISIONED == WiFiManager().Instance().GetStationStatus()); +} + +System::Clock::Timeout ConnectivityManagerImplWiFi::_GetWiFiStationReconnectInterval(void) +{ + return mWiFiStationReconnectInterval; +} + +CHIP_ERROR ConnectivityManagerImplWiFi::_SetWiFiStationReconnectInterval(System::Clock::Timeout val) +{ + mWiFiStationReconnectInterval = val; + return CHIP_NO_ERROR; +} + +bool ConnectivityManagerImplWiFi::_IsWiFiStationProvisioned(void) +{ + // from Matter perspective `provisioned` means that the supplicant has been provided + // with SSID and password (doesn't matter if valid or not) + return (WiFiManager::StationStatus::CONNECTING <= WiFiManager().Instance().GetStationStatus()); +} + +void ConnectivityManagerImplWiFi::_ClearWiFiStationProvision(void) +{ + if (_IsWiFiStationProvisioned()) + { + if (CHIP_NO_ERROR != WiFiManager().Instance().ClearStationProvisioningData()) + { + ChipLogError(DeviceLayer, "Cannot clear WiFi station provisioning data"); + } + } +} + +bool ConnectivityManagerImplWiFi::_CanStartWiFiScan() +{ + return (WiFiManager::StationStatus::DISABLED != WiFiManager().Instance().GetStationStatus() && + WiFiManager::StationStatus::SCANNING != WiFiManager().Instance().GetStationStatus() && + WiFiManager::StationStatus::CONNECTING != WiFiManager().Instance().GetStationStatus()); +} + +void ConnectivityManagerImplWiFi::_OnWiFiStationProvisionChange() +{ + // do nothing +} + +void ConnectivityManagerImplWiFi::_OnWiFiScanDone() {} + +CHIP_ERROR ConnectivityManagerImplWiFi::_GetAndLogWiFiStatsCounters(void) +{ + // TODO: when network statistics are enabled + return CHIP_NO_ERROR; +} + +void ConnectivityManagerImplWiFi::OnStationConnected() +{ + // ensure the station is connected + if (_IsWiFiStationConnected()) + { + ChipDeviceEvent connectEvent{}; + connectEvent.Type = DeviceEventType::kWiFiConnectivityChange; + connectEvent.WiFiConnectivityChange.Result = kConnectivity_Established; + PlatformMgr().PostEventOrDie(&connectEvent); + } + else + { + ChipLogError(DeviceLayer, "WiFi Station is not connected!"); + } +} + +void ConnectivityManagerImplWiFi::OnStationDisconnected() +{ + // ensure the station is disconnected + if (WiFiManager::StationStatus::DISCONNECTED == WiFiManager().Instance().GetStationStatus()) + { + ChipDeviceEvent disconnectEvent{}; + disconnectEvent.Type = DeviceEventType::kWiFiConnectivityChange; + disconnectEvent.WiFiConnectivityChange.Result = kConnectivity_Lost; + PlatformMgr().PostEventOrDie(&disconnectEvent); + } + else + { + ChipLogError(DeviceLayer, "WiFi Station is not disconnected!"); + } +} + +ConnectivityManager::WiFiAPMode ConnectivityManagerImplWiFi::_GetWiFiAPMode(void) +{ + /* AP mode is unsupported */ + return ConnectivityManager::WiFiAPMode::kWiFiAPMode_NotSupported; +} + +CHIP_ERROR ConnectivityManagerImplWiFi::_SetWiFiAPMode(ConnectivityManager::WiFiAPMode mode) +{ + /* AP mode is unsupported */ + VerifyOrReturnError(ConnectivityManager::WiFiAPMode::kWiFiAPMode_NotSupported == mode || + ConnectivityManager::WiFiAPMode::kWiFiAPMode_Disabled == mode, + CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE); + return CHIP_NO_ERROR; +} + +bool ConnectivityManagerImplWiFi::_IsWiFiAPActive(void) +{ + /* AP mode is unsupported */ + return false; +} + +bool ConnectivityManagerImplWiFi::_IsWiFiAPApplicationControlled(void) +{ + /* AP mode is unsupported */ + return false; +} + +void ConnectivityManagerImplWiFi::_DemandStartWiFiAP(void) +{ /* AP mode is unsupported */ +} + +void ConnectivityManagerImplWiFi::_StopOnDemandWiFiAP(void) +{ /* AP mode is unsupported */ +} + +void ConnectivityManagerImplWiFi::_MaintainOnDemandWiFiAP(void) +{ /* AP mode is unsupported */ +} + +System::Clock::Timeout ConnectivityManagerImplWiFi::_GetWiFiAPIdleTimeout(void) +{ + /* AP mode is unsupported */ + return System::Clock::kZero; +} + +void ConnectivityManagerImplWiFi::_SetWiFiAPIdleTimeout(System::Clock::Timeout val) +{ /* AP mode is unsupported */ +} + +} // namespace DeviceLayer +} // namespace chip + +#endif // CHIP_DEVICE_CONFIG_ENABLE_WIFI diff --git a/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.h b/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.h new file mode 100644 index 00000000000000..8198453038417a --- /dev/null +++ b/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.h @@ -0,0 +1,82 @@ +/* + * + * Copyright (c) 2022 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 + +#include + +#include + +namespace chip { +namespace Inet { +class IPAddress; +} // namespace Inet +} // namespace chip + +namespace chip { +namespace DeviceLayer { + +class ConnectivityManagerImplWiFi +{ + friend class ConnectivityManager; + +protected: + CHIP_ERROR InitWiFi(); + +private: + // Wi-Fi station + ConnectivityManager::WiFiStationMode _GetWiFiStationMode(void); + CHIP_ERROR _SetWiFiStationMode(ConnectivityManager::WiFiStationMode val); + bool _IsWiFiStationEnabled(void); + bool _IsWiFiStationApplicationControlled(void); + bool _IsWiFiStationConnected(void); + System::Clock::Timeout _GetWiFiStationReconnectInterval(void); + CHIP_ERROR _SetWiFiStationReconnectInterval(System::Clock::Timeout val); + bool _IsWiFiStationProvisioned(void); + void _ClearWiFiStationProvision(void); + CHIP_ERROR _GetAndLogWiFiStatsCounters(void); + bool _CanStartWiFiScan(); + void _OnWiFiScanDone(); + void _OnWiFiStationProvisionChange(); + void OnStationConnected(); + void OnStationDisconnected(); + + // Wi-Fi access point - not supported + ConnectivityManager::WiFiAPMode _GetWiFiAPMode(void); + CHIP_ERROR _SetWiFiAPMode(ConnectivityManager::WiFiAPMode val); + bool _IsWiFiAPActive(void); + bool _IsWiFiAPApplicationControlled(void); + void _DemandStartWiFiAP(void); + void _StopOnDemandWiFiAP(void); + void _MaintainOnDemandWiFiAP(void); + System::Clock::Timeout _GetWiFiAPIdleTimeout(void); + void _SetWiFiAPIdleTimeout(System::Clock::Timeout val); + + ConnectivityManager::WiFiStationMode mStationMode{ ConnectivityManager::WiFiStationMode::kWiFiStationMode_Disabled }; + ConnectivityManager::WiFiStationState mStationState{ ConnectivityManager::WiFiStationState::kWiFiStationState_NotConnected }; + System::Clock::Timeout mWiFiStationReconnectInterval{}; + + static const char * _WiFiStationModeToStr(ConnectivityManager::WiFiStationMode mode); + static const char * _WiFiAPModeToStr(ConnectivityManager::WiFiAPMode mode); + static const char * _WiFiStationStateToStr(ConnectivityManager::WiFiStationState state); + static const char * _WiFiAPStateToStr(ConnectivityManager::WiFiAPState state); +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nrfconnect/wifi/NrfWiFiDriver.cpp b/src/platform/nrfconnect/wifi/NrfWiFiDriver.cpp new file mode 100644 index 00000000000000..243a8d4f965c12 --- /dev/null +++ b/src/platform/nrfconnect/wifi/NrfWiFiDriver.cpp @@ -0,0 +1,256 @@ +/* + * + * Copyright (c) 2022 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. + */ + +#include "NrfWiFiDriver.h" + +#include "WiFiManager.h" +#include + +#include +#include +#include + +using namespace ::chip; +using namespace ::chip::DeviceLayer::Internal; +using namespace ::chip::DeviceLayer::PersistedStorage; + +namespace chip { +namespace DeviceLayer { +namespace NetworkCommissioning { + +bool NrfWiFiScanResponseIterator::Next(WiFiScanResponse & item) +{ + if (mResultId < mResultCount) + { + item = mResults[mResultId++]; + return true; + } + return false; +} + +void NrfWiFiScanResponseIterator::Release() +{ + mResultId = mResultCount = 0; + Platform::MemoryFree(mResults); + mResults = nullptr; +} + +void NrfWiFiScanResponseIterator::Add(const WiFiScanResponse & result) +{ + void * newResults = Platform::MemoryRealloc(mResults, (mResultCount + 1) * sizeof(WiFiScanResponse)); + + if (newResults) + { + mResults = static_cast(newResults); + mResults[mResultCount++] = result; + } +} + +CHIP_ERROR NrfWiFiDriver::Init(NetworkStatusChangeCallback * networkStatusChangeCallback) +{ + mpNetworkStatusChangeCallback = networkStatusChangeCallback; + + LoadFromStorage(); + + if (mStagingNetwork.IsConfigured()) + { + WiFiManager::ConnectionHandling handling{ [] { Instance().OnNetworkStatusChanged(Status::kSuccess); }, + [] { Instance().OnNetworkStatusChanged(Status::kUnknownError); }, + System::Clock::Timeout{ 40000 } }; + ReturnErrorOnFailure( + WiFiManager::Instance().Connect(mStagingNetwork.GetSsidSpan(), mStagingNetwork.GetPassSpan(), handling)); + } + + return CHIP_NO_ERROR; +} + +void NrfWiFiDriver::OnNetworkStatusChanged(Status status) +{ + if (status == Status::kSuccess) + { + ConnectivityMgr().SetWiFiStationMode(ConnectivityManager::kWiFiStationMode_Enabled); + } + + if (mpNetworkStatusChangeCallback) + mpNetworkStatusChangeCallback->OnNetworkingStatusChange(status, NullOptional, NullOptional); +} + +void NrfWiFiDriver::Shutdown() +{ + mpNetworkStatusChangeCallback = nullptr; +} + +CHIP_ERROR NrfWiFiDriver::CommitConfiguration() +{ + ReturnErrorOnFailure(KeyValueStoreMgr().Put(kPassKey, mStagingNetwork.pass, mStagingNetwork.passLen)); + ReturnErrorOnFailure(KeyValueStoreMgr().Put(kSsidKey, mStagingNetwork.ssid, mStagingNetwork.ssidLen)); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR NrfWiFiDriver::RevertConfiguration() +{ + // Disconnection should happen automatically when WiFiManager::Connect() is called. + // Here we do it also explicitly to ping the Connectivity Manager which + // will send the disconnection event as a result. + // TODO: refactor when the callback-based supplicant API is incorporated + WiFiManager::Instance().DisconnectStation(); + ConnectivityMgr().SetWiFiStationMode(ConnectivityManager::kWiFiStationMode_Disabled); + + LoadFromStorage(); + + if (mStagingNetwork.IsConfigured()) + { + WiFiManager::ConnectionHandling handling{ [] { Instance().OnConnectWiFiNetwork(); }, + [] { Instance().OnConnectWiFiNetworkFailed(); }, + System::Clock::Timeout{ 40000 } }; + ReturnErrorOnFailure( + WiFiManager::Instance().Connect(mStagingNetwork.GetSsidSpan(), mStagingNetwork.GetPassSpan(), handling)); + } + + return CHIP_NO_ERROR; +} + +Status NrfWiFiDriver::AddOrUpdateNetwork(ByteSpan ssid, ByteSpan credentials, MutableCharSpan & outDebugText, + uint8_t & outNetworkIndex) +{ + outDebugText = {}; + outNetworkIndex = 0; + + VerifyOrReturnError(!mStagingNetwork.IsConfigured() || ssid.data_equal(mStagingNetwork.GetSsidSpan()), Status::kBoundsExceeded); + VerifyOrReturnError(ssid.size() <= sizeof(mStagingNetwork.ssid), Status::kOutOfRange); + VerifyOrReturnError(credentials.size() <= sizeof(mStagingNetwork.pass), Status::kOutOfRange); + + memcpy(mStagingNetwork.ssid, ssid.data(), ssid.size()); + memcpy(mStagingNetwork.pass, credentials.data(), credentials.size()); + mStagingNetwork.ssidLen = ssid.size(); + mStagingNetwork.passLen = credentials.size(); + + return Status::kSuccess; +} + +Status NrfWiFiDriver::RemoveNetwork(ByteSpan networkId, MutableCharSpan & outDebugText, uint8_t & outNetworkIndex) +{ + outDebugText = {}; + outNetworkIndex = 0; + + VerifyOrReturnError(networkId.data_equal(mStagingNetwork.GetSsidSpan()), Status::kNetworkIDNotFound); + mStagingNetwork.Clear(); + + return Status::kSuccess; +} + +Status NrfWiFiDriver::ReorderNetwork(ByteSpan networkId, uint8_t index, MutableCharSpan & outDebugText) +{ + outDebugText = {}; + + // Only one network is supported for now + VerifyOrReturnError(index == 0, Status::kOutOfRange); + VerifyOrReturnError(networkId.data_equal(mStagingNetwork.GetSsidSpan()), Status::kNetworkIDNotFound); + + return Status::kSuccess; +} + +void NrfWiFiDriver::ConnectNetwork(ByteSpan networkId, ConnectCallback * callback) +{ + Status status = Status::kSuccess; + WiFiManager::ConnectionHandling handling{ [] { Instance().OnConnectWiFiNetwork(); }, + [] { Instance().OnConnectWiFiNetworkFailed(); }, System::Clock::Timeout{ 40000 } }; + + VerifyOrExit(networkId.data_equal(mStagingNetwork.GetSsidSpan()), status = Status::kNetworkIDNotFound); + VerifyOrExit(mpConnectCallback == nullptr, status = Status::kUnknownError); + + mpConnectCallback = callback; + WiFiManager::Instance().Connect(mStagingNetwork.GetSsidSpan(), mStagingNetwork.GetPassSpan(), handling); + +exit: + if (status != Status::kSuccess) + { + mpConnectCallback = nullptr; + callback->OnResult(status, CharSpan(), 0); + } +} + +CHIP_ERROR GetConfiguredNetwork(Network & network) +{ + return CHIP_NO_ERROR; +} + +void NrfWiFiDriver::OnConnectWiFiNetwork() +{ + ConnectivityMgr().SetWiFiStationMode(ConnectivityManager::kWiFiStationMode_Enabled); + + if (mpConnectCallback) + { + mpConnectCallback->OnResult(Status::kSuccess, CharSpan(), 0); + mpConnectCallback = nullptr; + } +} + +void NrfWiFiDriver::OnConnectWiFiNetworkFailed() +{ + if (mpConnectCallback) + { + mpConnectCallback->OnResult(Status::kNetworkNotFound, CharSpan(), 0); + mpConnectCallback = nullptr; + } +} + +void NrfWiFiDriver::ScanNetworks(ByteSpan ssid, WiFiDriver::ScanCallback * callback) +{ + mScanCallback = callback; + CHIP_ERROR error = WiFiManager::Instance().Scan( + ssid, [](int status, WiFiScanResponse * response) { Instance().OnScanWiFiNetworkDone(status, response); }); + + if (error != CHIP_NO_ERROR) + { + mScanCallback = nullptr; + callback->OnFinished(Status::kUnknownError, CharSpan(), nullptr); + } +} + +void NrfWiFiDriver::OnScanWiFiNetworkDone(int status, WiFiScanResponse * response) +{ + if (response != nullptr) + { + StackLock lock; + VerifyOrReturn(mScanCallback != nullptr); + mScanResponseIterator.Add(*response); + return; + } + + // Scan complete + DeviceLayer::SystemLayer().ScheduleLambda([this, status]() { + VerifyOrReturn(mScanCallback != nullptr); + mScanCallback->OnFinished(status == 0 ? Status::kSuccess : Status::kUnknownError, CharSpan(), &mScanResponseIterator); + mScanCallback = nullptr; + }); +} + +void NrfWiFiDriver::LoadFromStorage() +{ + WiFiNetwork network; + + mStagingNetwork = {}; + ReturnOnFailure(KeyValueStoreMgr().Get(kSsidKey, network.ssid, sizeof(network.ssid), &network.ssidLen)); + ReturnOnFailure(KeyValueStoreMgr().Get(kPassKey, network.pass, sizeof(network.pass), &network.passLen)); + mStagingNetwork = network; +} + +} // namespace NetworkCommissioning +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nrfconnect/wifi/NrfWiFiDriver.h b/src/platform/nrfconnect/wifi/NrfWiFiDriver.h new file mode 100644 index 00000000000000..b8302c1f0689b5 --- /dev/null +++ b/src/platform/nrfconnect/wifi/NrfWiFiDriver.h @@ -0,0 +1,122 @@ +/* + * + * Copyright (c) 2022 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 + +namespace chip { +namespace DeviceLayer { +namespace NetworkCommissioning { + +constexpr uint8_t kMaxWiFiNetworks = 1; +constexpr uint8_t kWiFiScanNetworksTimeOutSeconds = 10; +constexpr uint8_t kWiFiConnectNetworkTimeoutSeconds = 120; + +class NrfWiFiScanResponseIterator : public Iterator +{ +public: + size_t Count() override { return mResultCount; } + bool Next(WiFiScanResponse & item) override; + void Release() override; + void Add(const WiFiScanResponse & result); + +private: + size_t mResultId = 0; + size_t mResultCount = 0; + WiFiScanResponse * mResults = nullptr; +}; + +class NrfWiFiDriver final : public WiFiDriver +{ +public: + // Define non-volatile storage keys for SSID and password. + // The naming convention is aligned with DefaultStorageKeyAllocator class. + static constexpr const char * kSsidKey = "g/wi/s"; + static constexpr const char * kPassKey = "g/wi/p"; + + class WiFiNetworkIterator final : public NetworkIterator + { + public: + WiFiNetworkIterator(NrfWiFiDriver * aDriver) : mDriver(aDriver) {} + size_t Count() override { return 0; }; + bool Next(Network & item) override { return true; } + void Release() override { delete this; } + ~WiFiNetworkIterator() = default; + + private: + NrfWiFiDriver * mDriver; + }; + + struct WiFiNetwork + { + uint8_t ssid[DeviceLayer::Internal::kMaxWiFiSSIDLength]; + size_t ssidLen = 0; + uint8_t pass[DeviceLayer::Internal::kMaxWiFiKeyLength]; + size_t passLen = 0; + + bool IsConfigured() const { return ssidLen > 0; } + ByteSpan GetSsidSpan() const { return ByteSpan(ssid, ssidLen); } + ByteSpan GetPassSpan() const { return ByteSpan(pass, passLen); } + void Clear() { ssidLen = 0; } + }; + + // BaseDriver + NetworkIterator * GetNetworks() override { return new WiFiNetworkIterator(this); } + CHIP_ERROR Init(NetworkStatusChangeCallback * networkStatusChangeCallback) override; + void Shutdown() override; + + // WirelessDriver + uint8_t GetMaxNetworks() override { return kMaxWiFiNetworks; } + uint8_t GetScanNetworkTimeoutSeconds() override { return kWiFiScanNetworksTimeOutSeconds; } + uint8_t GetConnectNetworkTimeoutSeconds() override { return kWiFiConnectNetworkTimeoutSeconds; } + + CHIP_ERROR CommitConfiguration() override; + CHIP_ERROR RevertConfiguration() override; + + Status RemoveNetwork(ByteSpan networkId, MutableCharSpan & outDebugText, uint8_t & outNetworkIndex) override; + Status ReorderNetwork(ByteSpan networkId, uint8_t index, MutableCharSpan & outDebugText) override; + void ConnectNetwork(ByteSpan networkId, ConnectCallback * callback) override; + + // WiFiDriver + Status AddOrUpdateNetwork(ByteSpan ssid, ByteSpan credentials, MutableCharSpan & outDebugText, + uint8_t & outNetworkIndex) override; + void ScanNetworks(ByteSpan ssid, ScanCallback * callback) override; + + static NrfWiFiDriver & Instance() + { + static NrfWiFiDriver sInstance; + return sInstance; + } + + void OnConnectWiFiNetwork(); + void OnConnectWiFiNetworkFailed(); + void OnNetworkStatusChanged(Status status); + void OnScanWiFiNetworkDone(int status, WiFiScanResponse * result); + +private: + void LoadFromStorage(); + + ConnectCallback * mpConnectCallback{ nullptr }; + NetworkStatusChangeCallback * mpNetworkStatusChangeCallback{ nullptr }; + WiFiNetwork mStagingNetwork; + NrfWiFiScanResponseIterator mScanResponseIterator; + ScanCallback * mScanCallback{ nullptr }; +}; + +} // namespace NetworkCommissioning +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nrfconnect/wifi/WiFiManager.cpp b/src/platform/nrfconnect/wifi/WiFiManager.cpp new file mode 100644 index 00000000000000..083c27577ffd54 --- /dev/null +++ b/src/platform/nrfconnect/wifi/WiFiManager.cpp @@ -0,0 +1,430 @@ +/* + * + * Copyright (c) 2022 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. + */ + +/** + * @file + * Provides the wrapper for nRF WiFi API + */ + +#include "WiFiManager.h" + +#include +#include +#include +#include +#include + +#include +#include + +extern "C" { +#include +#include +#include +#include +#include +} + +extern struct wpa_supplicant * wpa_s_0; + +namespace chip { +namespace DeviceLayer { + +namespace { + +NetworkCommissioning::WiFiScanResponse ToScanResponse(wifi_scan_result * result) +{ + NetworkCommissioning::WiFiScanResponse response = {}; + + if (result != nullptr) + { + static_assert(sizeof(response.ssid) == sizeof(result->ssid), "SSID length mismatch"); + static_assert(sizeof(response.bssid) == sizeof(result->mac), "BSSID length mismatch"); + + // TODO: Distinguish WPA versions + response.security.Set(result->security == WIFI_SECURITY_TYPE_PSK ? NetworkCommissioning::WiFiSecurity::kWpaPersonal + : NetworkCommissioning::WiFiSecurity::kUnencrypted); + response.channel = result->channel; + response.rssi = result->rssi; + response.ssidLen = result->ssid_length; + memcpy(response.ssid, result->ssid, result->ssid_length); + // TODO: MAC/BSSID is not filled by the Wi-Fi driver + memcpy(response.bssid, result->mac, result->mac_length); + } + + return response; +} + +} // namespace + +// These enums shall reflect the overall ordered disconnected->connected flow +const Map + WiFiManager::sStatusMap({ { WPA_DISCONNECTED, WiFiManager::StationStatus::DISCONNECTED }, + { WPA_INTERFACE_DISABLED, WiFiManager::StationStatus::DISABLED }, + { WPA_INACTIVE, WiFiManager::StationStatus::DISABLED }, + { WPA_SCANNING, WiFiManager::StationStatus::SCANNING }, + { WPA_AUTHENTICATING, WiFiManager::StationStatus::CONNECTING }, + { WPA_ASSOCIATING, WiFiManager::StationStatus::CONNECTING }, + { WPA_ASSOCIATED, WiFiManager::StationStatus::CONNECTED }, + { WPA_4WAY_HANDSHAKE, WiFiManager::StationStatus::PROVISIONING }, + { WPA_GROUP_HANDSHAKE, WiFiManager::StationStatus::PROVISIONING }, + { WPA_COMPLETED, WiFiManager::StationStatus::FULLY_PROVISIONED } }); + +// Map WiFi center frequency to the corresponding channel number +const Map WiFiManager::sFreqChannelMap( + { { 4915, 183 }, { 4920, 184 }, { 4925, 185 }, { 4935, 187 }, { 4940, 188 }, { 4945, 189 }, { 4960, 192 }, + { 4980, 196 }, { 5035, 7 }, { 5040, 8 }, { 5045, 9 }, { 5055, 11 }, { 5060, 12 }, { 5080, 16 }, + { 5170, 34 }, { 5180, 36 }, { 5190, 38 }, { 5200, 40 }, { 5210, 42 }, { 5220, 44 }, { 5230, 46 }, + { 5240, 48 }, { 5260, 52 }, { 5280, 56 }, { 5300, 60 }, { 5320, 64 }, { 5500, 100 }, { 5520, 104 }, + { 5540, 108 }, { 5560, 112 }, { 5580, 116 }, { 5600, 120 }, { 5620, 124 }, { 5640, 128 }, { 5660, 132 }, + { 5680, 136 }, { 5700, 140 }, { 5745, 149 }, { 5765, 153 }, { 5785, 157 }, { 5805, 161 }, { 5825, 165 } }); + +CHIP_ERROR WiFiManager::Init() +{ + // wpa_supplicant instance should be initialized in dedicated supplicant thread + if (!wpa_s_0) + { + ChipLogError(DeviceLayer, "wpa_supplicant is not initialized!"); + + return CHIP_ERROR_INTERNAL; + } + + // TODO: consider moving these to ConnectivityManagerImpl to be prepared for handling multiple interfaces on a single device. + Inet::UDPEndPointImplSockets::SetJoinMulticastGroupHandler([](Inet::InterfaceId interfaceId, const Inet::IPAddress & address) { + const in6_addr addr = InetUtils::ToZephyrAddr(address); + net_if * iface = InetUtils::GetInterface(interfaceId); + VerifyOrReturnError(iface != nullptr, INET_ERROR_UNKNOWN_INTERFACE); + + net_if_mcast_addr * maddr = net_if_ipv6_maddr_add(iface, &addr); + + if (maddr && !net_if_ipv6_maddr_is_joined(maddr) && !net_ipv6_is_addr_mcast_link_all_nodes(&addr)) + { + net_if_ipv6_maddr_join(maddr); + } + + return CHIP_NO_ERROR; + }); + + Inet::UDPEndPointImplSockets::SetLeaveMulticastGroupHandler([](Inet::InterfaceId interfaceId, const Inet::IPAddress & address) { + const in6_addr addr = InetUtils::ToZephyrAddr(address); + net_if * iface = InetUtils::GetInterface(interfaceId); + VerifyOrReturnError(iface != nullptr, INET_ERROR_UNKNOWN_INTERFACE); + + if (!net_ipv6_is_addr_mcast_link_all_nodes(&addr) && !net_if_ipv6_maddr_rm(iface, &addr)) + { + return CHIP_ERROR_INVALID_ADDRESS; + } + + return CHIP_NO_ERROR; + }); + + ChipLogDetail(DeviceLayer, "wpa_supplicant has been initialized"); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR WiFiManager::AddNetwork(const ByteSpan & ssid, const ByteSpan & credentials) +{ + ChipLogDetail(DeviceLayer, "Adding WiFi network"); + mpWpaNetwork = wpa_supplicant_add_network(wpa_s_0); + if (mpWpaNetwork) + { + static constexpr size_t kMaxSsidLen{ 32 }; + mpWpaNetwork->ssid = (u8 *) k_malloc(kMaxSsidLen); + + if (mpWpaNetwork->ssid) + { + memcpy(mpWpaNetwork->ssid, ssid.data(), ssid.size()); + mpWpaNetwork->ssid_len = ssid.size(); + mpWpaNetwork->key_mgmt = WPA_KEY_MGMT_NONE; + mpWpaNetwork->disabled = 1; + wpa_s_0->conf->filter_ssids = 1; + + return AddPsk(credentials); + } + } + + return CHIP_ERROR_INTERNAL; +} + +CHIP_ERROR WiFiManager::Scan(const ByteSpan & ssid, ScanCallback callback) +{ + const StationStatus stationStatus = GetStationStatus(); + VerifyOrReturnError(stationStatus != StationStatus::DISABLED && stationStatus != StationStatus::SCANNING && + stationStatus != StationStatus::CONNECTING, + CHIP_ERROR_INCORRECT_STATE); + + net_if * const iface = InetUtils::GetInterface(); + VerifyOrReturnError(iface != nullptr, CHIP_ERROR_INTERNAL); + + const device * dev = net_if_get_device(iface); + VerifyOrReturnError(dev != nullptr, CHIP_ERROR_INTERNAL); + + const wifi_nrf_dev_ops * ops = static_cast(dev->api); + VerifyOrReturnError(ops != nullptr, CHIP_ERROR_INTERNAL); + + mScanCallback = callback; + + // TODO: Use saner API once such exists. + // TODO: Take 'ssid' into account. + VerifyOrReturnError(ops->off_api.disp_scan(dev, + [](net_if *, int status, wifi_scan_result * result) { + VerifyOrReturn(Instance().mScanCallback != nullptr); + NetworkCommissioning::WiFiScanResponse response = ToScanResponse(result); + Instance().mScanCallback(status, result != nullptr ? &response : nullptr); + }) == 0, + CHIP_ERROR_INTERNAL); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR WiFiManager::Connect(const ByteSpan & ssid, const ByteSpan & credentials, const ConnectionHandling & handling) +{ + ChipLogDetail(DeviceLayer, "Connecting to WiFi network"); + + mConnectionSuccessClbk = handling.mOnConnectionSuccess; + mConnectionFailedClbk = handling.mOnConnectionFailed; + mConnectionTimeoutMs = handling.mConnectionTimeoutMs; + + CHIP_ERROR err = AddNetwork(ssid, credentials); + if (CHIP_NO_ERROR == err) + { + EnableStation(true); + wpa_supplicant_select_network(wpa_s_0, mpWpaNetwork); + WaitForConnectionAsync(); + } + else + { + OnConnectionFailed(); + } + return err; +} + +void WiFiManager::OnConnectionSuccess() +{ + if (mConnectionSuccessClbk) + mConnectionSuccessClbk(); +} + +void WiFiManager::OnConnectionFailed() +{ + if (mConnectionFailedClbk) + mConnectionFailedClbk(); +} + +CHIP_ERROR WiFiManager::AddPsk(const ByteSpan & credentials) +{ + mpWpaNetwork->key_mgmt = WPA_KEY_MGMT_PSK; + str_clear_free(mpWpaNetwork->passphrase); + mpWpaNetwork->passphrase = dup_binstr(credentials.data(), credentials.size()); + + if (mpWpaNetwork->passphrase) + { + wpa_config_update_psk(mpWpaNetwork); + return CHIP_NO_ERROR; + } + + return CHIP_ERROR_INTERNAL; +} + +WiFiManager::StationStatus WiFiManager::GetStationStatus() const +{ + if (wpa_s_0) + { + return StatusFromWpaStatus(wpa_s_0->wpa_state); + } + else + { + ChipLogError(DeviceLayer, "wpa_supplicant is not initialized!"); + return StationStatus::NONE; + } +} + +WiFiManager::StationStatus WiFiManager::StatusFromWpaStatus(const wpa_states & status) +{ + ChipLogDetail(DeviceLayer, "WPA internal status: %d", static_cast(status)); + return WiFiManager::sStatusMap[status]; +} + +CHIP_ERROR WiFiManager::EnableStation(bool enable) +{ + VerifyOrReturnError(nullptr != wpa_s_0 && nullptr != mpWpaNetwork, CHIP_ERROR_INTERNAL); + if (enable) + { + wpa_supplicant_enable_network(wpa_s_0, mpWpaNetwork); + } + else + { + wpa_supplicant_disable_network(wpa_s_0, mpWpaNetwork); + // TODO: wpa_supplicant_remove_network(wpa_s, ssid->id)?? + // TODO: DisconnectStation()?? + } + + return CHIP_NO_ERROR; +} + +CHIP_ERROR WiFiManager::ClearStationProvisioningData() +{ + VerifyOrReturnError(nullptr != wpa_s_0 && nullptr != mpWpaNetwork, CHIP_ERROR_INTERNAL); + // TODO(?): wpa_supplicant_deauthenticate(wpa_s_0, 1); // 1 - unspecified reason (IEEE 802.11) + wpa_supplicant_cancel_scan(wpa_s_0); + wpa_clear_keys(wpa_s_0, mpWpaNetwork->bssid); + str_clear_free(mpWpaNetwork->passphrase); + wpa_config_update_psk(mpWpaNetwork); + wpa_supplicant_set_state(wpa_s_0, WPA_INACTIVE); + + return CHIP_NO_ERROR; +} + +CHIP_ERROR WiFiManager::DisconnectStation() +{ + VerifyOrReturnError(nullptr != wpa_s_0, CHIP_ERROR_INTERNAL); + wpa_supplicant_cancel_scan(wpa_s_0); + wpas_request_disconnection(wpa_s_0); + + return CHIP_NO_ERROR; +} + +void WiFiManager::WaitForConnectionAsync() +{ + chip::DeviceLayer::SystemLayer().StartTimer( + static_cast(1000), [](System::Layer *, void *) { Instance().PollTimerCallback(); }, nullptr); +} + +void WiFiManager::PollTimerCallback() +{ + const uint32_t kMaxRetriesNumber{ mConnectionTimeoutMs.count() / 1000 }; + static uint32_t retriesNumber{ 0 }; + + if (WiFiManager::StationStatus::FULLY_PROVISIONED == GetStationStatus()) + { + OnConnectionSuccess(); + } + else + { + if (retriesNumber++ < kMaxRetriesNumber) + { + // wait more time + WaitForConnectionAsync(); + } + else + { + // connection timeout + OnConnectionFailed(); + } + } +} + +CHIP_ERROR WiFiManager::GetWiFiInfo(WiFiInfo & info) const +{ + VerifyOrReturnError(nullptr != wpa_s_0, CHIP_ERROR_INTERNAL); + + static uint8_t sBssid[ETH_ALEN]; + if (WiFiManager::StationStatus::CONNECTED <= GetStationStatus()) + { + memcpy(sBssid, wpa_s_0->bssid, ETH_ALEN); + info.mBssId = ByteSpan(sBssid, ETH_ALEN); + info.mSecurityType = GetSecurityType(); + // TODO: this should reflect the real connection compliance + // i.e. the AP might support WiFi 5 only even though the station + // is WiFi 6 ready (so the connection is WiFi 5 effectively). + // For now just return what the station supports. + info.mWiFiVersion = EMBER_ZCL_WI_FI_VERSION_TYPE_802__11AX; + + wpa_signal_info signalInfo{}; + if (0 == wpa_drv_signal_poll(wpa_s_0, &signalInfo)) + { + info.mRssi = signalInfo.current_signal; // dBm + info.mChannel = FrequencyToChannel(signalInfo.frequency); + } + else + { + // this values should be nullable according to the Matter spec + info.mRssi = std::numeric_limits::min(); + info.mChannel = std::numeric_limits::min(); + } + return CHIP_NO_ERROR; + } + + return CHIP_ERROR_INTERNAL; +} + +uint8_t WiFiManager::GetSecurityType() const +{ + VerifyOrReturnValue(nullptr != mpWpaNetwork, EMBER_ZCL_SECURITY_TYPE_UNSPECIFIED); + + if ((mpWpaNetwork->key_mgmt & WPA_KEY_MGMT_NONE) || !wpa_key_mgmt_wpa_any(mpWpaNetwork->key_mgmt)) + { + return EMBER_ZCL_SECURITY_TYPE_NONE; + } + else if (wpa_key_mgmt_wpa_psk_no_sae(mpWpaNetwork->key_mgmt)) + { + return (mpWpaNetwork->pairwise_cipher & (WPA_CIPHER_TKIP | WPA_CIPHER_CCMP)) ? EMBER_ZCL_SECURITY_TYPE_WPA2 + : EMBER_ZCL_SECURITY_TYPE_WPA3; + } + else if (wpa_key_mgmt_sae(mpWpaNetwork->key_mgmt)) + { + return EMBER_ZCL_SECURITY_TYPE_WPA3; + } + else + { + return EMBER_ZCL_SECURITY_TYPE_WEP; + } + + return EMBER_ZCL_SECURITY_TYPE_UNSPECIFIED; +} + +uint8_t WiFiManager::FrequencyToChannel(uint16_t freq) +{ + static constexpr uint16_t k24MinFreq{ 2401 }; + static constexpr uint16_t k24MaxFreq{ 2484 }; + static constexpr uint8_t k24FreqConstDiff{ 5 }; + + if (freq >= k24MinFreq && freq < k24MaxFreq) + { + return static_cast((freq - k24MinFreq) / k24FreqConstDiff + 1); + } + else if (freq == k24MaxFreq) + { + return 14; + } + else if (freq > k24MaxFreq) + { + // assume we are in 5GH band + return sFreqChannelMap[freq]; + } + return 0; +} + +CHIP_ERROR WiFiManager::GetNetworkStatistics(NetworkStatistics & stats) const +{ + // TODO: below will not work (result will be all zeros) until + // the get_stats handler is implemented in WiFi driver + net_stats_eth data{}; + net_mgmt(NET_REQUEST_STATS_GET_ETHERNET, InetUtils::GetInterface(), &data, sizeof(data)); + + stats.mPacketMulticastRxCount = data.multicast.rx; + stats.mPacketMulticastTxCount = data.multicast.tx; + stats.mPacketUnicastRxCount = data.pkts.rx - data.multicast.rx - data.broadcast.rx; + stats.mPacketUnicastTxCount = data.pkts.tx - data.multicast.tx - data.broadcast.tx; + stats.mOverruns = 0; // TODO: clarify if this can be queried from mgmt API (e.g. data.tx_dropped) + + return CHIP_NO_ERROR; +} + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/nrfconnect/wifi/WiFiManager.h b/src/platform/nrfconnect/wifi/WiFiManager.h new file mode 100644 index 00000000000000..de2559d667b342 --- /dev/null +++ b/src/platform/nrfconnect/wifi/WiFiManager.h @@ -0,0 +1,169 @@ +/* + * + * Copyright (c) 2022 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. + */ + +/** + * @file + * Provides the wrapper for nRF wpa_supplicant API + */ + +#pragma once + +#include +#include +#include +#include + +#include + +extern "C" { +#include +#include +} + +struct net_if; +struct wpa_ssid; +using WpaNetwork = struct wpa_ssid; + +namespace chip { +namespace DeviceLayer { + +// emulation of dictionary - might be moved to utils +template +class Map +{ + struct Pair + { + T1 key; + T2 value; + }; + +public: + Map(const Pair (&list)[N]) + { + int idx{ 0 }; + for (const auto & pair : list) + { + mMap[idx++] = pair; + } + } + + T2 operator[](const T1 & key) const + { + for (const auto & it : mMap) + { + if (key == it.key) + return it.value; + } + + return T2{}; + } + + Map() = delete; + Map(const Map &) = delete; + Map(Map &&) = delete; + Map & operator=(const Map &) = delete; + Map & operator=(Map &&) = delete; + ~Map() = default; + +private: + Pair mMap[N]; +}; + +class WiFiManager +{ + using ConnectionCallback = void (*)(); + +public: + enum class StationStatus : uint8_t + { + NONE, + DISCONNECTED, + DISABLED, + SCANNING, + CONNECTING, + CONNECTED, + PROVISIONING, + FULLY_PROVISIONED + }; + + static WiFiManager & Instance() + { + static WiFiManager sInstance; + return sInstance; + } + + using ScanCallback = void (*)(int /* status */, NetworkCommissioning::WiFiScanResponse *); + + struct ConnectionHandling + { + ConnectionCallback mOnConnectionSuccess{}; + ConnectionCallback mOnConnectionFailed{}; + System::Clock::Timeout mConnectionTimeoutMs{}; + }; + + struct WiFiInfo + { + ByteSpan mBssId{}; + uint8_t mSecurityType{}; + uint8_t mWiFiVersion{}; + uint16_t mChannel{}; + int8_t mRssi{}; + }; + + struct NetworkStatistics + { + uint32_t mPacketMulticastRxCount{}; + uint32_t mPacketMulticastTxCount{}; + uint32_t mPacketUnicastRxCount{}; + uint32_t mPacketUnicastTxCount{}; + uint32_t mOverruns{}; + }; + + CHIP_ERROR Init(); + CHIP_ERROR Scan(const ByteSpan & ssid, ScanCallback callback); + CHIP_ERROR Connect(const ByteSpan & ssid, const ByteSpan & credentials, const ConnectionHandling & handling); + StationStatus GetStationStatus() const; + CHIP_ERROR ClearStationProvisioningData(); + CHIP_ERROR DisconnectStation(); + CHIP_ERROR GetWiFiInfo(WiFiInfo & info) const; + CHIP_ERROR GetNetworkStatistics(NetworkStatistics & stats) const; + +private: + CHIP_ERROR AddPsk(const ByteSpan & credentials); + CHIP_ERROR EnableStation(bool enable); + CHIP_ERROR AddNetwork(const ByteSpan & ssid, const ByteSpan & credentials); + void PollTimerCallback(); + void WaitForConnectionAsync(); + void OnConnectionSuccess(); + void OnConnectionFailed(); + uint8_t GetSecurityType() const; + + WpaNetwork * mpWpaNetwork{ nullptr }; + ConnectionCallback mConnectionSuccessClbk; + ConnectionCallback mConnectionFailedClbk; + System::Clock::Timeout mConnectionTimeoutMs; + ScanCallback mScanCallback{ nullptr }; + + static uint8_t FrequencyToChannel(uint16_t freq); + static StationStatus StatusFromWpaStatus(const wpa_states & status); + + static const Map sStatusMap; + static const Map sFreqChannelMap; +}; + +} // namespace DeviceLayer +} // namespace chip diff --git a/src/platform/telink/BUILD.gn b/src/platform/telink/BUILD.gn index 8b34590d370b17..7d1345df029be1 100644 --- a/src/platform/telink/BUILD.gn +++ b/src/platform/telink/BUILD.gn @@ -25,6 +25,7 @@ static_library("telink") { "../Zephyr/ConfigurationManagerImpl.cpp", "../Zephyr/DiagnosticDataProviderImpl.cpp", "../Zephyr/DiagnosticDataProviderImpl.h", + "../Zephyr/DiagnosticDataProviderImplGetter.cpp", "../Zephyr/KeyValueStoreManagerImpl.cpp", "../Zephyr/Logging.cpp", "../Zephyr/PlatformManagerImpl.cpp",