aboutsummaryrefslogtreecommitdiffstats
path: root/src/p2p
diff options
context:
space:
mode:
authorJouni Malinen <jouni@qca.qualcomm.com>2012-05-11 16:25:47 +0300
committerJouni Malinen <j@w1.fi>2012-05-11 16:25:47 +0300
commit3bc462cb88e0ffa2fe5b891b7539eb39757a5315 (patch)
tree8df810190c15168725eb29c20cf9e612daa8a3aa /src/p2p
parent1cbe86e2d6d2b5a7d072093ce1a94082b4b3f472 (diff)
downloadexternal_wpa_supplicant_8_ti-3bc462cb88e0ffa2fe5b891b7539eb39757a5315.zip
external_wpa_supplicant_8_ti-3bc462cb88e0ffa2fe5b891b7539eb39757a5315.tar.gz
external_wpa_supplicant_8_ti-3bc462cb88e0ffa2fe5b891b7539eb39757a5315.tar.bz2
P2P: Add option for Provision Discovery before GO Negotiation
This is a workaround for interoperability issues with some deployed P2P implementations that require a Provision Discovery exchange to be used before GO Negotiation. The new provdisc parameter for the p2p_connect command can be used to request this behavior without having to run a separate p2p_prov_disc command. Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>
Diffstat (limited to 'src/p2p')
-rw-r--r--src/p2p/p2p.c11
-rw-r--r--src/p2p/p2p.h6
-rw-r--r--src/p2p/p2p_go_neg.c17
-rw-r--r--src/p2p/p2p_i.h1
-rw-r--r--src/p2p/p2p_pd.c9
5 files changed, 40 insertions, 4 deletions
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index 2b084e7..deccfc0 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -1173,16 +1173,17 @@ int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr,
enum p2p_wps_method wps_method,
int go_intent, const u8 *own_interface_addr,
unsigned int force_freq, int persistent_group,
- const u8 *force_ssid, size_t force_ssid_len)
+ const u8 *force_ssid, size_t force_ssid_len,
+ int pd_before_go_neg)
{
struct p2p_device *dev;
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
"P2P: Request to start group negotiation - peer=" MACSTR
" GO Intent=%d Intended Interface Address=" MACSTR
- " wps_method=%d persistent_group=%d",
+ " wps_method=%d persistent_group=%d pd_before_go_neg=%d",
MAC2STR(peer_addr), go_intent, MAC2STR(own_interface_addr),
- wps_method, persistent_group);
+ wps_method, persistent_group, pd_before_go_neg);
if (p2p_prepare_channel(p2p, force_freq) < 0)
return -1;
@@ -1232,6 +1233,10 @@ int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr,
dev->flags &= ~P2P_DEV_USER_REJECTED;
dev->flags &= ~P2P_DEV_WAIT_GO_NEG_RESPONSE;
dev->flags &= ~P2P_DEV_WAIT_GO_NEG_CONFIRM;
+ if (pd_before_go_neg)
+ dev->flags |= P2P_DEV_PD_BEFORE_GO_NEG;
+ else
+ dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG;
dev->connect_reqs = 0;
dev->go_neg_req_sent = 0;
dev->go_state = UNKNOWN_GO;
diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h
index 92e7048..a759adf 100644
--- a/src/p2p/p2p.h
+++ b/src/p2p/p2p.h
@@ -880,13 +880,17 @@ int p2p_listen(struct p2p_data *p2p, unsigned int timeout);
* @force_ssid: Forced SSID for the group if we become GO or %NULL to generate
* a new SSID
* @force_ssid_len: Length of $force_ssid buffer
+ * @pd_before_go_neg: Whether to send Provision Discovery prior to GO
+ * Negotiation as an interoperability workaround when initiating group
+ * formation
* Returns: 0 on success, -1 on failure
*/
int p2p_connect(struct p2p_data *p2p, const u8 *peer_addr,
enum p2p_wps_method wps_method,
int go_intent, const u8 *own_interface_addr,
unsigned int force_freq, int persistent_group,
- const u8 *force_ssid, size_t force_ssid_len);
+ const u8 *force_ssid, size_t force_ssid_len,
+ int pd_before_go_neg);
/**
* p2p_authorize - Authorize P2P group formation (GO negotiation)
diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c
index 230948d..2bf48b3 100644
--- a/src/p2p/p2p_go_neg.c
+++ b/src/p2p/p2p_go_neg.c
@@ -184,6 +184,23 @@ int p2p_connect_send(struct p2p_data *p2p, struct p2p_device *dev)
struct wpabuf *req;
int freq;
+ if (dev->flags & P2P_DEV_PD_BEFORE_GO_NEG) {
+ u16 config_method;
+ wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
+ "P2P: Use PD-before-GO-Neg workaround for " MACSTR,
+ MAC2STR(dev->info.p2p_device_addr));
+ if (dev->wps_method == WPS_PIN_DISPLAY)
+ config_method = WPS_CONFIG_KEYPAD;
+ else if (dev->wps_method == WPS_PIN_KEYPAD)
+ config_method = WPS_CONFIG_DISPLAY;
+ else if (dev->wps_method == WPS_PBC)
+ config_method = WPS_CONFIG_PUSHBUTTON;
+ else
+ return -1;
+ return p2p_prov_disc_req(p2p, dev->info.p2p_device_addr,
+ config_method, 0, 0);
+ }
+
freq = dev->listen_freq > 0 ? dev->listen_freq : dev->oper_freq;
if (freq <= 0) {
wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h
index 279225c..39e879e 100644
--- a/src/p2p/p2p_i.h
+++ b/src/p2p/p2p_i.h
@@ -90,6 +90,7 @@ struct p2p_device {
#define P2P_DEV_PD_FOR_JOIN BIT(14)
#define P2P_DEV_REPORTED_ONCE BIT(15)
#define P2P_DEV_PREFER_PERSISTENT_RECONN BIT(16)
+#define P2P_DEV_PD_BEFORE_GO_NEG BIT(17)
unsigned int flags;
int status; /* enum p2p_status_code */
diff --git a/src/p2p/p2p_pd.c b/src/p2p/p2p_pd.c
index 6e251c5..7b47927 100644
--- a/src/p2p/p2p_pd.c
+++ b/src/p2p/p2p_pd.c
@@ -288,6 +288,15 @@ void p2p_process_prov_disc_resp(struct p2p_data *p2p, const u8 *sa,
out:
dev->req_config_methods = 0;
p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
+ if (dev->flags & P2P_DEV_PD_BEFORE_GO_NEG) {
+ wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
+ "P2P: Start GO Neg after the PD-before-GO-Neg "
+ "workaround with " MACSTR,
+ MAC2STR(dev->info.p2p_device_addr));
+ dev->flags &= ~P2P_DEV_PD_BEFORE_GO_NEG;
+ p2p_connect_send(p2p, dev);
+ return;
+ }
if (success && p2p->cfg->prov_disc_resp)
p2p->cfg->prov_disc_resp(p2p->cfg->cb_ctx, sa,
report_config_methods);