diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c index 7eaa8dcc2..b1703ac8b 100644 --- a/src/p2p/p2p_go_neg.c +++ b/src/p2p/p2p_go_neg.c @@ -348,6 +348,7 @@ void p2p_reselect_channel(struct p2p_data *p2p, int freq; u8 op_reg_class, op_channel; unsigned int i; + const int op_classes_5ghz[] = { 115, 124, 0 }; if (p2p->own_freq_preference > 0 && p2p_freq_to_channel(p2p->own_freq_preference, @@ -438,24 +439,11 @@ void p2p_reselect_channel(struct p2p_data *p2p, } /* Prefer a 5 GHz channel */ - for (i = 0; i < intersection->reg_classes; i++) { - struct p2p_reg_class *c = &intersection->reg_class[i]; - if ((c->reg_class == 115 || c->reg_class == 124) && - c->channels) { - unsigned int r; - - /* - * Pick one of the available channels in the operating - * class at random. - */ - os_get_random((u8 *) &r, sizeof(r)); - r %= c->channels; - p2p_dbg(p2p, "Pick possible 5 GHz channel (op_class %u channel %u) from intersection", - c->reg_class, c->channel[r]); - p2p->op_reg_class = c->reg_class; - p2p->op_channel = c->channel[r]; - return; - } + if (p2p_channel_select(intersection, op_classes_5ghz, + &p2p->op_reg_class, &p2p->op_channel) == 0) { + p2p_dbg(p2p, "Pick possible 5 GHz channel (op_class %u channel %u) from intersection", + p2p->op_reg_class, p2p->op_channel); + return; } /* diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h index 6b7f6bdfb..efc163a08 100644 --- a/src/p2p/p2p_i.h +++ b/src/p2p/p2p_i.h @@ -581,6 +581,8 @@ int p2p_channels_includes(const struct p2p_channels *channels, u8 reg_class, u8 channel); 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); /* 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 a3dcdebb0..a579509ae 100644 --- a/src/p2p/p2p_utils.c +++ b/src/p2p/p2p_utils.c @@ -439,3 +439,36 @@ void p2p_channels_dump(struct p2p_data *p2p, const char *title, p2p_dbg(p2p, "%s:%s", title, buf); } + + +int p2p_channel_select(struct p2p_channels *chans, const int *classes, + u8 *op_class, u8 *op_channel) +{ + unsigned int i, j, r; + + for (i = 0; i < chans->reg_classes; i++) { + struct p2p_reg_class *c = &chans->reg_class[i]; + + if (c->channels == 0) + continue; + + for (j = 0; classes[j]; j++) { + if (c->reg_class == classes[j]) + break; + } + if (!classes[j]) + continue; + + /* + * 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]; + return 0; + } + + return -1; +}