net: wifi: Added scan extension support for frequency bands

Added scan extension to support scanning individual Wi-Fi bands or
combinations thereof.

Signed-off-by: Sachin D Kulkarni <sachin.kulkarni@nordicsemi.no>
This commit is contained in:
Sachin D Kulkarni 2023-07-17 20:47:03 +05:30 committed by Fabio Baltieri
parent add1d15bee
commit ee6c81896d
9 changed files with 199 additions and 11 deletions

View file

@ -104,17 +104,22 @@ static inline const char *wifi_mfp_txt(enum wifi_mfp_options mfp)
}
}
/** IEEE 802.11 operational frequency bands (not exhaustive). */
/**
* @brief IEEE 802.11 operational frequency bands (not exhaustive).
*/
enum wifi_frequency_bands {
/** 2.4GHz band. */
/** 2.4 GHz band. */
WIFI_FREQ_BAND_2_4_GHZ = 0,
/** 5GHz band. */
/** 5 GHz band. */
WIFI_FREQ_BAND_5_GHZ,
/** 6GHz band (Wi-Fi 6E, also extends to 7GHz). */
/** 6 GHz band (Wi-Fi 6E, also extends to 7GHz). */
WIFI_FREQ_BAND_6_GHZ,
/** Number of frequency bands available. */
__WIFI_FREQ_BAND_AFTER_LAST,
/** Highest frequency band available. */
WIFI_FREQ_BAND_MAX = __WIFI_FREQ_BAND_AFTER_LAST - 1,
/** Invalid frequency band */
WIFI_FREQ_BAND_UNKNOWN
};

View file

@ -174,7 +174,11 @@ enum net_event_wifi_cmd {
#define NET_EVENT_WIFI_DISCONNECT_COMPLETE \
(_NET_WIFI_EVENT | NET_EVENT_WIFI_CMD_DISCONNECT_COMPLETE)
/** Wi-Fi scan parameters */
/**
* @brief Wi-Fi scan parameters structure.
* Used to specify parameters which can control how the Wi-Fi scan
* is performed.
*/
struct wifi_scan_params {
/** Scan type, see enum wifi_scan_type.
*
@ -184,6 +188,10 @@ struct wifi_scan_params {
* restrictions etc.
*/
enum wifi_scan_type scan_type;
/** Bitmap of bands to be scanned.
* Refer to ::wifi_frequency_bands for bit position of each band.
*/
uint8_t bands;
};
/** Wi-Fi scan result, each result is provided to the net_mgmt_event_callback

View file

@ -0,0 +1,69 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
/** @file
*
* @brief Utility functions to be used by the Wi-Fi subsystem.
*/
#ifndef ZEPHYR_INCLUDE_NET_WIFI_UTILS_H_
#define ZEPHYR_INCLUDE_NET_WIFI_UTILS_H_
#ifdef __cplusplus
extern "C" {
#endif
/**
* @addtogroup wifi_mgmt
* @{
*/
/**
* @name Wi-Fi utility functions.
*
* Utility functions for the Wi-Fi subsystem.
* @{
*/
#define WIFI_UTILS_MAX_BAND_STR_LEN 3
#define WIFI_UTILS_MAX_CHAN_STR_LEN 4
/**
* @brief Convert a band specification string to a bitmap representing the bands.
*
* @details The function will parse a string which specifies Wi-Fi frequency band
* values as a comma separated string and convert it to a bitmap. The string can
* use the following characters to represent the bands:
*
* - 2: 2.4 GHz
* - 5: 5 GHz
* - 6: 6 GHz
*
* For the bitmap generated refer to ::wifi_frequency_bands
* for bit position of each band.
*
* E.g. a string "2,5,6" will be converted to a bitmap value of 0x7
*
* @param scan_bands_str String which spe.
* @param band_map Pointer to the bitmap variable to be updated.
*
* @retval 0 on success.
* @retval -errno value in case of failure.
*/
int wifi_utils_parse_scan_bands(char *scan_bands_str, uint8_t *band_map);
/**
* @}
*/
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif /* ZEPHYR_INCLUDE_NET_WIFI_UTILS_H_ */

View file

@ -96,11 +96,17 @@ config NET_L2_CUSTOM_IEEE802154_MTU
source "subsys/net/l2/canbus/Kconfig"
config NET_L2_WIFI_UTILS
bool
help
This provides utility functions for Wi-Fi subsystem.
config NET_L2_WIFI_MGMT
bool "Wi-Fi Management support"
select NET_MGMT
select NET_MGMT_EVENT
select NET_MGMT_EVENT_INFO
select NET_L2_WIFI_UTILS
help
Add support for Wi-Fi Management interface.
@ -116,6 +122,7 @@ endif # NET_L2_WIFI_MGMT
config NET_L2_WIFI_SHELL
bool "Wi-Fi shell module"
select NET_L2_WIFI_MGMT
select NET_L2_WIFI_UTILS
select SHELL_GETOPT
select GETOPT_LONG
help

View file

@ -9,6 +9,7 @@ zephyr_library_compile_definitions_ifdef(
zephyr_library_sources_ifdef(CONFIG_NET_L2_WIFI_MGMT wifi_mgmt.c)
zephyr_library_sources_ifdef(CONFIG_NET_L2_WIFI_SHELL wifi_shell.c)
zephyr_library_sources_ifdef(CONFIG_WIFI_NM wifi_nm.c)
zephyr_library_sources_ifdef(CONFIG_NET_L2_WIFI_UTILS wifi_utils.c)
# Linker section placement for wifi_nm_instance iterable structure
zephyr_linker_sources_ifdef(CONFIG_WIFI_NM DATA_SECTIONS wifi_nm.ld)

View file

@ -47,6 +47,18 @@ config WIFI_MGMT_FORCED_PASSIVE_SCAN
This doesn't guarantee that passive scan will be used, it depends
on the underlying chip implementation to support and honour scan type.
config WIFI_MGMT_SCAN_BANDS
string "Frequency bands to scan"
default ""
help
Specifies the frequency bands to scan, as follows:
2 - 2.4 GHz
5 - 5 GHz
6 - 6 GHz
"" - All bands allowed by the regulatory domain.
Multiple bands can be specified as comma separated band values.
Only regulatory domain permitted values are allowed.
config WIFI_NM
bool "Wi-Fi Network manager support"
help

View file

@ -8,6 +8,7 @@
LOG_MODULE_REGISTER(net_wifi_mgmt, CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL);
#include <errno.h>
#include <string.h>
#include <zephyr/net/net_core.h>
#include <zephyr/net/net_if.h>
@ -110,7 +111,16 @@ static int wifi_scan(uint32_t mgmt_request, struct net_if *iface,
if (data && (len == sizeof(*params))) {
#ifdef CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN
params->scan_type = WIFI_SCAN_TYPE_PASSIVE;
#endif
#endif /* CONFIG_WIFI_MGMT_FORCED_PASSIVE_SCAN */
if (!params->bands) {
if (wifi_utils_parse_scan_bands(CONFIG_WIFI_MGMT_SCAN_BANDS,
&params->bands)) {
NET_ERR("Incorrect value(s) in CONFIG_WIFI_MGMT_SCAN_BANDS: %s",
CONFIG_WIFI_MGMT_SCAN_BANDS);
return -EINVAL;
}
}
}
return wifi_mgmt_api->scan(dev, params, scan_result_cb);

View file

@ -14,13 +14,15 @@ LOG_MODULE_REGISTER(net_wifi_shell, LOG_LEVEL_INF);
#include <zephyr/kernel.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zephyr/shell/shell.h>
#include <zephyr/sys/printk.h>
#include <zephyr/init.h>
#include <zephyr/net/net_if.h>
#include <zephyr/net/wifi_mgmt.h>
#include <zephyr/net/net_event.h>
#include <zephyr/net/wifi_mgmt.h>
#include <zephyr/net/wifi_utils.h>
#include <zephyr/posix/unistd.h>
#include "net_private.h"
@ -457,6 +459,7 @@ static int cmd_wifi_disconnect(const struct shell *sh, size_t argc,
}
static int wifi_scan_args_to_params(const struct shell *sh,
size_t argc,
char *argv[],
@ -465,10 +468,11 @@ static int wifi_scan_args_to_params(const struct shell *sh,
struct getopt_state *state;
int opt;
static struct option long_options[] = {{"type", required_argument, 0, 't'},
{0, 0, 0, 0}};
{"bands", required_argument, 0, 'b'},
{0, 0, 0, 0}};
int opt_index = 0;
while ((opt = getopt_long(argc, argv, "t:", long_options, &opt_index)) != -1) {
while ((opt = getopt_long(argc, argv, "t:b:", long_options, &opt_index)) != -1) {
state = getopt_state_get();
switch (opt) {
case 't':
@ -481,9 +485,15 @@ static int wifi_scan_args_to_params(const struct shell *sh,
return -ENOEXEC;
}
break;
case 'b':
if (wifi_utils_parse_scan_bands(optarg, &params->bands)) {
shell_fprintf(sh, SHELL_ERROR, "Invalid band value(s)\n");
return -ENOEXEC;
}
break;
case '?':
shell_fprintf(sh, SHELL_ERROR, "Invalid option or option usage: %s\n",
long_options[opt_index].name);
argv[opt_index + 1]);
return -ENOEXEC;
}
}
@ -1213,7 +1223,8 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands,
SHELL_CMD(scan, NULL,
"Scan for Wi-Fi APs\n"
"OPTIONS:\n"
"[-t, --type <active/passive>] : Preferred mode of scan. The actual mode of scan can depend on factors such as the Wi-Fi chip implementation, regulatory domain restrictions. Default type is active.",
"[-t, --type <active/passive>] : Preferred mode of scan. The actual mode of scan can depend on factors such as the Wi-Fi chip implementation, regulatory domain restrictions. Default type is active.\n"
"[-b, --bands <Comma separated list of band values (2/5/6)>] : Bands to be scanned where 2: 2.4 GHz, 5: 5 GHz, 6: 6 GHz.",
cmd_wifi_scan),
SHELL_CMD(statistics, NULL, "Wi-Fi interface statistics", cmd_wifi_stats),
SHELL_CMD(status, NULL, "Status of the Wi-Fi interface", cmd_wifi_status),

View file

@ -0,0 +1,65 @@
/*
* Copyright (c) 2023 Nordic Semiconductor ASA
*
* SPDX-License-Identifier: Apache-2.0
*/
/** @file
* @brief Utility functions to be used by the Wi-Fi subsytem.
*/
#include <zephyr/logging/log.h>
LOG_MODULE_REGISTER(net_wifi_utils, CONFIG_NET_L2_WIFI_MGMT_LOG_LEVEL);
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <zephyr/kernel.h>
#include <zephyr/net/net_core.h>
#include <zephyr/net/wifi.h>
/* Ensure 'strtok_r' is available even with -std=c99. */
char *strtok_r(char *str, const char *delim, char **saveptr);
static enum wifi_frequency_bands wifi_utils_map_band_str_to_idx(char *band_str)
{
if (!strcmp(band_str, "2")) {
return WIFI_FREQ_BAND_2_4_GHZ;
} else if (!strcmp(band_str, "5")) {
return WIFI_FREQ_BAND_5_GHZ;
} else if (!strcmp(band_str, "6")) {
return WIFI_FREQ_BAND_6_GHZ;
} else {
NET_ERR("Unknown band value: %s", band_str);
return WIFI_FREQ_BAND_UNKNOWN;
}
}
int wifi_utils_parse_scan_bands(char *scan_bands_str, uint8_t *band_map)
{
char *band_str = NULL;
char *ctx = NULL;
enum wifi_frequency_bands band = WIFI_FREQ_BAND_UNKNOWN;
if (!scan_bands_str) {
return -EINVAL;
}
band_str = strtok_r(scan_bands_str, ",", &ctx);
while (band_str) {
band = wifi_utils_map_band_str_to_idx(band_str);
if (band == WIFI_FREQ_BAND_UNKNOWN) {
NET_ERR("Invalid band value: %s", band_str);
return -EINVAL;
}
*band_map |= (1 << band);
band_str = strtok_r(NULL, ",", &ctx);
}
return 0;
}