]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Delay send_action call if p2p_scan is in progress
authorJouni Malinen <jouni.malinen@atheros.com>
Wed, 20 Oct 2010 16:41:20 +0000 (19:41 +0300)
committerJouni Malinen <j@w1.fi>
Wed, 20 Oct 2010 16:44:21 +0000 (19:44 +0300)
In order to avoid confusing the driver with a new remain-on-channel
request, delay sending of a new Action frame if the driver indicates
Action frame RX diromg a scan.

src/p2p/p2p.c
src/p2p/p2p_dev_disc.c
src/p2p/p2p_go_neg.c
src/p2p/p2p_i.h
src/p2p/p2p_invitation.c
src/p2p/p2p_pd.c
src/p2p/p2p_sd.c

index 1db44f55da23ef55e770d893db5e154a9503c528..5f112ab94de87bff19484410c5e6f6901deb5212 100644 (file)
@@ -691,6 +691,25 @@ static int p2p_run_after_scan(struct p2p_data *p2p)
        struct p2p_device *dev;
        enum p2p_after_scan op;
 
+       if (p2p->after_scan_tx) {
+               int ret;
+               /* TODO: schedule p2p_run_after_scan to be called from TX
+                * status callback(?) */
+               wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send pending "
+                       "Action frame at p2p_scan completion");
+               ret = p2p->cfg->send_action(p2p->cfg->cb_ctx,
+                                           p2p->after_scan_tx->freq,
+                                           p2p->after_scan_tx->dst,
+                                           p2p->after_scan_tx->src,
+                                           p2p->after_scan_tx->bssid,
+                                           (u8 *) (p2p->after_scan_tx + 1),
+                                           p2p->after_scan_tx->len,
+                                           p2p->after_scan_tx->wait_time);
+               os_free(p2p->after_scan_tx);
+               p2p->after_scan_tx = NULL;
+               return 1;
+       }
+
        op = p2p->start_after_scan;
        p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING;
        switch (op) {
@@ -1831,6 +1850,7 @@ void p2p_deinit(struct p2p_data *p2p)
        os_free(p2p->cfg->dev_name);
        os_free(p2p->groups);
        wpabuf_free(p2p->sd_resp);
+       os_free(p2p->after_scan_tx);
        os_free(p2p);
 }
 
@@ -2675,11 +2695,9 @@ int p2p_presence_req(struct p2p_data *p2p, const u8 *go_interface_addr,
                return -1;
 
        p2p->pending_action_state = P2P_NO_PENDING_ACTION;
-       if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, go_interface_addr,
-                                 own_interface_addr,
-                                 go_interface_addr,
-                                 wpabuf_head(req), wpabuf_len(req), 200) < 0)
-       {
+       if (p2p_send_action(p2p, freq, go_interface_addr, own_interface_addr,
+                           go_interface_addr,
+                           wpabuf_head(req), wpabuf_len(req), 200) < 0) {
                wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
                        "P2P: Failed to send Action frame");
        }
@@ -2776,9 +2794,8 @@ fail:
                return;
 
        p2p->pending_action_state = P2P_NO_PENDING_ACTION;
-       if (p2p->cfg->send_action(p2p->cfg->cb_ctx, rx_freq, sa, da, da,
-                                 wpabuf_head(resp), wpabuf_len(resp), 200) <
-           0) {
+       if (p2p_send_action(p2p, rx_freq, sa, da, da,
+                           wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
                wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
                        "P2P: Failed to send Action frame");
        }
@@ -3062,3 +3079,34 @@ void p2p_update_channel_list(struct p2p_data *p2p, struct p2p_channels *chan)
        wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Update channel list");
        os_memcpy(&p2p->cfg->channels, chan, sizeof(struct p2p_channels));
 }
+
+
+int p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst,
+                   const u8 *src, const u8 *bssid, const u8 *buf,
+                   size_t len, unsigned int wait_time)
+{
+       if (p2p->p2p_scan_running) {
+               wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Delay Action "
+                       "frame TX until p2p_scan completes");
+               if (p2p->after_scan_tx) {
+                       wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Dropped "
+                               "previous pending Action frame TX");
+                       os_free(p2p->after_scan_tx);
+               }
+               p2p->after_scan_tx = os_malloc(sizeof(*p2p->after_scan_tx) +
+                                              len);
+               if (p2p->after_scan_tx == NULL)
+                       return -1;
+               p2p->after_scan_tx->freq = freq;
+               os_memcpy(p2p->after_scan_tx->dst, dst, ETH_ALEN);
+               os_memcpy(p2p->after_scan_tx->src, src, ETH_ALEN);
+               os_memcpy(p2p->after_scan_tx->bssid, bssid, ETH_ALEN);
+               p2p->after_scan_tx->len = len;
+               p2p->after_scan_tx->wait_time = wait_time;
+               os_memcpy(p2p->after_scan_tx + 1, buf, len);
+               return 0;
+       }
+
+       return p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, dst, src, bssid,
+                                    buf, len, wait_time);
+}
index 7bd080ad8b73d67fb7074b54ee9ed6fc2f9ef7b2..2a0db6f0496a9c9bcf6ccaecb8875ec318d43ee5 100644 (file)
@@ -99,11 +99,9 @@ int p2p_send_dev_disc_req(struct p2p_data *p2p, struct p2p_device *dev)
        os_memcpy(p2p->pending_client_disc_addr, dev->p2p_device_addr,
                  ETH_ALEN);
        p2p->pending_action_state = P2P_PENDING_DEV_DISC_REQUEST;
-       if (p2p->cfg->send_action(p2p->cfg->cb_ctx, dev->oper_freq,
-                                 go->p2p_device_addr, p2p->cfg->dev_addr,
-                                 go->p2p_device_addr,
-                                 wpabuf_head(req), wpabuf_len(req), 1000) < 0)
-       {
+       if (p2p_send_action(p2p, dev->oper_freq, go->p2p_device_addr,
+                           p2p->cfg->dev_addr, go->p2p_device_addr,
+                           wpabuf_head(req), wpabuf_len(req), 1000) < 0) {
                wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
                        "P2P: Failed to send Action frame");
                wpabuf_free(req);
@@ -160,10 +158,9 @@ static void p2p_send_dev_disc_resp(struct p2p_data *p2p, u8 dialog_token,
                MAC2STR(addr), status, freq);
 
        p2p->pending_action_state = P2P_PENDING_DEV_DISC_RESPONSE;
-       if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, addr,
-                                 p2p->cfg->dev_addr, p2p->cfg->dev_addr,
-                                 wpabuf_head(resp), wpabuf_len(resp), 200) <
-           0) {
+       if (p2p_send_action(p2p, freq, addr, p2p->cfg->dev_addr,
+                           p2p->cfg->dev_addr,
+                           wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
                wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
                        "P2P: Failed to send Action frame");
        }
index 55c576dcab4504a184401e071a2b19897bd2af01..5b70f7a83adc991f1b1c2f70b7c917a02d0b990e 100644 (file)
@@ -209,11 +209,9 @@ int p2p_connect_send(struct p2p_data *p2p, struct p2p_device *dev)
        p2p->pending_action_state = P2P_PENDING_GO_NEG_REQUEST;
        p2p->go_neg_peer = dev;
        dev->flags |= P2P_DEV_WAIT_GO_NEG_RESPONSE;
-       if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq,
-                                 dev->p2p_device_addr, p2p->cfg->dev_addr,
-                                 dev->p2p_device_addr,
-                                 wpabuf_head(req), wpabuf_len(req), 200) < 0)
-       {
+       if (p2p_send_action(p2p, freq, dev->p2p_device_addr,
+                           p2p->cfg->dev_addr, dev->p2p_device_addr,
+                           wpabuf_head(req), wpabuf_len(req), 200) < 0) {
                wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
                        "P2P: Failed to send Action frame");
                /* Use P2P find to recover and retry */
@@ -616,10 +614,9 @@ fail:
        } else
                p2p->pending_action_state =
                        P2P_PENDING_GO_NEG_RESPONSE_FAILURE;
-       if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, sa,
-                                 p2p->cfg->dev_addr, p2p->cfg->dev_addr,
-                                 wpabuf_head(resp), wpabuf_len(resp), 200) <
-           0) {
+       if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
+                           p2p->cfg->dev_addr,
+                           wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
                wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
                        "P2P: Failed to send Action frame");
        }
@@ -982,10 +979,8 @@ fail:
                freq = rx_freq;
        else
                freq = dev->listen_freq;
-       if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, sa,
-                                 p2p->cfg->dev_addr, sa,
-                                 wpabuf_head(conf), wpabuf_len(conf), 200) <
-           0) {
+       if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, sa,
+                           wpabuf_head(conf), wpabuf_len(conf), 200) < 0) {
                wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
                        "P2P: Failed to send Action frame");
                p2p_go_neg_failed(p2p, dev, -1);
index 6119b60f80baae28e72c6983342d969fba02a159..b87a3ef4a663e63c85463170ff066111037a8449 100644 (file)
@@ -113,6 +113,16 @@ struct p2p_sd_query {
        struct wpabuf *tlvs;
 };
 
+struct p2p_pending_action_tx {
+       unsigned int freq;
+       u8 dst[ETH_ALEN];
+       u8 src[ETH_ALEN];
+       u8 bssid[ETH_ALEN];
+       size_t len;
+       unsigned int wait_time;
+       /* Followed by len octets of the frame */
+};
+
 /**
  * struct p2p_data - P2P module data (internal to P2P module)
  */
@@ -351,6 +361,7 @@ struct p2p_data {
                P2P_AFTER_SCAN_CONNECT
        } start_after_scan;
        u8 after_scan_peer[ETH_ALEN];
+       struct p2p_pending_action_tx *after_scan_tx;
 
        struct p2p_group **groups;
        size_t num_groups;
@@ -597,5 +608,8 @@ int dev_type_list_match(const u8 *dev_type, const u8 *req_dev_type[],
                        size_t num_req_dev_type);
 struct wpabuf * p2p_build_probe_resp_ies(struct p2p_data *p2p);
 void p2p_build_ssid(struct p2p_data *p2p, u8 *ssid, size_t *ssid_len);
+int p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst,
+                   const u8 *src, const u8 *bssid, const u8 *buf,
+                   size_t len, unsigned int wait_time);
 
 #endif /* P2P_I_H */
index 7d9ac4837142a624470be2b45f724344b781e1f9..6a085cb84a4bde26a1c86173ba930ed69d921c77 100644 (file)
@@ -271,10 +271,9 @@ fail:
        p2p->inv_op_freq = op_freq;
 
        p2p->pending_action_state = P2P_PENDING_INVITATION_RESPONSE;
-       if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, sa,
-                                 p2p->cfg->dev_addr, p2p->cfg->dev_addr,
-                                 wpabuf_head(resp), wpabuf_len(resp), 200) <
-           0) {
+       if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
+                           p2p->cfg->dev_addr,
+                           wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
                wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
                        "P2P: Failed to send Action frame");
        }
@@ -357,11 +356,9 @@ int p2p_invite_send(struct p2p_data *p2p, struct p2p_device *dev,
        p2p->pending_action_state = P2P_PENDING_INVITATION_REQUEST;
        p2p->invite_peer = dev;
        dev->invitation_reqs++;
-       if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq,
-                                 dev->p2p_device_addr, p2p->cfg->dev_addr,
-                                 dev->p2p_device_addr,
-                                 wpabuf_head(req), wpabuf_len(req), 200) < 0)
-       {
+       if (p2p_send_action(p2p, freq, dev->p2p_device_addr,
+                           p2p->cfg->dev_addr, dev->p2p_device_addr,
+                           wpabuf_head(req), wpabuf_len(req), 200) < 0) {
                wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
                        "P2P: Failed to send Action frame");
                /* Use P2P find to recover and retry */
index b942ab8636946a8755ce20e8711c04b47d2f8588..d637859a322e10678a15fd8df1599fb4814a94aa 100644 (file)
@@ -165,10 +165,9 @@ out:
                return;
        }
        p2p->pending_action_state = P2P_NO_PENDING_ACTION;
-       if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, sa,
-                                 p2p->cfg->dev_addr, p2p->cfg->dev_addr,
-                                 wpabuf_head(resp), wpabuf_len(resp), 200) <
-           0) {
+       if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr,
+                           p2p->cfg->dev_addr,
+                           wpabuf_head(resp), wpabuf_len(resp), 200) < 0) {
                wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
                        "P2P: Failed to send Action frame");
        }
@@ -292,11 +291,9 @@ int p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev,
                return -1;
 
        p2p->pending_action_state = P2P_PENDING_PD;
-       if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq,
-                                 dev->p2p_device_addr, p2p->cfg->dev_addr,
-                                 dev->p2p_device_addr,
-                                 wpabuf_head(req), wpabuf_len(req), 200) < 0)
-       {
+       if (p2p_send_action(p2p->cfg->cb_ctx, freq, dev->p2p_device_addr,
+                           p2p->cfg->dev_addr, dev->p2p_device_addr,
+                           wpabuf_head(req), wpabuf_len(req), 200) < 0) {
                wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
                        "P2P: Failed to send Action frame");
                wpabuf_free(req);
index 873356ae2015c5096fa905750b98f330d0189772..d5e4fd0f9c7fd948c9dba21eb951065d1f7dbde7 100644 (file)
@@ -149,9 +149,8 @@ static void p2p_send_gas_comeback_req(struct p2p_data *p2p, const u8 *dst,
                return;
 
        p2p->pending_action_state = P2P_NO_PENDING_ACTION;
-       if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq,
-                                 dst, p2p->cfg->dev_addr, dst,
-                                 wpabuf_head(req), wpabuf_len(req), 200) < 0)
+       if (p2p_send_action(p2p, freq, dst, p2p->cfg->dev_addr, dst,
+                           wpabuf_head(req), wpabuf_len(req), 200) < 0)
                wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
                        "P2P: Failed to send Action frame");
 
@@ -286,11 +285,9 @@ int p2p_start_sd(struct p2p_data *p2p, struct p2p_device *dev)
        p2p->sd_query = query;
        p2p->pending_action_state = P2P_PENDING_SD;
 
-       if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq,
-                                 dev->p2p_device_addr, p2p->cfg->dev_addr,
-                                 dev->p2p_device_addr,
-                                 wpabuf_head(req), wpabuf_len(req), 5000) < 0)
-       {
+       if (p2p_send_action(p2p->cfg->cb_ctx, freq, dev->p2p_device_addr,
+                           p2p->cfg->dev_addr, dev->p2p_device_addr,
+                           wpabuf_head(req), wpabuf_len(req), 5000) < 0) {
                wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
                        "P2P: Failed to send Action frame");
                ret = -1;
@@ -452,10 +449,9 @@ void p2p_sd_response(struct p2p_data *p2p, int freq, const u8 *dst,
                return;
 
        p2p->pending_action_state = P2P_NO_PENDING_ACTION;
-       if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq,
-                                 dst, p2p->cfg->dev_addr, p2p->cfg->dev_addr,
-                                 wpabuf_head(resp), wpabuf_len(resp), 200) <
-           0)
+       if (p2p_send_action(p2p->cfg->cb_ctx, freq, dst, p2p->cfg->dev_addr,
+                           p2p->cfg->dev_addr,
+                           wpabuf_head(resp), wpabuf_len(resp), 200) < 0)
                wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
                        "P2P: Failed to send Action frame");
 
@@ -691,10 +687,9 @@ void p2p_rx_gas_comeback_req(struct p2p_data *p2p, const u8 *sa,
        }
 
        p2p->pending_action_state = P2P_NO_PENDING_ACTION;
-       if (p2p->cfg->send_action(p2p->cfg->cb_ctx, rx_freq,
-                                 sa, p2p->cfg->dev_addr, p2p->cfg->dev_addr,
-                                 wpabuf_head(resp), wpabuf_len(resp), 200) <
-           0)
+       if (p2p_send_action(p2p, rx_freq, sa, p2p->cfg->dev_addr,
+                           p2p->cfg->dev_addr,
+                           wpabuf_head(resp), wpabuf_len(resp), 200) < 0)
                wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG,
                        "P2P: Failed to send Action frame");