diff options
Diffstat (limited to 'src/p2p')
| -rw-r--r-- | src/p2p/p2p.c | 46 | ||||
| -rw-r--r-- | src/p2p/p2p.h | 14 | ||||
| -rw-r--r-- | src/p2p/p2p_go_neg.c | 5 | ||||
| -rw-r--r-- | src/p2p/p2p_sd.c | 10 | ||||
| -rw-r--r-- | src/p2p/p2p_utils.c | 23 |
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; } |
