]> git.ipfire.org Git - thirdparty/hostap.git/commitdiff
P2P: Allow discoverable interval for p2p_find to be configured
authorJouni Malinen <jouni@qca.qualcomm.com>
Tue, 30 Oct 2012 13:12:04 +0000 (15:12 +0200)
committerJouni Malinen <j@w1.fi>
Tue, 30 Oct 2012 13:12:04 +0000 (15:12 +0200)
The new P2P_SET parameter disc_int can now be used to configure
discoverable interval for p2p_find operations. The format of the command
for setting the values is "P2P_SET disc_int <minDiscoverableInterval>
<maxDiscoverableInterval> <max TUs for discoverable interval>". The
first two parameters are given in units of 100 TUs (102.4 ms). The third
parameter can be used to further limit the interval into a specific TU
amount. If it is set to -1, no such additional limitation is enforced.
It should be noted that the P2P specification describes the random
Listen state interval to be in units of 100 TUs, so setting the max TU
value to anything else than -1 is not compliant with the specification
and should not be used in normal cases. The default parameters can be
set with "P2P_SET disc_int 1 3 -1".

Signed-hostap: Jouni Malinen <jouni@qca.qualcomm.com>

src/p2p/p2p.c
src/p2p/p2p.h
src/p2p/p2p_i.h
wpa_supplicant/ctrl_iface.c
wpa_supplicant/p2p_supplicant.c

index 7d449c6896a70f45d5c9afd38c065ab06d27615a..af2d24afdb4b0a50bce97d16b49c82fd239d99b9 100644 (file)
@@ -214,7 +214,7 @@ void p2p_go_neg_failed(struct p2p_data *p2p, struct p2p_device *peer,
 }
 
 
-static void p2p_listen_in_find(struct p2p_data *p2p)
+static void p2p_listen_in_find(struct p2p_data *p2p, int dev_disc)
 {
        unsigned int r, tu;
        int freq;
@@ -235,6 +235,19 @@ static void p2p_listen_in_find(struct p2p_data *p2p)
        os_get_random((u8 *) &r, sizeof(r));
        tu = (r % ((p2p->max_disc_int - p2p->min_disc_int) + 1) +
              p2p->min_disc_int) * 100;
+       if (p2p->max_disc_tu >= 0 && tu > (unsigned int) p2p->max_disc_tu)
+               tu = p2p->max_disc_tu;
+       if (!dev_disc && tu < 100)
+               tu = 100; /* Need to wait in non-device discovery use cases */
+       if (p2p->cfg->max_listen && 1024 * tu / 1000 > p2p->cfg->max_listen)
+               tu = p2p->cfg->max_listen * 1000 / 1024;
+
+       if (tu == 0) {
+               wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Skip listen state "
+                       "since duration was 0 TU");
+               p2p_set_timeout(p2p, 0, 0);
+               return;
+       }
 
        p2p->pending_listen_freq = freq;
        p2p->pending_listen_sec = 0;
@@ -2327,6 +2340,7 @@ struct p2p_data * p2p_init(const struct p2p_config *cfg)
 
        p2p->min_disc_int = 1;
        p2p->max_disc_int = 3;
+       p2p->max_disc_tu = -1;
 
        os_get_random(&p2p->next_tie_breaker, 1);
        p2p->next_tie_breaker &= 0x01;
@@ -2590,7 +2604,7 @@ void p2p_continue_find(struct p2p_data *p2p)
                }
        }
 
-       p2p_listen_in_find(p2p);
+       p2p_listen_in_find(p2p, 1);
 }
 
 
@@ -3060,7 +3074,7 @@ static void p2p_timeout_connect(struct p2p_data *p2p)
                return;
        }
        p2p_set_state(p2p, P2P_CONNECT_LISTEN);
-       p2p_listen_in_find(p2p);
+       p2p_listen_in_find(p2p, 0);
 }
 
 
@@ -3124,7 +3138,7 @@ static void p2p_timeout_wait_peer_idle(struct p2p_data *p2p)
                "P2P: Go to Listen state while waiting for the peer to become "
                "ready for GO Negotiation");
        p2p_set_state(p2p, P2P_WAIT_PEER_CONNECT);
-       p2p_listen_in_find(p2p);
+       p2p_listen_in_find(p2p, 0);
 }
 
 
@@ -3192,7 +3206,7 @@ static void p2p_timeout_invite(struct p2p_data *p2p)
                p2p_set_timeout(p2p, 0, 100000);
                return;
        }
-       p2p_listen_in_find(p2p);
+       p2p_listen_in_find(p2p, 0);
 }
 
 
@@ -4237,3 +4251,20 @@ int p2p_set_wfd_coupled_sink_info(struct p2p_data *p2p,
 }
 
 #endif /* CONFIG_WIFI_DISPLAY */
+
+
+int p2p_set_disc_int(struct p2p_data *p2p, int min_disc_int, int max_disc_int,
+                    int max_disc_tu)
+{
+       if (min_disc_int > max_disc_int || min_disc_int < 0 || max_disc_int < 0)
+               return -1;
+
+       p2p->min_disc_int = min_disc_int;
+       p2p->max_disc_int = max_disc_int;
+       p2p->max_disc_tu = max_disc_tu;
+       wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Set discoverable interval: "
+               "min=%d max=%d max_tu=%d", min_disc_int, max_disc_int,
+               max_disc_tu);
+
+       return 0;
+}
index e5833f00959482dfabae5403392efb29c498dbf5..4d40a9f79b67d2ccc9cb9ef6627b94090bd8535f 100644 (file)
@@ -354,6 +354,11 @@ struct p2p_config {
         */
        size_t ssid_postfix_len;
 
+       /**
+        * max_listen - Maximum listen duration in ms
+        */
+       unsigned int max_listen;
+
        /**
         * msg_ctx - Context to use with wpa_msg() calls
         */
@@ -1739,4 +1744,25 @@ int p2p_set_wfd_coupled_sink_info(struct p2p_data *p2p,
                                  const struct wpabuf *elem);
 struct wpabuf * wifi_display_encaps(struct wpabuf *subelems);
 
+/**
+ * p2p_set_disc_int - Set min/max discoverable interval for p2p_find
+ * @p2p: P2P module context from p2p_init()
+ * @min_disc_int: minDiscoverableInterval (in units of 100 TU); default 1
+ * @max_disc_int: maxDiscoverableInterval (in units of 100 TU); default 3
+ * @max_disc_tu: Maximum number of TUs (1.024 ms) for discoverable interval; or
+ *     -1 not to limit
+ * Returns: 0 on success, or -1 on failure
+ *
+ * This function can be used to configure minDiscoverableInterval and
+ * maxDiscoverableInterval parameters for the Listen state during device
+ * discovery (p2p_find). A random number of 100 TU units is picked for each
+ * Listen state iteration from [min_disc_int,max_disc_int] range.
+ *
+ * max_disc_tu can be used to futher limit the discoverable duration. However,
+ * it should be noted that use of this parameter is not recommended since it
+ * would not be compliant with the P2P specification.
+ */
+int p2p_set_disc_int(struct p2p_data *p2p, int min_disc_int, int max_disc_int,
+                    int max_disc_tu);
+
 #endif /* P2P_H */
index 0f00c5402ff33f9832c16ad6436cbb044735fb6b..c38eb3bdec1c0ce7410deb3ee4c12c4cb508ad01 100644 (file)
@@ -225,6 +225,11 @@ struct p2p_data {
         */
        int max_disc_int;
 
+       /**
+        * max_disc_tu - Maximum number of TUs for discoverable interval
+        */
+       int max_disc_tu;
+
        /**
         * devices - List of known P2P Device peers
         */
index 2f0b38c78a8ceeebe656ec790e111bee64f13291..a037cca4c49e190f3b58ced294217f3538f27d43 100644 (file)
@@ -4223,6 +4223,30 @@ static int p2p_ctrl_set(struct wpa_supplicant *wpa_s, char *cmd)
        if (os_strcmp(cmd, "disallow_freq") == 0)
                return p2p_ctrl_disallow_freq(wpa_s, param);
 
+       if (os_strcmp(cmd, "disc_int") == 0) {
+               int min_disc_int, max_disc_int, max_disc_tu;
+               char *pos;
+
+               pos = param;
+
+               min_disc_int = atoi(pos);
+               pos = os_strchr(pos, ' ');
+               if (pos == NULL)
+                       return -1;
+               *pos++ = '\0';
+
+               max_disc_int = atoi(pos);
+               pos = os_strchr(pos, ' ');
+               if (pos == NULL)
+                       return -1;
+               *pos++ = '\0';
+
+               max_disc_tu = atoi(pos);
+
+               return p2p_set_disc_int(wpa_s->global->p2p, min_disc_int,
+                                       max_disc_int, max_disc_tu);
+       }
+
        wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown P2P_SET field value '%s'",
                   cmd);
 
index 800499d1484c62277822668f66d0d323a26581dd..7dae6ef5cac199ad74f49b788565cc65ab3370ee 100644 (file)
@@ -2760,6 +2760,8 @@ int wpas_p2p_init(struct wpa_global *global, struct wpa_supplicant *wpa_s)
 
        p2p.p2p_intra_bss = wpa_s->conf->p2p_intra_bss;
 
+       p2p.max_listen = wpa_s->max_remain_on_chan;
+
        global->p2p = p2p_init(&p2p);
        if (global->p2p == NULL)
                return -1;