diff --git a/.github/workflows/chef.yaml b/.github/workflows/chef.yaml index 93320c07b4ec67..2e109de498da9b 100644 --- a/.github/workflows/chef.yaml +++ b/.github/workflows/chef.yaml @@ -85,8 +85,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - # TODO: update this to connectedhomeip/chip-build-vscode:0.6.30 once we can compile with latest NRF - image: connectedhomeip/chip-build-nrf-platform:0.6.18 + image: connectedhomeip/chip-build-nrf-platform:0.6.30 options: --user root steps: diff --git a/.github/workflows/examples-nrfconnect.yaml b/.github/workflows/examples-nrfconnect.yaml index 66785103769950..06d54c2b84176a 100644 --- a/.github/workflows/examples-nrfconnect.yaml +++ b/.github/workflows/examples-nrfconnect.yaml @@ -83,9 +83,9 @@ jobs: path: | .environment/gn_out/.ninja_log .environment/pigweed-venv/*.log - - name: Update nRF Connect SDK revision to the currently recommended. + - name: Check nRF Connect SDK revision. timeout-minutes: 15 - run: scripts/run_in_build_env.sh "python3 scripts/setup/nrfconnect/update_ncs.py --update --shallow" + run: scripts/run_in_build_env.sh "python3 scripts/setup/nrfconnect/update_ncs.py --check" - name: Run unit tests of factory data generation script timeout-minutes: 15 run: scripts/run_in_build_env.sh "./scripts/tools/nrfconnect/tests/test_generate_factory_data.py" diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index 3bfcc32bd9da4c..11bccad5b80828 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -28,7 +28,7 @@ jobs: if: github.actor != 'restyled-io[bot]' container: - image: connectedhomeip/chip-build:0.6.18 + image: connectedhomeip/chip-build:0.6.27 steps: - uses: Wandalen/wretry.action@v1.0.36 diff --git a/config/nrfconnect/.nrfconnect-recommended-revision b/config/nrfconnect/.nrfconnect-recommended-revision index 826e1424638453..a4b6ac3ded6d12 100644 --- a/config/nrfconnect/.nrfconnect-recommended-revision +++ b/config/nrfconnect/.nrfconnect-recommended-revision @@ -1 +1 @@ -v2.1.1 +v2.2.0 diff --git a/config/nrfconnect/chip-module/CMakeLists.txt b/config/nrfconnect/chip-module/CMakeLists.txt index cef54d4bd014f6..0ca4a816f5f1d2 100644 --- a/config/nrfconnect/chip-module/CMakeLists.txt +++ b/config/nrfconnect/chip-module/CMakeLists.txt @@ -92,6 +92,8 @@ set(CHIP_GN_ROOT_TARGET ${CHIP_ROOT}/config/nrfconnect/chip-gn) # Prepare compiler flags +list(APPEND CHIP_CFLAGS -D_DEFAULT_SOURCE) + if (CONFIG_ARM) list(APPEND CHIP_CFLAGS_C --specs=nosys.specs @@ -309,6 +311,7 @@ add_dependencies(chip-gn kernel) zephyr_interface_library_named(chip) target_compile_definitions(chip INTERFACE CHIP_HAVE_CONFIG_H) +target_compile_definitions(chip INTERFACE _DEFAULT_SOURCE) target_include_directories(chip INTERFACE ${CHIP_ROOT}/src ${CHIP_ROOT}/src/include diff --git a/config/nrfconnect/chip-module/Kconfig.defaults b/config/nrfconnect/chip-module/Kconfig.defaults index 88519293b67d77..f6010168f4b3da 100644 --- a/config/nrfconnect/chip-module/Kconfig.defaults +++ b/config/nrfconnect/chip-module/Kconfig.defaults @@ -71,10 +71,6 @@ config MAIN_STACK_SIZE config INIT_STACKS default y -# Disable certain parts of Zephyr IPv6 stack -config NET_IPV6_NBR_CACHE - default n - config NET_IPV6_MLD default y @@ -121,7 +117,9 @@ config BT_DEVICE_NAME_MAX default 15 config BT_MAX_CONN - default 1 + default 2 # a workaround for non-unreferenced BLE connection object + # when restaring the BLE advertising in disconnect callback + # TODO: analyze and revert to 1 if proper fix exists config BT_L2CAP_TX_MTU default 247 @@ -189,6 +187,11 @@ config NET_L2_OPENTHREAD if NET_L2_OPENTHREAD +# Disable certain parts of Zephyr IPv6 stack +config NET_IPV6_NBR_CACHE + bool + default n + # Increase the default RX stack size config IEEE802154_NRF5_RX_STACK_SIZE default 1024 @@ -204,7 +207,7 @@ config MBEDTLS_PSA_CRYPTO_EXTERNAL_RNG default n config SYSTEM_WORKQUEUE_STACK_SIZE - default 1120 + default 2048 # align these numbers to match the OpenThread config config NET_IF_UNICAST_IPV6_ADDR_COUNT @@ -319,9 +322,6 @@ config MBEDTLS_GCM_C config MBEDTLS_RSA_C default n -config PSA_WANT_KEY_TYPE_ARIA - default n - config PSA_WANT_KEY_TYPE_CHACHA20 default n diff --git a/config/zephyr/Kconfig b/config/zephyr/Kconfig index 4fd9b7ec36d17c..45b04b9a1e2216 100644 --- a/config/zephyr/Kconfig +++ b/config/zephyr/Kconfig @@ -20,6 +20,7 @@ menuconfig CHIP select CPLUSPLUS imply LIB_CPLUSPLUS imply REQUIRES_FULL_LIBC + imply NEWLIB_LIBC_NANO imply CBPRINTF_LIBC_SUBSTS imply POSIX_API if !ARCH_POSIX imply EVENTFD if !ARCH_POSIX 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 4b2eca8e4cd66b..3fa8dace395131 100644 --- a/examples/all-clusters-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/examples/all-clusters-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -14,11 +14,16 @@ * limitations under the License. */ +#include + / { chosen { nordic,pm-ext-flash = &mx25r64; }; +}; +&ipc0 { + zephyr,priority = <0 PRIO_COOP>; }; /* Disable unused peripherals to reduce power consumption */ diff --git a/examples/all-clusters-app/nrfconnect/main/AppTask.cpp b/examples/all-clusters-app/nrfconnect/main/AppTask.cpp index b42b7b41ccd8ad..5e3dc0adc48163 100644 --- a/examples/all-clusters-app/nrfconnect/main/AppTask.cpp +++ b/examples/all-clusters-app/nrfconnect/main/AppTask.cpp @@ -45,8 +45,8 @@ #endif #include +#include #include -#include LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); 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 4b2eca8e4cd66b..3fa8dace395131 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 @@ -14,11 +14,16 @@ * limitations under the License. */ +#include + / { chosen { nordic,pm-ext-flash = &mx25r64; }; +}; +&ipc0 { + zephyr,priority = <0 PRIO_COOP>; }; /* Disable unused peripherals to reduce power consumption */ diff --git a/examples/all-clusters-minimal-app/nrfconnect/main/AppTask.cpp b/examples/all-clusters-minimal-app/nrfconnect/main/AppTask.cpp index a2a149a9e01d50..5d3c2b0d2bba8c 100644 --- a/examples/all-clusters-minimal-app/nrfconnect/main/AppTask.cpp +++ b/examples/all-clusters-minimal-app/nrfconnect/main/AppTask.cpp @@ -36,8 +36,8 @@ #endif #include -#include -#include +#include +#include LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); diff --git a/examples/all-clusters-minimal-app/nrfconnect/main/main.cpp b/examples/all-clusters-minimal-app/nrfconnect/main/main.cpp index ec11d180c8c911..400f9b30e0dd01 100644 --- a/examples/all-clusters-minimal-app/nrfconnect/main/main.cpp +++ b/examples/all-clusters-minimal-app/nrfconnect/main/main.cpp @@ -17,11 +17,11 @@ #include "AppTask.h" -#include +#include #if DT_NODE_HAS_COMPAT(DT_CHOSEN(zephyr_console), zephyr_cdc_acm_uart) -#include -#include +#include +#include #endif LOG_MODULE_REGISTER(app, CONFIG_CHIP_APP_LOG_LEVEL); diff --git a/examples/common/pigweed/nrfconnect/PigweedLoggerMutex.h b/examples/common/pigweed/nrfconnect/PigweedLoggerMutex.h index 18a1327669bd37..1f00287a1581d9 100644 --- a/examples/common/pigweed/nrfconnect/PigweedLoggerMutex.h +++ b/examples/common/pigweed/nrfconnect/PigweedLoggerMutex.h @@ -20,7 +20,7 @@ #include "PigweedLogger.h" #include "pigweed/RpcService.h" -#include +#include namespace chip { namespace rpc { diff --git a/examples/light-switch-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/light-switch-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay index cf300f82ba0a4a..6f560e36368b6c 100644 --- a/examples/light-switch-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/examples/light-switch-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -14,9 +14,14 @@ * limitations under the License. */ +#include + / { chosen { nordic,pm-ext-flash = &mx25r64; }; +}; +&ipc0 { + zephyr,priority = <0 PRIO_COOP>; }; diff --git a/examples/light-switch-app/nrfconnect/boards/nrf7002dk_nrf5340_cpuapp.overlay b/examples/light-switch-app/nrfconnect/boards/nrf7002dk_nrf5340_cpuapp.overlay index 90f303f82cc4e0..3063fbbcdee779 100644 --- a/examples/light-switch-app/nrfconnect/boards/nrf7002dk_nrf5340_cpuapp.overlay +++ b/examples/light-switch-app/nrfconnect/boards/nrf7002dk_nrf5340_cpuapp.overlay @@ -14,7 +14,6 @@ * limitations under the License. */ - / { chosen { nordic,pm-ext-flash = &mx25r64; diff --git a/examples/light-switch-app/nrfconnect/main/AppTask.cpp b/examples/light-switch-app/nrfconnect/main/AppTask.cpp index 3ba17c73a5c147..bf28af3f97fab5 100644 --- a/examples/light-switch-app/nrfconnect/main/AppTask.cpp +++ b/examples/light-switch-app/nrfconnect/main/AppTask.cpp @@ -45,8 +45,8 @@ #endif #include +#include #include -#include LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); diff --git a/examples/lighting-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/lighting-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay index d900ac5d9861e4..ae489254784606 100644 --- a/examples/lighting-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/examples/lighting-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -14,6 +14,8 @@ * limitations under the License. */ +#include + / { chosen { nordic,pm-ext-flash = &mx25r64; @@ -34,7 +36,10 @@ pwms = < &pwm0 1 PWM_MSEC(20) PWM_POLARITY_INVERTED>; }; }; +}; +&ipc0 { + zephyr,priority = <0 PRIO_COOP>; }; &pwm0 { diff --git a/examples/lighting-app/nrfconnect/boards/nrf7002dk_nrf5340_cpuapp.overlay b/examples/lighting-app/nrfconnect/boards/nrf7002dk_nrf5340_cpuapp.overlay index 481ff46231e7d1..de203e27aa1f69 100644 --- a/examples/lighting-app/nrfconnect/boards/nrf7002dk_nrf5340_cpuapp.overlay +++ b/examples/lighting-app/nrfconnect/boards/nrf7002dk_nrf5340_cpuapp.overlay @@ -14,7 +14,6 @@ * limitations under the License. */ - / { chosen { nordic,pm-ext-flash = &mx25r64; @@ -32,7 +31,7 @@ pwmleds { compatible = "pwm-leds"; pwm_led1: pwm_led_1 { - pwms = < &pwm0 1 PWM_MSEC(20) PWM_POLARITY_INVERTED>; + pwms = < &pwm0 1 PWM_MSEC(20) PWM_POLARITY_NORMAL>; }; }; }; diff --git a/examples/lighting-app/nrfconnect/main/AppTask.cpp b/examples/lighting-app/nrfconnect/main/AppTask.cpp index 26a90b858eaf64..390a6718c8ea77 100644 --- a/examples/lighting-app/nrfconnect/main/AppTask.cpp +++ b/examples/lighting-app/nrfconnect/main/AppTask.cpp @@ -50,8 +50,8 @@ #endif #include +#include #include -#include LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); diff --git a/examples/lighting-app/nrfconnect/main/include/AppConfig.h b/examples/lighting-app/nrfconnect/main/include/AppConfig.h index 536e92e37bfd37..3f311d4a8a45d3 100644 --- a/examples/lighting-app/nrfconnect/main/include/AppConfig.h +++ b/examples/lighting-app/nrfconnect/main/include/AppConfig.h @@ -1,20 +1,18 @@ -/* - * - * Copyright (c) 2020 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. - */ +// +// Copyright (c) 2020 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 @@ -41,5 +39,3 @@ #define FACTORY_RESET_SIGNAL_LED DK_LED3 #define FACTORY_RESET_SIGNAL_LED1 DK_LED4 #endif -// Time it takes in ms for the simulated actuator to move from one state to another. -#define ACTUATOR_MOVEMENT_PERIOS_MS 2000 diff --git a/examples/lock-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/lock-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay index d1d93c9dbf033d..f9fe5b0fd9a950 100644 --- a/examples/lock-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/examples/lock-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -14,11 +14,16 @@ * limitations under the License. */ +#include + / { chosen { nordic,pm-ext-flash = &mx25r64; }; +}; +&ipc0 { + zephyr,priority = <0 PRIO_COOP>; }; /* Disable unused peripherals to reduce power consumption */ diff --git a/examples/lock-app/nrfconnect/main/AppTask.cpp b/examples/lock-app/nrfconnect/main/AppTask.cpp index 77d689971568c4..5e1248cfbd8ae4 100644 --- a/examples/lock-app/nrfconnect/main/AppTask.cpp +++ b/examples/lock-app/nrfconnect/main/AppTask.cpp @@ -48,8 +48,8 @@ #endif #include +#include #include -#include LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); diff --git a/examples/lock-app/nrfconnect/main/include/BoltLockManager.h b/examples/lock-app/nrfconnect/main/include/BoltLockManager.h index 8811723cd8421f..b5b5b66b9b1aef 100644 --- a/examples/lock-app/nrfconnect/main/include/BoltLockManager.h +++ b/examples/lock-app/nrfconnect/main/include/BoltLockManager.h @@ -23,7 +23,7 @@ #include #include -#include +#include #include diff --git a/examples/pigweed-app/nrfconnect/main/main.cpp b/examples/pigweed-app/nrfconnect/main/main.cpp index 9abede4a6f0314..dd092668d4192f 100644 --- a/examples/pigweed-app/nrfconnect/main/main.cpp +++ b/examples/pigweed-app/nrfconnect/main/main.cpp @@ -19,7 +19,7 @@ #include "LEDWidget.h" #include "PigweedLoggerMutex.h" #include "pigweed/RpcService.h" -#include +#include #include "pw_rpc/echo_service_nanopb.h" #include "pw_sys_io/sys_io.h" diff --git a/examples/platform/nrfconnect/pw_sys_io/sys_io_nrfconnect.cc b/examples/platform/nrfconnect/pw_sys_io/sys_io_nrfconnect.cc index f41dce65b59ff7..7c9f3429d12727 100644 --- a/examples/platform/nrfconnect/pw_sys_io/sys_io_nrfconnect.cc +++ b/examples/platform/nrfconnect/pw_sys_io/sys_io_nrfconnect.cc @@ -17,9 +17,9 @@ #include -#include "console/console.h" #include "pw_sys_io/sys_io.h" #include +#include #include #ifdef CONFIG_USB diff --git a/examples/platform/nrfconnect/util/LEDWidget.cpp b/examples/platform/nrfconnect/util/LEDWidget.cpp index eca7765ab0a0d9..56bb9436eece47 100644 --- a/examples/platform/nrfconnect/util/LEDWidget.cpp +++ b/examples/platform/nrfconnect/util/LEDWidget.cpp @@ -20,7 +20,7 @@ #include "LEDWidget.h" #include -#include +#include static LEDWidget::LEDWidgetStateUpdateHandler sStateUpdateCallback; diff --git a/examples/platform/nrfconnect/util/PWMDevice.cpp b/examples/platform/nrfconnect/util/PWMDevice.cpp index 2d17d31e4e703e..d0a77ab63f1800 100644 --- a/examples/platform/nrfconnect/util/PWMDevice.cpp +++ b/examples/platform/nrfconnect/util/PWMDevice.cpp @@ -23,8 +23,8 @@ #include #include +#include #include -#include LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); diff --git a/examples/platform/nrfconnect/util/PigweedLogger.cpp b/examples/platform/nrfconnect/util/PigweedLogger.cpp index 33e7fdc01068bd..851dd445ceff23 100644 --- a/examples/platform/nrfconnect/util/PigweedLogger.cpp +++ b/examples/platform/nrfconnect/util/PigweedLogger.cpp @@ -24,11 +24,11 @@ * needs to use HDLC/UART for another purpose like the RPC server. */ +#include #include #include #include #include -#include #include #include diff --git a/examples/platform/nrfconnect/util/include/DFUOverSMP.h b/examples/platform/nrfconnect/util/include/DFUOverSMP.h index cf839cf166911f..1c5ace635783e1 100644 --- a/examples/platform/nrfconnect/util/include/DFUOverSMP.h +++ b/examples/platform/nrfconnect/util/include/DFUOverSMP.h @@ -25,7 +25,7 @@ #include -#include +#include typedef void (*DFUOverSMPRestartAdvertisingHandler)(void); diff --git a/examples/platform/nrfconnect/util/include/LEDWidget.h b/examples/platform/nrfconnect/util/include/LEDWidget.h index 4859bc9bf048df..aee857ffd91667 100644 --- a/examples/platform/nrfconnect/util/include/LEDWidget.h +++ b/examples/platform/nrfconnect/util/include/LEDWidget.h @@ -20,7 +20,7 @@ #include -#include +#include class LEDWidget { diff --git a/examples/pump-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/pump-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay index 76031564db7950..e52b2072ec1b10 100644 --- a/examples/pump-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/examples/pump-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -14,9 +14,15 @@ * limitations under the License. */ +#include + / { chosen { nordic,pm-ext-flash = &mx25r64; }; +}; +&ipc0 { + zephyr,priority = <0 PRIO_COOP>; }; + diff --git a/examples/pump-app/nrfconnect/main/AppTask.cpp b/examples/pump-app/nrfconnect/main/AppTask.cpp index 14ea81f628e2d6..b6454b09be2871 100644 --- a/examples/pump-app/nrfconnect/main/AppTask.cpp +++ b/examples/pump-app/nrfconnect/main/AppTask.cpp @@ -42,8 +42,8 @@ #endif #include +#include #include -#include LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); diff --git a/examples/pump-app/nrfconnect/main/PumpManager.cpp b/examples/pump-app/nrfconnect/main/PumpManager.cpp index f24bd3262f45b8..1709e19fd32ff2 100644 --- a/examples/pump-app/nrfconnect/main/PumpManager.cpp +++ b/examples/pump-app/nrfconnect/main/PumpManager.cpp @@ -22,8 +22,8 @@ #include "AppConfig.h" #include "AppTask.h" +#include #include -#include LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); diff --git a/examples/pump-controller-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/pump-controller-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay index 76031564db7950..e52b2072ec1b10 100644 --- a/examples/pump-controller-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/examples/pump-controller-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -14,9 +14,15 @@ * limitations under the License. */ +#include + / { chosen { nordic,pm-ext-flash = &mx25r64; }; +}; +&ipc0 { + zephyr,priority = <0 PRIO_COOP>; }; + diff --git a/examples/pump-controller-app/nrfconnect/main/AppTask.cpp b/examples/pump-controller-app/nrfconnect/main/AppTask.cpp index 1e59d9bd6affbe..dd2ce3e4eab5f2 100644 --- a/examples/pump-controller-app/nrfconnect/main/AppTask.cpp +++ b/examples/pump-controller-app/nrfconnect/main/AppTask.cpp @@ -42,8 +42,8 @@ #endif #include +#include #include -#include LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); diff --git a/examples/pump-controller-app/nrfconnect/main/PumpManager.cpp b/examples/pump-controller-app/nrfconnect/main/PumpManager.cpp index 2b6215dc896938..64e848a56a312d 100644 --- a/examples/pump-controller-app/nrfconnect/main/PumpManager.cpp +++ b/examples/pump-controller-app/nrfconnect/main/PumpManager.cpp @@ -22,8 +22,8 @@ #include "AppConfig.h" #include "AppTask.h" +#include #include -#include LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); diff --git a/examples/window-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay b/examples/window-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay index f4559366c7df5c..d80b32f787a3cc 100644 --- a/examples/window-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay +++ b/examples/window-app/nrfconnect/boards/nrf5340dk_nrf5340_cpuapp.overlay @@ -14,6 +14,8 @@ * limitations under the License. */ +#include + / { chosen { nordic,pm-ext-flash = &mx25r64; @@ -37,9 +39,11 @@ pwms = <&pwm0 2 PWM_MSEC(20) PWM_POLARITY_INVERTED>; }; }; - }; +&ipc0 { + zephyr,priority = <0 PRIO_COOP>; +}; /* Disable unused peripherals to reduce power consumption */ &adc { diff --git a/examples/window-app/nrfconnect/main/AppTask.cpp b/examples/window-app/nrfconnect/main/AppTask.cpp index 212a3c8ce3e302..753149b19233e0 100644 --- a/examples/window-app/nrfconnect/main/AppTask.cpp +++ b/examples/window-app/nrfconnect/main/AppTask.cpp @@ -38,8 +38,8 @@ #endif #include +#include #include -#include LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); diff --git a/examples/window-app/nrfconnect/main/WindowCovering.cpp b/examples/window-app/nrfconnect/main/WindowCovering.cpp index 96320a6e92e189..13f22ad848a16f 100644 --- a/examples/window-app/nrfconnect/main/WindowCovering.cpp +++ b/examples/window-app/nrfconnect/main/WindowCovering.cpp @@ -24,8 +24,8 @@ #include #include #include +#include #include -#include LOG_MODULE_DECLARE(app, CONFIG_CHIP_APP_LOG_LEVEL); diff --git a/integrations/cloudbuild/build-all.yaml b/integrations/cloudbuild/build-all.yaml index 378112e497ce95..4c4df463b3b69a 100644 --- a/integrations/cloudbuild/build-all.yaml +++ b/integrations/cloudbuild/build-all.yaml @@ -76,8 +76,7 @@ steps: --target k32w-shell build --create-archives /workspace/artifacts/ - # TODO: update this to connectedhomeip/chip-build-vscode:0.6.30 once we can compile with latest NRF - - name: "connectedhomeip/chip-build-vscode:0.6.18" + - name: "connectedhomeip/chip-build-vscode:0.6.30" env: - PW_ENVIRONMENT_ROOT=/pwenv args: diff --git a/integrations/cloudbuild/smoke-test.yaml b/integrations/cloudbuild/smoke-test.yaml index a17fd6f35ade60..db2dd9c0269c66 100644 --- a/integrations/cloudbuild/smoke-test.yaml +++ b/integrations/cloudbuild/smoke-test.yaml @@ -40,9 +40,7 @@ steps: volumes: - name: pwenv path: /pwenv - - # TODO: update this to connectedhomeip/chip-build-vscode:0.6.30 once we can compile with latest NRF - - name: "connectedhomeip/chip-build-vscode:0.6.18" + - name: "connectedhomeip/chip-build-vscode:0.6.30" id: NRFConnect env: - PW_ENVIRONMENT_ROOT=/pwenv diff --git a/scripts/build/builders/nrf.py b/scripts/build/builders/nrf.py index 4f3b895f638c47..a1e7c457ea6ee2 100644 --- a/scripts/build/builders/nrf.py +++ b/scripts/build/builders/nrf.py @@ -147,13 +147,21 @@ def __init__(self, def generate(self): if not os.path.exists(self.output_dir): - # NRF does a in-place update of SDK tools + zephyr_sdk_dir = None + if not self._runner.dry_run: if 'ZEPHYR_BASE' not in os.environ: raise Exception("NRF builds require ZEPHYR_BASE to be set") + # Users are expected to set ZEPHYR_SDK_INSTALL_DIR but additionally cover the Docker + # case by inferring ZEPHYR_SDK_INSTALL_DIR from NRF5_TOOLS_ROOT. + if not os.environ.get('ZEPHYR_SDK_INSTALL_DIR') and not os.environ.get('NRF5_TOOLS_ROOT'): + raise Exception("NRF buils require ZEPHYR_SDK_INSTALL_DIR to be set") + zephyr_base = os.environ['ZEPHYR_BASE'] nrfconnect_sdk = os.path.dirname(zephyr_base) + zephyr_sdk_dir = os.environ.get('ZEPHYR_SDK_INSTALL_DIR') or os.path.join( + os.environ['NRF5_TOOLS_ROOT'], 'zephyr-sdk-0.15.2') # NRF builds will both try to change .west/config in nrfconnect and # overall perform a git fetch on that location @@ -186,7 +194,12 @@ def generate(self): cmd = ''' source "$ZEPHYR_BASE/zephyr-env.sh"; -export GNUARMEMB_TOOLCHAIN_PATH="$PW_ARM_CIPD_INSTALL_DIR"; +export ZEPHYR_TOOLCHAIN_VARIANT=zephyr;''' + if zephyr_sdk_dir: + cmd += f''' +export ZEPHYR_SDK_INSTALL_DIR={zephyr_sdk_dir};''' + + cmd += ''' west build --cmake-only -d {outdir} -b {board} {sourcedir}{build_flags} '''.format( outdir=shlex.quote(self.output_dir), @@ -194,8 +207,8 @@ def generate(self): sourcedir=shlex.quote(os.path.join( self.root, self.app.AppPath(), 'nrfconnect')), build_flags=build_flags - ).strip() - self._Execute(['bash', '-c', cmd], + ) + self._Execute(['bash', '-c', cmd.strip()], title='Generating ' + self.identifier) def _build(self): diff --git a/scripts/build/testdata/dry_run_nrf-nrf52840dk-pump.txt b/scripts/build/testdata/dry_run_nrf-nrf52840dk-pump.txt index e0b4d31e73bb26..500826f734eee9 100644 --- a/scripts/build/testdata/dry_run_nrf-nrf52840dk-pump.txt +++ b/scripts/build/testdata/dry_run_nrf-nrf52840dk-pump.txt @@ -3,7 +3,7 @@ cd "{root}" # Generating nrf-nrf52840dk-pump bash -c 'source "$ZEPHYR_BASE/zephyr-env.sh"; -export GNUARMEMB_TOOLCHAIN_PATH="$PW_ARM_CIPD_INSTALL_DIR"; +export ZEPHYR_TOOLCHAIN_VARIANT=zephyr; west build --cmake-only -d {out}/nrf-nrf52840dk-pump -b nrf52840dk_nrf52840 {root}/examples/pump-app/nrfconnect' # Building nrf-nrf52840dk-pump diff --git a/scripts/examples/nrfconnect_example.sh b/scripts/examples/nrfconnect_example.sh index 9c2ffa69380f75..072ecada10a2db 100755 --- a/scripts/examples/nrfconnect_example.sh +++ b/scripts/examples/nrfconnect_example.sh @@ -40,8 +40,12 @@ source "../scripts/activate.sh" # Activate Zephyr environment [[ -n $ZEPHYR_BASE ]] && source "$ZEPHYR_BASE/zephyr-env.sh" -# Use toolchain from Pigweed CIPD -export GNUARMEMB_TOOLCHAIN_PATH="$PW_ARM_CIPD_INSTALL_DIR" +# Use Zephyr SDK toolchain +export ZEPHYR_TOOLCHAIN_VARIANT=zephyr + +if [[ -z "$ZEPHYR_SDK_INSTALL_DIR" && -n "$NRF5_TOOLS_ROOT" ]]; then + export ZEPHYR_SDK_INSTALL_DIR="$NRF5_TOOLS_ROOT"/zephyr-sdk-0.15.2 +fi # Set ccache base directory to improve the cache hit ratio export CCACHE_BASEDIR="$PWD/$APP/nrfconnect" diff --git a/src/include/platform/internal/GenericPlatformManagerImpl_Zephyr.h b/src/include/platform/internal/GenericPlatformManagerImpl_Zephyr.h index c3f1de4dde19cb..88d98ec9613d92 100644 --- a/src/include/platform/internal/GenericPlatformManagerImpl_Zephyr.h +++ b/src/include/platform/internal/GenericPlatformManagerImpl_Zephyr.h @@ -27,7 +27,7 @@ #include #include -#include +#include namespace chip { namespace DeviceLayer { diff --git a/src/platform/Zephyr/BLEManagerImpl.cpp b/src/platform/Zephyr/BLEManagerImpl.cpp index 88edbd3da061f5..d4639f8ea94aa7 100644 --- a/src/platform/Zephyr/BLEManagerImpl.cpp +++ b/src/platform/Zephyr/BLEManagerImpl.cpp @@ -37,11 +37,11 @@ #include #endif -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include using namespace ::chip; using namespace ::chip::Ble; diff --git a/src/platform/Zephyr/BLEManagerImpl.h b/src/platform/Zephyr/BLEManagerImpl.h index a99847c9f90168..fae4799bda75e3 100644 --- a/src/platform/Zephyr/BLEManagerImpl.h +++ b/src/platform/Zephyr/BLEManagerImpl.h @@ -25,9 +25,9 @@ #if CHIP_DEVICE_CONFIG_ENABLE_CHIPOBLE -#include -#include -#include +#include +#include +#include #include diff --git a/src/platform/Zephyr/KeyValueStoreManagerImpl.h b/src/platform/Zephyr/KeyValueStoreManagerImpl.h index 1d4ee7d1f10fbf..de8707f32a7f97 100644 --- a/src/platform/Zephyr/KeyValueStoreManagerImpl.h +++ b/src/platform/Zephyr/KeyValueStoreManagerImpl.h @@ -24,7 +24,7 @@ #pragma once -#include +#include namespace chip { namespace DeviceLayer { diff --git a/src/platform/Zephyr/NFCManagerImpl.cpp b/src/platform/Zephyr/NFCManagerImpl.cpp index 53856af6b153b5..dd28457af12198 100644 --- a/src/platform/Zephyr/NFCManagerImpl.cpp +++ b/src/platform/Zephyr/NFCManagerImpl.cpp @@ -26,7 +26,7 @@ #include #include #include -#include +#include namespace chip { namespace DeviceLayer { diff --git a/src/platform/Zephyr/SysHeapMalloc.cpp b/src/platform/Zephyr/SysHeapMalloc.cpp index e65ec8a44b7c7a..1a80fadd1835a7 100644 --- a/src/platform/Zephyr/SysHeapMalloc.cpp +++ b/src/platform/Zephyr/SysHeapMalloc.cpp @@ -21,10 +21,10 @@ #include extern "C" { -#include -#include -#include -#include +#include +#include +#include +#include } #include @@ -131,7 +131,7 @@ CHIP_ERROR GetStats(Stats & stats) LockGuard lockGuard; ReturnErrorOnFailure(lockGuard.Error()); - sys_heap_runtime_stats sysHeapStats; + sys_memory_stats sysHeapStats; ReturnErrorOnFailure(System::MapErrorZephyr(sys_heap_runtime_stats_get(&sHeap, &sysHeapStats))); stats.free = sysHeapStats.free_bytes; diff --git a/src/platform/Zephyr/SystemTimeSupport.cpp b/src/platform/Zephyr/SystemTimeSupport.cpp index 90b63aded60b08..c9ebdf7da2c31d 100644 --- a/src/platform/Zephyr/SystemTimeSupport.cpp +++ b/src/platform/Zephyr/SystemTimeSupport.cpp @@ -26,7 +26,7 @@ #include -#include +#include #if !CHIP_SYSTEM_CONFIG_USE_POSIX_TIME_FUNCTS diff --git a/src/platform/Zephyr/ThreadStackManagerImpl.h b/src/platform/Zephyr/ThreadStackManagerImpl.h index 6600554a1966bd..d9a9020dfadf5c 100644 --- a/src/platform/Zephyr/ThreadStackManagerImpl.h +++ b/src/platform/Zephyr/ThreadStackManagerImpl.h @@ -25,8 +25,8 @@ #include +#include #include -#include #include #if !CONFIG_SOC_SERIES_RISCV_TELINK_B91 diff --git a/src/platform/nrfconnect/DiagnosticDataProviderImplNrf.cpp b/src/platform/nrfconnect/DiagnosticDataProviderImplNrf.cpp index 5f7bc1a6702b4e..e7326edd91f2fa 100644 --- a/src/platform/nrfconnect/DiagnosticDataProviderImplNrf.cpp +++ b/src/platform/nrfconnect/DiagnosticDataProviderImplNrf.cpp @@ -71,9 +71,7 @@ CHIP_ERROR DiagnosticDataProviderImplNrf::GetWiFiChannelNumber(uint16_t & channe 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; + return err; } CHIP_ERROR DiagnosticDataProviderImplNrf::GetWiFiRssi(int8_t & rssi) @@ -81,9 +79,7 @@ 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; + return err; } // below will be implemented when the WiFi driver exposes Zephyr NET_STATISTICS API diff --git a/src/platform/nrfconnect/FactoryDataParser.c b/src/platform/nrfconnect/FactoryDataParser.c index 19601887175bd6..85caee5f9ac6b2 100644 --- a/src/platform/nrfconnect/FactoryDataParser.c +++ b/src/platform/nrfconnect/FactoryDataParser.c @@ -17,8 +17,8 @@ #include "FactoryDataParser.h" -#include #include +#include #include #include diff --git a/src/platform/nrfconnect/FactoryDataProvider.cpp b/src/platform/nrfconnect/FactoryDataProvider.cpp index cd52046c6de4f8..200b8fac0f33e8 100644 --- a/src/platform/nrfconnect/FactoryDataProvider.cpp +++ b/src/platform/nrfconnect/FactoryDataProvider.cpp @@ -24,7 +24,7 @@ #include #endif -#include +#include namespace chip { namespace { diff --git a/src/platform/nrfconnect/FactoryDataProvider.h b/src/platform/nrfconnect/FactoryDataProvider.h index 3d46076a5a3669..c5517917cddde6 100644 --- a/src/platform/nrfconnect/FactoryDataProvider.h +++ b/src/platform/nrfconnect/FactoryDataProvider.h @@ -21,10 +21,10 @@ #include #include -#include #include #include #include +#include #include "FactoryDataParser.h" diff --git a/src/platform/nrfconnect/OTAImageProcessorImpl.cpp b/src/platform/nrfconnect/OTAImageProcessorImpl.cpp index 0daf01cb892d15..7448ffeb1bf16d 100644 --- a/src/platform/nrfconnect/OTAImageProcessorImpl.cpp +++ b/src/platform/nrfconnect/OTAImageProcessorImpl.cpp @@ -28,15 +28,15 @@ #if CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE #include #include -#include +#include #endif #include #include #include -#include -#include -#include +#include +#include +#include #if CONFIG_CHIP_CERTIFICATION_DECLARATION_STORAGE // Cd globals are needed to be accessed from dfu image writer lambdas diff --git a/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.cpp b/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.cpp index 73e16303a03bc5..b3bdede0f2f852 100644 --- a/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.cpp +++ b/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.cpp @@ -52,27 +52,9 @@ ConnectivityManager::WiFiStationMode ConnectivityManagerImplWiFi::_GetWiFiStatio CHIP_ERROR ConnectivityManagerImplWiFi::_SetWiFiStationMode(ConnectivityManager::WiFiStationMode aMode) { - VerifyOrReturnError(ConnectivityManager::WiFiStationMode::kWiFiStationMode_NotSupported != aMode, - CHIP_ERROR_UNSUPPORTED_CHIP_FEATURE); + VerifyOrReturnError(ConnectivityManager::WiFiStationMode::kWiFiStationMode_NotSupported != aMode, CHIP_ERROR_INVALID_ARGUMENT); - 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(); - } - } - } + mStationMode = aMode; return CHIP_NO_ERROR; } @@ -89,7 +71,7 @@ bool ConnectivityManagerImplWiFi::_IsWiFiStationApplicationControlled(void) bool ConnectivityManagerImplWiFi::_IsWiFiStationConnected(void) { - return (WiFiManager::StationStatus::FULLY_PROVISIONED == WiFiManager().Instance().GetStationStatus()); + return (WiFiManager::StationStatus::CONNECTED == WiFiManager().Instance().GetStationStatus()); } System::Clock::Timeout ConnectivityManagerImplWiFi::_GetWiFiStationReconnectInterval(void) @@ -141,38 +123,6 @@ CHIP_ERROR ConnectivityManagerImplWiFi::_GetAndLogWiFiStatsCounters(void) 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 */ diff --git a/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.h b/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.h index 8198453038417a..dfa6a05f0b7ae4 100644 --- a/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.h +++ b/src/platform/nrfconnect/wifi/ConnectivityManagerImplWiFi.h @@ -54,8 +54,6 @@ class ConnectivityManagerImplWiFi bool _CanStartWiFiScan(); void _OnWiFiScanDone(); void _OnWiFiStationProvisionChange(); - void OnStationConnected(); - void OnStationDisconnected(); // Wi-Fi access point - not supported ConnectivityManager::WiFiAPMode _GetWiFiAPMode(void); diff --git a/src/platform/nrfconnect/wifi/NrfWiFiDriver.cpp b/src/platform/nrfconnect/wifi/NrfWiFiDriver.cpp index 5092384006fca0..e8e5d10d73ae97 100644 --- a/src/platform/nrfconnect/wifi/NrfWiFiDriver.cpp +++ b/src/platform/nrfconnect/wifi/NrfWiFiDriver.cpp @@ -17,7 +17,6 @@ #include "NrfWiFiDriver.h" -#include "WiFiManager.h" #include #include @@ -27,6 +26,7 @@ using namespace ::chip; using namespace ::chip::DeviceLayer::Internal; using namespace ::chip::DeviceLayer::PersistedStorage; +using namespace ::chip::app::Clusters::NetworkCommissioning; namespace chip { namespace DeviceLayer { @@ -105,7 +105,7 @@ CHIP_ERROR NrfWiFiDriver::Init(NetworkStatusChangeCallback * networkStatusChange { WiFiManager::ConnectionHandling handling{ [] { Instance().OnNetworkStatusChanged(Status::kSuccess); }, [] { Instance().OnNetworkStatusChanged(Status::kUnknownError); }, - System::Clock::Timeout{ 40000 } }; + System::Clock::Seconds32{ kWiFiConnectNetworkTimeoutSeconds } }; ReturnErrorOnFailure( WiFiManager::Instance().Connect(mStagingNetwork.GetSsidSpan(), mStagingNetwork.GetPassSpan(), handling)); } @@ -121,7 +121,15 @@ void NrfWiFiDriver::OnNetworkStatusChanged(Status status) } if (mpNetworkStatusChangeCallback) + { mpNetworkStatusChangeCallback->OnNetworkingStatusChange(status, NullOptional, NullOptional); + } + + if (mpConnectCallback) + { + mpConnectCallback->OnResult(status, CharSpan(), 0); + mpConnectCallback = nullptr; + } } void NrfWiFiDriver::Shutdown() @@ -141,11 +149,24 @@ CHIP_ERROR NrfWiFiDriver::RevertConfiguration() { LoadFromStorage(); + if (WiFiManager::StationStatus::CONNECTING <= WiFiManager::Instance().GetStationStatus()) + { + WiFiManager::WiFiInfo wifiInfo; + ReturnErrorOnFailure(WiFiManager::Instance().GetWiFiInfo(wifiInfo)); + if (mStagingNetwork.GetSsidSpan().data_equal(ByteSpan(wifiInfo.mSsid, wifiInfo.mSsidLen))) + { + // we are already connected to this network, so return prematurely + return CHIP_NO_ERROR; + } + + WiFiManager::Instance().Disconnect(); + } + if (mStagingNetwork.IsConfigured()) { - WiFiManager::ConnectionHandling handling{ [] { Instance().OnConnectWiFiNetwork(); }, - [] { Instance().OnConnectWiFiNetworkFailed(); }, - System::Clock::Timeout{ 40000 } }; + WiFiManager::ConnectionHandling handling{ [] { Instance().OnNetworkStatusChanged(Status::kSuccess); }, + [] { Instance().OnNetworkStatusChanged(Status::kUnknownError); }, + System::Clock::Seconds32{ kWiFiConnectNetworkTimeoutSeconds } }; ReturnErrorOnFailure( WiFiManager::Instance().Connect(mStagingNetwork.GetSsidSpan(), mStagingNetwork.GetPassSpan(), handling)); } @@ -163,6 +184,7 @@ Status NrfWiFiDriver::AddOrUpdateNetwork(ByteSpan ssid, ByteSpan credentials, Mu VerifyOrReturnError(ssid.size() <= sizeof(mStagingNetwork.ssid), Status::kOutOfRange); VerifyOrReturnError(credentials.size() <= sizeof(mStagingNetwork.pass), Status::kOutOfRange); + mStagingNetwork.Erase(); memcpy(mStagingNetwork.ssid, ssid.data(), ssid.size()); memcpy(mStagingNetwork.pass, credentials.data(), credentials.size()); mStagingNetwork.ssidLen = ssid.size(); @@ -196,9 +218,12 @@ Status NrfWiFiDriver::ReorderNetwork(ByteSpan networkId, uint8_t index, MutableC void NrfWiFiDriver::ConnectNetwork(ByteSpan networkId, ConnectCallback * callback) { Status status = Status::kSuccess; - WiFiManager::ConnectionHandling handling{ [] { Instance().OnConnectWiFiNetwork(); }, - [] { Instance().OnConnectWiFiNetworkFailed(); }, System::Clock::Timeout{ 40000 } }; + WiFiManager::ConnectionHandling handling{ [] { Instance().OnNetworkStatusChanged(Status::kSuccess); }, + [] { Instance().OnNetworkStatusChanged(Status::kUnknownError); }, + System::Clock::Seconds32{ kWiFiConnectNetworkTimeoutSeconds } }; + VerifyOrExit(WiFiManager::StationStatus::CONNECTING != WiFiManager::Instance().GetStationStatus(), + status = Status::kOtherConnectionFailure); VerifyOrExit(networkId.data_equal(mStagingNetwork.GetSsidSpan()), status = Status::kNetworkIDNotFound); VerifyOrExit(mpConnectCallback == nullptr, status = Status::kUnknownError); @@ -206,43 +231,42 @@ void NrfWiFiDriver::ConnectNetwork(ByteSpan networkId, ConnectCallback * callbac WiFiManager::Instance().Connect(mStagingNetwork.GetSsidSpan(), mStagingNetwork.GetPassSpan(), handling); exit: - if (status != Status::kSuccess) + if (status != Status::kSuccess && mpConnectCallback) { + mpConnectCallback->OnResult(status, CharSpan(), 0); mpConnectCallback = nullptr; - callback->OnResult(status, CharSpan(), 0); } } -CHIP_ERROR GetConfiguredNetwork(Network & network) +void NrfWiFiDriver::LoadFromStorage() { - return CHIP_NO_ERROR; + WiFiManager::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; } -void NrfWiFiDriver::OnConnectWiFiNetwork() +void NrfWiFiDriver::OnScanWiFiNetworkDone(WiFiManager::WiFiRequestStatus status) { - ConnectivityMgr().SetWiFiStationMode(ConnectivityManager::kWiFiStationMode_Enabled); - - if (mpConnectCallback) - { - mpConnectCallback->OnResult(Status::kSuccess, CharSpan(), 0); - mpConnectCallback = nullptr; - } + VerifyOrReturn(mScanCallback != nullptr); + mScanCallback->OnFinished(status == WiFiManager::WiFiRequestStatus::SUCCESS ? Status::kSuccess : Status::kUnknownError, + CharSpan(), &mScanResponseIterator); + mScanCallback = nullptr; } -void NrfWiFiDriver::OnConnectWiFiNetworkFailed() +void NrfWiFiDriver::OnScanWiFiNetworkResult(const WiFiScanResponse & response) { - if (mpConnectCallback) - { - mpConnectCallback->OnResult(Status::kNetworkNotFound, CharSpan(), 0); - mpConnectCallback = nullptr; - } + mScanResponseIterator.Add(response); } 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); }); + ssid, [](const WiFiScanResponse & response) { Instance().OnScanWiFiNetworkResult(response); }, + [](WiFiManager::WiFiRequestStatus status) { Instance().OnScanWiFiNetworkDone(status); }); if (error != CHIP_NO_ERROR) { @@ -251,34 +275,6 @@ void NrfWiFiDriver::ScanNetworks(ByteSpan ssid, WiFiDriver::ScanCallback * callb } } -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 index 880cce80b69171..7b57607b306822 100644 --- a/src/platform/nrfconnect/wifi/NrfWiFiDriver.h +++ b/src/platform/nrfconnect/wifi/NrfWiFiDriver.h @@ -16,6 +16,9 @@ */ #pragma once + +#include "WiFiManager.h" + #include namespace chip { @@ -24,7 +27,7 @@ namespace NetworkCommissioning { constexpr uint8_t kMaxWiFiNetworks = 1; constexpr uint8_t kWiFiScanNetworksTimeOutSeconds = 10; -constexpr uint8_t kWiFiConnectNetworkTimeoutSeconds = 120; +constexpr uint8_t kWiFiConnectNetworkTimeoutSeconds = 35; class NrfWiFiScanResponseIterator : public Iterator { @@ -62,19 +65,6 @@ class NrfWiFiDriver final : public WiFiDriver bool mExhausted{ false }; }; - 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; @@ -103,17 +93,16 @@ class NrfWiFiDriver final : public WiFiDriver return sInstance; } - void OnConnectWiFiNetwork(); - void OnConnectWiFiNetworkFailed(); void OnNetworkStatusChanged(Status status); - void OnScanWiFiNetworkDone(int status, WiFiScanResponse * result); + void OnScanWiFiNetworkResult(const WiFiScanResponse & result); + void OnScanWiFiNetworkDone(WiFiManager::WiFiRequestStatus status); private: void LoadFromStorage(); ConnectCallback * mpConnectCallback{ nullptr }; NetworkStatusChangeCallback * mpNetworkStatusChangeCallback{ nullptr }; - WiFiNetwork mStagingNetwork; + WiFiManager::WiFiNetwork mStagingNetwork; NrfWiFiScanResponseIterator mScanResponseIterator; ScanCallback * mScanCallback{ nullptr }; }; diff --git a/src/platform/nrfconnect/wifi/WiFiManager.cpp b/src/platform/nrfconnect/wifi/WiFiManager.cpp index 7c2313f09014e8..a47655c0fa9624 100644 --- a/src/platform/nrfconnect/wifi/WiFiManager.cpp +++ b/src/platform/nrfconnect/wifi/WiFiManager.cpp @@ -22,33 +22,35 @@ #include "WiFiManager.h" +#include #include #include #include #include #include -#include -#include +#include +#include +#include +#include extern "C" { #include #include #include #include -#include -} - -extern struct wpa_global * global; -static struct wpa_supplicant * wpa_s; +// extern function to obtain bssid from status buffer +// It is defined in zephyr/subsys/net/ip/utils.c +extern char * net_sprint_ll_addr_buf(const uint8_t * ll, uint8_t ll_len, char * buf, int buflen); +} namespace chip { namespace DeviceLayer { namespace { -NetworkCommissioning::WiFiScanResponse ToScanResponse(wifi_scan_result * result) +NetworkCommissioning::WiFiScanResponse ToScanResponse(const wifi_scan_result * result) { NetworkCommissioning::WiFiScanResponse response = {}; @@ -73,49 +75,50 @@ NetworkCommissioning::WiFiScanResponse ToScanResponse(wifi_scan_result * result) } // 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() +const Map + WiFiManager::sStatusMap({ { WIFI_STATE_DISCONNECTED, WiFiManager::StationStatus::DISCONNECTED }, + { WIFI_STATE_INTERFACE_DISABLED, WiFiManager::StationStatus::DISABLED }, + { WIFI_STATE_INACTIVE, WiFiManager::StationStatus::DISABLED }, + { WIFI_STATE_SCANNING, WiFiManager::StationStatus::SCANNING }, + { WIFI_STATE_AUTHENTICATING, WiFiManager::StationStatus::CONNECTING }, + { WIFI_STATE_ASSOCIATING, WiFiManager::StationStatus::CONNECTING }, + { WIFI_STATE_ASSOCIATED, WiFiManager::StationStatus::CONNECTED }, + { WIFI_STATE_4WAY_HANDSHAKE, WiFiManager::StationStatus::PROVISIONING }, + { WIFI_STATE_GROUP_HANDSHAKE, WiFiManager::StationStatus::PROVISIONING }, + { WIFI_STATE_COMPLETED, WiFiManager::StationStatus::FULLY_PROVISIONED } }); + +const Map + WiFiManager::sEventHandlerMap({ { NET_EVENT_WIFI_SCAN_RESULT, WiFiManager::ScanResultHandler }, + { NET_EVENT_WIFI_SCAN_DONE, WiFiManager::ScanDoneHandler }, + { NET_EVENT_WIFI_CONNECT_RESULT, WiFiManager::ConnectHandler }, + { NET_EVENT_WIFI_DISCONNECT_RESULT, WiFiManager::DisconnectHandler } }); + +void WiFiManager::WifiMgmtEventHandler(net_mgmt_event_callback * cb, uint32_t mgmtEvent, net_if * iface) { - // wpa_supplicant instance is initialized in dedicated supplicant thread, so wait until - // the initialization is completed. - // TODO: fix thread-safety of the solution. - constexpr size_t kInitTimeoutMs = 5000; - const int64_t initStartTime = k_uptime_get(); - // TODO: Handle multiple VIFs - const char * ifname = "wlan0"; - - while (!global || !(wpa_s = wpa_supplicant_get_iface(global, ifname))) + if (0 == strcmp(iface->if_dev->dev->name, "wlan0")) { - if (k_uptime_get() > initStartTime + kInitTimeoutMs) + Platform::UniquePtr eventData(new uint8_t[cb->info_length]); + VerifyOrReturn(eventData); + memcpy(eventData.get(), cb->info, cb->info_length); + CHIP_ERROR status = SystemLayer().ScheduleLambda([data = eventData.get(), mgmtEvent]() { + if (data) + { + sEventHandlerMap[mgmtEvent](data); + // cleanup + delete[] data; + } + }); + + if (CHIP_NO_ERROR == status) { - ChipLogError(DeviceLayer, "wpa_supplicant is not initialized!"); - return CHIP_ERROR_INTERNAL; + // the ownership has been transferred to the worker thread - release the buffer + eventData.release(); } - - k_msleep(200); } +} +CHIP_ERROR WiFiManager::Init() +{ // 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); @@ -145,302 +148,289 @@ CHIP_ERROR WiFiManager::Init() return CHIP_NO_ERROR; }); - ChipLogDetail(DeviceLayer, "wpa_supplicant has been initialized"); + net_mgmt_init_event_callback(&mWiFiMgmtClbk, WifiMgmtEventHandler, kWifiManagementEvents); + net_mgmt_add_event_callback(&mWiFiMgmtClbk); + + ChipLogDetail(DeviceLayer, "WiFiManager has been initialized"); return CHIP_NO_ERROR; } - -CHIP_ERROR WiFiManager::AddNetwork(const ByteSpan & ssid, const ByteSpan & credentials) +CHIP_ERROR WiFiManager::Scan(const ByteSpan & ssid, ScanResultCallback resultCallback, ScanDoneCallback doneCallback, + bool internalScan) { - ChipLogDetail(DeviceLayer, "Adding WiFi network"); - mpWpaNetwork = wpa_supplicant_add_network(wpa_s); - if (mpWpaNetwork) - { - static constexpr size_t kMaxSsidLen{ 32 }; - mpWpaNetwork->ssid = (u8 *) k_malloc(kMaxSsidLen); + net_if * iface = InetUtils::GetInterface(); + VerifyOrReturnError(nullptr != iface, CHIP_ERROR_INTERNAL); - 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->conf->filter_ssids = 1; + mInternalScan = internalScan; + mScanResultCallback = resultCallback; + mScanDoneCallback = doneCallback; + mWiFiState = WIFI_STATE_SCANNING; - return AddPsk(credentials); - } + if (net_mgmt(NET_REQUEST_WIFI_SCAN, iface, NULL, 0)) + { + ChipLogError(DeviceLayer, "Scan request failed"); + return CHIP_ERROR_INTERNAL; } - return CHIP_ERROR_INTERNAL; + ChipLogDetail(DeviceLayer, "WiFi scanning started..."); + + return CHIP_NO_ERROR; } -CHIP_ERROR WiFiManager::Scan(const ByteSpan & ssid, ScanCallback callback) +CHIP_ERROR WiFiManager::ClearStationProvisioningData() { - 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 net_wifi_mgmt_offload * 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->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); - + mWiFiParams.mRssi = std::numeric_limits::min(); + memset(&mWiFiParams.mParams, 0, sizeof(mWiFiParams.mParams)); return CHIP_NO_ERROR; } CHIP_ERROR WiFiManager::Connect(const ByteSpan & ssid, const ByteSpan & credentials, const ConnectionHandling & handling) { - ChipLogDetail(DeviceLayer, "Connecting to WiFi network"); + ChipLogDetail(DeviceLayer, "Connecting to WiFi network: %*s", ssid.size(), ssid.data()); - mConnectionSuccessClbk = handling.mOnConnectionSuccess; - mConnectionFailedClbk = handling.mOnConnectionFailed; - mConnectionTimeoutMs = handling.mConnectionTimeoutMs; + mHandling.mOnConnectionSuccess = handling.mOnConnectionSuccess; + mHandling.mOnConnectionFailed = handling.mOnConnectionFailed; + mHandling.mConnectionTimeout = handling.mConnectionTimeout; - CHIP_ERROR err = AddNetwork(ssid, credentials); - if (CHIP_NO_ERROR == err) - { - EnableStation(true); - wpa_supplicant_select_network(wpa_s, mpWpaNetwork); - WaitForConnectionAsync(); - } - else - { - OnConnectionFailed(); - } - return err; -} + mWiFiState = WIFI_STATE_ASSOCIATING; -void WiFiManager::OnConnectionSuccess() -{ - if (mConnectionSuccessClbk) - mConnectionSuccessClbk(); -} + // Store SSID and credentials and perform the scan to detect the security mode supported by the AP. + // Zephyr WiFi connect request will be issued in the callback when we have the SSID match. + mWantedNetwork.Erase(); + memcpy(mWantedNetwork.ssid, ssid.data(), ssid.size()); + memcpy(mWantedNetwork.pass, credentials.data(), credentials.size()); + mWantedNetwork.ssidLen = ssid.size(); + mWantedNetwork.passLen = credentials.size(); -void WiFiManager::OnConnectionFailed() -{ - if (mConnectionFailedClbk) - mConnectionFailedClbk(); + return Scan(ssid, nullptr, nullptr, true /* internal scan */); } -CHIP_ERROR WiFiManager::AddPsk(const ByteSpan & credentials) +CHIP_ERROR WiFiManager::Disconnect() { - 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; - } + net_if * iface = InetUtils::GetInterface(); + VerifyOrReturnError(nullptr != iface, CHIP_ERROR_INTERNAL); - return CHIP_ERROR_INTERNAL; -} + int status = net_mgmt(NET_REQUEST_WIFI_DISCONNECT, iface, NULL, 0); -WiFiManager::StationStatus WiFiManager::GetStationStatus() const -{ - if (wpa_s) + if (status) { - return StatusFromWpaStatus(wpa_s->wpa_state); + if (status == -EALREADY) + { + ChipLogDetail(DeviceLayer, "Already disconnected"); + } + else + { + ChipLogDetail(DeviceLayer, "Disconnect request failed"); + return CHIP_ERROR_INTERNAL; + } } else { - ChipLogError(DeviceLayer, "wpa_supplicant is not initialized!"); - return StationStatus::NONE; + ChipLogDetail(DeviceLayer, "Disconnect requested"); } -} -WiFiManager::StationStatus WiFiManager::StatusFromWpaStatus(const wpa_states & status) -{ - ChipLogDetail(DeviceLayer, "WPA internal status: %d", static_cast(status)); - return WiFiManager::sStatusMap[status]; + return CHIP_NO_ERROR; } -CHIP_ERROR WiFiManager::EnableStation(bool enable) +CHIP_ERROR WiFiManager::GetWiFiInfo(WiFiInfo & info) const { - VerifyOrReturnError(nullptr != wpa_s && nullptr != mpWpaNetwork, CHIP_ERROR_INTERNAL); - if (enable) + net_if * iface = InetUtils::GetInterface(); + VerifyOrReturnError(nullptr != iface, CHIP_ERROR_INTERNAL); + struct wifi_iface_status status = { 0 }; + + if (net_mgmt(NET_REQUEST_WIFI_IFACE_STATUS, iface, &status, sizeof(struct wifi_iface_status))) { - wpa_supplicant_enable_network(wpa_s, mpWpaNetwork); + ChipLogError(DeviceLayer, "Status request failed"); + return CHIP_ERROR_INTERNAL; } - else + + if (status.state >= WIFI_STATE_ASSOCIATED) { - wpa_supplicant_disable_network(wpa_s, mpWpaNetwork); + uint8_t mac_string_buf[sizeof("xx:xx:xx:xx:xx:xx")]; + net_sprint_ll_addr_buf(reinterpret_cast(status.bssid), WIFI_MAC_ADDR_LEN, + reinterpret_cast(mac_string_buf), sizeof(mac_string_buf)); + info.mBssId = ByteSpan(mac_string_buf, sizeof(mac_string_buf)); + info.mSecurityType = static_cast(status.security); + info.mWiFiVersion = static_cast(status.link_mode); + info.mRssi = status.rssi; + info.mChannel = status.channel; + info.mSsidLen = status.ssid_len; + memcpy(info.mSsid, status.ssid, status.ssid_len); + + return CHIP_NO_ERROR; } - return CHIP_NO_ERROR; + return CHIP_ERROR_INTERNAL; } -CHIP_ERROR WiFiManager::ClearStationProvisioningData() +CHIP_ERROR WiFiManager::GetNetworkStatistics(NetworkStatistics & stats) const { - VerifyOrReturnError(nullptr != wpa_s && nullptr != mpWpaNetwork, CHIP_ERROR_INTERNAL); - wpa_supplicant_cancel_scan(wpa_s); - wpa_clear_keys(wpa_s, mpWpaNetwork->bssid); - str_clear_free(mpWpaNetwork->passphrase); - wpa_config_update_psk(mpWpaNetwork); - wpa_supplicant_set_state(wpa_s, WPA_INACTIVE); + // 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; } -CHIP_ERROR WiFiManager::DisconnectStation() +void WiFiManager::ScanResultHandler(uint8_t * data) { - VerifyOrReturnError(nullptr != wpa_s, CHIP_ERROR_INTERNAL); - wpa_supplicant_cancel_scan(wpa_s); - wpas_request_disconnection(wpa_s); + const struct wifi_scan_result * scanResult = reinterpret_cast(data); - return CHIP_NO_ERROR; -} + if (Instance().mInternalScan && + Instance().mWantedNetwork.GetSsidSpan().data_equal(ByteSpan(scanResult->ssid, scanResult->ssid_length))) + { + // Prepare the connection parameters + // In case there are many networks with the same SSID choose the one with the best RSSI + if (scanResult->rssi > Instance().mWiFiParams.mRssi) + { + Instance().ClearStationProvisioningData(); + Instance().mWiFiParams.mParams.ssid_length = Instance().mWantedNetwork.ssidLen; + Instance().mWiFiParams.mParams.ssid = Instance().mWantedNetwork.ssid; + // Fallback to the WIFI_SECURITY_TYPE_PSK if the security is unknown + Instance().mWiFiParams.mParams.security = + scanResult->security <= WIFI_SECURITY_TYPE_MAX ? scanResult->security : WIFI_SECURITY_TYPE_PSK; + Instance().mWiFiParams.mParams.psk_length = Instance().mWantedNetwork.passLen; + + // If the security is none, WiFi driver expects the psk to be nullptr + if (Instance().mWiFiParams.mParams.security == WIFI_SECURITY_TYPE_NONE) + { + Instance().mWiFiParams.mParams.psk = nullptr; + } + else + { + Instance().mWiFiParams.mParams.psk = Instance().mWantedNetwork.pass; + } + + Instance().mWiFiParams.mParams.timeout = Instance().mHandling.mConnectionTimeout.count(); + Instance().mWiFiParams.mParams.channel = scanResult->channel; + Instance().mWiFiParams.mRssi = scanResult->rssi; + } + } -void WiFiManager::WaitForConnectionAsync() -{ - chip::DeviceLayer::SystemLayer().StartTimer( - static_cast(1000), [](System::Layer *, void *) { Instance().PollTimerCallback(); }, nullptr); + if (Instance().mScanResultCallback && !Instance().mInternalScan) + { + Instance().mScanResultCallback(ToScanResponse(scanResult)); + } } -void WiFiManager::PollTimerCallback() +void WiFiManager::ScanDoneHandler(uint8_t * data) { - const uint32_t kMaxRetriesNumber{ mConnectionTimeoutMs.count() / 1000 }; - static uint32_t retriesNumber{ 0 }; + const wifi_status * status = reinterpret_cast(data); + WiFiRequestStatus requestStatus = static_cast(status->status); + + if (Instance().mScanDoneCallback && !Instance().mInternalScan) + { + Instance().mScanDoneCallback(requestStatus); + } - if (WiFiManager::StationStatus::FULLY_PROVISIONED == GetStationStatus()) + if (requestStatus == WiFiRequestStatus::FAILURE) { - retriesNumber = 0; - OnConnectionSuccess(); + ChipLogDetail(DeviceLayer, "Scan request failed (%d)", status->status); } else { - if (retriesNumber++ < kMaxRetriesNumber) - { - // wait more time - WaitForConnectionAsync(); - } - else + ChipLogDetail(DeviceLayer, "Scan request done (%d)", status->status); + + // Internal scan is supposed to be followed by connection request + if (Instance().mInternalScan) { - // connection timeout - retriesNumber = 0; - OnConnectionFailed(); + Instance().mWiFiState = WIFI_STATE_ASSOCIATING; + net_if * iface = InetUtils::GetInterface(); + VerifyOrReturn(nullptr != iface, CHIP_ERROR_INTERNAL); + + if (net_mgmt(NET_REQUEST_WIFI_CONNECT, iface, &(Instance().mWiFiParams.mParams), sizeof(wifi_connect_req_params))) + { + ChipLogError(DeviceLayer, "Connection request failed"); + if (Instance().mHandling.mOnConnectionFailed) + { + Instance().mHandling.mOnConnectionFailed(); + } + return; + } + ChipLogError(DeviceLayer, "Connection to %*s requested", Instance().mWiFiParams.mParams.ssid_length, + Instance().mWiFiParams.mParams.ssid); + Instance().mInternalScan = false; } } } -CHIP_ERROR WiFiManager::GetWiFiInfo(WiFiInfo & info) const +void WiFiManager::SendRouterSolicitation(System::Layer * layer, void * param) { - VerifyOrReturnError(nullptr != wpa_s, CHIP_ERROR_INTERNAL); - VerifyOrReturnError(nullptr != mpWpaNetwork, CHIP_ERROR_INTERNAL); - - static uint8_t sBssid[ETH_ALEN]; - if (WiFiManager::StationStatus::CONNECTED <= GetStationStatus()) + net_if * iface = InetUtils::GetInterface(); + if (iface && iface->if_dev->link_addr.type == NET_LINK_ETHERNET) { - memcpy(sBssid, wpa_s->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_AX; - - wpa_signal_info signalInfo{}; - if (0 == wpa_drv_signal_poll(wpa_s, &signalInfo)) + net_if_start_rs(iface); + Instance().mRouterSolicitationCounter++; + if (Instance().mRouterSolicitationCounter < kRouterSolicitationMaxCount) { - info.mRssi = signalInfo.current_signal; // dBm - info.mChannel = FrequencyToChannel(signalInfo.frequency); + DeviceLayer::SystemLayer().StartTimer(System::Clock::Milliseconds32(kRouterSolicitationIntervalMs), + SendRouterSolicitation, nullptr); } else { - // this values should be nullable according to the Matter spec - info.mRssi = std::numeric_limits::min(); - info.mChannel = std::numeric_limits::min(); + Instance().mRouterSolicitationCounter = 0; } - - memcpy(info.mSsid, mpWpaNetwork->ssid, mpWpaNetwork->ssid_len); - info.mSsidLen = mpWpaNetwork->ssid_len; - - return CHIP_NO_ERROR; } - - return CHIP_ERROR_INTERNAL; } -uint8_t WiFiManager::GetSecurityType() const +void WiFiManager::ConnectHandler(uint8_t * data) { - VerifyOrReturnValue(nullptr != mpWpaNetwork, EMBER_ZCL_SECURITY_TYPE_UNSPECIFIED); + const wifi_status * status = reinterpret_cast(data); + WiFiRequestStatus requestStatus = static_cast(status->status); - if ((mpWpaNetwork->key_mgmt & WPA_KEY_MGMT_NONE) || !wpa_key_mgmt_wpa_any(mpWpaNetwork->key_mgmt)) + if (requestStatus == WiFiRequestStatus::FAILURE || requestStatus == WiFiRequestStatus::TERMINATED) { - 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; + ChipLogDetail(DeviceLayer, "Connection to WiFi network failed or was terminated by another request"); + Instance().mWiFiState = WIFI_STATE_DISCONNECTED; + if (Instance().mHandling.mOnConnectionFailed) + { + Instance().mHandling.mOnConnectionFailed(); + } } else { - return EMBER_ZCL_SECURITY_TYPE_WEP; + // Workaround needed until sending Router Solicitation after connect will be done by the driver. + DeviceLayer::SystemLayer().StartTimer( + System::Clock::Milliseconds32(chip::Crypto::GetRandU16() % kMaxInitialRouterSolicitationDelayMs), + SendRouterSolicitation, nullptr); + + ChipLogDetail(DeviceLayer, "Connected to WiFi network"); + Instance().mWiFiState = WIFI_STATE_COMPLETED; + if (Instance().mHandling.mOnConnectionSuccess) + { + Instance().mHandling.mOnConnectionSuccess(); + } + Instance().PostConnectivityStatusChange(kConnectivity_Established); } - - return EMBER_ZCL_SECURITY_TYPE_UNSPECIFIED; + // cleanup the provisioning data as it is configured per each connect request + Instance().ClearStationProvisioningData(); } -uint8_t WiFiManager::FrequencyToChannel(uint16_t freq) +void WiFiManager::DisconnectHandler(uint8_t * data) { - 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; + ChipLogDetail(DeviceLayer, "WiFi station disconnected"); + Instance().mWiFiState = WIFI_STATE_DISCONNECTED; + Instance().PostConnectivityStatusChange(kConnectivity_Lost); } -CHIP_ERROR WiFiManager::GetNetworkStatistics(NetworkStatistics & stats) const +WiFiManager::StationStatus WiFiManager::GetStationStatus() 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 WiFiManager::sStatusMap[mWiFiState]; +} - return CHIP_NO_ERROR; +void WiFiManager::PostConnectivityStatusChange(ConnectivityChange changeType) +{ + ChipDeviceEvent networkEvent{}; + networkEvent.Type = DeviceEventType::kWiFiConnectivityChange; + networkEvent.WiFiConnectivityChange.Result = changeType; + PlatformMgr().PostEventOrDie(&networkEvent); } } // namespace DeviceLayer diff --git a/src/platform/nrfconnect/wifi/WiFiManager.h b/src/platform/nrfconnect/wifi/WiFiManager.h index b068cd99705eef..920df4dd778597 100644 --- a/src/platform/nrfconnect/wifi/WiFiManager.h +++ b/src/platform/nrfconnect/wifi/WiFiManager.h @@ -24,10 +24,12 @@ #include #include +#include #include #include -#include +#include +#include extern "C" { #include @@ -85,9 +87,18 @@ class Map class WiFiManager { +public: + enum WiFiRequestStatus : int + { + SUCCESS = 0, + FAILURE = 1, + TERMINATED = 2 + }; + + using ScanResultCallback = void (*)(const NetworkCommissioning::WiFiScanResponse &); + using ScanDoneCallback = void (*)(WiFiRequestStatus); using ConnectionCallback = void (*)(); -public: enum class StationStatus : uint8_t { NONE, @@ -97,7 +108,8 @@ class WiFiManager CONNECTING, CONNECTED, PROVISIONING, - FULLY_PROVISIONED + FULLY_PROVISIONED, + UNKNOWN }; static WiFiManager & Instance() @@ -106,13 +118,11 @@ class WiFiManager return sInstance; } - using ScanCallback = void (*)(int /* status */, NetworkCommissioning::WiFiScanResponse *); - struct ConnectionHandling { ConnectionCallback mOnConnectionSuccess{}; ConnectionCallback mOnConnectionFailed{}; - System::Clock::Timeout mConnectionTimeoutMs{}; + System::Clock::Seconds32 mConnectionTimeout{}; }; struct WiFiInfo @@ -135,36 +145,72 @@ class WiFiManager uint32_t mOverruns{}; }; + 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; } + void Erase() + { + memset(ssid, 0, DeviceLayer::Internal::kMaxWiFiSSIDLength); + memset(pass, 0, DeviceLayer::Internal::kMaxWiFiKeyLength); + ssidLen = 0; + passLen = 0; + } + }; + + static constexpr uint16_t kRouterSolicitationIntervalMs = 4000; + static constexpr uint16_t kMaxInitialRouterSolicitationDelayMs = 1000; + static constexpr uint8_t kRouterSolicitationMaxCount = 3; + CHIP_ERROR Init(); - CHIP_ERROR Scan(const ByteSpan & ssid, ScanCallback callback); + CHIP_ERROR Scan(const ByteSpan & ssid, ScanResultCallback resultCallback, ScanDoneCallback doneCallback, + bool internalScan = false); CHIP_ERROR Connect(const ByteSpan & ssid, const ByteSpan & credentials, const ConnectionHandling & handling); StationStatus GetStationStatus() const; CHIP_ERROR ClearStationProvisioningData(); - CHIP_ERROR DisconnectStation(); + CHIP_ERROR Disconnect(); 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; + using NetEventHandler = void (*)(uint8_t *); + + struct ConnectionParams + { + wifi_connect_req_params mParams; + int8_t mRssi{ std::numeric_limits::min() }; + }; + + constexpr static uint32_t kWifiManagementEvents = NET_EVENT_WIFI_SCAN_RESULT | NET_EVENT_WIFI_SCAN_DONE | + NET_EVENT_WIFI_CONNECT_RESULT | NET_EVENT_WIFI_DISCONNECT_RESULT | NET_EVENT_WIFI_IFACE_STATUS; + + // Event handling + static void WifiMgmtEventHandler(net_mgmt_event_callback * cb, uint32_t mgmtEvent, net_if * iface); + static void ScanResultHandler(uint8_t * data); + static void ScanDoneHandler(uint8_t * data); + static void ConnectHandler(uint8_t * data); + static void DisconnectHandler(uint8_t * data); + static void PostConnectivityStatusChange(ConnectivityChange changeType); + static void SendRouterSolicitation(System::Layer * layer, void * param); + + ConnectionParams mWiFiParams{}; + ConnectionHandling mHandling; + wifi_iface_state mWiFiState; + net_mgmt_event_callback mWiFiMgmtClbk{}; + ScanResultCallback mScanResultCallback{ nullptr }; + ScanDoneCallback mScanDoneCallback{ nullptr }; + WiFiNetwork mWantedNetwork{}; + bool mInternalScan{ false }; + uint8_t mRouterSolicitationCounter = 0; + static const Map sStatusMap; + static const Map sEventHandlerMap; }; } // namespace DeviceLayer diff --git a/src/test_driver/nrfconnect/main/runner.cpp b/src/test_driver/nrfconnect/main/runner.cpp index b7654f70a1f514..a44e09a3ebcae1 100644 --- a/src/test_driver/nrfconnect/main/runner.cpp +++ b/src/test_driver/nrfconnect/main/runner.cpp @@ -19,8 +19,8 @@ #include #include -#include -#include +#include +#include using namespace ::chip; using namespace ::chip::DeviceLayer;