diff --git a/hostapd/Android.mk b/hostapd/Android.mk
index df0dc95..627fd21 100644
--- a/hostapd/Android.mk
+++ b/hostapd/Android.mk
@@ -1125,9 +1125,9 @@
 endif
 
 ifeq ($(filter gce_x86 gce_x86_64 calypso, $(TARGET_DEVICE)),)
-ifdef CONFIG_CTRL_IFACE_HIDL
-HOSTAPD_USE_HIDL=y
-L_CFLAGS += -DCONFIG_CTRL_IFACE_HIDL
+ifdef CONFIG_CTRL_IFACE_AIDL
+HOSTAPD_USE_AIDL=y
+L_CFLAGS += -DCONFIG_CTRL_IFACE_AIDL
 L_CPPFLAGS = -Wall -Werror
 endif
 endif
@@ -1170,13 +1170,11 @@
 LOCAL_STATIC_LIBRARIES += libnl_2
 endif
 endif
-ifeq ($(HOSTAPD_USE_HIDL), y)
-LOCAL_SHARED_LIBRARIES += android.hardware.wifi.hostapd@1.0
-LOCAL_SHARED_LIBRARIES += android.hardware.wifi.hostapd@1.1
-LOCAL_SHARED_LIBRARIES += android.hardware.wifi.hostapd@1.2
-LOCAL_SHARED_LIBRARIES += android.hardware.wifi.hostapd@1.3
-LOCAL_SHARED_LIBRARIES += libbase libhidlbase libutils
-LOCAL_STATIC_LIBRARIES += libhostapd_hidl
+ifeq ($(HOSTAPD_USE_AIDL), y)
+LOCAL_SHARED_LIBRARIES += android.hardware.wifi.hostapd-V1-ndk_platform
+LOCAL_SHARED_LIBRARIES += libbase libutils
+LOCAL_SHARED_LIBRARIES += libbinder_ndk
+LOCAL_STATIC_LIBRARIES += libhostapd_aidl
 endif
 LOCAL_CFLAGS := $(L_CFLAGS)
 LOCAL_SRC_FILES := $(OBJS)
@@ -1186,7 +1184,7 @@
 
 ########################
 include $(CLEAR_VARS)
-LOCAL_MODULE := hostapd_nohidl
+LOCAL_MODULE := hostapd_noaidl
 LOCAL_LICENSE_KINDS := SPDX-license-identifier-BSD SPDX-license-identifier-BSD-3-Clause SPDX-license-identifier-ISC legacy_unencumbered
 LOCAL_LICENSE_CONDITIONS := notice unencumbered
 LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../COPYING $(LOCAL_PATH)/../NOTICE
@@ -1206,16 +1204,16 @@
 LOCAL_STATIC_LIBRARIES += libnl_2
 endif
 endif
-LOCAL_CFLAGS := $(patsubst -DCONFIG_CTRL_IFACE_HIDL,,$(L_CFLAGS))
+LOCAL_CFLAGS := $(patsubst -DCONFIG_CTRL_IFACE_AIDL,,$(L_CFLAGS))
 LOCAL_SRC_FILES := $(OBJS)
 LOCAL_C_INCLUDES := $(INCLUDES)
 include $(BUILD_EXECUTABLE)
 
-ifeq ($(HOSTAPD_USE_HIDL), y)
-### Hidl service library ###
+ifeq ($(HOSTAPD_USE_AIDL), y)
+### Aidl service library ###
 ########################
 include $(CLEAR_VARS)
-LOCAL_MODULE := libhostapd_hidl
+LOCAL_MODULE := libhostapd_aidl
 LOCAL_LICENSE_KINDS := SPDX-license-identifier-BSD SPDX-license-identifier-BSD-3-Clause SPDX-license-identifier-ISC legacy_unencumbered
 LOCAL_LICENSE_CONDITIONS := notice unencumbered
 LOCAL_NOTICE_FILE := $(LOCAL_PATH)/../COPYING $(LOCAL_PATH)/../NOTICE
@@ -1223,21 +1221,17 @@
 LOCAL_CPPFLAGS := $(L_CPPFLAGS)
 LOCAL_CFLAGS := $(L_CFLAGS)
 LOCAL_C_INCLUDES := $(INCLUDES)
-HIDL_INTERFACE_VERSION = 1.3
 LOCAL_SRC_FILES := \
-    hidl/$(HIDL_INTERFACE_VERSION)/hidl.cpp \
-    hidl/$(HIDL_INTERFACE_VERSION)/hostapd.cpp
+    aidl/aidl.cpp \
+    aidl/hostapd.cpp
 LOCAL_SHARED_LIBRARIES := \
-    android.hardware.wifi.hostapd@1.0 \
-    android.hardware.wifi.hostapd@1.1 \
-    android.hardware.wifi.hostapd@1.2 \
-    android.hardware.wifi.hostapd@1.3 \
+    android.hardware.wifi.hostapd-V1-ndk_platform \
+    libbinder_ndk \
     libbase \
-    libhidlbase \
     libutils \
     liblog
 LOCAL_EXPORT_C_INCLUDE_DIRS := \
-    $(LOCAL_PATH)/hidl/$(HIDL_INTERFACE_VERSION)
+    $(LOCAL_PATH)/aidl
 include $(BUILD_STATIC_LIBRARY)
-endif # HOSTAPD_USE_HIDL == y
+endif # HOSTAPD_USE_AIDL == y
 endif # ifeq ($(WPA_BUILD_HOSTAPD),true)
diff --git a/hostapd/hidl/.clang-format b/hostapd/aidl/.clang-format
similarity index 100%
rename from hostapd/hidl/.clang-format
rename to hostapd/aidl/.clang-format
diff --git a/hostapd/aidl/aidl.cpp b/hostapd/aidl/aidl.cpp
new file mode 100644
index 0000000..68a7714
--- /dev/null
+++ b/hostapd/aidl/aidl.cpp
@@ -0,0 +1,71 @@
+/*
+ * aidl interface for wpa_supplicant daemon
+ * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2018, Roshan Pius <rpius@google.com>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "hostapd.h"
+#include <android/binder_process.h>
+#include <android/binder_manager.h>
+
+extern "C"
+{
+#include "aidl.h"
+#include "utils/common.h"
+#include "utils/eloop.h"
+#include "utils/includes.h"
+}
+
+using aidl::android::hardware::wifi::hostapd::Hostapd;
+
+// This file is a bridge between the hostapd code written in 'C' and the aidl
+// interface in C++. So, using "C" style static globals here!
+static int aidl_fd = -1;
+static std::shared_ptr<Hostapd> service;
+
+void hostapd_aidl_sock_handler(
+    int /* sock */, void * /* eloop_ctx */, void * /* sock_ctx */)
+{
+	ABinderProcess_handlePolledCommands();
+}
+
+int hostapd_aidl_init(struct hapd_interfaces *interfaces)
+{
+	wpa_printf(MSG_DEBUG, "Initializing aidl control");
+	std::string instance;   // declared here to allow use of goto
+
+	ABinderProcess_setupPolling(&aidl_fd);
+	if (aidl_fd < 0)
+		goto err;
+
+	wpa_printf(MSG_INFO, "Processing aidl events on FD %d", aidl_fd);
+	// Look for read events from the aidl socket in the eloop.
+	if (eloop_register_read_sock(
+		aidl_fd, hostapd_aidl_sock_handler, interfaces, NULL) < 0)
+		goto err;
+
+	wpa_printf(MSG_DEBUG, "Make service");
+	service = ndk::SharedRefBase::make<Hostapd>(interfaces);
+	if (!service)
+		goto err;
+	wpa_printf(MSG_DEBUG, "Add service");
+	instance = std::string() + Hostapd::descriptor + "/default";
+	if (AServiceManager_addService(service->asBinder().get(), instance.c_str()) != STATUS_OK)
+		goto err;
+	return 0;
+err:
+	hostapd_aidl_deinit(interfaces);
+	return -1;
+}
+
+void hostapd_aidl_deinit(struct hapd_interfaces *interfaces)
+{
+	wpa_printf(MSG_INFO, "Deiniting aidl control");
+	// Before aidl init, make sure call terminate to clear callback_
+	service->terminate();
+	eloop_unregister_read_sock(aidl_fd);
+	aidl_fd = -1;
+}
diff --git a/hostapd/aidl/aidl.h b/hostapd/aidl/aidl.h
new file mode 100644
index 0000000..f82013d
--- /dev/null
+++ b/hostapd/aidl/aidl.h
@@ -0,0 +1,27 @@
+/*
+ * aidl interface for wpa_supplicant daemon
+ * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2018, Roshan Pius <rpius@google.com>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif  // _cplusplus
+#include "ap/hostapd.h"
+
+/**
+ * This is the aidl RPC interface entry point to the hostapd core.
+ * This initializes the aidl driver & IHostapd instance.
+ */
+int hostapd_aidl_init(struct hapd_interfaces *interfaces);
+void hostapd_aidl_deinit(struct hapd_interfaces *interfaces);
+
+#ifdef __cplusplus
+}
+#endif  // _cplusplus
diff --git a/hostapd/aidl/hostapd.cpp b/hostapd/aidl/hostapd.cpp
new file mode 100644
index 0000000..140298a
--- /dev/null
+++ b/hostapd/aidl/hostapd.cpp
@@ -0,0 +1,1002 @@
+/*
+ * aidl interface for wpa_hostapd daemon
+ * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2018, Roshan Pius <rpius@google.com>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+#include <iomanip>
+#include <sstream>
+#include <string>
+#include <vector>
+#include <net/if.h>
+#include <sys/socket.h>
+#include <linux/if_bridge.h>
+
+#include <android-base/file.h>
+#include <android-base/stringprintf.h>
+#include <android-base/unique_fd.h>
+
+#include "hostapd.h"
+#include <aidl/android/hardware/wifi/hostapd/ApInfo.h>
+#include <aidl/android/hardware/wifi/hostapd/BandMask.h>
+#include <aidl/android/hardware/wifi/hostapd/ChannelParams.h>
+#include <aidl/android/hardware/wifi/hostapd/ClientInfo.h>
+#include <aidl/android/hardware/wifi/hostapd/EncryptionType.h>
+#include <aidl/android/hardware/wifi/hostapd/HostapdStatusCode.h>
+#include <aidl/android/hardware/wifi/hostapd/IfaceParams.h>
+#include <aidl/android/hardware/wifi/hostapd/NetworkParams.h>
+#include <aidl/android/hardware/wifi/hostapd/ParamSizeLimits.h>
+
+extern "C"
+{
+#include "common/wpa_ctrl.h"
+#include "drivers/linux_ioctl.h"
+}
+
+// The AIDL implementation for hostapd creates a hostapd.conf dynamically for
+// each interface. This file can then be used to hook onto the normal config
+// file parsing logic in hostapd code.  Helps us to avoid duplication of code
+// in the AIDL interface.
+// TOOD(b/71872409): Add unit tests for this.
+namespace {
+constexpr char kConfFileNameFmt[] = "/data/vendor/wifi/hostapd/hostapd_%s.conf";
+
+using android::base::RemoveFileIfExists;
+using android::base::StringPrintf;
+using android::base::WriteStringToFile;
+using aidl::android::hardware::wifi::hostapd::BandMask;
+using aidl::android::hardware::wifi::hostapd::Bandwidth;
+using aidl::android::hardware::wifi::hostapd::ChannelParams;
+using aidl::android::hardware::wifi::hostapd::EncryptionType;
+using aidl::android::hardware::wifi::hostapd::Generation;
+using aidl::android::hardware::wifi::hostapd::HostapdStatusCode;
+using aidl::android::hardware::wifi::hostapd::IfaceParams;
+using aidl::android::hardware::wifi::hostapd::NetworkParams;
+using aidl::android::hardware::wifi::hostapd::ParamSizeLimits;
+
+int band2Ghz = (int)BandMask::BAND_2_GHZ;
+int band5Ghz = (int)BandMask::BAND_5_GHZ;
+int band6Ghz = (int)BandMask::BAND_6_GHZ;
+int band60Ghz = (int)BandMask::BAND_60_GHZ;
+
+#define MAX_PORTS 1024
+bool GetInterfacesInBridge(std::string br_name,
+                           std::vector<std::string>* interfaces) {
+	android::base::unique_fd sock(socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
+	if (sock.get() < 0) {
+		wpa_printf(MSG_ERROR, "Failed to create sock (%s) in %s",
+			strerror(errno), __FUNCTION__);
+		return false;
+	}
+
+	struct ifreq request;
+	int i, ifindices[MAX_PORTS];
+	char if_name[IFNAMSIZ];
+	unsigned long args[3];
+
+	memset(ifindices, 0, MAX_PORTS * sizeof(int));
+
+	args[0] = BRCTL_GET_PORT_LIST;
+	args[1] = (unsigned long) ifindices;
+	args[2] = MAX_PORTS;
+
+	strlcpy(request.ifr_name, br_name.c_str(), IFNAMSIZ);
+	request.ifr_data = (char *)args;
+
+	if (ioctl(sock.get(), SIOCDEVPRIVATE, &request) < 0) {
+		wpa_printf(MSG_ERROR, "Failed to ioctl SIOCDEVPRIVATE in %s",
+			__FUNCTION__);
+		return false;
+	}
+
+	for (i = 0; i < MAX_PORTS; i ++) {
+		memset(if_name, 0, IFNAMSIZ);
+		if (ifindices[i] == 0 || !if_indextoname(ifindices[i], if_name)) {
+			continue;
+		}
+		interfaces->push_back(if_name);
+	}
+	return true;
+}
+
+std::string WriteHostapdConfig(
+    const std::string& interface_name, const std::string& config)
+{
+	const std::string file_path =
+	    StringPrintf(kConfFileNameFmt, interface_name.c_str());
+	if (WriteStringToFile(
+		config, file_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
+		getuid(), getgid())) {
+		return file_path;
+	}
+	// Diagnose failure
+	int error = errno;
+	wpa_printf(
+		MSG_ERROR, "Cannot write hostapd config to %s, error: %s",
+		file_path.c_str(), strerror(error));
+	struct stat st;
+	int result = stat(file_path.c_str(), &st);
+	if (result == 0) {
+		wpa_printf(
+			MSG_ERROR, "hostapd config file uid: %d, gid: %d, mode: %d",
+			st.st_uid, st.st_gid, st.st_mode);
+	} else {
+		wpa_printf(
+			MSG_ERROR,
+			"Error calling stat() on hostapd config file: %s",
+			strerror(errno));
+	}
+	return "";
+}
+
+/*
+ * Get the op_class for a channel/band
+ * The logic here is based on Table E-4 in the 802.11 Specification
+ */
+int getOpClassForChannel(int channel, int band, bool support11n, bool support11ac) {
+	// 2GHz Band
+	if ((band & band2Ghz) != 0) {
+		if (channel == 14) {
+			return 82;
+		}
+		if (channel >= 1 && channel <= 13) {
+			if (!support11n) {
+				//20MHz channel
+				return 81;
+			}
+			if (channel <= 9) {
+				// HT40 with secondary channel above primary
+				return 83;
+			}
+			// HT40 with secondary channel below primary
+			return 84;
+		}
+		// Error
+		return 0;
+	}
+
+	// 5GHz Band
+	if ((band & band5Ghz) != 0) {
+		if (support11ac) {
+			switch (channel) {
+				case 42:
+				case 58:
+				case 106:
+				case 122:
+				case 138:
+				case 155:
+					// 80MHz channel
+					return 128;
+				case 50:
+				case 114:
+					// 160MHz channel
+					return 129;
+			}
+		}
+
+		if (!support11n) {
+			if (channel >= 36 && channel <= 48) {
+				return 115;
+			}
+			if (channel >= 52 && channel <= 64) {
+				return 118;
+			}
+			if (channel >= 100 && channel <= 144) {
+				return 121;
+			}
+			if (channel >= 149 && channel <= 161) {
+				return 124;
+			}
+			if (channel >= 165 && channel <= 169) {
+				return 125;
+			}
+		} else {
+			switch (channel) {
+				case 36:
+				case 44:
+					// HT40 with secondary channel above primary
+					return 116;
+				case 40:
+				case 48:
+					// HT40 with secondary channel below primary
+					return 117;
+				case 52:
+				case 60:
+					// HT40 with secondary channel above primary
+					return  119;
+				case 56:
+				case 64:
+					// HT40 with secondary channel below primary
+					return 120;
+				case 100:
+				case 108:
+				case 116:
+				case 124:
+				case 132:
+				case 140:
+					// HT40 with secondary channel above primary
+					return 122;
+				case 104:
+				case 112:
+				case 120:
+				case 128:
+				case 136:
+				case 144:
+					// HT40 with secondary channel below primary
+					return 123;
+				case 149:
+				case 157:
+					// HT40 with secondary channel above primary
+					return 126;
+				case 153:
+				case 161:
+					// HT40 with secondary channel below primary
+					return 127;
+			}
+		}
+		// Error
+		return 0;
+	}
+
+	// 6GHz Band
+	if ((band & band6Ghz) != 0) {
+		// Channels 1, 5. 9, 13, ...
+		if ((channel & 0x03) == 0x01) {
+			// 20MHz channel
+			return 131;
+		}
+		// Channels 3, 11, 19, 27, ...
+		if ((channel & 0x07) == 0x03) {
+			// 40MHz channel
+			return 132;
+		}
+		// Channels 7, 23, 39, 55, ...
+		if ((channel & 0x0F) == 0x07) {
+			// 80MHz channel
+			return 133;
+		}
+		// Channels 15, 47, 69, ...
+		if ((channel & 0x1F) == 0x0F) {
+			// 160MHz channel
+			return 134;
+		}
+		if (channel == 2) {
+			// 20MHz channel
+			return 136;
+		}
+		// Error
+		return 0;
+	}
+
+	if ((band & band60Ghz) != 0) {
+		if (1 <= channel && channel <= 8) {
+			return 180;
+		} else if (9 <= channel && channel <= 15) {
+			return 181;
+		} else if (17 <= channel && channel <= 22) {
+			return 182;
+		} else if (25 <= channel && channel <= 29) {
+			return 183;
+		}
+		// Error
+		return 0;
+	}
+
+	return 0;
+}
+
+bool validatePassphrase(int passphrase_len, int min_len, int max_len)
+{
+	if (min_len != -1 && passphrase_len < min_len) return false;
+	if (max_len != -1 && passphrase_len > max_len) return false;
+	return true;
+}
+
+std::string CreateHostapdConfig(
+	const IfaceParams& iface_params,
+	const ChannelParams& channelParams,
+	const NetworkParams& nw_params,
+	const std::string br_name)
+{
+	if (nw_params.ssid.size() >
+		static_cast<uint32_t>(
+		ParamSizeLimits::SSID_MAX_LEN_IN_BYTES)) {
+		wpa_printf(
+			MSG_ERROR, "Invalid SSID size: %zu", nw_params.ssid.size());
+		return "";
+	}
+
+	// SSID string
+	std::stringstream ss;
+	ss << std::hex;
+	ss << std::setfill('0');
+	for (uint8_t b : nw_params.ssid) {
+		ss << std::setw(2) << static_cast<unsigned int>(b);
+	}
+	const std::string ssid_as_string = ss.str();
+
+	// Encryption config string
+	uint32_t band = 0;
+	band |= static_cast<uint32_t>(channelParams.bandMask);
+	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;
+	switch (nw_params.encryptionType) {
+	case EncryptionType::NONE:
+		// no security params
+		break;
+	case EncryptionType::WPA:
+		if (!validatePassphrase(
+			nw_params.passphrase.size(),
+			static_cast<uint32_t>(ParamSizeLimits::
+				WPA2_PSK_PASSPHRASE_MIN_LEN_IN_BYTES),
+			static_cast<uint32_t>(ParamSizeLimits::
+				WPA2_PSK_PASSPHRASE_MAX_LEN_IN_BYTES))) {
+			return "";
+		}
+		encryption_config_as_string = StringPrintf(
+			"wpa=3\n"
+			"wpa_pairwise=%s\n"
+			"wpa_passphrase=%s",
+			is_60Ghz_band_only ? "GCMP" : "TKIP CCMP",
+			nw_params.passphrase.c_str());
+		break;
+	case EncryptionType::WPA2:
+		if (!validatePassphrase(
+			nw_params.passphrase.size(),
+			static_cast<uint32_t>(ParamSizeLimits::
+				WPA2_PSK_PASSPHRASE_MIN_LEN_IN_BYTES),
+			static_cast<uint32_t>(ParamSizeLimits::
+				WPA2_PSK_PASSPHRASE_MAX_LEN_IN_BYTES))) {
+			return "";
+		}
+		encryption_config_as_string = StringPrintf(
+			"wpa=2\n"
+			"rsn_pairwise=%s\n"
+			"wpa_passphrase=%s",
+			is_60Ghz_band_only ? "GCMP" : "CCMP",
+			nw_params.passphrase.c_str());
+		break;
+	case EncryptionType::WPA3_SAE_TRANSITION:
+		if (!validatePassphrase(
+			nw_params.passphrase.size(),
+			static_cast<uint32_t>(ParamSizeLimits::
+				WPA2_PSK_PASSPHRASE_MIN_LEN_IN_BYTES),
+			static_cast<uint32_t>(ParamSizeLimits::
+				WPA2_PSK_PASSPHRASE_MAX_LEN_IN_BYTES))) {
+			return "";
+		}
+		encryption_config_as_string = StringPrintf(
+			"wpa=2\n"
+			"rsn_pairwise=%s\n"
+			"wpa_key_mgmt=WPA-PSK SAE\n"
+			"ieee80211w=1\n"
+			"sae_require_mfp=1\n"
+			"wpa_passphrase=%s\n"
+			"sae_password=%s",
+			is_60Ghz_band_only ? "GCMP" : "CCMP",
+			nw_params.passphrase.c_str(),
+			nw_params.passphrase.c_str());
+		break;
+	case EncryptionType::WPA3_SAE:
+		if (!validatePassphrase(nw_params.passphrase.size(), 1, -1)) {
+			return "";
+		}
+		encryption_config_as_string = StringPrintf(
+			"wpa=2\n"
+			"rsn_pairwise=%s\n"
+			"wpa_key_mgmt=SAE\n"
+			"ieee80211w=2\n"
+			"sae_require_mfp=2\n"
+			"sae_pwe=%d\n"
+			"sae_password=%s",
+			is_60Ghz_band_only ? "GCMP" : "CCMP",
+			is_6Ghz_band_only ? 1 : 2,
+			nw_params.passphrase.c_str());
+		break;
+	default:
+		wpa_printf(MSG_ERROR, "Unknown encryption type");
+		return "";
+	}
+
+	std::string channel_config_as_string;
+	bool isFirst = true;
+	if (channelParams.enableAcs) {
+		std::string freqList_as_string;
+		for (const auto &range :
+			channelParams.acsChannelFreqRangesMhz) {
+			if (!isFirst) {
+				freqList_as_string += ",";
+			}
+			isFirst = false;
+
+			if (range.startMhz != range.endMhz) {
+				freqList_as_string +=
+					StringPrintf("%d-%d", range.startMhz, range.endMhz);
+			} else {
+				freqList_as_string += StringPrintf("%d", range.startMhz);
+			}
+		}
+		channel_config_as_string = StringPrintf(
+			"channel=0\n"
+			"acs_exclude_dfs=%d\n"
+			"freqlist=%s",
+			channelParams.acsShouldExcludeDfs,
+			freqList_as_string.c_str());
+	} else {
+		int op_class = getOpClassForChannel(
+			channelParams.channel,
+			band,
+			iface_params.hwModeParams.enable80211N,
+			iface_params.hwModeParams.enable80211AC);
+		channel_config_as_string = StringPrintf(
+			"channel=%d\n"
+			"op_class=%d",
+			channelParams.channel, op_class);
+	}
+
+	std::string hw_mode_as_string;
+	std::string ht_cap_vht_oper_chwidth_as_string;
+	std::string enable_edmg_as_string;
+	std::string edmg_channel_as_string;
+	bool is_60Ghz_used = false;
+
+	if (((band & band60Ghz) != 0)) {
+		hw_mode_as_string = "hw_mode=ad";
+		if (iface_params.hwModeParams.enableEdmg) {
+			enable_edmg_as_string = "enable_edmg=1";
+			edmg_channel_as_string = StringPrintf(
+				"edmg_channel=%d",
+				channelParams.channel);
+		}
+		is_60Ghz_used = true;
+	} else if ((band & band2Ghz) != 0) {
+		if (((band & band5Ghz) != 0)
+		    || ((band & band6Ghz) != 0)) {
+			hw_mode_as_string = "hw_mode=any";
+			if (iface_params.hwModeParams.enable80211AC) {
+				ht_cap_vht_oper_chwidth_as_string =
+					"ht_capab=[HT40+]\n"
+					"vht_oper_chwidth=1";
+			}
+		} else {
+			hw_mode_as_string = "hw_mode=g";
+		}
+	} else if (((band & band5Ghz) != 0)
+		    || ((band & band6Ghz) != 0)) {
+			hw_mode_as_string = "hw_mode=a";
+		if (iface_params.hwModeParams.enable80211AC) {
+			ht_cap_vht_oper_chwidth_as_string =
+				"ht_capab=[HT40+]\n"
+				"vht_oper_chwidth=1";
+		}
+	} else {
+		wpa_printf(MSG_ERROR, "Invalid band");
+		return "";
+	}
+
+	std::string he_params_as_string;
+#ifdef CONFIG_IEEE80211AX
+	if (iface_params.hwModeParams.enable80211AX && !is_60Ghz_used) {
+		he_params_as_string = StringPrintf(
+			"ieee80211ax=1\n"
+			"he_oper_chwidth=1\n"
+			"he_su_beamformer=%d\n"
+			"he_su_beamformee=%d\n"
+			"he_mu_beamformer=%d\n"
+			"he_twt_required=%d\n",
+			iface_params.hwModeParams.enableHeSingleUserBeamformer ? 1 : 0,
+			iface_params.hwModeParams.enableHeSingleUserBeamformee ? 1 : 0,
+			iface_params.hwModeParams.enableHeMultiUserBeamformer ? 1 : 0,
+			iface_params.hwModeParams.enableHeTargetWakeTime ? 1 : 0);
+	} else {
+		he_params_as_string = "ieee80211ax=0";
+	}
+#endif /* CONFIG_IEEE80211AX */
+
+#ifdef CONFIG_INTERWORKING
+	std::string access_network_params_as_string;
+	if (nw_params.isMetered) {
+		access_network_params_as_string = StringPrintf(
+			"interworking=1\n"
+			"access_network_type=2\n"); // CHARGEABLE_PUBLIC_NETWORK
+	} else {
+	    access_network_params_as_string = StringPrintf(
+			"interworking=0\n");
+	}
+#endif /* CONFIG_INTERWORKING */
+
+	std::string bridge_as_string;
+	if (!br_name.empty()) {
+		bridge_as_string = StringPrintf("bridge=%s", br_name.c_str());
+	}
+
+	return StringPrintf(
+		"interface=%s\n"
+		"driver=nl80211\n"
+		"ctrl_interface=/data/vendor/wifi/hostapd/ctrl\n"
+		// ssid2 signals to hostapd that the value is not a literal value
+		// for use as a SSID.  In this case, we're giving it a hex
+		// std::string and hostapd needs to expect that.
+		"ssid2=%s\n"
+		"%s\n"
+		"ieee80211n=%d\n"
+		"ieee80211ac=%d\n"
+		"%s\n"
+		"%s\n"
+		"%s\n"
+		"ignore_broadcast_ssid=%d\n"
+		"wowlan_triggers=any\n"
+#ifdef CONFIG_INTERWORKING
+		"%s\n"
+#endif /* CONFIG_INTERWORKING */
+		"%s\n"
+		"%s\n"
+		"%s\n"
+		"%s\n",
+		iface_params.name.c_str(), ssid_as_string.c_str(),
+		channel_config_as_string.c_str(),
+		iface_params.hwModeParams.enable80211N ? 1 : 0,
+		iface_params.hwModeParams.enable80211AC ? 1 : 0,
+		he_params_as_string.c_str(),
+		hw_mode_as_string.c_str(), ht_cap_vht_oper_chwidth_as_string.c_str(),
+		nw_params.isHidden ? 1 : 0,
+#ifdef CONFIG_INTERWORKING
+		access_network_params_as_string.c_str(),
+#endif /* CONFIG_INTERWORKING */
+		encryption_config_as_string.c_str(),
+		bridge_as_string.c_str(),
+		enable_edmg_as_string.c_str(),
+		edmg_channel_as_string.c_str());
+}
+
+Generation getGeneration(hostapd_hw_modes *current_mode)
+{
+	wpa_printf(MSG_DEBUG, "getGeneration hwmode=%d, ht_enabled=%d,"
+		   " vht_enabled=%d, he_supported=%d",
+		   current_mode->mode, current_mode->ht_capab != 0,
+		   current_mode->vht_capab != 0, current_mode->he_capab->he_supported);
+	switch (current_mode->mode) {
+	case HOSTAPD_MODE_IEEE80211B:
+		return Generation::WIFI_STANDARD_LEGACY;
+	case HOSTAPD_MODE_IEEE80211G:
+		return current_mode->ht_capab == 0 ?
+				Generation::WIFI_STANDARD_LEGACY : Generation::WIFI_STANDARD_11N;
+	case HOSTAPD_MODE_IEEE80211A:
+		if (current_mode->he_capab->he_supported) {
+			return Generation::WIFI_STANDARD_11AX;
+		}
+		return current_mode->vht_capab == 0 ?
+		       Generation::WIFI_STANDARD_11N : Generation::WIFI_STANDARD_11AC;
+	case HOSTAPD_MODE_IEEE80211AD:
+		return Generation::WIFI_STANDARD_11AD;
+	default:
+		return Generation::WIFI_STANDARD_UNKNOWN;
+	}
+}
+
+Bandwidth getBandwidth(struct hostapd_config *iconf)
+{
+	wpa_printf(MSG_DEBUG, "getBandwidth %d, isHT=%d, isHT40=%d",
+		   iconf->vht_oper_chwidth, iconf->ieee80211n,
+		   iconf->secondary_channel);
+	switch (iconf->vht_oper_chwidth) {
+	case CHANWIDTH_80MHZ:
+		return Bandwidth::BANDWIDTH_80;
+	case CHANWIDTH_80P80MHZ:
+		return Bandwidth::BANDWIDTH_80P80;
+		break;
+	case CHANWIDTH_160MHZ:
+		return Bandwidth::BANDWIDTH_160;
+		break;
+	case CHANWIDTH_USE_HT:
+		if (iconf->ieee80211n) {
+			return iconf->secondary_channel != 0 ?
+				Bandwidth::BANDWIDTH_40 : Bandwidth::BANDWIDTH_20;
+		}
+		return Bandwidth::BANDWIDTH_20_NOHT;
+	case CHANWIDTH_2160MHZ:
+		return Bandwidth::BANDWIDTH_2160;
+	case CHANWIDTH_4320MHZ:
+		return Bandwidth::BANDWIDTH_4320;
+	case CHANWIDTH_6480MHZ:
+		return Bandwidth::BANDWIDTH_6480;
+	case CHANWIDTH_8640MHZ:
+		return Bandwidth::BANDWIDTH_8640;
+	default:
+		return Bandwidth::BANDWIDTH_INVALID;
+	}
+}
+
+bool forceStaDisconnection(struct hostapd_data* hapd,
+			   const std::vector<uint8_t>& client_address,
+			   const uint16_t reason_code) {
+	struct sta_info *sta;
+	for (sta = hapd->sta_list; sta; sta = sta->next) {
+		int res;
+		res = memcmp(sta->addr, client_address.data(), ETH_ALEN);
+		if (res == 0) {
+			wpa_printf(MSG_INFO, "Force client:" MACSTR " disconnect with reason: %d",
+			    MAC2STR(client_address.data()), reason_code);
+			ap_sta_disconnect(hapd, sta, sta->addr, reason_code);
+			return true;
+		}
+	}
+	return false;
+}
+
+// hostapd core functions accept "C" style function pointers, so use global
+// functions to pass to the hostapd core function and store the corresponding
+// std::function methods to be invoked.
+//
+// NOTE: Using the pattern from the vendor HAL (wifi_legacy_hal.cpp).
+//
+// Callback to be invoked once setup is complete
+std::function<void(struct hostapd_data*)> on_setup_complete_internal_callback;
+void onAsyncSetupCompleteCb(void* ctx)
+{
+	struct hostapd_data* iface_hapd = (struct hostapd_data*)ctx;
+	if (on_setup_complete_internal_callback) {
+		on_setup_complete_internal_callback(iface_hapd);
+		// Invalidate this callback since we don't want this firing
+		// again in single AP mode.
+		if (strlen(iface_hapd->conf->bridge) > 0) {
+			on_setup_complete_internal_callback = nullptr;
+		}
+	}
+}
+
+// Callback to be invoked on hotspot client connection/disconnection
+std::function<void(struct hostapd_data*, const u8 *mac_addr, int authorized,
+		const u8 *p2p_dev_addr)> on_sta_authorized_internal_callback;
+void onAsyncStaAuthorizedCb(void* ctx, const u8 *mac_addr, int authorized,
+		const u8 *p2p_dev_addr)
+{
+	struct hostapd_data* iface_hapd = (struct hostapd_data*)ctx;
+	if (on_sta_authorized_internal_callback) {
+		on_sta_authorized_internal_callback(iface_hapd, mac_addr,
+			authorized, p2p_dev_addr);
+	}
+}
+
+std::function<void(struct hostapd_data*, int level,
+			enum wpa_msg_type type, const char *txt,
+			size_t len)> on_wpa_msg_internal_callback;
+
+void onAsyncWpaEventCb(void *ctx, int level,
+			enum wpa_msg_type type, const char *txt,
+			size_t len)
+{
+	struct hostapd_data* iface_hapd = (struct hostapd_data*)ctx;
+	if (on_wpa_msg_internal_callback) {
+		on_wpa_msg_internal_callback(iface_hapd, level,
+					type, txt, len);
+	}
+}
+
+inline ndk::ScopedAStatus createStatus(HostapdStatusCode status_code) {
+	return ndk::ScopedAStatus::fromServiceSpecificError(
+		static_cast<int32_t>(status_code));
+}
+
+inline ndk::ScopedAStatus createStatusWithMsg(
+	HostapdStatusCode status_code, std::string msg)
+{
+	return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+		static_cast<int32_t>(status_code), msg.c_str());
+}
+
+// Method called by death_notifier_ on client death.
+void onDeath(void* cookie) {
+	wpa_printf(MSG_ERROR, "Client died. Terminating...");
+	eloop_terminate();
+}
+
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace hostapd {
+
+Hostapd::Hostapd(struct hapd_interfaces* interfaces)
+	: interfaces_(interfaces)
+{
+	death_notifier_ = AIBinder_DeathRecipient_new(onDeath);
+}
+
+::ndk::ScopedAStatus Hostapd::addAccessPoint(
+	const IfaceParams& iface_params, const NetworkParams& nw_params)
+{
+	return addAccessPointInternal(iface_params, nw_params);
+}
+
+::ndk::ScopedAStatus Hostapd::removeAccessPoint(const std::string& iface_name)
+{
+	return removeAccessPointInternal(iface_name);
+}
+
+::ndk::ScopedAStatus Hostapd::terminate()
+{
+	wpa_printf(MSG_INFO, "Terminating...");
+	// Clear the callback to avoid IPCThreadState shutdown during the
+	// callback event.
+	callbacks_.clear();
+	eloop_terminate();
+	return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Hostapd::registerCallback(
+	const std::shared_ptr<IHostapdCallback>& callback)
+{
+	return registerCallbackInternal(callback);
+}
+
+::ndk::ScopedAStatus Hostapd::forceClientDisconnect(
+	const std::string& iface_name, const std::vector<uint8_t>& client_address,
+	Ieee80211ReasonCode reason_code)
+{
+	return forceClientDisconnectInternal(iface_name, client_address, reason_code);
+}
+
+::ndk::ScopedAStatus Hostapd::setDebugParams(DebugLevel level)
+{
+	return setDebugParamsInternal(level);
+}
+
+::ndk::ScopedAStatus Hostapd::addAccessPointInternal(
+	const IfaceParams& iface_params,
+	const NetworkParams& nw_params)
+{
+	int channelParamsSize = iface_params.channelParams.size();
+	if (channelParamsSize == 1) {
+		// Single AP
+		wpa_printf(MSG_INFO, "AddSingleAccessPoint, iface=%s",
+			iface_params.name.c_str());
+		return addSingleAccessPoint(iface_params, iface_params.channelParams[0],
+		    nw_params, "");
+	} else if (channelParamsSize == 2) {
+		// Concurrent APs
+		wpa_printf(MSG_INFO, "AddDualAccessPoint, iface=%s",
+			iface_params.name.c_str());
+		return addConcurrentAccessPoints(iface_params, nw_params);
+	}
+	return createStatus(HostapdStatusCode::FAILURE_ARGS_INVALID);
+}
+
+::ndk::ScopedAStatus Hostapd::addConcurrentAccessPoints(
+	const IfaceParams& iface_params, const NetworkParams& nw_params)
+{
+	int channelParamsListSize = iface_params.channelParams.size();
+	// Get available interfaces in bridge
+	std::vector<std::string> managed_interfaces;
+	std::string br_name = StringPrintf(
+		"%s", iface_params.name.c_str());
+	if (!GetInterfacesInBridge(br_name, &managed_interfaces)) {
+		return createStatusWithMsg(HostapdStatusCode::FAILURE_UNKNOWN,
+			"Get interfaces in bridge failed.");
+	}
+	if (managed_interfaces.size() < channelParamsListSize) {
+		return createStatusWithMsg(HostapdStatusCode::FAILURE_UNKNOWN,
+			"Available interfaces less than requested bands");
+	}
+	// start BSS on specified bands
+	for (std::size_t i = 0; i < channelParamsListSize; i ++) {
+		IfaceParams iface_params_new = iface_params;
+		iface_params_new.name = managed_interfaces[i];
+		ndk::ScopedAStatus status = addSingleAccessPoint(
+		    iface_params_new, iface_params.channelParams[i], nw_params, br_name);
+		if (!status.isOk()) {
+			wpa_printf(MSG_ERROR, "Failed to addAccessPoint %s",
+				   managed_interfaces[i].c_str());
+			return status;
+		}
+	}
+	// Save bridge interface info
+	br_interfaces_[br_name] = managed_interfaces;
+	return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Hostapd::addSingleAccessPoint(
+	const IfaceParams& iface_params,
+	const ChannelParams& channelParams,
+	const NetworkParams& nw_params,
+	const std::string br_name)
+{
+	if (hostapd_get_iface(interfaces_, iface_params.name.c_str())) {
+		wpa_printf(
+			MSG_ERROR, "Interface %s already present",
+			iface_params.name.c_str());
+		return createStatus(HostapdStatusCode::FAILURE_IFACE_EXISTS);
+	}
+	const auto conf_params = CreateHostapdConfig(iface_params, channelParams, nw_params, br_name);
+	if (conf_params.empty()) {
+		wpa_printf(MSG_ERROR, "Failed to create config params");
+		return createStatus(HostapdStatusCode::FAILURE_ARGS_INVALID);
+	}
+	const auto conf_file_path =
+		WriteHostapdConfig(iface_params.name, conf_params);
+	if (conf_file_path.empty()) {
+		wpa_printf(MSG_ERROR, "Failed to write config file");
+		return createStatus(HostapdStatusCode::FAILURE_UNKNOWN);
+	}
+	std::string add_iface_param_str = StringPrintf(
+		"%s config=%s", iface_params.name.c_str(),
+		conf_file_path.c_str());
+	std::vector<char> add_iface_param_vec(
+		add_iface_param_str.begin(), add_iface_param_str.end() + 1);
+	if (hostapd_add_iface(interfaces_, add_iface_param_vec.data()) < 0) {
+		wpa_printf(
+			MSG_ERROR, "Adding interface %s failed",
+			add_iface_param_str.c_str());
+		return createStatus(HostapdStatusCode::FAILURE_UNKNOWN);
+	}
+	struct hostapd_data* iface_hapd =
+	    hostapd_get_iface(interfaces_, iface_params.name.c_str());
+	WPA_ASSERT(iface_hapd != nullptr && iface_hapd->iface != nullptr);
+	// Register the setup complete callbacks
+	on_setup_complete_internal_callback =
+		[this](struct hostapd_data* iface_hapd) {
+			wpa_printf(
+			MSG_INFO, "AP interface setup completed - state %s",
+			hostapd_state_text(iface_hapd->iface->state));
+			if (iface_hapd->iface->state == HAPD_IFACE_DISABLED) {
+				// Invoke the failure callback on all registered
+				// clients.
+				for (const auto& callback : callbacks_) {
+					callback->onFailure(strlen(iface_hapd->conf->bridge) > 0 ?
+						iface_hapd->conf->bridge : iface_hapd->conf->iface);
+				}
+			}
+		};
+
+	// Register for new client connect/disconnect indication.
+	on_sta_authorized_internal_callback =
+		[this](struct hostapd_data* iface_hapd, const u8 *mac_addr,
+			int authorized, const u8 *p2p_dev_addr) {
+		wpa_printf(MSG_DEBUG, "notify client " MACSTR " %s",
+				MAC2STR(mac_addr),
+				(authorized) ? "Connected" : "Disconnected");
+		ClientInfo info;
+		info.ifaceName = strlen(iface_hapd->conf->bridge) > 0 ?
+			iface_hapd->conf->bridge : iface_hapd->conf->iface;
+		info.apIfaceInstance = iface_hapd->conf->iface;
+		info.clientAddress.assign(mac_addr, mac_addr + ETH_ALEN);
+		info.isConnected = authorized;
+		for (const auto &callback : callbacks_) {
+			callback->onConnectedClientsChanged(info);
+		}
+		};
+
+	// Register for wpa_event which used to get channel switch event
+	on_wpa_msg_internal_callback =
+		[this](struct hostapd_data* iface_hapd, int level,
+			enum wpa_msg_type type, const char *txt,
+			size_t len) {
+		wpa_printf(MSG_DEBUG, "Receive wpa msg : %s", txt);
+		if (os_strncmp(txt, AP_EVENT_ENABLED,
+					strlen(AP_EVENT_ENABLED)) == 0 ||
+			os_strncmp(txt, WPA_EVENT_CHANNEL_SWITCH,
+					strlen(WPA_EVENT_CHANNEL_SWITCH)) == 0) {
+			ApInfo info;
+			info.ifaceName = strlen(iface_hapd->conf->bridge) > 0 ?
+				iface_hapd->conf->bridge : iface_hapd->conf->iface,
+			info.apIfaceInstance = iface_hapd->conf->iface;
+			info.freqMhz = iface_hapd->iface->freq;
+			info.bandwidth = getBandwidth(iface_hapd->iconf);
+			info.generation = getGeneration(iface_hapd->iface->current_mode);
+			info.apIfaceInstanceMacAddress.assign(iface_hapd->own_addr,
+				iface_hapd->own_addr + ETH_ALEN);
+			for (const auto &callback : callbacks_) {
+				callback->onApInstanceInfoChanged(info);
+			}
+		}
+		};
+
+	// Setup callback
+	iface_hapd->setup_complete_cb = onAsyncSetupCompleteCb;
+	iface_hapd->setup_complete_cb_ctx = iface_hapd;
+	iface_hapd->sta_authorized_cb = onAsyncStaAuthorizedCb;
+	iface_hapd->sta_authorized_cb_ctx = iface_hapd;
+	wpa_msg_register_cb(onAsyncWpaEventCb);
+
+	if (hostapd_enable_iface(iface_hapd->iface) < 0) {
+		wpa_printf(
+			MSG_ERROR, "Enabling interface %s failed",
+			iface_params.name.c_str());
+		return createStatus(HostapdStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Hostapd::removeAccessPointInternal(const std::string& iface_name)
+{
+	// interfaces to be removed
+	std::vector<std::string> interfaces;
+	bool is_error = false;
+
+	const auto it = br_interfaces_.find(iface_name);
+	if (it != br_interfaces_.end()) {
+		// In case bridge, remove managed interfaces
+		interfaces = it->second;
+		br_interfaces_.erase(iface_name);
+	} else {
+		// else remove current interface
+		interfaces.push_back(iface_name);
+	}
+
+	for (auto& iface : interfaces) {
+		std::vector<char> remove_iface_param_vec(
+		    iface.begin(), iface.end() + 1);
+		if (hostapd_remove_iface(interfaces_, remove_iface_param_vec.data()) <  0) {
+			wpa_printf(MSG_INFO, "Remove interface %s failed", iface.c_str());
+			is_error = true;
+		}
+	}
+	if (is_error) {
+		return createStatus(HostapdStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Hostapd::registerCallbackInternal(
+	const std::shared_ptr<IHostapdCallback>& callback)
+{
+	binder_status_t status = AIBinder_linkToDeath(callback->asBinder().get(),
+			death_notifier_, this /* cookie */);
+	if (status != STATUS_OK) {
+		wpa_printf(
+			MSG_ERROR,
+			"Error registering for death notification for "
+			"hostapd callback object");
+		return createStatus(HostapdStatusCode::FAILURE_UNKNOWN);
+	}
+	callbacks_.push_back(callback);
+	return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Hostapd::forceClientDisconnectInternal(const std::string& iface_name,
+	const std::vector<uint8_t>& client_address, Ieee80211ReasonCode reason_code)
+{
+	struct hostapd_data *hapd = hostapd_get_iface(interfaces_, iface_name.c_str());
+	bool result;
+	if (!hapd) {
+		for (auto const& iface : br_interfaces_) {
+			if (iface.first == iface_name) {
+				for (auto const& instance : iface.second) {
+					hapd = hostapd_get_iface(interfaces_, instance.c_str());
+					if (hapd) {
+						result = forceStaDisconnection(hapd, client_address,
+								(uint16_t) reason_code);
+						if (result) break;
+					}
+				}
+			}
+		}
+	} else {
+		result = forceStaDisconnection(hapd, client_address, (uint16_t) reason_code);
+	}
+	if (!hapd) {
+		wpa_printf(MSG_ERROR, "Interface %s doesn't exist", iface_name.c_str());
+		return createStatus(HostapdStatusCode::FAILURE_IFACE_UNKNOWN);
+	}
+	if (result) {
+		return ndk::ScopedAStatus::ok();
+	}
+	return createStatus(HostapdStatusCode::FAILURE_CLIENT_UNKNOWN);
+}
+
+::ndk::ScopedAStatus Hostapd::setDebugParamsInternal(DebugLevel level)
+{
+	wpa_debug_level = static_cast<uint32_t>(level);
+	return ndk::ScopedAStatus::ok();
+}
+
+}  // namespace hostapd
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
\ No newline at end of file
diff --git a/hostapd/aidl/hostapd.h b/hostapd/aidl/hostapd.h
new file mode 100644
index 0000000..18a7a23
--- /dev/null
+++ b/hostapd/aidl/hostapd.h
@@ -0,0 +1,94 @@
+/*
+ * aidl interface for wpa_hostapd daemon
+ * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi>
+ * Copyright (c) 2004-2018, Roshan Pius <rpius@google.com>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#pragma once
+
+#include <map>
+#include <string>
+
+#include <android-base/macros.h>
+
+#include <aidl/android/hardware/wifi/hostapd/BnHostapd.h>
+
+extern "C"
+{
+#include "utils/common.h"
+#include "utils/eloop.h"
+#include "utils/includes.h"
+#include "utils/wpa_debug.h"
+#include "ap/hostapd.h"
+#include "ap/sta_info.h"
+}
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace hostapd {
+
+/**
+ * Implementation of the hostapd aidl object. This aidl
+ * object is used core for global control operations on
+ * hostapd.
+ */
+class Hostapd : public BnHostapd
+{
+public:
+	Hostapd(hapd_interfaces* interfaces);
+	~Hostapd() override = default;
+
+	// Aidl methods exposed.
+	::ndk::ScopedAStatus addAccessPoint(
+	    const IfaceParams& iface_params, const NetworkParams& nw_params) override;
+	::ndk::ScopedAStatus removeAccessPoint(const std::string& iface_name) override;
+	::ndk::ScopedAStatus terminate() override;
+	::ndk::ScopedAStatus registerCallback(
+	    const std::shared_ptr<IHostapdCallback>& callback) override;
+	::ndk::ScopedAStatus forceClientDisconnect(
+	    const std::string& iface_name,
+	    const std::vector<uint8_t>& client_address,
+	    Ieee80211ReasonCode reason_code) override;
+	::ndk::ScopedAStatus setDebugParams(DebugLevel level) override;
+private:
+	// Corresponding worker functions for the AIDL methods.
+	::ndk::ScopedAStatus addAccessPointInternal(
+	    const IfaceParams& iface_params,
+	    const NetworkParams& nw_params);
+	::ndk::ScopedAStatus addSingleAccessPoint(
+	    const IfaceParams& IfaceParams,
+	    const ChannelParams& channelParams,
+	    const NetworkParams& nw_params,
+	    std::string br_name);
+	::ndk::ScopedAStatus addConcurrentAccessPoints(
+	    const IfaceParams& IfaceParams,
+	    const NetworkParams& nw_params);
+	::ndk::ScopedAStatus removeAccessPointInternal(const std::string& iface_name);
+	::ndk::ScopedAStatus registerCallbackInternal(
+	    const std::shared_ptr<IHostapdCallback>& callback);
+	::ndk::ScopedAStatus forceClientDisconnectInternal(
+	    const std::string& iface_name,
+	    const std::vector<uint8_t>& client_address,
+	    Ieee80211ReasonCode reason_code);
+	::ndk::ScopedAStatus setDebugParamsInternal(DebugLevel level);
+
+	// Raw pointer to the global structure maintained by the core.
+	struct hapd_interfaces* interfaces_;
+	// Callbacks registered.
+	std::vector<std::shared_ptr<IHostapdCallback>> callbacks_;
+	// Death notifier.
+	AIBinder_DeathRecipient* death_notifier_;
+	// Bridge and its managed interfaces.
+	std::map<std::string, std::vector<std::string>> br_interfaces_;
+	DISALLOW_COPY_AND_ASSIGN(Hostapd);
+};
+}  // namespace hostapd
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/hostapd/android.config b/hostapd/android.config
index fd3c1a1..3f539dd 100644
--- a/hostapd/android.config
+++ b/hostapd/android.config
@@ -219,9 +219,9 @@
 # either wpa_supplicant or hostapd are run.
 CONFIG_NO_RANDOM_POOL=y
 
-# Add support for Hidl control interface
+# Add support for Aidl control interface
 # Only applicable for Android platforms.
-CONFIG_CTRL_IFACE_HIDL=y
+CONFIG_CTRL_IFACE_AIDL=y
 
 # Enable support of Automatic Channel Selection
 CONFIG_ACS=y
diff --git a/hostapd/android.hardware.wifi.hostapd.xml b/hostapd/android.hardware.wifi.hostapd.xml
index c688d3e..eb91ee2 100644
--- a/hostapd/android.hardware.wifi.hostapd.xml
+++ b/hostapd/android.hardware.wifi.hostapd.xml
@@ -1,11 +1,6 @@
 <manifest version="1.0" type="device">
-    <hal format="hidl">
+    <hal format="aidl">
         <name>android.hardware.wifi.hostapd</name>
-        <transport>hwbinder</transport>
-        <version>1.3</version>
-        <interface>
-            <name>IHostapd</name>
-            <instance>default</instance>
-        </interface>
+        <fqname>IHostapd/default</fqname>
     </hal>
 </manifest>
diff --git a/hostapd/hidl/1.3/hidl.cpp b/hostapd/hidl/1.3/hidl.cpp
deleted file mode 100644
index 8481908..0000000
--- a/hostapd/hidl/1.3/hidl.cpp
+++ /dev/null
@@ -1,72 +0,0 @@
-/*
- * hidl interface for wpa_supplicant daemon
- * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2018, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include <hwbinder/IPCThreadState.h>
-#include <hidl/HidlTransportSupport.h>
-
-#include "hostapd.h"
-
-extern "C"
-{
-#include "hidl.h"
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "utils/includes.h"
-}
-
-using android::hardware::configureRpcThreadpool;
-using android::hardware::IPCThreadState;
-using android::hardware::wifi::hostapd::V1_3::IHostapd;
-using android::hardware::wifi::hostapd::V1_3::implementation::Hostapd;
-
-// This file is a bridge between the hostapd code written in 'C' and the HIDL
-// interface in C++. So, using "C" style static globals here!
-static int hidl_fd = -1;
-static android::sp<IHostapd> service;
-
-void hostapd_hidl_sock_handler(
-    int /* sock */, void * /* eloop_ctx */, void * /* sock_ctx */)
-{
-	IPCThreadState::self()->handlePolledCommands();
-}
-
-int hostapd_hidl_init(struct hapd_interfaces *interfaces)
-{
-	wpa_printf(MSG_DEBUG, "Initing hidl control");
-
-	IPCThreadState::self()->setupPolling(&hidl_fd);
-	if (hidl_fd < 0)
-		goto err;
-
-	wpa_printf(MSG_INFO, "Processing hidl events on FD %d", hidl_fd);
-	// Look for read events from the hidl socket in the eloop.
-	if (eloop_register_read_sock(
-		hidl_fd, hostapd_hidl_sock_handler, interfaces, NULL) < 0)
-		goto err;
-	service = new Hostapd(interfaces);
-	if (!service)
-		goto err;
-	if (service->registerAsService() != android::NO_ERROR)
-		goto err;
-	return 0;
-err:
-	hostapd_hidl_deinit(interfaces);
-	return -1;
-}
-
-void hostapd_hidl_deinit(struct hapd_interfaces *interfaces)
-{
-	wpa_printf(MSG_INFO, "Deiniting hidl control");
-	// Before hidl init, make sure call terminate to clear callback_
-	service->terminate();
-	eloop_unregister_read_sock(hidl_fd);
-	IPCThreadState::shutdown();
-	hidl_fd = -1;
-	service.clear();
-}
diff --git a/hostapd/hidl/1.3/hidl.h b/hostapd/hidl/1.3/hidl.h
deleted file mode 100644
index 5decf64..0000000
--- a/hostapd/hidl/1.3/hidl.h
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * hidl interface for wpa_supplicant daemon
- * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2018, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef HOSTAPD_HIDL_HIDL_H
-#define HOSTAPD_HIDL_HIDL_H
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif  // _cplusplus
-#include "ap/hostapd.h"
-
-/**
- * This is the hidl RPC interface entry point to the hostapd core.
- * This initializes the hidl driver & IHostapd instance.
- */
-int hostapd_hidl_init(struct hapd_interfaces *interfaces);
-void hostapd_hidl_deinit(struct hapd_interfaces *interfaces);
-
-#ifdef __cplusplus
-}
-#endif  // _cplusplus
-
-#endif  // HOSTAPD_HIDL_HIDL_H
diff --git a/hostapd/hidl/1.3/hidl_return_util.h b/hostapd/hidl/1.3/hidl_return_util.h
deleted file mode 100644
index 6d50348..0000000
--- a/hostapd/hidl/1.3/hidl_return_util.h
+++ /dev/null
@@ -1,43 +0,0 @@
-/*
- * hidl interface for wpa_hostapd daemon
- * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2018, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef HIDL_RETURN_UTIL_H_
-#define HIDL_RETURN_UTIL_H_
-
-#include <functional>
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace hostapd {
-namespace V1_3 {
-namespace implementation {
-namespace hidl_return_util {
-
-/**
- * These utility functions are used to invoke a method on the provided
- * HIDL interface object.
- */
-// Use for HIDL methods which return only an instance of HostapdStatus.
-template <typename ObjT, typename WorkFuncT, typename StatusT, typename... Args>
-Return<void> call(
-    ObjT* obj, WorkFuncT&& work,
-    const std::function<void(const StatusT&)>& hidl_cb, Args&&... args)
-{
-	hidl_cb((obj->*work)(std::forward<Args>(args)...));
-	return Void();
-}
-}  // namespace hidl_return_util
-}  // namespace implementation
-}  // namespace V1_3
-}  // namespace hostapd
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-#endif  // HIDL_RETURN_UTIL_H_
diff --git a/hostapd/hidl/1.3/hostapd.cpp b/hostapd/hidl/1.3/hostapd.cpp
deleted file mode 100644
index 6add761..0000000
--- a/hostapd/hidl/1.3/hostapd.cpp
+++ /dev/null
@@ -1,1034 +0,0 @@
-/*
- * hidl interface for wpa_hostapd daemon
- * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2018, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-#include <iomanip>
-#include <sstream>
-#include <string>
-#include <vector>
-#include <net/if.h>
-#include <sys/socket.h>
-#include <linux/if_bridge.h>
-
-
-#include <android-base/file.h>
-#include <android-base/stringprintf.h>
-#include <android-base/unique_fd.h>
-
-#include "hostapd.h"
-#include "hidl_return_util.h"
-
-extern "C"
-{
-#include "common/wpa_ctrl.h"
-#include "drivers/linux_ioctl.h"
-}
-
-// The HIDL implementation for hostapd creates a hostapd.conf dynamically for
-// each interface. This file can then be used to hook onto the normal config
-// file parsing logic in hostapd code.  Helps us to avoid duplication of code
-// in the HIDL interface.
-// TOOD(b/71872409): Add unit tests for this.
-namespace {
-constexpr char kConfFileNameFmt[] = "/data/vendor/wifi/hostapd/hostapd_%s.conf";
-
-using android::base::RemoveFileIfExists;
-using android::base::StringPrintf;
-using android::base::WriteStringToFile;
-using android::hardware::wifi::hostapd::V1_3::IHostapd;
-using android::hardware::wifi::hostapd::V1_3::Generation;
-using android::hardware::wifi::hostapd::V1_3::Bandwidth;
-
-#define MAX_PORTS 1024
-bool GetInterfacesInBridge(std::string br_name,
-                           std::vector<std::string>* interfaces) {
-	android::base::unique_fd sock(socket(PF_INET, SOCK_DGRAM | SOCK_CLOEXEC, 0));
-	if (sock.get() < 0) {
-		wpa_printf(MSG_ERROR, "Failed to create sock (%s) in %s",
-			strerror(errno), __FUNCTION__);
-		return false;
-	}
-
-	struct ifreq request;
-	int i, ifindices[MAX_PORTS];
-	char if_name[IFNAMSIZ];
-	unsigned long args[3];
-
-	memset(ifindices, 0, MAX_PORTS * sizeof(int));
-
-	args[0] = BRCTL_GET_PORT_LIST;
-	args[1] = (unsigned long) ifindices;
-	args[2] = MAX_PORTS;
-
-	strlcpy(request.ifr_name, br_name.c_str(), IFNAMSIZ);
-	request.ifr_data = (char *)args;
-
-	if (ioctl(sock.get(), SIOCDEVPRIVATE, &request) < 0) {
-		wpa_printf(MSG_ERROR, "Failed to ioctl SIOCDEVPRIVATE in %s",
-			__FUNCTION__);
-		return false;
-	}
-
-	for (i = 0; i < MAX_PORTS; i ++) {
-		memset(if_name, 0, IFNAMSIZ);
-		if (ifindices[i] == 0 || !if_indextoname(ifindices[i], if_name)) {
-			continue;
-		}
-		interfaces->push_back(if_name);
-	}
-	return true;
-}
-
-std::string WriteHostapdConfig(
-    const std::string& interface_name, const std::string& config)
-{
-	const std::string file_path =
-	    StringPrintf(kConfFileNameFmt, interface_name.c_str());
-	if (WriteStringToFile(
-		config, file_path, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP,
-		getuid(), getgid())) {
-		return file_path;
-	}
-	// Diagnose failure
-	int error = errno;
-	wpa_printf(
-	    MSG_ERROR, "Cannot write hostapd config to %s, error: %s",
-	    file_path.c_str(), strerror(error));
-	struct stat st;
-	int result = stat(file_path.c_str(), &st);
-	if (result == 0) {
-		wpa_printf(
-		    MSG_ERROR, "hostapd config file uid: %d, gid: %d, mode: %d",
-		    st.st_uid, st.st_gid, st.st_mode);
-	} else {
-		wpa_printf(
-		    MSG_ERROR,
-		    "Error calling stat() on hostapd config file: %s",
-		    strerror(errno));
-	}
-	return "";
-}
-
-/*
- * Get the op_class for a channel/band
- * The logic here is based on Table E-4 in the 802.11 Specification
- */
-int getOpClassForChannel(int channel, int band, bool support11n, bool support11ac) {
-	// 2GHz Band
-	if ((band & IHostapd::BandMask::BAND_2_GHZ) != 0) {
-		if (channel == 14) {
-			return 82;
-		}
-		if (channel >= 1 && channel <= 13) {
-			if (!support11n) {
-				//20MHz channel
-				return 81;
-			}
-			if (channel <= 9) {
-				// HT40 with secondary channel above primary
-				return 83;
-			}
-			// HT40 with secondary channel below primary
-			return 84;
-		}
-		// Error
-		return 0;
-	}
-
-	// 5GHz Band
-	if ((band & IHostapd::BandMask::BAND_5_GHZ) != 0) {
-		if (support11ac) {
-			switch (channel) {
-				case 42:
-				case 58:
-				case 106:
-				case 122:
-				case 138:
-				case 155:
-					// 80MHz channel
-					return 128;
-				case 50:
-				case 114:
-					// 160MHz channel
-					return 129;
-			}
-		}
-
-		if (!support11n) {
-			if (channel >= 36 && channel <= 48) {
-				return 115;
-			}
-			if (channel >= 52 && channel <= 64) {
-				return 118;
-			}
-			if (channel >= 100 && channel <= 144) {
-				return 121;
-			}
-			if (channel >= 149 && channel <= 161) {
-				return 124;
-			}
-			if (channel >= 165 && channel <= 169) {
-				return 125;
-			}
-		} else {
-			switch (channel) {
-				case 36:
-				case 44:
-					// HT40 with secondary channel above primary
-					return 116;
-				case 40:
-				case 48:
-					// HT40 with secondary channel below primary
-					return 117;
-				case 52:
-				case 60:
-					// HT40 with secondary channel above primary
-					return  119;
-				case 56:
-				case 64:
-					// HT40 with secondary channel below primary
-					return 120;
-				case 100:
-				case 108:
-				case 116:
-				case 124:
-				case 132:
-				case 140:
-					// HT40 with secondary channel above primary
-					return 122;
-				case 104:
-				case 112:
-				case 120:
-				case 128:
-				case 136:
-				case 144:
-					// HT40 with secondary channel below primary
-					return 123;
-				case 149:
-				case 157:
-					// HT40 with secondary channel above primary
-					return 126;
-				case 153:
-				case 161:
-					// HT40 with secondary channel below primary
-					return 127;
-			}
-		}
-		// Error
-		return 0;
-	}
-
-	// 6GHz Band
-	if ((band & IHostapd::BandMask::BAND_6_GHZ) != 0) {
-		// Channels 1, 5. 9, 13, ...
-		if ((channel & 0x03) == 0x01) {
-			// 20MHz channel
-			return 131;
-		}
-		// Channels 3, 11, 19, 27, ...
-		if ((channel & 0x07) == 0x03) {
-			// 40MHz channel
-			return 132;
-		}
-		// Channels 7, 23, 39, 55, ...
-		if ((channel & 0x0F) == 0x07) {
-			// 80MHz channel
-			return 133;
-		}
-		// Channels 15, 47, 69, ...
-		if ((channel & 0x1F) == 0x0F) {
-			// 160MHz channel
-			return 134;
-		}
-		if (channel == 2) {
-			// 20MHz channel
-			return 136;
-		}
-		// Error
-		return 0;
-	}
-
-	if ((band & IHostapd::BandMask::BAND_60_GHZ) != 0) {
-		if (1 <= channel && channel <= 8) {
-			return 180;
-		} else if (9 <= channel && channel <= 15) {
-			return 181;
-		} else if (17 <= channel && channel <= 22) {
-			return 182;
-		} else if (25 <= channel && channel <= 29) {
-			return 183;
-		}
-		// Error
-		return 0;
-	}
-
-	return 0;
-}
-
-bool validatePassphrase(int passphrase_len, int min_len, int max_len)
-{
-	if (min_len != -1 && passphrase_len < min_len) return false;
-	if (max_len != -1 && passphrase_len > max_len) return false;
-	return true;
-}
-
-std::string CreateHostapdConfig(
-    const android::hardware::wifi::hostapd::V1_3::IHostapd::IfaceParams& iface_params,
-    const android::hardware::wifi::hostapd::V1_3::IHostapd::ChannelParams& channelParams,
-    const IHostapd::NetworkParams& nw_params,
-    const std::string br_name)
-{
-	if (nw_params.V1_2.V1_0.ssid.size() >
-	    static_cast<uint32_t>(
-		IHostapd::ParamSizeLimits::SSID_MAX_LEN_IN_BYTES)) {
-		wpa_printf(
-		    MSG_ERROR, "Invalid SSID size: %zu", nw_params.V1_2.V1_0.ssid.size());
-		return "";
-	}
-
-	// SSID string
-	std::stringstream ss;
-	ss << std::hex;
-	ss << std::setfill('0');
-	for (uint8_t b : nw_params.V1_2.V1_0.ssid) {
-		ss << std::setw(2) << static_cast<unsigned int>(b);
-	}
-	const std::string ssid_as_string = ss.str();
-
-	// Encryption config string
-	uint32_t band = 0;
-	band |= channelParams.bandMask;
-	bool is_6Ghz_band_only = band == static_cast<uint32_t>(IHostapd::BandMask::BAND_6_GHZ);
-	bool is_60Ghz_band_only = band == static_cast<uint32_t>(IHostapd::BandMask::BAND_60_GHZ);
-	std::string encryption_config_as_string;
-	switch (nw_params.V1_2.encryptionType) {
-	case IHostapd::EncryptionType::NONE:
-		// no security params
-		break;
-	case IHostapd::EncryptionType::WPA:
-		if (!validatePassphrase(
-		    nw_params.V1_2.passphrase.size(),
-		    static_cast<uint32_t>(IHostapd::ParamSizeLimits::
-				WPA2_PSK_PASSPHRASE_MIN_LEN_IN_BYTES),
-		    static_cast<uint32_t>(IHostapd::ParamSizeLimits::
-				WPA2_PSK_PASSPHRASE_MAX_LEN_IN_BYTES))) {
-			return "";
-		}
-		encryption_config_as_string = StringPrintf(
-		    "wpa=3\n"
-		    "wpa_pairwise=%s\n"
-		    "wpa_passphrase=%s",
-		    is_60Ghz_band_only ? "GCMP" : "TKIP CCMP",
-		    nw_params.V1_2.passphrase.c_str());
-		break;
-	case IHostapd::EncryptionType::WPA2:
-		if (!validatePassphrase(
-		    nw_params.V1_2.passphrase.size(),
-		    static_cast<uint32_t>(IHostapd::ParamSizeLimits::
-				WPA2_PSK_PASSPHRASE_MIN_LEN_IN_BYTES),
-		    static_cast<uint32_t>(IHostapd::ParamSizeLimits::
-				WPA2_PSK_PASSPHRASE_MAX_LEN_IN_BYTES))) {
-			return "";
-		}
-		encryption_config_as_string = StringPrintf(
-		    "wpa=2\n"
-		    "rsn_pairwise=%s\n"
-		    "wpa_passphrase=%s",
-		    is_60Ghz_band_only ? "GCMP" : "CCMP",
-		    nw_params.V1_2.passphrase.c_str());
-		break;
-	case IHostapd::EncryptionType::WPA3_SAE_TRANSITION:
-		if (!validatePassphrase(
-		    nw_params.V1_2.passphrase.size(),
-		    static_cast<uint32_t>(IHostapd::ParamSizeLimits::
-				WPA2_PSK_PASSPHRASE_MIN_LEN_IN_BYTES),
-		    static_cast<uint32_t>(IHostapd::ParamSizeLimits::
-				WPA2_PSK_PASSPHRASE_MAX_LEN_IN_BYTES))) {
-			return "";
-		}
-		encryption_config_as_string = StringPrintf(
-		    "wpa=2\n"
-		    "rsn_pairwise=%s\n"
-		    "wpa_key_mgmt=WPA-PSK SAE\n"
-		    "ieee80211w=1\n"
-		    "sae_require_mfp=1\n"
-		    "wpa_passphrase=%s\n"
-		    "sae_password=%s",
-		    is_60Ghz_band_only ? "GCMP" : "CCMP",
-		    nw_params.V1_2.passphrase.c_str(),
-		    nw_params.V1_2.passphrase.c_str());
-		break;
-	case IHostapd::EncryptionType::WPA3_SAE:
-		if (!validatePassphrase(nw_params.V1_2.passphrase.size(), 1, -1)) {
-			return "";
-		}
-		encryption_config_as_string = StringPrintf(
-		    "wpa=2\n"
-		    "rsn_pairwise=%s\n"
-		    "wpa_key_mgmt=SAE\n"
-		    "ieee80211w=2\n"
-		    "sae_require_mfp=2\n"
-		    "sae_pwe=%d\n"
-		    "sae_password=%s",
-		    is_60Ghz_band_only ? "GCMP" : "CCMP",
-		    is_6Ghz_band_only ? 1 : 2,
-		    nw_params.V1_2.passphrase.c_str());
-		break;
-	default:
-		wpa_printf(MSG_ERROR, "Unknown encryption type");
-		return "";
-	}
-
-	std::string channel_config_as_string;
-	bool isFirst = true;
-	if (channelParams.enableAcs) {
-		std::string freqList_as_string;
-		for (const auto &range :
-		    channelParams.V1_2.acsChannelFreqRangesMhz) {
-			if (!isFirst) {
-				freqList_as_string += ",";
-			}
-			isFirst = false;
-
-			if (range.start != range.end) {
-				freqList_as_string +=
-				    StringPrintf("%d-%d", range.start, range.end);
-			} else {
-				freqList_as_string += StringPrintf("%d", range.start);
-			}
-		}
-		channel_config_as_string = StringPrintf(
-		    "channel=0\n"
-		    "acs_exclude_dfs=%d\n"
-		    "freqlist=%s",
-		    iface_params.V1_2.V1_1.V1_0.channelParams.acsShouldExcludeDfs,
-		    freqList_as_string.c_str());
-	} else {
-		int op_class = getOpClassForChannel(
-		    channelParams.channel,
-		    band,
-		    iface_params.V1_2.V1_1.V1_0.hwModeParams.enable80211N,
-		    iface_params.V1_2.V1_1.V1_0.hwModeParams.enable80211AC);
-		channel_config_as_string = StringPrintf(
-		    "channel=%d\n"
-		    "op_class=%d",
-		    channelParams.channel, op_class);
-	}
-
-	std::string hw_mode_as_string;
-	std::string ht_cap_vht_oper_chwidth_as_string;
-	std::string enable_edmg_as_string;
-	std::string edmg_channel_as_string;
-	bool is_60Ghz_used = false;
-
-	if (((band & IHostapd::BandMask::BAND_60_GHZ) != 0)) {
-		hw_mode_as_string = "hw_mode=ad";
-		if (iface_params.hwModeParams.enableEdmg) {
-			enable_edmg_as_string = "enable_edmg=1";
-			edmg_channel_as_string = StringPrintf(
-				"edmg_channel=%d",
-				channelParams.channel);
-		}
-		is_60Ghz_used = true;
-	} else if ((band & IHostapd::BandMask::BAND_2_GHZ) != 0) {
-		if (((band & IHostapd::BandMask::BAND_5_GHZ) != 0)
-		    || ((band & IHostapd::BandMask::BAND_6_GHZ) != 0)) {
-			hw_mode_as_string = "hw_mode=any";
-			if (iface_params.V1_2.V1_1.V1_0.hwModeParams.enable80211AC) {
-				ht_cap_vht_oper_chwidth_as_string =
-				    "ht_capab=[HT40+]\n"
-				    "vht_oper_chwidth=1";
-			}
-		} else {
-			hw_mode_as_string = "hw_mode=g";
-		}
-	} else if (((band & IHostapd::BandMask::BAND_5_GHZ) != 0)
-		    || ((band & IHostapd::BandMask::BAND_6_GHZ) != 0)) {
-			hw_mode_as_string = "hw_mode=a";
-		if (iface_params.V1_2.V1_1.V1_0.hwModeParams.enable80211AC) {
-			ht_cap_vht_oper_chwidth_as_string =
-			    "ht_capab=[HT40+]\n"
-			    "vht_oper_chwidth=1";
-		}
-	} else {
-		wpa_printf(MSG_ERROR, "Invalid band");
-		return "";
-	}
-
-	std::string he_params_as_string;
-#ifdef CONFIG_IEEE80211AX
-	if (iface_params.V1_2.hwModeParams.enable80211AX && !is_60Ghz_used) {
-		he_params_as_string = StringPrintf(
-		    "ieee80211ax=1\n"
-		    "he_oper_chwidth=1\n"
-		    "he_su_beamformer=%d\n"
-		    "he_su_beamformee=%d\n"
-		    "he_mu_beamformer=%d\n"
-		    "he_twt_required=%d\n",
-		    iface_params.V1_2.hwModeParams.enableHeSingleUserBeamformer ? 1 : 0,
-		    iface_params.V1_2.hwModeParams.enableHeSingleUserBeamformee ? 1 : 0,
-		    iface_params.V1_2.hwModeParams.enableHeMultiUserBeamformer ? 1 : 0,
-		    iface_params.V1_2.hwModeParams.enableHeTargetWakeTime ? 1 : 0);
-	} else {
-		he_params_as_string = "ieee80211ax=0";
-	}
-#endif /* CONFIG_IEEE80211AX */
-
-#ifdef CONFIG_INTERWORKING
-	std::string access_network_params_as_string;
-	if (nw_params.isMetered) {
-		access_network_params_as_string = StringPrintf(
-		    "interworking=1\n"
-		    "access_network_type=2\n"); // CHARGEABLE_PUBLIC_NETWORK
-	} else {
-	    access_network_params_as_string = StringPrintf(
-		    "interworking=0\n");
-	}
-#endif /* CONFIG_INTERWORKING */
-
-	std::string bridge_as_string;
-	if (!br_name.empty()) {
-		bridge_as_string = StringPrintf("bridge=%s", br_name.c_str());
-	}
-
-	return StringPrintf(
-	    "interface=%s\n"
-	    "driver=nl80211\n"
-	    "ctrl_interface=/data/vendor/wifi/hostapd/ctrl\n"
-	    // ssid2 signals to hostapd that the value is not a literal value
-	    // for use as a SSID.  In this case, we're giving it a hex
-	    // std::string and hostapd needs to expect that.
-	    "ssid2=%s\n"
-	    "%s\n"
-	    "ieee80211n=%d\n"
-	    "ieee80211ac=%d\n"
-	    "%s\n"
-	    "%s\n"
-	    "%s\n"
-	    "ignore_broadcast_ssid=%d\n"
-	    "wowlan_triggers=any\n"
-#ifdef CONFIG_INTERWORKING
-	    "%s\n"
-#endif /* CONFIG_INTERWORKING */
-	    "%s\n"
-	    "%s\n"
-	    "%s\n"
-	    "%s\n",
-	    iface_params.V1_2.V1_1.V1_0.ifaceName.c_str(), ssid_as_string.c_str(),
-	    channel_config_as_string.c_str(),
-	    iface_params.V1_2.V1_1.V1_0.hwModeParams.enable80211N ? 1 : 0,
-	    iface_params.V1_2.V1_1.V1_0.hwModeParams.enable80211AC ? 1 : 0,
-	    he_params_as_string.c_str(),
-	    hw_mode_as_string.c_str(), ht_cap_vht_oper_chwidth_as_string.c_str(),
-	    nw_params.V1_2.V1_0.isHidden ? 1 : 0,
-#ifdef CONFIG_INTERWORKING
-	    access_network_params_as_string.c_str(),
-#endif /* CONFIG_INTERWORKING */
-	    encryption_config_as_string.c_str(),
-	    bridge_as_string.c_str(),
-	    enable_edmg_as_string.c_str(),
-	    edmg_channel_as_string.c_str());
-}
-
-Generation getGeneration(hostapd_hw_modes *current_mode)
-{
-	wpa_printf(MSG_DEBUG, "getGeneration hwmode=%d, ht_enabled=%d,"
-		   " vht_enabled=%d, he_supported=%d",
-		   current_mode->mode, current_mode->ht_capab != 0,
-		   current_mode->vht_capab != 0, current_mode->he_capab->he_supported);
-	switch (current_mode->mode) {
-	case HOSTAPD_MODE_IEEE80211B:
-		return Generation::WIFI_STANDARD_LEGACY;
-	case HOSTAPD_MODE_IEEE80211G:
-		return current_mode->ht_capab == 0 ?
-		       Generation::WIFI_STANDARD_LEGACY : Generation::WIFI_STANDARD_11N;
-	case HOSTAPD_MODE_IEEE80211A:
-		if (current_mode->he_capab->he_supported) {
-			return Generation::WIFI_STANDARD_11AX;
-		}
-		return current_mode->vht_capab == 0 ?
-		       Generation::WIFI_STANDARD_11N : Generation::WIFI_STANDARD_11AC;
-	case HOSTAPD_MODE_IEEE80211AD:
-		return Generation::WIFI_STANDARD_11AD;
-	default:
-		return Generation::WIFI_STANDARD_UNKNOWN;
-	}
-}
-
-Bandwidth getBandwidth(struct hostapd_config *iconf)
-{
-	wpa_printf(MSG_DEBUG, "getBandwidth %d, isHT=%d, isHT40=%d",
-		   iconf->vht_oper_chwidth, iconf->ieee80211n,
-		   iconf->secondary_channel);
-	switch (iconf->vht_oper_chwidth) {
-	case CHANWIDTH_80MHZ:
-		return Bandwidth::WIFI_BANDWIDTH_80;
-	case CHANWIDTH_80P80MHZ:
-		return Bandwidth::WIFI_BANDWIDTH_80P80;
-		break;
-	case CHANWIDTH_160MHZ:
-		return Bandwidth::WIFI_BANDWIDTH_160;
-		break;
-	case CHANWIDTH_USE_HT:
-		if (iconf->ieee80211n) {
-			return iconf->secondary_channel != 0 ?
-				Bandwidth::WIFI_BANDWIDTH_40 : Bandwidth::WIFI_BANDWIDTH_20;
-		}
-		return Bandwidth::WIFI_BANDWIDTH_20_NOHT;
-	case CHANWIDTH_2160MHZ:
-		return Bandwidth::WIFI_BANDWIDTH_2160;
-	case CHANWIDTH_4320MHZ:
-		return Bandwidth::WIFI_BANDWIDTH_4320;
-	case CHANWIDTH_6480MHZ:
-		return Bandwidth::WIFI_BANDWIDTH_6480;
-	case CHANWIDTH_8640MHZ:
-		return Bandwidth::WIFI_BANDWIDTH_8640;
-	default:
-		return Bandwidth::WIFI_BANDWIDTH_INVALID;
-	}
-}
-
-bool forceStaDisconnection(struct hostapd_data* hapd,
-			   const std::array<uint8_t, 6>& client_address,
-			   const uint16_t reason_code) {
-	struct sta_info *sta;
-	for (sta = hapd->sta_list; sta; sta = sta->next) {
-		int res;
-		res = memcmp(sta->addr, client_address.data(), ETH_ALEN);
-		if (res == 0) {
-			wpa_printf(MSG_INFO, "Force client:" MACSTR " disconnect with reason: %d",
-			    MAC2STR(client_address.data()), reason_code);
-			ap_sta_disconnect(hapd, sta, sta->addr, reason_code);
-			return true;
-		}
-	}
-	return false;
-}
-
-// hostapd core functions accept "C" style function pointers, so use global
-// functions to pass to the hostapd core function and store the corresponding
-// std::function methods to be invoked.
-//
-// NOTE: Using the pattern from the vendor HAL (wifi_legacy_hal.cpp).
-//
-// Callback to be invoked once setup is complete
-std::function<void(struct hostapd_data*)> on_setup_complete_internal_callback;
-void onAsyncSetupCompleteCb(void* ctx)
-{
-	struct hostapd_data* iface_hapd = (struct hostapd_data*)ctx;
-	if (on_setup_complete_internal_callback) {
-		on_setup_complete_internal_callback(iface_hapd);
-		// Invalidate this callback since we don't want this firing
-		// again in single AP mode.
-		if (strlen(iface_hapd->conf->bridge) > 0) {
-		    on_setup_complete_internal_callback = nullptr;
-		}
-	}
-}
-
-// Callback to be invoked on hotspot client connection/disconnection
-std::function<void(struct hostapd_data*, const u8 *mac_addr, int authorized,
-		   const u8 *p2p_dev_addr)> on_sta_authorized_internal_callback;
-void onAsyncStaAuthorizedCb(void* ctx, const u8 *mac_addr, int authorized,
-			    const u8 *p2p_dev_addr)
-{
-	struct hostapd_data* iface_hapd = (struct hostapd_data*)ctx;
-	if (on_sta_authorized_internal_callback) {
-		on_sta_authorized_internal_callback(iface_hapd, mac_addr,
-			authorized, p2p_dev_addr);
-	}
-}
-
-std::function<void(struct hostapd_data*, int level,
-                   enum wpa_msg_type type, const char *txt,
-                   size_t len)> on_wpa_msg_internal_callback;
-
-void onAsyncWpaEventCb(void *ctx, int level,
-                   enum wpa_msg_type type, const char *txt,
-                   size_t len)
-{
-	struct hostapd_data* iface_hapd = (struct hostapd_data*)ctx;
-	if (on_wpa_msg_internal_callback) {
-		on_wpa_msg_internal_callback(iface_hapd, level,
-					       type, txt, len);
-	}
-}
-
-
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace hostapd {
-namespace V1_3 {
-namespace implementation {
-using hidl_return_util::call;
-using namespace android::hardware::wifi::hostapd::V1_0;
-
-Hostapd::Hostapd(struct hapd_interfaces* interfaces)
-    : interfaces_(interfaces), death_notifier_(sp<DeathNotifier>::make())
-{}
-
-Return<void> Hostapd::addAccessPoint(
-    const V1_0::IHostapd::IfaceParams& iface_params,
-    const V1_0::IHostapd::NetworkParams& nw_params, addAccessPoint_cb _hidl_cb)
-{
-	return call(
-	    this, &Hostapd::addAccessPointInternal, _hidl_cb, iface_params,
-	    nw_params);
-}
-
-Return<void> Hostapd::addAccessPoint_1_1(
-    const V1_1::IHostapd::IfaceParams& iface_params,
-    const V1_0::IHostapd::NetworkParams& nw_params, addAccessPoint_cb _hidl_cb)
-{
-	return call(
-	    this, &Hostapd::addAccessPointInternal_1_1, _hidl_cb, iface_params,
-	    nw_params);
-}
-
-Return<void> Hostapd::addAccessPoint_1_2(
-    const V1_2::IHostapd::IfaceParams& iface_params,
-    const V1_2::IHostapd::NetworkParams& nw_params,
-    addAccessPoint_1_2_cb _hidl_cb)
-{
-	return call(
-	    this, &Hostapd::addAccessPointInternal_1_2, _hidl_cb, iface_params,
-	    nw_params);
-}
-
-Return<void> Hostapd::addAccessPoint_1_3(
-    const V1_3::IHostapd::IfaceParams& iface_params,
-    const V1_3::IHostapd::NetworkParams& nw_params,
-    addAccessPoint_1_3_cb _hidl_cb)
-{
-        return call(
-            this, &Hostapd::addAccessPointInternal_1_3, _hidl_cb, iface_params,
-            nw_params);
-}
-
-Return<void> Hostapd::removeAccessPoint(
-    const hidl_string& iface_name, removeAccessPoint_cb _hidl_cb)
-{
-	return call(
-	    this, &Hostapd::removeAccessPointInternal, _hidl_cb, iface_name);
-}
-
-Return<void> Hostapd::terminate()
-{
-	wpa_printf(MSG_INFO, "Terminating...");
-	// Clear the callback to avoid IPCThreadState shutdown during the
-	// callback event.
-	callbacks_.clear();
-	eloop_terminate();
-	return Void();
-}
-
-Return<void> Hostapd::registerCallback(
-    const sp<V1_1::IHostapdCallback>& callback, registerCallback_cb _hidl_cb)
-{
-	return call(
-	    this, &Hostapd::registerCallbackInternal, _hidl_cb, callback);
-}
-
-Return<void> Hostapd::registerCallback_1_3(
-    const sp<V1_3::IHostapdCallback>& callback, registerCallback_1_3_cb _hidl_cb)
-{
-	return call(
-	    this, &Hostapd::registerCallbackInternal_1_3, _hidl_cb, callback);
-}
-
-Return<void> Hostapd::forceClientDisconnect(
-    const hidl_string& iface_name, const hidl_array<uint8_t, 6>& client_address,
-    V1_2::Ieee80211ReasonCode reason_code, forceClientDisconnect_cb _hidl_cb)
-{
-	return call(
-	    this, &Hostapd::forceClientDisconnectInternal, _hidl_cb, iface_name,
-	    client_address, reason_code);
-}
-
-Return<void> Hostapd::setDebugParams(
-     V1_2::DebugLevel level, setDebugParams_cb _hidl_cb)
-{
-	return call(
-	    this, &Hostapd::setDebugParamsInternal, _hidl_cb, level);
-}
-
-V1_0::HostapdStatus Hostapd::addAccessPointInternal(
-    const V1_0::IHostapd::IfaceParams& iface_params,
-    const V1_0::IHostapd::NetworkParams& nw_params)
-{
-	return {V1_0::HostapdStatusCode::FAILURE_UNKNOWN, ""};
-}
-
-V1_0::HostapdStatus Hostapd::addAccessPointInternal_1_1(
-    const V1_1::IHostapd::IfaceParams& iface_params,
-    const V1_1::IHostapd::NetworkParams& nw_params)
-{
-	return {V1_0::HostapdStatusCode::FAILURE_UNKNOWN, ""};
-}
-
-V1_2::HostapdStatus Hostapd::addAccessPointInternal_1_2(
-    const V1_2::IHostapd::IfaceParams& iface_params,
-    const V1_2::IHostapd::NetworkParams& nw_params) {
-	return {V1_2::HostapdStatusCode::FAILURE_UNKNOWN, ""};
-}
-
-V1_2::HostapdStatus Hostapd::addAccessPointInternal_1_3(
-    const V1_3::IHostapd::IfaceParams& iface_params,
-    const V1_3::IHostapd::NetworkParams& nw_params)
-{
-	int channelParamsListSize = iface_params.channelParamsList.size();
-	if (channelParamsListSize == 1) {
-		// Single AP
-		wpa_printf(MSG_INFO, "AddSingleAccessPoint, iface=%s",
-		    iface_params.V1_2.V1_1.V1_0.ifaceName.c_str());
-		return addSingleAccessPoint(iface_params, iface_params.channelParamsList[0],
-		    nw_params, "");
-	} else if (channelParamsListSize == 2) {
-		// Concurrent APs
-		wpa_printf(MSG_INFO, "AddDualAccessPoint, iface=%s",
-		    iface_params.V1_2.V1_1.V1_0.ifaceName.c_str());
-		return addConcurrentAccessPoints(iface_params, nw_params);
-	}
-	return {V1_2::HostapdStatusCode::FAILURE_ARGS_INVALID, ""};
-}
-
-V1_2::HostapdStatus Hostapd::addConcurrentAccessPoints(
-    const V1_3::IHostapd::IfaceParams& iface_params, const V1_3::IHostapd::NetworkParams& nw_params)
-{
-	int channelParamsListSize = iface_params.channelParamsList.size();
-	// Get available interfaces in bridge
-	std::vector<std::string> managed_interfaces;
-	std::string br_name = StringPrintf(
-	    "%s", iface_params.V1_2.V1_1.V1_0.ifaceName.c_str());
-	if (!GetInterfacesInBridge(br_name, &managed_interfaces)) {
-		return {V1_2::HostapdStatusCode::FAILURE_UNKNOWN,
-		    "Get interfaces in bridge failed."};
-	}
-	if (managed_interfaces.size() < channelParamsListSize) {
-		return {V1_2::HostapdStatusCode::FAILURE_UNKNOWN,
-		    "Available interfaces less than requested bands"};
-	}
-	// start BSS on specified bands
-	for (std::size_t i = 0; i < channelParamsListSize; i ++) {
-		V1_3::IHostapd::IfaceParams iface_params_new = iface_params;
-		iface_params_new.V1_2.V1_1.V1_0.ifaceName = managed_interfaces[i];
-		V1_2::HostapdStatus status = addSingleAccessPoint(
-		    iface_params_new, iface_params.channelParamsList[i], nw_params, br_name);
-		if (status.code != V1_2::HostapdStatusCode::SUCCESS) {
-			wpa_printf(MSG_ERROR, "Failed to addAccessPoint %s",
-				   managed_interfaces[i].c_str());
-			return status;
-		}
-	}
-	// Save bridge interface info
-	br_interfaces_[br_name] = managed_interfaces;
-	return {V1_2::HostapdStatusCode::SUCCESS, ""};
-}
-
-V1_2::HostapdStatus Hostapd::addSingleAccessPoint(
-    const V1_3::IHostapd::IfaceParams& iface_params,
-    const V1_3::IHostapd::ChannelParams& channelParams,
-    const V1_3::IHostapd::NetworkParams& nw_params,
-    const std::string br_name)
-{
-	if (hostapd_get_iface(interfaces_, iface_params.V1_2.V1_1.V1_0.ifaceName.c_str())) {
-		wpa_printf(
-		    MSG_ERROR, "Interface %s already present",
-		    iface_params.V1_2.V1_1.V1_0.ifaceName.c_str());
-		return {V1_2::HostapdStatusCode::FAILURE_IFACE_EXISTS, ""};
-	}
-	const auto conf_params = CreateHostapdConfig(iface_params, channelParams, nw_params, br_name);
-	if (conf_params.empty()) {
-		wpa_printf(MSG_ERROR, "Failed to create config params");
-		return {V1_2::HostapdStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	const auto conf_file_path =
-	    WriteHostapdConfig(iface_params.V1_2.V1_1.V1_0.ifaceName, conf_params);
-	if (conf_file_path.empty()) {
-		wpa_printf(MSG_ERROR, "Failed to write config file");
-		return {V1_2::HostapdStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	std::string add_iface_param_str = StringPrintf(
-	    "%s config=%s", iface_params.V1_2.V1_1.V1_0.ifaceName.c_str(),
-	    conf_file_path.c_str());
-	std::vector<char> add_iface_param_vec(
-	    add_iface_param_str.begin(), add_iface_param_str.end() + 1);
-	if (hostapd_add_iface(interfaces_, add_iface_param_vec.data()) < 0) {
-		wpa_printf(
-		    MSG_ERROR, "Adding interface %s failed",
-		    add_iface_param_str.c_str());
-		return {V1_2::HostapdStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	struct hostapd_data* iface_hapd =
-	    hostapd_get_iface(interfaces_, iface_params.V1_2.V1_1.V1_0.ifaceName.c_str());
-	WPA_ASSERT(iface_hapd != nullptr && iface_hapd->iface != nullptr);
-	// Register the setup complete callbacks
-	on_setup_complete_internal_callback =
-	    [this](struct hostapd_data* iface_hapd) {
-		    wpa_printf(
-			MSG_INFO, "AP interface setup completed - state %s",
-			hostapd_state_text(iface_hapd->iface->state));
-		    if (iface_hapd->iface->state == HAPD_IFACE_DISABLED) {
-			    // Invoke the failure callback on all registered
-			    // clients.
-			    for (const auto& callback : callbacks_) {
-				    callback->onFailure(
-					iface_hapd->conf->iface);
-			    }
-		    }
-	    };
-
-	// Rgegister for new client connect/disconnect indication.
-	on_sta_authorized_internal_callback =
-	    [this](struct hostapd_data* iface_hapd, const u8 *mac_addr,
-		   int authorized, const u8 *p2p_dev_addr) {
-		wpa_printf(MSG_DEBUG, "notify client " MACSTR " %s",
-			   MAC2STR(mac_addr),
-			   (authorized) ? "Connected" : "Disconnected");
-		for (const auto &callback : callbacks_) {
-		    callback->onConnectedClientsChanged(strlen(iface_hapd->conf->bridge) > 0 ?
-			    iface_hapd->conf->bridge : iface_hapd->conf->iface,
-			    iface_hapd->conf->iface, mac_addr, authorized);
-		}
-	    };
-
-	// Register for wpa_event which used to get channel switch event
-	on_wpa_msg_internal_callback =
-	    [this](struct hostapd_data* iface_hapd, int level,
-		   enum wpa_msg_type type, const char *txt,
-		   size_t len) {
-		wpa_printf(MSG_DEBUG, "Receive wpa msg : %s", txt);
-		if (os_strncmp(txt, AP_EVENT_ENABLED,
-			       strlen(AP_EVENT_ENABLED)) == 0 ||
-		    os_strncmp(txt, WPA_EVENT_CHANNEL_SWITCH,
-			       strlen(WPA_EVENT_CHANNEL_SWITCH)) == 0) {
-		    for (const auto &callback : callbacks_) {
-			callback->onApInstanceInfoChanged(
-				strlen(iface_hapd->conf->bridge) > 0 ?
-				iface_hapd->conf->bridge : iface_hapd->conf->iface,
-				iface_hapd->conf->iface, iface_hapd->iface->freq,
-				getBandwidth(iface_hapd->iconf),
-				getGeneration(iface_hapd->iface->current_mode),
-				iface_hapd->own_addr);
-		    }
-		}
-	    };
-
-	// Setup callback
-	iface_hapd->setup_complete_cb = onAsyncSetupCompleteCb;
-	iface_hapd->setup_complete_cb_ctx = iface_hapd;
-	iface_hapd->sta_authorized_cb = onAsyncStaAuthorizedCb;
-	iface_hapd->sta_authorized_cb_ctx = iface_hapd;
-	wpa_msg_register_cb(onAsyncWpaEventCb);
-
-	if (hostapd_enable_iface(iface_hapd->iface) < 0) {
-		wpa_printf(
-		    MSG_ERROR, "Enabling interface %s failed",
-		    iface_params.V1_2.V1_1.V1_0.ifaceName.c_str());
-		return {V1_2::HostapdStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {V1_2::HostapdStatusCode::SUCCESS, ""};
-}
-
-V1_0::HostapdStatus Hostapd::removeAccessPointInternal(const std::string& iface_name)
-{
-	// interfaces to be removed
-	std::vector<std::string> interfaces;
-	bool is_error = false;
-
-	const auto it = br_interfaces_.find(iface_name);
-	if (it != br_interfaces_.end()) {
-		// In case bridge, remove managed interfaces
-		interfaces = it->second;
-		br_interfaces_.erase(iface_name);
-	} else {
-		// else remove current interface
-		interfaces.push_back(iface_name);
-	}
-
-	for (auto& iface : interfaces) {
-		std::vector<char> remove_iface_param_vec(
-		    iface.begin(), iface.end() + 1);
-		if (hostapd_remove_iface(interfaces_, remove_iface_param_vec.data()) <
-		    0) {
-			wpa_printf(MSG_INFO, "Remove interface %s failed",
-			    iface.c_str());
-			is_error = true;
-		}
-	}
-	if (is_error) {
-		return {V1_0::HostapdStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {V1_0::HostapdStatusCode::SUCCESS, ""};
-}
-
-V1_0::HostapdStatus Hostapd::registerCallbackInternal(
-    const sp<V1_1::IHostapdCallback>& callback)
-{
-	return {V1_0::HostapdStatusCode::FAILURE_UNKNOWN, ""};
-}
-
-V1_2::HostapdStatus Hostapd::registerCallbackInternal_1_3(
-    const sp<V1_3::IHostapdCallback>& callback)
-{
-	if (!callback->linkToDeath(death_notifier_, 0)) {
-		wpa_printf(
-		    MSG_ERROR,
-		    "Error registering for death notification for "
-		    "hostapd callback object");
-		return {V1_2::HostapdStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	callbacks_.push_back(callback);
-	return {V1_2::HostapdStatusCode::SUCCESS, ""};
-}
-
-V1_2::HostapdStatus Hostapd::forceClientDisconnectInternal(const std::string& iface_name,
-    const std::array<uint8_t, 6>& client_address, V1_2::Ieee80211ReasonCode reason_code)
-{
-	struct hostapd_data *hapd = hostapd_get_iface(interfaces_, iface_name.c_str());
-	bool result;
-	if (!hapd) {
-	    for (auto const& iface : br_interfaces_) {
-		if (iface.first == iface_name) {
-		    for (auto const& instance : iface.second) {
-			hapd = hostapd_get_iface(interfaces_, instance.c_str());
-			if (hapd) {
-				result = forceStaDisconnection(hapd, client_address,
-							       (uint16_t) reason_code);
-				if (result) break;
-			}
-		    }
-		}
-	    }
-	} else {
-		result = forceStaDisconnection(hapd, client_address, (uint16_t) reason_code);
-	}
-	if (!hapd) {
-		wpa_printf(MSG_ERROR, "Interface %s doesn't exist", iface_name.c_str());
-		return {V1_2::HostapdStatusCode::FAILURE_IFACE_UNKNOWN, ""};
-	}
-	if (result) {
-		return {V1_2::HostapdStatusCode::SUCCESS, ""};
-	}
-	return {V1_2::HostapdStatusCode::FAILURE_CLIENT_UNKNOWN, ""};
-}
-
-V1_2::HostapdStatus Hostapd::setDebugParamsInternal(V1_2::DebugLevel level)
-{
-	wpa_debug_level = static_cast<uint32_t>(level);
-	return {V1_2::HostapdStatusCode::SUCCESS, ""};
-}
-
-}  // namespace implementation
-}  // namespace V1_3
-}  // namespace hostapd
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/hostapd/hidl/1.3/hostapd.h b/hostapd/hidl/1.3/hostapd.h
deleted file mode 100644
index dc45932..0000000
--- a/hostapd/hidl/1.3/hostapd.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * hidl interface for wpa_hostapd daemon
- * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2018, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef HOSTAPD_HIDL_SUPPLICANT_H
-#define HOSTAPD_HIDL_SUPPLICANT_H
-
-#include <string>
-
-#include <android-base/macros.h>
-
-#include <android/hardware/wifi/hostapd/1.3/IHostapd.h>
-#include <android/hardware/wifi/hostapd/1.3/IHostapdCallback.h>
-
-extern "C"
-{
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "utils/includes.h"
-#include "utils/wpa_debug.h"
-#include "ap/hostapd.h"
-#include "ap/sta_info.h"
-}
-
-class DeathNotifier : public android::hardware::hidl_death_recipient
-{
-public:
-	void serviceDied(
-	    uint64_t /*cookie*/,
-	    const android::wp<android::hidl::base::V1_0::IBase>
-		& /* who */) override
-	{
-		wpa_printf(MSG_ERROR, "Client died. Terminating...");
-		eloop_terminate();
-	}
-};
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace hostapd {
-namespace V1_3 {
-namespace implementation {
-using namespace android::hardware::wifi::hostapd::V1_0;
-
-/**
- * Implementation of the hostapd hidl object. This hidl
- * object is used core for global control operations on
- * hostapd.
- */
-class Hostapd : public V1_3::IHostapd
-{
-public:
-	Hostapd(hapd_interfaces* interfaces);
-	~Hostapd() override = default;
-
-	// Hidl methods exposed.
-	Return<void> addAccessPoint(
-	    const V1_0::IHostapd::IfaceParams& iface_params,
-	    const V1_0::IHostapd::NetworkParams& nw_params, addAccessPoint_cb _hidl_cb) override;
-	Return<void> addAccessPoint_1_1(
-	    const V1_1::IHostapd::IfaceParams& iface_params,
-	    const V1_0::IHostapd::NetworkParams& nw_params, addAccessPoint_cb _hidl_cb) override;
-	Return<void> addAccessPoint_1_2(
-	    const V1_2::IHostapd::IfaceParams& iface_params,
-	    const V1_2::IHostapd::NetworkParams& nw_params,
-	    addAccessPoint_1_2_cb _hidl_cb) override;
-	Return<void> addAccessPoint_1_3(
-	    const V1_3::IHostapd::IfaceParams& iface_params,
-	    const V1_3::IHostapd::NetworkParams& nw_params,
-	    addAccessPoint_1_3_cb _hidl_cb) override;
-	Return<void> removeAccessPoint(
-	    const hidl_string& iface_name,
-	    removeAccessPoint_cb _hidl_cb) override;
-	Return<void> terminate() override;
-	Return<void> registerCallback(
-	    const sp<V1_1::IHostapdCallback>& callback,
-	    registerCallback_cb _hidl_cb) override;
-	Return<void> registerCallback_1_3(
-	    const sp<V1_3::IHostapdCallback>& callback,
-	    registerCallback_1_3_cb _hidl_cb) override;
-	Return<void>forceClientDisconnect(
-	    const hidl_string& iface_name,
-	    const hidl_array<uint8_t, 6>& client_address,
-	    V1_2::Ieee80211ReasonCode reason_code, forceClientDisconnect_cb _hidl_cb) override;
-	Return<void> setDebugParams(
-	    V1_2::DebugLevel level, setDebugParams_cb _hidl_cb) override;
-private:
-	// Corresponding worker functions for the HIDL methods.
-	V1_0::HostapdStatus addAccessPointInternal(
-	    const V1_0::IHostapd::IfaceParams& iface_params,
-	    const V1_0::IHostapd::NetworkParams& nw_params);
-	V1_0::HostapdStatus addAccessPointInternal_1_1(
-	    const V1_1::IHostapd::IfaceParams& IfaceParams,
-	    const V1_0::IHostapd::NetworkParams& nw_params);
-	V1_2::HostapdStatus addAccessPointInternal_1_2(
-	    const V1_2::IHostapd::IfaceParams& IfaceParams,
-	    const V1_2::IHostapd::NetworkParams& nw_params);
-	V1_2::HostapdStatus addAccessPointInternal_1_3(
-	    const V1_3::IHostapd::IfaceParams& IfaceParams,
-	    const V1_3::IHostapd::NetworkParams& nw_params);
-	V1_2::HostapdStatus addSingleAccessPoint(
-	    const V1_3::IHostapd::IfaceParams& IfaceParams,
-	    const V1_3::IHostapd::ChannelParams& channelParams,
-	    const V1_3::IHostapd::NetworkParams& nw_params,
-	    std::string br_name);
-	V1_2::HostapdStatus addConcurrentAccessPoints(
-	    const V1_3::IHostapd::IfaceParams& IfaceParams,
-	    const V1_3::IHostapd::NetworkParams& nw_params);
-	V1_0::HostapdStatus removeAccessPointInternal(const std::string& iface_name);
-	V1_0::HostapdStatus registerCallbackInternal(
-	    const sp<V1_1::IHostapdCallback>& callback);
-	V1_2::HostapdStatus registerCallbackInternal_1_3(
-	    const sp<V1_3::IHostapdCallback>& callback);
-	V1_2::HostapdStatus forceClientDisconnectInternal(
-	    const std::string& iface_name,
-	    const std::array<uint8_t, 6>& client_address,
-	    V1_2::Ieee80211ReasonCode reason_code);
-	V1_2::HostapdStatus setDebugParamsInternal(V1_2::DebugLevel level);
-	// Raw pointer to the global structure maintained by the core.
-	struct hapd_interfaces* interfaces_;
-	// Callbacks registered.
-	std::vector<sp<V1_3::IHostapdCallback>> callbacks_;
-	// Death notifier.
-	android::sp<DeathNotifier> death_notifier_;
-	// Bridge and its managed interfaces.
-	std::map<std::string, std::vector<std::string>> br_interfaces_;
-	DISALLOW_COPY_AND_ASSIGN(Hostapd);
-};
-}  // namespace implementation
-}  // namespace V1_3
-}  // namespace hostapd
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // HOSTAPD_HIDL_SUPPLICANT_H
diff --git a/hostapd/hostapd.android.rc b/hostapd/hostapd.android.rc
index 7cc45bd..4b6b17b 100644
--- a/hostapd/hostapd.android.rc
+++ b/hostapd/hostapd.android.rc
@@ -12,10 +12,7 @@
     mkdir /data/vendor/wifi/hostapd/sockets 0770 wifi wifi
 
 service hostapd /vendor/bin/hw/hostapd
-    interface android.hardware.wifi.hostapd@1.0::IHostapd default
-    interface android.hardware.wifi.hostapd@1.1::IHostapd default
-    interface android.hardware.wifi.hostapd@1.2::IHostapd default
-    interface android.hardware.wifi.hostapd@1.3::IHostapd default
+    interface aidl android.hardware.wifi.hostapd.IHostapd/default
     class main
     capabilities NET_ADMIN NET_RAW
     user wifi
diff --git a/hostapd/main.c b/hostapd/main.c
index 346df48..e59308a 100644
--- a/hostapd/main.c
+++ b/hostapd/main.c
@@ -30,9 +30,9 @@
 #include "config_file.h"
 #include "eap_register.h"
 #include "ctrl_iface.h"
-#ifdef CONFIG_CTRL_IFACE_HIDL
-#include "hidl.h"
-#endif /* CONFIG_CTRL_IFACE_HIDL */
+#ifdef CONFIG_CTRL_IFACE_AIDL
+#include "aidl.h"
+#endif /* CONFIG_CTRL_IFACE_AIDL */
 
 struct hapd_global {
 	void **drv_priv;
@@ -766,7 +766,7 @@
 		}
 	}
 
-#ifndef CONFIG_CTRL_IFACE_HIDL
+#ifndef CONFIG_CTRL_IFACE_AIDL
 	if (optind == argc && interfaces.global_iface_path == NULL &&
 	    num_bss_configs == 0)
 		usage();
@@ -891,12 +891,12 @@
 			goto out;
 	}
 
-#ifdef CONFIG_CTRL_IFACE_HIDL
-	if (hostapd_hidl_init(&interfaces)) {
-		wpa_printf(MSG_ERROR, "Failed to initialize HIDL interface");
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	if (hostapd_aidl_init(&interfaces)) {
+		wpa_printf(MSG_ERROR, "Failed to initialize AIDL interface");
 		goto out;
 	}
-#endif /* CONFIG_CTRL_IFACE_HIDL */
+#endif /* CONFIG_CTRL_IFACE_AIDL */
 	hostapd_global_ctrl_iface_init(&interfaces);
 
 	if (hostapd_global_run(&interfaces, daemonize, pid_file)) {
@@ -907,9 +907,9 @@
 	ret = 0;
 
  out:
-#ifdef CONFIG_CTRL_IFACE_HIDL
-	hostapd_hidl_deinit(&interfaces);
-#endif /* CONFIG_CTRL_IFACE_HIDL */
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	hostapd_aidl_deinit(&interfaces);
+#endif /* CONFIG_CTRL_IFACE_AIDL */
 	hostapd_global_ctrl_iface_deinit(&interfaces);
 	/* Deinitialize all interfaces */
 	for (i = 0; i < interfaces.count; i++) {
diff --git a/src/crypto/tls_openssl_ocsp.c b/src/crypto/tls_openssl_ocsp.c
index 8b37b34..97bf605 100644
--- a/src/crypto/tls_openssl_ocsp.c
+++ b/src/crypto/tls_openssl_ocsp.c
@@ -502,7 +502,7 @@
 	enum ocsp_result result = OCSP_INVALID;
 	X509_STORE *store;
 	STACK_OF(X509) *untrusted = NULL, *certs = NULL, *chain = NULL;
-	X509_STORE_CTX ctx;
+	X509_STORE_CTX *ctx = NULL;
 	X509 *signer, *tmp_cert;
 	int signer_trusted = 0;
 	EVP_PKEY *skey;
@@ -546,7 +546,7 @@
 		return OCSP_INVALID;
 	}
 
-	basic_data = ASN1_STRING_data(bytes->response);
+	basic_data = ASN1_STRING_get0_data(bytes->response);
 	basic_len = ASN1_STRING_length(bytes->response);
 	wpa_hexdump(MSG_DEBUG, "OpenSSL: BasicOCSPResponse",
 		    basic_data, basic_len);
@@ -643,12 +643,14 @@
 		   "OpenSSL: Found OCSP signer certificate %s and verified BasicOCSPResponse signature",
 		   buf);
 
-	if (!X509_STORE_CTX_init(&ctx, store, signer, untrusted))
+	ctx = X509_STORE_CTX_new();
+	if (!ctx ||
+	    !X509_STORE_CTX_init(ctx, store, signer, untrusted) ||
+	    !X509_STORE_CTX_set_purpose(ctx, X509_PURPOSE_OCSP_HELPER)) {
 		goto fail;
-	X509_STORE_CTX_set_purpose(&ctx, X509_PURPOSE_OCSP_HELPER);
-	ret = X509_verify_cert(&ctx);
-	chain = X509_STORE_CTX_get1_chain(&ctx);
-	X509_STORE_CTX_cleanup(&ctx);
+	}
+	ret = X509_verify_cert(ctx);
+	chain = X509_STORE_CTX_get1_chain(ctx);
 	if (ret <= 0) {
 		wpa_printf(MSG_DEBUG,
 			   "OpenSSL: Could not validate OCSP signer certificate");
@@ -661,9 +663,8 @@
 	}
 
 	if (!signer_trusted) {
-		X509_check_purpose(signer, -1, 0);
-		if ((signer->ex_flags & EXFLAG_XKUSAGE) &&
-		    (signer->ex_xkusage & XKU_OCSP_SIGN)) {
+		if ((X509_get_extension_flags(signer) & EXFLAG_XKUSAGE) &&
+		    (X509_get_extended_key_usage(signer) & XKU_OCSP_SIGN)) {
 			wpa_printf(MSG_DEBUG,
 				   "OpenSSL: OCSP signer certificate delegation OK");
 		} else {
@@ -839,6 +840,7 @@
 	sk_X509_pop_free(certs, X509_free);
 	BasicOCSPResponse_free(basic);
 	OCSPResponse_free(resp);
+	X509_STORE_CTX_free(ctx);
 
 	return result;
 }
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index a7e7587..9215794 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -104,6 +104,9 @@
  */
 #define P2P_RECONSIDER_GO_MOVE_DELAY 30
 
+/* Check if frequency is 2GHz */
+#define	IS_2GHZ(n)	(n >= 2412 && n <= 2484)
+
 enum p2p_group_removal_reason {
 	P2P_GROUP_REMOVAL_UNKNOWN,
 	P2P_GROUP_REMOVAL_SILENT,
@@ -5564,6 +5567,7 @@
 	struct wpa_used_freq_data *freqs;
 	int res, best_freq, num_unused;
 	unsigned int freq_in_use = 0, num, i, max_pref_freq;
+	int p2p_pref_freq;
 
 	max_pref_freq = *num_pref_freq;
 	*num_pref_freq = 0;
@@ -5632,46 +5636,68 @@
 
 	best_freq = wpas_p2p_pick_best_used_freq(wpa_s, freqs, num);
 
-	if (!wpa_s->conf->num_p2p_pref_chan && *pref_freq == 0) {
-		enum wpa_driver_if_type iface_type;
-
-		if (go)
-			iface_type = WPA_IF_P2P_GO;
-		else
-			iface_type = WPA_IF_P2P_CLIENT;
-
-		wpa_printf(MSG_DEBUG, "P2P: best_freq=%d, go=%d",
-			   best_freq, go);
-
-		res = wpa_drv_get_pref_freq_list(wpa_s, iface_type,
-						 &max_pref_freq,
-						 pref_freq_list);
-		if (!res && max_pref_freq > 0) {
-			*num_pref_freq = max_pref_freq;
+	if (*pref_freq == 0) {
+		if (wpa_s->conf->num_p2p_pref_chan && IS_2GHZ(best_freq)) {
 			i = 0;
-			while (i < *num_pref_freq &&
-			       (!p2p_supported_freq(wpa_s->global->p2p,
-						    pref_freq_list[i]) ||
-				wpas_p2p_disallowed_freq(wpa_s->global,
-							 pref_freq_list[i]))) {
-				wpa_printf(MSG_DEBUG,
-					   "P2P: preferred_freq_list[%d]=%d is disallowed",
-					   i, pref_freq_list[i]);
+			while (i < wpa_s->conf->num_p2p_pref_chan) {
+				p2p_pref_freq = ieee80211_chan_to_freq(NULL,
+					wpa_s->conf->p2p_pref_chan[i].op_class,
+					wpa_s->conf->p2p_pref_chan[i].chan);
+
+				if (p2p_supported_freq(wpa_s->global->p2p, p2p_pref_freq) &&
+					!wpas_p2p_disallowed_freq(wpa_s->global, p2p_pref_freq)) {
+					best_freq = p2p_pref_freq;
+					wpa_printf(MSG_DEBUG, "P2P: Using frequency (%u MHz) "
+						"from P2P preferred channel list", best_freq);
+					break;
+				} else {
+					wpa_printf(MSG_MSGDUMP, "P2P: Skipping preferred "
+						"frequency (%u MHz) ", p2p_pref_freq);
+				}
 				i++;
 			}
-			if (i != *num_pref_freq) {
-				best_freq = pref_freq_list[i];
-				wpa_printf(MSG_DEBUG,
-					   "P2P: Using preferred_freq_list[%d]=%d",
-					   i, best_freq);
+		} else {
+			enum wpa_driver_if_type iface_type;
+
+			if (go)
+				iface_type = WPA_IF_P2P_GO;
+			else
+				iface_type = WPA_IF_P2P_CLIENT;
+
+			wpa_printf(MSG_DEBUG, "P2P: best_freq=%d, go=%d",
+				best_freq, go);
+
+			res = wpa_drv_get_pref_freq_list(wpa_s, iface_type,
+						 &max_pref_freq,
+						 pref_freq_list);
+			if (!res && max_pref_freq > 0) {
+				*num_pref_freq = max_pref_freq;
+				i = 0;
+				while (i < *num_pref_freq &&
+					(!p2p_supported_freq(wpa_s->global->p2p,
+						pref_freq_list[i]) ||
+					wpas_p2p_disallowed_freq(wpa_s->global,
+							pref_freq_list[i]))) {
+					wpa_printf(MSG_DEBUG,
+						"P2P: preferred_freq_list[%d]=%d is disallowed",
+						i, pref_freq_list[i]);
+					i++;
+				}
+				if (i != *num_pref_freq) {
+					best_freq = pref_freq_list[i];
+					wpa_printf(MSG_DEBUG,
+						"P2P: Using preferred_freq_list[%d]=%d",
+						i, best_freq);
+				} else {
+					wpa_printf(MSG_DEBUG,
+						"P2P: All driver preferred frequencies are "
+						"disallowed for P2P use");
+					*num_pref_freq = 0;
+				}
 			} else {
 				wpa_printf(MSG_DEBUG,
-					   "P2P: All driver preferred frequencies are disallowed for P2P use");
-				*num_pref_freq = 0;
+					"P2P: No preferred frequency list available");
 			}
-		} else {
-			wpa_printf(MSG_DEBUG,
-				   "P2P: No preferred frequency list available");
 		}
 	}
 
