]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Add preferred frequency list extension to GO Neg Req
authorAhmad Kholaif <akholaif@qca.qualcomm.com>
Fri, 24 Jul 2015 00:39:45 +0000 (17:39 -0700)
committerJouni Malinen <j@w1.fi>
Thu, 30 Jul 2015 19:13:48 +0000 (22:13 +0300)
When sending a GO Negotiation Request, advertise the preferred frequency
list in a new vendor specific IE. This can be used to extend the
standard P2P behavior where a single preferred channel can be advertised
by allowing a priority list of channels to be indicated.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/p2p/p2p_build.c
src/p2p/p2p_go_neg.c
src/p2p/p2p_i.h

index c733543c4f9cb01cee2944da3ff74734f8c89bc5..793d28ba7bdd2a20efbd84f385898fd4c9dc5b98 100644 (file)
@@ -10,6 +10,7 @@
 
 #include "common.h"
 #include "common/ieee802_11_defs.h"
+#include "common/qca-vendor.h"
 #include "wps/wps_i.h"
 #include "p2p_i.h"
 
@@ -109,6 +110,44 @@ void p2p_buf_add_operating_channel(struct wpabuf *buf, const char *country,
 }
 
 
+void p2p_buf_add_pref_channel_list(struct wpabuf *buf,
+                                  const u32 *preferred_freq_list,
+                                  unsigned int size)
+{
+       unsigned int i, count = 0;
+       u8 op_class, op_channel;
+
+       if (!size)
+               return;
+
+       /*
+        * First, determine the number of P2P supported channels in the
+        * pref_freq_list returned from driver. This is needed for calculations
+        * of the vendor IE size.
+        */
+       for (i = 0; i < size; i++) {
+               if (p2p_freq_to_channel(preferred_freq_list[i], &op_class,
+                                       &op_channel) == 0)
+                       count++;
+       }
+
+       wpabuf_put_u8(buf, WLAN_EID_VENDOR_SPECIFIC);
+       wpabuf_put_u8(buf, 4 + count * sizeof(u16));
+       wpabuf_put_be24(buf, OUI_QCA);
+       wpabuf_put_u8(buf, QCA_VENDOR_ELEM_P2P_PREF_CHAN_LIST);
+       for (i = 0; i < size; i++) {
+               if (p2p_freq_to_channel(preferred_freq_list[i], &op_class,
+                                       &op_channel) < 0) {
+                       wpa_printf(MSG_DEBUG, "Unsupported frequency %u MHz",
+                                  preferred_freq_list[i]);
+                       continue;
+               }
+               wpabuf_put_u8(buf, op_class);
+               wpabuf_put_u8(buf, op_channel);
+       }
+}
+
+
 void p2p_buf_add_channel_list(struct wpabuf *buf, const char *country,
                              struct p2p_channels *chan)
 {
index 19f1daaf2ec3bc7250bd2c1a6c1ea8526e4e6fa5..d47763ac5d56ffbb3a7d2f4b453b30145b69c97c 100644 (file)
@@ -185,6 +185,9 @@ static struct wpabuf * p2p_build_go_neg_req(struct p2p_data *p2p,
                                      p2p->op_reg_class, p2p->op_channel);
        p2p_buf_update_ie_hdr(buf, len);
 
+       p2p_buf_add_pref_channel_list(buf, p2p->pref_freq_list,
+                                     p2p->num_pref_freq);
+
        /* WPS IE with Device Password ID attribute */
        pw_id = p2p_wps_method_pw_id(peer->wps_method);
        if (peer->oob_pw_id)
index 3d6bc70540ef9f35af1b25a964c4587661e0c87c..5921792da21ea92c253fd465f78f92a412dab54c 100644 (file)
@@ -769,6 +769,8 @@ void p2p_buf_add_persistent_group_info(struct wpabuf *buf, const u8 *dev_addr,
                                       const u8 *ssid, size_t ssid_len);
 int p2p_build_wps_ie(struct p2p_data *p2p, struct wpabuf *buf, int pw_id,
                     int all_attr);
+void p2p_buf_add_pref_channel_list(struct wpabuf *buf,
+                                  const u32 *preferred_freq_list, u32 size);
 
 /* p2p_sd.c */
 struct p2p_sd_query * p2p_pending_sd_req(struct p2p_data *p2p,