Add support of of AIDL interface to hostapd server.

Add support of AIDL interface and AIDL service implementation.
Change hostapd to AIDL service and managed by service manager.
Hostapd client will need to use service manager to obtain the
interace and use AIDL client to call the interface methods.

Bug: 194806512
Test: Manual test, enable Wifi hotspot successfully.

Change-Id: Ic4b22250f05f9d59ee39ccc8305c62a29e9cfdaf
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 f9d2647..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(strlen(iface_hapd->conf->bridge) > 0 ?
-					iface_hapd->conf->bridge : 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++) {