From 04a3e69dd18d2d0f48fc9365a8f9d1907d18ec07 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Fri, 26 Oct 2012 18:10:46 +0300 Subject: [PATCH] P2P: Allow all channels with multi-channel concurrency If the driver indicates support for multi-channel concurrency, change the p2p_connect behavior to not force the current operating channel, but instead, just mark it as preferred for GO Negotiation. This change applies only for the case when the freq parameter is not used with the p2p_connect command. Signed-hostap: Jouni Malinen --- src/drivers/driver_test.c | 2 +- src/p2p/p2p.c | 35 +++++++++++++++++++++------------ src/p2p/p2p.h | 9 +++++++-- wpa_supplicant/p2p_supplicant.c | 23 ++++++++++++++-------- 4 files changed, 45 insertions(+), 24 deletions(-) diff --git a/src/drivers/driver_test.c b/src/drivers/driver_test.c index e7bf19565..dd3a57f7b 100644 --- a/src/drivers/driver_test.c +++ b/src/drivers/driver_test.c @@ -2870,7 +2870,7 @@ static int wpa_driver_test_p2p_connect(void *priv, const u8 *peer_addr, return -1; return p2p_connect(drv->p2p, peer_addr, wps_method, go_intent, own_interface_addr, force_freq, persistent_group, - NULL, 0, 0); + NULL, 0, 0, 0); } diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 365d5fdf9..7d449c689 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -1086,15 +1086,17 @@ void p2p_stop_find(struct p2p_data *p2p) } -static int p2p_prepare_channel(struct p2p_data *p2p, unsigned int force_freq) +static int p2p_prepare_channel(struct p2p_data *p2p, unsigned int force_freq, + unsigned int pref_freq) { - if (force_freq) { + if (force_freq || pref_freq) { u8 op_reg_class, op_channel; - if (p2p_freq_to_channel(p2p->cfg->country, force_freq, + unsigned int freq = force_freq ? force_freq : pref_freq; + if (p2p_freq_to_channel(p2p->cfg->country, freq, &op_reg_class, &op_channel) < 0) { wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Unsupported frequency %u MHz", - force_freq); + freq); return -1; } if (!p2p_channels_includes(&p2p->cfg->channels, op_reg_class, @@ -1102,15 +1104,21 @@ static int p2p_prepare_channel(struct p2p_data *p2p, unsigned int force_freq) wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Frequency %u MHz (oper_class %u " "channel %u) not allowed for P2P", - force_freq, op_reg_class, op_channel); + freq, op_reg_class, op_channel); return -1; } p2p->op_reg_class = op_reg_class; p2p->op_channel = op_channel; - p2p->channels.reg_classes = 1; - p2p->channels.reg_class[0].channels = 1; - p2p->channels.reg_class[0].reg_class = p2p->op_reg_class; - p2p->channels.reg_class[0].channel[0] = p2p->op_channel; + if (force_freq) { + p2p->channels.reg_classes = 1; + p2p->channels.reg_class[0].channels = 1; + p2p->channels.reg_class[0].reg_class = + p2p->op_reg_class; + p2p->channels.reg_class[0].channel[0] = p2p->op_channel; + } else { + os_memcpy(&p2p->channels, &p2p->cfg->channels, + sizeof(struct p2p_channels)); + } } else { u8 op_reg_class, op_channel; @@ -1190,7 +1198,7 @@ int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr, int go_intent, const u8 *own_interface_addr, unsigned int force_freq, int persistent_group, const u8 *force_ssid, size_t force_ssid_len, - int pd_before_go_neg) + int pd_before_go_neg, unsigned int pref_freq) { struct p2p_device *dev; @@ -1201,7 +1209,7 @@ int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr, MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), wps_method, persistent_group, pd_before_go_neg); - if (p2p_prepare_channel(p2p, force_freq) < 0) + if (p2p_prepare_channel(p2p, force_freq, pref_freq) < 0) return -1; dev = p2p_get_device(p2p, peer_addr); @@ -1301,7 +1309,8 @@ int p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr, enum p2p_wps_method wps_method, int go_intent, const u8 *own_interface_addr, unsigned int force_freq, int persistent_group, - const u8 *force_ssid, size_t force_ssid_len) + const u8 *force_ssid, size_t force_ssid_len, + unsigned int pref_freq) { struct p2p_device *dev; @@ -1312,7 +1321,7 @@ int p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr, MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr), wps_method, persistent_group); - if (p2p_prepare_channel(p2p, force_freq) < 0) + if (p2p_prepare_channel(p2p, force_freq, pref_freq) < 0) return -1; dev = p2p_get_device(p2p, peer_addr); diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 9ea4694e7..e5833f009 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -889,6 +889,8 @@ int p2p_listen(struct p2p_data *p2p, unsigned int timeout); * @pd_before_go_neg: Whether to send Provision Discovery prior to GO * Negotiation as an interoperability workaround when initiating group * formation + * @pref_freq: Preferred operating frequency in MHz or 0 (this is only used if + * force_freq == 0) * Returns: 0 on success, -1 on failure */ int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr, @@ -896,7 +898,7 @@ int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr, int go_intent, const u8 *own_interface_addr, unsigned int force_freq, int persistent_group, const u8 *force_ssid, size_t force_ssid_len, - int pd_before_go_neg); + int pd_before_go_neg, unsigned int pref_freq); /** * p2p_authorize - Authorize P2P group formation (GO negotiation) @@ -912,6 +914,8 @@ int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr, * @force_ssid: Forced SSID for the group if we become GO or %NULL to generate * a new SSID * @force_ssid_len: Length of $force_ssid buffer + * @pref_freq: Preferred operating frequency in MHz or 0 (this is only used if + * force_freq == 0) * Returns: 0 on success, -1 on failure * * This is like p2p_connect(), but the actual group negotiation is not @@ -921,7 +925,8 @@ int p2p_authorize(struct p2p_data *p2p, const u8 *peer_addr, enum p2p_wps_method wps_method, int go_intent, const u8 *own_interface_addr, unsigned int force_freq, int persistent_group, - const u8 *force_ssid, size_t force_ssid_len); + const u8 *force_ssid, size_t force_ssid_len, + unsigned int pref_freq); /** * p2p_reject - Reject peer device (explicitly block connection attempts) diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 9e552c82e..be87567a4 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -2879,7 +2879,7 @@ static int wpas_p2p_start_go_neg(struct wpa_supplicant *wpa_s, enum p2p_wps_method wps_method, int go_intent, const u8 *own_interface_addr, unsigned int force_freq, int persistent_group, - struct wpa_ssid *ssid) + struct wpa_ssid *ssid, unsigned int pref_freq) { if (persistent_group && wpa_s->conf->persistent_reconnect) persistent_group = 2; @@ -2901,7 +2901,7 @@ static int wpas_p2p_start_go_neg(struct wpa_supplicant *wpa_s, go_intent, own_interface_addr, force_freq, persistent_group, ssid ? ssid->ssid : NULL, ssid ? ssid->ssid_len : 0, - wpa_s->p2p_pd_before_go_neg); + wpa_s->p2p_pd_before_go_neg, pref_freq); } @@ -2910,7 +2910,7 @@ static int wpas_p2p_auth_go_neg(struct wpa_supplicant *wpa_s, enum p2p_wps_method wps_method, int go_intent, const u8 *own_interface_addr, unsigned int force_freq, int persistent_group, - struct wpa_ssid *ssid) + struct wpa_ssid *ssid, unsigned int pref_freq) { if (persistent_group && wpa_s->conf->persistent_reconnect) persistent_group = 2; @@ -2921,7 +2921,7 @@ static int wpas_p2p_auth_go_neg(struct wpa_supplicant *wpa_s, return p2p_authorize(wpa_s->global->p2p, peer_addr, wps_method, go_intent, own_interface_addr, force_freq, persistent_group, ssid ? ssid->ssid : NULL, - ssid ? ssid->ssid_len : 0); + ssid ? ssid->ssid_len : 0, pref_freq); } @@ -3399,7 +3399,7 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr, int go_intent, int freq, int persistent_id, int pd, int ht40) { - int force_freq = 0, oper_freq = 0; + int force_freq = 0, pref_freq = 0, oper_freq = 0; u8 bssid[ETH_ALEN]; int ret = 0; enum wpa_driver_if_type iftype; @@ -3512,6 +3512,13 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr, "(%u MHz) not available for P2P - try to use " "another channel", oper_freq); force_freq = 0; + } else if (oper_freq > 0 && + (wpa_s->drv_flags & + WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) { + wpa_printf(MSG_DEBUG, "P2P: Trying to prefer the channel we " + "are already using (%u MHz) on another interface", + oper_freq); + pref_freq = oper_freq; } else if (oper_freq > 0) { wpa_printf(MSG_DEBUG, "P2P: Trying to force us to use the " "channel we are already using (%u MHz) on another " @@ -3539,15 +3546,15 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr, if (auth) { if (wpas_p2p_auth_go_neg(wpa_s, peer_addr, wps_method, go_intent, if_addr, - force_freq, persistent_group, ssid) < - 0) + force_freq, persistent_group, ssid, + pref_freq) < 0) return -1; return ret; } if (wpas_p2p_start_go_neg(wpa_s, peer_addr, wps_method, go_intent, if_addr, force_freq, - persistent_group, ssid) < 0) { + persistent_group, ssid, pref_freq) < 0) { if (wpa_s->create_p2p_iface) wpas_p2p_remove_pending_group_interface(wpa_s); return -1;