]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Skip GO Neg Conf ack failure workaround of send failures
authorJouni Malinen <jouni.malinen@atheros.com>
Tue, 19 Oct 2010 09:47:33 +0000 (12:47 +0300)
committerJouni Malinen <j@w1.fi>
Tue, 19 Oct 2010 09:47:33 +0000 (12:47 +0300)
The workaround to ignore no ctrl::ack received for GO Negotiation
Confirmation frame was only supposed to be used when the frame was
actually transmitted and just the ack was not received. However, due
to the way the driver failure on transmitting the frame were reported,
this ended up getting applied for all failures in sending the GO
Negotiation Confirmation frame.

Improve this by providing a mechanism to indicate whether send_action
operations fail locally before the frame was actually transmitted or
because of not receiving ack frame after having transmitted the frame.

src/p2p/p2p.c
src/p2p/p2p.h
wpa_supplicant/events.c
wpa_supplicant/p2p_supplicant.c
wpa_supplicant/p2p_supplicant.h

index 81a2a8e1d92979ee5cabc6c8601bdc84035fa1a3..7e93d9ae8ce8e0f38673a71eb61ebd58db059835 100644 (file)
@@ -2076,15 +2076,20 @@ static void p2p_go_neg_resp_failure_cb(struct p2p_data *p2p, int success)
 }
 
 
-static void p2p_go_neg_conf_cb(struct p2p_data *p2p, int success)
+static void p2p_go_neg_conf_cb(struct p2p_data *p2p,
+                              enum p2p_send_action_result result)
 {
        struct p2p_device *dev;
 
        wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
-               "P2P: GO Negotiation Confirm TX callback: success=%d",
-               success);
+               "P2P: GO Negotiation Confirm TX callback: result=%d",
+               result);
        p2p->cfg->send_action_done(p2p->cfg->cb_ctx);
-       if (!success) {
+       if (result == P2P_SEND_ACTION_FAILED) {
+               p2p_go_neg_failed(p2p, p2p->go_neg_peer, -1);
+               return;
+       }
+       if (result == P2P_SEND_ACTION_NO_ACK) {
                /*
                 * It looks like the TX status for GO Negotiation Confirm is
                 * often showing failure even when the peer has actually
@@ -2110,15 +2115,18 @@ static void p2p_go_neg_conf_cb(struct p2p_data *p2p, int success)
 
 
 void p2p_send_action_cb(struct p2p_data *p2p, unsigned int freq, const u8 *dst,
-                       const u8 *src, const u8 *bssid, int success)
+                       const u8 *src, const u8 *bssid,
+                       enum p2p_send_action_result result)
 {
        enum p2p_pending_action_state state;
+       int success;
 
        wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
                "P2P: Action frame TX callback (state=%d freq=%u dst=" MACSTR
-               " src=" MACSTR " bssid=" MACSTR " success=%d",
+               " src=" MACSTR " bssid=" MACSTR " result=%d",
                p2p->pending_action_state, freq, MAC2STR(dst), MAC2STR(src),
-               MAC2STR(bssid), success);
+               MAC2STR(bssid), result);
+       success = result == P2P_SEND_ACTION_SUCCESS;
        state = p2p->pending_action_state;
        p2p->pending_action_state = P2P_NO_PENDING_ACTION;
        switch (state) {
@@ -2134,7 +2142,7 @@ void p2p_send_action_cb(struct p2p_data *p2p, unsigned int freq, const u8 *dst,
                p2p_go_neg_resp_failure_cb(p2p, success);
                break;
        case P2P_PENDING_GO_NEG_CONFIRM:
-               p2p_go_neg_conf_cb(p2p, success);
+               p2p_go_neg_conf_cb(p2p, result);
                break;
        case P2P_PENDING_SD:
                p2p_sd_cb(p2p, success);
index af5f9b580a8e74b65e43ffade64f430a694d1bb4..d425eb7518e1d8045cfe02fd268bd97bf7bb78e4 100644 (file)
@@ -941,6 +941,12 @@ int p2p_scan_res_handler(struct p2p_data *p2p, const u8 *bssid, int freq,
  */
 void p2p_scan_res_handled(struct p2p_data *p2p);
 
+enum p2p_send_action_result {
+       P2P_SEND_ACTION_SUCCESS /* Frame was send and acknowledged */,
+       P2P_SEND_ACTION_NO_ACK /* Frame was sent, but not acknowledged */,
+       P2P_SEND_ACTION_FAILED /* Frame was not sent due to a failure */
+};
+
 /**
  * p2p_send_action_cb - Notify TX status of an Action frame
  * @p2p: P2P module context from p2p_init()
@@ -948,13 +954,14 @@ void p2p_scan_res_handled(struct p2p_data *p2p);
  * @dst: Destination MAC address (Address 1)
  * @src: Source MAC address (Address 2)
  * @bssid: BSSID (Address 3)
- * @success: Whether the transmission succeeded
+ * @result: Result of the transmission attempt
  *
  * This function is used to indicate the result of an Action frame transmission
  * that was requested with struct p2p_config::send_action() callback.
  */
 void p2p_send_action_cb(struct p2p_data *p2p, unsigned int freq, const u8 *dst,
-                       const u8 *src, const u8 *bssid, int success);
+                       const u8 *src, const u8 *bssid,
+                       enum p2p_send_action_result result);
 
 /**
  * p2p_listen_cb - Indicate the start of a requested Listen state
index 76ee93b225d29a65c4eb5b7cd90dbe26eea32e05..a4ee308a393f3d1c1e86390c985fc7f68ee59edb 100644 (file)
@@ -28,6 +28,7 @@
 #include "common/wpa_ctrl.h"
 #include "eap_peer/eap.h"
 #include "ap/hostapd.h"
+#include "p2p/p2p.h"
 #include "notify.h"
 #include "common/ieee802_11_defs.h"
 #include "common/ieee802_11_common.h"
@@ -1676,7 +1677,9 @@ void wpa_supplicant_event(void *ctx, enum wpa_event_type event,
                                        wpa_s, data->tx_status.dst,
                                        data->tx_status.data,
                                        data->tx_status.data_len,
-                                       data->tx_status.ack);
+                                       data->tx_status.ack ?
+                                       P2P_SEND_ACTION_SUCCESS :
+                                       P2P_SEND_ACTION_NO_ACK);
 #endif /* CONFIG_P2P */
                        break;
                }
index cecfb1a8c199ab6bae698fdb8297a50456df0e59..4a17a79f1cc12b70e4ef31692b6849ce1904abf8 100644 (file)
@@ -562,13 +562,15 @@ static void wpas_send_action_cb(void *eloop_ctx, void *timeout_ctx)
                wpas_send_action_tx_status(
                        wpa_s, wpa_s->pending_action_dst,
                        wpabuf_head(wpa_s->pending_action_tx),
-                       wpabuf_len(wpa_s->pending_action_tx), 0);
+                       wpabuf_len(wpa_s->pending_action_tx),
+                       P2P_SEND_ACTION_FAILED);
        }
 }
 
 
 void wpas_send_action_tx_status(struct wpa_supplicant *wpa_s, const u8 *dst,
-                               const u8 *data, size_t data_len, int ack)
+                               const u8 *data, size_t data_len,
+                               enum p2p_send_action_result result)
 {
        if (wpa_s->global->p2p_disabled)
                return;
@@ -592,7 +594,7 @@ void wpas_send_action_tx_status(struct wpa_supplicant *wpa_s, const u8 *dst,
                           wpa_s->pending_action_dst,
                           wpa_s->pending_action_src,
                           wpa_s->pending_action_bssid,
-                          ack);
+                          result);
 
        if (wpa_s->pending_pd_before_join &&
            (os_memcmp(wpa_s->pending_action_dst, wpa_s->pending_join_dev_addr,
index 73c6e1a5752523faa5216e362b8b930c0c17b041..e5b2964ae4ef760d728296b0355f1cfc3ff6f600 100644 (file)
@@ -17,6 +17,7 @@
 
 enum p2p_wps_method;
 struct p2p_go_neg_results;
+enum p2p_send_action_result;
 
 int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s);
 void wpas_p2p_deinit(struct wpa_supplicant *wpa_s);
@@ -43,7 +44,8 @@ void wpas_p2p_wps_success(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
 int wpas_p2p_prov_disc(struct wpa_supplicant *wpa_s, const u8 *peer_addr,
                       const char *config_method);
 void wpas_send_action_tx_status(struct wpa_supplicant *wpa_s, const u8 *dst,
-                               const u8 *data, size_t data_len, int ack);
+                               const u8 *data, size_t data_len,
+                               enum p2p_send_action_result result);
 int wpas_p2p_scan_result_text(const u8 *ies, size_t ies_len, char *buf,
                              char *end);
 enum p2p_discovery_type;