]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
AP: Store STA supported operating classes information
authorJouni Malinen <jouni@qca.qualcomm.com>
Wed, 24 Feb 2016 10:20:31 +0000 (12:20 +0200)
committerJouni Malinen <j@w1.fi>
Wed, 24 Feb 2016 10:20:31 +0000 (12:20 +0200)
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>
src/ap/ctrl_iface_ap.c
src/ap/drv_callbacks.c
src/ap/ieee802_11.c
src/ap/ieee802_11.h
src/ap/ieee802_11_shared.c
src/ap/sta_info.c
src/ap/sta_info.h
src/common/ieee802_11_common.c
src/common/ieee802_11_common.h

index a95230e06899aed822686e12b5c30e40ccb8abbf..9f249d741394c4c58a451cd4a000f41f9817c363 100644 (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;
 }
 
index 702ee647964f9766321a438335791232336c4b1f..803ca8ec608da7cab580afb197c7368de920e1e1 100644 (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
index 84e6e15aded1a83fb115c92f24d38303540b0bdd..b36e68dd6df1fe6a40cede635c085ce1e21376ec 100644 (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;
 }
 
index 78db204453c4cd375759e6e291ac2e3ecdc53625..1a96b33171c87b7ebaba8b1c635692d63f989cdc 100644 (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 */
index 10776353c7da8e51896aea584a58a463354b2baa..af858f09e53e8bfb0ab9159871ac87a33158ad41 100644 (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);
+}
index 60058e45c31c143524829b8d102dd547d83be11a..c36842b397cd20fa4c63e34557997aa8453f417e 100644 (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);
 }
index 08e795e1c275b07884a70f5720b63d426e6b6db8..e223341496de56e63bf68ebac57f728d12148088 100644 (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 */
 };
 
 
index 2e503b9537c05bc83b9f97374fbb5ce4659f1a51..5b05b68f1d4627ac9522b19f2007de60e70e370f 100644 (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)
index 3a3dd4d10af7497c111ab0c02257a048826ebdd1..d9fecd6c470bc72218b43a49b9466396edc157d1 100644 (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;
 };