Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Wi-Fi ready event library #15628

Merged
merged 4 commits into from
Jun 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions doc/nrf/libraries/networking/wifi_ready.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
.. _lib_wifi_ready:

Wi-Fi ready
###########

.. contents::
:local:
:depth: 2

The Wi-Fi ready library manages Wi-Fi® readiness for applications by handling supplicant ready and not ready events.

Overview
********

The Wi-Fi ready library informs applications of Wi-Fi readiness by managing supplicant events, indicating when Wi-Fi is available for use.

Configuration
*************

To use this library, enable the :kconfig:option:`CONFIG_WIFI_READY_EVENT_HANDLING` Kconfig option.

API documentation
*****************

| Header file: :file:`include/net/wifi_ready.h`
| Source files: :file:`subsys/net/lib/wifi_ready`

.. doxygengroup:: wifi_ready
:project: nrf
:members:
Original file line number Diff line number Diff line change
Expand Up @@ -788,6 +788,10 @@ Wi-Fi samples that used :ref:`zephyr:bluetooth-hci-ipc-sample` or :ref:`zephyr:n

* Added the :ref:`wifi_promiscuous_sample` sample that demonstrates how to set Promiscuous mode, establish a connection to an Access Point (AP), analyze incoming Wi-Fi packets, and print packet statistics.

* :ref:`wifi_station_sample` sample:

* Modified to use the :ref:`lib_wifi_ready` library to manage the Wi-Fi use.

Other samples
-------------

Expand Down Expand Up @@ -898,7 +902,10 @@ Modem libraries
Libraries for networking
------------------------

* Added the :ref:`lib_softap_wifi_provision` library.
* Added:

* :ref:`lib_softap_wifi_provision` library.
* :ref:`lib_wifi_ready` library.

* :ref:`lib_wifi_credentials` library:

Expand Down
75 changes: 75 additions & 0 deletions include/net/wifi_ready.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/*
* Copyright (c) 2024 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: LicenseRef-Nordic-5-Clause
*/


#ifndef __LIB_WIFI_READY_H__
#define __LIB_WIFI_READY_H__

#include <zephyr/net/net_if.h>

/**
* @defgroup wifi_ready Wi-Fi ready library
* @brief Library for handling Wi-Fi ready events.
*
* @{
*/

#ifdef __cplusplus
extern "C" {
#endif

D-Triveni marked this conversation as resolved.
Show resolved Hide resolved
/**
* @brief Structure for storing a callback function to be called when the Wi-Fi is ready.
*/
typedef struct {
/** Callback function to be called when the Wi-Fi is ready. */
void (*wifi_ready_cb)(bool wifi_ready);
/** Interface to which the callback is registered. */
struct net_if *iface;
/** Only for internal use. */
struct k_work item;
} wifi_ready_callback_t;

/**
* @brief Register a callback to be called when the Wi-Fi is ready.
*
* @param cb Callback function to be called when the Wi-Fi is ready.
* The callback is called from NET_MGMT thread, so, care should be taken
* to avoid blocking the thread and also stack size should be considered.
* @param iface (optional) Interface to which the callback is registered.
*
* @return 0 if the callback was successfully registered, or a negative error code
* if the callback could not be registered.
*
* @retval -EINVAL if the callback is NULL.
* @retval -ENOMEM if the callback array is full.
* @retval -EALREADY if the callback is already registered.
*/

int register_wifi_ready_callback(wifi_ready_callback_t cb, struct net_if *iface);
/**
* @brief Unregister a callback that was registered to be called when the Wi-Fi is ready.
*
* @param cb Callback function to be unregistered.
* @param iface (optional) Interface to which the callback is registered.
*
* @return 0 if the callback was successfully unregistered, or a negative error code
* if the callback could not be unregistered.
*
* @retval -EINVAL if the callback is NULL.
* @retval -ENOENT if the callback is not registered.
*/
int unregister_wifi_ready_callback(wifi_ready_callback_t cb, struct net_if *iface);

#ifdef __cplusplus
}
#endif

/**
* @}
*/

#endif /* __LIB_WIFI_READY_H__*/
6 changes: 6 additions & 0 deletions samples/wifi/sta/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,10 @@ config STA_CONN_TIMEOUT_SEC
Specify the connection timeout, in seconds. This is the overall timeout i.e., time to be waited for
a station to connect and get an IP address. DHCP retries should be taken into account when setting
this value. If the timeout is set to 0, the connection will not timeout.

config STA_SAMPLE_START_WIFI_THREAD_STACK_SIZE
int "Stack size for Wi-Fi start thread"
default 4096
help
Set the stack size for the Wi-Fi start thread.
endmenu
27 changes: 27 additions & 0 deletions samples/wifi/sta/README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ The sample can perform Wi-Fi operations such as connect and disconnect in the 2.

Using this sample, the development kit can connect to the specified access point in :abbr:`STA (Station)` mode.

The sample uses the :ref:`lib_wifi_ready` library to check Wi-Fi readiness.
To use the :ref:`lib_wifi_ready` library, enable the :kconfig:option:`CONFIG_WIFI_READY_EVENT_HANDLING` Kconfig option.

User interface
**************

Expand Down Expand Up @@ -180,6 +183,30 @@ Testing
[00:00:07.720,245] <inf> sta: RSSI: -57
[00:00:07.720,245] <inf> sta: Static IP address:

RPU recovery
************

The RPU recovery mechanism is used to recover from the RPU (nRF70) hang.
This feature performs an interface reset (down and up), which triggers a RPU cold boot.
Application's network connection will be lost during the recovery process, and it is application's responsibility to reestablish the network connection.

Testing
=======

To test RPU recovery, you must build the sample with :kconfig:option:`CONFIG_SHELL` and :kconfig:option:`CONFIG_NRF700X_UTIL` kconfig options.

#. Trigger RPU recovery using the following command:

.. code-block:: console

wifi_util rpu_recovery_test

If RPU recovery is triggered, you should see an output similar to the following:

.. code-block:: console

RPU recovery triggered

Power management testing
************************

Expand Down
1 change: 1 addition & 0 deletions samples/wifi/sta/boards/nrf52840dk_nrf52840.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
CONFIG_WIFI_READY_LIB=n
1 change: 1 addition & 0 deletions samples/wifi/sta/prj.conf
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ CONFIG_WIFI_NRF700X=y

# WPA supplicant
CONFIG_WPA_SUPP=y
CONFIG_WIFI_READY_LIB=y

CONFIG_WIFI_MGMT_EXT=y
CONFIG_WIFI_CREDENTIALS=y
Expand Down
8 changes: 8 additions & 0 deletions samples/wifi/sta/sample.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,14 @@ tests:
- nrf7002dk/nrf5340/cpuapp
platform_allow: nrf7002dk/nrf5340/cpuapp
tags: ci_build sysbuild
sample.nrf7002.sta.no_wifi_ready:
sysbuild: true
build_only: true
extra_args: CONFIG_WIFI_READY_LIB=n
integration_platforms:
- nrf7002dk/nrf5340/cpuapp
platform_allow: nrf7002dk/nrf5340/cpuapp
tags: ci_build sysbuild
sample.nrf7001.sta:
sysbuild: true
build_only: true
Expand Down
139 changes: 119 additions & 20 deletions samples/wifi/sta/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ LOG_MODULE_REGISTER(sta, CONFIG_LOG_DEFAULT_LEVEL);
#include <zephyr/drivers/gpio.h>

#include <net/wifi_mgmt_ext.h>
#include <net/wifi_ready.h>

#include <qspi_if.h>

Expand Down Expand Up @@ -52,6 +53,11 @@ static const struct gpio_dt_spec led = GPIO_DT_SPEC_GET(LED0_NODE, gpios);
static struct net_mgmt_event_callback wifi_shell_mgmt_cb;
static struct net_mgmt_event_callback net_shell_mgmt_cb;

#ifdef CONFIG_WIFI_READY_LIB
static K_SEM_DEFINE(wifi_ready_state_changed_sem, 0, 1);
static bool wifi_ready_status;
#endif /* CONFIG_WIFI_READY_LIB */

static struct {
const struct shell *sh;
union {
Expand Down Expand Up @@ -247,31 +253,13 @@ int bytes_from_str(const char *str, uint8_t *bytes, size_t bytes_len)
return 0;
}

int main(void)
int start_app(void)
{
memset(&context, 0, sizeof(context));

net_mgmt_init_event_callback(&wifi_shell_mgmt_cb,
wifi_mgmt_event_handler,
WIFI_SHELL_MGMT_EVENTS);

net_mgmt_add_event_callback(&wifi_shell_mgmt_cb);


net_mgmt_init_event_callback(&net_shell_mgmt_cb,
net_mgmt_event_handler,
NET_EVENT_IPV4_DHCP_BOUND);

net_mgmt_add_event_callback(&net_shell_mgmt_cb);

LOG_INF("Starting %s with CPU frequency: %d MHz", CONFIG_BOARD, SystemCoreClock/MHZ(1));
k_sleep(K_SECONDS(1));

#if defined(CONFIG_BOARD_NRF7002DK_NRF7001_NRF5340_CPUAPP) || \
defined(CONFIG_BOARD_NRF7002DK_NRF5340_CPUAPP)
if (strlen(CONFIG_NRF700X_QSPI_ENCRYPTION_KEY)) {
char key[QSPI_KEY_LEN_BYTES];
int ret;
char key[QSPI_KEY_LEN_BYTES];

ret = bytes_from_str(CONFIG_NRF700X_QSPI_ENCRYPTION_KEY, key, sizeof(key));
if (ret) {
Expand Down Expand Up @@ -302,6 +290,25 @@ int main(void)
CONFIG_NET_CONFIG_MY_IPV4_GW);

while (1) {
#ifdef CONFIG_WIFI_READY_LIB
int ret;

LOG_INF("Waiting for Wi-Fi to be ready");
ret = k_sem_take(&wifi_ready_state_changed_sem, K_FOREVER);
if (ret) {
LOG_ERR("Failed to take semaphore: %d", ret);
return ret;
}

check_wifi_ready:
if (!wifi_ready_status) {
LOG_INF("Wi-Fi is not ready");
/* Perform any cleanup and stop using Wi-Fi and wait for
* Wi-Fi to be ready
*/
continue;
}
#endif /* CONFIG_WIFI_READY_LIB */
wifi_connect();

while (!context.connect_result) {
Expand All @@ -311,9 +318,101 @@ int main(void)

if (context.connected) {
cmd_wifi_status();
#ifdef CONFIG_WIFI_READY_LIB
ret = k_sem_take(&wifi_ready_state_changed_sem, K_FOREVER);
if (ret) {
LOG_ERR("Failed to take semaphore: %d", ret);
return ret;
}
goto check_wifi_ready;
#else
k_sleep(K_FOREVER);
#endif /* CONFIG_WIFI_READY_LIB */
}
}

return 0;
}

#ifdef CONFIG_WIFI_READY_LIB
void start_wifi_thread(void);
#define THREAD_PRIORITY K_PRIO_COOP(CONFIG_NUM_COOP_PRIORITIES - 1)
K_THREAD_DEFINE(start_wifi_thread_id, CONFIG_STA_SAMPLE_START_WIFI_THREAD_STACK_SIZE,
start_wifi_thread, NULL, NULL, NULL,
THREAD_PRIORITY, 0, -1);

void start_wifi_thread(void)
{
start_app();
}

void wifi_ready_cb(bool wifi_ready)
{
LOG_DBG("Is Wi-Fi ready?: %s", wifi_ready ? "yes" : "no");
wifi_ready_status = wifi_ready;
k_sem_give(&wifi_ready_state_changed_sem);
}
#endif /* CONFIG_WIFI_READY_LIB */

void net_mgmt_callback_init(void)
{
memset(&context, 0, sizeof(context));

net_mgmt_init_event_callback(&wifi_shell_mgmt_cb,
wifi_mgmt_event_handler,
WIFI_SHELL_MGMT_EVENTS);

net_mgmt_add_event_callback(&wifi_shell_mgmt_cb);

net_mgmt_init_event_callback(&net_shell_mgmt_cb,
net_mgmt_event_handler,
NET_EVENT_IPV4_DHCP_BOUND);

net_mgmt_add_event_callback(&net_shell_mgmt_cb);

LOG_INF("Starting %s with CPU frequency: %d MHz", CONFIG_BOARD, SystemCoreClock/MHZ(1));
k_sleep(K_SECONDS(1));
}

#ifdef CONFIG_WIFI_READY_LIB
static int register_wifi_ready(void)
{
int ret = 0;
wifi_ready_callback_t cb;
struct net_if *iface = net_if_get_first_wifi();

if (!iface) {
LOG_ERR("Failed to get Wi-Fi interface");
return -1;
}

cb.wifi_ready_cb = wifi_ready_cb;

LOG_DBG("Registering Wi-Fi ready callbacks");
ret = register_wifi_ready_callback(cb, iface);
if (ret) {
LOG_ERR("Failed to register Wi-Fi ready callbacks %s", strerror(ret));
return ret;
}

return ret;
}
#endif /* CONFIG_WIFI_READY_LIB */

int main(void)
{
int ret = 0;

net_mgmt_callback_init();

#ifdef CONFIG_WIFI_READY_LIB
ret = register_wifi_ready();
if (ret) {
return ret;
}
k_thread_start(start_wifi_thread_id);
#else
start_app();
#endif /* CONFIG_WIFI_READY_LIB */
return ret;
}
1 change: 1 addition & 0 deletions subsys/net/lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ add_subdirectory_ifdef(CONFIG_LWM2M_CLIENT_UTILS lwm2m_client_utils)
add_subdirectory_ifdef(CONFIG_WIFI_CREDENTIALS wifi_credentials)
add_subdirectory_ifdef(CONFIG_SOFTAP_WIFI_PROVISION softap_wifi_provision)
add_subdirectory_ifdef(CONFIG_WIFI_MGMT_EXT wifi_mgmt_ext)
add_subdirectory_ifdef(CONFIG_WIFI_READY_LIB wifi_ready)
add_subdirectory_ifdef(CONFIG_MQTT_HELPER mqtt_helper)
add_subdirectory_ifdef(CONFIG_NRF_PROVISIONING nrf_provisioning)
add_subdirectory_ifdef(CONFIG_NRF_MCUMGR_SMP_CLIENT mcumgr_smp_client)
Loading
Loading