P2P: Fix SD and DevDisc to limit maximum wait time per driver support
authorJouni Malinen <jouni@qca.qualcomm.com>
Thu, 12 Jun 2014 07:49:19 +0000 (10:49 +0300)
committerJouni Malinen <j@w1.fi>
Thu, 12 Jun 2014 07:49:19 +0000 (10:49 +0300)
The driver may reject offchannel TX operation if the requested wait time
is longer than what the driver indicates as the maximum
remain-on-channel time. Two of the P2P action frame cases used long
enough wait times (1000 ms for DevDisc and 5000 ms for SD) that could go
beyond the limit with some drivers. Fix these to limit the maximum wait
to what the driver indicates as supported.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
src/p2p/p2p_dev_disc.c
src/p2p/p2p_sd.c

index 76d01cf..86bae1a 100644 (file)
@@ -68,6 +68,7 @@ int p2p_send_dev_disc_req(struct p2p_data *p2p, struct p2p_device *dev)
 {
        struct p2p_device *go;
        struct wpabuf *req;
+       unsigned int wait_time;
 
        go = p2p_get_device(p2p, dev->member_in_go_dev);
        if (go == NULL || dev->oper_freq <= 0) {
@@ -88,9 +89,12 @@ int p2p_send_dev_disc_req(struct p2p_data *p2p, struct p2p_device *dev)
        os_memcpy(p2p->pending_client_disc_addr, dev->info.p2p_device_addr,
                  ETH_ALEN);
        p2p->pending_action_state = P2P_PENDING_DEV_DISC_REQUEST;
+       wait_time = 1000;
+       if (p2p->cfg->max_listen && wait_time > p2p->cfg->max_listen)
+               wait_time = p2p->cfg->max_listen;
        if (p2p_send_action(p2p, dev->oper_freq, go->info.p2p_device_addr,
                            p2p->cfg->dev_addr, go->info.p2p_device_addr,
-                           wpabuf_head(req), wpabuf_len(req), 1000) < 0) {
+                           wpabuf_head(req), wpabuf_len(req), wait_time) < 0) {
                p2p_dbg(p2p, "Failed to send Action frame");
                wpabuf_free(req);
                /* TODO: how to recover from failure? */
index 9df834c..6235b1d 100644 (file)
@@ -266,6 +266,7 @@ int p2p_start_sd(struct p2p_data *p2p, struct p2p_device *dev)
        int ret = 0;
        struct p2p_sd_query *query;
        int freq;
+       unsigned int wait_time;
 
        freq = dev->listen_freq > 0 ? dev->listen_freq : dev->oper_freq;
        if (freq <= 0) {
@@ -290,9 +291,12 @@ int p2p_start_sd(struct p2p_data *p2p, struct p2p_device *dev)
        p2p->sd_query = query;
        p2p->pending_action_state = P2P_PENDING_SD;
 
+       wait_time = 5000;
+       if (p2p->cfg->max_listen && wait_time > p2p->cfg->max_listen)
+               wait_time = p2p->cfg->max_listen;
        if (p2p_send_action(p2p, freq, dev->info.p2p_device_addr,
                            p2p->cfg->dev_addr, dev->info.p2p_device_addr,
-                           wpabuf_head(req), wpabuf_len(req), 5000) < 0) {
+                           wpabuf_head(req), wpabuf_len(req), wait_time) < 0) {
                p2p_dbg(p2p, "Failed to send Action frame");
                ret = -1;
        }