P2P: Allow P2P client to specify preferred group channel

When re-invoking a persistent group in P2P client role, the new
pref=<MHz> parameter can now be used with the p2p_invite command to
indicate a preferred operating frequency. Unlike the older freq=<MHz>
parameter, this leaves GO an option to select another channel (from our
supported channels) if the GO cannot accept the channel.

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
This commit is contained in:
Jouni Malinen 2013-03-01 19:40:54 +02:00 committed by Jouni Malinen
parent 5de4b72177
commit f5877af01e
7 changed files with 34 additions and 11 deletions

View file

@ -92,6 +92,7 @@ struct p2p_device {
#define P2P_DEV_REPORTED_ONCE BIT(15) #define P2P_DEV_REPORTED_ONCE BIT(15)
#define P2P_DEV_PREFER_PERSISTENT_RECONN BIT(16) #define P2P_DEV_PREFER_PERSISTENT_RECONN BIT(16)
#define P2P_DEV_PD_BEFORE_GO_NEG BIT(17) #define P2P_DEV_PD_BEFORE_GO_NEG BIT(17)
#define P2P_DEV_NO_PREF_CHAN BIT(18)
unsigned int flags; unsigned int flags;
int status; /* enum p2p_status_code */ int status; /* enum p2p_status_code */

View file

@ -62,8 +62,11 @@ static struct wpabuf * p2p_build_invitation_req(struct p2p_data *p2p,
p2p->client_timeout); p2p->client_timeout);
p2p_buf_add_invitation_flags(buf, p2p->inv_persistent ? p2p_buf_add_invitation_flags(buf, p2p->inv_persistent ?
P2P_INVITATION_FLAGS_TYPE : 0); P2P_INVITATION_FLAGS_TYPE : 0);
p2p_buf_add_operating_channel(buf, p2p->cfg->country, if (p2p->inv_role != P2P_INVITE_ROLE_CLIENT ||
p2p->op_reg_class, p2p->op_channel); !(peer->flags & P2P_DEV_NO_PREF_CHAN))
p2p_buf_add_operating_channel(buf, p2p->cfg->country,
p2p->op_reg_class,
p2p->op_channel);
if (p2p->inv_bssid_set) if (p2p->inv_bssid_set)
p2p_buf_add_group_bssid(buf, p2p->inv_bssid); p2p_buf_add_group_bssid(buf, p2p->inv_bssid);
p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->channels); p2p_buf_add_channel_list(buf, p2p->cfg->country, &p2p->channels);
@ -564,6 +567,12 @@ int p2p_invite(struct p2p_data *p2p, const u8 *peer, enum p2p_invite_role role,
if (p2p_prepare_channel(p2p, dev, force_freq, pref_freq) < 0) if (p2p_prepare_channel(p2p, dev, force_freq, pref_freq) < 0)
return -1; return -1;
if (persistent_group && role == P2P_INVITE_ROLE_CLIENT && !force_freq &&
!pref_freq)
dev->flags |= P2P_DEV_NO_PREF_CHAN;
else
dev->flags &= ~P2P_DEV_NO_PREF_CHAN;
if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) { if (dev->flags & P2P_DEV_GROUP_CLIENT_ONLY) {
if (!(dev->info.dev_capab & if (!(dev->info.dev_capab &
P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) { P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) {

View file

@ -365,7 +365,7 @@ Remove all local services from internal SD query processing.
Invitation Invitation
p2p_invite [persistent=<network id>|group=<group ifname>] [peer=address] p2p_invite [persistent=<network id>|group=<group ifname>] [peer=address]
[go_dev_addr=address] [freq=<freq in MHz>] [ht40] [go_dev_addr=address] [freq=<freq in MHz>] [ht40] [pref=<MHz>]
Invite a peer to join a group (e.g., group=wlan1) or to reinvoke a Invite a peer to join a group (e.g., group=wlan1) or to reinvoke a
persistent group (e.g., persistent=4). If the peer device is the GO of persistent group (e.g., persistent=4). If the peer device is the GO of
@ -374,7 +374,11 @@ used to specify which device to invite. go_dev_addr parameter can be
used to override the GO device address for Invitation Request should used to override the GO device address for Invitation Request should
it be not known for some reason (this should not be needed in most it be not known for some reason (this should not be needed in most
cases). When reinvoking a persistent group, the GO device can specify cases). When reinvoking a persistent group, the GO device can specify
the frequency for the group with the freq parameter. the frequency for the group with the freq parameter. When reinvoking a
persistent group, the P2P client device can use freq parameter to force
a specific operating channel (or invitation failure if GO rejects that)
or pref parameter to request a specific channel (while allowing GO to
select to use another channel, if needed).
Group Operations Group Operations

View file

@ -3969,7 +3969,7 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
int id; int id;
struct wpa_ssid *ssid; struct wpa_ssid *ssid;
u8 *_peer = NULL, peer[ETH_ALEN]; u8 *_peer = NULL, peer[ETH_ALEN];
int freq = 0; int freq = 0, pref_freq = 0;
int ht40; int ht40;
id = atoi(cmd); id = atoi(cmd);
@ -3996,9 +3996,17 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
return -1; return -1;
} }
pos = os_strstr(cmd, " pref=");
if (pos) {
pos += 6;
pref_freq = atoi(pos);
if (pref_freq <= 0)
return -1;
}
ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40; ht40 = (os_strstr(cmd, " ht40") != NULL) || wpa_s->conf->p2p_go_ht40;
return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, ht40); return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, ht40, pref_freq);
} }

View file

@ -630,7 +630,8 @@ DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message,
if (ssid == NULL || ssid->disabled != 2) if (ssid == NULL || ssid->disabled != 2)
goto err; goto err;
if (wpas_p2p_invite(wpa_s, peer_addr, ssid, NULL, 0, 0) < 0) { if (wpas_p2p_invite(wpa_s, peer_addr, ssid, NULL, 0, 0, 0) < 0)
{
reply = wpas_dbus_error_unknown_error( reply = wpas_dbus_error_unknown_error(
message, message,
"Failed to reinvoke a persistent group"); "Failed to reinvoke a persistent group");

View file

@ -3585,7 +3585,7 @@ static int wpas_p2p_setup_freqs(struct wpa_supplicant *wpa_s, int freq,
"(%u MHz) not available for P2P - try to use " "(%u MHz) not available for P2P - try to use "
"another channel", *oper_freq); "another channel", *oper_freq);
*force_freq = 0; *force_freq = 0;
} else if (*oper_freq > 0 && } else if (*oper_freq > 0 && *pref_freq == 0 &&
(wpa_s->drv_flags & (wpa_s->drv_flags &
WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) { WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) {
wpa_printf(MSG_DEBUG, "P2P: Trying to prefer the channel we " wpa_printf(MSG_DEBUG, "P2P: Trying to prefer the channel we "
@ -4583,11 +4583,11 @@ int wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr)
/* Invite to reinvoke a persistent group */ /* Invite to reinvoke a persistent group */
int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr, int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq, struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq,
int ht40) int ht40, int pref_freq)
{ {
enum p2p_invite_role role; enum p2p_invite_role role;
u8 *bssid = NULL, bssid_buf[ETH_ALEN]; u8 *bssid = NULL, bssid_buf[ETH_ALEN];
int force_freq = 0, pref_freq = 0, oper_freq = 0; int force_freq = 0, oper_freq = 0;
int res; int res;
wpa_s->p2p_persistent_go_freq = freq; wpa_s->p2p_persistent_go_freq = freq;

View file

@ -105,7 +105,7 @@ int wpas_p2p_service_del_upnp(struct wpa_supplicant *wpa_s, u8 version,
int wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr); int wpas_p2p_reject(struct wpa_supplicant *wpa_s, const u8 *addr);
int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr, int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq, struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq,
int ht40); int ht40, int pref_freq);
int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname, int wpas_p2p_invite_group(struct wpa_supplicant *wpa_s, const char *ifname,
const u8 *peer_addr, const u8 *go_dev_addr); const u8 *peer_addr, const u8 *go_dev_addr);
void wpas_p2p_completed(struct wpa_supplicant *wpa_s); void wpas_p2p_completed(struct wpa_supplicant *wpa_s);