AP: Store STA supported operating classes information

This makes hostapd track Supported Operating Classes information from
the associated STAs. The stored information is available through the STA
control interface command (supp_op_classes row) as a hexdump of the
Supported Operating Classes element starting from the Length field. This
information can be used as input to BSS transition management and
channel switching decisions.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2016-02-24 12:20:31 +02:00 committed by Jouni Malinen
parent 077dcfb8c4
commit adf0478e8e
9 changed files with 47 additions and 0 deletions

View file

@ -166,6 +166,15 @@ static int hostapd_ctrl_iface_sta_mib(struct hostapd_data *hapd,
if (res >= 0)
len += res;
if (sta->supp_op_classes &&
buflen - len > (unsigned) (17 + 2 * sta->supp_op_classes[0])) {
len += os_snprintf(buf + len, buflen - len, "supp_op_classes=");
len += wpa_snprintf_hex(buf + len, buflen - len,
sta->supp_op_classes + 1,
sta->supp_op_classes[0]);
len += os_snprintf(buf + len, buflen - len, "\n");
}
return len;
}

View file

@ -176,6 +176,9 @@ int hostapd_notif_assoc(struct hostapd_data *hapd, const u8 *addr,
mbo_ap_check_sta_assoc(hapd, sta, &elems);
ap_copy_sta_supp_op_classes(sta, elems.supp_op_classes,
elems.supp_op_classes_len);
if (hapd->conf->wpa) {
if (ie == NULL || ielen == 0) {
#ifdef CONFIG_WPS

View file

@ -1726,6 +1726,9 @@ static u16 check_assoc_ies(struct hostapd_data *hapd, struct sta_info *sta,
}
#endif /* CONFIG_MBO */
ap_copy_sta_supp_op_classes(sta, elems.supp_op_classes,
elems.supp_op_classes_len);
return WLAN_STATUS_SUCCESS;
}

View file

@ -130,4 +130,8 @@ static inline u8 hostapd_mbo_ie_len(struct hostapd_data *hapd)
#endif /* CONFIG_MBO */
void ap_copy_sta_supp_op_classes(struct sta_info *sta,
const u8 *supp_op_classes,
size_t supp_op_classes_len);
#endif /* IEEE802_11_H */

View file

@ -558,3 +558,20 @@ u8 hostapd_mbo_ie_len(struct hostapd_data *hapd)
}
#endif /* CONFIG_MBO */
void ap_copy_sta_supp_op_classes(struct sta_info *sta,
const u8 *supp_op_classes,
size_t supp_op_classes_len)
{
if (!supp_op_classes)
return;
os_free(sta->supp_op_classes);
sta->supp_op_classes = os_malloc(1 + supp_op_classes_len);
if (!sta->supp_op_classes)
return;
sta->supp_op_classes[0] = supp_op_classes_len;
os_memcpy(sta->supp_op_classes + 1, supp_op_classes,
supp_op_classes_len);
}

View file

@ -328,6 +328,7 @@ void ap_free_sta(struct hostapd_data *hapd, struct sta_info *sta)
#endif /* CONFIG_SAE */
mbo_ap_sta_free(sta);
os_free(sta->supp_op_classes);
os_free(sta);
}

View file

@ -190,6 +190,9 @@ struct sta_info {
* enum mbo_cellular_capa values */
struct mbo_non_pref_chan_info *non_pref_chan;
#endif /* CONFIG_MBO */
u8 *supp_op_classes; /* Supported Operating Classes element, if
* received, starting from the Length field */
};

View file

@ -371,6 +371,10 @@ ParseRes ieee802_11_parse_elems(const u8 *start, size_t len,
elems->mb_ies.ies[elems->mb_ies.nof_ies].ie_len = elen;
elems->mb_ies.nof_ies++;
break;
case WLAN_EID_SUPPORTED_OPERATING_CLASSES:
elems->supp_op_classes = pos;
elems->supp_op_classes_len = elen;
break;
default:
unknown++;
if (!show_errors)

View file

@ -62,6 +62,7 @@ struct ieee802_11_elems {
const u8 *ampe;
const u8 *mic;
const u8 *pref_freq_list;
const u8 *supp_op_classes;
u8 ssid_len;
u8 supp_rates_len;
@ -92,6 +93,8 @@ struct ieee802_11_elems {
u8 ampe_len;
u8 mic_len;
u8 pref_freq_list_len;
u8 supp_op_classes_len;
struct mb_ies_info mb_ies;
};