]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Allow GO to be discovered based on Beacon frame
authorJouni Malinen <jouni@qca.qualcomm.com>
Mon, 14 Oct 2013 16:25:28 +0000 (19:25 +0300)
committerJouni Malinen <j@w1.fi>
Mon, 14 Oct 2013 16:25:28 +0000 (19:25 +0300)
This fixes some P2P-join-a-group cases where GO may have been discovered
based on passive scan or non-P2P scan. P2P IEs may have been received
from a Beacon frame in such a case and that information can be used to
create a P2P peer entry, e.g., to allow provision discovery exchange to
be completed.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

wpa_supplicant/p2p_supplicant.c
wpa_supplicant/scan.c
wpa_supplicant/scan.h

index 4b54a63fa68d2a0e21d7c2cdfe2d8a77430824b4..4780ad1482a2cbe44fc22eb8e6a73651e5e0300f 100644 (file)
@@ -195,13 +195,28 @@ static void wpas_p2p_scan_res_handler(struct wpa_supplicant *wpa_s,
        for (i = 0; i < scan_res->num; i++) {
                struct wpa_scan_res *bss = scan_res->res[i];
                struct os_time time_tmp_age, entry_ts;
+               const u8 *ies;
+               size_t ies_len;
+
                time_tmp_age.sec = bss->age / 1000;
                time_tmp_age.usec = (bss->age % 1000) * 1000;
                os_time_sub(&scan_res->fetch_time, &time_tmp_age, &entry_ts);
+
+               ies = (const u8 *) (bss + 1);
+               ies_len = bss->ie_len;
+               if (bss->beacon_ie_len > 0 &&
+                   !wpa_scan_get_vendor_ie(bss, P2P_IE_VENDOR_TYPE) &&
+                   wpa_scan_get_vendor_ie_beacon(bss, P2P_IE_VENDOR_TYPE)) {
+                       wpa_printf(MSG_DEBUG, "P2P: Use P2P IE(s) from Beacon frame since no P2P IE(s) in Probe Response frames received for "
+                                  MACSTR, MAC2STR(bss->bssid));
+                       ies = ies + ies_len;
+                       ies_len = bss->beacon_ie_len;
+               }
+
+
                if (p2p_scan_res_handler(wpa_s->global->p2p, bss->bssid,
                                         bss->freq, &entry_ts, bss->level,
-                                        (const u8 *) (bss + 1),
-                                        bss->ie_len) > 0)
+                                        ies, ies_len) > 0)
                        break;
        }
 
index 04e8fa6ca01ecdd765b15115a1e8061149605b4f..be826dbff1da05d8a09f7848e8956b94e153f49b 100644 (file)
@@ -1331,6 +1331,43 @@ const u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res,
 }
 
 
+/**
+ * wpa_scan_get_vendor_ie_beacon - Fetch vendor information from a scan result
+ * @res: Scan result entry
+ * @vendor_type: Vendor type (four octets starting the IE payload)
+ * Returns: Pointer to the information element (id field) or %NULL if not found
+ *
+ * This function returns the first matching information element in the scan
+ * result.
+ *
+ * This function is like wpa_scan_get_vendor_ie(), but uses IE buffer only
+ * from Beacon frames instead of either Beacon or Probe Response frames.
+ */
+const u8 * wpa_scan_get_vendor_ie_beacon(const struct wpa_scan_res *res,
+                                        u32 vendor_type)
+{
+       const u8 *end, *pos;
+
+       if (res->beacon_ie_len == 0)
+               return NULL;
+
+       pos = (const u8 *) (res + 1);
+       pos += res->ie_len;
+       end = pos + res->beacon_ie_len;
+
+       while (pos + 1 < end) {
+               if (pos + 2 + pos[1] > end)
+                       break;
+               if (pos[0] == WLAN_EID_VENDOR_SPECIFIC && pos[1] >= 4 &&
+                   vendor_type == WPA_GET_BE32(&pos[2]))
+                       return pos;
+               pos += 2 + pos[1];
+       }
+
+       return NULL;
+}
+
+
 /**
  * wpa_scan_get_vendor_ie_multi - Fetch vendor IE data from a scan result
  * @res: Scan result entry
index 2144787b56866bf3b55095e07c38161ad6a72103..66581a9db1deb2d1791fc92200c35f05b0d044c7 100644 (file)
@@ -29,6 +29,8 @@ int wpa_supplicant_update_scan_results(struct wpa_supplicant *wpa_s);
 const u8 * wpa_scan_get_ie(const struct wpa_scan_res *res, u8 ie);
 const u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res,
                                  u32 vendor_type);
+const u8 * wpa_scan_get_vendor_ie_beacon(const struct wpa_scan_res *res,
+                                        u32 vendor_type);
 struct wpabuf * wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res *res,
                                             u32 vendor_type);
 int wpa_supplicant_filter_bssid_match(struct wpa_supplicant *wpa_s,