aboutsummaryrefslogtreecommitdiffstats
path: root/src/p2p
diff options
context:
space:
mode:
Diffstat (limited to 'src/p2p')
-rw-r--r--src/p2p/p2p.c17
-rw-r--r--src/p2p/p2p_i.h2
-rw-r--r--src/p2p/p2p_utils.c46
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;
+}