MBO: Add option to add MBO query list to ANQP query
MBO techspec v0.0_r27 changed the MBO ANQP-element format. The MBO element in ANQP query should now include an MBO Query List element that contains a list of MBO elements to query. Add API to add the MBO Query List to an ANQP query. Format: ANQP_GET <addr> <info_id>[,<info_id>]...[,mbo:<subtype>...] Example for querying neighbor report with MBO cellular data connection preference: ANQP_GET <bssid> 272,mbo:2 Signed-off-by: Avraham Stern <avraham.stern@intel.com>
This commit is contained in:
parent
f7c25d1a50
commit
2316cb358c
6 changed files with 26 additions and 14 deletions
|
@ -1419,9 +1419,11 @@ enum wfa_wnm_notif_subelem_id {
|
||||||
WFA_WNM_NOTIF_SUBELEM_CELL_DATA_CAPA = 3,
|
WFA_WNM_NOTIF_SUBELEM_CELL_DATA_CAPA = 3,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* MBO v0.0_r25, 4.3: MBO ANQP-elements */
|
/* MBO v0.0_r27, 4.3: MBO ANQP-elements */
|
||||||
#define MBO_ANQP_OUI_TYPE 0x12
|
#define MBO_ANQP_OUI_TYPE 0x12
|
||||||
#define MBO_ANQP_SUBTYPE_CELL_CONN_PREF 1
|
#define MBO_ANQP_SUBTYPE_QUERY_LIST 1
|
||||||
|
#define MBO_ANQP_SUBTYPE_CELL_CONN_PREF 2
|
||||||
|
#define MAX_MBO_ANQP_SUBTYPE MBO_ANQP_SUBTYPE_CELL_CONN_PREF
|
||||||
|
|
||||||
/* Wi-Fi Direct (P2P) */
|
/* Wi-Fi Direct (P2P) */
|
||||||
|
|
||||||
|
|
|
@ -6712,7 +6712,7 @@ static int get_anqp(struct wpa_supplicant *wpa_s, char *dst)
|
||||||
u16 id[MAX_ANQP_INFO_ID];
|
u16 id[MAX_ANQP_INFO_ID];
|
||||||
size_t num_id = 0;
|
size_t num_id = 0;
|
||||||
u32 subtypes = 0;
|
u32 subtypes = 0;
|
||||||
int get_cell_pref = 0;
|
u32 mbo_subtypes = 0;
|
||||||
|
|
||||||
used = hwaddr_aton2(dst, dst_addr);
|
used = hwaddr_aton2(dst, dst_addr);
|
||||||
if (used < 0)
|
if (used < 0)
|
||||||
|
@ -6733,9 +6733,10 @@ static int get_anqp(struct wpa_supplicant *wpa_s, char *dst)
|
||||||
} else if (os_strncmp(pos, "mbo:", 4) == 0) {
|
} else if (os_strncmp(pos, "mbo:", 4) == 0) {
|
||||||
#ifdef CONFIG_MBO
|
#ifdef CONFIG_MBO
|
||||||
int num = atoi(pos + 4);
|
int num = atoi(pos + 4);
|
||||||
if (num != MBO_ANQP_SUBTYPE_CELL_CONN_PREF)
|
|
||||||
|
if (num <= 0 || num > MAX_MBO_ANQP_SUBTYPE)
|
||||||
return -1;
|
return -1;
|
||||||
get_cell_pref = 1;
|
mbo_subtypes |= BIT(num);
|
||||||
#else /* CONFIG_MBO */
|
#else /* CONFIG_MBO */
|
||||||
return -1;
|
return -1;
|
||||||
#endif /* CONFIG_MBO */
|
#endif /* CONFIG_MBO */
|
||||||
|
@ -6754,7 +6755,7 @@ static int get_anqp(struct wpa_supplicant *wpa_s, char *dst)
|
||||||
return -1;
|
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);
|
mbo_subtypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -2694,7 +2694,7 @@ void interworking_stop_fetch_anqp(struct wpa_supplicant *wpa_s)
|
||||||
|
|
||||||
int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst,
|
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)
|
u32 mbo_subtypes)
|
||||||
{
|
{
|
||||||
struct wpabuf *buf;
|
struct wpabuf *buf;
|
||||||
struct wpabuf *extra_buf = NULL;
|
struct wpabuf *extra_buf = NULL;
|
||||||
|
@ -2728,10 +2728,10 @@ int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst,
|
||||||
#endif /* CONFIG_HS20 */
|
#endif /* CONFIG_HS20 */
|
||||||
|
|
||||||
#ifdef CONFIG_MBO
|
#ifdef CONFIG_MBO
|
||||||
if (get_cell_pref) {
|
if (mbo_subtypes) {
|
||||||
struct wpabuf *mbo;
|
struct wpabuf *mbo;
|
||||||
|
|
||||||
mbo = mbo_build_anqp_buf(wpa_s, bss);
|
mbo = mbo_build_anqp_buf(wpa_s, bss, mbo_subtypes);
|
||||||
if (mbo) {
|
if (mbo) {
|
||||||
if (wpabuf_resize(&extra_buf, wpabuf_len(mbo))) {
|
if (wpabuf_resize(&extra_buf, wpabuf_len(mbo))) {
|
||||||
wpabuf_free(extra_buf);
|
wpabuf_free(extra_buf);
|
||||||
|
|
|
@ -13,7 +13,7 @@ enum gas_query_result;
|
||||||
|
|
||||||
int anqp_send_req(struct wpa_supplicant *wpa_s, const u8 *dst,
|
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);
|
u32 mbo_subtypes);
|
||||||
void anqp_resp_cb(void *ctx, const u8 *dst, u8 dialog_token,
|
void anqp_resp_cb(void *ctx, const u8 *dst, u8 dialog_token,
|
||||||
enum gas_query_result result,
|
enum gas_query_result result,
|
||||||
const struct wpabuf *adv_proto,
|
const struct wpabuf *adv_proto,
|
||||||
|
|
|
@ -515,10 +515,11 @@ 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 wpabuf * mbo_build_anqp_buf(struct wpa_supplicant *wpa_s,
|
||||||
struct wpa_bss *bss)
|
struct wpa_bss *bss, u32 mbo_subtypes)
|
||||||
{
|
{
|
||||||
struct wpabuf *anqp_buf;
|
struct wpabuf *anqp_buf;
|
||||||
u8 *len_pos;
|
u8 *len_pos;
|
||||||
|
u8 i;
|
||||||
|
|
||||||
if (!wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE)) {
|
if (!wpa_bss_get_vendor_ie(bss, MBO_IE_VENDOR_TYPE)) {
|
||||||
wpa_printf(MSG_INFO, "MBO: " MACSTR
|
wpa_printf(MSG_INFO, "MBO: " MACSTR
|
||||||
|
@ -527,7 +528,8 @@ struct wpabuf * mbo_build_anqp_buf(struct wpa_supplicant *wpa_s,
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
anqp_buf = wpabuf_alloc(10);
|
/* Allocate size for the maximum case - all MBO subtypes are set */
|
||||||
|
anqp_buf = wpabuf_alloc(9 + MAX_MBO_ANQP_SUBTYPE);
|
||||||
if (!anqp_buf)
|
if (!anqp_buf)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -535,7 +537,14 @@ struct wpabuf * mbo_build_anqp_buf(struct wpa_supplicant *wpa_s,
|
||||||
wpabuf_put_be24(anqp_buf, OUI_WFA);
|
wpabuf_put_be24(anqp_buf, OUI_WFA);
|
||||||
wpabuf_put_u8(anqp_buf, MBO_ANQP_OUI_TYPE);
|
wpabuf_put_u8(anqp_buf, MBO_ANQP_OUI_TYPE);
|
||||||
|
|
||||||
wpabuf_put_u8(anqp_buf, MBO_ANQP_SUBTYPE_CELL_CONN_PREF);
|
wpabuf_put_u8(anqp_buf, MBO_ANQP_SUBTYPE_QUERY_LIST);
|
||||||
|
|
||||||
|
/* The first valid MBO subtype is 1 */
|
||||||
|
for (i = 1; i <= MAX_MBO_ANQP_SUBTYPE; i++) {
|
||||||
|
if (mbo_subtypes & BIT(i))
|
||||||
|
wpabuf_put_u8(anqp_buf, i);
|
||||||
|
}
|
||||||
|
|
||||||
gas_anqp_set_element_len(anqp_buf, len_pos);
|
gas_anqp_set_element_len(anqp_buf, len_pos);
|
||||||
|
|
||||||
return anqp_buf;
|
return anqp_buf;
|
||||||
|
|
|
@ -1294,7 +1294,7 @@ size_t wpas_mbo_ie_bss_trans_reject(struct wpa_supplicant *wpa_s, u8 *pos,
|
||||||
enum mbo_transition_reject_reason reason);
|
enum mbo_transition_reject_reason reason);
|
||||||
void wpas_mbo_update_cell_capa(struct wpa_supplicant *wpa_s, u8 mbo_cell_capa);
|
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 wpabuf * mbo_build_anqp_buf(struct wpa_supplicant *wpa_s,
|
||||||
struct wpa_bss *bss);
|
struct wpa_bss *bss, u32 mbo_subtypes);
|
||||||
|
|
||||||
/* op_classes.c */
|
/* op_classes.c */
|
||||||
enum chan_allowed {
|
enum chan_allowed {
|
||||||
|
|
Loading…
Reference in a new issue