MBO: Add MBO ANQP-element processing on AP

This extends the GAS server to process MBO ANQP-elements and reply to a
query for the Cellular Data Connection Preference (if configured). The
new configuration parameter mbo_cell_data_conn_pref can be used to set
the value (0, 1, or 255) for the preference to indicate.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2017-03-10 18:33:51 +02:00 committed by Jouni Malinen
parent 2453f2517c
commit 941caed980
6 changed files with 157 additions and 41 deletions

View File

@ -3442,6 +3442,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
#ifdef CONFIG_MBO
} else if (os_strcmp(buf, "mbo") == 0) {
bss->mbo_enabled = atoi(pos);
} else if (os_strcmp(buf, "mbo_cell_data_conn_pref") == 0) {
bss->mbo_cell_data_conn_pref = atoi(pos);
#endif /* CONFIG_MBO */
#ifdef CONFIG_TESTING_OPTIONS
#define PARSE_TEST_PROBABILITY(_val) \

View File

@ -2035,6 +2035,19 @@ own_ip_addr=127.0.0.1
#
#osu_server_uri=...
##### Multiband Operation (MBO) ###############################################
#
# MBO enabled
# 0 = disabled (default)
# 1 = enabled
#mbo=1
#
# Cellular data connection preference
# 0 = Excluded - AP does not want STA to use the cellular data connection
# 1 = AP prefers the STA not to use cellular data connection
# 255 = AP prefers the STA to use cellular data connection
#mbo_cell_data_conn_pref=1
##### Fast Session Transfer (FST) support #####################################
#
# The options in this section are only available when the build configuration

View File

@ -109,6 +109,10 @@ void hostapd_config_defaults_bss(struct hostapd_bss_config *bss)
#endif /* CONFIG_FILS */
bss->broadcast_deauth = 1;
#ifdef CONFIG_MBO
bss->mbo_cell_data_conn_pref = -1;
#endif /* CONFIG_MBO */
}

View File

@ -600,6 +600,7 @@ struct hostapd_bss_config {
#ifdef CONFIG_MBO
int mbo_enabled;
int mbo_cell_data_conn_pref;
#endif /* CONFIG_MBO */
int ftm_responder;

View File

@ -828,6 +828,22 @@ static void anqp_add_icon_binary_file(struct hostapd_data *hapd,
#endif /* CONFIG_HS20 */
#ifdef CONFIG_MBO
static void anqp_add_mbo_cell_data_conn_pref(struct hostapd_data *hapd,
struct wpabuf *buf)
{
if (hapd->conf->mbo_cell_data_conn_pref >= 0) {
u8 *len = gas_anqp_add_element(buf, ANQP_VENDOR_SPECIFIC);
wpabuf_put_be24(buf, OUI_WFA);
wpabuf_put_u8(buf, MBO_ANQP_OUI_TYPE);
wpabuf_put_u8(buf, MBO_ANQP_SUBTYPE_CELL_CONN_PREF);
wpabuf_put_u8(buf, hapd->conf->mbo_cell_data_conn_pref);
gas_anqp_set_element_len(buf, len);
}
}
#endif /* CONFIG_MBO */
static size_t anqp_get_required_len(struct hostapd_data *hapd,
const u16 *infoid,
unsigned int num_infoid)
@ -933,6 +949,11 @@ gas_serv_build_gas_resp_payload(struct hostapd_data *hapd,
anqp_add_icon_binary_file(hapd, buf, icon_name, icon_name_len);
#endif /* CONFIG_HS20 */
#ifdef CONFIG_MBO
if (request & ANQP_REQ_MBO_CELL_DATA_CONN_PREF)
anqp_add_mbo_cell_data_conn_pref(hapd, buf);
#endif /* CONFIG_MBO */
return buf;
}
@ -1152,49 +1173,12 @@ static void rx_anqp_hs_icon_request(struct hostapd_data *hapd,
}
static void rx_anqp_vendor_specific(struct hostapd_data *hapd,
const u8 *pos, const u8 *end,
struct anqp_query_info *qi)
static void rx_anqp_vendor_specific_hs20(struct hostapd_data *hapd,
const u8 *pos, const u8 *end,
struct anqp_query_info *qi)
{
u32 oui;
u8 subtype;
if (end - pos < 4) {
wpa_printf(MSG_DEBUG, "ANQP: Too short vendor specific ANQP "
"Query element");
return;
}
oui = WPA_GET_BE24(pos);
pos += 3;
if (oui != OUI_WFA) {
wpa_printf(MSG_DEBUG, "ANQP: Unsupported vendor OUI %06x",
oui);
return;
}
#ifdef CONFIG_P2P
if (*pos == P2P_OUI_TYPE) {
/*
* This is for P2P SD and will be taken care of by the P2P
* implementation. This query needs to be ignored in the generic
* GAS server to avoid duplicated response.
*/
wpa_printf(MSG_DEBUG,
"ANQP: Ignore WFA vendor type %u (P2P SD) in generic GAS server",
*pos);
qi->p2p_sd = 1;
return;
}
#endif /* CONFIG_P2P */
if (*pos != HS20_ANQP_OUI_TYPE) {
wpa_printf(MSG_DEBUG, "ANQP: Unsupported WFA vendor type %u",
*pos);
return;
}
pos++;
if (end - pos <= 1)
return;
@ -1224,6 +1208,115 @@ static void rx_anqp_vendor_specific(struct hostapd_data *hapd,
#endif /* CONFIG_HS20 */
#ifdef CONFIG_P2P
static void rx_anqp_vendor_specific_p2p(struct hostapd_data *hapd,
struct anqp_query_info *qi)
{
/*
* This is for P2P SD and will be taken care of by the P2P
* implementation. This query needs to be ignored in the generic
* GAS server to avoid duplicated response.
*/
wpa_printf(MSG_DEBUG,
"ANQP: Ignore WFA vendor type %u (P2P SD) in generic GAS server",
P2P_OUI_TYPE);
qi->p2p_sd = 1;
return;
}
#endif /* CONFIG_P2P */
#ifdef CONFIG_MBO
static void rx_anqp_mbo_query_list(struct hostapd_data *hapd, u8 subtype,
struct anqp_query_info *qi)
{
switch (subtype) {
case MBO_ANQP_SUBTYPE_CELL_CONN_PREF:
set_anqp_req(ANQP_REQ_MBO_CELL_DATA_CONN_PREF,
"Cellular Data Connection Preference",
hapd->conf->mbo_cell_data_conn_pref >= 0, qi);
break;
default:
wpa_printf(MSG_DEBUG, "ANQP: Unsupported MBO subtype %u",
subtype);
break;
}
}
static void rx_anqp_vendor_specific_mbo(struct hostapd_data *hapd,
const u8 *pos, const u8 *end,
struct anqp_query_info *qi)
{
u8 subtype;
if (end - pos < 1)
return;
subtype = *pos++;
switch (subtype) {
case MBO_ANQP_SUBTYPE_QUERY_LIST:
wpa_printf(MSG_DEBUG, "ANQP: MBO Query List");
while (pos < end) {
rx_anqp_mbo_query_list(hapd, *pos, qi);
pos++;
}
break;
default:
wpa_printf(MSG_DEBUG, "ANQP: Unsupported MBO query subtype %u",
subtype);
break;
}
}
#endif /* CONFIG_MBO */
static void rx_anqp_vendor_specific(struct hostapd_data *hapd,
const u8 *pos, const u8 *end,
struct anqp_query_info *qi)
{
u32 oui;
if (end - pos < 4) {
wpa_printf(MSG_DEBUG, "ANQP: Too short vendor specific ANQP "
"Query element");
return;
}
oui = WPA_GET_BE24(pos);
pos += 3;
if (oui != OUI_WFA) {
wpa_printf(MSG_DEBUG, "ANQP: Unsupported vendor OUI %06x",
oui);
return;
}
switch (*pos) {
#ifdef CONFIG_P2P
case P2P_OUI_TYPE:
rx_anqp_vendor_specific_p2p(hapd, qi);
break;
#endif /* CONFIG_P2P */
#ifdef CONFIG_HS20
case HS20_ANQP_OUI_TYPE:
rx_anqp_vendor_specific_hs20(hapd, pos + 1, end, qi);
break;
#endif /* CONFIG_HS20 */
#ifdef CONFIG_MBO
case MBO_ANQP_OUI_TYPE:
rx_anqp_vendor_specific_mbo(hapd, pos + 1, end, qi);
break;
#endif /* CONFIG_MBO */
default:
wpa_printf(MSG_DEBUG, "ANQP: Unsupported WFA vendor type %u",
*pos);
break;
}
}
static void gas_serv_req_local_processing(struct hostapd_data *hapd,
const u8 *sa, u8 dialog_token,
struct anqp_query_info *qi, int prot,

View File

@ -41,7 +41,7 @@
#define ANQP_REQ_EMERGENCY_NAI \
(1 << (ANQP_EMERGENCY_NAI - ANQP_QUERY_LIST))
/*
* First 16 Hotspot 2.0 vendor specific ANQP-elements can be included in the
* First 15 Hotspot 2.0 vendor specific ANQP-elements can be included in the
* optimized bitmap.
*/
#define ANQP_REQ_HS_CAPABILITY_LIST \
@ -60,6 +60,9 @@
(0x10000 << HS20_STYPE_OSU_PROVIDERS_LIST)
#define ANQP_REQ_ICON_REQUEST \
(0x10000 << HS20_STYPE_ICON_REQUEST)
/* The first MBO ANQP-element can be included in the optimized bitmap. */
#define ANQP_REQ_MBO_CELL_DATA_CONN_PREF \
(BIT(29) << MBO_ANQP_SUBTYPE_CELL_CONN_PREF)
struct gas_dialog_info {
u8 valid;