aboutsummaryrefslogtreecommitdiffstats
path: root/src/p2p
diff options
context:
space:
mode:
authorDmitry Shmidt <dimitrysh@google.com>2014-04-11 10:23:22 -0700
committerDmitry Shmidt <dimitrysh@google.com>2014-04-11 10:23:22 -0700
commit413dde71f7bc166de54229f337c24b61f4d909fd (patch)
tree0d357065859ff68d3b6dbaa93dd38f3753aed4e2 /src/p2p
parent26af48b2fcdee1b88e4092a9078cb7c9bf79da6e (diff)
downloadandroid_external_wpa_supplicant_8-413dde71f7bc166de54229f337c24b61f4d909fd.tar.gz
android_external_wpa_supplicant_8-413dde71f7bc166de54229f337c24b61f4d909fd.tar.bz2
android_external_wpa_supplicant_8-413dde71f7bc166de54229f337c24b61f4d909fd.zip
Cumulative patch from commit f3ff948753ebe5643b5c2d16546a4d16e2c9d20a
f3ff948 P2P: Add NFC_HANDOVER commands to p2p_redir list efd11c0 Add reassociate command to dbus doxygen 481e66b Fix reassociate dbus method 2150c33 wpa_cli: Fix wrong comparison in wpa_cli_cmd_interface 83c4cb5 nl80211: Handle multiple interface combinations for P2P 0133591 HS 2.0 SPP server: Fix aaa_trust_root_cert_url example to use DER 0e0e1e5 P2P: Add retry mechanism for GO Negotiation Confirmation 8235f89 P2P: Mark the scan in p2p_in_invitation as p2p_probe 9392c9b nl80211: Use LEAVE_IBSS with driver-based-SME 38ce8e2 Android: Add qca-vendor.h to be exported Change-Id: I34771c58e2de5e0a3133326d4b3171341ac07b17 Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
Diffstat (limited to 'src/p2p')
-rw-r--r--src/p2p/p2p.c41
-rw-r--r--src/p2p/p2p_go_neg.c21
-rw-r--r--src/p2p/p2p_i.h18
3 files changed, 71 insertions, 9 deletions
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index ea167617..bcc7e644 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -218,6 +218,8 @@ void p2p_go_neg_failed(struct p2p_data *p2p, struct p2p_device *peer,
os_memset(&res, 0, sizeof(res));
res.status = status;
if (peer) {
+ wpabuf_free(peer->go_neg_conf);
+ peer->go_neg_conf = NULL;
os_memcpy(res.peer_device_addr, peer->info.p2p_device_addr,
ETH_ALEN);
os_memcpy(res.peer_interface_addr, peer->intended_addr,
@@ -802,6 +804,7 @@ static void p2p_device_free(struct p2p_data *p2p, struct p2p_device *dev)
}
wpabuf_free(dev->info.wfd_subelems);
+ wpabuf_free(dev->go_neg_conf);
os_free(dev);
}
@@ -1611,6 +1614,8 @@ void p2p_go_complete(struct p2p_data *p2p, struct p2p_device *peer)
peer->go_neg_req_sent = 0;
peer->wps_method = WPS_NOT_READY;
peer->oob_pw_id = 0;
+ wpabuf_free(peer->go_neg_conf);
+ peer->go_neg_conf = NULL;
p2p_set_state(p2p, P2P_PROVISIONING);
p2p->cfg->go_neg_completed(p2p->cfg->cb_ctx, &res);
@@ -2952,13 +2957,44 @@ static void p2p_go_neg_conf_cb(struct p2p_data *p2p,
struct p2p_device *dev;
p2p_dbg(p2p, "GO Negotiation Confirm TX callback: result=%d", result);
- p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
if (result == P2P_SEND_ACTION_FAILED) {
+ p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1);
return;
}
+
+ dev = p2p->go_neg_peer;
+
if (result == P2P_SEND_ACTION_NO_ACK) {
/*
+ * Retry GO Negotiation Confirmation
+ * P2P_GO_NEG_CNF_MAX_RETRY_COUNT times if we did not receive
+ * ACK for confirmation.
+ */
+ if (dev && dev->go_neg_conf &&
+ dev->go_neg_conf_sent <= P2P_GO_NEG_CNF_MAX_RETRY_COUNT) {
+ p2p_dbg(p2p, "GO Negotiation Confirm retry %d",
+ dev->go_neg_conf_sent);
+ p2p->pending_action_state = P2P_PENDING_GO_NEG_CONFIRM;
+ if (p2p_send_action(p2p, dev->go_neg_conf_freq,
+ dev->info.p2p_device_addr,
+ p2p->cfg->dev_addr,
+ dev->info.p2p_device_addr,
+ wpabuf_head(dev->go_neg_conf),
+ wpabuf_len(dev->go_neg_conf), 0) >=
+ 0) {
+ dev->go_neg_conf_sent++;
+ return;
+ }
+ p2p_dbg(p2p, "Failed to re-send Action frame");
+
+ /*
+ * Continue with the assumption that the first attempt
+ * went through and just the ACK frame was lost.
+ */
+ }
+
+ /*
* It looks like the TX status for GO Negotiation Confirm is
* often showing failure even when the peer has actually
* received the frame. Since the peer may change channels
@@ -2971,7 +3007,8 @@ static void p2p_go_neg_conf_cb(struct p2p_data *p2p,
p2p_dbg(p2p, "Assume GO Negotiation Confirm TX was actually received by the peer even though Ack was not reported");
}
- dev = p2p->go_neg_peer;
+ p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
+
if (dev == NULL)
return;
diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c
index a32cfac6..ac939026 100644
--- a/src/p2p/p2p_go_neg.c
+++ b/src/p2p/p2p_go_neg.c
@@ -896,7 +896,6 @@ void p2p_process_go_neg_resp(struct p2p_data *p2p, const u8 *sa,
const u8 *data, size_t len, int rx_freq)
{
struct p2p_device *dev;
- struct wpabuf *conf;
int go = -1;
struct p2p_message msg;
u8 status = P2P_SC_SUCCESS;
@@ -1101,10 +1100,13 @@ void p2p_process_go_neg_resp(struct p2p_data *p2p, const u8 *sa,
os_memcpy(dev->intended_addr, msg.intended_addr, ETH_ALEN);
fail:
- conf = p2p_build_go_neg_conf(p2p, dev, msg.dialog_token, status,
- msg.operating_channel, go);
+ /* Store GO Negotiation Confirmation to allow retransmission */
+ wpabuf_free(dev->go_neg_conf);
+ dev->go_neg_conf = p2p_build_go_neg_conf(p2p, dev, msg.dialog_token,
+ status, msg.operating_channel,
+ go);
p2p_parse_free(&msg);
- if (conf == NULL)
+ if (dev->go_neg_conf == NULL)
return;
p2p_dbg(p2p, "Sending GO Negotiation Confirm");
if (status == P2P_SC_SUCCESS) {
@@ -1116,13 +1118,18 @@ fail:
freq = rx_freq;
else
freq = dev->listen_freq;
+
+ dev->go_neg_conf_freq = freq;
+ dev->go_neg_conf_sent = 0;
+
if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, sa,
- wpabuf_head(conf), wpabuf_len(conf), 200) < 0) {
+ wpabuf_head(dev->go_neg_conf),
+ wpabuf_len(dev->go_neg_conf), 200) < 0) {
p2p_dbg(p2p, "Failed to send Action frame");
p2p_go_neg_failed(p2p, dev, -1);
p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
- }
- wpabuf_free(conf);
+ } else
+ dev->go_neg_conf_sent++;
if (status != P2P_SC_SUCCESS) {
p2p_dbg(p2p, "GO Negotiation failed");
p2p_go_neg_failed(p2p, dev, status);
diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h
index 8c225ec5..44b66c4a 100644
--- a/src/p2p/p2p_i.h
+++ b/src/p2p/p2p_i.h
@@ -12,6 +12,8 @@
#include "utils/list.h"
#include "p2p.h"
+#define P2P_GO_NEG_CNF_MAX_RETRY_COUNT 1
+
enum p2p_role_indication;
enum p2p_go_state {
@@ -108,6 +110,22 @@ struct p2p_device {
u8 go_timeout;
u8 client_timeout;
+
+ /**
+ * go_neg_conf_sent - Number of GO Negotiation Confirmation retries
+ */
+ u8 go_neg_conf_sent;
+
+ /**
+ * freq - Frquency on which the GO Negotiation Confirmation is sent
+ */
+ int go_neg_conf_freq;
+
+ /**
+ * go_neg_conf - GO Negotiation Confirmation frame
+ */
+ struct wpabuf *go_neg_conf;
+
int sd_pending_bcast_queries;
};