Merge "wifi: Support interface disable event in hostapd" into tm-dev
diff --git a/hostapd/aidl/hostapd.cpp b/hostapd/aidl/hostapd.cpp
index e4e0a88..11d1290 100644
--- a/hostapd/aidl/hostapd.cpp
+++ b/hostapd/aidl/hostapd.cpp
@@ -321,6 +321,7 @@
 	// Encryption config string
 	uint32_t band = 0;
 	band |= static_cast<uint32_t>(channelParams.bandMask);
+	bool is_2Ghz_band_only = band == static_cast<uint32_t>(band2Ghz);
 	bool is_6Ghz_band_only = band == static_cast<uint32_t>(band6Ghz);
 	bool is_60Ghz_band_only = band == static_cast<uint32_t>(band60Ghz);
 	std::string encryption_config_as_string;
@@ -460,9 +461,7 @@
 	std::string hw_mode_as_string;
 	std::string enable_edmg_as_string;
 	std::string edmg_channel_as_string;
-#ifdef CONFIG_IEEE80211AX
 	bool is_60Ghz_used = false;
-#endif /* CONFIG_IEEE80211AX */
 
 	if (((band & band60Ghz) != 0)) {
 		hw_mode_as_string = "hw_mode=ad";
@@ -472,9 +471,7 @@
 				"edmg_channel=%d",
 				channelParams.channel);
 		}
-#ifdef CONFIG_IEEE80211AX
 		is_60Ghz_used = true;
-#endif /* CONFIG_IEEE80211AX */
 	} else if ((band & band2Ghz) != 0) {
 		if (((band & band5Ghz) != 0)
 		    || ((band & band6Ghz) != 0)) {
@@ -550,17 +547,17 @@
 			iface_params.hwModeParams.enable80211AC ? 2 : 0);
 		break;
 	default:
-		ht_cap_vht_oper_he_oper_chwidth_as_string = StringPrintf(
-			"ht_capab=[HT40+]\n"
+		if (!is_2Ghz_band_only && !is_60Ghz_used
+		    && iface_params.hwModeParams.enable80211AC) {
+			ht_cap_vht_oper_he_oper_chwidth_as_string =
+					"ht_capab=[HT40+]\n"
+					"vht_oper_chwidth=1\n";
+		}
 #ifdef CONFIG_IEEE80211AX
-			"he_oper_chwidth=%d\n"
+		if (iface_params.hwModeParams.enable80211AX && !is_60Ghz_used) {
+			ht_cap_vht_oper_he_oper_chwidth_as_string += "he_oper_chwidth=1";
+		}
 #endif
-			"vht_oper_chwidth=%d",
-#ifdef CONFIG_IEEE80211AX
-			(iface_params.hwModeParams.enable80211AX && !is_60Ghz_used) ? 1 : 0,
-#endif
-			((((band & band5Ghz) != 0) || ((band & band6Ghz) != 0))
-			&& iface_params.hwModeParams.enable80211AC) ? 1 : 0);
 		break;
 	}
 
diff --git a/wpa_supplicant/aidl/aidl_manager.cpp b/wpa_supplicant/aidl/aidl_manager.cpp
index e18292a..9124570 100644
--- a/wpa_supplicant/aidl/aidl_manager.cpp
+++ b/wpa_supplicant/aidl/aidl_manager.cpp
@@ -1584,7 +1584,12 @@
 		config->ssid + config->ssid_len);
 
 	if (securityAkm == DppAkm::DPP) {
-		// TODO Add code to fill aidl_keys
+		std::string connector_str = misc_utils::charBufToString(config->dpp_connector);
+		aidl_keys.connector = std::vector<uint8_t>(connector_str.begin(),
+			connector_str.end());
+		aidl_keys.cSign = byteArrToVec(config->dpp_csign, config->dpp_csign_len);
+		aidl_keys.netAccessKey = byteArrToVec(config->dpp_netaccesskey,
+			config->dpp_netaccesskey_len);
 	}
 
 	/* At this point, the network is already registered, notify about new
diff --git a/wpa_supplicant/aidl/sta_iface.cpp b/wpa_supplicant/aidl/sta_iface.cpp
index f382285..b4fbb24 100644
--- a/wpa_supplicant/aidl/sta_iface.cpp
+++ b/wpa_supplicant/aidl/sta_iface.cpp
@@ -1419,6 +1419,9 @@
 #ifdef CONFIG_DPP
 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
 	std::string cmd = "";
+	std::string cmd2 = "";
+	int32_t id;
+	char key[1024];
 
 	if (net_role != DppNetRole::AP &&
 			net_role != DppNetRole::STA) {
@@ -1493,8 +1496,10 @@
 		role += "psk-sae";
 		break;
 
-	// TODO add code to handle DPP AKM
 	case DppAkm::DPP:
+		role += "dpp";
+		break;
+
 	default:
 		wpa_printf(MSG_ERROR,
 			   "DPP: Invalid or unsupported security AKM specified: %d", security_akm);
@@ -1510,10 +1515,33 @@
 		cmd += " conn_status=1";
 	}
 
+	if (security_akm == DppAkm::DPP) {
+		if (!privEcKey.empty()) {
+			cmd2 += " key=" + std::string(privEcKey.begin(), privEcKey.end());
+		}
+		id = dpp_configurator_add(wpa_s->dpp, cmd2.c_str());
+		if (id < 0 || (privEcKey.empty() &&
+			       (dpp_configurator_get_key_id(wpa_s->dpp, id, key, sizeof(key)) < 0)))
+		{
+			wpa_printf(MSG_ERROR, "DPP configurator add failed. "
+			           "Input key might be incorrect");
+			return {std::vector<uint8_t>(),
+				createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+		}
+
+		cmd += " configurator=" + std::to_string(id);
+	}
+
 	wpa_printf(MSG_DEBUG,
 		   "DPP initiator command: %s", cmd.c_str());
 
 	if (wpas_dpp_auth_init(wpa_s, cmd.c_str()) == 0) {
+		// Return key if input privEcKey was null/empty.
+		if (security_akm == DppAkm::DPP && privEcKey.empty()) {
+			std::string k(key);
+			std::vector<uint8_t> vKey(k.begin(), k.end());
+			return {vKey, ndk::ScopedAStatus::ok()};
+		}
 		return {std::vector<uint8_t>(), ndk::ScopedAStatus::ok()};
 	}
 #endif
@@ -1666,8 +1694,46 @@
 		const std::vector<uint8_t> &privEcKey)
 {
 #ifdef CONFIG_DPP
-    // TODO Implement this function
-    return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	std::string cmd = "";
+	char *ssid_hex_str;
+	int len;
+	int32_t id;
+
+	if (ssid.empty() || privEcKey.empty()) {
+		wpa_printf(MSG_ERROR, "DPP generate self configuration failed. ssid/key empty");
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	cmd += " key=" + std::string(privEcKey.begin(), privEcKey.end());
+
+	id = dpp_configurator_add(wpa_s->dpp, cmd.c_str());
+	if (id < 0) {
+		wpa_printf(MSG_ERROR, "DPP configurator add failed. Input key might be incorrect");
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	cmd = " conf=sta-dpp";
+	cmd += " configurator=" + std::to_string(id);
+
+	ssid_hex_str = (char *) os_zalloc(ssid.size() * 2 + 1);
+	if (!ssid_hex_str) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	wpa_snprintf_hex(ssid_hex_str, ssid.size() * 2 + 1, (u8*)ssid.data(), ssid.size());
+	cmd += " ssid=" + std::string(ssid_hex_str);
+
+	/* Report received configuration to AIDL and create an internal profile */
+	wpa_s->conf->dpp_config_processing = 1;
+
+	if (wpas_dpp_configurator_sign(wpa_s, cmd.c_str()) == 0) {
+		os_free(ssid_hex_str);
+		return ndk::ScopedAStatus::ok();
+	}
+
+	os_free(ssid_hex_str);
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
 #else
 	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
 #endif
diff --git a/wpa_supplicant/aidl/sta_network.cpp b/wpa_supplicant/aidl/sta_network.cpp
index da5decd..88e7b74 100644
--- a/wpa_supplicant/aidl/sta_network.cpp
+++ b/wpa_supplicant/aidl/sta_network.cpp
@@ -45,7 +45,8 @@
 	 static_cast<uint32_t>(KeyMgmtMask::WAPI_PSK) |
 	 static_cast<uint32_t>(KeyMgmtMask::WAPI_CERT) |
 	 static_cast<uint32_t>(KeyMgmtMask::FILS_SHA256) |
-	 static_cast<uint32_t>(KeyMgmtMask::FILS_SHA384));
+	 static_cast<uint32_t>(KeyMgmtMask::FILS_SHA384) |
+	 static_cast<uint32_t>(KeyMgmtMask::DPP));
 constexpr uint32_t kAllowedProtoMask =
 	(static_cast<uint32_t>(ProtoMask::WPA) |
 	 static_cast<uint32_t>(ProtoMask::RSN) |
@@ -946,10 +947,33 @@
 ndk::ScopedAStatus StaNetwork::setDppKeysInternal(const DppConnectionKeys& keys)
 {
 #ifdef CONFIG_DPP
-    // TODO Implement the function
-    return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+	if (keys.connector.empty() || keys.cSign.empty() || keys.netAccessKey.empty()) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	std::string connector_str(keys.connector.begin(), keys.connector.end());
+
+	if (setStringFieldAndResetState(
+		connector_str.c_str(), &(wpa_ssid->dpp_connector), "dpp_connector")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	if (setByteArrayFieldAndResetState(
+		keys.cSign.data(), keys.cSign.size(), &(wpa_ssid->dpp_csign),
+		&(wpa_ssid->dpp_csign_len), "dpp csign")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	if (setByteArrayFieldAndResetState(
+		keys.netAccessKey.data(), keys.netAccessKey.size(), &(wpa_ssid->dpp_netaccesskey),
+		&(wpa_ssid->dpp_netaccesskey_len), "dpp netAccessKey")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	return ndk::ScopedAStatus::ok();
 #else
-    return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
 #endif
 }
 
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index cb01929..f1d033b 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -5803,7 +5803,7 @@
 				}
 				i++;
 			}
-		} else {
+		} else if (!wpa_s->conf->num_p2p_pref_chan) {
 			enum wpa_driver_if_type iface_type;
 
 			if (go)