}
-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;
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;
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;
}
}
- p2p_listen_in_find(p2p);
+ p2p_listen_in_find(p2p, 1);
}
return;
}
p2p_set_state(p2p, P2P_CONNECT_LISTEN);
- p2p_listen_in_find(p2p);
+ p2p_listen_in_find(p2p, 0);
}
"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);
}
p2p_set_timeout(p2p, 0, 100000);
return;
}
- p2p_listen_in_find(p2p);
+ p2p_listen_in_find(p2p, 0);
}
}
#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;
+}
*/
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
*/
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 */
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);