Skip to content

Commit 4d633d7

Browse files
committed
modules: hostap: Support bgscan
Add configuration options for background scanning (bgscan) in wpa_supplicant. Signed-off-by: Pieter De Gendt <[email protected]>
1 parent 9eb8bee commit 4d633d7

File tree

7 files changed

+197
-0
lines changed

7 files changed

+197
-0
lines changed

include/zephyr/net/wifi_mgmt.h

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,8 @@ enum net_request_wifi_cmd {
137137
NET_REQUEST_WIFI_CMD_AP_WPS_CONFIG,
138138
/** Configure BSS maximum idle period */
139139
NET_REQUEST_WIFI_CMD_BSS_MAX_IDLE_PERIOD,
140+
/** Configure background scanning */
141+
NET_REQUEST_WIFI_CMD_BGSCAN,
140142
/** @cond INTERNAL_HIDDEN */
141143
NET_REQUEST_WIFI_CMD_MAX
142144
/** @endcond */
@@ -332,6 +334,11 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_NEIGHBOR_REP_COMPLETE);
332334

333335
NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_BSS_MAX_IDLE_PERIOD);
334336

337+
#define NET_REQUEST_WIFI_BGSCAN \
338+
(NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_BGSCAN)
339+
340+
NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_BGSCAN);
341+
335342
/** @cond INTERNAL_HIDDEN */
336343

337344
enum {
@@ -1393,6 +1400,32 @@ enum wifi_sap_iface_state {
13931400
WIFI_SAP_IFACE_ENABLED
13941401
};
13951402

1403+
#if defined(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN) || defined(__DOXYGEN__)
1404+
/** @brief Wi-Fi background scan implementation */
1405+
enum wifi_bgscan_type {
1406+
/** None, background scan is disabled */
1407+
WIFI_BGSCAN_NONE = 0,
1408+
/** Simple, periodic scan based on signal strength */
1409+
WIFI_BGSCAN_SIMPLE,
1410+
/** Learn channels used by the network (experimental) */
1411+
WIFI_BGSCAN_LEARN,
1412+
};
1413+
1414+
/** @brief Wi-Fi background scan parameters */
1415+
struct wifi_bgscan_params {
1416+
/** The type of background scanning */
1417+
enum wifi_bgscan_type type;
1418+
/** Short scan interval in seconds */
1419+
uint16_t short_interval;
1420+
/** Long scan interval in seconds */
1421+
uint16_t long_interval;
1422+
/** Signal strength threshold in dBm */
1423+
int8_t rssi_threshold;
1424+
/** Number of BSS Transition Management (BTM) queries */
1425+
uint16_t btm_queries;
1426+
};
1427+
#endif
1428+
13961429
/* Extended Capabilities */
13971430
enum wifi_ext_capab {
13981431
WIFI_EXT_CAPAB_20_40_COEX = 0,
@@ -1732,6 +1765,16 @@ struct wifi_mgmt_ops {
17321765
*/
17331766
int (*set_bss_max_idle_period)(const struct device *dev,
17341767
unsigned short bss_max_idle_period);
1768+
#if defined(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN) || defined(__DOXYGEN__)
1769+
/** Configure background scanning
1770+
*
1771+
* @param dev Pointer to the device structure for the driver instance.
1772+
* @param params Background scanning configuration parameters
1773+
*
1774+
* @return 0 if ok, < 0 if error
1775+
*/
1776+
int (*set_bgscan)(const struct device *dev, struct wifi_bgscan_params *params);
1777+
#endif
17351778
};
17361779

17371780
/** Wi-Fi management offload API */

modules/hostap/CMakeLists.txt

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,16 @@ zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM
7878
CONFIG_WNM
7979
)
8080

81+
zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN
82+
CONFIG_BGSCAN
83+
)
84+
zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN_SIMPLE
85+
CONFIG_BGSCAN_SIMPLE
86+
)
87+
zephyr_library_compile_definitions_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN_LEARN
88+
CONFIG_BGSCAN_LEARN
89+
)
90+
8191
zephyr_library_include_directories(
8292
${CMAKE_CURRENT_SOURCE_DIR}/src
8393
${HOSTAP_BASE}/
@@ -156,6 +166,16 @@ zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM
156166
${WIFI_NM_WPA_SUPPLICANT_BASE}/wnm_sta.c
157167
)
158168

169+
zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN
170+
${WIFI_NM_WPA_SUPPLICANT_BASE}/bgscan.c
171+
)
172+
zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN_SIMPLE
173+
${WIFI_NM_WPA_SUPPLICANT_BASE}/bgscan_simple.c
174+
)
175+
zephyr_library_sources_ifdef(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN_LEARN
176+
${WIFI_NM_WPA_SUPPLICANT_BASE}/bgscan_learn.c
177+
)
178+
159179
zephyr_library_sources_ifdef(CONFIG_WPA_CLI
160180
src/wpa_cli.c
161181
)

modules/hostap/Kconfig

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -455,6 +455,27 @@ config WIFI_NM_WPA_SUPPLICANT_SKIP_DHCP_ON_ROAMING
455455
needs to get new IP address after roaming to new AP. Disable this to keep
456456
DHCP after roaming.
457457

458+
config WIFI_NM_WPA_SUPPLICANT_BGSCAN
459+
bool "Background scanning (for legacy roaming), recommended if 802.11r is not supported"
460+
depends on WIFI_NM_WPA_SUPPLICANT_WNM
461+
depends on !WIFI_NM_WPA_SUPPLICANT_ROAMING
462+
463+
if WIFI_NM_WPA_SUPPLICANT_BGSCAN
464+
465+
config WIFI_NM_WPA_SUPPLICANT_BGSCAN_SIMPLE
466+
bool "Simple background scanning"
467+
default y
468+
help
469+
Periodic background scans based on signal strength.
470+
471+
config WIFI_NM_WPA_SUPPLICANT_BGSCAN_LEARN
472+
bool "Learning"
473+
help
474+
Learn channels used by the network and try to avoid
475+
background scans on other channels (experimental).
476+
477+
endif # WIFI_NM_WPA_SUPPLICANT_BGSCAN
478+
458479
# Create hidden config options that are used in hostap. This way we do not need
459480
# to mark them as allowed for CI checks, and also someone else cannot use the
460481
# same name options.
@@ -486,6 +507,15 @@ config NO_RANDOM_POOL
486507
config WNM
487508
bool
488509

510+
config BGSCAN
511+
bool
512+
513+
config BGSCAN_SIMPLE
514+
bool
515+
516+
config BGSCAN_LEARN
517+
bool
518+
489519
config NO_WPA
490520
bool
491521
default y if WIFI_NM_WPA_SUPPLICANT_CRYPTO_NONE

modules/hostap/src/supp_api.c

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1900,6 +1900,71 @@ int supplicant_set_bss_max_idle_period(const struct device *dev,
19001900
return wifi_mgmt_api->set_bss_max_idle_period(dev, bss_max_idle_period);
19011901
}
19021902

1903+
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN
1904+
int supplicant_set_bgscan(const struct device *dev, struct wifi_bgscan_params *params)
1905+
{
1906+
struct wpa_supplicant *wpa_s;
1907+
struct wpa_ssid *ssid;
1908+
int ret = -1;
1909+
1910+
k_mutex_lock(&wpa_supplicant_mutex, K_FOREVER);
1911+
1912+
wpa_s = get_wpa_s_handle(dev);
1913+
if (wpa_s == NULL) {
1914+
wpa_printf(MSG_ERROR, "Interface %s not found", dev->name);
1915+
goto out;
1916+
}
1917+
1918+
ssid = wpa_s->current_ssid;
1919+
if (ssid == NULL) {
1920+
wpa_printf(MSG_ERROR, "SSID for %s not found", dev->name);
1921+
goto out;
1922+
}
1923+
1924+
switch (params->type) {
1925+
case WIFI_BGSCAN_SIMPLE:
1926+
if (!IS_ENABLED(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN_SIMPLE)) {
1927+
wpa_printf(MSG_ERROR, "Invalid bgscan type, enable "
1928+
"CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN_SIMPLE");
1929+
ret = -ENOTSUP;
1930+
goto out;
1931+
}
1932+
if (!wpa_cli_cmd_v("set_network %d bgscan \"simple:%d:%d:%d:%d\"", ssid->id,
1933+
params->short_interval, params->rssi_threshold,
1934+
params->long_interval, params->btm_queries)) {
1935+
goto out;
1936+
}
1937+
break;
1938+
case WIFI_BGSCAN_LEARN:
1939+
if (!IS_ENABLED(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN_LEARN)) {
1940+
wpa_printf(MSG_ERROR, "Invalid bgscan type, enable "
1941+
"CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN_LEARN");
1942+
ret = -ENOTSUP;
1943+
goto out;
1944+
}
1945+
if (!wpa_cli_cmd_v("set_network %d bgscan \"learn:%d:%d:%d\"", ssid->id,
1946+
params->short_interval, params->rssi_threshold,
1947+
params->long_interval)) {
1948+
goto out;
1949+
}
1950+
break;
1951+
case WIFI_BGSCAN_NONE:
1952+
default:
1953+
if (!wpa_cli_cmd_v("set_network %d bgscan \"\"", ssid->id)) {
1954+
goto out;
1955+
}
1956+
break;
1957+
}
1958+
1959+
ret = 0;
1960+
1961+
out:
1962+
k_mutex_unlock(&wpa_supplicant_mutex);
1963+
1964+
return ret;
1965+
}
1966+
#endif
1967+
19031968
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM
19041969
int supplicant_btm_query(const struct device *dev, uint8_t reason)
19051970
{

modules/hostap/src/supp_api.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -321,6 +321,17 @@ int supplicant_wps_config(const struct device *dev, struct wifi_wps_config_param
321321
*/
322322
int supplicant_set_bss_max_idle_period(const struct device *dev,
323323
unsigned short bss_max_idle_period);
324+
325+
#if defined(CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN) || defined(__DOXYGEN__)
326+
/** @ Set Wi-Fi background scanning parameters
327+
*
328+
* @param dev Wi-Fi interface handle to use
329+
* @param params bgscan parameters
330+
* @return 0 for OK; -1 for ERROR
331+
*/
332+
int supplicant_set_bgscan(const struct device *dev, struct wifi_bgscan_params *params);
333+
#endif
334+
324335
#ifdef CONFIG_AP
325336
int set_ap_bandwidth(const struct device *dev, enum wifi_frequency_bandwidths bandwidth);
326337

modules/hostap/src/supp_main.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,9 @@ static const struct wifi_mgmt_ops mgmt_ops = {
8585
.get_conn_params = supplicant_get_wifi_conn_params,
8686
.wps_config = supplicant_wps_config,
8787
.set_bss_max_idle_period = supplicant_set_bss_max_idle_period,
88+
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN
89+
.set_bgscan = supplicant_set_bgscan,
90+
#endif /* CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN */
8891
#ifdef CONFIG_AP
8992
.ap_enable = supplicant_ap_enable,
9093
.ap_disable = supplicant_ap_disable,

subsys/net/l2/wifi/wifi_mgmt.c

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1449,6 +1449,31 @@ static int wifi_set_bss_max_idle_period(uint64_t mgmt_request, struct net_if *if
14491449
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_BSS_MAX_IDLE_PERIOD,
14501450
wifi_set_bss_max_idle_period);
14511451

1452+
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_BGSCAN
1453+
static int wifi_set_bgscan(uint64_t mgmt_request, struct net_if *iface, void *data, size_t len)
1454+
{
1455+
const struct device *dev = net_if_get_device(iface);
1456+
const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface);
1457+
struct wifi_bgscan_params *params = data;
1458+
1459+
if (wifi_mgmt_api == NULL || wifi_mgmt_api->set_bgscan == NULL) {
1460+
return -ENOTSUP;
1461+
}
1462+
1463+
if (!net_if_is_admin_up(iface)) {
1464+
return -ENETDOWN;
1465+
}
1466+
1467+
if (data == NULL || len != sizeof(*params)) {
1468+
return -EINVAL;
1469+
}
1470+
1471+
return wifi_mgmt_api->set_bgscan(dev, params);
1472+
}
1473+
1474+
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_BGSCAN, wifi_set_bgscan);
1475+
#endif
1476+
14521477
#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS
14531478
void wifi_mgmt_raise_raw_scan_result_event(struct net_if *iface,
14541479
struct wifi_raw_scan_result *raw_scan_result)

0 commit comments

Comments
 (0)