Skip to content
Open
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
43 changes: 43 additions & 0 deletions include/zephyr/net/wifi_mgmt.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ enum net_request_wifi_cmd {
NET_REQUEST_WIFI_CMD_AP_WPS_CONFIG,
/** Configure BSS maximum idle period */
NET_REQUEST_WIFI_CMD_BSS_MAX_IDLE_PERIOD,
/** Configure background scanning */
NET_REQUEST_WIFI_CMD_BGSCAN,
/** @cond INTERNAL_HIDDEN */
NET_REQUEST_WIFI_CMD_MAX
/** @endcond */
Expand Down Expand Up @@ -332,6 +334,11 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_NEIGHBOR_REP_COMPLETE);

NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_BSS_MAX_IDLE_PERIOD);

#define NET_REQUEST_WIFI_BGSCAN \
(NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_BGSCAN)

NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_BGSCAN);

/** @cond INTERNAL_HIDDEN */

enum {
Expand Down Expand Up @@ -1393,6 +1400,32 @@ enum wifi_sap_iface_state {
WIFI_SAP_IFACE_ENABLED
};

#if defined(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN) || defined(__DOXYGEN__)
/** @brief Wi-Fi background scan implementation */
enum wifi_bgscan_type {
/** None, background scan is disabled */
WIFI_BGSCAN_NONE = 0,
/** Simple, periodic scan based on signal strength */
WIFI_BGSCAN_SIMPLE,
/** Learn channels used by the network (experimental) */
WIFI_BGSCAN_LEARN,
};

/** @brief Wi-Fi background scan parameters */
struct wifi_bgscan_params {
/** The type of background scanning */
enum wifi_bgscan_type type;
/** Short scan interval in seconds */
uint16_t short_interval;
/** Long scan interval in seconds */
uint16_t long_interval;
/** Signal strength threshold in dBm */
int8_t rssi_threshold;
/** Number of BSS Transition Management (BTM) queries */
uint16_t btm_queries;
};
#endif

/* Extended Capabilities */
enum wifi_ext_capab {
WIFI_EXT_CAPAB_20_40_COEX = 0,
Expand Down Expand Up @@ -1732,6 +1765,16 @@ struct wifi_mgmt_ops {
*/
int (*set_bss_max_idle_period)(const struct device *dev,
unsigned short bss_max_idle_period);
#if defined(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN) || defined(__DOXYGEN__)
/** Configure background scanning
*
* @param dev Pointer to the device structure for the driver instance.
* @param params Background scanning configuration parameters
*
* @return 0 if ok, < 0 if error
*/
int (*set_bgscan)(const struct device *dev, struct wifi_bgscan_params *params);
#endif
};

/** Wi-Fi management offload API */
Expand Down
20 changes: 20 additions & 0 deletions modules/hostap/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM
CONFIG_WNM
)

zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN
CONFIG_BGSCAN
)
zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN_SIMPLE
CONFIG_BGSCAN_SIMPLE
)
zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN_LEARN
CONFIG_BGSCAN_LEARN
)

zephyr_library_include_directories(
${CMAKE_CURRENT_SOURCE_DIR}/src
${HOSTAP_BASE}/
Expand Down Expand Up @@ -156,6 +166,16 @@ zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM
${WIFI_NM_WPA_SUPPLICANT_BASE}/wnm_sta.c
)

zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN
${WIFI_NM_WPA_SUPPLICANT_BASE}/bgscan.c
)
zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN_SIMPLE
${WIFI_NM_WPA_SUPPLICANT_BASE}/bgscan_simple.c
)
zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN_LEARN
${WIFI_NM_WPA_SUPPLICANT_BASE}/bgscan_learn.c
)

zephyr_library_sources_ifdef(CONFIG_WPA_CLI
src/wpa_cli.c
)
Expand Down
30 changes: 30 additions & 0 deletions modules/hostap/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,27 @@ config WIFI_NM_WPA_SUPPLICANT_SKIP_DHCP_ON_ROAMING
needs to get new IP address after roaming to new AP. Disable this to keep
DHCP after roaming.

config WIFI_NM_WPA_SUPPLICANT_BGSCAN
bool "Background scanning (for legacy roaming), recommended if 802.11r is not supported"
depends on WIFI_NM_WPA_SUPPLICANT_WNM
depends on !WIFI_NM_WPA_SUPPLICANT_ROAMING

if WIFI_NM_WPA_SUPPLICANT_BGSCAN

config WIFI_NM_WPA_SUPPLICANT_BGSCAN_SIMPLE
bool "Simple background scanning"
default y
help
Periodic background scans based on signal strength.

config WIFI_NM_WPA_SUPPLICANT_BGSCAN_LEARN
bool "Learning"
help
Learn channels used by the network and try to avoid
background scans on other channels (experimental).

endif # WIFI_NM_WPA_SUPPLICANT_BGSCAN

# Create hidden config options that are used in hostap. This way we do not need
# to mark them as allowed for CI checks, and also someone else cannot use the
# same name options.
Expand Down Expand Up @@ -486,6 +507,15 @@ config NO_RANDOM_POOL
config WNM
bool

config BGSCAN
bool

config BGSCAN_SIMPLE
bool

config BGSCAN_LEARN
bool

config NO_WPA
bool
default y if WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE
Expand Down
65 changes: 65 additions & 0 deletions modules/hostap/src/supp_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -1907,6 +1907,71 @@ int supplicant_set_bss_max_idle_period(const struct device *dev,
return wifi_mgmt_api->set_bss_max_idle_period(dev, bss_max_idle_period);
}

#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN
int supplicant_set_bgscan(const struct device *dev, struct wifi_bgscan_params *params)
{
struct wpa_supplicant *wpa_s;
struct wpa_ssid *ssid;
int ret = -1;

k_mutex_lock(&wpa_supplicant_mutex, K_FOREVER);

wpa_s = get_wpa_s_handle(dev);
if (wpa_s == NULL) {
wpa_printf(MSG_ERROR, "Interface %s not found", dev->name);
goto out;
}

ssid = wpa_s->current_ssid;
if (ssid == NULL) {
wpa_printf(MSG_ERROR, "SSID for %s not found", dev->name);
goto out;
}

switch (params->type) {
case WIFI_BGSCAN_SIMPLE:
if (!IS_ENABLED(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN_SIMPLE)) {
wpa_printf(MSG_ERROR, "Invalid bgscan type, enable "
"CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN_SIMPLE");
ret = -ENOTSUP;
goto out;
}
if (!wpa_cli_cmd_v("set_network %d bgscan \"simple:%d:%d:%d:%d\"", ssid->id,
params->short_interval, params->rssi_threshold,
params->long_interval, params->btm_queries)) {
goto out;
}
break;
case WIFI_BGSCAN_LEARN:
if (!IS_ENABLED(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN_LEARN)) {
wpa_printf(MSG_ERROR, "Invalid bgscan type, enable "
"CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN_LEARN");
ret = -ENOTSUP;
goto out;
}
if (!wpa_cli_cmd_v("set_network %d bgscan \"learn:%d:%d:%d\"", ssid->id,
params->short_interval, params->rssi_threshold,
params->long_interval)) {
goto out;
}
break;
case WIFI_BGSCAN_NONE:
default:
if (!wpa_cli_cmd_v("set_network %d bgscan \"\"", ssid->id)) {
goto out;
}
break;
}

ret = 0;

out:
k_mutex_unlock(&wpa_supplicant_mutex);

return ret;
}
#endif

#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM
int supplicant_btm_query(const struct device *dev, uint8_t reason)
{
Expand Down
11 changes: 11 additions & 0 deletions modules/hostap/src/supp_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,17 @@ int supplicant_wps_config(const struct device *dev, struct wifi_wps_config_param
*/
int supplicant_set_bss_max_idle_period(const struct device *dev,
unsigned short bss_max_idle_period);

#if defined(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN) || defined(__DOXYGEN__)
/** @ Set Wi-Fi background scanning parameters
*
* @param dev Wi-Fi interface handle to use
* @param params bgscan parameters
* @return 0 for OK; -1 for ERROR
*/
int supplicant_set_bgscan(const struct device *dev, struct wifi_bgscan_params *params);
#endif

#ifdef CONFIG_AP
int set_ap_bandwidth(const struct device *dev, enum wifi_frequency_bandwidths bandwidth);

Expand Down
3 changes: 3 additions & 0 deletions modules/hostap/src/supp_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,9 @@ static const struct wifi_mgmt_ops mgmt_ops = {
.get_conn_params = supplicant_get_wifi_conn_params,
.wps_config = supplicant_wps_config,
.set_bss_max_idle_period = supplicant_set_bss_max_idle_period,
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN
.set_bgscan = supplicant_set_bgscan,
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN */
#ifdef CONFIG_AP
.ap_enable = supplicant_ap_enable,
.ap_disable = supplicant_ap_disable,
Expand Down
25 changes: 25 additions & 0 deletions subsys/net/l2/wifi/wifi_mgmt.c
Original file line number Diff line number Diff line change
Expand Up @@ -1450,6 +1450,31 @@ static int wifi_set_bss_max_idle_period(uint64_t mgmt_request, struct net_if *if
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_BSS_MAX_IDLE_PERIOD,
wifi_set_bss_max_idle_period);

#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN
static int wifi_set_bgscan(uint64_t mgmt_request, struct net_if *iface, void *data, size_t len)
{
const struct device *dev = net_if_get_device(iface);
const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
struct wifi_bgscan_params *params = data;

if (wifi_mgmt_api == NULL || wifi_mgmt_api->set_bgscan == NULL) {
return -ENOTSUP;
}

if (!net_if_is_admin_up(iface)) {
return -ENETDOWN;
}

if (data == NULL || len != sizeof(*params)) {
return -EINVAL;
}

return wifi_mgmt_api->set_bgscan(dev, params);
}

NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_BGSCAN, wifi_set_bgscan);
#endif

#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS
void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface,
struct wifi_raw_scan_result *raw_scan_result)
Expand Down
Loading