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:
parent
b16696ff72
commit
aaeb9c98e6
3 changed files with 56 additions and 2 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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,
|
||||||
|
|
Loading…
Reference in a new issue