diff --git a/include/zephyr/net/wifi_mgmt.h b/include/zephyr/net/wifi_mgmt.h index ac4b39e7c49..c7576ade067 100644 --- a/include/zephyr/net/wifi_mgmt.h +++ b/include/zephyr/net/wifi_mgmt.h @@ -1261,6 +1261,15 @@ enum wifi_sap_iface_state { WIFI_SAP_IFACE_ENABLED }; +/* Extended Capabilities */ +enum wifi_ext_capab { + WIFI_EXT_CAPAB_20_40_COEX = 0, + WIFI_EXT_CAPAB_GLK = 1, + WIFI_EXT_CAPAB_EXT_CHAN_SWITCH = 2, + WIFI_EXT_CAPAB_TIM_BROADCAST = 18, + WIFI_EXT_CAPAB_BSS_TRANSITION = 19, +}; + #include /** Scan result callback @@ -1454,6 +1463,23 @@ struct wifi_mgmt_ops { */ int (*btm_query)(const struct device *dev, uint8_t reason); #endif + /** Judge ap whether support the capability + * + * @param dev Pointer to the device structure for the driver instance. + * @param capab is the capability to judge + * + * @return 1 if support, 0 if not support + */ + int (*bss_ext_capab)(const struct device *dev, int capab); + + /** Send legacy scan + * + * @param dev Pointer to the device structure for the driver instance. + * + * @return 0 if ok, < 0 if error + */ + int (*legacy_roam)(const struct device *dev); + /** Get Version of WiFi driver and Firmware * * The driver that implements the get_version function must not use stack to allocate the diff --git a/modules/hostap/src/supp_api.c b/modules/hostap/src/supp_api.c index 519a3553832..e530ff4b1bd 100644 --- a/modules/hostap/src/supp_api.c +++ b/modules/hostap/src/supp_api.c @@ -13,6 +13,8 @@ #include "includes.h" #include "common.h" #include "common/defs.h" +#include "common/ieee802_11_defs.h" +#include "common/ieee802_11_common.h" #include "wpa_supplicant/config.h" #include "wpa_supplicant_i.h" #include "driver_i.h" @@ -26,6 +28,7 @@ #include "ap_drv_ops.h" #endif #include "supp_events.h" +#include "wpa_supplicant/bss.h" extern struct k_sem wpa_supplicant_ready_sem; extern struct wpa_global *global; @@ -1944,6 +1947,41 @@ int supplicant_get_rts_threshold(const struct device *dev, unsigned int *rts_thr return wifi_mgmt_api->get_rts_threshold(dev, rts_threshold); } +int supplicant_bss_ext_capab(const struct device *dev, int capab) +{ + struct wpa_supplicant *wpa_s; + int is_support = 0; + + wpa_s = get_wpa_s_handle(dev); + if (!wpa_s) { + wpa_printf(MSG_ERROR, "Interface %s not found", dev->name); + return 0; + } + + k_mutex_lock(&wpa_supplicant_mutex, K_FOREVER); + is_support = wpa_bss_ext_capab(wpa_s->current_bss, capab); + k_mutex_unlock(&wpa_supplicant_mutex); + + return is_support; +} + +int supplicant_legacy_roam(const struct device *dev) +{ + int ret = -1; + + k_mutex_lock(&wpa_supplicant_mutex, K_FOREVER); + if (!wpa_cli_cmd_v("scan")) { + goto out; + } + + ret = 0; + +out: + k_mutex_unlock(&wpa_supplicant_mutex); + + return ret; +} + #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM int supplicant_btm_query(const struct device *dev, uint8_t reason) { diff --git a/modules/hostap/src/supp_api.h b/modules/hostap/src/supp_api.h index f817e2939a9..cb4e7836f1c 100644 --- a/modules/hostap/src/supp_api.h +++ b/modules/hostap/src/supp_api.h @@ -252,6 +252,23 @@ int supplicant_get_rts_threshold(const struct device *dev, unsigned int *rts_thr int supplicant_btm_query(const struct device *dev, uint8_t reason); #endif +/** Send legacy roam + * + * @param dev Pointer to the device structure for the driver instance. + * + * @return 0 if ok, < 0 if error + */ +int supplicant_legacy_roam(const struct device *dev); + +/** Judge ap whether support the capability + * + * @param dev Pointer to the device structure for the driver instance. + * @param capab is the capability to judge + * + * @return 1 if support, 0 if not support + */ +int supplicant_bss_ext_capab(const struct device *dev, int capab); + /** Get Wi-Fi connection parameters recently used * * @param dev Pointer to the device structure for the driver instance diff --git a/modules/hostap/src/supp_main.c b/modules/hostap/src/supp_main.c index 7fc01b0a2e9..02aa85d0d2b 100644 --- a/modules/hostap/src/supp_main.c +++ b/modules/hostap/src/supp_main.c @@ -77,6 +77,8 @@ static const struct wifi_mgmt_ops mgmt_ops = { .channel = supplicant_channel, .set_rts_threshold = supplicant_set_rts_threshold, .get_rts_threshold = supplicant_get_rts_threshold, + .bss_ext_capab = supplicant_bss_ext_capab, + .legacy_roam = supplicant_legacy_roam, #ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM .btm_query = supplicant_btm_query, #endif diff --git a/subsys/net/l2/wifi/wifi_mgmt.c b/subsys/net/l2/wifi/wifi_mgmt.c index db758cb2b6c..4d124b64eb4 100644 --- a/subsys/net/l2/wifi/wifi_mgmt.c +++ b/subsys/net/l2/wifi/wifi_mgmt.c @@ -477,26 +477,34 @@ static int wifi_start_roaming(uint32_t mgmt_request, struct net_if *iface, const struct device *dev = net_if_get_device(iface); const struct wifi_mgmt_ops *const wifi_mgmt_api = get_wifi_api(iface); + if (wifi_mgmt_api == NULL) { + return -ENOTSUP; + } if (roaming_params.is_11r_used) { - if (wifi_mgmt_api == NULL || - wifi_mgmt_api->start_11r_roaming == NULL) { + if (wifi_mgmt_api->start_11r_roaming == NULL) { return -ENOTSUP; } return wifi_mgmt_api->start_11r_roaming(dev); } else if (roaming_params.is_11k_enabled) { memset(&roaming_params.neighbor_rep, 0x0, sizeof(roaming_params.neighbor_rep)); - if (wifi_mgmt_api == NULL - || wifi_mgmt_api->send_11k_neighbor_request == NULL) { + if (wifi_mgmt_api->send_11k_neighbor_request == NULL) { return -ENOTSUP; } return wifi_mgmt_api->send_11k_neighbor_request(dev, NULL); - } else if (wifi_mgmt_api == NULL || wifi_mgmt_api->btm_query == NULL) { + } else if (wifi_mgmt_api->bss_ext_capab && + wifi_mgmt_api->bss_ext_capab(dev, WIFI_EXT_CAPAB_BSS_TRANSITION)) { + if (wifi_mgmt_api->btm_query) { + return wifi_mgmt_api->btm_query(dev, 0x10); + } else { + return -ENOTSUP; + } + } else if (wifi_mgmt_api->legacy_roam) { + return wifi_mgmt_api->legacy_roam(dev); + } else { return -ENOTSUP; } - - return wifi_mgmt_api->btm_query(dev, 0x10); } NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_START_ROAMING, wifi_start_roaming);