aboutsummaryrefslogtreecommitdiffstats
path: root/wpa_supplicant
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2013-10-14 16:25:28 (GMT)
committerJouni Malinen <j@w1.fi>2013-10-14 16:25:28 (GMT)
commitaaeb9c98e6aad64bbf92c7cb6ef4531c039b8a1d (patch)
tree39e2aecb64be11ab9b4c7602d63e53a057827b3c /wpa_supplicant
parentb16696ff72969329c9e4507f9bbcaf5882b492f7 (diff)
downloadhostap-aaeb9c98e6aad64bbf92c7cb6ef4531c039b8a1d.zip
hostap-aaeb9c98e6aad64bbf92c7cb6ef4531c039b8a1d.tar.gz
hostap-aaeb9c98e6aad64bbf92c7cb6ef4531c039b8a1d.tar.bz2
P2P: Allow GO to be discovered based on Beacon frame
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>
Diffstat (limited to 'wpa_supplicant')
-rw-r--r--wpa_supplicant/p2p_supplicant.c19
-rw-r--r--wpa_supplicant/scan.c37
-rw-r--r--wpa_supplicant/scan.h2
3 files changed, 56 insertions, 2 deletions
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 4b54a63..4780ad1 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -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;
}
diff --git a/wpa_supplicant/scan.c b/wpa_supplicant/scan.c
index 04e8fa6..be826db 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -1332,6 +1332,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
* @vendor_type: Vendor type (four octets starting the IE payload)
diff --git a/wpa_supplicant/scan.h b/wpa_supplicant/scan.h
index 2144787..66581a9 100644
--- a/wpa_supplicant/scan.h
+++ b/wpa_supplicant/scan.h
@@ -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,