diff --git a/hostapd/aidl/.clang-format b/hostapd/aidl/.clang-format
new file mode 100644
index 0000000..42fadb5
--- /dev/null
+++ b/hostapd/aidl/.clang-format
@@ -0,0 +1,9 @@
+BasedOnStyle: Google
+IndentWidth: 8
+UseTab: Always
+BreakBeforeBraces: Mozilla
+AllowShortIfStatementsOnASingleLine: false
+IndentCaseLabels: false
+AccessModifierOffset: -8
+AlignAfterOpenBracket: AlwaysBreak
+SortIncludes: false
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
