Browse Source

P2P: Clean up channel selection code to use helper functions

This moves some of the p2p_prepare_channel_best() functionality into
separate helper functions to make the implementation easier to read.

Signed-off-by: Jouni Malinen <j@w1.fi>
Jouni Malinen 11 years ago
parent
commit
6ace13a9e5
3 changed files with 54 additions and 45 deletions
  1. 12 39
      src/p2p/p2p.c
  2. 2 0
      src/p2p/p2p_i.h
  3. 40 6
      src/p2p/p2p_utils.c

+ 12 - 39
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,

+ 2 - 0
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);

+ 40 - 6
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;
+}