aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAhmad Kholaif <akholaif@qca.qualcomm.com>2015-07-24 00:39:45 +0000
committerAnjaneedevi Kapparapu <akappa@codeaurora.org>2016-04-01 16:45:21 +0530
commit9fe2590f82a6e74d8f4502ba562e339caebdd288 (patch)
treef356b0d1d86ed1161622eeb2a349a97801da736e
parentfa36f79488af4aac63c1851c944ea3a41e9d7985 (diff)
downloadandroid_external_wpa_supplicant_8-9fe2590f82a6e74d8f4502ba562e339caebdd288.tar.gz
android_external_wpa_supplicant_8-9fe2590f82a6e74d8f4502ba562e339caebdd288.tar.bz2
android_external_wpa_supplicant_8-9fe2590f82a6e74d8f4502ba562e339caebdd288.zip
P2P: Use preferred frequency list from the local driver
If the driver supports the preferred frequency list extension, use this information from the driver when no explicitly configured preference list (p2p_pref_chan) is present for P2P operating channel selection. This commit adds this for GO Negotiation and Invitation use cases. Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com> Git-commit: 370017d968e071522357ea88c0c6aaed02853222 Git-repo : git://w1.fi/srv/git/hostap.git Change-Id: Idd39a8276daaf450b8d720a9fdf617f6427f5e48 CRs-fixed: 842468
-rw-r--r--src/p2p/p2p.c17
-rw-r--r--src/p2p/p2p.h9
-rw-r--r--src/p2p/p2p_i.h3
-rw-r--r--wpa_supplicant/p2p_supplicant.c66
4 files changed, 90 insertions, 5 deletions
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index 99bd402a..fb4c0aec 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -5390,3 +5390,20 @@ void p2p_go_neg_wait_timeout(void *eloop_ctx, void *timeout_ctx)
"Timeout on waiting peer to become ready for GO Negotiation");
p2p_go_neg_failed(p2p, -1);
}
+
+
+void p2p_set_own_pref_freq_list(struct p2p_data *p2p,
+ const unsigned int *pref_freq_list,
+ unsigned int size)
+{
+ unsigned int i;
+
+ if (size > P2P_MAX_PREF_CHANNELS)
+ size = P2P_MAX_PREF_CHANNELS;
+ p2p->num_pref_freq = size;
+ for (i = 0; i < size; i++) {
+ p2p->pref_freq_list[i] = pref_freq_list[i];
+ p2p_dbg(p2p, "Own preferred frequency list[%u]=%u MHz",
+ i, p2p->pref_freq_list[i]);
+ }
+}
diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h
index 67b8bdb6..f12419fb 100644
--- a/src/p2p/p2p.h
+++ b/src/p2p/p2p.h
@@ -23,6 +23,11 @@
#define P2P_MAX_QUERY_HASH 6
/**
+ * P2P_MAX_PREF_CHANNELS - Maximum number of preferred channels
+ */
+#define P2P_MAX_PREF_CHANNELS 100
+
+/**
* P2P_MAX_REG_CLASSES - Maximum number of regulatory classes
*/
#define P2P_MAX_REG_CLASSES 10
@@ -2253,4 +2258,8 @@ int p2p_service_del_asp(struct p2p_data *p2p, u32 adv_id);
void p2p_service_flush_asp(struct p2p_data *p2p);
struct p2ps_advertisement * p2p_get_p2ps_adv_list(struct p2p_data *p2p);
+void p2p_set_own_pref_freq_list(struct p2p_data *p2p,
+ const unsigned int *pref_freq_list,
+ unsigned int size);
+
#endif /* P2P_H */
diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h
index 78e52c93..407316fc 100644
--- a/src/p2p/p2p_i.h
+++ b/src/p2p/p2p_i.h
@@ -535,6 +535,9 @@ struct p2p_data {
u16 authorized_oob_dev_pw_id;
struct wpabuf **vendor_elem;
+
+ unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS];
+ unsigned int num_pref_freq;
};
/**
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 2f85f0fd..bbdee0ff 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -4724,11 +4724,16 @@ static int wpas_p2p_join_start(struct wpa_supplicant *wpa_s, int freq,
static int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq,
- int *force_freq, int *pref_freq, int go)
+ int *force_freq, int *pref_freq, int go,
+ unsigned int *pref_freq_list,
+ unsigned int *num_pref_freq)
{
struct wpa_used_freq_data *freqs;
int res, best_freq, num_unused;
- unsigned int freq_in_use = 0, num, i;
+ unsigned int freq_in_use = 0, num, i, max_pref_freq;
+
+ max_pref_freq = *num_pref_freq;
+ *num_pref_freq = 0;
freqs = os_calloc(wpa_s->num_multichan_concurrent,
sizeof(struct wpa_used_freq_data));
@@ -4793,6 +4798,47 @@ static int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq,
best_freq = wpas_p2p_pick_best_used_freq(wpa_s, freqs, num);
+ if (!wpa_s->conf->num_p2p_pref_chan && *pref_freq == 0) {
+ enum wpa_driver_if_type iface_type;
+
+ if (go)
+ iface_type = WPA_IF_P2P_GO;
+ else
+ iface_type = WPA_IF_P2P_CLIENT;
+
+ wpa_printf(MSG_DEBUG, "P2P: best_freq=%d, go=%d",
+ best_freq, go);
+
+ res = wpa_drv_get_pref_freq_list(wpa_s, iface_type,
+ &max_pref_freq,
+ pref_freq_list);
+ if (!res && max_pref_freq > 0) {
+ *num_pref_freq = max_pref_freq;
+ i = 0;
+ while (wpas_p2p_disallowed_freq(wpa_s->global,
+ pref_freq_list[i]) &&
+ i < *num_pref_freq) {
+ wpa_printf(MSG_DEBUG,
+ "P2P: preferred_freq_list[%d]=%d is disallowed",
+ i, pref_freq_list[i]);
+ i++;
+ }
+ if (i != *num_pref_freq) {
+ best_freq = pref_freq_list[i];
+ wpa_printf(MSG_DEBUG,
+ "P2P: Using preferred_freq_list[%d]=%d",
+ i, best_freq);
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "P2P: All driver preferred frequencies are disallowed for P2P use");
+ *num_pref_freq = 0;
+ }
+ } else {
+ wpa_printf(MSG_DEBUG,
+ "P2P: No preferred frequency list available");
+ }
+ }
+
/* We have a candidate frequency to use */
if (best_freq > 0) {
if (*pref_freq == 0 && num_unused > 0) {
@@ -4857,6 +4903,7 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
enum wpa_driver_if_type iftype;
const u8 *if_addr;
struct wpa_ssid *ssid = NULL;
+ unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS], size;
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
return -1;
@@ -4933,13 +4980,16 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
return ret;
}
+ size = P2P_MAX_PREF_CHANNELS;
res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
- go_intent == 15);
+ go_intent == 15, pref_freq_list, &size);
if (res)
return res;
wpas_p2p_set_own_freq_preference(wpa_s,
force_freq ? force_freq : pref_freq);
+ p2p_set_own_pref_freq_list(wpa_s->global->p2p, pref_freq_list, size);
+
wpa_s->create_p2p_iface = wpas_p2p_create_iface(wpa_s);
if (wpa_s->create_p2p_iface) {
@@ -6127,6 +6177,7 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
int force_freq = 0;
int res;
int no_pref_freq_given = pref_freq == 0;
+ unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS], size;
wpa_s->global->p2p_invite_group = NULL;
if (peer_addr)
@@ -6160,8 +6211,10 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
}
wpa_s->pending_invite_ssid_id = ssid->id;
+ size = P2P_MAX_PREF_CHANNELS;
res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
- role == P2P_INVITE_ROLE_GO);
+ role == P2P_INVITE_ROLE_GO,
+ pref_freq_list, &size);
if (res)
return res;
@@ -6200,6 +6253,7 @@ int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
int persistent;
int freq = 0, force_freq = 0, pref_freq = 0;
int res;
+ unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS], size;
wpa_s->p2p_persistent_go_freq = 0;
wpa_s->p2p_go_ht40 = 0;
@@ -6251,8 +6305,10 @@ int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
return -1;
+ size = P2P_MAX_PREF_CHANNELS;
res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
- role == P2P_INVITE_ROLE_ACTIVE_GO);
+ role == P2P_INVITE_ROLE_ACTIVE_GO,
+ pref_freq_list, &size);
if (res)
return res;
wpas_p2p_set_own_freq_preference(wpa_s, force_freq);