aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2013-10-18 10:44:54 +0530
committerRashmi Ramanna <rashmi@codeaurora.org>2013-10-18 10:46:41 +0530
commitc7f6e283ecbed797898aabf00263fd667a568ad8 (patch)
treea14086e6942f3ae1ec3421a90c8598bfc59b8384
parent88e26447fd5feaf74e76644e60bcecb44324d457 (diff)
downloadandroid_external_wpa_supplicant_8-c7f6e283ecbed797898aabf00263fd667a568ad8.tar.gz
android_external_wpa_supplicant_8-c7f6e283ecbed797898aabf00263fd667a568ad8.tar.bz2
android_external_wpa_supplicant_8-c7f6e283ecbed797898aabf00263fd667a568ad8.zip
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. Change-Id: I8502c61fa0f149f7636708458f5e51ca627ac6b7 CRs-Fixed: 535523 Git-commit: aaeb9c98e6aad64bbf92c7cb6ef4531c039b8a1d Git-repo: git://w1.fi/srv/git/hostap.git Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
-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 ca813f12..a285ff98 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -146,13 +146,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 07e3e06c..25717477 100644
--- a/wpa_supplicant/scan.c
+++ b/wpa_supplicant/scan.c
@@ -1345,6 +1345,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 e892479f..6eeb19a9 100644
--- a/wpa_supplicant/scan.h
+++ b/wpa_supplicant/scan.h
@@ -28,6 +28,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,