Accumulative patch from commit ce26864e79144cba12d5ff98632570593cc57b8a

187f87f hostapd: Allow ctrl_iface group to be specified on command line
9f890c9 TDLS: Support both external and internal setup in disabling link
864fe3a TDLS: Fix TDLS Setup Request processing in existing-peer cases
1d43e28 TDLS: Fix TPK M2 processing in concurrent initiation case
ef8151a P2P: Write p2p_ignore_shared_freq to configuration file on updates
8047f70 P2P: Ignore Tx acknowledgment status for Invitation Response
18a2eaa Add ap_vendor_elements for wpa_supplicant AP/P2P GO mode
b084df8 Add vendor_elements into Beacon/Probe Response IE parameters
b92e08f nl80211: Add debug prints for set_ap parameters
c30a4ab nl80211: Fix mode settings with split wiphy dump

Change-Id: I859638e630b6ca32b64e09943fce4d96f779897b
Signed-off-by: Dmitry Shmidt <dimitrysh@google.com>
diff --git a/src/drivers/driver_nl80211.c b/src/drivers/driver_nl80211.c
index efd5cab..c2b9fff 100644
--- a/src/drivers/driver_nl80211.c
+++ b/src/drivers/driver_nl80211.c
@@ -5100,21 +5100,19 @@
 			  struct hostapd_channel_data *chan,
 			  struct nlattr *tb_freq[])
 {
+	enum hostapd_hw_mode m;
+
 	chan->freq = nla_get_u32(tb_freq[NL80211_FREQUENCY_ATTR_FREQ]);
 	chan->flag = 0;
 
-	/* mode is not set */
-	if (mode->mode >= NUM_HOSTAPD_MODES) {
-		/* crude heuristic */
-		if (chan->freq < 4000)
-			mode->mode = HOSTAPD_MODE_IEEE80211B;
-		else if (chan->freq > 50000)
-			mode->mode = HOSTAPD_MODE_IEEE80211AD;
-		else
-			mode->mode = HOSTAPD_MODE_IEEE80211A;
-	}
+	if (chan->freq < 4000)
+		m = HOSTAPD_MODE_IEEE80211B;
+	else if (chan->freq > 50000)
+		m = HOSTAPD_MODE_IEEE80211AD;
+	else
+		m = HOSTAPD_MODE_IEEE80211A;
 
-	switch (mode->mode) {
+	switch (m) {
 	case HOSTAPD_MODE_IEEE80211AD:
 		chan->chan = (chan->freq - 56160) / 2160;
 		break;
@@ -5238,12 +5236,6 @@
 			continue;
 		mode->rates[idx] = nla_get_u32(
 			tb_rate[NL80211_BITRATE_ATTR_RATE]);
-
-		/* crude heuristic */
-		if (mode->mode == HOSTAPD_MODE_IEEE80211B &&
-		    mode->rates[idx] > 200)
-			mode->mode = HOSTAPD_MODE_IEEE80211G;
-
 		idx++;
 	}
 
@@ -5321,12 +5313,31 @@
 
 
 static struct hostapd_hw_modes *
-wpa_driver_nl80211_add_11b(struct hostapd_hw_modes *modes, u16 *num_modes)
+wpa_driver_nl80211_postprocess_modes(struct hostapd_hw_modes *modes,
+				     u16 *num_modes)
 {
 	u16 m;
 	struct hostapd_hw_modes *mode11g = NULL, *nmodes, *mode;
 	int i, mode11g_idx = -1;
 
+	/* heuristic to set up modes */
+	for (m = 0; m < *num_modes; m++) {
+		if (!modes[m].num_channels)
+			continue;
+		if (modes[m].channels[0].freq < 4000) {
+			modes[m].mode = HOSTAPD_MODE_IEEE80211B;
+			for (i = 0; i < modes[m].num_rates; i++) {
+				if (modes[m].rates[i] > 200) {
+					modes[m].mode = HOSTAPD_MODE_IEEE80211G;
+					break;
+				}
+			}
+		} else if (modes[m].channels[0].freq > 50000)
+			modes[m].mode = HOSTAPD_MODE_IEEE80211AD;
+		else
+			modes[m].mode = HOSTAPD_MODE_IEEE80211A;
+	}
+
 	/* If only 802.11g mode is included, use it to construct matching
 	 * 802.11b mode data. */
 
@@ -5572,7 +5583,8 @@
 
 	if (send_and_recv_msgs(drv, msg, phy_info_handler, &result) == 0) {
 		nl80211_set_ht40_flags(drv, &result);
-		return wpa_driver_nl80211_add_11b(result.modes, num_modes);
+		return wpa_driver_nl80211_postprocess_modes(result.modes,
+							    num_modes);
 	}
 	msg = NULL;
  nla_put_failure:
@@ -5790,32 +5802,49 @@
 		cmd = NL80211_CMD_SET_BEACON;
 
 	nl80211_cmd(drv, msg, 0, cmd);
+	wpa_hexdump(MSG_DEBUG, "nl80211: Beacon head",
+		    params->head, params->head_len);
 	NLA_PUT(msg, NL80211_ATTR_BEACON_HEAD, params->head_len, params->head);
+	wpa_hexdump(MSG_DEBUG, "nl80211: Beacon tail",
+		    params->tail, params->tail_len);
 	NLA_PUT(msg, NL80211_ATTR_BEACON_TAIL, params->tail_len, params->tail);
+	wpa_printf(MSG_DEBUG, "nl80211: ifindex=%d", ifindex);
 	NLA_PUT_U32(msg, NL80211_ATTR_IFINDEX, ifindex);
+	wpa_printf(MSG_DEBUG, "nl80211: beacon_int=%d", params->beacon_int);
 	NLA_PUT_U32(msg, NL80211_ATTR_BEACON_INTERVAL, params->beacon_int);
+	wpa_printf(MSG_DEBUG, "nl80211: dtim_period=%d", params->dtim_period);
 	NLA_PUT_U32(msg, NL80211_ATTR_DTIM_PERIOD, params->dtim_period);
+	wpa_hexdump_ascii(MSG_DEBUG, "nl80211: ssid",
+			  params->ssid, params->ssid_len);
 	NLA_PUT(msg, NL80211_ATTR_SSID, params->ssid_len,
 		params->ssid);
-	if (params->proberesp && params->proberesp_len)
+	if (params->proberesp && params->proberesp_len) {
+		wpa_hexdump(MSG_DEBUG, "nl80211: proberesp (offload)",
+			    params->proberesp, params->proberesp_len);
 		NLA_PUT(msg, NL80211_ATTR_PROBE_RESP, params->proberesp_len,
 			params->proberesp);
+	}
 	switch (params->hide_ssid) {
 	case NO_SSID_HIDING:
+		wpa_printf(MSG_DEBUG, "nl80211: hidden SSID not in use");
 		NLA_PUT_U32(msg, NL80211_ATTR_HIDDEN_SSID,
 			    NL80211_HIDDEN_SSID_NOT_IN_USE);
 		break;
 	case HIDDEN_SSID_ZERO_LEN:
+		wpa_printf(MSG_DEBUG, "nl80211: hidden SSID zero len");
 		NLA_PUT_U32(msg, NL80211_ATTR_HIDDEN_SSID,
 			    NL80211_HIDDEN_SSID_ZERO_LEN);
 		break;
 	case HIDDEN_SSID_ZERO_CONTENTS:
+		wpa_printf(MSG_DEBUG, "nl80211: hidden SSID zero contents");
 		NLA_PUT_U32(msg, NL80211_ATTR_HIDDEN_SSID,
 			    NL80211_HIDDEN_SSID_ZERO_CONTENTS);
 		break;
 	}
+	wpa_printf(MSG_DEBUG, "nl80211: privacy=%d", params->privacy);
 	if (params->privacy)
 		NLA_PUT_FLAG(msg, NL80211_ATTR_PRIVACY);
+	wpa_printf(MSG_DEBUG, "nl80211: auth_algs=0x%x", params->auth_algs);
 	if ((params->auth_algs & (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) ==
 	    (WPA_AUTH_ALG_OPEN | WPA_AUTH_ALG_SHARED)) {
 		/* Leave out the attribute */
@@ -5826,6 +5855,7 @@
 		NLA_PUT_U32(msg, NL80211_ATTR_AUTH_TYPE,
 			    NL80211_AUTHTYPE_OPEN_SYSTEM);
 
+	wpa_printf(MSG_DEBUG, "nl80211: wpa_version=0x%x", params->wpa_version);
 	ver = 0;
 	if (params->wpa_version & WPA_PROTO_WPA)
 		ver |= NL80211_WPA_VERSION_1;
@@ -5834,6 +5864,8 @@
 	if (ver)
 		NLA_PUT_U32(msg, NL80211_ATTR_WPA_VERSIONS, ver);
 
+	wpa_printf(MSG_DEBUG, "nl80211: key_mgmt_suites=0x%x",
+		   params->key_mgmt_suites);
 	num_suites = 0;
 	if (params->key_mgmt_suites & WPA_KEY_MGMT_IEEE8021X)
 		suites[num_suites++] = WLAN_AKM_SUITE_8021X;
@@ -5848,6 +5880,8 @@
 	    params->pairwise_ciphers & (WPA_CIPHER_WEP104 | WPA_CIPHER_WEP40))
 		NLA_PUT_FLAG(msg, NL80211_ATTR_CONTROL_PORT_NO_ENCRYPT);
 
+	wpa_printf(MSG_DEBUG, "nl80211: pairwise_ciphers=0x%x",
+		   params->pairwise_ciphers);
 	num_suites = 0;
 	if (params->pairwise_ciphers & WPA_CIPHER_CCMP)
 		suites[num_suites++] = WLAN_CIPHER_SUITE_CCMP;
@@ -5864,6 +5898,8 @@
 			num_suites * sizeof(u32), suites);
 	}
 
+	wpa_printf(MSG_DEBUG, "nl80211: group_cipher=0x%x",
+		   params->group_cipher);
 	switch (params->group_cipher) {
 	case WPA_CIPHER_CCMP:
 		NLA_PUT_U32(msg, NL80211_ATTR_CIPHER_SUITE_GROUP,
@@ -5888,21 +5924,29 @@
 	}
 
 	if (params->beacon_ies) {
+		wpa_hexdump_buf(MSG_DEBUG, "nl80211: beacon_ies",
+				params->beacon_ies);
 		NLA_PUT(msg, NL80211_ATTR_IE, wpabuf_len(params->beacon_ies),
 			wpabuf_head(params->beacon_ies));
 	}
 	if (params->proberesp_ies) {
+		wpa_hexdump_buf(MSG_DEBUG, "nl80211: proberesp_ies",
+				params->proberesp_ies);
 		NLA_PUT(msg, NL80211_ATTR_IE_PROBE_RESP,
 			wpabuf_len(params->proberesp_ies),
 			wpabuf_head(params->proberesp_ies));
 	}
 	if (params->assocresp_ies) {
+		wpa_hexdump_buf(MSG_DEBUG, "nl80211: assocresp_ies",
+				params->assocresp_ies);
 		NLA_PUT(msg, NL80211_ATTR_IE_ASSOC_RESP,
 			wpabuf_len(params->assocresp_ies),
 			wpabuf_head(params->assocresp_ies));
 	}
 
 	if (drv->capa.flags & WPA_DRIVER_FLAGS_INACTIVITY_TIMER)  {
+		wpa_printf(MSG_DEBUG, "nl80211: ap_max_inactivity=%d",
+			   params->ap_max_inactivity);
 		NLA_PUT_U16(msg, NL80211_ATTR_INACTIVITY_TIMEOUT,
 			    params->ap_max_inactivity);
 	}