Interworking: Add support for QoS Mapping functionality for the STA
Indicate support for QoS Mapping and configure driver to update the QoS Map if QoS Map Set elements is received from the AP either in (Re)Association Response or QoS Map Configure frame. This commit adds support for receiving the frames with nl80211 drivers, but the actual QoS Map configuration command is still missing. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
850e1c2579
commit
56f5af489c
6 changed files with 79 additions and 0 deletions
|
@ -276,6 +276,12 @@ ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
|
|||
elems->interworking = pos;
|
||||
elems->interworking_len = elen;
|
||||
break;
|
||||
case WLAN_EID_QOS_MAP_SET:
|
||||
if (elen < 16)
|
||||
break;
|
||||
elems->qos_map_set = pos;
|
||||
elems->qos_map_set_len = elen;
|
||||
break;
|
||||
case WLAN_EID_EXT_CAPAB:
|
||||
elems->ext_capab = pos;
|
||||
elems->ext_capab_len = elen;
|
||||
|
|
|
@ -40,6 +40,7 @@ struct ieee802_11_elems {
|
|||
const u8 *wfd;
|
||||
const u8 *link_id;
|
||||
const u8 *interworking;
|
||||
const u8 *qos_map_set;
|
||||
const u8 *hs20;
|
||||
const u8 *ext_capab;
|
||||
const u8 *bss_max_idle_period;
|
||||
|
@ -73,6 +74,7 @@ struct ieee802_11_elems {
|
|||
u8 p2p_len;
|
||||
u8 wfd_len;
|
||||
u8 interworking_len;
|
||||
u8 qos_map_set_len;
|
||||
u8 hs20_len;
|
||||
u8 ext_capab_len;
|
||||
u8 ssid_list_len;
|
||||
|
|
|
@ -3805,6 +3805,11 @@ static int nl80211_mgmt_subscribe_non_ap(struct i802_bss *bss)
|
|||
wpa_printf(MSG_DEBUG, "nl80211: Subscribe to mgmt frames with non-AP "
|
||||
"handle %p", bss->nl_mgmt);
|
||||
|
||||
#ifdef CONFIG_INTERWORKING
|
||||
/* QoS Map Configure */
|
||||
if (nl80211_register_action_frame(bss, (u8 *) "\x01\x04", 2) < 0)
|
||||
return -1;
|
||||
#endif /* CONFIG_INTERWORKING */
|
||||
#if defined(CONFIG_P2P) || defined(CONFIG_INTERWORKING)
|
||||
/* GAS Initial Request */
|
||||
if (nl80211_register_action_frame(bss, (u8 *) "\x04\x0a", 2) < 0)
|
||||
|
|
|
@ -708,4 +708,13 @@ static inline int wpa_drv_status(struct wpa_supplicant *wpa_s,
|
|||
return wpa_s->driver->status(wpa_s->drv_priv, buf, buflen);
|
||||
}
|
||||
|
||||
static inline int wpa_drv_set_qos_map(struct wpa_supplicant *wpa_s,
|
||||
const u8 *qos_map_set, u8 qos_map_set_len)
|
||||
{
|
||||
if (!wpa_s->driver->set_qos_map)
|
||||
return -1;
|
||||
return wpa_s->driver->set_qos_map(wpa_s->drv_priv, qos_map_set,
|
||||
qos_map_set_len);
|
||||
}
|
||||
|
||||
#endif /* DRIVER_I_H */
|
||||
|
|
|
@ -1503,6 +1503,43 @@ void wnm_bss_keep_alive_deinit(struct wpa_supplicant *wpa_s)
|
|||
}
|
||||
|
||||
|
||||
#ifdef CONFIG_INTERWORKING
|
||||
|
||||
static int wpas_qos_map_set(struct wpa_supplicant *wpa_s, const u8 *qos_map,
|
||||
size_t len)
|
||||
{
|
||||
int res;
|
||||
|
||||
wpa_hexdump(MSG_DEBUG, "Interworking: QoS Map Set", qos_map, len);
|
||||
res = wpa_drv_set_qos_map(wpa_s, qos_map, len);
|
||||
if (res) {
|
||||
wpa_printf(MSG_DEBUG, "Interworking: Failed to configure QoS Map Set to the driver");
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
static void interworking_process_assoc_resp(struct wpa_supplicant *wpa_s,
|
||||
const u8 *ies, size_t ies_len)
|
||||
{
|
||||
struct ieee802_11_elems elems;
|
||||
|
||||
if (ies == NULL)
|
||||
return;
|
||||
|
||||
if (ieee802_11_parse_elems(ies, ies_len, &elems, 1) == ParseFailed)
|
||||
return;
|
||||
|
||||
if (elems.qos_map_set) {
|
||||
wpas_qos_map_set(wpa_s, elems.qos_map_set,
|
||||
elems.qos_map_set_len);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* CONFIG_INTERWORKING */
|
||||
|
||||
|
||||
static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
|
||||
union wpa_event_data *data)
|
||||
{
|
||||
|
@ -1527,6 +1564,10 @@ static int wpa_supplicant_event_associnfo(struct wpa_supplicant *wpa_s,
|
|||
wnm_process_assoc_resp(wpa_s, data->assoc_info.resp_ies,
|
||||
data->assoc_info.resp_ies_len);
|
||||
#endif /* CONFIG_WNM */
|
||||
#ifdef CONFIG_INTERWORKING
|
||||
interworking_process_assoc_resp(wpa_s, data->assoc_info.resp_ies,
|
||||
data->assoc_info.resp_ies_len);
|
||||
#endif /* CONFIG_INTERWORKING */
|
||||
}
|
||||
if (data->assoc_info.beacon_ies)
|
||||
wpa_hexdump(MSG_DEBUG, "beacon_ies",
|
||||
|
@ -2906,6 +2947,19 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
|
|||
break;
|
||||
}
|
||||
#endif /* CONFIG_TDLS */
|
||||
#ifdef CONFIG_INTERWORKING
|
||||
if (data->rx_action.category == WLAN_ACTION_QOS &&
|
||||
data->rx_action.len >= 1 &&
|
||||
data->rx_action.data[0] == QOS_QOS_MAP_CONFIG) {
|
||||
wpa_dbg(wpa_s, MSG_DEBUG, "Interworking: Received QoS Map Configure frame from "
|
||||
MACSTR, MAC2STR(data->rx_action.sa));
|
||||
if (os_memcmp(data->rx_action.sa, wpa_s->bssid, ETH_ALEN)
|
||||
== 0)
|
||||
wpas_qos_map_set(wpa_s, data->rx_action.data + 1,
|
||||
data->rx_action.len - 1);
|
||||
break;
|
||||
}
|
||||
#endif /* CONFIG_INTERWORKING */
|
||||
#ifdef CONFIG_P2P
|
||||
wpas_p2p_rx_action(wpa_s, data->rx_action.da,
|
||||
data->rx_action.sa,
|
||||
|
|
|
@ -1219,6 +1219,9 @@ static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
|
|||
#endif /* CONFIG_INTERWORKING */
|
||||
break;
|
||||
case 4: /* Bits 32-39 */
|
||||
#ifdef CONFIG_INTERWORKING
|
||||
*pos |= 0x01; /* Bit 32 - QoS Map */
|
||||
#endif /* CONFIG_INTERWORKING */
|
||||
break;
|
||||
case 5: /* Bits 40-47 */
|
||||
break;
|
||||
|
|
Loading…
Reference in a new issue