MBO: Add support to send ANQP request to get cellular preference
This extends ANQP_GET command to support querying MBO cellular preference also. The cellular preference can be requested along with neigbor report by appending mbo:1 to the command arguments. For example: ANQP_GET <bssid> 272,mbo:1 Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
5b71cb552b
commit
8f47917493
6 changed files with 73 additions and 9 deletions
|
@ -1180,6 +1180,10 @@ enum wfa_wnm_notif_subelem_id {
|
|||
WFA_WNM_NOTIF_SUBELEM_CELL_DATA_CAPA = 3,
|
||||
};
|
||||
|
||||
/* MBO v0.0_r25, 4.3: MBO ANQP-elements */
|
||||
#define MBO_ANQP_OUI_TYPE 0x12
|
||||
#define MBO_ANQP_SUBTYPE_CELL_CONN_PREF 1
|
||||
|
||||
/* Wi-Fi Direct (P2P) */
|
||||
|
||||
#define P2P_OUI_TYPE 9
|
||||
|
|
|
@ -6383,6 +6383,7 @@ static int get_anqp(struct wpa_supplicant *wpa_s, char *dst)
|
|||
u16 id[MAX_ANQP_INFO_ID];
|
||||
size_t num_id = 0;
|
||||
u32 subtypes = 0;
|
||||
int get_cell_pref = 0;
|
||||
|
||||
used = hwaddr_aton2(dst, dst_addr);
|
||||
if (used < 0)
|
||||
|
@ -6400,6 +6401,15 @@ static int get_anqp(struct wpa_supplicant *wpa_s, char *dst)
|
|||
#else /* CONFIG_HS20 */
|
||||
return -1;
|
||||
#endif /* CONFIG_HS20 */
|
||||
} else if (os_strncmp(pos, "mbo:", 4) == 0) {
|
||||
#ifdef CONFIG_MBO
|
||||
int num = atoi(pos + 4);
|
||||
if (num != MBO_ANQP_SUBTYPE_CELL_CONN_PREF)
|
||||
return -1;
|
||||
get_cell_pref = 1;
|
||||
#else /* CONFIG_MBO */
|
||||
return -1;
|
||||
#endif /* CONFIG_MBO */
|
||||
} else {
|
||||
id[num_id] = atoi(pos);
|
||||
if (id[num_id])
|
||||
|
@ -6414,7 +6424,8 @@ static int get_anqp(struct wpa_supplicant *wpa_s, char *dst)
|
|||
if (num_id == 0)
|
||||
return -1;
|
||||
|
||||
return anqp_send_req(wpa_s, dst_addr, id, num_id, subtypes);
|
||||
return anqp_send_req(wpa_s, dst_addr, id, num_id, subtypes,
|
||||
get_cell_pref);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -2692,10 +2692,11 @@ void interworking_stop_fetch_anqp(struct wpa_supplicant *wpa_s)
|
|||
|
||||
|
||||
int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst,
|
||||
u16 info_ids[], size_t num_ids, u32 subtypes)
|
||||
u16 info_ids[], size_t num_ids, u32 subtypes,
|
||||
int get_cell_pref)
|
||||
{
|
||||
struct wpabuf *buf;
|
||||
struct wpabuf *hs20_buf = NULL;
|
||||
struct wpabuf *extra_buf = NULL;
|
||||
int ret = 0;
|
||||
int freq;
|
||||
struct wpa_bss *bss;
|
||||
|
@ -2718,15 +2719,31 @@ int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst,
|
|||
|
||||
#ifdef CONFIG_HS20
|
||||
if (subtypes != 0) {
|
||||
hs20_buf = wpabuf_alloc(100);
|
||||
if (hs20_buf == NULL)
|
||||
extra_buf = wpabuf_alloc(100);
|
||||
if (extra_buf == NULL)
|
||||
return -1;
|
||||
hs20_put_anqp_req(subtypes, NULL, 0, hs20_buf);
|
||||
hs20_put_anqp_req(subtypes, NULL, 0, extra_buf);
|
||||
}
|
||||
#endif /* CONFIG_HS20 */
|
||||
|
||||
buf = anqp_build_req(info_ids, num_ids, hs20_buf);
|
||||
wpabuf_free(hs20_buf);
|
||||
#ifdef CONFIG_MBO
|
||||
if (get_cell_pref) {
|
||||
struct wpabuf *mbo;
|
||||
|
||||
mbo = mbo_build_anqp_buf(wpa_s, bss);
|
||||
if (mbo) {
|
||||
if (wpabuf_resize(&extra_buf, wpabuf_len(mbo))) {
|
||||
wpabuf_free(extra_buf);
|
||||
return -1;
|
||||
}
|
||||
wpabuf_put_buf(extra_buf, mbo);
|
||||
wpabuf_free(mbo);
|
||||
}
|
||||
}
|
||||
#endif /* CONFIG_MBO */
|
||||
|
||||
buf = anqp_build_req(info_ids, num_ids, extra_buf);
|
||||
wpabuf_free(extra_buf);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
|
||||
|
|
|
@ -12,7 +12,8 @@
|
|||
enum gas_query_result;
|
||||
|
||||
int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst,
|
||||
u16 info_ids[], size_t num_ids, u32 subtypes);
|
||||
u16 info_ids[], size_t num_ids, u32 subtypes,
|
||||
int get_cell_pref);
|
||||
void anqp_resp_cb(void *ctx, const u8 *dst, u8 dialog_token,
|
||||
enum gas_query_result result,
|
||||
const struct wpabuf *adv_proto,
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include "utils/common.h"
|
||||
#include "common/ieee802_11_defs.h"
|
||||
#include "common/gas.h"
|
||||
#include "config.h"
|
||||
#include "wpa_supplicant_i.h"
|
||||
#include "driver_i.h"
|
||||
|
@ -805,3 +806,31 @@ void wpas_mbo_update_cell_capa(struct wpa_supplicant *wpa_s, u8 mbo_cell_capa)
|
|||
wpas_mbo_send_wnm_notification(wpa_s, cell_capa, 7);
|
||||
wpa_supplicant_set_default_scan_ies(wpa_s);
|
||||
}
|
||||
|
||||
|
||||
struct wpabuf * mbo_build_anqp_buf(struct wpa_supplicant *wpa_s,
|
||||
struct wpa_bss *bss)
|
||||
{
|
||||
struct wpabuf *anqp_buf;
|
||||
u8 *len_pos;
|
||||
|
||||
if (!wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE)) {
|
||||
wpa_printf(MSG_INFO, "MBO: " MACSTR
|
||||
" does not support MBO - cannot request MBO ANQP elements from it",
|
||||
MAC2STR(bss->bssid));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
anqp_buf = wpabuf_alloc(10);
|
||||
if (!anqp_buf)
|
||||
return NULL;
|
||||
|
||||
len_pos = gas_anqp_add_element(anqp_buf, ANQP_VENDOR_SPECIFIC);
|
||||
wpabuf_put_be24(anqp_buf, OUI_WFA);
|
||||
wpabuf_put_u8(anqp_buf, MBO_ANQP_OUI_TYPE);
|
||||
|
||||
wpabuf_put_u8(anqp_buf, MBO_ANQP_SUBTYPE_CELL_CONN_PREF);
|
||||
gas_anqp_set_element_len(anqp_buf, len_pos);
|
||||
|
||||
return anqp_buf;
|
||||
}
|
||||
|
|
|
@ -1204,6 +1204,8 @@ size_t wpas_mbo_ie_bss_trans_reject(struct wpa_supplicant *wpa_s, u8 *pos,
|
|||
size_t len,
|
||||
enum mbo_transition_reject_reason reason);
|
||||
void wpas_mbo_update_cell_capa(struct wpa_supplicant *wpa_s, u8 mbo_cell_capa);
|
||||
struct wpabuf * mbo_build_anqp_buf(struct wpa_supplicant *wpa_s,
|
||||
struct wpa_bss *bss);
|
||||
|
||||
/**
|
||||
* wpa_supplicant_ctrl_iface_ctrl_rsp_handle - Handle a control response
|
||||
|
|
Loading…
Reference in a new issue