Cumulative patch from commit 31ded52e7084976c5f84caae6cb55e632dd8b013

31ded52 SME: Add more debug prints for OBSS scans and 20/40 MHz co-ex report
7f8eb34 SME: Fix OBSS scan result processing for 20/40 MHz co-ex report
b7a8d67 Allow hostapd to advertise 40 MHz intolerant HT capability
692ec30 FT: Add support for postponing FT response
6ace13a P2P: Clean up channel selection code to use helper functions
70c3523 WPS: Comment out unused AP WEP config write with WPS 2.0
c3ba70f P2P: Update op_reg_class in random social channel case
70634ee hostapd: Check driver DFS offload capability for channel disablement
65d645c nl80211: Fetch DFS offload capability from driver
a500f31 WPS: Comment out unused AP WEP config update with WPS 2.0
be4e5af Add SAE and FT-SAE key_mgmt to hostapd GET_CONFIG
1d4fe3b Remove unnecessary parameter validation
94b84bc P2P: Avoid unsafe pre-configured channel as channel preference
d3c9c35 Add freq= parameter to 'set pno' command
b998236 dbus: Implement P2P Peers info IEs buffer getter
c6f356f dbus: Export the peer's device address as a property
442adfd dbus: Declare properly ServiceDiscoveryRequest method
8903741 dbus: Cancelling a service request always reply by an error
13494c4 dbus: Remove duplicate signal declaration
513dcec Don't overwrite channel on hostapd config reload
5eae87a P2P: Fix GO failed interface init
c46235a wpa_supplicant: Fix radio_remove_interface
2ce7e4f Android: Enable CONFIG_EAP_AKA_PRIME option
95bf699 Add get_radio_name() driver wrapper for wpa_supplicant
d06ecab D-Bus: Make p2p_no_group_iface configurable
8b6b6d8 Fix hostapd.conf description of HT40+

Change-Id: I5e776f71050a106195a39e96d0c38930a387a806
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/p2p/p2p_utils.c b/src/p2p/p2p_utils.c
index 161a402..de47c12 100644
--- a/src/p2p/p2p_utils.c
+++ b/src/p2p/p2p_utils.c
@@ -441,31 +441,65 @@
 }
 
 
+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;
+}