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>
This commit is contained in:
parent
9baaac2d84
commit
370017d968
4 changed files with 90 additions and 5 deletions
|
@ -5383,3 +5383,20 @@ void p2p_go_neg_wait_timeout(void *eloop_ctx, void *timeout_ctx)
|
||||||
"Timeout on waiting peer to become ready for GO Negotiation");
|
"Timeout on waiting peer to become ready for GO Negotiation");
|
||||||
p2p_go_neg_failed(p2p, -1);
|
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]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -23,6 +23,11 @@
|
||||||
#define P2P_MAX_QUERY_HASH 6
|
#define P2P_MAX_QUERY_HASH 6
|
||||||
#define P2PS_FEATURE_CAPAB_CPT_MAX 2
|
#define P2PS_FEATURE_CAPAB_CPT_MAX 2
|
||||||
|
|
||||||
|
/**
|
||||||
|
* P2P_MAX_PREF_CHANNELS - Maximum number of preferred channels
|
||||||
|
*/
|
||||||
|
#define P2P_MAX_PREF_CHANNELS 100
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* P2P_MAX_REG_CLASSES - Maximum number of regulatory classes
|
* P2P_MAX_REG_CLASSES - Maximum number of regulatory classes
|
||||||
*/
|
*/
|
||||||
|
@ -2302,4 +2307,8 @@ struct p2ps_advertisement * p2p_get_p2ps_adv_list(struct p2p_data *p2p);
|
||||||
*/
|
*/
|
||||||
void p2p_expire_peers(struct p2p_data *p2p);
|
void p2p_expire_peers(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 */
|
#endif /* P2P_H */
|
||||||
|
|
|
@ -538,6 +538,9 @@ struct p2p_data {
|
||||||
u16 authorized_oob_dev_pw_id;
|
u16 authorized_oob_dev_pw_id;
|
||||||
|
|
||||||
struct wpabuf **vendor_elem;
|
struct wpabuf **vendor_elem;
|
||||||
|
|
||||||
|
unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS];
|
||||||
|
unsigned int num_pref_freq;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -4792,11 +4792,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,
|
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;
|
struct wpa_used_freq_data *freqs;
|
||||||
int res, best_freq, num_unused;
|
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,
|
freqs = os_calloc(wpa_s->num_multichan_concurrent,
|
||||||
sizeof(struct wpa_used_freq_data));
|
sizeof(struct wpa_used_freq_data));
|
||||||
|
@ -4861,6 +4866,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);
|
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 */
|
/* We have a candidate frequency to use */
|
||||||
if (best_freq > 0) {
|
if (best_freq > 0) {
|
||||||
if (*pref_freq == 0 && num_unused > 0) {
|
if (*pref_freq == 0 && num_unused > 0) {
|
||||||
|
@ -4925,6 +4971,7 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
|
||||||
enum wpa_driver_if_type iftype;
|
enum wpa_driver_if_type iftype;
|
||||||
const u8 *if_addr;
|
const u8 *if_addr;
|
||||||
struct wpa_ssid *ssid = NULL;
|
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)
|
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -5001,13 +5048,16 @@ int wpas_p2p_connect(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
size = P2P_MAX_PREF_CHANNELS;
|
||||||
res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
|
res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
|
||||||
go_intent == 15);
|
go_intent == 15, pref_freq_list, &size);
|
||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
wpas_p2p_set_own_freq_preference(wpa_s,
|
wpas_p2p_set_own_freq_preference(wpa_s,
|
||||||
force_freq ? force_freq : pref_freq);
|
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);
|
wpa_s->create_p2p_iface = wpas_p2p_create_iface(wpa_s);
|
||||||
|
|
||||||
if (wpa_s->create_p2p_iface) {
|
if (wpa_s->create_p2p_iface) {
|
||||||
|
@ -6190,6 +6240,7 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
|
||||||
int force_freq = 0;
|
int force_freq = 0;
|
||||||
int res;
|
int res;
|
||||||
int no_pref_freq_given = pref_freq == 0;
|
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;
|
wpa_s->global->p2p_invite_group = NULL;
|
||||||
if (peer_addr)
|
if (peer_addr)
|
||||||
|
@ -6223,8 +6274,10 @@ int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
|
||||||
}
|
}
|
||||||
wpa_s->pending_invite_ssid_id = ssid->id;
|
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,
|
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)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
|
@ -6263,6 +6316,7 @@ int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
|
||||||
int persistent;
|
int persistent;
|
||||||
int freq = 0, force_freq = 0, pref_freq = 0;
|
int freq = 0, force_freq = 0, pref_freq = 0;
|
||||||
int res;
|
int res;
|
||||||
|
unsigned int pref_freq_list[P2P_MAX_PREF_CHANNELS], size;
|
||||||
|
|
||||||
wpa_s->p2p_persistent_go_freq = 0;
|
wpa_s->p2p_persistent_go_freq = 0;
|
||||||
wpa_s->p2p_go_ht40 = 0;
|
wpa_s->p2p_go_ht40 = 0;
|
||||||
|
@ -6314,8 +6368,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)
|
if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
size = P2P_MAX_PREF_CHANNELS;
|
||||||
res = wpas_p2p_setup_freqs(wpa_s, freq, &force_freq, &pref_freq,
|
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)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
wpas_p2p_set_own_freq_preference(wpa_s, force_freq);
|
wpas_p2p_set_own_freq_preference(wpa_s, force_freq);
|
||||||
|
|
Loading…
Reference in a new issue