From 94b84bc7253680a2b201d5c88d36ada91a3e20b4 Mon Sep 17 00:00:00 2001 From: Arif Hussain Date: Fri, 21 Mar 2014 00:38:23 -0700 Subject: [PATCH] P2P: Avoid unsafe pre-configured channel as channel preference Do not select pre-configured channel as operating channel preference if it is unavailable maybe due to interference or possible known co-existence constraints, and try to select random available channel. Signed-off-by: Jouni Malinen --- src/p2p/p2p.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/src/p2p/p2p.c b/src/p2p/p2p.c index c5bf41fe8..b2186e787 100644 --- a/src/p2p/p2p.c +++ b/src/p2p/p2p.c @@ -1208,10 +1208,51 @@ 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 { + 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"); + 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]; } os_memcpy(&p2p->channels, &p2p->cfg->channels,