]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
WNM: Collocated Interference Reporting
authorJouni Malinen <jouni@codeaurora.org>
Tue, 30 Oct 2018 12:00:00 +0000 (14:00 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 30 Oct 2018 12:07:51 +0000 (14:07 +0200)
Add support for negotiating WNM Collocated Interference Reporting. This
allows hostapd to request associated STAs to report their collocated
interference information and wpa_supplicant to process such request and
reporting. The actual values (Collocated Interference Report Elements)
are out of scope of hostapd and wpa_supplicant, i.e., external
components are expected to generated and process these.

For hostapd/AP, this mechanism is enabled by setting
coloc_intf_reporting=1 in configuration. STAs are requested to perform
reporting with "COLOC_INTF_REQ <addr> <Automatic Report Enabled> <Report
Timeout>" control interface command. The received reports are indicated
as control interface events "COLOC-INTF-REPORT <addr> <dialog token>
<hexdump of report elements>".

For wpa_supplicant/STA, this mechanism is enabled by setting
coloc_intf_reporting=1 in configuration and setting Collocated
Interference Report Elements as a hexdump with "SET coloc_intf_elems
<hexdump>" control interface command. The hexdump can contain one or
more Collocated Interference Report Elements (each including the
information element header). For additional testing purposes, received
requests are reported with "COLOC-INTF-REQ <dialog token> <automatic
report enabled> <report timeout>" control interface events and
unsolicited reports can be sent with "COLOC_INTF_REPORT <hexdump>".

This commit adds support for reporting changes in the collocated
interference (Automatic Report Enabled == 1 and partial 3), but not for
periodic reports (2 and other part of 3).

Signed-off-by: Jouni Malinen <jouni@codeaurora.org>
18 files changed:
hostapd/config_file.c
hostapd/ctrl_iface.c
src/ap/ap_config.h
src/ap/ieee802_11_shared.c
src/ap/wnm_ap.c
src/ap/wnm_ap.h
src/common/ieee802_11_defs.h
src/common/wpa_ctrl.h
src/drivers/driver_nl80211.c
wpa_supplicant/config.c
wpa_supplicant/config.h
wpa_supplicant/config_file.c
wpa_supplicant/ctrl_iface.c
wpa_supplicant/events.c
wpa_supplicant/wnm_sta.c
wpa_supplicant/wnm_sta.h
wpa_supplicant/wpa_supplicant.c
wpa_supplicant/wpa_supplicant_i.h

index fbaa042164d5bbdd1ddbc4b287ac782f0144c39e..b26da71a84100a6c51ae2e89046a9487241e2454 100644 (file)
@@ -4108,6 +4108,8 @@ static int hostapd_config_fill(struct hostapd_config *conf,
                                   line, pos);
                        return 1;
                }
+       } else if (os_strcmp(buf, "coloc_intf_reporting") == 0) {
+               bss->coloc_intf_reporting = atoi(pos);
 #endif /* CONFIG_OWE */
        } else {
                wpa_printf(MSG_ERROR,
index 628278f5694bf58993e5c298923940874272fb7d..e539a0902c770021c3c4837631560d422d45e51b 100644 (file)
@@ -992,6 +992,42 @@ fail:
        return ret;
 }
 
+
+static int hostapd_ctrl_iface_coloc_intf_req(struct hostapd_data *hapd,
+                                            const char *cmd)
+{
+       u8 addr[ETH_ALEN];
+       struct sta_info *sta;
+       const char *pos;
+       unsigned int auto_report, timeout;
+
+       if (hwaddr_aton(cmd, addr)) {
+               wpa_printf(MSG_DEBUG, "Invalid STA MAC address");
+               return -1;
+       }
+
+       sta = ap_get_sta(hapd, addr);
+       if (!sta) {
+               wpa_printf(MSG_DEBUG, "Station " MACSTR
+                          " not found for Collocated Interference Request",
+                          MAC2STR(addr));
+               return -1;
+       }
+
+       pos = cmd + 17;
+       if (*pos != ' ')
+               return -1;
+       pos++;
+       auto_report = atoi(pos);
+       pos = os_strchr(pos, ' ');
+       if (!pos)
+               return -1;
+       pos++;
+       timeout = atoi(pos);
+
+       return wnm_send_coloc_intf_req(hapd, sta, auto_report, timeout);
+}
+
 #endif /* CONFIG_WNM_AP */
 
 
@@ -2961,6 +2997,9 @@ static int hostapd_ctrl_iface_receive_process(struct hostapd_data *hapd,
        } else if (os_strncmp(buf, "BSS_TM_REQ ", 11) == 0) {
                if (hostapd_ctrl_iface_bss_tm_req(hapd, buf + 11))
                        reply_len = -1;
+       } else if (os_strncmp(buf, "COLOC_INTF_REQ ", 15) == 0) {
+               if (hostapd_ctrl_iface_coloc_intf_req(hapd, buf + 15))
+                       reply_len = -1;
 #endif /* CONFIG_WNM_AP */
        } else if (os_strcmp(buf, "GET_CONFIG") == 0) {
                reply_len = hostapd_ctrl_iface_get_config(hapd, reply,
index 73d2fd832af4cc2967a5fb3d2c3ec2a430842190..778366d49afe01c8e62b5e385475ae9cd7e28407 100644 (file)
@@ -684,6 +684,8 @@ struct hostapd_bss_config {
        char owe_transition_ifname[IFNAMSIZ + 1];
        int *owe_groups;
 #endif /* CONFIG_OWE */
+
+       int coloc_intf_reporting;
 };
 
 /**
index a3f860992effa3f070ee5d21680b3b6c2cfc42ae..c4813996586b9d9ad03909ea0d659f0e6d707276 100644 (file)
@@ -178,6 +178,10 @@ static void hostapd_ext_capab_byte(struct hostapd_data *hapd, u8 *pos, int idx)
        case 1: /* Bits 8-15 */
                if (hapd->conf->proxy_arp)
                        *pos |= 0x10; /* Bit 12 - Proxy ARP */
+               if (hapd->conf->coloc_intf_reporting) {
+                       /* Bit 13 - Collocated Interference Reporting */
+                       *pos |= 0x20;
+               }
                break;
        case 2: /* Bits 16-23 */
                if (hapd->conf->wnm_sleep_mode)
index 710fe502b0fc41abde222473a3b87d22e2a9a03a..1e8f58b4d07eeae068e014c0264e89d10f6662bb 100644 (file)
@@ -453,6 +453,48 @@ static void ieee802_11_rx_wnm_notification_req(struct hostapd_data *hapd,
 }
 
 
+static void ieee802_11_rx_wnm_coloc_intf_report(struct hostapd_data *hapd,
+                                               const u8 *addr, const u8 *buf,
+                                               size_t len)
+{
+       u8 dialog_token;
+       char *hex;
+       size_t hex_len;
+
+       if (!hapd->conf->coloc_intf_reporting) {
+               wpa_printf(MSG_DEBUG,
+                          "WNM: Ignore unexpected Collocated Interference Report from "
+                          MACSTR, MAC2STR(addr));
+               return;
+       }
+
+       if (len < 1) {
+               wpa_printf(MSG_DEBUG,
+                          "WNM: Ignore too short Collocated Interference Report from "
+                          MACSTR, MAC2STR(addr));
+               return;
+       }
+       dialog_token = *buf++;
+       len--;
+
+       wpa_printf(MSG_DEBUG,
+                  "WNM: Received Collocated Interference Report frame from "
+                  MACSTR " (dialog_token=%u)",
+                  MAC2STR(addr), dialog_token);
+       wpa_hexdump(MSG_MSGDUMP, "WNM: Collocated Interference Report Elements",
+                   buf, len);
+
+       hex_len = 2 * len + 1;
+       hex = os_malloc(hex_len);
+       if (!hex)
+               return;
+       wpa_snprintf_hex(hex, hex_len, buf, len);
+       wpa_msg_ctrl(hapd->msg_ctx, MSG_INFO, COLOC_INTF_REPORT MACSTR " %d %s",
+                    MAC2STR(addr), dialog_token, hex);
+       os_free(hex);
+}
+
+
 int ieee802_11_rx_wnm_action_ap(struct hostapd_data *hapd,
                                const struct ieee80211_mgmt *mgmt, size_t len)
 {
@@ -483,6 +525,10 @@ int ieee802_11_rx_wnm_action_ap(struct hostapd_data *hapd,
                ieee802_11_rx_wnm_notification_req(hapd, mgmt->sa, payload,
                                                   plen);
                return 0;
+       case WNM_COLLOCATED_INTERFERENCE_REPORT:
+               ieee802_11_rx_wnm_coloc_intf_report(hapd, mgmt->sa, payload,
+                                                   plen);
+               return 0;
        }
 
        wpa_printf(MSG_DEBUG, "WNM: Unsupported WNM Action %u from " MACSTR,
@@ -681,3 +727,40 @@ int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
 
        return 0;
 }
+
+
+int wnm_send_coloc_intf_req(struct hostapd_data *hapd, struct sta_info *sta,
+                           unsigned int auto_report, unsigned int timeout)
+{
+       u8 buf[100], *pos;
+       struct ieee80211_mgmt *mgmt;
+       u8 dialog_token = 1;
+
+       if (auto_report > 3 || timeout > 63)
+               return -1;
+       os_memset(buf, 0, sizeof(buf));
+       mgmt = (struct ieee80211_mgmt *) buf;
+       mgmt->frame_control = IEEE80211_FC(WLAN_FC_TYPE_MGMT,
+                                          WLAN_FC_STYPE_ACTION);
+       os_memcpy(mgmt->da, sta->addr, ETH_ALEN);
+       os_memcpy(mgmt->sa, hapd->own_addr, ETH_ALEN);
+       os_memcpy(mgmt->bssid, hapd->own_addr, ETH_ALEN);
+       mgmt->u.action.category = WLAN_ACTION_WNM;
+       mgmt->u.action.u.coloc_intf_req.action =
+               WNM_COLLOCATED_INTERFERENCE_REQ;
+       mgmt->u.action.u.coloc_intf_req.dialog_token = dialog_token;
+       mgmt->u.action.u.coloc_intf_req.req_info = auto_report | (timeout << 2);
+       pos = &mgmt->u.action.u.coloc_intf_req.req_info;
+       pos++;
+
+       wpa_printf(MSG_DEBUG, "WNM: Sending Collocated Interference Request to "
+                  MACSTR " (dialog_token=%u auto_report=%u timeout=%u)",
+                  MAC2STR(sta->addr), dialog_token, auto_report, timeout);
+       if (hostapd_drv_send_mlme(hapd, buf, pos - buf, 0) < 0) {
+               wpa_printf(MSG_DEBUG,
+                          "WNM: Failed to send Collocated Interference Request frame");
+               return -1;
+       }
+
+       return 0;
+}
index 56d0f881ee272b3aafc2f8a400505c1e8b83c833..1806ba0e0525b20a6b521e93545eaf8ae66a3266 100644 (file)
@@ -24,5 +24,7 @@ int wnm_send_bss_tm_req(struct hostapd_data *hapd, struct sta_info *sta,
                        const u8 *nei_rep, size_t nei_rep_len,
                        const u8 *mbo_attrs, size_t mbo_len);
 void ap_sta_reset_steer_flag_timer(void *eloop_ctx, void *timeout_ctx);
+int wnm_send_coloc_intf_req(struct hostapd_data *hapd, struct sta_info *sta,
+                           unsigned int auto_report, unsigned int timeout);
 
 #endif /* WNM_AP_H */
index 80ea605d89b09d4e3c4805cd0af7258442ca51f0..762e731ab022c908059e39876a2b86d8b891274a 100644 (file)
@@ -921,6 +921,16 @@ struct ieee80211_mgmt {
                                         * Entries (optional) */
                                        u8 variable[];
                                } STRUCT_PACKED bss_tm_query;
+                               struct {
+                                       u8 action; /* 11 */
+                                       u8 dialog_token;
+                                       u8 req_info;
+                               } STRUCT_PACKED coloc_intf_req;
+                               struct {
+                                       u8 action; /* 12 */
+                                       u8 dialog_token;
+                                       u8 variable[];
+                               } STRUCT_PACKED coloc_intf_report;
                                struct {
                                        u8 action; /* 15 */
                                        u8 variable[];
index 4ee6400dabbbfc08db1dc92b39f3d07f29fd5cc4..f65077e04282e8d9783b4f7b2fe05a2378696677 100644 (file)
@@ -332,6 +332,13 @@ extern "C" {
 /* BSS Transition Management Response frame received */
 #define BSS_TM_RESP "BSS-TM-RESP "
 
+/* Collocated Interference Request frame received;
+ * parameters: <dialog token> <automatic report enabled> <report timeout> */
+#define COLOC_INTF_REQ "COLOC-INTF-REQ "
+/* Collocated Interference Report frame received;
+ * parameters: <STA address> <dialog token> <hexdump of report elements> */
+#define COLOC_INTF_REPORT "COLOC-INTF-REPORT "
+
 /* MBO IE with cellular data connection preference received */
 #define MBO_CELL_PREFERENCE "MBO-CELL-PREFERENCE "
 
index 23a657bf0767b32590a163310b2e5fb1f88d3072..771e766968b16ca55c1419be3665f557b2e394b8 100644 (file)
@@ -2200,6 +2200,11 @@ static int nl80211_mgmt_subscribe_non_ap(struct i802_bss *bss)
        /* WNM-Sleep Mode Response */
        if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x11", 2) < 0)
                ret = -1;
+#ifdef CONFIG_WNM
+       /* WNM - Collocated Interference Request */
+       if (nl80211_register_action_frame(bss, (u8 *) "\x0a\x0b", 2) < 0)
+               ret = -1;
+#endif /* CONFIG_WNM */
 
 #ifdef CONFIG_HS20
        /* WNM-Notification */
index ced77ebdaae00b2d8935979995f6ff34eba9769a..c43960697dc39240d56ab6ad2880e54dc876e6a1 100644 (file)
@@ -4755,6 +4755,7 @@ static const struct global_parse_data global_fields[] = {
        { INT(gas_rand_addr_lifetime), 0 },
        { INT_RANGE(gas_rand_mac_addr, 0, 2), 0 },
        { INT_RANGE(dpp_config_processing, 0, 2), 0 },
+       { INT_RANGE(coloc_intf_reporting, 0, 1), 0 },
 };
 
 #undef FUNC
index ad4dd886f21921a45698d9c1f8e0af50da40bf05..cd7571f593291e0ca1d9e2ab972b6bafd45f9d70 100644 (file)
@@ -1469,6 +1469,15 @@ struct wpa_config {
         *      profile automatically
         */
        int dpp_config_processing;
+
+       /**
+        * coloc_intf_reporting - Colocated interference reporting
+        *
+        * dot11CoLocIntfReportingActivated
+        * 0 = disabled (false)
+        * 1 = enabled (true)
+        */
+       int coloc_intf_reporting;
 };
 
 
index aa73f9df6dfac513cebda50fa34904962b382920..09115e19dc2d405b752708e4ca65aaa085129622 100644 (file)
@@ -1511,7 +1511,9 @@ static void wpa_config_write_global(FILE *f, struct wpa_config *config)
        if (config->dpp_config_processing)
                fprintf(f, "dpp_config_processing=%d\n",
                        config->dpp_config_processing);
-
+       if (config->coloc_intf_reporting)
+               fprintf(f, "coloc_intf_reporting=%d\n",
+                       config->coloc_intf_reporting);
 }
 
 #endif /* CONFIG_NO_CONFIG_WRITE */
index 945ab9c4dd6b7071c376c8e274527e7ae6da6eb5..77a3133d8d5605e35e5c7fe5da72aca33dd0c7d4 100644 (file)
@@ -750,6 +750,15 @@ static int wpa_supplicant_ctrl_iface_set(struct wpa_supplicant *wpa_s,
                ret = wpas_ctrl_iface_set_ric_ies(wpa_s, value);
        } else if (os_strcasecmp(cmd, "roaming") == 0) {
                ret = wpa_drv_roaming(wpa_s, atoi(value), NULL);
+#ifdef CONFIG_WNM
+       } else if (os_strcasecmp(cmd, "coloc_intf_elems") == 0) {
+               struct wpabuf *elems;
+
+               elems = wpabuf_parse_bin(value);
+               if (!elems)
+                       return -1;
+               wnm_set_coloc_intf_elems(wpa_s, elems);
+#endif /* CONFIG_WNM */
        } else {
                value[-1] = '=';
                ret = wpa_config_process_global(wpa_s->conf, cmd, -1);
@@ -7437,6 +7446,22 @@ static int wpas_ctrl_iface_wnm_bss_query(struct wpa_supplicant *wpa_s, char *cmd
                                                  list);
 }
 
+
+static int wpas_ctrl_iface_coloc_intf_report(struct wpa_supplicant *wpa_s,
+                                            char *cmd)
+{
+       struct wpabuf *elems;
+       int ret;
+
+       elems = wpabuf_parse_bin(cmd);
+       if (!elems)
+               return -1;
+
+       ret = wnm_send_coloc_intf_report(wpa_s, 0, elems);
+       wpabuf_free(elems);
+       return ret;
+}
+
 #endif /* CONFIG_WNM */
 
 
@@ -10423,6 +10448,9 @@ char * wpa_supplicant_ctrl_iface_process(struct wpa_supplicant *wpa_s,
        } else if (os_strncmp(buf, "WNM_BSS_QUERY ", 14) == 0) {
                if (wpas_ctrl_iface_wnm_bss_query(wpa_s, buf + 14))
                                reply_len = -1;
+       } else if (os_strncmp(buf, "COLOC_INTF_REPORT ", 18) == 0) {
+               if (wpas_ctrl_iface_coloc_intf_report(wpa_s, buf + 18))
+                       reply_len = -1;
 #endif /* CONFIG_WNM */
        } else if (os_strcmp(buf, "FLUSH") == 0) {
                wpa_supplicant_ctrl_iface_flush(wpa_s);
index 860b2792cc53d4650b5013c19210776369e4145f..dd6dd52676b87eddfb77f990796967863e5cf1ab 100644 (file)
@@ -317,6 +317,7 @@ void wpa_supplicant_mark_disassoc(struct wpa_supplicant *wpa_s)
 
        wpas_rrm_reset(wpa_s);
        wpa_s->wnmsleep_used = 0;
+       wnm_clear_coloc_intf_reporting(wpa_s);
 
 #ifdef CONFIG_TESTING_OPTIONS
        wpa_s->last_tk_alg = WPA_ALG_NONE;
@@ -4339,6 +4340,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
 #endif /* CONFIG_AP */
 
                wpas_p2p_update_channel_list(wpa_s, WPAS_P2P_CHANNEL_UPDATE_CS);
+               wnm_clear_coloc_intf_reporting(wpa_s);
                break;
 #ifdef CONFIG_AP
 #ifdef NEED_AP_MLME
index 7c410e7301429de040094ab8fb8f079959ff8a62..6b68fc9e3772a0251c8968c94834f6ab57afbcc0 100644 (file)
@@ -338,6 +338,9 @@ void wnm_deallocate_memory(struct wpa_supplicant *wpa_s)
        wpa_s->wnm_num_neighbor_report = 0;
        os_free(wpa_s->wnm_neighbor_report_elements);
        wpa_s->wnm_neighbor_report_elements = NULL;
+
+       wpabuf_free(wpa_s->coloc_intf_elems);
+       wpa_s->coloc_intf_elems = NULL;
 }
 
 
@@ -1717,6 +1720,46 @@ static void ieee802_11_rx_wnm_notif_req(struct wpa_supplicant *wpa_s,
 }
 
 
+static void ieee802_11_rx_wnm_coloc_intf_req(struct wpa_supplicant *wpa_s,
+                                            const u8 *sa, const u8 *frm,
+                                            int len)
+{
+       u8 dialog_token, req_info, auto_report, timeout;
+
+       if (!wpa_s->conf->coloc_intf_reporting)
+               return;
+
+       /* Dialog Token [1] | Request Info [1] */
+
+       if (len < 2)
+               return;
+       dialog_token = frm[0];
+       req_info = frm[1];
+       auto_report = req_info & 0x03;
+       timeout = req_info >> 2;
+
+       wpa_dbg(wpa_s, MSG_DEBUG,
+               "WNM: Received Collocated Interference Request (dialog_token %u auto_report %u timeout %u sa " MACSTR ")",
+               dialog_token, auto_report, timeout, MAC2STR(sa));
+
+       if (dialog_token == 0)
+               return; /* only nonzero values are used for request */
+
+       if (wpa_s->wpa_state != WPA_COMPLETED ||
+           os_memcmp(sa, wpa_s->bssid, ETH_ALEN) != 0) {
+               wpa_dbg(wpa_s, MSG_DEBUG,
+                       "WNM: Collocated Interference Request frame not from current AP - ignore it");
+               return;
+       }
+
+       wpa_msg(wpa_s, MSG_INFO, COLOC_INTF_REQ "%u %u %u",
+               dialog_token, auto_report, timeout);
+       wpa_s->coloc_intf_dialog_token = dialog_token;
+       wpa_s->coloc_intf_auto_report = auto_report;
+       wpa_s->coloc_intf_timeout = timeout;
+}
+
+
 void ieee802_11_rx_wnm_action(struct wpa_supplicant *wpa_s,
                              const struct ieee80211_mgmt *mgmt, size_t len)
 {
@@ -1750,8 +1793,75 @@ void ieee802_11_rx_wnm_action(struct wpa_supplicant *wpa_s,
        case WNM_NOTIFICATION_REQ:
                ieee802_11_rx_wnm_notif_req(wpa_s, mgmt->sa, pos, end - pos);
                break;
+       case WNM_COLLOCATED_INTERFERENCE_REQ:
+               ieee802_11_rx_wnm_coloc_intf_req(wpa_s, mgmt->sa, pos,
+                                                end - pos);
+               break;
        default:
                wpa_printf(MSG_ERROR, "WNM: Unknown request");
                break;
        }
 }
+
+
+int wnm_send_coloc_intf_report(struct wpa_supplicant *wpa_s, u8 dialog_token,
+                              const struct wpabuf *elems)
+{
+       struct wpabuf *buf;
+       int ret;
+
+       if (wpa_s->wpa_state < WPA_ASSOCIATED || !elems)
+               return -1;
+
+       wpa_printf(MSG_DEBUG, "WNM: Send Collocated Interference Report to "
+                  MACSTR " (dialog token %u)",
+                  MAC2STR(wpa_s->bssid), dialog_token);
+
+       buf = wpabuf_alloc(3 + wpabuf_len(elems));
+       if (!buf)
+               return -1;
+
+       wpabuf_put_u8(buf, WLAN_ACTION_WNM);
+       wpabuf_put_u8(buf, WNM_COLLOCATED_INTERFERENCE_REPORT);
+       wpabuf_put_u8(buf, dialog_token);
+       wpabuf_put_buf(buf, elems);
+
+       ret = wpa_drv_send_action(wpa_s, wpa_s->assoc_freq, 0, wpa_s->bssid,
+                                 wpa_s->own_addr, wpa_s->bssid,
+                                 wpabuf_head_u8(buf), wpabuf_len(buf), 0);
+       wpabuf_free(buf);
+       return ret;
+}
+
+
+void wnm_set_coloc_intf_elems(struct wpa_supplicant *wpa_s,
+                             struct wpabuf *elems)
+{
+       wpabuf_free(wpa_s->coloc_intf_elems);
+       if (elems && wpabuf_len(elems) == 0) {
+               wpabuf_free(elems);
+               elems = NULL;
+       }
+       wpa_s->coloc_intf_elems = elems;
+
+       if (wpa_s->conf->coloc_intf_reporting && wpa_s->coloc_intf_elems &&
+           wpa_s->coloc_intf_dialog_token &&
+           (wpa_s->coloc_intf_auto_report == 1 ||
+            wpa_s->coloc_intf_auto_report == 3)) {
+               /* TODO: Check that there has not been less than
+                * wpa_s->coloc_intf_timeout * 200 TU from the last report.
+                */
+               wnm_send_coloc_intf_report(wpa_s,
+                                          wpa_s->coloc_intf_dialog_token,
+                                          wpa_s->coloc_intf_elems);
+       }
+}
+
+
+void wnm_clear_coloc_intf_reporting(struct wpa_supplicant *wpa_s)
+{
+#ifdef CONFIG_WNM
+       wpa_s->coloc_intf_dialog_token = 0;
+       wpa_s->coloc_intf_auto_report = 0;
+#endif /* CONFIG_WNM */
+}
index 02cd1cde67425251ca46280a5710ff0ceee69230..29625f8ca943e62ad955087585573ab5470c3dbd 100644 (file)
@@ -65,11 +65,16 @@ int wnm_send_bss_transition_mgmt_query(struct wpa_supplicant *wpa_s,
                                       int cand_list);
 
 void wnm_deallocate_memory(struct wpa_supplicant *wpa_s);
+int wnm_send_coloc_intf_report(struct wpa_supplicant *wpa_s, u8 dialog_token,
+                              const struct wpabuf *elems);
+void wnm_set_coloc_intf_elems(struct wpa_supplicant *wpa_s,
+                             struct wpabuf *elems);
 
 
 #ifdef CONFIG_WNM
 
 int wnm_scan_process(struct wpa_supplicant *wpa_s, int reply_on_fail);
+void wnm_clear_coloc_intf_reporting(struct wpa_supplicant *wpa_s);
 
 #else /* CONFIG_WNM */
 
@@ -79,6 +84,10 @@ static inline int wnm_scan_process(struct wpa_supplicant *wpa_s,
        return 0;
 }
 
+static inline void wnm_clear_coloc_intf_reporting(struct wpa_supplicant *wpa_s)
+{
+}
+
 #endif /* CONFIG_WNM */
 
 #endif /* WNM_STA_H */
index eed973590a71840ad9aeb75bf1c173f5b6486d03..6090e06620c973c09a434e1725f40992f6a878ba 100644 (file)
@@ -1645,6 +1645,10 @@ static void wpas_ext_capab_byte(struct wpa_supplicant *wpa_s, u8 *pos, int idx)
        case 0: /* Bits 0-7 */
                break;
        case 1: /* Bits 8-15 */
+               if (wpa_s->conf->coloc_intf_reporting) {
+                       /* Bit 13 - Collocated Interference Reporting */
+                       *pos |= 0x20;
+               }
                break;
        case 2: /* Bits 16-23 */
 #ifdef CONFIG_WNM
index 6a521f0627ad4f25133ab766ce37d0a293e8abba..8b749f44e235cf5e5aeefd3ee9003cb891cb6da4 100644 (file)
@@ -1059,6 +1059,10 @@ struct wpa_supplicant {
        struct neighbor_report *wnm_neighbor_report_elements;
        struct os_reltime wnm_cand_valid_until;
        u8 wnm_cand_from_bss[ETH_ALEN];
+       struct wpabuf *coloc_intf_elems;
+       u8 coloc_intf_dialog_token;
+       u8 coloc_intf_auto_report;
+       u8 coloc_intf_timeout;
 #ifdef CONFIG_MBO
        unsigned int wnm_mbo_trans_reason_present:1;
        u8 wnm_mbo_transition_reason;