From 79879f4ae8f3eacee52699e3ccd5e0baba601c4d Mon Sep 17 00:00:00 2001 From: Deepthi Gowri Date: Mon, 25 Feb 2013 18:41:32 +0200 Subject: [PATCH] P2P: Allow all channels in case of multi channel concurrency If multi channel concurrency is supported, we have to populate the p2p_channels with list of channels that we support. Use the same design that was previously added for GO Negotiation. Signed-hostap: Jouni Malinen --- src/p2p/p2p.c | 4 +- src/p2p/p2p.h | 4 +- src/p2p/p2p_i.h | 2 + src/p2p/p2p_invitation.c | 25 ++------ wpa_supplicant/p2p_supplicant.c | 108 ++++++++++++++++++++++++++++++-- 5 files changed, 114 insertions(+), 29 deletions(-) diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 15df215e3..ec62836ee 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -1259,8 +1259,8 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p) * may be further optimized in p2p_reselect_channel() once the peer information * is available. */ -static int p2p_prepare_channel(struct p2p_data *p2p, struct p2p_device *dev, - unsigned int force_freq, unsigned int pref_freq) +int p2p_prepare_channel(struct p2p_data *p2p, struct p2p_device *dev, + unsigned int force_freq, unsigned int pref_freq) { if (force_freq || pref_freq) { if (p2p_prepare_channel_pref(p2p, force_freq, pref_freq) < 0) diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index 4a35d5256..3a724bee3 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -1042,12 +1042,14 @@ enum p2p_invite_role { * @force_freq: The only allowed channel frequency in MHz or 0 * @go_dev_addr: Forced GO Device Address or %NULL if none * @persistent_group: Whether this is to reinvoke a persistent group + * @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_invite(struct p2p_data *p2p, const u8 *peer, enum p2p_invite_role role, const u8 *bssid, const u8 *ssid, size_t ssid_len, unsigned int force_freq, const u8 *go_dev_addr, - int persistent_group); + int persistent_group, unsigned int pref_freq); /** * p2p_presence_req - Request GO presence diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h index e91959f82..856f78f52 100644 --- a/src/p2p/p2p_i.h +++ b/src/p2p/p2p_i.h @@ -713,5 +713,7 @@ int p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst, const u8 *src, const u8 *bssid, const u8 *buf, size_t len, unsigned int wait_time); void p2p_stop_listen_for_freq(struct p2p_data *p2p, int freq); +int p2p_prepare_channel(struct p2p_data *p2p, struct p2p_device *dev, + unsigned int force_freq, unsigned int pref_freq); #endif /* P2P_I_H */ diff --git a/src/p2p/p2p_invitation.c b/src/p2p/p2p_invitation.c index 10aa61684..918fd4bf1 100644 --- a/src/p2p/p2p_invitation.c +++ b/src/p2p/p2p_invitation.c @@ -531,7 +531,7 @@ void p2p_invitation_resp_cb(struct p2p_data *p2p, int success) int p2p_invite(struct p2p_data *p2p, const u8 *peer, enum p2p_invite_role role, const u8 *bssid, const u8 *ssid, size_t ssid_len, unsigned int force_freq, const u8 *go_dev_addr, - int persistent_group) + int persistent_group, unsigned int pref_freq) { struct p2p_device *dev; @@ -561,6 +561,9 @@ int p2p_invite(struct p2p_data *p2p, const u8 *peer, enum p2p_invite_role role, return -1; } + if (p2p_prepare_channel(p2p, dev, force_freq, pref_freq) < 0) + return -1; + if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) { if (!(dev->info.dev_capab & P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) { @@ -574,26 +577,6 @@ int p2p_invite(struct p2p_data *p2p, const u8 *peer, enum p2p_invite_role role, dev->invitation_reqs = 0; - if (force_freq) { - if (p2p_freq_to_channel(p2p->cfg->country, force_freq, - &p2p->op_reg_class, &p2p->op_channel) < - 0) { - wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, - "P2P: Unsupported frequency %u MHz", - force_freq); - return -1; - } - 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 { - p2p->op_reg_class = p2p->cfg->op_reg_class; - p2p->op_channel = p2p->cfg->op_channel; - os_memcpy(&p2p->channels, &p2p->cfg->channels, - sizeof(struct p2p_channels)); - } - if (p2p->state != P2P_IDLE) p2p_stop_find(p2p); diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index d6015b9eb..dd86caa17 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -4573,7 +4573,8 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr, int ht40) { enum p2p_invite_role role; - u8 *bssid = NULL; + u8 *bssid = NULL, bssid_buf[ETH_ALEN]; + int force_freq = 0, pref_freq = 0, oper_freq = 0; wpa_s->p2p_persistent_go_freq = freq; wpa_s->p2p_go_ht40 = !!ht40; @@ -4601,6 +4602,63 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr, } wpa_s->pending_invite_ssid_id = ssid->id; + if (wpa_s->current_ssid && wpa_drv_get_bssid(wpa_s, bssid_buf) == 0 && + wpa_s->assoc_freq) { + oper_freq = wpa_s->assoc_freq; + if (bssid == NULL) + bssid = bssid_buf; + } else { + oper_freq = wpa_drv_shared_freq(wpa_s); + if (oper_freq < 0) + oper_freq = 0; + } + + if (freq > 0) { + if (!p2p_supported_freq(wpa_s->global->p2p, freq)) { + wpa_printf(MSG_DEBUG, "P2P: The forced channel " + "(%u MHz) is not supported for P2P uses", + freq); + return -3; + } + + if (oper_freq > 0 && freq != oper_freq && + !(wpa_s->drv_flags & + WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) { + wpa_printf(MSG_DEBUG, "P2P: Cannot start P2P group " + "on %u MHz while connected on another " + "channel (%u MHz)", freq, oper_freq); + return -2; + } + wpa_printf(MSG_DEBUG, "P2P: Trying to force us to use the " + "requested channel (%u MHz)", freq); + force_freq = freq; + } else if (oper_freq > 0 && + !p2p_supported_freq(wpa_s->global->p2p, oper_freq)) { + if (!(wpa_s->drv_flags & + WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) { + wpa_printf(MSG_DEBUG, "P2P: Cannot start P2P group " + "while connected on non-P2P supported " + "channel (%u MHz)", oper_freq); + return -2; + } + wpa_printf(MSG_DEBUG, "P2P: Current operating channel " + "(%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 " + "interface", oper_freq); + force_freq = oper_freq; + } + if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_P2P_MGMT) return wpa_drv_p2p_invite(wpa_s, peer_addr, role, bssid, ssid->ssid, ssid->ssid_len, @@ -4610,7 +4668,8 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr, return -1; return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid, - ssid->ssid, ssid->ssid_len, freq, go_dev_addr, 1); + ssid->ssid, ssid->ssid_len, force_freq, go_dev_addr, + 1, pref_freq); } @@ -4620,9 +4679,10 @@ int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname, { struct wpa_global *global = wpa_s->global; enum p2p_invite_role role; - u8 *bssid = NULL; + u8 *bssid = NULL, bssid_buf[ETH_ALEN]; struct wpa_ssid *ssid; int persistent; + int force_freq = 0, oper_freq = 0, pref_freq = 0; wpa_s->p2p_persistent_go_freq = 0; wpa_s->p2p_go_ht40 = 0; @@ -4674,9 +4734,47 @@ 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; + if (wpa_s->current_ssid && wpa_drv_get_bssid(wpa_s, bssid_buf) == 0 && + wpa_s->assoc_freq) { + oper_freq = wpa_s->assoc_freq; + if (bssid == NULL) + bssid = bssid_buf; + } else { + oper_freq = wpa_drv_shared_freq(wpa_s); + if (oper_freq < 0) + oper_freq = 0; + } + + if (oper_freq > 0 && + !p2p_supported_freq(wpa_s->global->p2p, oper_freq)) { + if (!(wpa_s->drv_flags & + WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) { + wpa_printf(MSG_DEBUG, "P2P: Cannot start P2P group " + "while connected on non-P2P supported " + "channel (%u MHz)", oper_freq); + return -2; + } + wpa_printf(MSG_DEBUG, "P2P: Current operating channel " + "(%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 " + "interface", oper_freq); + force_freq = oper_freq; + } + return p2p_invite(wpa_s->global->p2p, peer_addr, role, bssid, - ssid->ssid, ssid->ssid_len, wpa_s->assoc_freq, - go_dev_addr, persistent); + ssid->ssid, ssid->ssid_len, force_freq, + go_dev_addr, persistent, pref_freq); }