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>
This commit is contained in:
Jouni Malinen 2013-10-14 19:25:28 +03:00 committed by Jouni Malinen
parent b16696ff72
commit aaeb9c98e6
3 changed files with 56 additions and 2 deletions

View 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++) { for (i = 0; i < scan_res->num; i++) {
struct wpa_scan_res *bss = scan_res->res[i]; struct wpa_scan_res *bss = scan_res->res[i];
struct os_time time_tmp_age, entry_ts; 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.sec = bss->age / 1000;
time_tmp_age.usec = (bss->age % 1000) * 1000; time_tmp_age.usec = (bss->age % 1000) * 1000;
os_time_sub(&scan_res->fetch_time, &time_tmp_age, &entry_ts); 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, if (p2p_scan_res_handler(wpa_s->global->p2p, bss->bssid,
bss->freq, &entry_ts, bss->level, bss->freq, &entry_ts, bss->level,
(const u8 *) (bss + 1), ies, ies_len) > 0)
bss->ie_len) > 0)
break; break;
} }

View 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 * wpa_scan_get_vendor_ie_multi - Fetch vendor IE data from a scan result
* @res: Scan result entry * @res: Scan result entry

View 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_ie(const struct wpa_scan_res *res, u8 ie);
const u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res, const u8 * wpa_scan_get_vendor_ie(const struct wpa_scan_res *res,
u32 vendor_type); 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, struct wpabuf * wpa_scan_get_vendor_ie_multi(const struct wpa_scan_res *res,
u32 vendor_type); u32 vendor_type);
int wpa_supplicant_filter_bssid_match(struct wpa_supplicant *wpa_s, int wpa_supplicant_filter_bssid_match(struct wpa_supplicant *wpa_s,