P2P: Add rx_freq parameter to Probe Request frame handler
authorMax Stepanov <Max.Stepanov@intel.com>
Wed, 10 Jun 2015 08:43:31 +0000 (11:43 +0300)
committerJouni Malinen <j@w1.fi>
Sun, 14 Jun 2015 20:16:55 +0000 (23:16 +0300)
In some cases, Probe Request frames can be received by a peer not only
on a listen channel. In this case an additional rx_freq parameter
explitly contains a Probe Request frame RX frequency. In case rx_freq is
set to 0, a Probe Request frame RX channel is assumed to be our own
listen channel (p2p->cfg->channel).

Signed-off-by: Max Stepanov <Max.Stepanov@intel.com>
Reviewed-by: Ilan Peer <ilan.peer@intel.com>
src/p2p/p2p.c
src/p2p/p2p.h
wpa_supplicant/ap.c
wpa_supplicant/events.c
wpa_supplicant/p2p_supplicant.c
wpa_supplicant/p2p_supplicant.h

index b31bc36..c9dd7fc 100644 (file)
@@ -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) &&
index 6b0ba80..b4407f0 100644 (file)
@@ -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
index bfb69fc..15192d1 100644 (file)
@@ -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);
 }
 
 
index a1dae30..b615fbd 100644 (file)
@@ -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:
index 6e6bdca..d89e270 100644 (file)
@@ -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);
index 0b9ebc0..ed2e542 100644 (file)
@@ -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;
 }