@@ -732,9 +732,6 @@ int p2p_add_device(struct p2p_data *p2p, const u8 *addr, int freq,
p2p_parse_free(&msg);
- if (p2p_pending_sd_req(p2p, dev))
- dev->flags |= P2P_DEV_SD_SCHEDULE;
-
if (dev->flags & P2P_DEV_REPORTED)
return 0;
@@ -2384,6 +2381,7 @@ struct p2p_data * p2p_init(const struct p2p_config *cfg)
p2p->go_timeout = 100;
p2p->client_timeout = 20;
+ p2p->num_p2p_sd_queries = 0;
p2p_dbg(p2p, "initialized");
p2p_channels_dump(p2p, "channels", &p2p->cfg->channels);
@@ -2618,13 +2616,18 @@ void p2p_continue_find(struct p2p_data *p2p)
struct p2p_device *dev;
p2p_set_state(p2p, P2P_SEARCH);
dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
- if (dev->flags & P2P_DEV_SD_SCHEDULE) {
+ if (dev->sd_pending_bcast_queries == 0) {
+ /* Initialize with Total number of Registered BCAST Queries*/
+ dev->sd_pending_bcast_queries = p2p->num_p2p_sd_queries;
+ }
+
+ if (dev->sd_pending_bcast_queries > 0) {
if (p2p_start_sd(p2p, dev) == 0)
return;
else
break;
} else if (dev->req_config_methods &&
- !(dev->flags & P2P_DEV_PD_FOR_JOIN)) {
+ !(dev->flags & P2P_DEV_PD_FOR_JOIN)) {
p2p_dbg(p2p, "Send pending Provision Discovery Request to "
MACSTR " (config methods 0x%x)",
MAC2STR(dev->info.p2p_device_addr),
@@ -2646,7 +2649,6 @@ static void p2p_sd_cb(struct p2p_data *p2p, int success)
if (!success) {
if (p2p->sd_peer) {
- p2p->sd_peer->flags &= ~P2P_DEV_SD_SCHEDULE;
p2p->sd_peer = NULL;
}
p2p_continue_find(p2p);
@@ -3457,7 +3459,7 @@ int p2p_get_peer_info_txt(const struct p2p_peer_info *info,
"country=%c%c\n"
"oper_freq=%d\n"
"req_config_methods=0x%x\n"
- "flags=%s%s%s%s%s%s%s%s%s%s%s%s%s%s%s\n"
+ "flags=%s%s%s%s%s%s%s%s%s%s%s%s%s\n"
"status=%d\n"
"wait_count=%u\n"
"invitation_reqs=%u\n",
@@ -3480,9 +3482,6 @@ int p2p_get_peer_info_txt(const struct p2p_peer_info *info,
dev->flags & P2P_DEV_REPORTED ? "[REPORTED]" : "",
dev->flags & P2P_DEV_NOT_YET_READY ?
"[NOT_YET_READY]" : "",
- dev->flags & P2P_DEV_SD_INFO ? "[SD_INFO]" : "",
- dev->flags & P2P_DEV_SD_SCHEDULE ? "[SD_SCHEDULE]" :
- "",
dev->flags & P2P_DEV_PD_PEER_DISPLAY ?
"[PD_PEER_DISPLAY]" : "",
dev->flags & P2P_DEV_PD_PEER_KEYPAD ?
@@ -105,6 +105,7 @@ struct p2p_device {
u8 go_timeout;
u8 client_timeout;
+ int sd_pending_bcast_queries;
};
struct p2p_sd_query {
@@ -250,6 +251,11 @@ struct p2p_data {
*/
struct p2p_sd_query *sd_query;
+ /**
+ * total number of sd broadcast queries present in the list
+ */
+ int num_p2p_sd_queries;
+
/* GO Negotiation data */
/**
@@ -52,6 +52,7 @@ struct p2p_sd_query * p2p_pending_sd_req(struct p2p_data *p2p,
{
struct p2p_sd_query *q;
int wsd = 0;
+ int count = 0;
if (!(dev->info.dev_capab & P2P_DEV_CAPAB_SERVICE_DISCOVERY))
return NULL; /* peer does not support SD */
@@ -64,8 +65,17 @@ struct p2p_sd_query * p2p_pending_sd_req(struct p2p_data *p2p,
/* Use WSD only if the peer indicates support or it */
if (q->wsd && !wsd)
continue;
- if (q->for_all_peers && !(dev->flags & P2P_DEV_SD_INFO))
- return q;
+ /* if the query is a broadcast query */
+ if (q->for_all_peers) {
+ /* check if there are any broadcast queries pending for this device */
+ if (dev->sd_pending_bcast_queries <= 0)
+ return NULL;
+ /* query number that needs to be send to the device */
+ else if (count == (dev->sd_pending_bcast_queries - 1)) {
+ return q;
+ } else
+ count++;
+ }
if (!q->for_all_peers &&
os_memcmp(q->peer, dev->info.p2p_device_addr, ETH_ALEN) ==
0)
@@ -80,10 +90,25 @@ static int p2p_unlink_sd_query(struct p2p_data *p2p,
struct p2p_sd_query *query)
{
struct p2p_sd_query *q, *prev;
+ struct p2p_device *dev;
+ int query_number = 0;
q = p2p->sd_queries;
prev = NULL;
while (q) {
if (q == query) {
+ /* if the query is a broadcast query decrease one from all the devices */
+ if (query->for_all_peers) {
+ p2p->num_p2p_sd_queries--;
+ dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
+ if (query_number <= (dev->sd_pending_bcast_queries - 1)) {
+ /*
+ * Query not yet send to the device and is to be removed.
+ * So update the pending count.
+ */
+ dev->sd_pending_bcast_queries--;
+ }
+ }
+ }
if (prev)
prev->next = q->next;
else
@@ -92,6 +117,8 @@ static int p2p_unlink_sd_query(struct p2p_data *p2p,
p2p->sd_query = NULL;
return 1;
}
+ if (q->for_all_peers)
+ query_number++;
prev = q;
q = q->next;
}
@@ -262,6 +289,16 @@ int p2p_start_sd(struct p2p_data *p2p, struct p2p_device *dev)
ret = -1;
}
+ /* Update the pending Bcast sd query count for this device */
+ dev->sd_pending_bcast_queries--;
+
+ /*
+ * If there are no pending bcast query for this device,
+ * mark it as done (-1).
+ */
+ if (dev->sd_pending_bcast_queries == 0)
+ dev->sd_pending_bcast_queries = -1;
+
wpabuf_free(req);
return ret;
@@ -841,8 +878,15 @@ void * p2p_sd_request(struct p2p_data *p2p, const u8 *dst,
if (dst == NULL) {
struct p2p_device *dev;
- dl_list_for_each(dev, &p2p->devices, struct p2p_device, list)
- dev->flags &= ~P2P_DEV_SD_INFO;
+ p2p->num_p2p_sd_queries++;
+
+ /* Update all the devices for the newly added bcast query */
+ dl_list_for_each(dev, &p2p->devices, struct p2p_device, list) {
+ if (dev->sd_pending_bcast_queries <= 0)
+ dev->sd_pending_bcast_queries = 1;
+ else
+ dev->sd_pending_bcast_queries++;
+ }
}
return q;