MBO: Update STA cellular data capability based on WNM Notification
This makes hostapd parse a received WNM Notification Request frame subelements and if a WFA MBO cellular data capability subelement is seen, update the cellular data capability for the STA. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
parent
6332aaf3b2
commit
8dd49f0cff
4 changed files with 82 additions and 0 deletions
|
@ -47,3 +47,68 @@ int mbo_ap_get_info(struct sta_info *sta, char *buf, size_t buflen)
|
||||||
return 0;
|
return 0;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void mbo_ap_wnm_notif_req_cell_capa(struct sta_info *sta,
|
||||||
|
const u8 *buf, size_t len)
|
||||||
|
{
|
||||||
|
if (len < 1)
|
||||||
|
return;
|
||||||
|
wpa_printf(MSG_DEBUG, "MBO: STA " MACSTR
|
||||||
|
" updated cellular data capability: %u",
|
||||||
|
MAC2STR(sta->addr), buf[0]);
|
||||||
|
sta->cell_capa = buf[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void mbo_ap_wnm_notif_req_elem(struct sta_info *sta, u8 type,
|
||||||
|
const u8 *buf, size_t len)
|
||||||
|
{
|
||||||
|
switch (type) {
|
||||||
|
case WFA_WNM_NOTIF_SUBELEM_CELL_DATA_CAPA:
|
||||||
|
mbo_ap_wnm_notif_req_cell_capa(sta, buf, len);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"MBO: Ignore unknown WNM Notification WFA subelement %u",
|
||||||
|
type);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void mbo_ap_wnm_notification_req(struct hostapd_data *hapd, const u8 *addr,
|
||||||
|
const u8 *buf, size_t len)
|
||||||
|
{
|
||||||
|
const u8 *pos, *end;
|
||||||
|
u8 ie_len;
|
||||||
|
struct sta_info *sta;
|
||||||
|
|
||||||
|
if (!hapd->conf->mbo_enabled)
|
||||||
|
return;
|
||||||
|
|
||||||
|
sta = ap_get_sta(hapd, addr);
|
||||||
|
if (!sta)
|
||||||
|
return;
|
||||||
|
|
||||||
|
pos = buf;
|
||||||
|
end = buf + len;
|
||||||
|
|
||||||
|
while (end - pos > 1) {
|
||||||
|
ie_len = pos[1];
|
||||||
|
|
||||||
|
if (2 + ie_len > end - pos)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (pos[0] == WLAN_EID_VENDOR_SPECIFIC &&
|
||||||
|
ie_len >= 4 && WPA_GET_BE24(pos + 2) == OUI_WFA)
|
||||||
|
mbo_ap_wnm_notif_req_elem(sta, pos[5],
|
||||||
|
pos + 6, ie_len - 4);
|
||||||
|
else
|
||||||
|
wpa_printf(MSG_DEBUG,
|
||||||
|
"MBO: Ignore unknown WNM Notification element %u (len=%u)",
|
||||||
|
pos[0], pos[1]);
|
||||||
|
|
||||||
|
pos += 2 + pos[1];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -18,6 +18,8 @@ struct ieee802_11_elems;
|
||||||
void mbo_ap_check_sta_assoc(struct hostapd_data *hapd, struct sta_info *sta,
|
void mbo_ap_check_sta_assoc(struct hostapd_data *hapd, struct sta_info *sta,
|
||||||
struct ieee802_11_elems *elems);
|
struct ieee802_11_elems *elems);
|
||||||
int mbo_ap_get_info(struct sta_info *sta, char *buf, size_t buflen);
|
int mbo_ap_get_info(struct sta_info *sta, char *buf, size_t buflen);
|
||||||
|
void mbo_ap_wnm_notification_req(struct hostapd_data *hapd, const u8 *addr,
|
||||||
|
const u8 *buf, size_t len);
|
||||||
|
|
||||||
#else /* CONFIG_MBO */
|
#else /* CONFIG_MBO */
|
||||||
|
|
||||||
|
@ -33,6 +35,12 @@ static inline int mbo_ap_get_info(struct sta_info *sta, char *buf,
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void mbo_ap_wnm_notification_req(struct hostapd_data *hapd,
|
||||||
|
const u8 *addr,
|
||||||
|
const u8 *buf, size_t len)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_MBO */
|
#endif /* CONFIG_MBO */
|
||||||
|
|
||||||
#endif /* MBO_AP_H */
|
#endif /* MBO_AP_H */
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
#include "ap/ap_config.h"
|
#include "ap/ap_config.h"
|
||||||
#include "ap/ap_drv_ops.h"
|
#include "ap/ap_drv_ops.h"
|
||||||
#include "ap/wpa_auth.h"
|
#include "ap/wpa_auth.h"
|
||||||
|
#include "mbo_ap.h"
|
||||||
#include "wnm_ap.h"
|
#include "wnm_ap.h"
|
||||||
|
|
||||||
#define MAX_TFS_IE_LEN 1024
|
#define MAX_TFS_IE_LEN 1024
|
||||||
|
@ -394,6 +395,8 @@ static void ieee802_11_rx_wnm_notification_req(struct hostapd_data *hapd,
|
||||||
MAC2STR(addr), dialog_token, type);
|
MAC2STR(addr), dialog_token, type);
|
||||||
wpa_hexdump(MSG_MSGDUMP, "WNM: Notification Request subelements",
|
wpa_hexdump(MSG_MSGDUMP, "WNM: Notification Request subelements",
|
||||||
buf, len);
|
buf, len);
|
||||||
|
if (type == WLAN_EID_VENDOR_SPECIFIC)
|
||||||
|
mbo_ap_wnm_notification_req(hapd, addr, buf, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1113,6 +1113,12 @@ enum mbo_transition_reject_reason {
|
||||||
MBO_TRANSITION_REJECT_REASON_SERVICES = 6,
|
MBO_TRANSITION_REJECT_REASON_SERVICES = 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* MBO v0.0_r19, 4.4: WNM-Notification vendor subelements */
|
||||||
|
enum wfa_wnm_notif_subelem_id {
|
||||||
|
WFA_WNM_NOTIF_SUBELEM_NON_PREF_CHAN_REPORT = 2,
|
||||||
|
WFA_WNM_NOTIF_SUBELEM_CELL_DATA_CAPA = 3,
|
||||||
|
};
|
||||||
|
|
||||||
/* Wi-Fi Direct (P2P) */
|
/* Wi-Fi Direct (P2P) */
|
||||||
|
|
||||||
#define P2P_OUI_TYPE 9
|
#define P2P_OUI_TYPE 9
|
||||||
|
|
Loading…
Reference in a new issue