diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index b31bc36ba..c9dd7fc91 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -2234,13 +2234,15 @@ static int p2p_service_find_asp(struct p2p_data *p2p, const u8 *hash) static enum p2p_probe_req_status p2p_reply_probe(struct p2p_data *p2p, const u8 *addr, const u8 *dst, - const u8 *bssid, const u8 *ie, size_t ie_len) + const u8 *bssid, const u8 *ie, size_t ie_len, + unsigned int rx_freq) { struct ieee802_11_elems elems; struct wpabuf *buf; struct ieee80211_mgmt *resp; struct p2p_message msg; struct wpabuf *ies; + u8 channel, op_class; if (ieee802_11_parse_elems((u8 *) ie, ie_len, &elems, 0) == ParseFailed) { @@ -2423,9 +2425,17 @@ p2p_reply_probe(struct p2p_data *p2p, const u8 *addr, const u8 *dst, wpabuf_put_u8(buf, 480 / 5); wpabuf_put_u8(buf, 540 / 5); + if (!rx_freq) { + channel = p2p->cfg->channel; + } else if (p2p_freq_to_channel(rx_freq, &op_class, &channel)) { + wpabuf_free(ies); + wpabuf_free(buf); + return P2P_PREQ_NOT_PROCESSED; + } + wpabuf_put_u8(buf, WLAN_EID_DS_PARAMS); wpabuf_put_u8(buf, 1); - wpabuf_put_u8(buf, p2p->cfg->channel); + wpabuf_put_u8(buf, channel); wpabuf_put_buf(buf, ies); wpabuf_free(ies); @@ -2440,13 +2450,14 @@ p2p_reply_probe(struct p2p_data *p2p, const u8 *addr, const u8 *dst, enum p2p_probe_req_status p2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *dst, - const u8 *bssid, const u8 *ie, size_t ie_len) + const u8 *bssid, const u8 *ie, size_t ie_len, + unsigned int rx_freq) { enum p2p_probe_req_status res; p2p_add_dev_from_probe_req(p2p, addr, ie, ie_len); - res = p2p_reply_probe(p2p, addr, dst, bssid, ie, ie_len); + res = p2p_reply_probe(p2p, addr, dst, bssid, ie, ie_len, rx_freq); p2p->query_count = 0; if ((p2p->state == P2P_CONNECT || p2p->state == P2P_CONNECT_LISTEN) && diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 6b0ba8008..b4407f0db 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -1463,11 +1463,13 @@ enum p2p_probe_req_status { * @bssid: BSSID if available or %NULL * @ie: Information elements from the Probe Request frame body * @ie_len: Length of ie buffer in octets + * @rx_freq: Probe Request frame RX frequency * Returns: value indicating the type and status of the probe request */ enum p2p_probe_req_status p2p_probe_req_rx(struct p2p_data *p2p, const u8 *addr, const u8 *dst, - const u8 *bssid, const u8 *ie, size_t ie_len); + const u8 *bssid, const u8 *ie, size_t ie_len, + unsigned int rx_freq); /** * p2p_rx_action - Report received Action frame diff --git a/wpa_supplicant/ap.c b/wpa_supplicant/ap.c index bfb69fc8c..15192d159 100644 --- a/wpa_supplicant/ap.c +++ b/wpa_supplicant/ap.c @@ -486,7 +486,7 @@ static int ap_probe_req_rx(void *ctx, const u8 *sa, const u8 *da, { struct wpa_supplicant *wpa_s = ctx; return wpas_p2p_probe_req_rx(wpa_s, sa, da, bssid, ie, ie_len, - ssi_signal); + 0, ssi_signal); } diff --git a/wpa_supplicant/events.c b/wpa_supplicant/events.c index a1dae30e8..b615fbd42 100644 --- a/wpa_supplicant/events.c +++ b/wpa_supplicant/events.c @@ -3491,6 +3491,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, wpas_p2p_probe_req_rx( wpa_s, src, mgmt->da, mgmt->bssid, ie, ie_len, + data->rx_mgmt.freq, data->rx_mgmt.ssi_signal); break; } @@ -3562,6 +3563,7 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event, data->rx_probe_req.bssid, data->rx_probe_req.ie, data->rx_probe_req.ie_len, + 0, data->rx_probe_req.ssi_signal); break; case EVENT_REMAIN_ON_CHANNEL: diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 6e6bdca87..d89e2704e 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -6014,7 +6014,8 @@ int wpas_p2p_assoc_req_ie(struct wpa_supplicant *wpa_s, struct wpa_bss *bss, int wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr, const u8 *dst, const u8 *bssid, - const u8 *ie, size_t ie_len, int ssi_signal) + const u8 *ie, size_t ie_len, + unsigned int rx_freq, int ssi_signal) { if (wpa_s->global->p2p_disabled) return 0; @@ -6022,7 +6023,7 @@ int wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr, return 0; switch (p2p_probe_req_rx(wpa_s->global->p2p, addr, dst, bssid, - ie, ie_len)) { + ie, ie_len, rx_freq)) { case P2P_PREQ_NOT_P2P: wpas_notify_preq(wpa_s, addr, dst, bssid, ie, ie_len, ssi_signal); diff --git a/wpa_supplicant/p2p_supplicant.h b/wpa_supplicant/p2p_supplicant.h index 0b9ebc0b6..ed2e54299 100644 --- a/wpa_supplicant/p2p_supplicant.h +++ b/wpa_supplicant/p2p_supplicant.h @@ -158,7 +158,7 @@ void wpas_p2p_update_config(struct wpa_supplicant *wpa_s); int wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr, const u8 *dst, const u8 *bssid, const u8 *ie, size_t ie_len, - int ssi_signal); + unsigned int rx_freq, int ssi_signal); void wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr, int registrar); void wpas_p2p_update_channel_list(struct wpa_supplicant *wpa_s); @@ -212,7 +212,7 @@ static inline int wpas_p2p_probe_req_rx(struct wpa_supplicant *wpa_s, const u8 *addr, const u8 *dst, const u8 *bssid, const u8 *ie, size_t ie_len, - int ssi_signal) + unsigned int rx_freq, int ssi_signal) { return 0; }