hostap: add 11v BTM query support

Add 11v BTM query L2 layer cmd support.

Signed-off-by: Rex Chen <rex.chen_1@nxp.com>
This commit is contained in:
Rex Chen 2024-07-23 20:22:50 -07:00 committed by Anas Nashif
parent ff7bb3e85c
commit 1b8fa46ac1
7 changed files with 130 additions and 0 deletions

View file

@ -492,6 +492,20 @@ static const char * const wifi_ps_param_config_err_code_tbl[] = {
};
/** @endcond */
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM
/** IEEE 802.11v BTM (BSS transition management) Query reasons.
* Refer to IEEE Std 802.11v-2011 - Table 7-43x-Transition and Transition Query reasons table.
*/
enum wifi_btm_query_reason {
/** Unspecified. */
WIFI_BTM_QUERY_REASON_UNSPECIFIED = 0,
/** Low RSSI. */
WIFI_BTM_QUERY_REASON_LOW_RSSI = 16,
/** Leaving ESS. */
WIFI_BTM_QUERY_REASON_LEAVING_ESS = 20,
};
#endif
/** Helper function to get user-friendly power save error code name. */
static inline const char *wifi_ps_get_config_err_code_str(int16_t err_no)
{

View file

@ -94,6 +94,10 @@ enum net_request_wifi_cmd {
NET_REQUEST_WIFI_CMD_AP_CONFIG_PARAM,
/** DPP actions */
NET_REQUEST_WIFI_CMD_DPP,
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM
/** BSS transition management query */
NET_REQUEST_WIFI_CMD_BTM_QUERY,
#endif
/** @cond INTERNAL_HIDDEN */
NET_REQUEST_WIFI_CMD_MAX
/** @endcond */
@ -207,6 +211,13 @@ NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_AP_CONFIG_PARAM);
NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_DPP);
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM
/** Request a Wi-Fi BTM query */
#define NET_REQUEST_WIFI_BTM_QUERY (_NET_WIFI_BASE | NET_REQUEST_WIFI_CMD_BTM_QUERY)
NET_MGMT_DEFINE_REQUEST_HANDLER(NET_REQUEST_WIFI_BTM_QUERY);
#endif
/** @brief Wi-Fi management events */
enum net_event_wifi_cmd {
/** Scan results available */
@ -1110,6 +1121,16 @@ struct wifi_mgmt_ops {
* @return 0 if ok, < 0 if error
*/
int (*channel)(const struct device *dev, struct wifi_channel_info *channel);
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM
/** Send BTM query
*
* @param dev Pointer to the device structure for the driver instance.
* @param reason query reason
*
* @return 0 if ok, < 0 if error
*/
int (*btm_query)(const struct device *dev, uint8_t reason);
#endif
/** Get Version of WiFi driver and Firmware
*
* The driver that implements the get_version function must not use stack to allocate the

View file

@ -929,6 +929,34 @@ int supplicant_channel(const struct device *dev, struct wifi_channel_info *chann
return wifi_mgmt_api->channel(dev, channel);
}
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM
int supplicant_btm_query(const struct device *dev, uint8_t reason)
{
struct wpa_supplicant *wpa_s;
int ret = -1;
k_mutex_lock(&wpa_supplicant_mutex, K_FOREVER);
wpa_s = get_wpa_s_handle(dev);
if (!wpa_s) {
ret = -1;
wpa_printf(MSG_ERROR, "Interface %s not found", dev->name);
goto out;
}
if (!wpa_cli_cmd_v("wnm_bss_query %d", reason)) {
goto out;
}
ret = 0;
out:
k_mutex_unlock(&wpa_supplicant_mutex);
return ret;
}
#endif
#ifdef CONFIG_AP
int supplicant_ap_enable(const struct device *dev,
struct wifi_connect_req_params *params)

View file

@ -148,6 +148,17 @@ int supplicant_filter(const struct device *dev, struct wifi_filter_info *filter)
*/
int supplicant_channel(const struct device *dev, struct wifi_channel_info *channel);
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM
/** Send bss transition query
*
* @param dev Pointer to the device structure for the driver instance.
* @param reason query reason
*
* @return 0 if ok, < 0 if error
*/
int supplicant_btm_query(const struct device *dev, uint8_t reason);
#endif
#ifdef CONFIG_AP
/**
* @brief Set Wi-Fi AP configuration

View file

@ -61,6 +61,9 @@ static const struct wifi_mgmt_ops mgmt_ops = {
.mode = supplicant_mode,
.filter = supplicant_filter,
.channel = supplicant_channel,
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM
.btm_query = supplicant_btm_query,
#endif
#ifdef CONFIG_AP
.ap_enable = supplicant_ap_enable,
.ap_disable = supplicant_ap_disable,

View file

@ -775,6 +775,28 @@ static int wifi_get_version(uint32_t mgmt_request, struct net_if *iface,
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_VERSION, wifi_get_version);
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM
static int wifi_btm_query(uint32_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);
uint8_t query_reason = *((uint8_t *)data);
if (wifi_mgmt_api == NULL || wifi_mgmt_api->btm_query == NULL) {
return -ENOTSUP;
}
if (query_reason >= WIFI_BTM_QUERY_REASON_UNSPECIFIED &&
query_reason <= WIFI_BTM_QUERY_REASON_LEAVING_ESS) {
return wifi_mgmt_api->btm_query(dev, query_reason);
}
return -EINVAL;
}
NET_MGMT_REGISTER_REQUEST_HANDLER(NET_REQUEST_WIFI_BTM_QUERY, wifi_btm_query);
#endif
static int wifi_set_rts_threshold(uint32_t mgmt_request, struct net_if *iface,
void *data, size_t len)
{

View file

@ -1570,6 +1570,30 @@ static int cmd_wifi_listen_interval(const struct shell *sh, size_t argc, char *a
return 0;
}
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM
static int cmd_wifi_btm_query(const struct shell *sh, size_t argc, char *argv[])
{
struct net_if *iface = net_if_get_first_wifi();
uint8_t query_reason = 0;
context.sh = sh;
if (!parse_number(sh, (long *)&query_reason, argv[1], NULL,
WIFI_BTM_QUERY_REASON_UNSPECIFIED, WIFI_BTM_QUERY_REASON_LEAVING_ESS)) {
return -EINVAL;
}
if (net_mgmt(NET_REQUEST_WIFI_BTM_QUERY, iface, &query_reason, sizeof(query_reason))) {
PR_WARNING("Setting BTM query Reason failed..Reason :%d\n", query_reason);
return -ENOEXEC;
}
PR("Query reason %d\n", query_reason);
return 0;
}
#endif
static int cmd_wifi_ps_wakeup_mode(const struct shell *sh, size_t argc, char *argv[])
{
struct net_if *iface = net_if_get_first_wifi();
@ -2594,6 +2618,13 @@ SHELL_STATIC_SUBCMD_SET_CREATE(wifi_commands,
"wifi -i1 -c5.\n",
cmd_wifi_channel,
2, 4),
#ifdef CONFIG_WIFI_NM_WPA_SUPPLICANT_WNM
SHELL_CMD_ARG(11v_btm_query,
NULL,
"<query_reason: The reason code for a BSS transition management query>.\n",
cmd_wifi_btm_query,
2, 0),
#endif
SHELL_CMD_ARG(ps_timeout,
NULL,
"<val> - PS inactivity timer(in ms).\n",