aboutsummaryrefslogtreecommitdiffstats
path: root/src/p2p
diff options
context:
space:
mode:
Diffstat (limited to 'src/p2p')
-rw-r--r--src/p2p/p2p.c46
-rw-r--r--src/p2p/p2p.h14
-rw-r--r--src/p2p/p2p_go_neg.c5
-rw-r--r--src/p2p/p2p_sd.c10
-rw-r--r--src/p2p/p2p_utils.c23
5 files changed, 79 insertions, 19 deletions
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c
index 3a5486b9..7d4a03c5 100644
--- a/src/p2p/p2p.c
+++ b/src/p2p/p2p.c
@@ -259,7 +259,8 @@ static void p2p_listen_in_find(struct p2p_data *p2p, int dev_disc)
return;
}
- os_get_random((u8 *) &r, sizeof(r));
+ if (os_get_random((u8 *) &r, sizeof(r)) < 0)
+ r = 0;
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)
@@ -1286,8 +1287,8 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p)
} else if (p2p_channel_random_social(&p2p->cfg->channels,
&p2p->op_reg_class,
&p2p->op_channel) == 0) {
- p2p_dbg(p2p, "Select random available social channel %d from 2.4 GHz band as operating channel preference",
- p2p->op_channel);
+ p2p_dbg(p2p, "Select random available social channel (op_class %u channel %u) as operating channel preference",
+ p2p->op_reg_class, p2p->op_channel);
} else {
/* Select any random available channel from the first available
* operating class */
@@ -1824,8 +1825,17 @@ static void p2p_go_neg_start(void *eloop_ctx, void *timeout_ctx)
struct p2p_data *p2p = eloop_ctx;
if (p2p->go_neg_peer == NULL)
return;
+ if (p2p->pending_listen_freq) {
+ p2p_dbg(p2p, "Clear pending_listen_freq for p2p_go_neg_start");
+ p2p->pending_listen_freq = 0;
+ }
p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
p2p->go_neg_peer->status = P2P_SC_SUCCESS;
+ /*
+ * Set new timeout to make sure a previously set one does not expire
+ * too quickly while waiting for the GO Negotiation to complete.
+ */
+ p2p_set_timeout(p2p, 0, 500000);
p2p_connect_send(p2p, p2p->go_neg_peer);
}
@@ -1835,6 +1845,10 @@ static void p2p_invite_start(void *eloop_ctx, void *timeout_ctx)
struct p2p_data *p2p = eloop_ctx;
if (p2p->invite_peer == NULL)
return;
+ if (p2p->pending_listen_freq) {
+ p2p_dbg(p2p, "Clear pending_listen_freq for p2p_invite_start");
+ p2p->pending_listen_freq = 0;
+ }
p2p->cfg->stop_listen(p2p->cfg->cb_ctx);
p2p_invite_send(p2p, p2p->invite_peer, p2p->invite_go_dev_addr,
p2p->invite_dev_pw_id);
@@ -2480,7 +2494,8 @@ struct p2p_data * p2p_init(const struct p2p_config *cfg)
p2p->max_disc_int = 3;
p2p->max_disc_tu = -1;
- os_get_random(&p2p->next_tie_breaker, 1);
+ if (os_get_random(&p2p->next_tie_breaker, 1) < 0)
+ p2p->next_tie_breaker = 0;
p2p->next_tie_breaker &= 0x01;
if (cfg->sd_request)
p2p->dev_capab |= P2P_DEV_CAPAB_SERVICE_DISCOVERY;
@@ -2773,6 +2788,19 @@ static void p2p_sd_cb(struct p2p_data *p2p, int success)
return;
}
+ if (p2p->sd_query->for_all_peers) {
+ /* Update the pending broadcast SD query count for this device
+ */
+ p2p->sd_peer->sd_pending_bcast_queries--;
+
+ /*
+ * If there are no pending broadcast queries for this device,
+ * mark it as done (-1).
+ */
+ if (p2p->sd_peer->sd_pending_bcast_queries == 0)
+ p2p->sd_peer->sd_pending_bcast_queries = -1;
+ }
+
/* Wait for response from the peer */
p2p_set_state(p2p, P2P_SD_DURING_FIND);
p2p_set_timeout(p2p, 0, 200000);
@@ -3003,7 +3031,8 @@ static void p2p_go_neg_req_cb(struct p2p_data *p2p, int success)
* make it less likely to hit cases where we could end up in
* sync with peer not listening.
*/
- os_get_random((u8 *) &r, sizeof(r));
+ if (os_get_random((u8 *) &r, sizeof(r)) < 0)
+ r = 0;
timeout += r % 100000;
}
p2p_set_timeout(p2p, 0, timeout);
@@ -4075,6 +4104,13 @@ void p2p_set_managed_oper(struct p2p_data *p2p, int enabled)
}
+int p2p_config_get_random_social(struct p2p_config *p2p, u8 *op_class,
+ u8 *op_channel)
+{
+ return p2p_channel_random_social(&p2p->channels, op_class, op_channel);
+}
+
+
int p2p_set_listen_channel(struct p2p_data *p2p, u8 reg_class, u8 channel,
u8 forced)
{
diff --git a/src/p2p/p2p.h b/src/p2p/p2p.h
index dee79dfb..076a2ac1 100644
--- a/src/p2p/p2p.h
+++ b/src/p2p/p2p.h
@@ -1691,6 +1691,20 @@ void p2p_set_client_discoverability(struct p2p_data *p2p, int enabled);
*/
void p2p_set_managed_oper(struct p2p_data *p2p, int enabled);
+/**
+ * p2p_config_get_random_social - Return a random social channel
+ * @p2p: P2P config
+ * @op_class: Selected operating class
+ * @op_channel: Selected social channel
+ * Returns: 0 on success, -1 on failure
+ *
+ * This function is used before p2p_init is called. A random social channel
+ * from supports bands 2.4 GHz (channels 1,6,11) and 60 GHz (channel 2) is
+ * returned on success.
+ */
+int p2p_config_get_random_social(struct p2p_config *p2p, u8 *op_class,
+ u8 *op_channel);
+
int p2p_set_listen_channel(struct p2p_data *p2p, u8 reg_class, u8 channel,
u8 forced);
diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c
index bd7a2cf5..21fae3f2 100644
--- a/src/p2p/p2p_go_neg.c
+++ b/src/p2p/p2p_go_neg.c
@@ -958,7 +958,10 @@ void p2p_process_go_neg_resp(struct p2p_data *p2p, const u8 *sa,
p2p_dbg(p2p, "Wait for the peer to become ready for GO Negotiation");
dev->flags |= P2P_DEV_NOT_YET_READY;
os_get_reltime(&dev->go_neg_wait_started);
- p2p_set_state(p2p, P2P_WAIT_PEER_IDLE);
+ if (p2p->state == P2P_CONNECT_LISTEN)
+ p2p_set_state(p2p, P2P_WAIT_PEER_CONNECT);
+ else
+ p2p_set_state(p2p, P2P_WAIT_PEER_IDLE);
p2p_set_timeout(p2p, 0, 0);
} else {
p2p_dbg(p2p, "Stop GO Negotiation attempt");
diff --git a/src/p2p/p2p_sd.c b/src/p2p/p2p_sd.c
index 6235b1de..13119c20 100644
--- a/src/p2p/p2p_sd.c
+++ b/src/p2p/p2p_sd.c
@@ -301,16 +301,6 @@ int p2p_start_sd(struct p2p_data *p2p, struct p2p_device *dev)
ret = -1;
}
- /* Update the pending broadcast SD query count for this device */
- dev->sd_pending_bcast_queries--;
-
- /*
- * If there are no pending broadcast queries 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;
diff --git a/src/p2p/p2p_utils.c b/src/p2p/p2p_utils.c
index 189300ad..23acce76 100644
--- a/src/p2p/p2p_utils.c
+++ b/src/p2p/p2p_utils.c
@@ -149,6 +149,15 @@ int p2p_freq_to_channel(unsigned int freq, u8 *op_class, u8 *channel)
return 0;
}
+ if (freq >= 58320 && freq <= 64800) {
+ if ((freq - 58320) % 2160)
+ return -1;
+
+ *op_class = 180; /* 60 GHz, channels 1..4 */
+ *channel = (freq - 56160) / 2160;
+ return 0;
+ }
+
return -1;
}
@@ -441,7 +450,8 @@ void p2p_channels_dump(struct p2p_data *p2p, const char *title,
static u8 p2p_channel_pick_random(const u8 *channels, unsigned int num_channels)
{
unsigned int r;
- os_get_random((u8 *) &r, sizeof(r));
+ if (os_get_random((u8 *) &r, sizeof(r)) < 0)
+ r = 0;
r %= num_channels;
return channels[r];
}
@@ -481,7 +491,7 @@ int p2p_channel_select(struct p2p_channels *chans, const int *classes,
int p2p_channel_random_social(struct p2p_channels *chans, u8 *op_class,
u8 *op_channel)
{
- u8 chan[3];
+ u8 chan[4];
unsigned int num_channels = 0;
/* Try to find available social channels from 2.4 GHz */
@@ -492,11 +502,18 @@ int p2p_channel_random_social(struct p2p_channels *chans, u8 *op_class,
if (p2p_channels_includes(chans, 81, 11))
chan[num_channels++] = 11;
+ /* Try to find available social channels from 60 GHz */
+ if (p2p_channels_includes(chans, 180, 2))
+ chan[num_channels++] = 2;
+
if (num_channels == 0)
return -1;
- *op_class = 81;
*op_channel = p2p_channel_pick_random(chan, num_channels);
+ if (*op_channel == 2)
+ *op_class = 180;
+ else
+ *op_class = 81;
return 0;
}