diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index 01b067b7e..a1325d36d 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -1214,46 +1214,19 @@ static void p2p_prepare_channel_best(struct p2p_data *p2p) 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 { - u8 op_chans[3]; - u8 *op_chan; - size_t num_channels = 0; - unsigned int r; - - /* Try to find available social channels from 2.4 GHz */ - if (p2p_channels_includes(&p2p->cfg->channels, 81, 1)) - op_chans[num_channels++] = 1; - if (p2p_channels_includes(&p2p->cfg->channels, 81, 6)) - op_chans[num_channels++] = 6; - if (p2p_channels_includes(&p2p->cfg->channels, 81, 11)) - op_chans[num_channels++] = 11; - - if (num_channels) { - p2p_dbg(p2p, "Select random available social channel from 2.4 GHz band as operating channel preference"); - p2p->op_reg_class = 81; - op_chan = op_chans; - } else { - struct p2p_reg_class *class; - - /* Select any random available channel from the first - * operating class */ - p2p_dbg(p2p, "Select random available channel from operating class %d as operating channel preference", - p2p->op_reg_class); - class = &p2p->cfg->channels.reg_class[0]; - p2p->op_reg_class = class->reg_class; - op_chan = &class->channel[0]; - num_channels = class->channels; - if (num_channels == 0) { - /* Should not happen, but make sure we do not - * try to divide by zero */ - op_chan = op_chans; - op_chans[0] = 1; - num_channels = 1; - } - } - os_get_random((u8 *) &r, sizeof(r)); - r %= num_channels; - p2p->op_channel = op_chan[r]; + /* 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 420c7391b..8c225ec54 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 161a402ef..de47c1223 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; +}