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 <jouni@qca.qualcomm.com>
This commit is contained in:
parent
4033935dd9
commit
72728c6fa8
3 changed files with 37 additions and 15 deletions
|
@ -689,6 +689,7 @@ struct p2p_config {
|
||||||
* @persistent_group: Whether this is an invitation to reinvoke a
|
* @persistent_group: Whether this is an invitation to reinvoke a
|
||||||
* persistent group (instead of invitation to join an active
|
* persistent group (instead of invitation to join an active
|
||||||
* group)
|
* group)
|
||||||
|
* @channels: Available operating channels for the group
|
||||||
* Returns: Status code (P2P_SC_*)
|
* Returns: Status code (P2P_SC_*)
|
||||||
*
|
*
|
||||||
* This optional callback can be used to implement persistent reconnect
|
* 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,
|
u8 (*invitation_process)(void *ctx, const u8 *sa, const u8 *bssid,
|
||||||
const u8 *go_dev_addr, const u8 *ssid,
|
const u8 *go_dev_addr, const u8 *ssid,
|
||||||
size_t ssid_len, int *go, u8 *group_bssid,
|
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
|
* invitation_received - Callback on Invitation Request RX
|
||||||
|
|
|
@ -221,11 +221,14 @@ void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
p2p_channels_intersect(&p2p->cfg->channels, &dev->channels,
|
||||||
|
&intersection);
|
||||||
|
|
||||||
if (p2p->cfg->invitation_process) {
|
if (p2p->cfg->invitation_process) {
|
||||||
status = p2p->cfg->invitation_process(
|
status = p2p->cfg->invitation_process(
|
||||||
p2p->cfg->cb_ctx, sa, msg.group_bssid, msg.group_id,
|
p2p->cfg->cb_ctx, sa, msg.group_bssid, msg.group_id,
|
||||||
msg.group_id + ETH_ALEN, msg.group_id_len - ETH_ALEN,
|
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) {
|
if (op_freq) {
|
||||||
|
@ -238,8 +241,6 @@ void p2p_process_invitation_req(struct p2p_data *p2p, const u8 *sa,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
p2p_channels_intersect(&p2p->cfg->channels, &dev->channels,
|
|
||||||
&intersection);
|
|
||||||
if (!p2p_channels_includes(&intersection, reg_class, channel))
|
if (!p2p_channels_includes(&intersection, reg_class, channel))
|
||||||
{
|
{
|
||||||
p2p_dbg(p2p, "forced freq %d MHz not in the supported channels interaction",
|
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 {
|
} else {
|
||||||
p2p_dbg(p2p, "No forced channel from invitation processing - figure out best one to use");
|
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 */
|
/* Default to own configuration as a starting point */
|
||||||
p2p->op_reg_class = p2p->cfg->op_reg_class;
|
p2p->op_reg_class = p2p->cfg->op_reg_class;
|
||||||
p2p->op_channel = p2p->cfg->op_channel;
|
p2p->op_channel = p2p->cfg->op_channel;
|
||||||
|
|
|
@ -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,
|
static u8 wpas_invitation_process(void *ctx, const u8 *sa, const u8 *bssid,
|
||||||
const u8 *go_dev_addr, const u8 *ssid,
|
const u8 *go_dev_addr, const u8 *ssid,
|
||||||
size_t ssid_len, int *go, u8 *group_bssid,
|
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_supplicant *wpa_s = ctx;
|
||||||
struct wpa_ssid *s;
|
struct wpa_ssid *s;
|
||||||
|
@ -2461,6 +2471,25 @@ accept_inv:
|
||||||
wpas_p2p_set_own_freq_preference(wpa_s, res);
|
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;
|
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,
|
static int wpas_p2p_init_go_params(struct wpa_supplicant *wpa_s,
|
||||||
struct p2p_go_neg_results *params,
|
struct p2p_go_neg_results *params,
|
||||||
int freq, int ht40,
|
int freq, int ht40,
|
||||||
|
|
Loading…
Reference in a new issue