]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Allow P2P client to specify preferred group channel
authorJouni Malinen <jouni@qca.qualcomm.com>
Fri, 1 Mar 2013 17:40:54 +0000 (19:40 +0200)
committerJouni Malinen <j@w1.fi>
Fri, 1 Mar 2013 17:40:54 +0000 (19:40 +0200)
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>

src/p2p/p2p_i.h
src/p2p/p2p_invitation.c
wpa_supplicant/README-P2P
wpa_supplicant/ctrl_iface.c
wpa_supplicant/dbus/dbus_new_handlers_p2p.c
wpa_supplicant/p2p_supplicant.c
wpa_supplicant/p2p_supplicant.h

index 856f78f524531a127d7dcfa2ac42f2bdfbda6268..c753d49396cdf9935807d9854289588dbe874ede 100644 (file)
@@ -92,6 +92,7 @@ struct p2p_device {
 #define P2P_DEV_REPORTED_ONCE BIT(15)
 #define P2P_DEV_PREFER_PERSISTENT_RECONN BIT(16)
 #define P2P_DEV_PD_BEFORE_GO_NEG BIT(17)
+#define P2P_DEV_NO_PREF_CHAN BIT(18)
        unsigned int flags;
 
        int status; /* enum p2p_status_code */
index 918fd4bf1c7c01ea7bc59ebbf60d4cfd7e56a8ed..9cde8bfae3ad54ecf13522b623a901987f1678a3 100644 (file)
@@ -62,8 +62,11 @@ static struct wpabuf * p2p_build_invitation_req(struct p2p_data *p2p,
                                           p2p->client_timeout);
        p2p_buf_add_invitation_flags(buf, p2p->inv_persistent ?
                                     P2P_INVITATION_FLAGS_TYPE : 0);
-       p2p_buf_add_operating_channel(buf, p2p->cfg->country,
-                                     p2p->op_reg_class, p2p->op_channel);
+       if (p2p->inv_role != P2P_INVITE_ROLE_CLIENT ||
+           !(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)
                p2p_buf_add_group_bssid(buf, p2p->inv_bssid);
        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)
                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->info.dev_capab &
                      P2P_DEV_CAPAB_CLIENT_DISCOVERABILITY)) {
index fb99c7bcdf0dd57e357b9d26a3a30448a3f78a30..8447a9044f67f606943729604e741f41bd1c09b2 100644 (file)
@@ -365,7 +365,7 @@ Remove all local services from internal SD query processing.
 Invitation
 
 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
 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
 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
-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
 
index 06efd2c5ac434ffc2e91dcb2a372b40154119d8c..0804d7184baad65240760561010e20dcf8f25d1a 100644 (file)
@@ -3969,7 +3969,7 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
        int id;
        struct wpa_ssid *ssid;
        u8 *_peer = NULL, peer[ETH_ALEN];
-       int freq = 0;
+       int freq = 0, pref_freq = 0;
        int ht40;
 
        id = atoi(cmd);
@@ -3996,9 +3996,17 @@ static int p2p_ctrl_invite_persistent(struct wpa_supplicant *wpa_s, char *cmd)
                        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;
 
-       return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, ht40);
+       return wpas_p2p_invite(wpa_s, _peer, ssid, NULL, freq, ht40, pref_freq);
 }
 
 
index 30e0eb3e5fb8c7f215057c59329168f1ec324aa7..6279f415fab49ec6d230fc237f4d615391bd3aac 100644 (file)
@@ -630,7 +630,8 @@ DBusMessage * wpas_dbus_handler_p2p_invite(DBusMessage *message,
                if (ssid == NULL || ssid->disabled != 2)
                        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(
                                message,
                                "Failed to reinvoke a persistent group");
index 4ec6ed11755d871c2a4c834777879e6724190aac..004cf74b30b7bae8dbbf3be1e71170bc9fd0bc8b 100644 (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 "
                           "another channel", *oper_freq);
                *force_freq = 0;
-       } else if (*oper_freq > 0 &&
+       } else if (*oper_freq > 0 && *pref_freq == 0 &&
                   (wpa_s->drv_flags &
                    WPA_DRIVER_FLAGS_MULTI_CHANNEL_CONCURRENT)) {
                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 */
 int wpas_p2p_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
                    struct wpa_ssid *ssid, const u8 *go_dev_addr, int freq,
-                   int ht40)
+                   int ht40, int pref_freq)
 {
        enum p2p_invite_role role;
        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;
 
        wpa_s->p2p_persistent_go_freq = freq;
index b6ecf14cf1feb3f4dc5b6c78ec9d8c1332ee1e89..caeac7c1614f939a74f7eb02fedf7f62cc87f865 100644 (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_invite(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
                    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,
                          const u8 *peer_addr, const u8 *go_dev_addr);
 void wpas_p2p_completed(struct wpa_supplicant *wpa_s);