From 72728c6fa8e63f7eb2b6e54e6a610d569483eee5 Mon Sep 17 00:00:00 2001 From: Sean Lin Date: Wed, 22 May 2013 13:29:46 +0300 Subject: [PATCH] P2P: Relax channel forcing for invitation processing with MCC support When STA interface is connected and P2P interface gets invited in a different channel from previous P2P group, the invitiation would fail because of no common channel found. Fix this by using different logic when device support multi channel concurrency. Signed-hostap: Jouni Malinen --- src/p2p/p2p.h | 4 +++- src/p2p/p2p_invitation.c | 9 ++++---- wpa_supplicant/p2p_supplicant.c | 39 +++++++++++++++++++++++++-------- 3 files changed, 37 insertions(+), 15 deletions(-) diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h index fc48e6b8c..e911474e6 100644 --- a/src/p2p/p2p.h +++ b/src/p2p/p2p.h @@ -689,6 +689,7 @@ struct p2p_config { * @persistent_group: Whether this is an invitation to reinvoke a * persistent group (instead of invitation to join an active * group) + * @channels: Available operating channels for the group * Returns: Status code (P2P_SC_*) * * This optional callback can be used to implement persistent reconnect @@ -709,7 +710,8 @@ struct p2p_config { u8 (*invitation_process)(void *ctx, const u8 *sa, const u8 *bssid, const u8 *go_dev_addr, const u8 *ssid, size_t ssid_len, int *go, u8 *group_bssid, - int *force_freq, int persistent_group); + int *force_freq, int persistent_group, + const struct p2p_channels *channels); /** * invitation_received - Callback on Invitation Request RX diff --git a/src/p2p/p2p_invitation.c b/src/p2p/p2p_invitation.c index a3d013f79..293fef0c4 100644 --- a/src/p2p/p2p_invitation.c +++ b/src/p2p/p2p_invitation.c @@ -221,11 +221,14 @@ void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa, goto fail; } + p2p_channels_intersect(&p2p->cfg->channels, &dev->channels, + &intersection); + if (p2p->cfg->invitation_process) { status = p2p->cfg->invitation_process( p2p->cfg->cb_ctx, sa, msg.group_bssid, msg.group_id, msg.group_id + ETH_ALEN, msg.group_id_len - ETH_ALEN, - &go, group_bssid, &op_freq, persistent); + &go, group_bssid, &op_freq, persistent, &intersection); } if (op_freq) { @@ -238,8 +241,6 @@ void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa, goto fail; } - p2p_channels_intersect(&p2p->cfg->channels, &dev->channels, - &intersection); if (!p2p_channels_includes(&intersection, reg_class, channel)) { p2p_dbg(p2p, "forced freq %d MHz not in the supported channels interaction", @@ -253,8 +254,6 @@ void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa, } else { p2p_dbg(p2p, "No forced channel from invitation processing - figure out best one to use"); - p2p_channels_intersect(&p2p->cfg->channels, &dev->channels, - &intersection); /* Default to own configuration as a starting point */ p2p->op_reg_class = p2p->cfg->op_reg_class; p2p->op_channel = p2p->cfg->op_channel; diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c index 450853870..7b8db8060 100644 --- a/wpa_supplicant/p2p_supplicant.c +++ b/wpa_supplicant/p2p_supplicant.c @@ -2360,10 +2360,20 @@ static void wpas_prov_disc_fail(void *ctx, const u8 *peer, } +static int freq_included(const struct p2p_channels *channels, unsigned int freq) +{ + if (channels == NULL) + return 1; /* Assume no restrictions */ + return p2p_channels_includes_freq(channels, freq); + +} + + static u8 wpas_invitation_process(void *ctx, const u8 *sa, const u8 *bssid, const u8 *go_dev_addr, const u8 *ssid, size_t ssid_len, int *go, u8 *group_bssid, - int *force_freq, int persistent_group) + int *force_freq, int persistent_group, + const struct p2p_channels *channels) { struct wpa_supplicant *wpa_s = ctx; struct wpa_ssid *s; @@ -2461,6 +2471,25 @@ accept_inv: wpas_p2p_set_own_freq_preference(wpa_s, res); } + if (*force_freq > 0 && + (wpa_s->drv_flags & WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) { + if (*go == 0) { + /* We are the client */ + wpa_printf(MSG_DEBUG, "P2P: Peer was found to be " + "running a GO but we are capable of MCC, " + "figure out the best channel to use"); + *force_freq = 0; + } else if (!freq_included(channels, *force_freq)) { + /* We are the GO, and *force_freq is not in the + * intersection */ + wpa_printf(MSG_DEBUG, "P2P: Forced GO freq %d MHz not " + "in intersection but we are capable of MCC, " + "figure out the best channel to use", + *force_freq); + *force_freq = 0; + } + } + return P2P_SC_SUCCESS; } @@ -4005,14 +4034,6 @@ int wpas_p2p_group_remove(struct wpa_supplicant *wpa_s, const char *ifname) } -static int freq_included(const struct p2p_channels *channels, unsigned int freq) -{ - if (channels == NULL) - return 1; /* Assume no restrictions */ - return p2p_channels_includes_freq(channels, freq); -} - - static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s, struct p2p_go_neg_results *params, int freq, int ht40,