diff options
Diffstat (limited to 'src/p2p')
| -rw-r--r-- | src/p2p/p2p.c | 17 | ||||
| -rw-r--r-- | src/p2p/p2p_i.h | 2 | ||||
| -rw-r--r-- | src/p2p/p2p_utils.c | 46 |
3 files changed, 58 insertions, 7 deletions
diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index c5bf41fe..a1325d36 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -1208,10 +1208,25 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p) 0) { p2p_dbg(p2p, "Select possible 5 GHz channel (op_class %u channel %u) as operating channel preference", p2p->op_reg_class, p2p->op_channel); - } else { + } else if (p2p_channels_includes(&p2p->cfg->channels, + p2p->cfg->op_reg_class, + p2p->cfg->op_channel)) { p2p_dbg(p2p, "Select pre-configured channel as operating channel preference"); p2p->op_reg_class = p2p->cfg->op_reg_class; p2p->op_channel = p2p->cfg->op_channel; + } 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); + } else { + /* Select any random available channel from the first available + * operating class */ + p2p_channel_select(&p2p->cfg->channels, NULL, + &p2p->op_reg_class, + &p2p->op_channel); + p2p_dbg(p2p, "Select random available channel %d from operating class %d as operating channel preference", + p2p->op_channel, p2p->op_reg_class); } os_memcpy(&p2p->channels, &p2p->cfg->channels, diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h index 420c7391..8c225ec5 100644 --- a/src/p2p/p2p_i.h +++ b/src/p2p/p2p_i.h @@ -592,6 +592,8 @@ void p2p_channels_dump(struct p2p_data *p2p, const char *title, const struct p2p_channels *chan); int p2p_channel_select(struct p2p_channels *chans, const int *classes, u8 *op_class, u8 *op_channel); +int p2p_channel_random_social(struct p2p_channels *chans, u8 *op_class, + u8 *op_channel); /* p2p_parse.c */ int p2p_parse_p2p_ie(const struct wpabuf *buf, struct p2p_message *msg); diff --git a/src/p2p/p2p_utils.c b/src/p2p/p2p_utils.c index 161a402e..de47c122 100644 --- a/src/p2p/p2p_utils.c +++ b/src/p2p/p2p_utils.c @@ -441,31 +441,65 @@ 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)); + r %= num_channels; + return channels[r]; +} + + int p2p_channel_select(struct p2p_channels *chans, const int *classes, u8 *op_class, u8 *op_channel) { - unsigned int i, j, r; + unsigned int i, j; - for (j = 0; classes[j]; j++) { + for (j = 0; classes == NULL || classes[j]; j++) { for (i = 0; i < chans->reg_classes; i++) { struct p2p_reg_class *c = &chans->reg_class[i]; if (c->channels == 0) continue; - if (c->reg_class == classes[j]) { + if (classes == NULL || c->reg_class == classes[j]) { /* * Pick one of the available channels in the * operating class at random. */ - os_get_random((u8 *) &r, sizeof(r)); - r %= c->channels; *op_class = c->reg_class; - *op_channel = c->channel[r]; + *op_channel = p2p_channel_pick_random( + c->channel, c->channels); return 0; } } + if (classes == NULL) + break; } return -1; } + + +int p2p_channel_random_social(struct p2p_channels *chans, u8 *op_class, + u8 *op_channel) +{ + u8 chan[3]; + unsigned int num_channels = 0; + + /* Try to find available social channels from 2.4 GHz */ + if (p2p_channels_includes(chans, 81, 1)) + chan[num_channels++] = 1; + if (p2p_channels_includes(chans, 81, 6)) + chan[num_channels++] = 6; + if (p2p_channels_includes(chans, 81, 11)) + chan[num_channels++] = 11; + + if (num_channels == 0) + return -1; + + *op_class = 81; + *op_channel = p2p_channel_pick_random(chan, num_channels); + + return 0; +} |
