diff --git a/hostapd/Android.bp b/hostapd/Android.bp
index e5d54f3..d7cc39b 100644
--- a/hostapd/Android.bp
+++ b/hostapd/Android.bp
@@ -45,13 +45,10 @@
     defaults: ["hostapd_cflags_defaults"],
     srcs: [":hostapd_srcs"],
     shared_libs: [
-        "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",
         "libbase",
-        "libhidlbase",
         "libutils",
+        "libbinder_ndk",
         "libc",
         "libcutils",
         "liblog",
@@ -63,11 +60,11 @@
     relative_install_path: "hw",
     soc_specific: true,
     static_libs: [
-        "libhostapd_hidl_bp",
+        "libhostapd_aidl_bp",
     ],
     header_libs: [
         "hostapd_headers",
-        "libhostapd_hidl_headers",
+        "libhostapd_aidl_headers",
     ],
 }
 
@@ -165,7 +162,7 @@
         "-DCONFIG_PROXYARP",
         "-DCONFIG_ACS",
         "-DCONFIG_ANDROID_LOG",
-        "-DCONFIG_CTRL_IFACE_HIDL",
+        "-DCONFIG_CTRL_IFACE_AIDL",
         "-Wall",
         "-Werror",
         "-Wno-unused-parameter",
diff --git a/hostapd/Android.mk b/hostapd/Android.mk
index 9cce32b..1f6ac36 100644
--- a/hostapd/Android.mk
+++ b/hostapd/Android.mk
@@ -42,6 +42,10 @@
 L_CFLAGS += -DANDROID_LIB_STUB
 endif
 
+ifeq ($(BOARD_HOSTAPD_CONFIG_80211W_MFP_OPTIONAL),true)
+L_CFLAGS += -DENABLE_HOSTAPD_CONFIG_80211W_MFP_OPTIONAL
+endif
+
 # Use Android specific directory for control interface sockets
 L_CFLAGS += -DCONFIG_CTRL_IFACE_CLIENT_DIR=\"/data/vendor/wifi/hostapd/sockets\"
 L_CFLAGS += -DCONFIG_CTRL_IFACE_DIR=\"/data/vendor/wifi/hostapd/ctrl\"
@@ -1125,9 +1129,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 +1174,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
+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 +1188,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)/../LICENSE
@@ -1206,16 +1208,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 +1225,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 \
+    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/hidl/1.3/Android.bp b/hostapd/aidl/Android.bp
similarity index 78%
rename from hostapd/hidl/1.3/Android.bp
rename to hostapd/aidl/Android.bp
index 4568ef9..3cbccee 100644
--- a/hostapd/hidl/1.3/Android.bp
+++ b/hostapd/aidl/Android.bp
@@ -20,23 +20,20 @@
 }
 
 cc_library_headers {
-    name: "libhostapd_hidl_headers",
+    name: "libhostapd_aidl_headers",
     export_include_dirs: ["."],
     soc_specific: true,
 }
 
 cc_library_static {
-    name: "libhostapd_hidl_bp",
+    name: "libhostapd_aidl_bp",
     srcs: ["*.cpp"],
     defaults: ["hostapd_cflags_defaults"],
     soc_specific: true,
     shared_libs: [
-        "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",
+        "libbinder_ndk",
         "libbase",
-        "libhidlbase",
         "libutils",
         "liblog",
     ],
@@ -46,6 +43,6 @@
     ],
     header_libs: [
         "hostapd_headers",
-        "libhostapd_hidl_headers",
+        "libhostapd_aidl_headers",
     ],
 }
diff --git a/hostapd/aidl/aidl.cpp b/hostapd/aidl/aidl.cpp
new file mode 100644
index 0000000..e02708c
--- /dev/null
+++ b/hostapd/aidl/aidl.cpp
@@ -0,0 +1,73 @@
+/*
+ * 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 deinit, make sure call terminate to clear callback_
+	if (service) {
+		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..61539a0
--- /dev/null
+++ b/hostapd/aidl/hostapd.cpp
@@ -0,0 +1,1081 @@
+/*
+ * 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::ChannelBandwidth;
+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,
+	const std::string owe_transition_ifname)
+{
+	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"
+#ifdef ENABLE_HOSTAPD_CONFIG_80211W_MFP_OPTIONAL
+			"ieee80211w=1\n"
+#endif
+			"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;
+	case EncryptionType::WPA3_OWE_TRANSITION:
+		encryption_config_as_string = StringPrintf(
+			"wpa=2\n"
+			"rsn_pairwise=%s\n"
+			"wpa_key_mgmt=OWE\n"
+			"ieee80211w=2",
+			is_60Ghz_band_only ? "GCMP" : "CCMP");
+		break;
+	case EncryptionType::WPA3_OWE:
+		encryption_config_as_string = StringPrintf(
+			"wpa=2\n"
+			"rsn_pairwise=%s\n"
+			"wpa_key_mgmt=OWE\n"
+			"ieee80211w=2",
+			is_60Ghz_band_only ? "GCMP" : "CCMP");
+		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());
+	}
+
+	// vendor_elements string
+	std::string vendor_elements_as_string;
+	if (nw_params.vendorElements.size() > 0) {
+		std::stringstream ss;
+		ss << std::hex;
+		ss << std::setfill('0');
+		for (uint8_t b : nw_params.vendorElements) {
+			ss << std::setw(2) << static_cast<unsigned int>(b);
+		}
+		vendor_elements_as_string = StringPrintf("vendor_elements=%s", ss.str().c_str());
+	}
+
+	std::string owe_transition_ifname_as_string;
+	if (!owe_transition_ifname.empty()) {
+		owe_transition_ifname_as_string = StringPrintf(
+			"owe_transition_ifname=%s", owe_transition_ifname.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"
+		"%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(),
+		owe_transition_ifname_as_string.c_str(),
+		enable_edmg_as_string.c_str(),
+		edmg_channel_as_string.c_str(),
+		vendor_elements_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;
+	}
+}
+
+ChannelBandwidth getChannelBandwidth(struct hostapd_config *iconf)
+{
+	wpa_printf(MSG_DEBUG, "getChannelBandwidth %d, isHT=%d, isHT40=%d",
+		   iconf->vht_oper_chwidth, iconf->ieee80211n,
+		   iconf->secondary_channel);
+	switch (iconf->vht_oper_chwidth) {
+	case CHANWIDTH_80MHZ:
+		return ChannelBandwidth::BANDWIDTH_80;
+	case CHANWIDTH_80P80MHZ:
+		return ChannelBandwidth::BANDWIDTH_80P80;
+		break;
+	case CHANWIDTH_160MHZ:
+		return ChannelBandwidth::BANDWIDTH_160;
+		break;
+	case CHANWIDTH_USE_HT:
+		if (iconf->ieee80211n) {
+			return iconf->secondary_channel != 0 ?
+				ChannelBandwidth::BANDWIDTH_40 : ChannelBandwidth::BANDWIDTH_20;
+		}
+		return ChannelBandwidth::BANDWIDTH_20_NOHT;
+	case CHANWIDTH_2160MHZ:
+		return ChannelBandwidth::BANDWIDTH_2160;
+	case CHANWIDTH_4320MHZ:
+		return ChannelBandwidth::BANDWIDTH_4320;
+	case CHANWIDTH_6480MHZ:
+		return ChannelBandwidth::BANDWIDTH_6480;
+	case CHANWIDTH_8640MHZ:
+		return ChannelBandwidth::BANDWIDTH_8640;
+	default:
+		return ChannelBandwidth::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);
+}
+
+std::vector<uint8_t>  generateRandomOweSsid()
+{
+	u8 random[8] = {0};
+	os_get_random(random, 8);
+
+	std::string ssid = StringPrintf("Owe-%s", random);
+	wpa_printf(MSG_INFO, "Generated OWE SSID: %s", ssid.c_str());
+	std::vector<uint8_t> vssid(ssid.begin(), ssid.end());
+
+	return vssid;
+}
+
+::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;
+		NetworkParams nw_params_new = nw_params;
+		iface_params_new.name = managed_interfaces[i];
+
+		std::string owe_transition_ifname = "";
+		if (nw_params.encryptionType == EncryptionType::WPA3_OWE_TRANSITION) {
+			if (i == 0 && i+1 < channelParamsListSize) {
+				owe_transition_ifname = managed_interfaces[i+1];
+				nw_params_new.encryptionType = EncryptionType::NONE;
+			} else {
+				owe_transition_ifname = managed_interfaces[0];
+				nw_params_new.isHidden = true;
+				nw_params_new.ssid = generateRandomOweSsid();
+			}
+		}
+
+		ndk::ScopedAStatus status = addSingleAccessPoint(
+		    iface_params_new, iface_params.channelParams[i], nw_params_new,
+		    br_name, owe_transition_ifname);
+		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,
+	const std::string owe_transition_ifname)
+{
+	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, owe_transition_ifname);
+	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,
+							    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.channelBandwidth = getChannelBandwidth(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);
+			}
+		} else if (os_strncmp(txt, AP_EVENT_DISABLED, strlen(AP_EVENT_DISABLED)) == 0) {
+			// 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,
+						    iface_hapd->conf->iface);
+			}
+		}
+	};
+
+	// 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
diff --git a/hostapd/aidl/hostapd.h b/hostapd/aidl/hostapd.h
new file mode 100644
index 0000000..ffdbd8e
--- /dev/null
+++ b/hostapd/aidl/hostapd.h
@@ -0,0 +1,95 @@
+/*
+ * 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,
+	    std::string owe_transition_ifname);
+	::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 72efd3f..0000000
--- a/hostapd/hidl/1.3/hostapd.cpp
+++ /dev/null
@@ -1,1042 +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);
-		    }
-		}
-		else if (os_strncmp(txt, AP_EVENT_DISABLED,
-			 strlen(AP_EVENT_DISABLED)) == 0) {
-		    // 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);
-		    }
-		}
-	};
-
-	// Setup callback
-	iface_hapd->setup_complete_cb = onAsyncSetupCompleteCb;
-	iface_hapd->setup_complete_cb_ctx = iface_hapd;
-	iface_hapd->sta_authorized_cb = onAsyncStaAuthorizedCb;
-	iface_hapd->sta_authorized_cb_ctx = iface_hapd;
-	wpa_msg_register_cb(onAsyncWpaEventCb);
-
-	if (hostapd_enable_iface(iface_hapd->iface) < 0) {
-		wpa_printf(
-		    MSG_ERROR, "Enabling interface %s failed",
-		    iface_params.V1_2.V1_1.V1_0.ifaceName.c_str());
-		return {V1_2::HostapdStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {V1_2::HostapdStatusCode::SUCCESS, ""};
-}
-
-V1_0::HostapdStatus Hostapd::removeAccessPointInternal(const std::string& iface_name)
-{
-	// interfaces to be removed
-	std::vector<std::string> interfaces;
-	bool is_error = false;
-
-	const auto it = br_interfaces_.find(iface_name);
-	if (it != br_interfaces_.end()) {
-		// In case bridge, remove managed interfaces
-		interfaces = it->second;
-		br_interfaces_.erase(iface_name);
-	} else {
-		// else remove current interface
-		interfaces.push_back(iface_name);
-	}
-
-	for (auto& iface : interfaces) {
-		std::vector<char> remove_iface_param_vec(
-		    iface.begin(), iface.end() + 1);
-		if (hostapd_remove_iface(interfaces_, remove_iface_param_vec.data()) <
-		    0) {
-			wpa_printf(MSG_INFO, "Remove interface %s failed",
-			    iface.c_str());
-			is_error = true;
-		}
-	}
-	if (is_error) {
-		return {V1_0::HostapdStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {V1_0::HostapdStatusCode::SUCCESS, ""};
-}
-
-V1_0::HostapdStatus Hostapd::registerCallbackInternal(
-    const sp<V1_1::IHostapdCallback>& callback)
-{
-	return {V1_0::HostapdStatusCode::FAILURE_UNKNOWN, ""};
-}
-
-V1_2::HostapdStatus Hostapd::registerCallbackInternal_1_3(
-    const sp<V1_3::IHostapdCallback>& callback)
-{
-	if (!callback->linkToDeath(death_notifier_, 0)) {
-		wpa_printf(
-		    MSG_ERROR,
-		    "Error registering for death notification for "
-		    "hostapd callback object");
-		return {V1_2::HostapdStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	callbacks_.push_back(callback);
-	return {V1_2::HostapdStatusCode::SUCCESS, ""};
-}
-
-V1_2::HostapdStatus Hostapd::forceClientDisconnectInternal(const std::string& iface_name,
-    const std::array<uint8_t, 6>& client_address, V1_2::Ieee80211ReasonCode reason_code)
-{
-	struct hostapd_data *hapd = hostapd_get_iface(interfaces_, iface_name.c_str());
-	bool result;
-	if (!hapd) {
-	    for (auto const& iface : br_interfaces_) {
-		if (iface.first == iface_name) {
-		    for (auto const& instance : iface.second) {
-			hapd = hostapd_get_iface(interfaces_, instance.c_str());
-			if (hapd) {
-				result = forceStaDisconnection(hapd, client_address,
-							       (uint16_t) reason_code);
-				if (result) break;
-			}
-		    }
-		}
-	    }
-	} else {
-		result = forceStaDisconnection(hapd, client_address, (uint16_t) reason_code);
-	}
-	if (!hapd) {
-		wpa_printf(MSG_ERROR, "Interface %s doesn't exist", iface_name.c_str());
-		return {V1_2::HostapdStatusCode::FAILURE_IFACE_UNKNOWN, ""};
-	}
-	if (result) {
-		return {V1_2::HostapdStatusCode::SUCCESS, ""};
-	}
-	return {V1_2::HostapdStatusCode::FAILURE_CLIENT_UNKNOWN, ""};
-}
-
-V1_2::HostapdStatus Hostapd::setDebugParamsInternal(V1_2::DebugLevel level)
-{
-	wpa_debug_level = static_cast<uint32_t>(level);
-	return {V1_2::HostapdStatusCode::SUCCESS, ""};
-}
-
-}  // namespace implementation
-}  // namespace V1_3
-}  // namespace hostapd
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/hostapd/hidl/1.3/hostapd.h b/hostapd/hidl/1.3/hostapd.h
deleted file mode 100644
index dc45932..0000000
--- a/hostapd/hidl/1.3/hostapd.h
+++ /dev/null
@@ -1,142 +0,0 @@
-/*
- * hidl interface for wpa_hostapd daemon
- * Copyright (c) 2004-2018, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2018, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef HOSTAPD_HIDL_SUPPLICANT_H
-#define HOSTAPD_HIDL_SUPPLICANT_H
-
-#include <string>
-
-#include <android-base/macros.h>
-
-#include <android/hardware/wifi/hostapd/1.3/IHostapd.h>
-#include <android/hardware/wifi/hostapd/1.3/IHostapdCallback.h>
-
-extern "C"
-{
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "utils/includes.h"
-#include "utils/wpa_debug.h"
-#include "ap/hostapd.h"
-#include "ap/sta_info.h"
-}
-
-class DeathNotifier : public android::hardware::hidl_death_recipient
-{
-public:
-	void serviceDied(
-	    uint64_t /*cookie*/,
-	    const android::wp<android::hidl::base::V1_0::IBase>
-		& /* who */) override
-	{
-		wpa_printf(MSG_ERROR, "Client died. Terminating...");
-		eloop_terminate();
-	}
-};
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace hostapd {
-namespace V1_3 {
-namespace implementation {
-using namespace android::hardware::wifi::hostapd::V1_0;
-
-/**
- * Implementation of the hostapd hidl object. This hidl
- * object is used core for global control operations on
- * hostapd.
- */
-class Hostapd : public V1_3::IHostapd
-{
-public:
-	Hostapd(hapd_interfaces* interfaces);
-	~Hostapd() override = default;
-
-	// Hidl methods exposed.
-	Return<void> addAccessPoint(
-	    const V1_0::IHostapd::IfaceParams& iface_params,
-	    const V1_0::IHostapd::NetworkParams& nw_params, addAccessPoint_cb _hidl_cb) override;
-	Return<void> addAccessPoint_1_1(
-	    const V1_1::IHostapd::IfaceParams& iface_params,
-	    const V1_0::IHostapd::NetworkParams& nw_params, addAccessPoint_cb _hidl_cb) override;
-	Return<void> addAccessPoint_1_2(
-	    const V1_2::IHostapd::IfaceParams& iface_params,
-	    const V1_2::IHostapd::NetworkParams& nw_params,
-	    addAccessPoint_1_2_cb _hidl_cb) override;
-	Return<void> addAccessPoint_1_3(
-	    const V1_3::IHostapd::IfaceParams& iface_params,
-	    const V1_3::IHostapd::NetworkParams& nw_params,
-	    addAccessPoint_1_3_cb _hidl_cb) override;
-	Return<void> removeAccessPoint(
-	    const hidl_string& iface_name,
-	    removeAccessPoint_cb _hidl_cb) override;
-	Return<void> terminate() override;
-	Return<void> registerCallback(
-	    const sp<V1_1::IHostapdCallback>& callback,
-	    registerCallback_cb _hidl_cb) override;
-	Return<void> registerCallback_1_3(
-	    const sp<V1_3::IHostapdCallback>& callback,
-	    registerCallback_1_3_cb _hidl_cb) override;
-	Return<void>forceClientDisconnect(
-	    const hidl_string& iface_name,
-	    const hidl_array<uint8_t, 6>& client_address,
-	    V1_2::Ieee80211ReasonCode reason_code, forceClientDisconnect_cb _hidl_cb) override;
-	Return<void> setDebugParams(
-	    V1_2::DebugLevel level, setDebugParams_cb _hidl_cb) override;
-private:
-	// Corresponding worker functions for the HIDL methods.
-	V1_0::HostapdStatus addAccessPointInternal(
-	    const V1_0::IHostapd::IfaceParams& iface_params,
-	    const V1_0::IHostapd::NetworkParams& nw_params);
-	V1_0::HostapdStatus addAccessPointInternal_1_1(
-	    const V1_1::IHostapd::IfaceParams& IfaceParams,
-	    const V1_0::IHostapd::NetworkParams& nw_params);
-	V1_2::HostapdStatus addAccessPointInternal_1_2(
-	    const V1_2::IHostapd::IfaceParams& IfaceParams,
-	    const V1_2::IHostapd::NetworkParams& nw_params);
-	V1_2::HostapdStatus addAccessPointInternal_1_3(
-	    const V1_3::IHostapd::IfaceParams& IfaceParams,
-	    const V1_3::IHostapd::NetworkParams& nw_params);
-	V1_2::HostapdStatus addSingleAccessPoint(
-	    const V1_3::IHostapd::IfaceParams& IfaceParams,
-	    const V1_3::IHostapd::ChannelParams& channelParams,
-	    const V1_3::IHostapd::NetworkParams& nw_params,
-	    std::string br_name);
-	V1_2::HostapdStatus addConcurrentAccessPoints(
-	    const V1_3::IHostapd::IfaceParams& IfaceParams,
-	    const V1_3::IHostapd::NetworkParams& nw_params);
-	V1_0::HostapdStatus removeAccessPointInternal(const std::string& iface_name);
-	V1_0::HostapdStatus registerCallbackInternal(
-	    const sp<V1_1::IHostapdCallback>& callback);
-	V1_2::HostapdStatus registerCallbackInternal_1_3(
-	    const sp<V1_3::IHostapdCallback>& callback);
-	V1_2::HostapdStatus forceClientDisconnectInternal(
-	    const std::string& iface_name,
-	    const std::array<uint8_t, 6>& client_address,
-	    V1_2::Ieee80211ReasonCode reason_code);
-	V1_2::HostapdStatus setDebugParamsInternal(V1_2::DebugLevel level);
-	// Raw pointer to the global structure maintained by the core.
-	struct hapd_interfaces* interfaces_;
-	// Callbacks registered.
-	std::vector<sp<V1_3::IHostapdCallback>> callbacks_;
-	// Death notifier.
-	android::sp<DeathNotifier> death_notifier_;
-	// Bridge and its managed interfaces.
-	std::map<std::string, std::vector<std::string>> br_interfaces_;
-	DISALLOW_COPY_AND_ASSIGN(Hostapd);
-};
-}  // namespace implementation
-}  // namespace V1_3
-}  // namespace hostapd
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // HOSTAPD_HIDL_SUPPLICANT_H
diff --git a/hostapd/hostapd.android.rc b/hostapd/hostapd.android.rc
index 7cc45bd..4b6b17b 100644
--- a/hostapd/hostapd.android.rc
+++ b/hostapd/hostapd.android.rc
@@ -12,10 +12,7 @@
     mkdir /data/vendor/wifi/hostapd/sockets 0770 wifi wifi
 
 service hostapd /vendor/bin/hw/hostapd
-    interface android.hardware.wifi.hostapd@1.0::IHostapd default
-    interface android.hardware.wifi.hostapd@1.1::IHostapd default
-    interface android.hardware.wifi.hostapd@1.2::IHostapd default
-    interface android.hardware.wifi.hostapd@1.3::IHostapd default
+    interface aidl android.hardware.wifi.hostapd.IHostapd/default
     class main
     capabilities NET_ADMIN NET_RAW
     user wifi
diff --git a/hostapd/main.c b/hostapd/main.c
index 346df48..e59308a 100644
--- a/hostapd/main.c
+++ b/hostapd/main.c
@@ -30,9 +30,9 @@
 #include "config_file.h"
 #include "eap_register.h"
 #include "ctrl_iface.h"
-#ifdef CONFIG_CTRL_IFACE_HIDL
-#include "hidl.h"
-#endif /* CONFIG_CTRL_IFACE_HIDL */
+#ifdef CONFIG_CTRL_IFACE_AIDL
+#include "aidl.h"
+#endif /* CONFIG_CTRL_IFACE_AIDL */
 
 struct hapd_global {
 	void **drv_priv;
@@ -766,7 +766,7 @@
 		}
 	}
 
-#ifndef CONFIG_CTRL_IFACE_HIDL
+#ifndef CONFIG_CTRL_IFACE_AIDL
 	if (optind == argc && interfaces.global_iface_path == NULL &&
 	    num_bss_configs == 0)
 		usage();
@@ -891,12 +891,12 @@
 			goto out;
 	}
 
-#ifdef CONFIG_CTRL_IFACE_HIDL
-	if (hostapd_hidl_init(&interfaces)) {
-		wpa_printf(MSG_ERROR, "Failed to initialize HIDL interface");
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	if (hostapd_aidl_init(&interfaces)) {
+		wpa_printf(MSG_ERROR, "Failed to initialize AIDL interface");
 		goto out;
 	}
-#endif /* CONFIG_CTRL_IFACE_HIDL */
+#endif /* CONFIG_CTRL_IFACE_AIDL */
 	hostapd_global_ctrl_iface_init(&interfaces);
 
 	if (hostapd_global_run(&interfaces, daemonize, pid_file)) {
@@ -907,9 +907,9 @@
 	ret = 0;
 
  out:
-#ifdef CONFIG_CTRL_IFACE_HIDL
-	hostapd_hidl_deinit(&interfaces);
-#endif /* CONFIG_CTRL_IFACE_HIDL */
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	hostapd_aidl_deinit(&interfaces);
+#endif /* CONFIG_CTRL_IFACE_AIDL */
 	hostapd_global_ctrl_iface_deinit(&interfaces);
 	/* Deinitialize all interfaces */
 	for (i = 0; i < interfaces.count; i++) {
diff --git a/src/crypto/tls_openssl.c b/src/crypto/tls_openssl.c
index 086dfb3..4bc5075 100644
--- a/src/crypto/tls_openssl.c
+++ b/src/crypto/tls_openssl.c
@@ -3066,7 +3066,7 @@
 #ifdef CONFIG_SUITEB
 #ifdef OPENSSL_IS_BORINGSSL
 	/* Start with defaults from BoringSSL */
-	SSL_CTX_set_verify_algorithm_prefs(conn->ssl_ctx, NULL, 0);
+	SSL_set_verify_algorithm_prefs(conn->ssl, NULL, 0);
 #endif /* OPENSSL_IS_BORINGSSL */
 #if OPENSSL_VERSION_NUMBER >= 0x10002000L
 	if (flags & TLS_CONN_SUITEB_NO_ECDH) {
@@ -3120,7 +3120,7 @@
 #ifdef OPENSSL_IS_BORINGSSL
 		uint16_t sigalgs[1] = { SSL_SIGN_RSA_PKCS1_SHA384 };
 
-		if (SSL_CTX_set_verify_algorithm_prefs(conn->ssl_ctx, sigalgs,
+		if (SSL_set_verify_algorithm_prefs(conn->ssl, sigalgs,
 						       1) != 1) {
 			wpa_printf(MSG_INFO,
 				   "OpenSSL: Failed to set Suite B sigalgs");
@@ -3158,7 +3158,7 @@
 			return -1;
 		}
 
-		if (SSL_CTX_set_verify_algorithm_prefs(conn->ssl_ctx, sigalgs,
+		if (SSL_set_verify_algorithm_prefs(conn->ssl, sigalgs,
 						       1) != 1) {
 			wpa_printf(MSG_INFO,
 				   "OpenSSL: Failed to set Suite B sigalgs");
diff --git a/wpa_supplicant/Android.bp b/wpa_supplicant/Android.bp
index 2d4bb2b..0d088bb 100644
--- a/wpa_supplicant/Android.bp
+++ b/wpa_supplicant/Android.bp
@@ -67,16 +67,12 @@
     defaults: ["wpa_supplicant_cflags_defaults"],
     srcs: [":wpa_supplicant_srcs"],
     shared_libs: [
-        "android.hardware.wifi.supplicant@1.0",
-        "android.hardware.wifi.supplicant@1.1",
-        "android.hardware.wifi.supplicant@1.2",
-        "android.hardware.wifi.supplicant@1.3",
-        "android.hardware.wifi.supplicant@1.4",
+        "android.hardware.wifi.supplicant-V1-ndk",
         "libbase",
+        "libbinder_ndk",
         "libc",
         "libcrypto",
         "libcutils",
-        "libhidlbase",
         "libkeystore-engine-wifi-hidl",
         "libkeystore-wifi-hidl",
         "liblog",
@@ -87,11 +83,11 @@
     relative_install_path: "hw",
     soc_specific: true,
     static_libs: [
-        "libwpa_hidl_bp",
+        "libwpa_aidl_bp",
     ],
     header_libs: [
         "wpa_supplicant_headers",
-        "libwpa_hidl_headers",
+        "libwpa_aidl_headers",
     ],
 }
 
@@ -137,7 +133,7 @@
         "-DCONFIG_CTRL_IFACE",
         "-DCONFIG_CTRL_IFACE_CLIENT_DIR=\"/data/vendor/wifi/wpa/sockets\"",
         "-DCONFIG_CTRL_IFACE_DIR=\"/data/vendor/wifi/wpa/sockets\"",
-        "-DCONFIG_CTRL_IFACE_HIDL",
+        "-DCONFIG_CTRL_IFACE_AIDL",
         "-DCONFIG_CTRL_IFACE_UNIX",
         "-DCONFIG_DPP",
         "-DCONFIG_DPP2",
@@ -147,7 +143,7 @@
         "-DCONFIG_FILS",
         "-DCONFIG_GAS",
         "-DCONFIG_GAS_SERVER",
-        "-DCONFIG_HIDL",
+        "-DCONFIG_AIDL",
         "-DCONFIG_HMAC_SHA256_KDF",
         "-DCONFIG_HMAC_SHA384_KDF",
         "-DCONFIG_HMAC_SHA512_KDF",
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index 4a3eda0..8a1e6d8 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -87,7 +87,7 @@
 L_CFLAGS += -mabi=aapcs-linux
 endif
 
-# C++ flags for hidl interface
+# C++ flags for aidl interface
 L_CPPFLAGS := -Wall -Werror
 # TODO: Remove these allowed warnings later.
 L_CPPFLAGS += -Wno-unused-variable -Wno-unused-parameter
@@ -1525,10 +1525,9 @@
 L_CFLAGS += $(DBUS_INCLUDE)
 endif
 
-ifdef CONFIG_CTRL_IFACE_HIDL
-WPA_SUPPLICANT_USE_HIDL=y
-L_CFLAGS += -DCONFIG_HIDL -DCONFIG_CTRL_IFACE_HIDL
-HIDL_INTERFACE_VERSION := 1.4
+ifdef CONFIG_CTRL_IFACE_AIDL
+WPA_SUPPLICANT_USE_AIDL=y
+L_CFLAGS += -DCONFIG_AIDL -DCONFIG_CTRL_IFACE_AIDL
 endif
 
 ifdef CONFIG_READLINE
@@ -1788,17 +1787,14 @@
 ifeq ($(DBUS), y)
 LOCAL_SHARED_LIBRARIES += libdbus
 endif
-ifeq ($(WPA_SUPPLICANT_USE_HIDL), y)
-LOCAL_SHARED_LIBRARIES += android.hardware.wifi.supplicant@1.0
-LOCAL_SHARED_LIBRARIES += android.hardware.wifi.supplicant@1.1
-LOCAL_SHARED_LIBRARIES += android.hardware.wifi.supplicant@1.2
-LOCAL_SHARED_LIBRARIES += android.hardware.wifi.supplicant@1.3
-LOCAL_SHARED_LIBRARIES += android.hardware.wifi.supplicant@1.4
-LOCAL_SHARED_LIBRARIES += libhidlbase libutils libbase
-LOCAL_STATIC_LIBRARIES += libwpa_hidl
-LOCAL_VINTF_FRAGMENTS := hidl/$(HIDL_INTERFACE_VERSION)/android.hardware.wifi.supplicant.xml
+ifeq ($(WPA_SUPPLICANT_USE_AIDL), y)
+LOCAL_SHARED_LIBRARIES += android.hardware.wifi.supplicant-V1-ndk
+LOCAL_SHARED_LIBRARIES += libutils libbase
+LOCAL_SHARED_LIBRARIES += libbinder_ndk
+LOCAL_STATIC_LIBRARIES += libwpa_aidl
+LOCAL_VINTF_FRAGMENTS := aidl/android.hardware.wifi.supplicant.xml
 ifeq ($(WIFI_HIDL_UNIFIED_SUPPLICANT_SERVICE_RC_ENTRY), true)
-LOCAL_INIT_RC=hidl/$(HIDL_INTERFACE_VERSION)/android.hardware.wifi.supplicant-service.rc
+LOCAL_INIT_RC=aidl/android.hardware.wifi.supplicant-service.rc
 endif
 endif
 include $(BUILD_EXECUTABLE)
@@ -1842,11 +1838,11 @@
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/wpa_client_include $(LOCAL_PATH)/wpa_client_include/libwpa_client
 include $(BUILD_SHARED_LIBRARY)
 
-ifeq ($(WPA_SUPPLICANT_USE_HIDL), y)
-### Hidl service library ###
+ifeq ($(WPA_SUPPLICANT_USE_AIDL), y)
+### Aidl service library ###
 ########################
 include $(CLEAR_VARS)
-LOCAL_MODULE := libwpa_hidl
+LOCAL_MODULE := libwpa_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)/../LICENSE
@@ -1855,26 +1851,22 @@
 LOCAL_CFLAGS := $(L_CFLAGS)
 LOCAL_C_INCLUDES := $(INCLUDES)
 LOCAL_SRC_FILES := \
-    hidl/$(HIDL_INTERFACE_VERSION)/hidl.cpp \
-    hidl/$(HIDL_INTERFACE_VERSION)/hidl_manager.cpp \
-    hidl/$(HIDL_INTERFACE_VERSION)/iface_config_utils.cpp \
-    hidl/$(HIDL_INTERFACE_VERSION)/p2p_iface.cpp \
-    hidl/$(HIDL_INTERFACE_VERSION)/p2p_network.cpp \
-    hidl/$(HIDL_INTERFACE_VERSION)/sta_iface.cpp \
-    hidl/$(HIDL_INTERFACE_VERSION)/sta_network.cpp \
-    hidl/$(HIDL_INTERFACE_VERSION)/supplicant.cpp
+    aidl/aidl.cpp \
+    aidl/aidl_manager.cpp \
+    aidl/iface_config_utils.cpp \
+    aidl/p2p_iface.cpp \
+    aidl/p2p_network.cpp \
+    aidl/sta_iface.cpp \
+    aidl/sta_network.cpp \
+    aidl/supplicant.cpp
 LOCAL_SHARED_LIBRARIES := \
-    android.hardware.wifi.supplicant@1.0 \
-    android.hardware.wifi.supplicant@1.1 \
-    android.hardware.wifi.supplicant@1.2 \
-    android.hardware.wifi.supplicant@1.3 \
-    android.hardware.wifi.supplicant@1.4 \
+    android.hardware.wifi.supplicant-V1-ndk \
+    libbinder_ndk \
     libbase \
-    libhidlbase \
     libutils \
     liblog \
     libssl
 LOCAL_EXPORT_C_INCLUDE_DIRS := \
-    $(LOCAL_PATH)/hidl/$(HIDL_INTERFACE_VERSION)
+    $(LOCAL_PATH)/aidl
 include $(BUILD_STATIC_LIBRARY)
-endif # WPA_SUPPLICANT_USE_HIDL == y
+endif # WPA_SUPPLICANT_USE_AIDL == y
diff --git a/wpa_supplicant/hidl/.clang-format b/wpa_supplicant/aidl/.clang-format
similarity index 100%
rename from wpa_supplicant/hidl/.clang-format
rename to wpa_supplicant/aidl/.clang-format
diff --git a/wpa_supplicant/hidl/1.4/Android.bp b/wpa_supplicant/aidl/Android.bp
similarity index 77%
rename from wpa_supplicant/hidl/1.4/Android.bp
rename to wpa_supplicant/aidl/Android.bp
index b4ddae9..0785fe1 100644
--- a/wpa_supplicant/hidl/1.4/Android.bp
+++ b/wpa_supplicant/aidl/Android.bp
@@ -14,29 +14,28 @@
 
 package {
     // See: http://go/android-license-faq
-    // Inherits SPDX-license-identifier-BSD-3-Clause
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "external_wpa_supplicant_8_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-BSD
     default_applicable_licenses: ["external_wpa_supplicant_8_license"],
 }
 
 cc_library_headers {
-    name: "libwpa_hidl_headers",
+    name: "libwpa_aidl_headers",
     export_include_dirs: ["."],
     soc_specific: true,
 }
 
 cc_library_static {
-    name: "libwpa_hidl_bp",
+    name: "libwpa_aidl_bp",
     srcs: ["*.cpp"],
     defaults: ["wpa_supplicant_cflags_defaults"],
     soc_specific: true,
     shared_libs: [
-        "android.hardware.wifi.supplicant@1.0",
-        "android.hardware.wifi.supplicant@1.1",
-        "android.hardware.wifi.supplicant@1.2",
-        "android.hardware.wifi.supplicant@1.3",
-        "android.hardware.wifi.supplicant@1.4",
+        "android.hardware.wifi.supplicant-V1-ndk",
+        "libbinder_ndk",
         "libbase",
-        "libhidlbase",
         "libutils",
         "liblog",
         "libssl",
@@ -51,7 +50,7 @@
     ],
     header_libs: [
         "wpa_supplicant_headers",
-        "libwpa_hidl_headers",
+        "libwpa_aidl_headers",
     ],
 }
 
diff --git a/wpa_supplicant/aidl/aidl.cpp b/wpa_supplicant/aidl/aidl.cpp
new file mode 100644
index 0000000..f078e71
--- /dev/null
+++ b/wpa_supplicant/aidl/aidl.cpp
@@ -0,0 +1,963 @@
+/*
+ * WPA Supplicant - Aidl entry point to wpa_supplicant core
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include <android/binder_process.h>
+#include <android/binder_manager.h>
+
+#include "aidl_manager.h"
+
+extern "C"
+{
+#include "aidl.h"
+#include "aidl_i.h"
+#include "utils/common.h"
+#include "utils/eloop.h"
+#include "utils/includes.h"
+#include "dpp.h"
+}
+
+using aidl::android::hardware::wifi::supplicant::AidlManager;
+using aidl::android::hardware::wifi::supplicant::DppEventType;
+using aidl::android::hardware::wifi::supplicant::DppFailureCode;
+using aidl::android::hardware::wifi::supplicant::DppProgressCode;
+
+static void wpas_aidl_notify_dpp_failure(struct wpa_supplicant *wpa_s, DppFailureCode code);
+static void wpas_aidl_notify_dpp_progress(struct wpa_supplicant *wpa_s, DppProgressCode code);
+static void wpas_aidl_notify_dpp_success(struct wpa_supplicant *wpa_s, DppEventType code);
+
+void wpas_aidl_sock_handler(
+	int /* sock */, void * /* eloop_ctx */, void * /* sock_ctx */)
+{
+	ABinderProcess_handlePolledCommands();
+}
+
+struct wpas_aidl_priv *wpas_aidl_init(struct wpa_global *global)
+{
+	struct wpas_aidl_priv *priv;
+	AidlManager *aidl_manager;
+
+	priv = (wpas_aidl_priv *)os_zalloc(sizeof(*priv));
+	if (!priv)
+		return NULL;
+	priv->global = global;
+
+	wpa_printf(MSG_DEBUG, "Initing aidl control");
+
+	ABinderProcess_setupPolling(&priv->aidl_fd);
+	if (priv->aidl_fd < 0)
+		goto err;
+
+	wpa_printf(MSG_INFO, "Processing aidl events on FD %d", priv->aidl_fd);
+	// Look for read events from the aidl socket in the eloop.
+	if (eloop_register_read_sock(
+		priv->aidl_fd, wpas_aidl_sock_handler, global, priv) < 0)
+		goto err;
+
+	aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		goto err;
+	if (aidl_manager->registerAidlService(global)) {
+		goto err;
+	}
+	// We may not need to store this aidl manager reference in the
+	// global data strucure because we've made it a singleton class.
+	priv->aidl_manager = (void *)aidl_manager;
+
+	return priv;
+err:
+	wpas_aidl_deinit(priv);
+	return NULL;
+}
+
+void wpas_aidl_deinit(struct wpas_aidl_priv *priv)
+{
+	if (!priv)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Deiniting aidl control");
+
+	AidlManager::destroyInstance();
+	eloop_unregister_read_sock(priv->aidl_fd);
+	os_free(priv);
+}
+
+int wpas_aidl_register_interface(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s || !wpa_s->global->aidl)
+		return 1;
+
+	wpa_printf(
+		MSG_DEBUG, "Registering interface to aidl control: %s",
+		wpa_s->ifname);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return 1;
+
+	return aidl_manager->registerInterface(wpa_s);
+}
+
+int wpas_aidl_unregister_interface(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s || !wpa_s->global->aidl)
+		return 1;
+
+	wpa_printf(
+		MSG_DEBUG, "Deregistering interface from aidl control: %s",
+		wpa_s->ifname);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return 1;
+
+	return aidl_manager->unregisterInterface(wpa_s);
+}
+
+int wpas_aidl_register_network(
+	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
+{
+	if (!wpa_s || !wpa_s->global->aidl || !ssid)
+		return 1;
+
+	wpa_printf(
+		MSG_DEBUG, "Registering network to aidl control: %d", ssid->id);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return 1;
+
+	return aidl_manager->registerNetwork(wpa_s, ssid);
+}
+
+int wpas_aidl_unregister_network(
+	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
+{
+	if (!wpa_s || !wpa_s->global->aidl || !ssid)
+		return 1;
+
+	wpa_printf(
+		MSG_DEBUG, "Deregistering network from aidl control: %d", ssid->id);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return 1;
+
+	return aidl_manager->unregisterNetwork(wpa_s, ssid);
+}
+
+int wpas_aidl_notify_state_changed(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s || !wpa_s->global->aidl)
+		return 1;
+
+	wpa_printf(
+		MSG_DEBUG, "Notifying state change event to aidl control: %d",
+		wpa_s->wpa_state);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return 1;
+
+	return aidl_manager->notifyStateChange(wpa_s);
+}
+
+int wpas_aidl_notify_network_request(
+	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
+	enum wpa_ctrl_req_type rtype, const char *default_txt)
+{
+	if (!wpa_s || !wpa_s->global->aidl || !ssid)
+		return 1;
+
+	wpa_printf(
+		MSG_DEBUG, "Notifying network request to aidl control: %d",
+		ssid->id);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return 1;
+
+	return aidl_manager->notifyNetworkRequest(
+		wpa_s, ssid, rtype, default_txt);
+}
+
+void wpas_aidl_notify_anqp_query_done(
+	struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
+	const struct wpa_bss_anqp *anqp)
+{
+	if (!wpa_s || !wpa_s->global->aidl || !bssid || !result || !anqp)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying ANQP query done to aidl control: " MACSTR "result: %s",
+		MAC2STR(bssid), result);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyAnqpQueryDone(wpa_s, bssid, result, anqp);
+}
+
+void wpas_aidl_notify_hs20_icon_query_done(
+	struct wpa_supplicant *wpa_s, const u8 *bssid, const char *file_name,
+	const u8 *image, u32 image_length)
+{
+	if (!wpa_s || !wpa_s->global->aidl || !bssid || !file_name || !image)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying HS20 icon query done to aidl control: " MACSTR
+		"file_name: %s",
+		MAC2STR(bssid), file_name);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyHs20IconQueryDone(
+		wpa_s, bssid, file_name, image, image_length);
+}
+
+void wpas_aidl_notify_hs20_rx_subscription_remediation(
+	struct wpa_supplicant *wpa_s, const char *url, u8 osu_method)
+{
+	if (!wpa_s || !wpa_s->global->aidl || !url)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying HS20 subscription remediation rx to aidl control: %s",
+		url);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyHs20RxSubscriptionRemediation(
+		wpa_s, url, osu_method);
+}
+
+void wpas_aidl_notify_hs20_rx_deauth_imminent_notice(
+	struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay, const char *url)
+{
+	if (!wpa_s || !wpa_s->global->aidl)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying HS20 deauth imminent notice rx to aidl control: %s",
+		url ? url : "<no URL>");
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyHs20RxDeauthImminentNotice(
+		wpa_s, code, reauth_delay, url);
+}
+
+void wpas_aidl_notify_hs20_rx_terms_and_conditions_acceptance(
+		struct wpa_supplicant *wpa_s, const char *url)
+{
+	if (!wpa_s || !wpa_s->global->aidl || !url)
+		return;
+
+	wpa_printf(MSG_DEBUG,
+			"Notifying HS20 terms and conditions acceptance rx to aidl control: %s",
+			url);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyHs20RxTermsAndConditionsAcceptance(wpa_s, url);
+}
+
+void wpas_aidl_notify_disconnect_reason(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG, "Notifying disconnect reason to aidl control: %d",
+		wpa_s->disconnect_reason);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyDisconnectReason(wpa_s);
+}
+
+void wpas_aidl_notify_assoc_reject(struct wpa_supplicant *wpa_s,
+	const u8 *bssid, u8 timed_out, const u8 *assoc_resp_ie, size_t assoc_resp_ie_len)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG, "Notifying assoc reject to aidl control: %d",
+		wpa_s->assoc_status_code);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyAssocReject(wpa_s, bssid, timed_out, assoc_resp_ie, assoc_resp_ie_len);
+}
+
+void wpas_aidl_notify_auth_timeout(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Notifying auth timeout to aidl control");
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyAuthTimeout(wpa_s);
+}
+
+void wpas_aidl_notify_bssid_changed(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Notifying bssid changed to aidl control");
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyBssidChanged(wpa_s);
+}
+
+void wpas_aidl_notify_wps_event_fail(
+	struct wpa_supplicant *wpa_s, uint8_t *peer_macaddr, uint16_t config_error,
+	uint16_t error_indication)
+{
+	if (!wpa_s || !peer_macaddr)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG, "Notifying Wps event fail to aidl control: %d, %d",
+		config_error, error_indication);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyWpsEventFail(
+		wpa_s, peer_macaddr, config_error, error_indication);
+}
+
+void wpas_aidl_notify_wps_event_success(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Notifying Wps event success to aidl control");
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyWpsEventSuccess(wpa_s);
+}
+
+void wpas_aidl_notify_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG, "Notifying Wps event PBC overlap to aidl control");
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyWpsEventPbcOverlap(wpa_s);
+}
+
+void wpas_aidl_notify_p2p_device_found(
+	struct wpa_supplicant *wpa_s, const u8 *addr,
+	const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
+	u8 peer_wfd_device_info_len, const u8 *peer_wfd_r2_device_info,
+	u8 peer_wfd_r2_device_info_len)
+{
+	if (!wpa_s || !addr || !info)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG, "Notifying P2P device found to aidl control " MACSTR,
+		MAC2STR(info->p2p_device_addr));
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pDeviceFound(
+		wpa_s, addr, info, peer_wfd_device_info,
+		peer_wfd_device_info_len, peer_wfd_r2_device_info,
+		peer_wfd_r2_device_info_len);
+}
+
+void wpas_aidl_notify_p2p_device_lost(
+	struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr)
+{
+	if (!wpa_s || !p2p_device_addr)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG, "Notifying P2P device lost to aidl control " MACSTR,
+		MAC2STR(p2p_device_addr));
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pDeviceLost(wpa_s, p2p_device_addr);
+}
+
+void wpas_aidl_notify_p2p_find_stopped(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Notifying P2P find stop to aidl control");
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pFindStopped(wpa_s);
+}
+
+void wpas_aidl_notify_p2p_go_neg_req(
+	struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
+	u8 go_intent)
+{
+	if (!wpa_s || !src_addr)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying P2P GO negotiation request to aidl control " MACSTR,
+		MAC2STR(src_addr));
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pGoNegReq(
+		wpa_s, src_addr, dev_passwd_id, go_intent);
+}
+
+void wpas_aidl_notify_p2p_go_neg_completed(
+	struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res)
+{
+	if (!wpa_s || !res)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying P2P GO negotiation completed to aidl control: %d",
+		res->status);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pGoNegCompleted(wpa_s, res);
+}
+
+void wpas_aidl_notify_p2p_group_formation_failure(
+	struct wpa_supplicant *wpa_s, const char *reason)
+{
+	if (!wpa_s || !reason)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying P2P Group formation failure to aidl control: %s",
+		reason);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pGroupFormationFailure(wpa_s, reason);
+}
+
+void wpas_aidl_notify_p2p_group_started(
+	struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid, int persistent,
+	int client)
+{
+	if (!wpa_s || !ssid)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG, "Notifying P2P Group start to aidl control: %d",
+		ssid->id);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pGroupStarted(wpa_s, ssid, persistent, client);
+}
+
+void wpas_aidl_notify_p2p_group_removed(
+	struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid, const char *role)
+{
+	if (!wpa_s || !ssid || !role)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG, "Notifying P2P Group removed to aidl control: %d",
+		ssid->id);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pGroupRemoved(wpa_s, ssid, role);
+}
+
+void wpas_aidl_notify_p2p_invitation_received(
+	struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
+	const u8 *bssid, int id, int op_freq)
+{
+	if (!wpa_s || !sa || !go_dev_addr || !bssid)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying P2P invitation received to aidl control: %d " MACSTR, id,
+		MAC2STR(bssid));
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pInvitationReceived(
+		wpa_s, sa, go_dev_addr, bssid, id, op_freq);
+}
+
+void wpas_aidl_notify_p2p_invitation_result(
+	struct wpa_supplicant *wpa_s, int status, const u8 *bssid)
+{
+	if (!wpa_s)
+		return;
+	if (bssid) {
+		wpa_printf(
+			MSG_DEBUG,
+			"Notifying P2P invitation result to aidl control: " MACSTR,
+			MAC2STR(bssid));
+	} else {
+		wpa_printf(
+			MSG_DEBUG,
+			"Notifying P2P invitation result to aidl control: NULL "
+			"bssid");
+	}
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pInvitationResult(wpa_s, status, bssid);
+}
+
+void wpas_aidl_notify_p2p_provision_discovery(
+	struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
+	enum p2p_prov_disc_status status, u16 config_methods,
+	unsigned int generated_pin)
+{
+	if (!wpa_s || !dev_addr)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying P2P provision discovery to aidl control " MACSTR,
+		MAC2STR(dev_addr));
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pProvisionDiscovery(
+		wpa_s, dev_addr, request, status, config_methods, generated_pin);
+}
+
+void wpas_aidl_notify_p2p_sd_response(
+	struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
+	const u8 *tlvs, size_t tlvs_len)
+{
+	if (!wpa_s || !sa || !tlvs)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying P2P service discovery response to aidl control " MACSTR,
+		MAC2STR(sa));
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyP2pSdResponse(
+		wpa_s, sa, update_indic, tlvs, tlvs_len);
+}
+
+void wpas_aidl_notify_ap_sta_authorized(
+	struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
+{
+	if (!wpa_s || !sta)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying P2P AP STA authorized to aidl control " MACSTR,
+		MAC2STR(sta));
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyApStaAuthorized(wpa_s, sta, p2p_dev_addr);
+}
+
+void wpas_aidl_notify_ap_sta_deauthorized(
+	struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
+{
+	if (!wpa_s || !sta)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying P2P AP STA deauthorized to aidl control " MACSTR,
+		MAC2STR(sta));
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyApStaDeauthorized(wpa_s, sta, p2p_dev_addr);
+}
+
+void wpas_aidl_notify_eap_error(struct wpa_supplicant *wpa_s, int error_code)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Notifying EAP Error: %d ", error_code);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyEapError(wpa_s, error_code);
+}
+
+void wpas_aidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
+		struct wpa_ssid *ssid)
+{
+	if (!wpa_s || !ssid)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying DPP configuration received for SSID %d", ssid->id);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyDppConfigReceived(wpa_s, ssid);
+}
+
+void wpas_aidl_notify_dpp_config_sent(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_success(wpa_s, DppEventType::CONFIGURATION_SENT);
+}
+
+/* DPP Progress notifications */
+void wpas_aidl_notify_dpp_auth_success(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_progress(wpa_s, DppProgressCode::AUTHENTICATION_SUCCESS);
+}
+
+void wpas_aidl_notify_dpp_resp_pending(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_progress(wpa_s, DppProgressCode::RESPONSE_PENDING);
+}
+
+/* DPP Failure notifications */
+void wpas_aidl_notify_dpp_not_compatible(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_failure(wpa_s, DppFailureCode::NOT_COMPATIBLE);
+}
+
+void wpas_aidl_notify_dpp_missing_auth(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_failure(wpa_s, DppFailureCode::AUTHENTICATION);
+}
+
+void wpas_aidl_notify_dpp_configuration_failure(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_failure(wpa_s, DppFailureCode::CONFIGURATION);
+}
+
+void wpas_aidl_notify_dpp_timeout(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_failure(wpa_s, DppFailureCode::TIMEOUT);
+}
+
+void wpas_aidl_notify_dpp_auth_failure(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_failure(wpa_s, DppFailureCode::AUTHENTICATION);
+}
+
+void wpas_aidl_notify_dpp_fail(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_failure(wpa_s, DppFailureCode::FAILURE);
+}
+
+void wpas_aidl_notify_dpp_config_sent_wait_response(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_progress(wpa_s, DppProgressCode::CONFIGURATION_SENT_WAITING_RESPONSE);
+}
+
+/* DPP notification helper functions */
+static void wpas_aidl_notify_dpp_failure(struct wpa_supplicant *wpa_s, DppFailureCode code)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying DPP failure event %d", code);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyDppFailure(wpa_s, code);
+}
+
+static void wpas_aidl_notify_dpp_progress(struct wpa_supplicant *wpa_s, DppProgressCode code)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying DPP progress event %d", code);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyDppProgress(wpa_s, code);
+}
+
+void wpas_aidl_notify_dpp_config_accepted(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_progress(wpa_s, DppProgressCode::CONFIGURATION_ACCEPTED);
+}
+
+static void wpas_aidl_notify_dpp_config_applied(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_success(wpa_s, DppEventType::CONFIGURATION_APPLIED);
+}
+
+static void wpas_aidl_notify_dpp_success(struct wpa_supplicant *wpa_s, DppEventType code)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying DPP progress event %d", code);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyDppSuccess(wpa_s, code);
+}
+
+void wpas_aidl_notify_dpp_config_rejected(struct wpa_supplicant *wpa_s)
+{
+	wpas_aidl_notify_dpp_failure(wpa_s, DppFailureCode::CONFIGURATION_REJECTED);
+}
+
+static void wpas_aidl_notify_dpp_no_ap_failure(struct wpa_supplicant *wpa_s,
+		const char *ssid, const char *channel_list, unsigned short band_list[],
+		int size)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(MSG_DEBUG,
+			"Notifying DPP NO AP event for SSID %s\nTried channels: %s",
+			ssid ? ssid : "N/A", channel_list ? channel_list : "N/A");
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyDppFailure(wpa_s, DppFailureCode::CANNOT_FIND_NETWORK,
+			ssid, channel_list, band_list, size);
+}
+
+void wpas_aidl_notify_dpp_enrollee_auth_failure(struct wpa_supplicant *wpa_s,
+		const char *ssid, unsigned short band_list[], int size)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(MSG_DEBUG,
+			"Notifying DPP Enrollee authentication failure, SSID %s",
+			ssid ? ssid : "N/A");
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyDppFailure(wpa_s, DppFailureCode::ENROLLEE_AUTHENTICATION,
+			ssid, NULL, band_list, size);
+}
+
+
+void wpas_aidl_notify_dpp_conn_status(struct wpa_supplicant *wpa_s, enum dpp_status_error status,
+		const char *ssid, const char *channel_list, unsigned short band_list[], int size)
+{
+	switch (status)
+	{
+	case DPP_STATUS_OK:
+		wpas_aidl_notify_dpp_config_applied(wpa_s);
+		break;
+
+	case DPP_STATUS_NO_AP:
+		wpas_aidl_notify_dpp_no_ap_failure(wpa_s, ssid, channel_list, band_list, size);
+		break;
+
+	case DPP_STATUS_AUTH_FAILURE:
+		wpas_aidl_notify_dpp_enrollee_auth_failure(wpa_s, ssid, band_list, size);
+		break;
+
+	default:
+		break;
+	}
+}
+
+void wpas_aidl_notify_pmk_cache_added(
+	struct wpa_supplicant *wpa_s,
+	struct rsn_pmksa_cache_entry *pmksa_entry)
+{
+	if (!wpa_s || !pmksa_entry)
+		return;
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	wpa_printf(
+		MSG_DEBUG,
+		"Notifying PMK cache added event");
+
+	aidl_manager->notifyPmkCacheAdded(wpa_s, pmksa_entry);
+}
+
+void wpas_aidl_notify_bss_tm_status(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Notifying BSS transition status");
+
+	aidl_manager->notifyBssTmStatus(wpa_s);
+}
+
+void wpas_aidl_notify_transition_disable(struct wpa_supplicant *wpa_s,
+						struct wpa_ssid *ssid,
+						u8 bitmap)
+{
+	if (!wpa_s || !ssid)
+		return;
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	aidl_manager->notifyTransitionDisable(wpa_s, ssid, bitmap);
+}
+
+void wpas_aidl_notify_network_not_found(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Notify network not found");
+
+	aidl_manager->notifyNetworkNotFound(wpa_s);
+}
+
+void wpas_aidl_notify_bss_freq_changed(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Notify %s frequency changed to %d",
+	    wpa_s->ifname, wpa_s->assoc_freq);
+
+	aidl_manager->notifyBssFreqChanged(wpa_s);
+}
+
+void wpas_aidl_notify_ceritification(struct wpa_supplicant *wpa_s,
+		int depth, const char *subject,
+		const char *altsubject[],
+		int num_altsubject,
+		const char *cert_hash,
+		const struct wpabuf *cert)
+{
+	if (!wpa_s)
+		return;
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager)
+		return;
+
+	wpa_printf(MSG_DEBUG, "Notify certification");
+
+	aidl_manager->notifyCertification(wpa_s,
+			depth,
+			subject,
+			altsubject,
+			num_altsubject,
+			cert_hash,
+			cert);
+}
diff --git a/wpa_supplicant/aidl/aidl.h b/wpa_supplicant/aidl/aidl.h
new file mode 100644
index 0000000..71275e3
--- /dev/null
+++ b/wpa_supplicant/aidl/aidl.h
@@ -0,0 +1,302 @@
+/*
+ * WPA Supplicant - Aidl entry point to wpa_supplicant core
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef WPA_SUPPLICANT_AIDL_AIDL_H
+#define WPA_SUPPLICANT_AIDL_AIDL_H
+
+#ifdef _cplusplus
+extern "C"
+{
+#endif  // _cplusplus
+
+	/**
+	 * This is the aidl RPC interface entry point to the wpa_supplicant
+	 * core. This initializes the aidl driver & AidlManager instance and
+	 * then forwards all the notifcations from the supplicant core to the
+	 * AidlManager.
+	 */
+	struct wpas_aidl_priv;
+	struct wpa_global;
+
+	struct wpas_aidl_priv *wpas_aidl_init(struct wpa_global *global);
+	void wpas_aidl_deinit(struct wpas_aidl_priv *priv);
+
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	int wpas_aidl_register_interface(struct wpa_supplicant *wpa_s);
+	int wpas_aidl_unregister_interface(struct wpa_supplicant *wpa_s);
+	int wpas_aidl_register_network(
+		struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
+	int wpas_aidl_unregister_network(
+		struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
+	int wpas_aidl_notify_state_changed(struct wpa_supplicant *wpa_s);
+	int wpas_aidl_notify_network_request(
+		struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
+		enum wpa_ctrl_req_type rtype, const char *default_txt);
+	void wpas_aidl_notify_anqp_query_done(
+		struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
+		const struct wpa_bss_anqp *anqp);
+	void wpas_aidl_notify_hs20_icon_query_done(
+		struct wpa_supplicant *wpa_s, const u8 *bssid,
+		const char *file_name, const u8 *image, u32 image_length);
+	void wpas_aidl_notify_hs20_rx_subscription_remediation(
+		struct wpa_supplicant *wpa_s, const char *url, u8 osu_method);
+	void wpas_aidl_notify_hs20_rx_deauth_imminent_notice(
+		struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay,
+		const char *url);
+	void wpas_aidl_notify_hs20_rx_terms_and_conditions_acceptance(
+			struct wpa_supplicant *wpa_s, const char *url);
+	void wpas_aidl_notify_disconnect_reason(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_assoc_reject(struct wpa_supplicant *wpa_s, const u8 *bssid,
+		u8 timed_out, const u8 *assoc_resp_ie, size_t assoc_resp_ie_len);
+	void wpas_aidl_notify_auth_timeout(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_bssid_changed(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_wps_event_fail(
+		struct wpa_supplicant *wpa_s, uint8_t *peer_macaddr,
+		uint16_t config_error, uint16_t error_indication);
+	void wpas_aidl_notify_wps_event_success(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_wps_event_pbc_overlap(
+		struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_p2p_device_found(
+		struct wpa_supplicant *wpa_s, const u8 *addr,
+		const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
+		u8 peer_wfd_device_info_len, const u8 *peer_wfd_r2_device_info,
+		u8 peer_wfd_r2_device_info_len);
+	void wpas_aidl_notify_p2p_device_lost(
+		struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr);
+	void wpas_aidl_notify_p2p_find_stopped(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_p2p_go_neg_req(
+		struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
+		u8 go_intent);
+	void wpas_aidl_notify_p2p_go_neg_completed(
+		struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res);
+	void wpas_aidl_notify_p2p_group_formation_failure(
+		struct wpa_supplicant *wpa_s, const char *reason);
+	void wpas_aidl_notify_p2p_group_started(
+		struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid,
+		int persistent, int client);
+	void wpas_aidl_notify_p2p_group_removed(
+		struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid,
+		const char *role);
+	void wpas_aidl_notify_p2p_invitation_received(
+		struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
+		const u8 *bssid, int id, int op_freq);
+	void wpas_aidl_notify_p2p_invitation_result(
+		struct wpa_supplicant *wpa_s, int status, const u8 *bssid);
+	void wpas_aidl_notify_p2p_provision_discovery(
+		struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
+		enum p2p_prov_disc_status status, u16 config_methods,
+		unsigned int generated_pin);
+	void wpas_aidl_notify_p2p_sd_response(
+		struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
+		const u8 *tlvs, size_t tlvs_len);
+	void wpas_aidl_notify_ap_sta_authorized(
+		struct wpa_supplicant *wpa_s, const u8 *sta,
+		const u8 *p2p_dev_addr);
+	void wpas_aidl_notify_ap_sta_deauthorized(
+		struct wpa_supplicant *wpa_s, const u8 *sta,
+		const u8 *p2p_dev_addr);
+	void wpas_aidl_notify_eap_error(
+		struct wpa_supplicant *wpa_s, int error_code);
+	void wpas_aidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
+			struct wpa_ssid *ssid);
+	void wpas_aidl_notify_dpp_config_sent(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_auth_success(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_resp_pending(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_not_compatible(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_missing_auth(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_configuration_failure(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_invalid_uri(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_timeout(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_auth_failure(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_fail(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_config_sent_wait_response(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_config_accepted(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_config_rejected(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_dpp_conn_status(struct wpa_supplicant *wpa_s,
+		enum dpp_status_error status, const char *ssid,
+		const char *channel_list, unsigned short band_list[], int size);
+	void wpas_aidl_notify_pmk_cache_added(
+		struct wpa_supplicant *wpas, struct rsn_pmksa_cache_entry *pmksa_entry);
+	void wpas_aidl_notify_bss_tm_status(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_transition_disable(
+		struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, u8 bitmap);
+	void wpas_aidl_notify_network_not_found(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_bss_freq_changed(struct wpa_supplicant *wpa_s);
+	void wpas_aidl_notify_ceritification(struct wpa_supplicant *wpa_s,
+		int depth, const char *subject,
+		const char *altsubject[],
+		int num_altsubject,
+		const char *cert_hash,
+		const struct wpabuf *cert);
+#else   // CONFIG_CTRL_IFACE_AIDL
+static inline int wpas_aidl_register_interface(struct wpa_supplicant *wpa_s)
+{
+	return 0;
+}
+static inline int wpas_aidl_unregister_interface(struct wpa_supplicant *wpa_s)
+{
+	return 0;
+}
+static inline int wpas_aidl_register_network(
+	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
+{
+	return 0;
+}
+static inline int wpas_aidl_unregister_network(
+	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
+{
+	return 0;
+}
+static inline int wpas_aidl_notify_state_changed(struct wpa_supplicant *wpa_s)
+{
+	return 0;
+}
+static inline int wpas_aidl_notify_network_request(
+	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
+	enum wpa_ctrl_req_type rtype, const char *default_txt)
+{
+	return 0;
+}
+static void wpas_aidl_notify_anqp_query_done(
+	struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
+	const struct wpa_bss_anqp *anqp)
+{}
+static void wpas_aidl_notify_hs20_icon_query_done(
+	struct wpa_supplicant *wpa_s, const u8 *bssid, const char *file_name,
+	const u8 *image, u32 image_length)
+{}
+static void wpas_aidl_notify_hs20_rx_subscription_remediation(
+	struct wpa_supplicant *wpa_s, const char *url, u8 osu_method)
+{}
+static void wpas_aidl_notify_hs20_rx_deauth_imminent_notice(
+	struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay, const char *url)
+{}
+void wpas_aidl_notify_hs20_rx_terms_and_conditions_acceptance(
+		struct wpa_supplicant *wpa_s, const char *url)
+{}
+static void wpas_aidl_notify_disconnect_reason(struct wpa_supplicant *wpa_s) {}
+static void wpas_aidl_notify_assoc_reject(struct wpa_supplicant *wpa_s, const u8 *bssid,
+	u8 timed_out, const u8 *assoc_resp_ie, size_t assoc_resp_ie_len) {}
+static void wpas_aidl_notify_auth_timeout(struct wpa_supplicant *wpa_s) {}
+static void wpas_aidl_notify_wps_event_fail(
+	struct wpa_supplicant *wpa_s, uint8_t *peer_macaddr, uint16_t config_error,
+	uint16_t error_indication)
+{}
+static void wpas_aidl_notify_bssid_changed(struct wpa_supplicant *wpa_s) {}
+static void wpas_aidl_notify_wps_event_success(struct wpa_supplicant *wpa_s) {}
+static void wpas_aidl_notify_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_p2p_device_found(
+	struct wpa_supplicant *wpa_s, const u8 *addr,
+	const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
+	u8 peer_wfd_device_info_len)
+{}
+static void wpas_aidl_notify_p2p_device_lost(
+	struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr)
+{}
+static void wpas_aidl_notify_p2p_find_stopped(struct wpa_supplicant *wpa_s) {}
+static void wpas_aidl_notify_p2p_go_neg_req(
+	struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
+	u8 go_intent)
+{}
+static void wpas_aidl_notify_p2p_go_neg_completed(
+	struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res)
+{}
+static void wpas_aidl_notify_p2p_group_formation_failure(
+	struct wpa_supplicant *wpa_s, const char *reason)
+{}
+static void wpas_aidl_notify_p2p_group_started(
+	struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid, int persistent,
+	int client)
+{}
+static void wpas_aidl_notify_p2p_group_removed(
+	struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid, const char *role)
+{}
+static void wpas_aidl_notify_p2p_invitation_received(
+	struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
+	const u8 *bssid, int id, int op_freq)
+{}
+static void wpas_aidl_notify_p2p_invitation_result(
+	struct wpa_supplicant *wpa_s, int status, const u8 *bssid)
+{}
+static void wpas_aidl_notify_p2p_provision_discovery(
+	struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
+	enum p2p_prov_disc_status status, u16 config_methods,
+	unsigned int generated_pin)
+{}
+static void wpas_aidl_notify_p2p_sd_response(
+	struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
+	const u8 *tlvs, size_t tlvs_len)
+{}
+static void wpas_aidl_notify_ap_sta_authorized(
+	struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
+{}
+static void wpas_aidl_notify_ap_sta_deauthorized(
+	struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
+{}
+static void wpas_aidl_notify_eap_error(
+	struct wpa_supplicant *wpa_s, int error_code)
+{}
+static void wpas_aidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
+		struct wpa_ssid *ssid)
+{}
+static void wpas_aidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
+		struct wpa_ssid *ssid);
+static void wpas_aidl_notify_dpp_config_sent(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_dpp_auth_success(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_dpp_resp_pending(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_dpp_not_compatible(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_dpp_missing_auth(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_dpp_configuration_failure(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_dpp_invalid_uri(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_dpp_timeout(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_dpp_failure(struct wpa_supplicant *wpa_s)
+{}
+void wpas_aidl_notify_dpp_config_sent_wait_response(struct wpa_supplicant *wpa_s)
+{}
+void wpas_aidl_notify_dpp_config_accepted(struct wpa_supplicant *wpa_s)
+{}
+void wpas_aidl_notify_dpp_config_applied(struct wpa_supplicant *wpa_s)
+{}
+void wpas_aidl_notify_dpp_config_rejected(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_pmk_cache_added(struct wpa_supplicant *wpas,
+						 struct rsn_pmksa_cache_entry *pmksa_entry)
+{}
+void wpas_aidl_notify_bss_tm_status(struct wpa_supplicant *wpa_s)
+{}
+static void wpas_aidl_notify_transition_disable(struct wpa_supplicant *wpa_s,
+						struct wpa_ssid *ssid,
+						u8 bitmap)
+{}
+static void wpas_aidl_notify_network_not_found(struct wpa_supplicant *wpa_s)
+{}
+void wpas_aidl_notify_bss_freq_changed(struct wpa_supplicant *wpa_s)
+{}
+void wpas_aidl_notify_ceritification(struct wpa_supplicant *wpa_s,
+	int depth, const char *subject,
+	const char *altsubject[],
+	int num_altsubject,
+	const char *cert_hash,
+	const struct wpabuf *cert)
+{}
+#endif  // CONFIG_CTRL_IFACE_AIDL
+
+#ifdef _cplusplus
+}
+#endif  // _cplusplus
+
+#endif  // WPA_SUPPLICANT_AIDL_AIDL_H
diff --git a/wpa_supplicant/aidl/aidl_i.h b/wpa_supplicant/aidl/aidl_i.h
new file mode 100644
index 0000000..7f377cd
--- /dev/null
+++ b/wpa_supplicant/aidl/aidl_i.h
@@ -0,0 +1,28 @@
+/*
+ * WPA Supplicant - Global Aidl struct
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef AIDL_I_H
+#define AIDL_I_H
+
+#ifdef _cplusplus
+extern "C"
+{
+#endif  // _cplusplus
+
+	struct wpas_aidl_priv
+	{
+		int aidl_fd;
+		struct wpa_global *global;
+		void *aidl_manager;
+	};
+
+#ifdef _cplusplus
+}
+#endif  // _cplusplus
+
+#endif  // AIDL_I_H
diff --git a/wpa_supplicant/aidl/aidl_manager.cpp b/wpa_supplicant/aidl/aidl_manager.cpp
new file mode 100644
index 0000000..04e84b4
--- /dev/null
+++ b/wpa_supplicant/aidl/aidl_manager.cpp
@@ -0,0 +1,2316 @@
+/*
+ * WPA Supplicant - Manager for Aidl interface objects
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include <algorithm>
+#include <functional>
+#include <iostream>
+#include <regex>
+
+#include "aidl_manager.h"
+#include "misc_utils.h"
+#include <android/binder_process.h>
+#include <android/binder_manager.h>
+
+extern "C" {
+#include "scan.h"
+#include "src/eap_common/eap_sim_common.h"
+#include "list.h"
+}
+
+namespace {
+
+constexpr uint8_t kWfdDeviceInfoLen = 6;
+constexpr uint8_t kWfdR2DeviceInfoLen = 2;
+// GSM-AUTH:<RAND1>:<RAND2>[:<RAND3>]
+constexpr char kGsmAuthRegex2[] = "GSM-AUTH:([0-9a-f]+):([0-9a-f]+)";
+constexpr char kGsmAuthRegex3[] =
+	"GSM-AUTH:([0-9a-f]+):([0-9a-f]+):([0-9a-f]+)";
+// UMTS-AUTH:<RAND>:<AUTN>
+constexpr char kUmtsAuthRegex[] = "UMTS-AUTH:([0-9a-f]+):([0-9a-f]+)";
+constexpr size_t kGsmRandLenBytes = GSM_RAND_LEN;
+constexpr size_t kUmtsRandLenBytes = EAP_AKA_RAND_LEN;
+constexpr size_t kUmtsAutnLenBytes = EAP_AKA_AUTN_LEN;
+const std::vector<uint8_t> kZeroBssid = {0, 0, 0, 0, 0, 0};
+
+using aidl::android::hardware::wifi::supplicant::GsmRand;
+
+/**
+ * Check if the provided |wpa_supplicant| structure represents a P2P iface or
+ * not.
+ */
+constexpr bool isP2pIface(const struct wpa_supplicant *wpa_s)
+{
+	return wpa_s->global->p2p_init_wpa_s == wpa_s;
+}
+
+/**
+ * Creates a unique key for the network using the provided |ifname| and
+ * |network_id| to be used in the internal map of |ISupplicantNetwork| objects.
+ * This is of the form |ifname|_|network_id|. For ex: "wlan0_1".
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param network_id ID of the corresponding network.
+ */
+const std::string getNetworkObjectMapKey(
+	const std::string &ifname, int network_id)
+{
+	return ifname + "_" + std::to_string(network_id);
+}
+
+/**
+ * Add callback to the corresponding list after linking to death on the
+ * corresponding aidl object reference.
+ */
+template <class CallbackType>
+int registerForDeathAndAddCallbackAidlObjectToList(
+	AIBinder_DeathRecipient* death_notifier,
+	const std::shared_ptr<CallbackType> &callback,
+	std::vector<std::shared_ptr<CallbackType>> &callback_list)
+{
+	binder_status_t status = AIBinder_linkToDeath(callback->asBinder().get(),
+			death_notifier, nullptr /* cookie */);
+	if (status != STATUS_OK) {
+		wpa_printf(
+			MSG_ERROR,
+			"Error registering for death notification for "
+			"supplicant callback object");
+		return 1;
+	}
+	callback_list.push_back(callback);
+	return 0;
+}
+
+template <class ObjectType>
+int addAidlObjectToMap(
+	const std::string &key, const std::shared_ptr<ObjectType> &object,
+	std::map<const std::string, std::shared_ptr<ObjectType>> &object_map)
+{
+	// Return failure if we already have an object for that |key|.
+	if (object_map.find(key) != object_map.end())
+		return 1;
+	object_map[key] = object;
+	if (!object_map[key].get())
+		return 1;
+	return 0;
+}
+
+template <class ObjectType>
+int removeAidlObjectFromMap(
+	const std::string &key,
+	std::map<const std::string, std::shared_ptr<ObjectType>> &object_map)
+{
+	// Return failure if we dont have an object for that |key|.
+	const auto &object_iter = object_map.find(key);
+	if (object_iter == object_map.end())
+		return 1;
+	object_iter->second->invalidate();
+	object_map.erase(object_iter);
+	return 0;
+}
+
+template <class CallbackType>
+int addIfaceCallbackAidlObjectToMap(
+	AIBinder_DeathRecipient* death_notifier,
+	const std::string &ifname, const std::shared_ptr<CallbackType> &callback,
+	std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
+	&callbacks_map)
+{
+	if (ifname.empty())
+		return 1;
+
+	auto iface_callback_map_iter = callbacks_map.find(ifname);
+	if (iface_callback_map_iter == callbacks_map.end())
+		return 1;
+	auto &iface_callback_list = iface_callback_map_iter->second;
+
+	// Register for death notification before we add it to our list.
+	return registerForDeathAndAddCallbackAidlObjectToList<CallbackType>(
+		death_notifier, callback, iface_callback_list);
+}
+
+template <class CallbackType>
+int addNetworkCallbackAidlObjectToMap(
+	AIBinder_DeathRecipient* death_notifier,
+	const std::string &ifname, int network_id,
+	const std::shared_ptr<CallbackType> &callback,
+	std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
+	&callbacks_map)
+{
+	if (ifname.empty() || network_id < 0)
+		return 1;
+
+	// Generate the key to be used to lookup the network.
+	const std::string network_key =
+		getNetworkObjectMapKey(ifname, network_id);
+	auto network_callback_map_iter = callbacks_map.find(network_key);
+	if (network_callback_map_iter == callbacks_map.end())
+		return 1;
+	auto &network_callback_list = network_callback_map_iter->second;
+
+	// Register for death notification before we add it to our list.
+	return registerForDeathAndAddCallbackAidlObjectToList<CallbackType>(
+		death_notifier, callback, network_callback_list);
+}
+
+template <class CallbackType>
+int removeAllIfaceCallbackAidlObjectsFromMap(
+	AIBinder_DeathRecipient* death_notifier,
+	const std::string &ifname,
+	std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
+	&callbacks_map)
+{
+	auto iface_callback_map_iter = callbacks_map.find(ifname);
+	if (iface_callback_map_iter == callbacks_map.end())
+		return 1;
+	const auto &iface_callback_list = iface_callback_map_iter->second;
+	for (const auto &callback : iface_callback_list) {
+		binder_status_t status = AIBinder_linkToDeath(callback->asBinder().get(),
+				death_notifier, nullptr /* cookie */);
+		if (status != STATUS_OK) {
+			wpa_printf(
+				MSG_ERROR,
+				"Error deregistering for death notification for "
+				"iface callback object");
+		}
+	}
+	callbacks_map.erase(iface_callback_map_iter);
+	return 0;
+}
+
+template <class CallbackType>
+int removeAllNetworkCallbackAidlObjectsFromMap(
+	AIBinder_DeathRecipient* death_notifier,
+	const std::string &network_key,
+	std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
+	&callbacks_map)
+{
+	auto network_callback_map_iter = callbacks_map.find(network_key);
+	if (network_callback_map_iter == callbacks_map.end())
+		return 1;
+	const auto &network_callback_list = network_callback_map_iter->second;
+	for (const auto &callback : network_callback_list) {
+		binder_status_t status = AIBinder_linkToDeath(callback->asBinder().get(),
+				death_notifier, nullptr /* cookie */);
+		if (status != STATUS_OK) {
+			wpa_printf(
+				MSG_ERROR,
+				"Error deregistering for death "
+				"notification for "
+				"network callback object");
+		}
+	}
+	callbacks_map.erase(network_callback_map_iter);
+	return 0;
+}
+
+template <class CallbackType>
+void removeIfaceCallbackAidlObjectFromMap(
+	const std::string &ifname, const std::shared_ptr<CallbackType> &callback,
+	std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
+	&callbacks_map)
+{
+	if (ifname.empty())
+		return;
+
+	auto iface_callback_map_iter = callbacks_map.find(ifname);
+	if (iface_callback_map_iter == callbacks_map.end())
+		return;
+
+	auto &iface_callback_list = iface_callback_map_iter->second;
+	iface_callback_list.erase(
+		std::remove(
+		iface_callback_list.begin(), iface_callback_list.end(),
+		callback),
+		iface_callback_list.end());
+}
+
+template <class CallbackType>
+void removeNetworkCallbackAidlObjectFromMap(
+	const std::string &ifname, int network_id,
+	const std::shared_ptr<CallbackType> &callback,
+	std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
+	&callbacks_map)
+{
+	if (ifname.empty() || network_id < 0)
+		return;
+
+	// Generate the key to be used to lookup the network.
+	const std::string network_key =
+		getNetworkObjectMapKey(ifname, network_id);
+
+	auto network_callback_map_iter = callbacks_map.find(network_key);
+	if (network_callback_map_iter == callbacks_map.end())
+		return;
+
+	auto &network_callback_list = network_callback_map_iter->second;
+	network_callback_list.erase(
+		std::remove(
+		network_callback_list.begin(), network_callback_list.end(),
+		callback),
+		network_callback_list.end());
+}
+
+template <class CallbackType>
+void callWithEachIfaceCallback(
+	const std::string &ifname,
+	const std::function<ndk::ScopedAStatus(std::shared_ptr<CallbackType>)> &method,
+	const std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
+	&callbacks_map)
+{
+	if (ifname.empty())
+		return;
+
+	auto iface_callback_map_iter = callbacks_map.find(ifname);
+	if (iface_callback_map_iter == callbacks_map.end())
+		return;
+	const auto &iface_callback_list = iface_callback_map_iter->second;
+	for (const auto &callback : iface_callback_list) {
+		if (!method(callback).isOk()) {
+			wpa_printf(
+				MSG_ERROR, "Failed to invoke AIDL iface callback");
+		}
+	}
+}
+
+template <class CallbackType>
+void callWithEachNetworkCallback(
+	const std::string &ifname, int network_id,
+	const std::function<
+	ndk::ScopedAStatus(std::shared_ptr<CallbackType>)> &method,
+	const std::map<const std::string, std::vector<std::shared_ptr<CallbackType>>>
+	&callbacks_map)
+{
+	if (ifname.empty() || network_id < 0)
+		return;
+
+	// Generate the key to be used to lookup the network.
+	const std::string network_key =
+		getNetworkObjectMapKey(ifname, network_id);
+	auto network_callback_map_iter = callbacks_map.find(network_key);
+	if (network_callback_map_iter == callbacks_map.end())
+		return;
+	const auto &network_callback_list = network_callback_map_iter->second;
+	for (const auto &callback : network_callback_list) {
+		if (!method(callback).isOk()) {
+			wpa_printf(
+				MSG_ERROR,
+				"Failed to invoke AIDL network callback");
+		}
+	}
+}
+
+int parseGsmAuthNetworkRequest(
+	const std::string &params_str,
+	std::vector<GsmRand> *out_rands)
+{
+	std::smatch matches;
+	std::regex params_gsm_regex2(kGsmAuthRegex2);
+	std::regex params_gsm_regex3(kGsmAuthRegex3);
+	if (!std::regex_match(params_str, matches, params_gsm_regex3) &&
+		!std::regex_match(params_str, matches, params_gsm_regex2)) {
+		return 1;
+	}
+	for (uint32_t i = 1; i < matches.size(); i++) {
+		GsmRand rand;
+		rand.data = std::vector<uint8_t>(kGsmRandLenBytes);
+		const auto &match = matches[i];
+		WPA_ASSERT(match.size() >= 2 * rand.data.size());
+		if (hexstr2bin(match.str().c_str(), rand.data.data(), rand.data.size())) {
+			wpa_printf(MSG_ERROR, "Failed to parse GSM auth params");
+			return 1;
+		}
+		out_rands->push_back(rand);
+	}
+	return 0;
+}
+
+int parseUmtsAuthNetworkRequest(
+	const std::string &params_str,
+	std::vector<uint8_t> *out_rand,
+	std::vector<uint8_t> *out_autn)
+{
+	std::smatch matches;
+	std::regex params_umts_regex(kUmtsAuthRegex);
+	if (!std::regex_match(params_str, matches, params_umts_regex)) {
+		return 1;
+	}
+	WPA_ASSERT(matches[1].size() >= 2 * out_rand->size());
+	if (hexstr2bin(
+		matches[1].str().c_str(), out_rand->data(), out_rand->size())) {
+		wpa_printf(MSG_ERROR, "Failed to parse UMTS auth params");
+		return 1;
+	}
+	WPA_ASSERT(matches[2].size() >= 2 * out_autn->size());
+	if (hexstr2bin(
+		matches[2].str().c_str(), out_autn->data(), out_autn->size())) {
+		wpa_printf(MSG_ERROR, "Failed to parse UMTS auth params");
+		return 1;
+	}
+	return 0;
+}
+
+inline std::vector<uint8_t> byteArrToVec(const uint8_t* arr, int len) {
+	return std::vector<uint8_t>{arr, arr + len};
+}
+
+inline std::vector<uint8_t> macAddrToVec(const uint8_t* mac_addr) {
+	return byteArrToVec(mac_addr, ETH_ALEN);
+}
+
+// Raw pointer to the global structure maintained by the core.
+// Declared here to be accessible to onDeath()
+struct wpa_global *wpa_global_;
+
+void onDeath(void* cookie) {
+	wpa_printf(MSG_ERROR, "Client died. Terminating...");
+	wpa_supplicant_terminate_proc(wpa_global_);
+}
+
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+
+AidlManager *AidlManager::instance_ = NULL;
+
+AidlManager *AidlManager::getInstance()
+{
+	if (!instance_)
+		instance_ = new AidlManager();
+	return instance_;
+}
+
+void AidlManager::destroyInstance()
+{
+	if (instance_)
+		delete instance_;
+	instance_ = NULL;
+}
+
+int AidlManager::registerAidlService(struct wpa_global *global)
+{
+	// Create the main aidl service object and register it.
+	wpa_printf(MSG_INFO, "Starting AIDL supplicant");
+	supplicant_object_ = ndk::SharedRefBase::make<Supplicant>(global);
+	wpa_global_ = global;
+	std::string instance = std::string() + Supplicant::descriptor + "/default";
+	if (AServiceManager_addService(supplicant_object_->asBinder().get(),
+			instance.c_str()) != STATUS_OK)
+	{
+		return 1;
+	}
+
+	// Initialize the death notifier.
+	death_notifier_ = AIBinder_DeathRecipient_new(onDeath);
+	return 0;
+}
+
+/**
+ * Register an interface to aidl manager.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::registerInterface(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return 1;
+
+	if (isP2pIface(wpa_s)) {
+		if (addAidlObjectToMap<P2pIface>(
+			wpa_s->ifname,
+			ndk::SharedRefBase::make<P2pIface>(wpa_s->global, wpa_s->ifname),
+			p2p_iface_object_map_)) {
+			wpa_printf(
+				MSG_ERROR,
+				"Failed to register P2P interface with AIDL "
+				"control: %s",
+				wpa_s->ifname);
+			return 1;
+		}
+		p2p_iface_callbacks_map_[wpa_s->ifname] =
+			std::vector<std::shared_ptr<ISupplicantP2pIfaceCallback>>();
+	} else {
+		if (addAidlObjectToMap<StaIface>(
+			wpa_s->ifname,
+			ndk::SharedRefBase::make<StaIface>(wpa_s->global, wpa_s->ifname),
+			sta_iface_object_map_)) {
+			wpa_printf(
+				MSG_ERROR,
+				"Failed to register STA interface with AIDL "
+				"control: %s",
+				wpa_s->ifname);
+			return 1;
+		}
+		sta_iface_callbacks_map_[wpa_s->ifname] =
+			std::vector<std::shared_ptr<ISupplicantStaIfaceCallback>>();
+		// Turn on Android specific customizations for STA interfaces
+		// here!
+		//
+		// Turn on scan mac randomization only if driver supports.
+		if (wpa_s->mac_addr_rand_supported & MAC_ADDR_RAND_SCAN) {
+			if (wpas_mac_addr_rand_scan_set(
+				wpa_s, MAC_ADDR_RAND_SCAN, nullptr, nullptr)) {
+				wpa_printf(
+					MSG_ERROR,
+					"Failed to enable scan mac randomization");
+			}
+		}
+
+		// Enable randomized source MAC address for GAS/ANQP
+		// Set the lifetime to 0, guarantees a unique address for each GAS
+		// session
+		wpa_s->conf->gas_rand_mac_addr = 1;
+		wpa_s->conf->gas_rand_addr_lifetime = 0;
+	}
+
+	// Invoke the |onInterfaceCreated| method on all registered callbacks.
+	callWithEachSupplicantCallback(std::bind(
+		&ISupplicantCallback::onInterfaceCreated, std::placeholders::_1,
+		misc_utils::charBufToString(wpa_s->ifname)));
+	return 0;
+}
+
+/**
+ * Unregister an interface from aidl manager.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::unregisterInterface(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return 1;
+
+	// Check if this interface is present in P2P map first, else check in
+	// STA map.
+	// Note: We can't use isP2pIface() here because interface
+	// pointers (wpa_s->global->p2p_init_wpa_s == wpa_s) used by the helper
+	// function is cleared by the core before notifying the AIDL interface.
+	bool success =
+		!removeAidlObjectFromMap(wpa_s->ifname, p2p_iface_object_map_);
+	if (success) {  // assumed to be P2P
+		success = !removeAllIfaceCallbackAidlObjectsFromMap(
+			death_notifier_, wpa_s->ifname, p2p_iface_callbacks_map_);
+	} else {  // assumed to be STA
+		success = !removeAidlObjectFromMap(
+			wpa_s->ifname, sta_iface_object_map_);
+		if (success) {
+			success = !removeAllIfaceCallbackAidlObjectsFromMap(
+				death_notifier_, wpa_s->ifname, sta_iface_callbacks_map_);
+		}
+	}
+	if (!success) {
+		wpa_printf(
+			MSG_ERROR,
+			"Failed to unregister interface with AIDL "
+			"control: %s",
+			wpa_s->ifname);
+		return 1;
+	}
+
+	// Invoke the |onInterfaceRemoved| method on all registered callbacks.
+	callWithEachSupplicantCallback(std::bind(
+		&ISupplicantCallback::onInterfaceRemoved, std::placeholders::_1,
+		misc_utils::charBufToString(wpa_s->ifname)));
+	return 0;
+}
+
+/**
+ * Register a network to aidl manager.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
+ * the network is added.
+ * @param ssid |wpa_ssid| struct corresponding to the network being added.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::registerNetwork(
+	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
+{
+	if (!wpa_s || !ssid)
+		return 1;
+
+	// Generate the key to be used to lookup the network.
+	const std::string network_key =
+		getNetworkObjectMapKey(wpa_s->ifname, ssid->id);
+
+	if (isP2pIface(wpa_s)) {
+		if (addAidlObjectToMap<P2pNetwork>(
+			network_key,
+			ndk::SharedRefBase::make<P2pNetwork>(wpa_s->global, wpa_s->ifname, ssid->id),
+			p2p_network_object_map_)) {
+			wpa_printf(
+				MSG_ERROR,
+				"Failed to register P2P network with AIDL "
+				"control: %d",
+				ssid->id);
+			return 1;
+		}
+	} else {
+		if (addAidlObjectToMap<StaNetwork>(
+			network_key,
+			ndk::SharedRefBase::make<StaNetwork>(wpa_s->global, wpa_s->ifname, ssid->id),
+			sta_network_object_map_)) {
+			wpa_printf(
+				MSG_ERROR,
+				"Failed to register STA network with AIDL "
+				"control: %d",
+				ssid->id);
+			return 1;
+		}
+		sta_network_callbacks_map_[network_key] =
+			std::vector<std::shared_ptr<ISupplicantStaNetworkCallback>>();
+		// Invoke the |onNetworkAdded| method on all registered
+		// callbacks.
+		callWithEachStaIfaceCallback(
+			misc_utils::charBufToString(wpa_s->ifname),
+			std::bind(
+			&ISupplicantStaIfaceCallback::onNetworkAdded,
+			std::placeholders::_1, ssid->id));
+	}
+	return 0;
+}
+
+/**
+ * Unregister a network from aidl manager.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
+ * the network is added.
+ * @param ssid |wpa_ssid| struct corresponding to the network being added.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::unregisterNetwork(
+	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
+{
+	if (!wpa_s || !ssid)
+		return 1;
+
+	// Generate the key to be used to lookup the network.
+	const std::string network_key =
+		getNetworkObjectMapKey(wpa_s->ifname, ssid->id);
+
+	if (isP2pIface(wpa_s)) {
+		if (removeAidlObjectFromMap(
+			network_key, p2p_network_object_map_)) {
+			wpa_printf(
+				MSG_ERROR,
+				"Failed to unregister P2P network with AIDL "
+				"control: %d",
+				ssid->id);
+			return 1;
+		}
+	} else {
+		if (removeAidlObjectFromMap(
+			network_key, sta_network_object_map_)) {
+			wpa_printf(
+				MSG_ERROR,
+				"Failed to unregister STA network with AIDL "
+				"control: %d",
+				ssid->id);
+			return 1;
+		}
+		if (removeAllNetworkCallbackAidlObjectsFromMap(
+			death_notifier_, network_key, sta_network_callbacks_map_)) {
+			return 1;
+		}
+
+		// Invoke the |onNetworkRemoved| method on all registered
+		// callbacks.
+		callWithEachStaIfaceCallback(
+			misc_utils::charBufToString(wpa_s->ifname),
+			std::bind(
+			&ISupplicantStaIfaceCallback::onNetworkRemoved,
+			std::placeholders::_1, ssid->id));
+	}
+	return 0;
+}
+
+/**
+ * Notify all listeners about any state changes on a particular interface.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
+ * the state change event occured.
+ */
+int AidlManager::notifyStateChange(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return 1;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return 1;
+
+	// Invoke the |onStateChanged| method on all registered callbacks.
+	uint32_t aidl_network_id = UINT32_MAX;
+	std::vector<uint8_t> aidl_ssid;
+	if (wpa_s->current_ssid) {
+		aidl_network_id = wpa_s->current_ssid->id;
+		aidl_ssid.assign(
+			wpa_s->current_ssid->ssid,
+			wpa_s->current_ssid->ssid + wpa_s->current_ssid->ssid_len);
+	}
+	std::vector<uint8_t> bssid;
+	// wpa_supplicant sets the |pending_bssid| field when it starts a
+	// connection. Only after association state does it update the |bssid|
+	// field. So, in the AIDL callback send the appropriate bssid.
+	if (wpa_s->wpa_state <= WPA_ASSOCIATED) {
+		bssid = macAddrToVec(wpa_s->pending_bssid);
+	} else {
+		bssid = macAddrToVec(wpa_s->bssid);
+	}
+	bool fils_hlp_sent =
+		(wpa_auth_alg_fils(wpa_s->auth_alg) &&
+		 !dl_list_empty(&wpa_s->fils_hlp_req) &&
+		 (wpa_s->wpa_state == WPA_COMPLETED)) ? true : false;
+
+	// Invoke the |onStateChanged| method on all registered callbacks.
+	std::function<
+		ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
+		func = std::bind(
+			&ISupplicantStaIfaceCallback::onStateChanged,
+			std::placeholders::_1,
+			static_cast<StaIfaceCallbackState>(
+				wpa_s->wpa_state),
+				bssid, aidl_network_id, aidl_ssid,
+				fils_hlp_sent);
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname), func);
+	return 0;
+}
+
+/**
+ * Notify all listeners about a request on a particular network.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
+ * the network is present.
+ * @param ssid |wpa_ssid| struct corresponding to the network.
+ * @param type type of request.
+ * @param param addition params associated with the request.
+ */
+int AidlManager::notifyNetworkRequest(
+	struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int type,
+	const char *param)
+{
+	if (!wpa_s || !ssid)
+		return 1;
+
+	const std::string network_key =
+		getNetworkObjectMapKey(wpa_s->ifname, ssid->id);
+	if (sta_network_object_map_.find(network_key) ==
+		sta_network_object_map_.end())
+		return 1;
+
+	if (type == WPA_CTRL_REQ_EAP_IDENTITY) {
+		callWithEachStaNetworkCallback(
+			misc_utils::charBufToString(wpa_s->ifname),
+			ssid->id,
+			std::bind(
+			&ISupplicantStaNetworkCallback::
+				onNetworkEapIdentityRequest,
+			std::placeholders::_1));
+		return 0;
+	}
+	if (type == WPA_CTRL_REQ_SIM) {
+		std::vector<GsmRand> gsm_rands;
+		std::vector<uint8_t> umts_rand = std::vector<uint8_t>(16);
+		std::vector<uint8_t> umts_autn = std::vector<uint8_t>(16);
+		if (!parseGsmAuthNetworkRequest(param, &gsm_rands)) {
+			NetworkRequestEapSimGsmAuthParams aidl_params;
+			aidl_params.rands = gsm_rands;
+			callWithEachStaNetworkCallback(
+				misc_utils::charBufToString(wpa_s->ifname),
+				ssid->id,
+				std::bind(
+				&ISupplicantStaNetworkCallback::
+					onNetworkEapSimGsmAuthRequest,
+				std::placeholders::_1, aidl_params));
+			return 0;
+		}
+		if (!parseUmtsAuthNetworkRequest(
+			param, &umts_rand, &umts_autn)) {
+			NetworkRequestEapSimUmtsAuthParams aidl_params;
+			aidl_params.rand = umts_rand;
+			aidl_params.autn = umts_autn;
+			callWithEachStaNetworkCallback(
+				misc_utils::charBufToString(wpa_s->ifname),
+				ssid->id,
+				std::bind(
+				&ISupplicantStaNetworkCallback::
+					onNetworkEapSimUmtsAuthRequest,
+				std::placeholders::_1, aidl_params));
+			return 0;
+		}
+	}
+	return 1;
+}
+
+/**
+ * Notify all listeners about the end of an ANQP query.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
+ * @param bssid BSSID of the access point.
+ * @param result Result of the operation ("SUCCESS" or "FAILURE").
+ * @param anqp |wpa_bss_anqp| ANQP data fetched.
+ */
+void AidlManager::notifyAnqpQueryDone(
+	struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
+	const struct wpa_bss_anqp *anqp)
+{
+	if (!wpa_s || !bssid || !result || !anqp)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	AnqpData aidl_anqp_data;
+	Hs20AnqpData aidl_hs20_anqp_data;
+	if (std::string(result) == "SUCCESS") {
+		aidl_anqp_data.venueName =
+			misc_utils::convertWpaBufToVector(anqp->venue_name);
+		aidl_anqp_data.roamingConsortium =
+			misc_utils::convertWpaBufToVector(anqp->roaming_consortium);
+		aidl_anqp_data.ipAddrTypeAvailability =
+			misc_utils::convertWpaBufToVector(
+			anqp->ip_addr_type_availability);
+		aidl_anqp_data.naiRealm =
+			misc_utils::convertWpaBufToVector(anqp->nai_realm);
+		aidl_anqp_data.anqp3gppCellularNetwork =
+			misc_utils::convertWpaBufToVector(anqp->anqp_3gpp);
+		aidl_anqp_data.domainName =
+			misc_utils::convertWpaBufToVector(anqp->domain_name);
+
+		struct wpa_bss_anqp_elem *elem;
+		dl_list_for_each(elem, &anqp->anqp_elems, struct wpa_bss_anqp_elem,
+				 list) {
+			if (elem->infoid == ANQP_VENUE_URL && elem->protected_response) {
+				aidl_anqp_data.venueUrl =
+							misc_utils::convertWpaBufToVector(elem->payload);
+				break;
+			}
+		}
+
+		aidl_hs20_anqp_data.operatorFriendlyName =
+			misc_utils::convertWpaBufToVector(
+			anqp->hs20_operator_friendly_name);
+		aidl_hs20_anqp_data.wanMetrics =
+			misc_utils::convertWpaBufToVector(anqp->hs20_wan_metrics);
+		aidl_hs20_anqp_data.connectionCapability =
+			misc_utils::convertWpaBufToVector(
+			anqp->hs20_connection_capability);
+		aidl_hs20_anqp_data.osuProvidersList =
+			misc_utils::convertWpaBufToVector(
+			anqp->hs20_osu_providers_list);
+	}
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname), std::bind(
+				   &ISupplicantStaIfaceCallback::onAnqpQueryDone,
+				   std::placeholders::_1, macAddrToVec(bssid), aidl_anqp_data,
+				   aidl_hs20_anqp_data));
+}
+
+/**
+ * Notify all listeners about the end of an HS20 icon query.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
+ * @param bssid BSSID of the access point.
+ * @param file_name Name of the icon file.
+ * @param image Raw bytes of the icon file.
+ * @param image_length Size of the the icon file.
+ */
+void AidlManager::notifyHs20IconQueryDone(
+	struct wpa_supplicant *wpa_s, const u8 *bssid, const char *file_name,
+	const u8 *image, u32 image_length)
+{
+	if (!wpa_s || !bssid || !file_name || !image)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onHs20IconQueryDone,
+		std::placeholders::_1, macAddrToVec(bssid), file_name,
+		std::vector<uint8_t>(image, image + image_length)));
+}
+
+/**
+ * Notify all listeners about the reception of HS20 subscription
+ * remediation notification from the server.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
+ * @param url URL of the server.
+ * @param osu_method OSU method (OMA_DM or SOAP_XML_SPP).
+ */
+void AidlManager::notifyHs20RxSubscriptionRemediation(
+	struct wpa_supplicant *wpa_s, const char *url, u8 osu_method)
+{
+	if (!wpa_s || !url)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	OsuMethod aidl_osu_method;
+	if (osu_method & 0x1) {
+		aidl_osu_method = OsuMethod::OMA_DM;
+	} else if (osu_method & 0x2) {
+		aidl_osu_method = OsuMethod::SOAP_XML_SPP;
+	}
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onHs20SubscriptionRemediation,
+		std::placeholders::_1, macAddrToVec(wpa_s->bssid), aidl_osu_method, url));
+}
+
+/**
+ * Notify all listeners about the reception of HS20 imminent death
+ * notification from the server.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
+ * @param code Death reason code sent from server.
+ * @param reauth_delay Reauthentication delay in seconds sent from server.
+ * @param url URL of the server containing the reason text.
+ */
+void AidlManager::notifyHs20RxDeauthImminentNotice(
+	struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay, const char *url)
+{
+	if (!wpa_s)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onHs20DeauthImminentNotice,
+		std::placeholders::_1, macAddrToVec(wpa_s->bssid), code,
+		reauth_delay, misc_utils::charBufToString(url)));
+}
+
+/**
+ * Notify all listeners about the reception of HS20 terms and conditions
+ * acceptance notification from the server.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
+ * @param url URL of the T&C server.
+ */
+void AidlManager::notifyHs20RxTermsAndConditionsAcceptance(
+	struct wpa_supplicant *wpa_s, const char *url)
+{
+	if (!wpa_s || !url)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname)
+			== sta_iface_object_map_.end())
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+			&ISupplicantStaIfaceCallback
+			::onHs20TermsAndConditionsAcceptanceRequestedNotification,
+			std::placeholders::_1, macAddrToVec(wpa_s->bssid), url));
+}
+
+/**
+ * Notify all listeners about the reason code for disconnection from the
+ * currently connected network.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
+ * the network is present.
+ */
+void AidlManager::notifyDisconnectReason(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	const u8 *bssid = wpa_s->bssid;
+	if (is_zero_ether_addr(bssid)) {
+		bssid = wpa_s->pending_bssid;
+	}
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onDisconnected,
+		std::placeholders::_1, macAddrToVec(bssid), wpa_s->disconnect_reason < 0,
+		static_cast<StaIfaceReasonCode>(
+			abs(wpa_s->disconnect_reason))));
+}
+
+/**
+ * Notify all listeners about association reject from the access point to which
+ * we are attempting to connect.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
+ * the network is present.
+ * @param bssid bssid of AP that rejected the association.
+ * @param timed_out flag to indicate failure is due to timeout
+ * (auth, assoc, ...) rather than explicit rejection response from the AP.
+ * @param assoc_resp_ie Association response IE.
+ * @param assoc_resp_ie_len Association response IE length.
+ */
+void AidlManager::notifyAssocReject(struct wpa_supplicant *wpa_s,
+	const u8 *bssid, u8 timed_out, const u8 *assoc_resp_ie, size_t assoc_resp_ie_len)
+{
+	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+#ifdef CONFIG_MBO
+	struct wpa_bss *reject_bss;
+#endif /* CONFIG_MBO */
+	AssociationRejectionData aidl_assoc_reject_data{};
+
+	if (!wpa_s)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+	if (wpa_s->current_ssid) {
+		aidl_assoc_reject_data.ssid = std::vector<uint8_t>(
+			wpa_s->current_ssid->ssid,
+			wpa_s->current_ssid->ssid + wpa_s->current_ssid->ssid_len);
+	}
+	aidl_assoc_reject_data.bssid = macAddrToVec(bssid);
+	aidl_assoc_reject_data.statusCode = static_cast<StaIfaceStatusCode>(
+						wpa_s->assoc_status_code);
+	if (timed_out) {
+		aidl_assoc_reject_data.timedOut = true;
+	}
+#ifdef CONFIG_MBO
+	if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) {
+		reject_bss = wpa_s->current_bss;
+	} else {
+		reject_bss = wpa_bss_get_bssid(wpa_s, bssid);
+	}
+	if (reject_bss && assoc_resp_ie && assoc_resp_ie_len > 0) {
+		if (wpa_s->assoc_status_code ==
+			WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS) {
+			const u8 *rssi_rej;
+			rssi_rej = mbo_get_attr_from_ies(
+					assoc_resp_ie,
+					assoc_resp_ie_len,
+					OCE_ATTR_ID_RSSI_BASED_ASSOC_REJECT);
+			if (rssi_rej && rssi_rej[1] == 2) {
+				wpa_printf(MSG_INFO,
+					   "OCE: RSSI-based association rejection from "
+					   MACSTR " Delta RSSI: %u, Retry Delay: %u bss rssi: %d",
+					   MAC2STR(reject_bss->bssid),
+					   rssi_rej[2], rssi_rej[3], reject_bss->level);
+				aidl_assoc_reject_data.isOceRssiBasedAssocRejectAttrPresent = true;
+				aidl_assoc_reject_data.oceRssiBasedAssocRejectData.deltaRssi
+						= rssi_rej[2];
+				aidl_assoc_reject_data.oceRssiBasedAssocRejectData.retryDelayS
+						= rssi_rej[3];
+			}
+		} else if (wpa_s->assoc_status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
+			  || wpa_s->assoc_status_code == WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA) {
+			const u8 *assoc_disallowed;
+			assoc_disallowed = mbo_get_attr_from_ies(
+							assoc_resp_ie,
+							assoc_resp_ie_len,
+							MBO_ATTR_ID_ASSOC_DISALLOW);
+			if (assoc_disallowed && assoc_disallowed[1] == 1) {
+				wpa_printf(MSG_INFO,
+					"MBO: association disallowed indication from "
+					MACSTR " Reason: %d",
+					MAC2STR(reject_bss->bssid),
+					assoc_disallowed[2]);
+				aidl_assoc_reject_data.isMboAssocDisallowedReasonCodePresent = true;
+				aidl_assoc_reject_data.mboAssocDisallowedReason
+					= static_cast<MboAssocDisallowedReasonCode>(assoc_disallowed[2]);
+			}
+		}
+	}
+#endif /* CONFIG_MBO */
+
+	const std::function<
+			ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
+			func = std::bind(
+			&ISupplicantStaIfaceCallback::onAssociationRejected,
+			std::placeholders::_1, aidl_assoc_reject_data);
+	callWithEachStaIfaceCallback(aidl_ifname, func);
+}
+
+void AidlManager::notifyAuthTimeout(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	const std::string ifname(wpa_s->ifname);
+	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
+		return;
+
+	const u8 *bssid = wpa_s->bssid;
+	if (is_zero_ether_addr(bssid)) {
+		bssid = wpa_s->pending_bssid;
+	}
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onAuthenticationTimeout,
+		std::placeholders::_1, macAddrToVec(bssid)));
+}
+
+void AidlManager::notifyBssidChanged(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	const std::string ifname(wpa_s->ifname);
+	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
+		return;
+
+	// wpa_supplicant does not explicitly give us the reason for bssid
+	// change, but we figure that out from what is set out of |wpa_s->bssid|
+	// & |wpa_s->pending_bssid|.
+	const u8 *bssid;
+	BssidChangeReason reason;
+	if (is_zero_ether_addr(wpa_s->bssid) &&
+		!is_zero_ether_addr(wpa_s->pending_bssid)) {
+		bssid = wpa_s->pending_bssid;
+		reason = BssidChangeReason::ASSOC_START;
+	} else if (
+		!is_zero_ether_addr(wpa_s->bssid) &&
+		is_zero_ether_addr(wpa_s->pending_bssid)) {
+		bssid = wpa_s->bssid;
+		reason = BssidChangeReason::ASSOC_COMPLETE;
+	} else if (
+		is_zero_ether_addr(wpa_s->bssid) &&
+		is_zero_ether_addr(wpa_s->pending_bssid)) {
+		bssid = wpa_s->pending_bssid;
+		reason = BssidChangeReason::DISASSOC;
+	} else {
+		wpa_printf(MSG_ERROR, "Unknown bssid change reason");
+		return;
+	}
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname), std::bind(
+				   &ISupplicantStaIfaceCallback::onBssidChanged,
+				   std::placeholders::_1, reason, macAddrToVec(bssid)));
+}
+
+void AidlManager::notifyWpsEventFail(
+	struct wpa_supplicant *wpa_s, uint8_t *peer_macaddr, uint16_t config_error,
+	uint16_t error_indication)
+{
+	if (!wpa_s || !peer_macaddr)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onWpsEventFail,
+		std::placeholders::_1, macAddrToVec(peer_macaddr),
+		static_cast<WpsConfigError>(
+			config_error),
+		static_cast<WpsErrorIndication>(
+			error_indication)));
+}
+
+void AidlManager::notifyWpsEventSuccess(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname), std::bind(
+				   &ISupplicantStaIfaceCallback::onWpsEventSuccess,
+				   std::placeholders::_1));
+}
+
+void AidlManager::notifyWpsEventPbcOverlap(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onWpsEventPbcOverlap,
+		std::placeholders::_1));
+}
+
+void AidlManager::notifyP2pDeviceFound(
+	struct wpa_supplicant *wpa_s, const u8 *addr,
+	const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
+	u8 peer_wfd_device_info_len, const u8 *peer_wfd_r2_device_info,
+	u8 peer_wfd_r2_device_info_len)
+{
+	if (!wpa_s || !addr || !info)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	std::vector<uint8_t> aidl_peer_wfd_device_info(kWfdDeviceInfoLen);
+	if (peer_wfd_device_info) {
+		if (peer_wfd_device_info_len != kWfdDeviceInfoLen) {
+			wpa_printf(
+				MSG_ERROR, "Unexpected WFD device info len: %d",
+				peer_wfd_device_info_len);
+		} else {
+			os_memcpy(
+				aidl_peer_wfd_device_info.data(),
+				peer_wfd_device_info, kWfdDeviceInfoLen);
+		}
+	}
+
+	std::vector<uint8_t> aidl_peer_wfd_r2_device_info;
+	if (peer_wfd_r2_device_info) {
+		if (peer_wfd_r2_device_info_len != kWfdR2DeviceInfoLen) {
+			wpa_printf(
+				MSG_ERROR, "Unexpected WFD R2 device info len: %d",
+				peer_wfd_r2_device_info_len);
+			return;
+		} else {
+			std::copy(peer_wfd_r2_device_info,
+			    peer_wfd_r2_device_info + peer_wfd_r2_device_info_len,
+			    std::back_inserter(aidl_peer_wfd_r2_device_info));
+		}
+	}
+
+	std::vector<uint8_t> aidl_vendor_elems;
+	if (NULL != info->vendor_elems && wpabuf_len(info->vendor_elems) > 0) {
+		aidl_vendor_elems.reserve(wpabuf_len(info->vendor_elems));
+		std::copy(wpabuf_head_u8(info->vendor_elems),
+			wpabuf_head_u8(info->vendor_elems)
+				+ wpabuf_len(info->vendor_elems),
+			std::back_inserter(aidl_vendor_elems));
+	}
+
+	const std::function<
+		ndk::ScopedAStatus(std::shared_ptr<ISupplicantP2pIfaceCallback>)>
+		func = std::bind(
+		&ISupplicantP2pIfaceCallback::onDeviceFoundWithVendorElements,
+		std::placeholders::_1, macAddrToVec(addr), macAddrToVec(info->p2p_device_addr),
+		byteArrToVec(info->pri_dev_type, 8), misc_utils::charBufToString(info->device_name),
+		static_cast<WpsConfigMethods>(info->config_methods),
+		info->dev_capab, static_cast<P2pGroupCapabilityMask>(info->group_capab), aidl_peer_wfd_device_info,
+		aidl_peer_wfd_r2_device_info, aidl_vendor_elems);
+	callWithEachP2pIfaceCallback(wpa_s->ifname, func);
+}
+
+void AidlManager::notifyP2pDeviceLost(
+	struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr)
+{
+	if (!wpa_s || !p2p_device_addr)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname), std::bind(
+				   &ISupplicantP2pIfaceCallback::onDeviceLost,
+				   std::placeholders::_1, macAddrToVec(p2p_device_addr)));
+}
+
+void AidlManager::notifyP2pFindStopped(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname), std::bind(
+				   &ISupplicantP2pIfaceCallback::onFindStopped,
+				   std::placeholders::_1));
+}
+
+void AidlManager::notifyP2pGoNegReq(
+	struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
+	u8 /* go_intent */)
+{
+	if (!wpa_s || !src_addr)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onGoNegotiationRequest,
+		std::placeholders::_1, macAddrToVec(src_addr),
+		static_cast<WpsDevPasswordId>(
+			dev_passwd_id)));
+}
+
+void AidlManager::notifyP2pGoNegCompleted(
+	struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res)
+{
+	if (!wpa_s || !res)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onGoNegotiationCompleted,
+		std::placeholders::_1,
+		static_cast<P2pStatusCode>(
+			res->status)));
+}
+
+void AidlManager::notifyP2pGroupFormationFailure(
+	struct wpa_supplicant *wpa_s, const char *reason)
+{
+	if (!wpa_s || !reason)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onGroupFormationFailure,
+		std::placeholders::_1, reason));
+}
+
+void AidlManager::notifyP2pGroupStarted(
+	struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
+	int persistent, int client)
+{
+	if (!wpa_group_s || !wpa_group_s->parent || !ssid)
+		return;
+
+	// For group notifications, need to use the parent iface for callbacks.
+	struct wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
+	if (!wpa_s)
+		return;
+
+	uint32_t aidl_freq = wpa_group_s->current_bss
+				 ? wpa_group_s->current_bss->freq
+				 : wpa_group_s->assoc_freq;
+	std::vector<uint8_t> aidl_psk(32);
+	if (ssid->psk_set) {
+		aidl_psk.assign(ssid->psk, ssid->psk + 32);
+	}
+	bool aidl_is_go = (client == 0 ? true : false);
+	bool aidl_is_persistent = (persistent == 1 ? true : false);
+
+	// notify the group device again to ensure the framework knowing this device.
+	struct p2p_data *p2p = wpa_s->global->p2p;
+	struct p2p_device *dev = p2p_get_device(p2p, wpa_group_s->go_dev_addr);
+	if (NULL != dev) {
+		wpa_printf(MSG_DEBUG, "P2P: Update GO device on group started.");
+		p2p->cfg->dev_found(p2p->cfg->cb_ctx, wpa_group_s->go_dev_addr,
+				&dev->info, !(dev->flags & P2P_DEV_REPORTED_ONCE));
+		dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE;
+	}
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onGroupStarted,
+		std::placeholders::_1, misc_utils::charBufToString(wpa_group_s->ifname),
+		aidl_is_go, byteArrToVec(ssid->ssid, ssid->ssid_len),
+		aidl_freq, aidl_psk, misc_utils::charBufToString(ssid->passphrase),
+		macAddrToVec(wpa_group_s->go_dev_addr), aidl_is_persistent));
+}
+
+void AidlManager::notifyP2pGroupRemoved(
+	struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
+	const char *role)
+{
+	if (!wpa_group_s || !wpa_group_s->parent || !ssid || !role)
+		return;
+
+	// For group notifications, need to use the parent iface for callbacks.
+	struct wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
+	if (!wpa_s)
+		return;
+
+	bool aidl_is_go = (std::string(role) == "GO");
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onGroupRemoved,
+		std::placeholders::_1, misc_utils::charBufToString(wpa_group_s->ifname), aidl_is_go));
+}
+
+void AidlManager::notifyP2pInvitationReceived(
+	struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
+	const u8 *bssid, int id, int op_freq)
+{
+	if (!wpa_s || !sa || !go_dev_addr || !bssid)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	int aidl_network_id;
+	if (id < 0) {
+		aidl_network_id = UINT32_MAX;
+	}
+	aidl_network_id = id;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onInvitationReceived,
+		std::placeholders::_1, macAddrToVec(sa), macAddrToVec(go_dev_addr),
+		macAddrToVec(bssid), aidl_network_id, op_freq));
+}
+
+void AidlManager::notifyP2pInvitationResult(
+	struct wpa_supplicant *wpa_s, int status, const u8 *bssid)
+{
+	if (!wpa_s)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onInvitationResult,
+		std::placeholders::_1, bssid ? macAddrToVec(bssid) : kZeroBssid,
+		static_cast<P2pStatusCode>(
+			status)));
+}
+
+void AidlManager::notifyP2pProvisionDiscovery(
+	struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
+	enum p2p_prov_disc_status status, u16 config_methods,
+	unsigned int generated_pin)
+{
+	if (!wpa_s || !dev_addr)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	std::string aidl_generated_pin;
+	if (generated_pin > 0) {
+		aidl_generated_pin =
+			misc_utils::convertWpsPinToString(generated_pin);
+	}
+	bool aidl_is_request = (request == 1 ? true : false);
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onProvisionDiscoveryCompleted,
+		std::placeholders::_1, macAddrToVec(dev_addr), aidl_is_request,
+		static_cast<P2pProvDiscStatusCode>(status),
+		static_cast<WpsConfigMethods>(config_methods), aidl_generated_pin));
+}
+
+void AidlManager::notifyP2pSdResponse(
+	struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
+	const u8 *tlvs, size_t tlvs_len)
+{
+	if (!wpa_s || !sa || !tlvs)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onServiceDiscoveryResponse,
+		std::placeholders::_1, macAddrToVec(sa), update_indic,
+		byteArrToVec(tlvs, tlvs_len)));
+}
+
+void AidlManager::notifyApStaAuthorized(
+	struct wpa_supplicant *wpa_group_s, const u8 *sta, const u8 *p2p_dev_addr)
+{
+	if (!wpa_group_s || !wpa_group_s->parent || !sta)
+		return;
+	wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
+	if (!wpa_s)
+		return;
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onStaAuthorized,
+		std::placeholders::_1, macAddrToVec(sta),
+		p2p_dev_addr ? macAddrToVec(p2p_dev_addr) : kZeroBssid));
+}
+
+void AidlManager::notifyApStaDeauthorized(
+	struct wpa_supplicant *wpa_group_s, const u8 *sta, const u8 *p2p_dev_addr)
+{
+	if (!wpa_group_s || !wpa_group_s->parent || !sta)
+		return;
+	wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
+	if (!wpa_s)
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onStaDeauthorized,
+		std::placeholders::_1, macAddrToVec(sta),
+		p2p_dev_addr ? macAddrToVec(p2p_dev_addr) : kZeroBssid));
+}
+
+void AidlManager::notifyExtRadioWorkStart(
+	struct wpa_supplicant *wpa_s, uint32_t id)
+{
+	if (!wpa_s)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onExtRadioWorkStart,
+		std::placeholders::_1, id));
+}
+
+void AidlManager::notifyExtRadioWorkTimeout(
+	struct wpa_supplicant *wpa_s, uint32_t id)
+{
+	if (!wpa_s)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onExtRadioWorkTimeout,
+		std::placeholders::_1, id));
+}
+
+void AidlManager::notifyEapError(struct wpa_supplicant *wpa_s, int error_code)
+{
+	if (!wpa_s)
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onEapFailure,
+		std::placeholders::_1, error_code));
+}
+
+/**
+ * Notify listener about a new DPP configuration received success event
+ *
+ * @param ifname Interface name
+ * @param config Configuration object
+ */
+void AidlManager::notifyDppConfigReceived(struct wpa_supplicant *wpa_s,
+		struct wpa_ssid *config)
+{
+	DppAkm securityAkm;
+	DppConnectionKeys aidl_keys{};
+	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+
+	if ((config->key_mgmt & WPA_KEY_MGMT_SAE) &&
+			(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE)) {
+		securityAkm = DppAkm::SAE;
+	} else if (config->key_mgmt & WPA_KEY_MGMT_PSK) {
+			securityAkm = DppAkm::PSK;
+	} else if (config->key_mgmt & WPA_KEY_MGMT_DPP) {
+			securityAkm = DppAkm::DPP;
+	} else {
+		/* Unsupported AKM */
+		wpa_printf(MSG_ERROR, "DPP: Error: Unsupported AKM 0x%X",
+				config->key_mgmt);
+		notifyDppFailure(wpa_s, DppFailureCode::NOT_SUPPORTED);
+		return;
+	}
+
+	std::string passphrase = misc_utils::charBufToString(config->passphrase);
+	std::vector<uint8_t> aidl_ssid(
+		config->ssid,
+		config->ssid + config->ssid_len);
+
+	if (securityAkm == DppAkm::DPP) {
+		// TODO Add code to fill aidl_keys
+	}
+
+	/* At this point, the network is already registered, notify about new
+	 * received configuration
+	 */
+	callWithEachStaIfaceCallback(aidl_ifname,
+			std::bind(
+					&ISupplicantStaIfaceCallback::onDppSuccessConfigReceived,
+					std::placeholders::_1, aidl_ssid, passphrase,
+					byteArrToVec(config->psk, 32), securityAkm,
+					aidl_keys));
+}
+
+/**
+ * Notify listener about a DPP configuration sent success event
+ *
+ * @param ifname Interface name
+ */
+void AidlManager::notifyDppConfigSent(struct wpa_supplicant *wpa_s)
+{
+	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+
+	callWithEachStaIfaceCallback(aidl_ifname,
+			std::bind(&ISupplicantStaIfaceCallback::onDppSuccessConfigSent,
+					std::placeholders::_1));
+}
+
+/**
+ * Notify listener about a DPP failure event
+ *
+ * @param ifname Interface name
+ * @param code Status code
+ */
+void AidlManager::notifyDppFailure(struct wpa_supplicant *wpa_s,
+		android::hardware::wifi::supplicant::DppFailureCode code) {
+	notifyDppFailure(wpa_s, code, NULL, NULL, NULL, 0);
+}
+
+/**
+ * Notify listener about a DPP failure event
+ *
+ * @param ifname Interface name
+ * @param code Status code
+ */
+void AidlManager::notifyDppFailure(struct wpa_supplicant *wpa_s,
+		DppFailureCode code, const char *ssid, const char *channel_list,
+		unsigned short band_list[], int size) {
+	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+	std::vector<char16_t> band_list_vec(band_list, band_list + size);
+
+	callWithEachStaIfaceCallback(aidl_ifname,
+			std::bind(&ISupplicantStaIfaceCallback::onDppFailure,
+					std::placeholders::_1, code, misc_utils::charBufToString(ssid),
+					misc_utils::charBufToString(channel_list), band_list_vec));
+}
+
+/**
+ * Notify listener about a DPP progress event
+ *
+ * @param ifname Interface name
+ * @param code Status code
+ */
+void AidlManager::notifyDppProgress(
+		struct wpa_supplicant *wpa_s, DppProgressCode code) {
+	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+
+	callWithEachStaIfaceCallback(aidl_ifname,
+			std::bind(&ISupplicantStaIfaceCallback::onDppProgress,
+					std::placeholders::_1, code));
+}
+
+/**
+ * Notify listener about a DPP success event
+ *
+ * @param ifname Interface name
+ * @param code Status code
+ */
+void AidlManager::notifyDppSuccess(struct wpa_supplicant *wpa_s, DppEventType code)
+{
+	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+
+	callWithEachStaIfaceCallback(aidl_ifname,
+			std::bind(&ISupplicantStaIfaceCallback::onDppSuccess,
+					std::placeholders::_1, code));
+}
+
+/**
+ * Notify listener about a PMK cache added event
+ *
+ * @param ifname Interface name
+ * @param entry PMK cache entry
+ */
+void AidlManager::notifyPmkCacheAdded(
+	struct wpa_supplicant *wpa_s, struct rsn_pmksa_cache_entry *pmksa_entry)
+{
+	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+
+	// Serialize PmkCacheEntry into blob.
+	std::stringstream ss(
+		std::stringstream::in | std::stringstream::out | std::stringstream::binary);
+	misc_utils::serializePmkCacheEntry(ss, pmksa_entry);
+	std::vector<uint8_t> serializedEntry(
+		std::istreambuf_iterator<char>(ss), {});
+
+	const std::function<
+		ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
+		func = std::bind(
+		&ISupplicantStaIfaceCallback::onPmkCacheAdded,
+		std::placeholders::_1, pmksa_entry->expiration, serializedEntry);
+	callWithEachStaIfaceCallback(aidl_ifname, func);
+}
+
+#ifdef CONFIG_WNM
+BssTmStatusCode convertSupplicantBssTmStatusToAidl(
+	enum bss_trans_mgmt_status_code bss_tm_status)
+{
+	switch (bss_tm_status) {
+		case WNM_BSS_TM_ACCEPT:
+			return BssTmStatusCode::ACCEPT;
+		case WNM_BSS_TM_REJECT_UNSPECIFIED:
+			return BssTmStatusCode::REJECT_UNSPECIFIED;
+		case WNM_BSS_TM_REJECT_INSUFFICIENT_BEACON:
+			return BssTmStatusCode::REJECT_INSUFFICIENT_BEACON;
+		case WNM_BSS_TM_REJECT_INSUFFICIENT_CAPABITY:
+			return BssTmStatusCode::REJECT_INSUFFICIENT_CAPABITY;
+		case WNM_BSS_TM_REJECT_UNDESIRED:
+			return BssTmStatusCode::REJECT_BSS_TERMINATION_UNDESIRED;
+		case WNM_BSS_TM_REJECT_DELAY_REQUEST:
+			return BssTmStatusCode::REJECT_BSS_TERMINATION_DELAY_REQUEST;
+		case WNM_BSS_TM_REJECT_STA_CANDIDATE_LIST_PROVIDED:
+			return BssTmStatusCode::REJECT_STA_CANDIDATE_LIST_PROVIDED;
+		case WNM_BSS_TM_REJECT_NO_SUITABLE_CANDIDATES:
+			return BssTmStatusCode::REJECT_NO_SUITABLE_CANDIDATES;
+		case WNM_BSS_TM_REJECT_LEAVING_ESS:
+			return BssTmStatusCode::REJECT_LEAVING_ESS;
+		default:
+			return BssTmStatusCode::REJECT_UNSPECIFIED;
+	}
+}
+
+BssTmDataFlagsMask setBssTmDataFlagsMask(struct wpa_supplicant *wpa_s)
+{
+	uint32_t flags = 0;
+
+	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED) {
+		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::WNM_MODE_BSS_TERMINATION_INCLUDED);
+	}
+	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_ESS_DISASSOC_IMMINENT) {
+		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::WNM_MODE_ESS_DISASSOCIATION_IMMINENT);
+	}
+	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_DISASSOC_IMMINENT) {
+		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::WNM_MODE_DISASSOCIATION_IMMINENT);
+	}
+	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_ABRIDGED) {
+		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::WNM_MODE_ABRIDGED);
+	}
+	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED) {
+		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::WNM_MODE_PREFERRED_CANDIDATE_LIST_INCLUDED);
+	}
+#ifdef CONFIG_MBO
+	if (wpa_s->wnm_mbo_assoc_retry_delay_present) {
+		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::MBO_ASSOC_RETRY_DELAY_INCLUDED);
+	}
+	if (wpa_s->wnm_mbo_trans_reason_present) {
+		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::MBO_TRANSITION_REASON_CODE_INCLUDED);
+	}
+	if (wpa_s->wnm_mbo_cell_pref_present) {
+		flags |= static_cast<uint32_t>(BssTmDataFlagsMask::MBO_CELLULAR_DATA_CONNECTION_PREFERENCE_INCLUDED);
+	}
+#endif
+	return static_cast<BssTmDataFlagsMask>(flags);
+}
+
+uint32_t getBssTmDataAssocRetryDelayMs(struct wpa_supplicant *wpa_s)
+{
+	uint32_t beacon_int;
+	uint32_t duration_ms = 0;
+
+	if (wpa_s->current_bss)
+		beacon_int = wpa_s->current_bss->beacon_int;
+	else
+		beacon_int = 100; /* best guess */
+
+	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_DISASSOC_IMMINENT) {
+		// number of tbtts to milliseconds
+		duration_ms = wpa_s->wnm_dissoc_timer * beacon_int * 128 / 125;
+	}
+	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED) {
+		//wnm_bss_termination_duration contains 12 bytes of BSS
+		//termination duration subelement. Format of IE is
+		// Sub eid | Length | BSS termination TSF | Duration
+		//	1	 1		 8		2
+		// Duration indicates number of minutes for which BSS is not
+		// present.
+		duration_ms = WPA_GET_LE16(wpa_s->wnm_bss_termination_duration + 10);
+		// minutes to milliseconds
+		duration_ms = duration_ms * 60 * 1000;
+	}
+#ifdef CONFIG_MBO
+	if (wpa_s->wnm_mbo_assoc_retry_delay_present) {
+		// number of seconds to milliseconds
+		duration_ms = wpa_s->wnm_mbo_assoc_retry_delay_sec * 1000;
+	}
+#endif
+
+	return duration_ms;
+}
+#endif
+
+/**
+ * Notify listener about the status of BSS transition management
+ * request frame handling.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
+ * the network is present.
+ */
+void AidlManager::notifyBssTmStatus(struct wpa_supplicant *wpa_s)
+{
+#ifdef CONFIG_WNM
+	std::string aidl_ifname = misc_utils::charBufToString(wpa_s->ifname);
+	BssTmData aidl_bsstm_data{};
+
+	aidl_bsstm_data.status = convertSupplicantBssTmStatusToAidl(wpa_s->bss_tm_status);
+	aidl_bsstm_data.flags = setBssTmDataFlagsMask(wpa_s);
+	aidl_bsstm_data.assocRetryDelayMs = getBssTmDataAssocRetryDelayMs(wpa_s);
+#ifdef CONFIG_MBO
+	if (wpa_s->wnm_mbo_cell_pref_present) {
+		aidl_bsstm_data.mboCellPreference = static_cast
+			<MboCellularDataConnectionPrefValue>
+			(wpa_s->wnm_mbo_cell_preference);
+	}
+	if (wpa_s->wnm_mbo_trans_reason_present) {
+		aidl_bsstm_data.mboTransitionReason =
+			static_cast<MboTransitionReasonCode>
+			(wpa_s->wnm_mbo_transition_reason);
+	}
+#endif
+
+	const std::function<
+		ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
+		func = std::bind(
+		&ISupplicantStaIfaceCallback::onBssTmHandlingDone,
+		std::placeholders::_1, aidl_bsstm_data);
+	callWithEachStaIfaceCallback(aidl_ifname, func);
+#endif
+}
+
+TransitionDisableIndication setTransitionDisableFlagsMask(u8 bitmap)
+{
+	uint32_t flags = 0;
+
+	if (bitmap & TRANSITION_DISABLE_WPA3_PERSONAL) {
+		flags |= static_cast<uint32_t>(TransitionDisableIndication::
+			USE_WPA3_PERSONAL);
+		bitmap &= ~TRANSITION_DISABLE_WPA3_PERSONAL;
+	}
+	if (bitmap & TRANSITION_DISABLE_SAE_PK) {
+		flags |= static_cast<uint32_t>(TransitionDisableIndication::
+			USE_SAE_PK);
+		bitmap &= ~TRANSITION_DISABLE_SAE_PK;
+	}
+	if (bitmap & TRANSITION_DISABLE_WPA3_ENTERPRISE) {
+		flags |= static_cast<uint32_t>(TransitionDisableIndication::
+			USE_WPA3_ENTERPRISE);
+		bitmap &= ~TRANSITION_DISABLE_WPA3_ENTERPRISE;
+	}
+	if (bitmap & TRANSITION_DISABLE_ENHANCED_OPEN) {
+		flags |= static_cast<uint32_t>(TransitionDisableIndication::
+			USE_ENHANCED_OPEN);
+		bitmap &= ~TRANSITION_DISABLE_ENHANCED_OPEN;
+	}
+
+	if (bitmap != 0) {
+		wpa_printf(MSG_WARNING, "Unhandled transition disable bit: 0x%x", bitmap);
+	}
+
+	return static_cast<TransitionDisableIndication>(flags);
+}
+
+void AidlManager::notifyTransitionDisable(struct wpa_supplicant *wpa_s,
+	struct wpa_ssid *ssid, u8 bitmap)
+{
+	TransitionDisableIndication flag = setTransitionDisableFlagsMask(bitmap);
+	const std::function<
+		ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaNetworkCallback>)>
+		func = std::bind(
+		&ISupplicantStaNetworkCallback::onTransitionDisable,
+		std::placeholders::_1, flag);
+
+	callWithEachStaNetworkCallback(
+		misc_utils::charBufToString(wpa_s->ifname), ssid->id, func);
+}
+
+void AidlManager::notifyNetworkNotFound(struct wpa_supplicant *wpa_s)
+{
+	std::vector<uint8_t> aidl_ssid;
+
+	if (!wpa_s->current_ssid) {
+		wpa_printf(MSG_ERROR, "Current network NULL. Drop WPA_EVENT_NETWORK_NOT_FOUND!");
+		return;
+	}
+
+	aidl_ssid.assign(
+			wpa_s->current_ssid->ssid,
+			wpa_s->current_ssid->ssid + wpa_s->current_ssid->ssid_len);
+
+	const std::function<
+		ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
+		func = std::bind(
+		&ISupplicantStaIfaceCallback::onNetworkNotFound,
+		std::placeholders::_1, aidl_ssid);
+	callWithEachStaIfaceCallback(misc_utils::charBufToString(wpa_s->ifname), func);
+}
+
+void AidlManager::notifyBssFreqChanged(struct wpa_supplicant *wpa_group_s)
+{
+	if (!wpa_group_s || !wpa_group_s->parent)
+		return;
+
+	// For group notifications, need to use the parent iface for callbacks.
+	struct wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
+	if (!wpa_s) {
+		wpa_printf(MSG_INFO, "Drop BSS frequency changed event");
+		return;
+	}
+
+	uint32_t aidl_freq = wpa_group_s->current_bss
+				? wpa_group_s->current_bss->freq
+				: wpa_group_s->assoc_freq;
+
+	const std::function<
+		ndk::ScopedAStatus(std::shared_ptr<ISupplicantP2pIfaceCallback>)>
+		func = std::bind(&ISupplicantP2pIfaceCallback::onGroupFrequencyChanged,
+		std::placeholders::_1, misc_utils::charBufToString(wpa_group_s->ifname), aidl_freq);
+	callWithEachP2pIfaceCallback(misc_utils::charBufToString(wpa_s->ifname), func);
+}
+
+void AidlManager::notifyCertification(struct wpa_supplicant *wpa_s,
+		int depth, const char *subject,
+		const char *altsubject[],
+		int num_altsubject,
+		const char *cert_hash,
+		const struct wpabuf *cert)
+{
+	if (!wpa_s->current_ssid) {
+		wpa_printf(MSG_ERROR, "Current network NULL. Drop Certification event!");
+		return;
+	}
+	struct wpa_ssid *current_ssid = wpa_s->current_ssid;
+	if (NULL == subject || NULL == cert_hash || NULL == cert) {
+		wpa_printf(MSG_ERROR,
+				"Incomplete certificate information. Drop Certification event!");
+		return;
+	}
+	if (!wpa_key_mgmt_wpa_ieee8021x(current_ssid->key_mgmt)) {
+		wpa_printf(MSG_ERROR, "Not 802.1x configuration, Drop Certification event!");
+		return;
+	}
+	if (current_ssid->eap.cert.ca_path || current_ssid->eap.cert.ca_cert) {
+		wpa_printf(MSG_DEBUG, "Already has CA certificate. Drop Certification event!");
+		return;
+	}
+
+	wpa_printf(MSG_DEBUG, "notifyCertification: depth=%d subject=%s hash=%s cert-size=%zu",
+			depth, subject, cert_hash, cert->used);
+	std::vector<uint8_t> subjectBlob(subject, subject + strlen(subject));
+	std::vector<uint8_t> certHashBlob(cert_hash, cert_hash + strlen(cert_hash));
+	std::vector<uint8_t> certBlob(cert->buf, cert->buf + cert->used);
+
+	const std::function<
+		ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaNetworkCallback>)>
+		func = std::bind(
+		&ISupplicantStaNetworkCallback::onServerCertificateAvailable,
+		std::placeholders::_1,
+		depth,
+		subjectBlob,
+		certHashBlob,
+		certBlob);
+
+	callWithEachStaNetworkCallback(
+		misc_utils::charBufToString(wpa_s->ifname), current_ssid->id, func);
+}
+
+/**
+ * Retrieve the |ISupplicantP2pIface| aidl object reference using the provided
+ * ifname.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param iface_object Aidl reference corresponding to the iface.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::getP2pIfaceAidlObjectByIfname(
+	const std::string &ifname, std::shared_ptr<ISupplicantP2pIface> *iface_object)
+{
+	if (ifname.empty() || !iface_object)
+		return 1;
+
+	auto iface_object_iter = p2p_iface_object_map_.find(ifname);
+	if (iface_object_iter == p2p_iface_object_map_.end())
+		return 1;
+
+	*iface_object = iface_object_iter->second;
+	return 0;
+}
+
+/**
+ * Retrieve the |ISupplicantStaIface| aidl object reference using the provided
+ * ifname.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param iface_object Aidl reference corresponding to the iface.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::getStaIfaceAidlObjectByIfname(
+	const std::string &ifname, std::shared_ptr<ISupplicantStaIface> *iface_object)
+{
+	if (ifname.empty() || !iface_object)
+		return 1;
+
+	auto iface_object_iter = sta_iface_object_map_.find(ifname);
+	if (iface_object_iter == sta_iface_object_map_.end())
+		return 1;
+
+	*iface_object = iface_object_iter->second;
+	return 0;
+}
+
+/**
+ * Retrieve the |ISupplicantP2pNetwork| aidl object reference using the provided
+ * ifname and network_id.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param network_id ID of the corresponding network.
+ * @param network_object Aidl reference corresponding to the network.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::getP2pNetworkAidlObjectByIfnameAndNetworkId(
+	const std::string &ifname, int network_id,
+	std::shared_ptr<ISupplicantP2pNetwork> *network_object)
+{
+	if (ifname.empty() || network_id < 0 || !network_object)
+		return 1;
+
+	// Generate the key to be used to lookup the network.
+	const std::string network_key =
+		getNetworkObjectMapKey(ifname, network_id);
+
+	auto network_object_iter = p2p_network_object_map_.find(network_key);
+	if (network_object_iter == p2p_network_object_map_.end())
+		return 1;
+
+	*network_object = network_object_iter->second;
+	return 0;
+}
+
+/**
+ * Retrieve the |ISupplicantStaNetwork| aidl object reference using the provided
+ * ifname and network_id.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param network_id ID of the corresponding network.
+ * @param network_object Aidl reference corresponding to the network.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::getStaNetworkAidlObjectByIfnameAndNetworkId(
+	const std::string &ifname, int network_id,
+	std::shared_ptr<ISupplicantStaNetwork> *network_object)
+{
+	if (ifname.empty() || network_id < 0 || !network_object)
+		return 1;
+
+	// Generate the key to be used to lookup the network.
+	const std::string network_key =
+		getNetworkObjectMapKey(ifname, network_id);
+
+	auto network_object_iter = sta_network_object_map_.find(network_key);
+	if (network_object_iter == sta_network_object_map_.end())
+		return 1;
+
+	*network_object = network_object_iter->second;
+	return 0;
+}
+
+/**
+ * Add a new |ISupplicantCallback| aidl object reference to our
+ * global callback list.
+ *
+ * @param callback Aidl reference of the |ISupplicantCallback| object.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::addSupplicantCallbackAidlObject(
+	const std::shared_ptr<ISupplicantCallback> &callback)
+{
+	return registerForDeathAndAddCallbackAidlObjectToList<
+		ISupplicantCallback>(
+		death_notifier_, callback, supplicant_callbacks_);
+}
+
+/**
+ * Add a new iface callback aidl object reference to our
+ * interface callback list.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param callback Aidl reference of the callback object.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::addP2pIfaceCallbackAidlObject(
+	const std::string &ifname,
+	const std::shared_ptr<ISupplicantP2pIfaceCallback> &callback)
+{
+	return addIfaceCallbackAidlObjectToMap(
+		death_notifier_, ifname, callback, p2p_iface_callbacks_map_);
+}
+
+/**
+ * Add a new iface callback aidl object reference to our
+ * interface callback list.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param callback Aidl reference of the callback object.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::addStaIfaceCallbackAidlObject(
+	const std::string &ifname,
+	const std::shared_ptr<ISupplicantStaIfaceCallback> &callback)
+{
+	return addIfaceCallbackAidlObjectToMap(
+		death_notifier_, ifname, callback, sta_iface_callbacks_map_);
+}
+
+/**
+ * Add a new network callback aidl object reference to our network callback
+ * list.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param network_id ID of the corresponding network.
+ * @param callback Aidl reference of the callback object.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int AidlManager::addStaNetworkCallbackAidlObject(
+	const std::string &ifname, int network_id,
+	const std::shared_ptr<ISupplicantStaNetworkCallback> &callback)
+{
+	return addNetworkCallbackAidlObjectToMap(
+		death_notifier_, ifname, network_id, callback,
+		sta_network_callbacks_map_);
+}
+
+/**
+ * Finds the correct |wpa_supplicant| object for P2P notifications
+ *
+ * @param wpa_s the |wpa_supplicant| that triggered the P2P event.
+ * @return appropriate |wpa_supplicant| object or NULL if not found.
+ */
+struct wpa_supplicant *AidlManager::getTargetP2pIfaceForGroup(
+		struct wpa_supplicant *wpa_group_s)
+{
+	if (!wpa_group_s || !wpa_group_s->parent)
+		return NULL;
+
+	struct wpa_supplicant *target_wpa_s = wpa_group_s->parent;
+
+	// check wpa_supplicant object is a p2p device interface
+	if ((wpa_group_s == wpa_group_s->p2pdev) && wpa_group_s->p2p_mgmt) {
+		if (p2p_iface_object_map_.find(wpa_group_s->ifname) !=
+			p2p_iface_object_map_.end())
+			return wpa_group_s;
+	}
+
+	if (p2p_iface_object_map_.find(target_wpa_s->ifname) !=
+		p2p_iface_object_map_.end())
+		return target_wpa_s;
+
+	// try P2P device if available
+	if (!target_wpa_s->p2pdev || !target_wpa_s->p2pdev->p2p_mgmt)
+		return NULL;
+
+	target_wpa_s = target_wpa_s->p2pdev;
+	if (p2p_iface_object_map_.find(target_wpa_s->ifname) !=
+		p2p_iface_object_map_.end())
+		return target_wpa_s;
+
+	return NULL;
+}
+
+/**
+ * Removes the provided |ISupplicantCallback| aidl object reference
+ * from our global callback list.
+ *
+ * @param callback Aidl reference of the |ISupplicantCallback| object.
+ */
+void AidlManager::removeSupplicantCallbackAidlObject(
+	const std::shared_ptr<ISupplicantCallback> &callback)
+{
+	supplicant_callbacks_.erase(
+		std::remove(
+		supplicant_callbacks_.begin(), supplicant_callbacks_.end(),
+		callback),
+		supplicant_callbacks_.end());
+}
+
+/**
+ * Removes the provided iface callback aidl object reference from
+ * our interface callback list.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param callback Aidl reference of the callback object.
+ */
+void AidlManager::removeP2pIfaceCallbackAidlObject(
+	const std::string &ifname,
+	const std::shared_ptr<ISupplicantP2pIfaceCallback> &callback)
+{
+	return removeIfaceCallbackAidlObjectFromMap(
+		ifname, callback, p2p_iface_callbacks_map_);
+}
+
+/**
+ * Removes the provided iface callback aidl object reference from
+ * our interface callback list.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param callback Aidl reference of the callback object.
+ */
+void AidlManager::removeStaIfaceCallbackAidlObject(
+	const std::string &ifname,
+	const std::shared_ptr<ISupplicantStaIfaceCallback> &callback)
+{
+	return removeIfaceCallbackAidlObjectFromMap(
+		ifname, callback, sta_iface_callbacks_map_);
+}
+
+/**
+ * Removes the provided network callback aidl object reference from
+ * our network callback list.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param network_id ID of the corresponding network.
+ * @param callback Aidl reference of the callback object.
+ */
+void AidlManager::removeStaNetworkCallbackAidlObject(
+	const std::string &ifname, int network_id,
+	const std::shared_ptr<ISupplicantStaNetworkCallback> &callback)
+{
+	return removeNetworkCallbackAidlObjectFromMap(
+		ifname, network_id, callback, sta_network_callbacks_map_);
+}
+
+/**
+ * Helper function to invoke the provided callback method on all the
+ * registered |ISupplicantCallback| callback aidl objects.
+ *
+ * @param method Pointer to the required aidl method from
+ * |ISupplicantCallback|.
+ */
+void AidlManager::callWithEachSupplicantCallback(
+	const std::function<ndk::ScopedAStatus(std::shared_ptr<ISupplicantCallback>)> &method)
+{
+	for (const auto &callback : supplicant_callbacks_) {
+		if (!method(callback).isOk()) {
+			wpa_printf(MSG_ERROR, "Failed to invoke AIDL callback");
+		}
+	}
+}
+
+/**
+ * Helper function to invoke the provided callback method on all the
+ * registered iface callback aidl objects for the specified
+ * |ifname|.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param method Pointer to the required aidl method from
+ * |ISupplicantIfaceCallback|.
+ */
+void AidlManager::callWithEachP2pIfaceCallback(
+	const std::string &ifname,
+	const std::function<ndk::ScopedAStatus(std::shared_ptr<ISupplicantP2pIfaceCallback>)>
+	&method)
+{
+	callWithEachIfaceCallback(ifname, method, p2p_iface_callbacks_map_);
+}
+
+/**
+ * Helper function to invoke the provided callback method on all the
+ * registered interface callback aidl objects for the specified
+ * |ifname|.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param method Pointer to the required aidl method from
+ * |ISupplicantIfaceCallback|.
+ */
+void AidlManager::callWithEachStaIfaceCallback(
+	const std::string &ifname,
+	const std::function<ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaIfaceCallback>)>
+	&method)
+{
+	callWithEachIfaceCallback(ifname, method, sta_iface_callbacks_map_);
+}
+
+/**
+ * Helper function to invoke the provided callback method on all the
+ * registered network callback aidl objects for the specified
+ * |ifname| & |network_id|.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param network_id ID of the corresponding network.
+ * @param method Pointer to the required aidl method from 
+ * |ISupplicantStaNetworkCallback|.
+ */
+void AidlManager::callWithEachStaNetworkCallback(
+	const std::string &ifname, int network_id,
+	const std::function<
+	ndk::ScopedAStatus(std::shared_ptr<ISupplicantStaNetworkCallback>)> &method)
+{
+	callWithEachNetworkCallback(
+		ifname, network_id, method, sta_network_callbacks_map_);
+}
+
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wpa_supplicant/aidl/aidl_manager.h b/wpa_supplicant/aidl/aidl_manager.h
new file mode 100644
index 0000000..babb2cc
--- /dev/null
+++ b/wpa_supplicant/aidl/aidl_manager.h
@@ -0,0 +1,708 @@
+/*
+ * WPA Supplicant - Manager for Aidl interface objects
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef WPA_SUPPLICANT_AIDL_AIDL_MANAGER_H
+#define WPA_SUPPLICANT_AIDL_AIDL_MANAGER_H
+
+#include <map>
+#include <string>
+
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.h>
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.h>
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.h>
+
+#include "p2p_iface.h"
+#include "p2p_network.h"
+#include "rsn_supp/pmksa_cache.h"
+#include "sta_iface.h"
+#include "sta_network.h"
+#include "supplicant.h"
+
+extern "C"
+{
+#include "utils/common.h"
+#include "utils/includes.h"
+#include "wpa_supplicant_i.h"
+#include "driver_i.h"
+}
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+
+/**
+ * AidlManager is responsible for managing the lifetime of all
+ * aidl objects created by wpa_supplicant. This is a singleton
+ * class which is created by the supplicant core and can be used
+ * to get references to the aidl objects.
+ */
+class AidlManager
+{
+public:
+	static AidlManager *getInstance();
+	static void destroyInstance();
+
+	// Methods called from wpa_supplicant core.
+	int registerAidlService(struct wpa_global *global);
+	int registerInterface(struct wpa_supplicant *wpa_s);
+	int unregisterInterface(struct wpa_supplicant *wpa_s);
+	int registerNetwork(
+		struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
+	int unregisterNetwork(
+		struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
+	int notifyStateChange(struct wpa_supplicant *wpa_s);
+	int notifyNetworkRequest(
+		struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int type,
+		const char *param);
+	void notifyAnqpQueryDone(
+		struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
+		const struct wpa_bss_anqp *anqp);
+	void notifyHs20IconQueryDone(
+		struct wpa_supplicant *wpa_s, const u8 *bssid,
+		const char *file_name, const u8 *image, u32 image_length);
+	void notifyHs20RxSubscriptionRemediation(
+		struct wpa_supplicant *wpa_s, const char *url, u8 osu_method);
+	void notifyHs20RxDeauthImminentNotice(
+		struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay,
+		const char *url);
+	void notifyHs20RxTermsAndConditionsAcceptance(
+			struct wpa_supplicant *wpa_s, const char *url);
+	void notifyDisconnectReason(struct wpa_supplicant *wpa_s);
+	void notifyAssocReject(struct wpa_supplicant *wpa_s, const u8 *bssid,
+		u8 timed_out, const u8 *assoc_resp_ie, size_t assoc_resp_ie_len);
+	void notifyAuthTimeout(struct wpa_supplicant *wpa_s);
+	void notifyBssidChanged(struct wpa_supplicant *wpa_s);
+	void notifyWpsEventFail(
+		struct wpa_supplicant *wpa_s, uint8_t *peer_macaddr,
+		uint16_t config_error, uint16_t error_indication);
+	void notifyWpsEventSuccess(struct wpa_supplicant *wpa_s);
+	void notifyWpsEventPbcOverlap(struct wpa_supplicant *wpa_s);
+	void notifyP2pDeviceFound(
+		struct wpa_supplicant *wpa_s, const u8 *addr,
+		const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
+		u8 peer_wfd_device_info_len, const u8 *peer_wfd_r2_device_info,
+		u8 peer_wfd_r2_device_info_len);
+	void notifyP2pDeviceLost(
+		struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr);
+	void notifyP2pFindStopped(struct wpa_supplicant *wpa_s);
+	void notifyP2pGoNegReq(
+		struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
+		u8 go_intent);
+	void notifyP2pGoNegCompleted(
+		struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res);
+	void notifyP2pGroupFormationFailure(
+		struct wpa_supplicant *wpa_s, const char *reason);
+	void notifyP2pGroupStarted(
+		struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
+		int persistent, int client);
+	void notifyP2pGroupRemoved(
+		struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
+		const char *role);
+	void notifyP2pInvitationReceived(
+		struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
+		const u8 *bssid, int id, int op_freq);
+	void notifyP2pInvitationResult(
+		struct wpa_supplicant *wpa_s, int status, const u8 *bssid);
+	void notifyP2pProvisionDiscovery(
+		struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
+		enum p2p_prov_disc_status status, u16 config_methods,
+		unsigned int generated_pin);
+	void notifyP2pSdResponse(
+		struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
+		const u8 *tlvs, size_t tlvs_len);
+	void notifyApStaAuthorized(
+		struct wpa_supplicant *wpa_s, const u8 *sta,
+		const u8 *p2p_dev_addr);
+	void notifyApStaDeauthorized(
+		struct wpa_supplicant *wpa_s, const u8 *sta,
+		const u8 *p2p_dev_addr);
+	void notifyEapError(struct wpa_supplicant *wpa_s, int error_code);
+	void notifyDppConfigReceived(struct wpa_supplicant *wpa_s,
+			struct wpa_ssid *config);
+	void notifyDppConfigSent(struct wpa_supplicant *wpa_s);
+	void notifyDppSuccess(struct wpa_supplicant *wpa_s, DppEventType code);
+	void notifyDppFailure(struct wpa_supplicant *wpa_s,
+			DppFailureCode code);
+	void notifyDppFailure(struct wpa_supplicant *wpa_s,
+			DppFailureCode code,
+			const char *ssid, const char *channel_list, unsigned short band_list[],
+			int size);
+	void notifyDppProgress(struct wpa_supplicant *wpa_s,
+			DppProgressCode code);
+	void notifyPmkCacheAdded(struct wpa_supplicant *wpa_s,
+			struct rsn_pmksa_cache_entry *pmksa_entry);
+	void notifyBssTmStatus(struct wpa_supplicant *wpa_s);
+	void notifyTransitionDisable(struct wpa_supplicant *wpa_s,
+			struct wpa_ssid *ssid,
+			u8 bitmap);
+	void notifyNetworkNotFound(struct wpa_supplicant *wpa_s);
+	void notifyBssFreqChanged(struct wpa_supplicant *wpa_s);
+	void notifyCertification(struct wpa_supplicant *wpa_s,
+			int depth, const char *subject,
+			const char *altsubject[],
+			int num_altsubject,
+			const char *cert_hash,
+			const struct wpabuf *cert);
+
+	// Methods called from aidl objects.
+	void notifyExtRadioWorkStart(struct wpa_supplicant *wpa_s, uint32_t id);
+	void notifyExtRadioWorkTimeout(
+		struct wpa_supplicant *wpa_s, uint32_t id);
+
+	int getP2pIfaceAidlObjectByIfname(
+		const std::string &ifname,
+		std::shared_ptr<ISupplicantP2pIface> *iface_object);
+	int getStaIfaceAidlObjectByIfname(
+		const std::string &ifname,
+		std::shared_ptr<ISupplicantStaIface> *iface_object);
+	int getP2pNetworkAidlObjectByIfnameAndNetworkId(
+		const std::string &ifname, int network_id,
+		std::shared_ptr<ISupplicantP2pNetwork> *network_object);
+	int getStaNetworkAidlObjectByIfnameAndNetworkId(
+		const std::string &ifname, int network_id,
+		std::shared_ptr<ISupplicantStaNetwork> *network_object);
+	int addSupplicantCallbackAidlObject(
+		const std::shared_ptr<ISupplicantCallback> &callback);
+	int addP2pIfaceCallbackAidlObject(
+		const std::string &ifname,
+		const std::shared_ptr<ISupplicantP2pIfaceCallback> &callback);
+	int addStaIfaceCallbackAidlObject(
+		const std::string &ifname,
+		const std::shared_ptr<ISupplicantStaIfaceCallback> &callback);
+	int addStaNetworkCallbackAidlObject(
+		const std::string &ifname, int network_id,
+		const std::shared_ptr<ISupplicantStaNetworkCallback> &callback);
+
+private:
+	AidlManager() = default;
+	~AidlManager() = default;
+	AidlManager(const AidlManager &) = default;
+	AidlManager &operator=(const AidlManager &) = default;
+
+	struct wpa_supplicant *getTargetP2pIfaceForGroup(
+		struct wpa_supplicant *wpa_s);
+	void removeSupplicantCallbackAidlObject(
+		const std::shared_ptr<ISupplicantCallback> &callback);
+	void removeP2pIfaceCallbackAidlObject(
+		const std::string &ifname,
+		const std::shared_ptr<ISupplicantP2pIfaceCallback> &callback);
+	void removeStaIfaceCallbackAidlObject(
+		const std::string &ifname,
+		const std::shared_ptr<ISupplicantStaIfaceCallback> &callback);
+	void removeStaNetworkCallbackAidlObject(
+		const std::string &ifname, int network_id,
+		const std::shared_ptr<ISupplicantStaNetworkCallback> &callback);
+
+	void callWithEachSupplicantCallback(
+		const std::function<ndk::ScopedAStatus(
+		std::shared_ptr<ISupplicantCallback>)> &method);
+	void callWithEachP2pIfaceCallback(
+		const std::string &ifname,
+		const std::function<ndk::ScopedAStatus(
+		std::shared_ptr<ISupplicantP2pIfaceCallback>)> &method);
+	void callWithEachStaIfaceCallback(
+		const std::string &ifname,
+		const std::function<ndk::ScopedAStatus(
+		std::shared_ptr<ISupplicantStaIfaceCallback>)> &method);
+	void callWithEachStaNetworkCallback(
+		const std::string &ifname, int network_id,
+		const std::function<::ndk::ScopedAStatus(
+		std::shared_ptr<ISupplicantStaNetworkCallback>)> &method);
+
+	// Singleton instance of this class.
+	static AidlManager *instance_;
+	// Death notifier.
+	AIBinder_DeathRecipient* death_notifier_;
+	// The main aidl service object.
+	std::shared_ptr<Supplicant> supplicant_object_;
+	// Map of all the P2P interface specific aidl objects controlled by
+	// wpa_supplicant. This map is keyed in by the corresponding
+	// |ifname|.
+	std::map<const std::string, std::shared_ptr<P2pIface>>
+		p2p_iface_object_map_;
+	// Map of all the STA interface specific aidl objects controlled by
+	// wpa_supplicant. This map is keyed in by the corresponding
+	// |ifname|.
+	std::map<const std::string, std::shared_ptr<StaIface>>
+		sta_iface_object_map_;
+	// Map of all the P2P network specific aidl objects controlled by
+	// wpa_supplicant. This map is keyed in by the corresponding
+	// |ifname| & |network_id|.
+	std::map<const std::string, std::shared_ptr<P2pNetwork>>
+		p2p_network_object_map_;
+	// Map of all the STA network specific aidl objects controlled by
+	// wpa_supplicant. This map is keyed in by the corresponding
+	// |ifname| & |network_id|.
+	std::map<const std::string, std::shared_ptr<StaNetwork>>
+		sta_network_object_map_;
+
+	// Callbacks registered for the main aidl service object.
+	std::vector<std::shared_ptr<ISupplicantCallback>> supplicant_callbacks_;
+	// Map of all the callbacks registered for P2P interface specific
+	// aidl objects controlled by wpa_supplicant.  This map is keyed in by
+	// the corresponding |ifname|.
+	std::map<
+		const std::string,
+		std::vector<std::shared_ptr<ISupplicantP2pIfaceCallback>>>
+		p2p_iface_callbacks_map_;
+	// Map of all the callbacks registered for STA interface specific
+	// aidl objects controlled by wpa_supplicant.  This map is keyed in by
+	// the corresponding |ifname|.
+	std::map<
+		const std::string,
+		std::vector<std::shared_ptr<ISupplicantStaIfaceCallback>>>
+		sta_iface_callbacks_map_;
+	// Map of all the callbacks registered for STA network specific
+	// aidl objects controlled by wpa_supplicant.  This map is keyed in by
+	// the corresponding |ifname| & |network_id|.
+	std::map<
+		const std::string,
+		std::vector<std::shared_ptr<ISupplicantStaNetworkCallback>>>
+		sta_network_callbacks_map_;
+};
+
+// The aidl interface uses some values which are the same as internal ones to
+// avoid nasty runtime conversion functions. So, adding compile time asserts
+// to guard against any internal changes breaking the aidl interface.
+static_assert(
+	static_cast<uint32_t>(DebugLevel::EXCESSIVE) == MSG_EXCESSIVE,
+	"Debug level value mismatch");
+static_assert(
+	static_cast<uint32_t>(DebugLevel::ERROR) == MSG_ERROR,
+	"Debug level value mismatch");
+
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::NONE) ==
+	WPA_KEY_MGMT_NONE,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::WPA_PSK) ==
+	WPA_KEY_MGMT_PSK,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::WPA_EAP) ==
+	WPA_KEY_MGMT_IEEE8021X,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::IEEE8021X) ==
+	WPA_KEY_MGMT_IEEE8021X_NO_WPA,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::FT_EAP) ==
+	WPA_KEY_MGMT_FT_IEEE8021X,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::FT_PSK) ==
+	WPA_KEY_MGMT_FT_PSK,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::OSEN) ==
+	WPA_KEY_MGMT_OSEN,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::SAE) ==
+	WPA_KEY_MGMT_SAE,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::SUITE_B_192) ==
+	WPA_KEY_MGMT_IEEE8021X_SUITE_B_192,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::OWE) ==
+	WPA_KEY_MGMT_OWE,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::WPA_PSK_SHA256) ==
+	WPA_KEY_MGMT_PSK_SHA256,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::WPA_EAP_SHA256) ==
+	WPA_KEY_MGMT_IEEE8021X_SHA256,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::WAPI_PSK) ==
+	WPA_KEY_MGMT_WAPI_PSK,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(KeyMgmtMask::WAPI_CERT) ==
+	WPA_KEY_MGMT_WAPI_CERT,
+	"KeyMgmt value mismatch");
+static_assert(
+	static_cast<uint32_t>(ProtoMask::WPA) ==
+	WPA_PROTO_WPA,
+	"Proto value mismatch");
+static_assert(
+	static_cast<uint32_t>(ProtoMask::RSN) ==
+	WPA_PROTO_RSN,
+	"Proto value mismatch");
+static_assert(
+	static_cast<uint32_t>(ProtoMask::OSEN) ==
+	WPA_PROTO_OSEN,
+	"Proto value mismatch");
+static_assert(
+	static_cast<uint32_t>(ProtoMask::WAPI) ==
+	WPA_PROTO_WAPI,
+	"Proto value mismatch");
+static_assert(
+	static_cast<uint32_t>(AuthAlgMask::OPEN) ==
+	WPA_AUTH_ALG_OPEN,
+	"AuthAlg value mismatch");
+static_assert(
+	static_cast<uint32_t>(AuthAlgMask::SHARED) ==
+	WPA_AUTH_ALG_SHARED,
+	"AuthAlg value mismatch");
+static_assert(
+	static_cast<uint32_t>(AuthAlgMask::LEAP) ==
+	WPA_AUTH_ALG_LEAP,
+	"AuthAlg value mismatch");
+static_assert(
+	static_cast<uint32_t>(GroupCipherMask::WEP40) ==
+	WPA_CIPHER_WEP40,
+	"GroupCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(GroupCipherMask::WEP104) ==
+	WPA_CIPHER_WEP104,
+	"GroupCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(GroupCipherMask::TKIP) ==
+	WPA_CIPHER_TKIP,
+	"GroupCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(GroupCipherMask::CCMP) ==
+	WPA_CIPHER_CCMP,
+	"GroupCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(GroupCipherMask::GCMP_256) ==
+	WPA_CIPHER_GCMP_256,
+	"GroupCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(GroupCipherMask::SMS4) ==
+	WPA_CIPHER_SMS4,
+	"GroupCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(
+	GroupCipherMask::GTK_NOT_USED) ==
+	WPA_CIPHER_GTK_NOT_USED,
+	"GroupCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(PairwiseCipherMask::NONE) ==
+	WPA_CIPHER_NONE,
+	"PairwiseCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(PairwiseCipherMask::TKIP) ==
+	WPA_CIPHER_TKIP,
+	"PairwiseCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(PairwiseCipherMask::CCMP) ==
+	WPA_CIPHER_CCMP,
+	"PairwiseCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(
+	PairwiseCipherMask::GCMP_256) ==
+	WPA_CIPHER_GCMP_256,
+	"PairwiseCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(
+	PairwiseCipherMask::SMS4) ==
+	WPA_CIPHER_SMS4,
+	"PairwiseCipher value mismatch");
+static_assert(
+	static_cast<uint32_t>(StaIfaceCallbackState::DISCONNECTED) ==
+	WPA_DISCONNECTED,
+	"State value mismatch");
+static_assert(
+	static_cast<uint32_t>(StaIfaceCallbackState::COMPLETED) ==
+	WPA_COMPLETED,
+	"State value mismatch");
+
+static_assert(
+	static_cast<uint32_t>(AnqpInfoId::VENUE_NAME) ==
+	ANQP_VENUE_NAME,
+	"ANQP ID value mismatch");
+static_assert(
+	static_cast<uint32_t>(
+	AnqpInfoId::ROAMING_CONSORTIUM) ==
+	ANQP_ROAMING_CONSORTIUM,
+	"ANQP ID value mismatch");
+static_assert(
+	static_cast<uint32_t>(AnqpInfoId::NAI_REALM) ==
+	ANQP_NAI_REALM,
+	"ANQP ID value mismatch");
+static_assert(
+	static_cast<uint32_t>(
+	AnqpInfoId::IP_ADDR_TYPE_AVAILABILITY) ==
+	ANQP_IP_ADDR_TYPE_AVAILABILITY,
+	"ANQP ID value mismatch");
+static_assert(
+	static_cast<uint32_t>(
+	AnqpInfoId::ANQP_3GPP_CELLULAR_NETWORK) ==
+	ANQP_3GPP_CELLULAR_NETWORK,
+	"ANQP ID value mismatch");
+static_assert(
+	static_cast<uint32_t>(AnqpInfoId::DOMAIN_NAME) ==
+	ANQP_DOMAIN_NAME,
+	"ANQP ID value mismatch");
+static_assert(
+	static_cast<uint32_t>(
+	Hs20AnqpSubtypes::OPERATOR_FRIENDLY_NAME) ==
+	HS20_STYPE_OPERATOR_FRIENDLY_NAME,
+	"HS Subtype value mismatch");
+static_assert(
+	static_cast<uint32_t>(Hs20AnqpSubtypes::WAN_METRICS) ==
+	HS20_STYPE_WAN_METRICS,
+	"HS Subtype value mismatch");
+static_assert(
+	static_cast<uint32_t>(
+	Hs20AnqpSubtypes::CONNECTION_CAPABILITY) ==
+	HS20_STYPE_CONNECTION_CAPABILITY,
+	"HS Subtype value mismatch");
+static_assert(
+	static_cast<uint32_t>(
+	Hs20AnqpSubtypes::OSU_PROVIDERS_LIST) ==
+	HS20_STYPE_OSU_PROVIDERS_LIST,
+	"HS Subtype value mismatch");
+
+static_assert(
+	static_cast<uint16_t>(
+	WpsConfigError::NO_ERROR) ==
+	WPS_CFG_NO_ERROR,
+	"Wps config error value mismatch");
+static_assert(
+	static_cast<uint16_t>(WpsConfigError::
+				  PUBLIC_KEY_HASH_MISMATCH) ==
+	WPS_CFG_PUBLIC_KEY_HASH_MISMATCH,
+	"Wps config error value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	WpsErrorIndication::NO_ERROR) ==
+	WPS_EI_NO_ERROR,
+	"Wps error indication value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	WpsErrorIndication::AUTH_FAILURE) ==
+	WPS_EI_AUTH_FAILURE,
+	"Wps error indication value mismatch");
+
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::USBA) == WPS_CONFIG_USBA,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::ETHERNET) == WPS_CONFIG_ETHERNET,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::LABEL) == WPS_CONFIG_LABEL,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::DISPLAY) == WPS_CONFIG_DISPLAY,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::INT_NFC_TOKEN) ==
+	WPS_CONFIG_INT_NFC_TOKEN,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::EXT_NFC_TOKEN) ==
+	WPS_CONFIG_EXT_NFC_TOKEN,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::NFC_INTERFACE) ==
+	WPS_CONFIG_NFC_INTERFACE,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::PUSHBUTTON) ==
+	WPS_CONFIG_PUSHBUTTON,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::KEYPAD) == WPS_CONFIG_KEYPAD,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::VIRT_PUSHBUTTON) ==
+	WPS_CONFIG_VIRT_PUSHBUTTON,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::PHY_PUSHBUTTON) ==
+	WPS_CONFIG_PHY_PUSHBUTTON,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::P2PS) == WPS_CONFIG_P2PS,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::VIRT_DISPLAY) ==
+	WPS_CONFIG_VIRT_DISPLAY,
+	"Wps config value mismatch");
+static_assert(
+	static_cast<uint32_t>(WpsConfigMethods::PHY_DISPLAY) ==
+	WPS_CONFIG_PHY_DISPLAY,
+	"Wps config value mismatch");
+
+static_assert(
+	static_cast<uint32_t>(P2pGroupCapabilityMask::GROUP_OWNER) ==
+	P2P_GROUP_CAPAB_GROUP_OWNER,
+	"P2P capability value mismatch");
+static_assert(
+	static_cast<uint32_t>(P2pGroupCapabilityMask::PERSISTENT_GROUP) ==
+	P2P_GROUP_CAPAB_PERSISTENT_GROUP,
+	"P2P capability value mismatch");
+static_assert(
+	static_cast<uint32_t>(P2pGroupCapabilityMask::GROUP_LIMIT) ==
+	P2P_GROUP_CAPAB_GROUP_LIMIT,
+	"P2P capability value mismatch");
+static_assert(
+	static_cast<uint32_t>(P2pGroupCapabilityMask::INTRA_BSS_DIST) ==
+	P2P_GROUP_CAPAB_INTRA_BSS_DIST,
+	"P2P capability value mismatch");
+static_assert(
+	static_cast<uint32_t>(P2pGroupCapabilityMask::CROSS_CONN) ==
+	P2P_GROUP_CAPAB_CROSS_CONN,
+	"P2P capability value mismatch");
+static_assert(
+	static_cast<uint32_t>(P2pGroupCapabilityMask::PERSISTENT_RECONN) ==
+	P2P_GROUP_CAPAB_PERSISTENT_RECONN,
+	"P2P capability value mismatch");
+static_assert(
+	static_cast<uint32_t>(P2pGroupCapabilityMask::GROUP_FORMATION) ==
+	P2P_GROUP_CAPAB_GROUP_FORMATION,
+	"P2P capability value mismatch");
+
+static_assert(
+	static_cast<uint16_t>(
+	WpsDevPasswordId::DEFAULT) ==
+	DEV_PW_DEFAULT,
+	"Wps dev password id value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	WpsDevPasswordId::USER_SPECIFIED) ==
+	DEV_PW_USER_SPECIFIED,
+	"Wps dev password id value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	WpsDevPasswordId::MACHINE_SPECIFIED) ==
+	DEV_PW_MACHINE_SPECIFIED,
+	"Wps dev password id value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	WpsDevPasswordId::REKEY) == DEV_PW_REKEY,
+	"Wps dev password id value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	WpsDevPasswordId::PUSHBUTTON) ==
+	DEV_PW_PUSHBUTTON,
+	"Wps dev password id value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	WpsDevPasswordId::REGISTRAR_SPECIFIED) ==
+	DEV_PW_REGISTRAR_SPECIFIED,
+	"Wps dev password id value mismatch");
+static_assert(
+	static_cast<uint16_t>(WpsDevPasswordId::
+				  NFC_CONNECTION_HANDOVER) ==
+	DEV_PW_NFC_CONNECTION_HANDOVER,
+	"Wps dev password id value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	WpsDevPasswordId::P2PS_DEFAULT) ==
+	DEV_PW_P2PS_DEFAULT,
+	"Wps dev password id value mismatch");
+
+static_assert(
+	static_cast<uint16_t>(
+	P2pStatusCode::SUCCESS) == P2P_SC_SUCCESS,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(P2pStatusCode::
+				  FAIL_INFO_CURRENTLY_UNAVAILABLE) ==
+	P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pStatusCode::FAIL_INCOMPATIBLE_PARAMS) ==
+	P2P_SC_FAIL_INCOMPATIBLE_PARAMS,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pStatusCode::FAIL_LIMIT_REACHED) ==
+	P2P_SC_FAIL_LIMIT_REACHED,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pStatusCode::FAIL_INVALID_PARAMS) ==
+	P2P_SC_FAIL_INVALID_PARAMS,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(P2pStatusCode::
+				  FAIL_UNABLE_TO_ACCOMMODATE) ==
+	P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pStatusCode::FAIL_PREV_PROTOCOL_ERROR) ==
+	P2P_SC_FAIL_PREV_PROTOCOL_ERROR,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pStatusCode::FAIL_NO_COMMON_CHANNELS) ==
+	P2P_SC_FAIL_NO_COMMON_CHANNELS,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pStatusCode::FAIL_UNKNOWN_GROUP) ==
+	P2P_SC_FAIL_UNKNOWN_GROUP,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pStatusCode::FAIL_BOTH_GO_INTENT_15) ==
+	P2P_SC_FAIL_BOTH_GO_INTENT_15,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(P2pStatusCode::
+				  FAIL_INCOMPATIBLE_PROV_METHOD) ==
+	P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pStatusCode::FAIL_REJECTED_BY_USER) ==
+	P2P_SC_FAIL_REJECTED_BY_USER,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pStatusCode::SUCCESS_DEFERRED) ==
+	P2P_SC_SUCCESS_DEFERRED,
+	"P2P status code value mismatch");
+
+static_assert(
+	static_cast<uint16_t>(
+	P2pProvDiscStatusCode::SUCCESS) ==
+	P2P_PROV_DISC_SUCCESS,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pProvDiscStatusCode::TIMEOUT) ==
+	P2P_PROV_DISC_TIMEOUT,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pProvDiscStatusCode::REJECTED) ==
+	P2P_PROV_DISC_REJECTED,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pProvDiscStatusCode::TIMEOUT_JOIN) ==
+	P2P_PROV_DISC_TIMEOUT_JOIN,
+	"P2P status code value mismatch");
+static_assert(
+	static_cast<uint16_t>(
+	P2pProvDiscStatusCode::INFO_UNAVAILABLE) ==
+	P2P_PROV_DISC_INFO_UNAVAILABLE,
+	"P2P status code value mismatch");
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+#endif  // WPA_SUPPLICANT_AIDL_AIDL_MANAGER_H
diff --git a/wpa_supplicant/aidl/aidl_return_util.h b/wpa_supplicant/aidl/aidl_return_util.h
new file mode 100644
index 0000000..109723a
--- /dev/null
+++ b/wpa_supplicant/aidl/aidl_return_util.h
@@ -0,0 +1,66 @@
+/*
+ * WPA Supplicant - Validate interfaces before calling methods
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef AIDL_RETURN_UTIL_H_
+#define AIDL_RETURN_UTIL_H_
+
+#include <aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.h>
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+namespace aidl_return_util {
+
+/**
+ * These utility functions are used to invoke a method on the provided
+ * AIDL interface object.
+ * These functions check if the provided AIDL interface object is valid.
+ * a) If valid, invokes the corresponding internal implementation function of
+ * the AIDL method.
+ * b) If invalid, return without calling the internal implementation function.
+ */
+
+// Use for AIDL methods which only return an AIDL status
+template <typename ObjT, typename WorkFuncT, typename... Args>
+::ndk::ScopedAStatus validateAndCall(
+	ObjT* obj, SupplicantStatusCode status_code_if_invalid, WorkFuncT&& work,
+	Args&&... args)
+{
+	if (obj->isValid()) {
+		return (obj->*work)(std::forward<Args>(args)...);
+	} else {
+		return ndk::ScopedAStatus::fromServiceSpecificError(
+			static_cast<int32_t>(status_code_if_invalid));
+	}
+}
+
+// Use for AIDL methods which have a return value along with the AIDL status
+template <typename ObjT, typename WorkFuncT, typename ReturnT, typename... Args>
+::ndk::ScopedAStatus validateAndCall(
+	ObjT* obj, SupplicantStatusCode status_code_if_invalid, WorkFuncT&& work,
+	ReturnT* ret_val, Args&&... args)
+{
+	if (obj->isValid()) {
+		auto call_pair = (obj->*work)(std::forward<Args>(args)...);
+		*ret_val = call_pair.first;
+		return std::forward<::ndk::ScopedAStatus>(call_pair.second);
+	} else {
+		return ndk::ScopedAStatus::fromServiceSpecificError(
+			static_cast<int32_t>(status_code_if_invalid));
+	}
+}
+
+}  // namespace aidl_return_util
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+#endif  // AIDL_RETURN_UTIL_H_
diff --git a/wpa_supplicant/aidl/android.hardware.wifi.supplicant-service.rc b/wpa_supplicant/aidl/android.hardware.wifi.supplicant-service.rc
new file mode 100644
index 0000000..3275e36
--- /dev/null
+++ b/wpa_supplicant/aidl/android.hardware.wifi.supplicant-service.rc
@@ -0,0 +1,12 @@
+service wpa_supplicant /vendor/bin/hw/wpa_supplicant \
+	-O/data/vendor/wifi/wpa/sockets -dd \
+	-g@android:wpa_wlan0
+	#   we will start as root and wpa_supplicant will switch to user wifi
+	#   after setting up the capabilities required for WEXT
+	#   user wifi
+	#   group wifi inet keystore
+	interface aidl android.hardware.wifi.supplicant.ISupplicant/default
+	class main
+	socket wpa_wlan0 dgram 660 wifi wifi
+	disabled
+	oneshot
diff --git a/wpa_supplicant/aidl/android.hardware.wifi.supplicant.xml b/wpa_supplicant/aidl/android.hardware.wifi.supplicant.xml
new file mode 100644
index 0000000..3dc9b02
--- /dev/null
+++ b/wpa_supplicant/aidl/android.hardware.wifi.supplicant.xml
@@ -0,0 +1,6 @@
+<manifest version="1.0" type="device">
+	<hal format="aidl">
+		<name>android.hardware.wifi.supplicant</name>
+		<fqname>ISupplicant/default</fqname>
+	</hal>
+</manifest>
diff --git a/wpa_supplicant/aidl/iface_config_utils.cpp b/wpa_supplicant/aidl/iface_config_utils.cpp
new file mode 100644
index 0000000..4d3f29c
--- /dev/null
+++ b/wpa_supplicant/aidl/iface_config_utils.cpp
@@ -0,0 +1,179 @@
+/*
+ * WPA Supplicant - Iface configuration methods
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "aidl_manager.h"
+#include "aidl_return_util.h"
+#include "iface_config_utils.h"
+#include "misc_utils.h"
+
+namespace {
+using aidl::android::hardware::wifi::supplicant::SupplicantStatusCode;
+using aidl::android::hardware::wifi::supplicant::WpsConfigMethods;
+
+constexpr uint32_t kMaxWpsDeviceNameSize = WPS_DEV_NAME_MAX_LEN;
+constexpr uint32_t kMaxWpsManufacturerSize = WPS_MANUFACTURER_MAX_LEN;
+constexpr uint32_t kMaxWpsModelNameSize = WPS_MODEL_NAME_MAX_LEN;
+constexpr uint32_t kMaxWpsModelNumberSize = WPS_MODEL_NUMBER_MAX_LEN;
+constexpr uint32_t kMaxWpsSerialNumberSize = WPS_SERIAL_NUMBER_MAX_LEN;
+
+void processConfigUpdate(struct wpa_supplicant* wpa_s, uint32_t changed_param)
+{
+	wpa_s->conf->changed_parameters |= changed_param;
+	wpa_supplicant_update_config(wpa_s);
+}
+
+// Free any existing pointer stored in |dst| and store the provided string value
+// there.
+int freeAndSetStringConfigParam(
+	struct wpa_supplicant* wpa_s, const std::string& value, uint32_t max_size,
+	uint32_t changed_param, char** dst)
+{
+	if (value.size() > max_size) {
+		return -1;
+	}
+	WPA_ASSERT(dst);
+	os_free(static_cast<void*>(*dst));
+	*dst = os_strdup(value.c_str());
+	processConfigUpdate(wpa_s, changed_param);
+	return 0;
+}
+
+std::string convertWpsConfigMethodsMaskToString(uint16_t config_methods)
+{
+	std::string config_methods_str;
+	for (const auto& flag_and_name :
+		 {std::make_pair(WpsConfigMethods::USBA, "usba"),
+		  {WpsConfigMethods::ETHERNET, "ethernet"},
+		  {WpsConfigMethods::LABEL, "label"},
+		  {WpsConfigMethods::DISPLAY, "display"},
+		  {WpsConfigMethods::INT_NFC_TOKEN, "int_nfc_token"},
+		  {WpsConfigMethods::EXT_NFC_TOKEN, "ext_nfc_token"},
+		  {WpsConfigMethods::NFC_INTERFACE, "nfc_interface"},
+		  {WpsConfigMethods::PUSHBUTTON, "push_button"},
+		  {WpsConfigMethods::KEYPAD, "keypad"},
+		  {WpsConfigMethods::VIRT_PUSHBUTTON, "virtual_push_button"},
+		  {WpsConfigMethods::PHY_PUSHBUTTON, "physical_push_button"},
+		  {WpsConfigMethods::P2PS, "p2ps"},
+		  {WpsConfigMethods::VIRT_DISPLAY, "virtual_display"},
+		  {WpsConfigMethods::PHY_DISPLAY, "physical_display"}}) {
+		const auto flag =
+			static_cast<std::underlying_type<WpsConfigMethods>::type>(
+			flag_and_name.first);
+		if ((config_methods & flag) == flag) {
+			config_methods_str += flag_and_name.second;
+			config_methods_str += " ";
+		}
+	}
+	return config_methods_str;
+}
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+namespace iface_config_utils {
+using misc_utils::createStatus;
+
+ndk::ScopedAStatus setWpsDeviceName(
+	struct wpa_supplicant* wpa_s, const std::string& name)
+{
+	WPA_ASSERT(wpa_s);
+	if (freeAndSetStringConfigParam(
+		wpa_s, name, kMaxWpsDeviceNameSize, CFG_CHANGED_DEVICE_NAME,
+		&wpa_s->conf->device_name)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus setWpsDeviceType(
+	struct wpa_supplicant* wpa_s, const std::array<uint8_t, WPS_DEV_TYPE_LEN>& type)
+{
+	WPA_ASSERT(wpa_s);
+	WPA_ASSERT(type.size() == WPS_DEV_TYPE_LEN);
+	os_memcpy(wpa_s->conf->device_type, type.data(), WPS_DEV_TYPE_LEN);
+	processConfigUpdate(wpa_s, CFG_CHANGED_DEVICE_TYPE);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus setWpsManufacturer(
+	struct wpa_supplicant* wpa_s, const std::string& manufacturer)
+{
+	WPA_ASSERT(wpa_s);
+	if (freeAndSetStringConfigParam(
+		wpa_s, manufacturer, kMaxWpsManufacturerSize,
+		CFG_CHANGED_WPS_STRING, &wpa_s->conf->manufacturer)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus setWpsModelName(
+	struct wpa_supplicant* wpa_s, const std::string& model_name)
+{
+	WPA_ASSERT(wpa_s);
+	if (freeAndSetStringConfigParam(
+		wpa_s, model_name, kMaxWpsModelNameSize, CFG_CHANGED_WPS_STRING,
+		&wpa_s->conf->model_name)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus setWpsModelNumber(
+	struct wpa_supplicant* wpa_s, const std::string& model_number)
+{
+	WPA_ASSERT(wpa_s);
+	if (freeAndSetStringConfigParam(
+		wpa_s, model_number, kMaxWpsModelNumberSize,
+		CFG_CHANGED_WPS_STRING, &wpa_s->conf->model_number)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus setWpsSerialNumber(
+	struct wpa_supplicant* wpa_s, const std::string& serial_number)
+{
+	WPA_ASSERT(wpa_s);
+	if (freeAndSetStringConfigParam(
+		wpa_s, serial_number, kMaxWpsSerialNumberSize,
+		CFG_CHANGED_WPS_STRING, &wpa_s->conf->serial_number)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus setWpsConfigMethods(
+	struct wpa_supplicant* wpa_s, uint16_t config_methods)
+{
+	WPA_ASSERT(wpa_s);
+	if (freeAndSetStringConfigParam(
+		wpa_s, convertWpsConfigMethodsMaskToString(config_methods),
+		UINT32_MAX, CFG_CHANGED_CONFIG_METHODS,
+		&wpa_s->conf->config_methods)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus setExternalSim(
+	struct wpa_supplicant* wpa_s, bool useExternalSim)
+{
+	WPA_ASSERT(wpa_s);
+	wpa_s->conf->external_sim = useExternalSim ? 1 : 0;
+	return ndk::ScopedAStatus::ok();
+}
+}  // namespace iface_config_utils
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wpa_supplicant/aidl/iface_config_utils.h b/wpa_supplicant/aidl/iface_config_utils.h
new file mode 100644
index 0000000..c17dbb4
--- /dev/null
+++ b/wpa_supplicant/aidl/iface_config_utils.h
@@ -0,0 +1,55 @@
+/*
+ * WPA Supplicant - Iface configuration methods
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef WPA_SUPPLICANT_AIDL_IFACE_CONFIG_UTILS_H
+#define WPA_SUPPLICANT_AIDL_IFACE_CONFIG_UTILS_H
+
+#include <android-base/macros.h>
+
+extern "C"
+{
+#include "utils/common.h"
+#include "utils/includes.h"
+#include "wpa_supplicant_i.h"
+#include "config.h"
+}
+
+/**
+ * Utility functions to set various config parameters of an iface via AIDL
+ * methods.
+ */
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+namespace iface_config_utils {
+ndk::ScopedAStatus setWpsDeviceName(
+	struct wpa_supplicant* wpa_s, const std::string& name);
+ndk::ScopedAStatus setWpsDeviceType(
+	struct wpa_supplicant* wpa_s, const std::array<uint8_t, 8>& type);
+ndk::ScopedAStatus setWpsManufacturer(
+	struct wpa_supplicant* wpa_s, const std::string& manufacturer);
+ndk::ScopedAStatus setWpsModelName(
+	struct wpa_supplicant* wpa_s, const std::string& model_name);
+ndk::ScopedAStatus setWpsModelNumber(
+	struct wpa_supplicant* wpa_s, const std::string& model_number);
+ndk::ScopedAStatus setWpsSerialNumber(
+	struct wpa_supplicant* wpa_s, const std::string& serial_number);
+ndk::ScopedAStatus setWpsConfigMethods(
+	struct wpa_supplicant* wpa_s, uint16_t config_methods);
+ndk::ScopedAStatus setExternalSim(
+	struct wpa_supplicant* wpa_s, bool useExternalSim);
+}  // namespace iface_config_utils
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WPA_SUPPLICANT_AIDL_IFACE_CONFIG_UTILS_H
diff --git a/wpa_supplicant/hidl/1.4/misc_utils.h b/wpa_supplicant/aidl/misc_utils.h
similarity index 75%
rename from wpa_supplicant/hidl/1.4/misc_utils.h
rename to wpa_supplicant/aidl/misc_utils.h
index 6e69d4c..5c5b68c 100644
--- a/wpa_supplicant/hidl/1.4/misc_utils.h
+++ b/wpa_supplicant/aidl/misc_utils.h
@@ -1,7 +1,6 @@
 /*
- * hidl interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
+ * WPA Supplicant - Helper methods for Aidl
+ * Copyright (c) 2021, Google Inc. All rights reserved.
  *
  * This software may be distributed under the terms of the BSD license.
  * See README for more details.
@@ -11,6 +10,7 @@
 #define MISC_UTILS_H_
 
 #include <iostream>
+#include <aidl/android/hardware/wifi/supplicant/SupplicantStatusCode.h>
 
 extern "C"
 {
@@ -23,12 +23,11 @@
 void freeWpaBuf(wpabuf *ptr) { wpabuf_free(ptr); }
 }  // namespace
 
+namespace aidl {
 namespace android {
 namespace hardware {
 namespace wifi {
 namespace supplicant {
-namespace V1_4 {
-namespace implementation {
 namespace misc_utils {
 using wpabuf_unique_ptr = std::unique_ptr<wpabuf, void (*)(wpabuf *)>;
 
@@ -43,7 +42,7 @@
 inline wpabuf_unique_ptr convertVectorToWpaBuf(const std::vector<uint8_t> &data)
 {
 	return createWpaBufUniquePtr(
-	    wpabuf_alloc_copy(data.data(), data.size()));
+		wpabuf_alloc_copy(data.data(), data.size()));
 }
 
 // Copies the provided wpabuf contents to a std::vector.
@@ -51,7 +50,7 @@
 {
 	if (buf) {
 		return std::vector<uint8_t>(
-		    wpabuf_head_u8(buf), wpabuf_head_u8(buf) + wpabuf_len(buf));
+			wpabuf_head_u8(buf), wpabuf_head_u8(buf) + wpabuf_len(buf));
 	} else {
 		return std::vector<uint8_t>();
 	}
@@ -65,8 +64,26 @@
 	return pin_str;
 }
 
+// Wrappers to create a ScopedAStatus using a SupplicantStatusCode
+inline ndk::ScopedAStatus createStatus(SupplicantStatusCode status_code) {
+	return ndk::ScopedAStatus::fromServiceSpecificError(
+		static_cast<int32_t>(status_code));
+}
+
+inline ndk::ScopedAStatus createStatusWithMsg(
+	SupplicantStatusCode status_code, std::string msg)
+{
+	return ndk::ScopedAStatus::fromServiceSpecificErrorWithMessage(
+		static_cast<int32_t>(status_code), msg.c_str());
+}
+
+// Creates an std::string from a char*, which could be null
+inline std::string charBufToString(const char* buf) {
+	return buf ? std::string(buf) : "";
+}
+
 inline std::stringstream& serializePmkCacheEntry(
-    std::stringstream &ss, struct rsn_pmksa_cache_entry *pmksa_entry) {
+	std::stringstream &ss, struct rsn_pmksa_cache_entry *pmksa_entry) {
 	ss.write((char *) &pmksa_entry->pmk_len, sizeof(pmksa_entry->pmk_len));
 	ss.write((char *) pmksa_entry->pmk, pmksa_entry->pmk_len);
 	ss.write((char *) pmksa_entry->pmkid, PMKID_LEN);
@@ -84,7 +101,7 @@
 }
 
 inline std::stringstream& deserializePmkCacheEntry(
-    std::stringstream &ss, struct rsn_pmksa_cache_entry *pmksa_entry) {
+	std::stringstream &ss, struct rsn_pmksa_cache_entry *pmksa_entry) {
 	ss.seekg(0);
 	ss.read((char *) &pmksa_entry->pmk_len, sizeof(pmksa_entry->pmk_len));
 	ss.read((char *) pmksa_entry->pmk, pmksa_entry->pmk_len);
@@ -102,10 +119,9 @@
 	return ss;
 }
 }  // namespace misc_utils
-}  // namespace implementation
-}  // namespace V1_4
 }  // namespace supplicant
 }  // namespace wifi
 }  // namespace hardware
 }  // namespace android
+}  // namespace aidl
 #endif  // MISC_UTILS_H_
diff --git a/wpa_supplicant/aidl/p2p_iface.cpp b/wpa_supplicant/aidl/p2p_iface.cpp
new file mode 100644
index 0000000..50d8fb2
--- /dev/null
+++ b/wpa_supplicant/aidl/p2p_iface.cpp
@@ -0,0 +1,2166 @@
+/*
+ * WPA Supplicant - P2P Iface Aidl interface
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "aidl_manager.h"
+#include "aidl_return_util.h"
+#include "iface_config_utils.h"
+#include "misc_utils.h"
+#include "p2p_iface.h"
+#include "sta_network.h"
+
+extern "C"
+{
+#include "ap.h"
+#include "wps_supplicant.h"
+#include "wifi_display.h"
+#include "utils/eloop.h"
+#include "wpa_supplicant_i.h"
+#include "driver_i.h"
+}
+
+#define P2P_MAX_JOIN_SCAN_ATTEMPTS 3
+// Wait time before triggering the single channel scan to discover Auto GO.
+// Use a shorter wait time when the given frequency is GO operating frequency.
+// The idea is to quickly finish scans and return the status to application.
+#define P2P_JOIN_SINGLE_CHANNEL_SCAN_INTERVAL_USECS 200000
+// Wait time before triggering the multiple channel scan to discover Auto GO.
+#define P2P_JOIN_MULTIPLE_CHANNEL_SCAN_INTERVAL_USECS 1000000
+
+namespace {
+const char kConfigMethodStrPbc[] = "pbc";
+const char kConfigMethodStrDisplay[] = "display";
+const char kConfigMethodStrKeypad[] = "keypad";
+constexpr char kSetMiracastMode[] = "MIRACAST ";
+constexpr uint8_t kWfdDeviceInfoSubelemId = 0;
+constexpr uint8_t kWfdR2DeviceInfoSubelemId = 11;
+constexpr char kWfdDeviceInfoSubelemLenHexStr[] = "0006";
+
+std::function<void()> pending_join_scan_callback = NULL;
+std::function<void()> pending_scan_res_join_callback = NULL;
+
+using aidl::android::hardware::wifi::supplicant::ISupplicantP2pIface;
+using aidl::android::hardware::wifi::supplicant::ISupplicantStaNetwork;
+using aidl::android::hardware::wifi::supplicant::MiracastMode;
+using aidl::android::hardware::wifi::supplicant::P2pFrameTypeMask;
+
+uint8_t convertAidlMiracastModeToInternal(
+	MiracastMode mode)
+{
+	switch (mode) {
+	case MiracastMode::DISABLED:
+		return 0;
+	case MiracastMode::SOURCE:
+		return 1;
+	case MiracastMode::SINK:
+		return 2;
+	};
+	WPA_ASSERT(false);
+}
+
+/**
+ * Check if the provided ssid is valid or not.
+ *
+ * Returns 1 if valid, 0 otherwise.
+ */
+int isSsidValid(const std::vector<uint8_t>& ssid)
+{
+	if (ssid.size() == 0 ||
+		ssid.size() >
+		static_cast<uint32_t>(ISupplicantStaNetwork::
+					  SSID_MAX_LEN_IN_BYTES)) {
+		return 0;
+	}
+	return 1;
+}
+
+/**
+ * Check if the provided psk passhrase is valid or not.
+ *
+ * Returns 1 if valid, 0 otherwise.
+ */
+int isPskPassphraseValid(const std::string &psk)
+{
+	if (psk.size() <
+		static_cast<uint32_t>(ISupplicantStaNetwork::
+					  PSK_PASSPHRASE_MIN_LEN_IN_BYTES) ||
+		psk.size() >
+		static_cast<uint32_t>(ISupplicantStaNetwork::
+					  PSK_PASSPHRASE_MAX_LEN_IN_BYTES)) {
+		return 0;
+	}
+	if (has_ctrl_char((u8 *)psk.c_str(), psk.size())) {
+		return 0;
+	}
+	return 1;
+}
+
+static int setBandScanFreqsList(
+	struct wpa_supplicant *wpa_s,
+	enum hostapd_hw_mode hw_mode,
+	bool exclude_dfs,
+	struct wpa_driver_scan_params *params)
+{
+	struct hostapd_hw_modes *mode;
+	int count, i;
+
+	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, hw_mode, 0);
+	if (mode == NULL || !mode->num_channels) {
+		wpa_printf(MSG_ERROR,
+			"P2P: No channels supported in this hw_mode: %d", hw_mode);
+		return -1;
+	}
+
+	/*
+	 * Allocate memory for frequency array, allocate one extra
+	 * slot for the zero-terminator.
+	 */
+	params->freqs = (int *) os_calloc(mode->num_channels + 1, sizeof(int));
+	if (params->freqs == NULL) {
+		return -ENOMEM;
+	}
+	for (count = 0, i = 0; i < mode->num_channels; i++) {
+		if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED) {
+			continue;
+		}
+		if (exclude_dfs && (mode->channels[i].flag & HOSTAPD_CHAN_RADAR)) {
+			continue;
+		}
+		params->freqs[count++] = mode->channels[i].freq;
+	}
+	if (!count && params->freqs) {
+		wpa_printf(MSG_ERROR,
+			"P2P: All channels(exclude_dfs: %d) are disabled in this hw_mode: %d",
+			exclude_dfs, hw_mode);
+		os_free(params->freqs);
+		return -1;
+	}
+	return 0;
+}
+
+static int setScanFreq(struct wpa_supplicant *wpa_s, struct wpa_driver_scan_params *params,
+	int freq, int operating_freq)
+{
+	int frequency = operating_freq ? operating_freq : freq;
+	if (disabled_freq(wpa_s, frequency)) {
+		wpa_printf(MSG_ERROR,
+				"P2P: freq %d is not supported for a client.", frequency);
+		return -1;
+	}
+	/*
+	 * Allocate memory for frequency array, with one extra
+	 * slot for the zero-terminator.
+	 */
+	params->freqs = new int[2] {frequency, 0};
+	return 0;
+}
+
+/**
+ * setP2pCliOptimizedScanFreqsList - Fill the frequencies to scan in Scan
+ * parameters.
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @params: Pointer to Scan parameters.
+ * @freq: Frequency/Band requested to scan by the application, possible values are,
+ *		0 - All the frequencies - full scan
+ *		2 - Frequencies in 2.4GHz
+ *		5 - Frequencies in 5GHz
+ *		- Valid frequency
+ * @operating_freq: Frequency of BSS if found in scan cache
+ * Returns: Pointer to the BSS entry or %NULL if not found
+ */
+static int setP2pCliOptimizedScanFreqsList(struct wpa_supplicant *wpa_s,
+	struct wpa_driver_scan_params *params, int freq, int operating_freq)
+{
+	int ret;
+	/* If BSS is found in scan cache, first scan its operating frequency */
+	if (!wpa_s->p2p_join_scan_count && operating_freq) {
+		ret = setScanFreq(wpa_s, params, freq, operating_freq);
+		if (!ret) {
+			return ret;
+		}
+	}
+
+	/* Empty freq params means scan all the frequencies */
+	if (freq == 0) {
+		return 0;
+	}
+	else if (freq == 2 || freq == 5) {
+		/* Scan the frequencies in the band */
+		enum hostapd_hw_mode mode;
+		int ret;
+		if (wpa_s->hw.modes == NULL) {
+			wpa_printf(MSG_DEBUG,
+				   "P2P: Unknown what %dG channels the driver supports.", freq);
+			return 0;
+		}
+		mode = freq == 5 ? HOSTAPD_MODE_IEEE80211A : HOSTAPD_MODE_IEEE80211G;
+		if (wpa_s->p2p_join_scan_count < 2) {
+			// scan all non DFS channels in the first two attempts
+			ret = setBandScanFreqsList(wpa_s, mode, true, params);
+			if (ret < 0 && (-ENOMEM != ret)) {
+				// try to scan all channels before returning error
+				ret = setBandScanFreqsList(wpa_s, mode, false, params);
+			}
+		} else {
+			// scan all channels
+			ret = setBandScanFreqsList(wpa_s, mode, false, params);
+		}
+		return ret;
+	} else {
+		/* Scan the frequency requested by the application */
+		ret = setScanFreq(wpa_s, params, freq, 0);
+		return ret;
+	}
+	return 0;
+}
+
+/**
+ * getP2pJoinScanInterval - Get the delay in triggering the scan to discover
+ * Auto GO.
+ */
+static int getP2pJoinScanIntervalUsecs(int freq)
+{
+	if (freq == 5 || freq == 2 || freq == 0) {
+		return P2P_JOIN_MULTIPLE_CHANNEL_SCAN_INTERVAL_USECS;
+	} else {
+		return P2P_JOIN_SINGLE_CHANNEL_SCAN_INTERVAL_USECS;
+	}
+}
+
+/*
+ * isAnyEtherAddr - match any ether address
+ *
+ */
+int isAnyEtherAddr(const u8 *a)
+{
+	// 02:00:00:00:00:00
+	return (a[0] == 2) && !(a[1] | a[2] | a[3] | a[4] | a[5]);
+}
+
+/**
+ * findBssBySsid - Fetch a BSS table entry based on SSID and optional BSSID.
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @bssid: BSSID, 02:00:00:00:00:00 matches any bssid
+ * @ssid: SSID
+ * @ssid_len: Length of @ssid
+ * Returns: Pointer to the BSS entry or %NULL if not found
+ */
+struct wpa_bss* findBssBySsid(
+	struct wpa_supplicant *wpa_s, const u8 *bssid,
+	const u8 *ssid, size_t ssid_len)
+{
+	struct wpa_bss *bss;
+	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
+		if ((isAnyEtherAddr(bssid) ||
+			os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0) &&
+			bss->ssid_len == ssid_len &&
+			os_memcmp(bss->ssid, ssid, ssid_len) == 0)
+			return bss;
+	}
+	return NULL;
+}
+
+/**
+ * findBssBySsidFromAnyInterface - Fetch a BSS table entry based on SSID and optional BSSID
+ * by iterating through all the interfaces.
+ * @head: Head of Pointer to wpa_supplicant data
+ * @bssid: BSSID, 02:00:00:00:00:00 matches any bssid
+ * @ssid: SSID
+ * @ssid_len: Length of @ssid
+ * Returns: Pointer to the BSS entry or %NULL if not found
+ */
+struct wpa_bss* findBssBySsidFromAnyInterface(
+	struct wpa_supplicant *head, const u8 *bssid,
+	const u8 *ssid, size_t ssid_len)
+{
+	struct wpa_supplicant *wpa_s;
+	struct wpa_bss *bss = NULL;
+	for (wpa_s = head; wpa_s; wpa_s = wpa_s->next) {
+		bss = findBssBySsid(wpa_s, bssid, ssid, ssid_len);
+		if (bss != NULL) {
+			return bss;
+		}
+	}
+	return bss;
+}
+
+struct wpa_ssid* addGroupClientNetwork(
+	struct wpa_supplicant* wpa_s,
+	uint8_t *group_owner_bssid,
+	const std::vector<uint8_t>& ssid,
+	const std::string& passphrase)
+{
+	struct wpa_ssid* wpa_network = wpa_config_add_network(wpa_s->conf);
+	if (!wpa_network) {
+		return NULL;
+	}
+	// set general network defaults
+	wpa_config_set_network_defaults(wpa_network);
+
+	// set P2p network defaults
+	wpa_network->p2p_group = 1;
+	wpa_network->mode = wpas_mode::WPAS_MODE_INFRA;
+
+	wpa_network->auth_alg = WPA_AUTH_ALG_OPEN;
+	wpa_network->key_mgmt = WPA_KEY_MGMT_PSK;
+	wpa_network->proto = WPA_PROTO_RSN;
+	wpa_network->pairwise_cipher = WPA_CIPHER_CCMP;
+	wpa_network->group_cipher = WPA_CIPHER_CCMP;
+	wpa_network->disabled = 2;
+
+	// set necessary fields
+	os_memcpy(wpa_network->bssid, group_owner_bssid, ETH_ALEN);
+	wpa_network->bssid_set = 1;
+
+	wpa_network->ssid = (uint8_t *)os_malloc(ssid.size());
+	if (wpa_network->ssid == NULL) {
+		wpa_config_remove_network(wpa_s->conf, wpa_network->id);
+		return  NULL;
+	}
+	memcpy(wpa_network->ssid, ssid.data(), ssid.size());
+	wpa_network->ssid_len = ssid.size();
+
+	wpa_network->psk_set = 0;
+	wpa_network->passphrase = dup_binstr(passphrase.c_str(), passphrase.length());
+	if (wpa_network->passphrase == NULL) {
+		wpa_config_remove_network(wpa_s->conf, wpa_network->id);
+		return  NULL;
+	}
+	wpa_config_update_psk(wpa_network);
+
+	return wpa_network;
+
+}
+
+void joinScanWrapper(void *eloop_ctx, void *timeout_ctx)
+{
+	struct wpa_supplicant *wpa_s = (struct wpa_supplicant *) eloop_ctx;
+
+	if (pending_join_scan_callback != NULL) {
+		pending_join_scan_callback();
+	}
+}
+
+void scanResJoinWrapper(
+	struct wpa_supplicant *wpa_s,
+	struct wpa_scan_results *scan_res)
+{
+	if (wpa_s->p2p_scan_work) {
+		struct wpa_radio_work *work = wpa_s->p2p_scan_work;
+		wpa_s->p2p_scan_work = NULL;
+		radio_work_done(work);
+	}
+
+	if (pending_scan_res_join_callback) {
+		pending_scan_res_join_callback();
+	}
+}
+
+int joinScanReq(
+	struct wpa_supplicant* wpa_s,
+	const std::vector<uint8_t>& ssid,
+	int freq, int operating_freq)
+{
+	int ret;
+	struct wpa_driver_scan_params params;
+	struct wpabuf *ies;
+	size_t ielen;
+	unsigned int bands;
+
+	if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) {
+		wpa_printf(MSG_ERROR,
+			"P2P: P2P interface is gone, cancel join scan");
+		return -ENXIO;
+	}
+
+	os_memset(&params, 0, sizeof(params));
+	if (ssid.size() > 0) {
+		params.ssids[0].ssid = ssid.data();
+		params.ssids[0].ssid_len = ssid.size();
+	} else {
+		params.ssids[0].ssid = (u8 *) P2P_WILDCARD_SSID;
+		params.ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN;
+	}
+	wpa_printf(MSG_DEBUG, "Scan SSID %s for join with frequency %d"
+		"BSS operating_freq from scan cache %d",
+		wpa_ssid_txt(params.ssids[0].ssid, params.ssids[0].ssid_len), freq, operating_freq);
+
+	/* Construct an optimized p2p scan channel list */
+	ret = setP2pCliOptimizedScanFreqsList(wpa_s, &params, freq, operating_freq);
+	if (ret < 0) {
+		wpa_printf(MSG_ERROR,
+				   "Failed to set frequency in p2p scan params, error = %d", ret);
+		return -1;
+	}
+
+	ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
+	ies = wpabuf_alloc(ielen);
+	if (ies == NULL) {
+		if (params.freqs) {
+			os_free(params.freqs);
+		}
+		return -1;
+	}
+
+	bands = wpas_get_bands(wpa_s, params.freqs);
+	p2p_scan_ie(wpa_s->global->p2p, ies, NULL, bands);
+
+	params.p2p_probe = 1;
+	params.extra_ies = (u8 *) wpabuf_head(ies);
+	params.extra_ies_len = wpabuf_len(ies);
+	if (wpa_s->clear_driver_scan_cache) {
+		wpa_printf(MSG_DEBUG,
+			"Request driver to clear scan cache due to local BSS flush");
+		params.only_new_results = 1;
+	}
+
+	ret = wpa_drv_scan(wpa_s, &params);
+	if (!ret) {
+		os_get_reltime(&wpa_s->scan_trigger_time);
+		if (wpa_s->scan_res_handler) {
+			wpa_printf(MSG_DEBUG, "Replace current running scan result handler");
+		}
+		wpa_s->p2p_join_scan_count++;
+		wpa_s->scan_res_handler = scanResJoinWrapper;
+		wpa_s->own_scan_requested = 1;
+		wpa_s->clear_driver_scan_cache = 0;
+	}
+
+	if (params.freqs) {
+		os_free(params.freqs);
+	}
+
+	wpabuf_free(ies);
+
+	return ret;
+}
+
+int joinGroup(
+	struct wpa_supplicant* wpa_s,
+	uint8_t *group_owner_bssid,
+	const std::vector<uint8_t>& ssid,
+	const std::string& passphrase)
+{
+	int ret = 0;
+	int he = wpa_s->conf->p2p_go_he;
+	int vht = wpa_s->conf->p2p_go_vht;
+	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
+
+	// Construct a network for adding group.
+	// Group client follows the persistent attribute of Group Owner.
+	// If joined group is persistent, it adds a persistent network on GroupStarted.
+	struct wpa_ssid *wpa_network = addGroupClientNetwork(
+		wpa_s, group_owner_bssid, ssid, passphrase);
+	if (wpa_network == NULL) {
+		wpa_printf(MSG_ERROR, "P2P: Cannot construct a network for group join.");
+		return -1;
+	}
+
+	// this is temporary network only for establishing the connection.
+	wpa_network->temporary = 1;
+
+	if (wpas_p2p_group_add_persistent(
+		wpa_s, wpa_network, 0, 0, 0, 0, ht40, vht,
+		CHANWIDTH_USE_HT, he, 0, NULL, 0, 0)) {
+		ret = -1;
+	}
+
+	// Always remove this temporary network at the end.
+	wpa_config_remove_network(wpa_s->conf, wpa_network->id);
+	return ret;
+}
+
+void notifyGroupJoinFailure(
+	struct wpa_supplicant* wpa_s)
+{
+	u8 zero_addr[ETH_ALEN] = {0};
+	std::vector<uint8_t> ssid = {'D', 'I', 'R', 'E','C', 'T', '-'};
+	std::string passphrase = "";
+	struct wpa_ssid *wpa_network = addGroupClientNetwork(
+		wpa_s, zero_addr, ssid, passphrase);
+	if (wpa_network) {
+		wpa_network->temporary = 1;
+		wpas_notify_p2p_group_formation_failure(wpa_s, "Failed to find the group.");
+		wpas_notify_p2p_group_removed(
+			wpa_s, wpa_network, "client");
+		wpa_config_remove_network(
+			wpa_s->conf, wpa_network->id);
+	} else {
+		wpa_printf(MSG_ERROR,
+			"P2P: Cannot construct a network.");
+	}
+}
+
+void scanResJoinIgnore(struct wpa_supplicant *wpa_s, struct wpa_scan_results *scan_res) {
+	wpa_printf(MSG_DEBUG, "P2P: Ignore group join scan results.");
+
+	if (wpa_s->p2p_scan_work) {
+		struct wpa_radio_work *work = wpa_s->p2p_scan_work;
+		wpa_s->p2p_scan_work = NULL;
+		radio_work_done(work);
+	}
+
+}
+
+static void updateP2pVendorElem(struct wpa_supplicant* wpa_s, enum wpa_vendor_elem_frame frameType,
+	const std::vector<uint8_t>& vendorElemBytes) {
+
+	wpa_printf(MSG_INFO, "Set vendor elements to frames %d", frameType);
+	struct wpa_supplicant* vendor_elem_wpa_s = wpas_vendor_elem(wpa_s, frameType);
+	if (vendor_elem_wpa_s->vendor_elem[frameType]) {
+		wpabuf_free(vendor_elem_wpa_s->vendor_elem[frameType]);
+		vendor_elem_wpa_s->vendor_elem[frameType] = NULL;
+	}
+	if (vendorElemBytes.size() > 0) {
+		vendor_elem_wpa_s->vendor_elem[frameType] =
+			wpabuf_alloc_copy(vendorElemBytes.data(), vendorElemBytes.size());
+	}
+	wpas_vendor_elem_update(vendor_elem_wpa_s);
+}
+
+uint32_t convertWpaP2pFrameTypeToHalP2pFrameTypeBit(int frameType) {
+	switch (frameType) {
+	case VENDOR_ELEM_PROBE_REQ_P2P:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_PROBE_REQ_P2P);
+	case VENDOR_ELEM_PROBE_RESP_P2P:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_PROBE_RESP_P2P);
+	case VENDOR_ELEM_PROBE_RESP_P2P_GO:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_PROBE_RESP_P2P_GO);
+	case VENDOR_ELEM_BEACON_P2P_GO:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_BEACON_P2P_GO);
+	case VENDOR_ELEM_P2P_PD_REQ:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_PD_REQ);
+	case VENDOR_ELEM_P2P_PD_RESP:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_PD_RESP);
+	case VENDOR_ELEM_P2P_GO_NEG_REQ:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_GO_NEG_REQ);
+	case VENDOR_ELEM_P2P_GO_NEG_RESP:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_GO_NEG_RESP);
+	case VENDOR_ELEM_P2P_GO_NEG_CONF:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_GO_NEG_CONF);
+	case VENDOR_ELEM_P2P_INV_REQ:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_INV_REQ);
+	case VENDOR_ELEM_P2P_INV_RESP:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_INV_RESP);
+	case VENDOR_ELEM_P2P_ASSOC_REQ:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_ASSOC_REQ);
+	case VENDOR_ELEM_P2P_ASSOC_RESP:
+		return static_cast<uint32_t>(P2pFrameTypeMask::P2P_FRAME_P2P_ASSOC_RESP);
+	}
+	return 0;
+}
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+using aidl_return_util::validateAndCall;
+using misc_utils::createStatus;
+using misc_utils::createStatusWithMsg;
+
+P2pIface::P2pIface(struct wpa_global* wpa_global, const char ifname[])
+	: wpa_global_(wpa_global), ifname_(ifname), is_valid_(true)
+{}
+
+void P2pIface::invalidate() { is_valid_ = false; }
+bool P2pIface::isValid()
+{
+	return (is_valid_ && (retrieveIfacePtr() != nullptr));
+}
+
+::ndk::ScopedAStatus P2pIface::getName(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::getNameInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pIface::getType(
+	IfaceType* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::getTypeInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pIface::addNetwork(
+	std::shared_ptr<ISupplicantP2pNetwork>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::addNetworkInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pIface::removeNetwork(
+	int32_t in_id)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::removeNetworkInternal, in_id);
+}
+
+::ndk::ScopedAStatus P2pIface::getNetwork(
+	int32_t in_id, std::shared_ptr<ISupplicantP2pNetwork>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::getNetworkInternal, _aidl_return, in_id);
+}
+
+::ndk::ScopedAStatus P2pIface::listNetworks(
+	std::vector<int32_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::listNetworksInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pIface::registerCallback(
+	const std::shared_ptr<ISupplicantP2pIfaceCallback>& in_callback)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::registerCallbackInternal, in_callback);
+}
+
+::ndk::ScopedAStatus P2pIface::getDeviceAddress(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::getDeviceAddressInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pIface::setSsidPostfix(
+	const std::vector<uint8_t>& in_postfix)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setSsidPostfixInternal, in_postfix);
+}
+
+::ndk::ScopedAStatus P2pIface::setGroupIdle(
+	const std::string& in_groupIfName, int32_t in_timeoutInSec)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setGroupIdleInternal, in_groupIfName,
+		in_timeoutInSec);
+}
+
+::ndk::ScopedAStatus P2pIface::setPowerSave(
+	const std::string& in_groupIfName, bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setPowerSaveInternal, in_groupIfName, in_enable);
+}
+
+::ndk::ScopedAStatus P2pIface::find(
+	int32_t in_timeoutInSec)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::findInternal, in_timeoutInSec);
+}
+
+::ndk::ScopedAStatus P2pIface::stopFind()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::stopFindInternal);
+}
+
+::ndk::ScopedAStatus P2pIface::flush()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::flushInternal);
+}
+
+::ndk::ScopedAStatus P2pIface::connect(
+	const std::vector<uint8_t>& in_peerAddress,
+	WpsProvisionMethod in_provisionMethod,
+	const std::string& in_preSelectedPin, bool in_joinExistingGroup,
+	bool in_persistent, int32_t in_goIntent, std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::connectInternal, _aidl_return, in_peerAddress,
+		in_provisionMethod, in_preSelectedPin, in_joinExistingGroup,
+		in_persistent, in_goIntent);
+}
+
+::ndk::ScopedAStatus P2pIface::cancelConnect()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::cancelConnectInternal);
+}
+
+::ndk::ScopedAStatus P2pIface::provisionDiscovery(
+	const std::vector<uint8_t>& in_peerAddress,
+	WpsProvisionMethod in_provisionMethod)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::provisionDiscoveryInternal, in_peerAddress,
+		in_provisionMethod);
+}
+
+ndk::ScopedAStatus P2pIface::addGroup(
+	bool in_persistent, int32_t in_persistentNetworkId)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::addGroupInternal, in_persistent,
+		in_persistentNetworkId);
+}
+
+::ndk::ScopedAStatus P2pIface::addGroupWithConfig(
+	const std::vector<uint8_t>& in_ssid,
+	const std::string& in_pskPassphrase, bool in_persistent,
+	int32_t in_freq, const std::vector<uint8_t>& in_peerAddress,
+	bool in_joinExistingGroup)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::addGroupWithConfigInternal, in_ssid,
+		in_pskPassphrase, in_persistent, in_freq,
+		in_peerAddress, in_joinExistingGroup);
+}
+
+::ndk::ScopedAStatus P2pIface::removeGroup(
+	const std::string& in_groupIfName)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::removeGroupInternal, in_groupIfName);
+}
+
+::ndk::ScopedAStatus P2pIface::reject(
+	const std::vector<uint8_t>& in_peerAddress)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::rejectInternal, in_peerAddress);
+}
+
+::ndk::ScopedAStatus P2pIface::invite(
+	const std::string& in_groupIfName,
+	const std::vector<uint8_t>& in_goDeviceAddress,
+	const std::vector<uint8_t>& in_peerAddress)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::inviteInternal, in_groupIfName,
+		in_goDeviceAddress, in_peerAddress);
+}
+
+::ndk::ScopedAStatus P2pIface::reinvoke(
+	int32_t in_persistentNetworkId,
+	const std::vector<uint8_t>& in_peerAddress)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::reinvokeInternal, in_persistentNetworkId,
+		in_peerAddress);
+}
+
+::ndk::ScopedAStatus P2pIface::configureExtListen(
+	int32_t in_periodInMillis, int32_t in_intervalInMillis)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::configureExtListenInternal, in_periodInMillis,
+		in_intervalInMillis);
+}
+
+::ndk::ScopedAStatus P2pIface::setListenChannel(
+	int32_t in_channel, int32_t in_operatingClass)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setListenChannelInternal, in_channel,
+		in_operatingClass);
+}
+
+::ndk::ScopedAStatus P2pIface::setDisallowedFrequencies(
+	const std::vector<FreqRange>& in_ranges)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setDisallowedFrequenciesInternal, in_ranges);
+}
+
+::ndk::ScopedAStatus P2pIface::getSsid(
+	const std::vector<uint8_t>& in_peerAddress,
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::getSsidInternal, _aidl_return, in_peerAddress);
+}
+
+::ndk::ScopedAStatus P2pIface::getGroupCapability(
+	const std::vector<uint8_t>& in_peerAddress,
+	P2pGroupCapabilityMask* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::getGroupCapabilityInternal, _aidl_return, in_peerAddress);
+}
+
+::ndk::ScopedAStatus P2pIface::addBonjourService(
+	const std::vector<uint8_t>& in_query,
+	const std::vector<uint8_t>& in_response)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::addBonjourServiceInternal, in_query, in_response);
+}
+
+::ndk::ScopedAStatus P2pIface::removeBonjourService(
+	const std::vector<uint8_t>& in_query)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::removeBonjourServiceInternal, in_query);
+}
+
+::ndk::ScopedAStatus P2pIface::addUpnpService(
+	int32_t in_version, const std::string& in_serviceName)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::addUpnpServiceInternal, in_version, in_serviceName);
+}
+
+::ndk::ScopedAStatus P2pIface::removeUpnpService(
+	int32_t in_version, const std::string& in_serviceName)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::removeUpnpServiceInternal, in_version,
+		in_serviceName);
+}
+
+::ndk::ScopedAStatus P2pIface::flushServices()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::flushServicesInternal);
+}
+
+::ndk::ScopedAStatus P2pIface::requestServiceDiscovery(
+	const std::vector<uint8_t>& in_peerAddress,
+	const std::vector<uint8_t>& in_query,
+	int64_t* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::requestServiceDiscoveryInternal, _aidl_return,
+		in_peerAddress, in_query);
+}
+
+::ndk::ScopedAStatus P2pIface::cancelServiceDiscovery(
+	int64_t in_identifier)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::cancelServiceDiscoveryInternal, in_identifier);
+}
+
+::ndk::ScopedAStatus P2pIface::setMiracastMode(
+	MiracastMode in_mode)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setMiracastModeInternal, in_mode);
+}
+
+::ndk::ScopedAStatus P2pIface::startWpsPbc(
+	const std::string& in_groupIfName,
+	const std::vector<uint8_t>& in_bssid)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::startWpsPbcInternal, in_groupIfName, in_bssid);
+}
+
+::ndk::ScopedAStatus P2pIface::startWpsPinKeypad(
+	const std::string& in_groupIfName,
+	const std::string& in_pin)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::startWpsPinKeypadInternal, in_groupIfName, in_pin);
+}
+
+::ndk::ScopedAStatus P2pIface::startWpsPinDisplay(
+	const std::string& in_groupIfName,
+	const std::vector<uint8_t>& in_bssid,
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::startWpsPinDisplayInternal, _aidl_return,
+		in_groupIfName, in_bssid);
+}
+
+::ndk::ScopedAStatus P2pIface::cancelWps(
+	const std::string& in_groupIfName)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::cancelWpsInternal, in_groupIfName);
+}
+
+::ndk::ScopedAStatus P2pIface::setWpsDeviceName(
+	const std::string& in_name)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setWpsDeviceNameInternal, in_name);
+}
+
+::ndk::ScopedAStatus P2pIface::setWpsDeviceType(
+	const std::vector<uint8_t>& in_type)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setWpsDeviceTypeInternal, in_type);
+}
+
+::ndk::ScopedAStatus P2pIface::setWpsManufacturer(
+	const std::string& in_manufacturer)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setWpsManufacturerInternal, in_manufacturer);
+}
+
+::ndk::ScopedAStatus P2pIface::setWpsModelName(
+	const std::string& in_modelName)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setWpsModelNameInternal, in_modelName);
+}
+
+::ndk::ScopedAStatus P2pIface::setWpsModelNumber(
+	const std::string& in_modelNumber)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setWpsModelNumberInternal, in_modelNumber);
+}
+
+::ndk::ScopedAStatus P2pIface::setWpsSerialNumber(
+	const std::string& in_serialNumber)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setWpsSerialNumberInternal, in_serialNumber);
+}
+
+::ndk::ScopedAStatus P2pIface::setWpsConfigMethods(
+	WpsConfigMethods in_configMethods)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setWpsConfigMethodsInternal, in_configMethods);
+}
+
+::ndk::ScopedAStatus P2pIface::enableWfd(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::enableWfdInternal, in_enable);
+}
+
+::ndk::ScopedAStatus P2pIface::setWfdDeviceInfo(
+	const std::vector<uint8_t>& in_info)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setWfdDeviceInfoInternal, in_info);
+}
+
+::ndk::ScopedAStatus P2pIface::createNfcHandoverRequestMessage(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::createNfcHandoverRequestMessageInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pIface::createNfcHandoverSelectMessage(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::createNfcHandoverSelectMessageInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pIface::reportNfcHandoverResponse(
+	const std::vector<uint8_t>& in_request)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::reportNfcHandoverResponseInternal, in_request);
+}
+
+::ndk::ScopedAStatus P2pIface::reportNfcHandoverInitiation(
+	const std::vector<uint8_t>& in_select)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::reportNfcHandoverInitiationInternal, in_select);
+}
+
+::ndk::ScopedAStatus P2pIface::saveConfig()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::saveConfigInternal);
+}
+
+::ndk::ScopedAStatus P2pIface::setMacRandomization(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setMacRandomizationInternal, in_enable);
+}
+
+::ndk::ScopedAStatus P2pIface::setEdmg(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pIface::setEdmgInternal, in_enable);
+}
+
+::ndk::ScopedAStatus P2pIface::getEdmg(
+	bool* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pIface::getEdmgInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pIface::setWfdR2DeviceInfo(
+	const std::vector<uint8_t>& in_info)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setWfdR2DeviceInfoInternal, in_info);
+}
+
+::ndk::ScopedAStatus P2pIface::removeClient(
+        const std::vector<uint8_t>& peer_address, bool isLegacyClient)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::removeClientInternal, peer_address, isLegacyClient);
+}
+
+::ndk::ScopedAStatus P2pIface::findOnSocialChannels(
+	int32_t in_timeoutInSec)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::findOnSocialChannelsInternal, in_timeoutInSec);
+}
+
+::ndk::ScopedAStatus P2pIface::findOnSpecificFrequency(
+	int32_t in_freq,
+	int32_t in_timeoutInSec)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::findOnSpecificFrequencyInternal,
+		in_freq, in_timeoutInSec);
+}
+
+::ndk::ScopedAStatus P2pIface::setVendorElements(
+	P2pFrameTypeMask in_frameTypeMask,
+	const std::vector<uint8_t>& in_vendorElemBytes)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&P2pIface::setVendorElementsInternal, in_frameTypeMask, in_vendorElemBytes);
+}
+
+std::pair<std::string, ndk::ScopedAStatus> P2pIface::getNameInternal()
+{
+	return {ifname_, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<IfaceType, ndk::ScopedAStatus> P2pIface::getTypeInternal()
+{
+	return {IfaceType::P2P, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::shared_ptr<ISupplicantP2pNetwork>, ndk::ScopedAStatus>
+P2pIface::addNetworkInternal()
+{
+	std::shared_ptr<ISupplicantP2pNetwork> network;
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	struct wpa_ssid* ssid = wpa_supplicant_add_network(wpa_s);
+	if (!ssid) {
+		return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	AidlManager* aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager ||
+		aidl_manager->getP2pNetworkAidlObjectByIfnameAndNetworkId(
+		wpa_s->ifname, ssid->id, &network)) {
+		return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {network, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus P2pIface::removeNetworkInternal(int32_t id)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	int result = wpa_supplicant_remove_network(wpa_s, id);
+	if (result == -1) {
+		return createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN);
+	} else if (result != 0) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::shared_ptr<ISupplicantP2pNetwork>, ndk::ScopedAStatus>
+P2pIface::getNetworkInternal(int32_t id)
+{
+	std::shared_ptr<ISupplicantP2pNetwork> network;
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	struct wpa_ssid* ssid = wpa_config_get_network(wpa_s->conf, id);
+	if (!ssid) {
+		return {network, createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN)};
+	}
+	AidlManager* aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager ||
+		aidl_manager->getP2pNetworkAidlObjectByIfnameAndNetworkId(
+		wpa_s->ifname, ssid->id, &network)) {
+		return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {network, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<int32_t>, ndk::ScopedAStatus>
+P2pIface::listNetworksInternal()
+{
+	std::vector<int32_t> network_ids;
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	for (struct wpa_ssid* wpa_ssid = wpa_s->conf->ssid; wpa_ssid;
+		 wpa_ssid = wpa_ssid->next) {
+		network_ids.emplace_back(wpa_ssid->id);
+	}
+	return {std::move(network_ids), ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus P2pIface::registerCallbackInternal(
+	const std::shared_ptr<ISupplicantP2pIfaceCallback>& callback)
+{
+	AidlManager* aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager ||
+		aidl_manager->addP2pIfaceCallbackAidlObject(ifname_, callback)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+P2pIface::getDeviceAddressInternal()
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	std::vector<uint8_t> addr(
+		wpa_s->global->p2p_dev_addr,
+		wpa_s->global->p2p_dev_addr + ETH_ALEN);
+	return {addr, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus P2pIface::setSsidPostfixInternal(
+	const std::vector<uint8_t>& postfix)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (p2p_set_ssid_postfix(
+		wpa_s->global->p2p, postfix.data(), postfix.size())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::setGroupIdleInternal(
+	const std::string& group_ifname, uint32_t timeout_in_sec)
+{
+	struct wpa_supplicant* wpa_group_s =
+		retrieveGroupIfacePtr(group_ifname);
+	if (!wpa_group_s) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
+	}
+	wpa_group_s->conf->p2p_group_idle = timeout_in_sec;
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::setPowerSaveInternal(
+	const std::string& group_ifname, bool enable)
+{
+	struct wpa_supplicant* wpa_group_s =
+		retrieveGroupIfacePtr(group_ifname);
+	if (!wpa_group_s) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
+	}
+	if (wpa_drv_set_p2p_powersave(wpa_group_s, enable, -1, -1)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::findInternal(uint32_t timeout_in_sec)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+	uint32_t search_delay = wpas_p2p_search_delay(wpa_s);
+	if (wpas_p2p_find(
+		wpa_s, timeout_in_sec, P2P_FIND_START_WITH_FULL, 0, nullptr,
+		nullptr, search_delay, 0, nullptr, 0)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::stopFindInternal()
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+	if (wpa_s->scan_res_handler == scanResJoinWrapper) {
+		wpa_printf(MSG_DEBUG, "P2P: Stop pending group scan for stopping find).");
+		pending_scan_res_join_callback = NULL;
+		wpa_s->scan_res_handler = scanResJoinIgnore;
+	}
+	wpas_p2p_stop_find(wpa_s);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::flushInternal()
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
+	wpa_s->force_long_sd = 0;
+	wpas_p2p_stop_find(wpa_s);
+	wpa_s->parent->p2ps_method_config_any = 0;
+	wpa_bss_flush(wpa_s);
+	if (wpa_s->global->p2p)
+		p2p_flush(wpa_s->global->p2p);
+	return ndk::ScopedAStatus::ok();
+}
+
+// This method only implements support for subset (needed by Android framework)
+// of parameters that can be specified for connect.
+std::pair<std::string, ndk::ScopedAStatus> P2pIface::connectInternal(
+	const std::vector<uint8_t>& peer_address,
+	WpsProvisionMethod provision_method,
+	const std::string& pre_selected_pin, bool join_existing_group,
+	bool persistent, uint32_t go_intent)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (go_intent > 15) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID)};
+	}
+	int go_intent_signed = join_existing_group ? -1 : go_intent;
+	p2p_wps_method wps_method = {};
+	switch (provision_method) {
+	case WpsProvisionMethod::PBC:
+		wps_method = WPS_PBC;
+		break;
+	case WpsProvisionMethod::DISPLAY:
+		wps_method = WPS_PIN_DISPLAY;
+		break;
+	case WpsProvisionMethod::KEYPAD:
+		wps_method = WPS_PIN_KEYPAD;
+		break;
+	}
+	int he = wpa_s->conf->p2p_go_he;
+	int vht = wpa_s->conf->p2p_go_vht;
+	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
+	const char* pin =
+		pre_selected_pin.length() > 0 ? pre_selected_pin.data() : nullptr;
+	bool auto_join = !join_existing_group;
+	int new_pin = wpas_p2p_connect(
+		wpa_s, peer_address.data(), pin, wps_method, persistent, auto_join,
+		join_existing_group, false, go_intent_signed, 0, 0, -1, false, ht40,
+		vht, CHANWIDTH_USE_HT, he, 0, nullptr, 0);
+	if (new_pin < 0) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	std::string pin_ret;
+	if (provision_method == WpsProvisionMethod::DISPLAY &&
+		pre_selected_pin.empty()) {
+		pin_ret = misc_utils::convertWpsPinToString(new_pin);
+	}
+	return {pin_ret, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus P2pIface::cancelConnectInternal()
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpa_s->scan_res_handler == scanResJoinWrapper) {
+		wpa_printf(MSG_DEBUG, "P2P: Stop pending group scan for canceling connect");
+		pending_scan_res_join_callback = NULL;
+		wpa_s->scan_res_handler = scanResJoinIgnore;
+	}
+	if (wpas_p2p_cancel(wpa_s)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::provisionDiscoveryInternal(
+	const std::vector<uint8_t>& peer_address,
+	WpsProvisionMethod provision_method)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	p2ps_provision* prov_param;
+	const char* config_method_str = nullptr;
+	switch (provision_method) {
+	case WpsProvisionMethod::PBC:
+		config_method_str = kConfigMethodStrPbc;
+		break;
+	case WpsProvisionMethod::DISPLAY:
+		config_method_str = kConfigMethodStrDisplay;
+		break;
+	case WpsProvisionMethod::KEYPAD:
+		config_method_str = kConfigMethodStrKeypad;
+		break;
+	}
+	if (wpas_p2p_prov_disc(
+		wpa_s, peer_address.data(), config_method_str,
+		WPAS_P2P_PD_FOR_GO_NEG, nullptr)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::removeGroupInternal(const std::string& group_ifname)
+{
+	struct wpa_supplicant* wpa_group_s =
+		retrieveGroupIfacePtr(group_ifname);
+	if (!wpa_group_s) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
+	}
+	wpa_group_s->global->p2p_go_found_external_scan = 0;
+	if (wpas_p2p_group_remove(wpa_group_s, group_ifname.c_str())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::rejectInternal(
+	const std::vector<uint8_t>& peer_address)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+	if (wpas_p2p_reject(wpa_s, peer_address.data())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::inviteInternal(
+	const std::string& group_ifname,
+	const std::vector<uint8_t>& go_device_address,
+	const std::vector<uint8_t>& peer_address)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpas_p2p_invite_group(
+		wpa_s, group_ifname.c_str(), peer_address.data(),
+		go_device_address.data())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::reinvokeInternal(
+	int32_t persistent_network_id,
+	const std::vector<uint8_t>& peer_address)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	int he = wpa_s->conf->p2p_go_he;
+	int vht = wpa_s->conf->p2p_go_vht;
+	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
+	struct wpa_ssid* ssid =
+		wpa_config_get_network(wpa_s->conf, persistent_network_id);
+	if (ssid == NULL || ssid->disabled != 2) {
+		return createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN);
+	}
+	if (wpas_p2p_invite(
+		wpa_s, peer_address.data(), ssid, NULL, 0, 0, ht40, vht,
+		CHANWIDTH_USE_HT, 0, he, 0)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::configureExtListenInternal(
+	uint32_t period_in_millis, uint32_t interval_in_millis)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpas_p2p_ext_listen(wpa_s, period_in_millis, interval_in_millis)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::setListenChannelInternal(
+	uint32_t channel, uint32_t operating_class)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (p2p_set_listen_channel(
+		wpa_s->global->p2p, operating_class, channel, 1)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::setDisallowedFrequenciesInternal(
+	const std::vector<FreqRange>& ranges)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	using DestT = struct wpa_freq_range_list::wpa_freq_range;
+	DestT* freq_ranges = nullptr;
+	// Empty ranges is used to enable all frequencies.
+	if (ranges.size() != 0) {
+		freq_ranges = static_cast<DestT*>(
+			os_malloc(sizeof(DestT) * ranges.size()));
+		if (!freq_ranges) {
+			return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+		}
+		uint32_t i = 0;
+		for (const auto& range : ranges) {
+			freq_ranges[i].min = range.min;
+			freq_ranges[i].max = range.max;
+			i++;
+		}
+	}
+
+	os_free(wpa_s->global->p2p_disallow_freq.range);
+	wpa_s->global->p2p_disallow_freq.range = freq_ranges;
+	wpa_s->global->p2p_disallow_freq.num = ranges.size();
+	wpas_p2p_update_channel_list(wpa_s, WPAS_P2P_CHANNEL_UPDATE_DISALLOW);
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> P2pIface::getSsidInternal(
+	const std::vector<uint8_t>& peer_address)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	const struct p2p_peer_info* info =
+		p2p_get_peer_info(wpa_s->global->p2p, peer_address.data(), 0);
+	if (!info) {
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	const struct p2p_device* dev =
+		reinterpret_cast<const struct p2p_device*>(
+		(reinterpret_cast<const uint8_t*>(info)) -
+		offsetof(struct p2p_device, info));
+	std::vector<uint8_t> ssid;
+	if (dev && dev->oper_ssid_len) {
+		ssid.assign(
+			dev->oper_ssid, dev->oper_ssid + dev->oper_ssid_len);
+	}
+	return {ssid, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<P2pGroupCapabilityMask, ndk::ScopedAStatus> P2pIface::getGroupCapabilityInternal(
+	const std::vector<uint8_t>& peer_address)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	const struct p2p_peer_info* info =
+		p2p_get_peer_info(wpa_s->global->p2p, peer_address.data(), 0);
+	if (!info) {
+		return {static_cast<P2pGroupCapabilityMask>(0),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {static_cast<P2pGroupCapabilityMask>(info->group_capab),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus P2pIface::addBonjourServiceInternal(
+	const std::vector<uint8_t>& query, const std::vector<uint8_t>& response)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	auto query_buf = misc_utils::convertVectorToWpaBuf(query);
+	auto response_buf = misc_utils::convertVectorToWpaBuf(response);
+	if (!query_buf || !response_buf) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	if (wpas_p2p_service_add_bonjour(
+		wpa_s, query_buf.get(), response_buf.get())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	// If successful, the wpabuf is referenced internally and hence should
+	// not be freed.
+	query_buf.release();
+	response_buf.release();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::removeBonjourServiceInternal(
+	const std::vector<uint8_t>& query)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	auto query_buf = misc_utils::convertVectorToWpaBuf(query);
+	if (!query_buf) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	if (wpas_p2p_service_del_bonjour(wpa_s, query_buf.get())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::addUpnpServiceInternal(
+	uint32_t version, const std::string& service_name)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpas_p2p_service_add_upnp(wpa_s, version, service_name.c_str())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::removeUpnpServiceInternal(
+	uint32_t version, const std::string& service_name)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpas_p2p_service_del_upnp(wpa_s, version, service_name.c_str())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::flushServicesInternal()
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	wpas_p2p_service_flush(wpa_s);
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<uint64_t, ndk::ScopedAStatus> P2pIface::requestServiceDiscoveryInternal(
+	const std::vector<uint8_t>& peer_address,
+	const std::vector<uint8_t>& query)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	auto query_buf = misc_utils::convertVectorToWpaBuf(query);
+	if (!query_buf) {
+		return {0, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	const uint8_t* dst_addr = is_zero_ether_addr(peer_address.data())
+					  ? nullptr
+					  : peer_address.data();
+	uint64_t identifier =
+		wpas_p2p_sd_request(wpa_s, dst_addr, query_buf.get());
+	if (identifier == 0) {
+		return {0, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {identifier, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus P2pIface::cancelServiceDiscoveryInternal(uint64_t identifier)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpas_p2p_sd_cancel_request(wpa_s, identifier)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::setMiracastModeInternal(
+	MiracastMode mode)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	uint8_t mode_internal = convertAidlMiracastModeToInternal(mode);
+	const std::string cmd_str =
+		kSetMiracastMode + std::to_string(mode_internal);
+	std::vector<char> cmd(
+		cmd_str.c_str(), cmd_str.c_str() + cmd_str.size() + 1);
+	char driver_cmd_reply_buf[4096] = {};
+	if (wpa_drv_driver_cmd(
+		wpa_s, cmd.data(), driver_cmd_reply_buf,
+		sizeof(driver_cmd_reply_buf))) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::startWpsPbcInternal(
+	const std::string& group_ifname, const std::vector<uint8_t>& bssid)
+{
+	struct wpa_supplicant* wpa_group_s =
+		retrieveGroupIfacePtr(group_ifname);
+	if (!wpa_group_s) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
+	}
+	const uint8_t* bssid_addr =
+		is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
+#ifdef CONFIG_AP
+	if (wpa_group_s->ap_iface) {
+		if (wpa_supplicant_ap_wps_pbc(wpa_group_s, bssid_addr, NULL)) {
+			return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+		}
+		return ndk::ScopedAStatus::ok();
+	}
+#endif /* CONFIG_AP */
+	if (wpas_wps_start_pbc(wpa_group_s, bssid_addr, 0, 0)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::startWpsPinKeypadInternal(
+	const std::string& group_ifname, const std::string& pin)
+{
+	struct wpa_supplicant* wpa_group_s =
+		retrieveGroupIfacePtr(group_ifname);
+	if (!wpa_group_s) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
+	}
+#ifdef CONFIG_AP
+	if (wpa_group_s->ap_iface) {
+		if (wpa_supplicant_ap_wps_pin(
+			wpa_group_s, nullptr, pin.c_str(), nullptr, 0, 0) < 0) {
+			return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+		}
+		return ndk::ScopedAStatus::ok();
+	}
+#endif /* CONFIG_AP */
+	if (wpas_wps_start_pin(
+		wpa_group_s, nullptr, pin.c_str(), 0, DEV_PW_DEFAULT)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::string, ndk::ScopedAStatus> P2pIface::startWpsPinDisplayInternal(
+	const std::string& group_ifname, const std::vector<uint8_t>& bssid)
+{
+	struct wpa_supplicant* wpa_group_s =
+		retrieveGroupIfacePtr(group_ifname);
+	if (!wpa_group_s) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN)};
+	}
+	const uint8_t* bssid_addr =
+		is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
+	int pin = wpas_wps_start_pin(
+		wpa_group_s, bssid_addr, nullptr, 0, DEV_PW_DEFAULT);
+	if (pin < 0) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::convertWpsPinToString(pin), ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus P2pIface::cancelWpsInternal(const std::string& group_ifname)
+{
+	struct wpa_supplicant* wpa_group_s =
+		retrieveGroupIfacePtr(group_ifname);
+	if (!wpa_group_s) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
+	}
+	if (wpas_wps_cancel(wpa_group_s)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::setWpsDeviceNameInternal(const std::string& name)
+{
+	return iface_config_utils::setWpsDeviceName(retrieveIfacePtr(), name);
+}
+
+ndk::ScopedAStatus P2pIface::setWpsDeviceTypeInternal(
+	const std::vector<uint8_t>& type)
+{
+	std::array<uint8_t, 8> type_arr;
+	std::copy_n(type.begin(), 8, type_arr.begin());
+	return iface_config_utils::setWpsDeviceType(retrieveIfacePtr(), type_arr);
+}
+
+ndk::ScopedAStatus P2pIface::setWpsManufacturerInternal(
+	const std::string& manufacturer)
+{
+	return iface_config_utils::setWpsManufacturer(
+		retrieveIfacePtr(), manufacturer);
+}
+
+ndk::ScopedAStatus P2pIface::setWpsModelNameInternal(
+	const std::string& model_name)
+{
+	return iface_config_utils::setWpsModelName(
+		retrieveIfacePtr(), model_name);
+}
+
+ndk::ScopedAStatus P2pIface::setWpsModelNumberInternal(
+	const std::string& model_number)
+{
+	return iface_config_utils::setWpsModelNumber(
+		retrieveIfacePtr(), model_number);
+}
+
+ndk::ScopedAStatus P2pIface::setWpsSerialNumberInternal(
+	const std::string& serial_number)
+{
+	return iface_config_utils::setWpsSerialNumber(
+		retrieveIfacePtr(), serial_number);
+}
+
+ndk::ScopedAStatus P2pIface::setWpsConfigMethodsInternal(WpsConfigMethods config_methods)
+{
+
+	return iface_config_utils::setWpsConfigMethods(
+		retrieveIfacePtr(), static_cast<uint16_t>(config_methods));
+}
+
+ndk::ScopedAStatus P2pIface::enableWfdInternal(bool enable)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	wifi_display_enable(wpa_s->global, enable);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::setWfdDeviceInfoInternal(
+	const std::vector<uint8_t>& info)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	std::vector<char> wfd_device_info_hex(info.size() * 2 + 1);
+	wpa_snprintf_hex(
+		wfd_device_info_hex.data(), wfd_device_info_hex.size(), info.data(),
+		info.size());
+	// |wifi_display_subelem_set| expects the first 2 bytes
+	// to hold the lenght of the subelement. In this case it's
+	// fixed to 6, so prepend that.
+	std::string wfd_device_info_set_cmd_str =
+		std::to_string(kWfdDeviceInfoSubelemId) + " " +
+		kWfdDeviceInfoSubelemLenHexStr + wfd_device_info_hex.data();
+	std::vector<char> wfd_device_info_set_cmd(
+		wfd_device_info_set_cmd_str.c_str(),
+		wfd_device_info_set_cmd_str.c_str() +
+		wfd_device_info_set_cmd_str.size() + 1);
+	if (wifi_display_subelem_set(
+		wpa_s->global, wfd_device_info_set_cmd.data())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+P2pIface::createNfcHandoverRequestMessageInternal()
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	auto buf = misc_utils::createWpaBufUniquePtr(
+		wpas_p2p_nfc_handover_req(wpa_s, 1));
+	if (!buf) {
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::convertWpaBufToVector(buf.get()),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+P2pIface::createNfcHandoverSelectMessageInternal()
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	auto buf = misc_utils::createWpaBufUniquePtr(
+		wpas_p2p_nfc_handover_sel(wpa_s, 1, 0));
+	if (!buf) {
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::convertWpaBufToVector(buf.get()),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus P2pIface::reportNfcHandoverResponseInternal(
+	const std::vector<uint8_t>& request)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	auto req = misc_utils::convertVectorToWpaBuf(request);
+	auto sel = misc_utils::convertVectorToWpaBuf(std::vector<uint8_t>{0});
+	if (!req || !sel) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	if (wpas_p2p_nfc_report_handover(wpa_s, 0, req.get(), sel.get(), 0)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::reportNfcHandoverInitiationInternal(
+	const std::vector<uint8_t>& select)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	auto req = misc_utils::convertVectorToWpaBuf(std::vector<uint8_t>{0});
+	auto sel = misc_utils::convertVectorToWpaBuf(select);
+	if (!req || !sel) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	if (wpas_p2p_nfc_report_handover(wpa_s, 1, req.get(), sel.get(), 0)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::saveConfigInternal()
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (!wpa_s->conf->update_config) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	if (wpa_config_write(wpa_s->confname, wpa_s->conf)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::addGroupInternal(
+	bool persistent, int32_t persistent_network_id)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	int he = wpa_s->conf->p2p_go_he;
+	int vht = wpa_s->conf->p2p_go_vht;
+	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
+	struct wpa_ssid* ssid =
+		wpa_config_get_network(wpa_s->conf, persistent_network_id);
+	if (ssid == NULL) {
+		if (wpas_p2p_group_add(
+			wpa_s, persistent, 0, 0, ht40, vht,
+			CHANWIDTH_USE_HT, he, 0)) {
+			return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+		} else {
+			return ndk::ScopedAStatus::ok();
+		}
+	} else if (ssid->disabled == 2) {
+		if (wpas_p2p_group_add_persistent(
+			wpa_s, ssid, 0, 0, 0, 0, ht40, vht,
+			CHANWIDTH_USE_HT, he, 0, NULL, 0, 0)) {
+			return createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN);
+		} else {
+			return ndk::ScopedAStatus::ok();
+		}
+	}
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+}
+
+ndk::ScopedAStatus P2pIface::addGroupWithConfigInternal(
+	const std::vector<uint8_t>& ssid, const std::string& passphrase,
+	bool persistent, uint32_t freq, const std::vector<uint8_t>& peer_address,
+	bool joinExistingGroup)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	int he = wpa_s->conf->p2p_go_he;
+	int vht = wpa_s->conf->p2p_go_vht;
+	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
+
+	if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+
+	if (!isSsidValid(ssid)) {
+		return createStatusWithMsg(SupplicantStatusCode::FAILURE_ARGS_INVALID,
+			"SSID is invalid.");
+	}
+
+	if (!isPskPassphraseValid(passphrase)) {
+		return createStatusWithMsg(SupplicantStatusCode::FAILURE_ARGS_INVALID,
+			"Passphrase is invalid.");
+	}
+
+	if (!joinExistingGroup) {
+		struct p2p_data *p2p = wpa_s->global->p2p;
+		os_memcpy(p2p->ssid, ssid.data(), ssid.size());
+		p2p->ssid_len = ssid.size();
+		p2p->ssid_set = 1;
+
+		os_memset(p2p->passphrase, 0, sizeof(p2p->passphrase));
+		os_memcpy(p2p->passphrase, passphrase.c_str(), passphrase.length());
+		p2p->passphrase_set = 1;
+
+		if (wpas_p2p_group_add(
+			wpa_s, persistent, freq, 0, ht40, vht,
+			CHANWIDTH_USE_HT, he, 0)) {
+			return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+		}
+		return ndk::ScopedAStatus::ok();
+	}
+
+	// The rest is for group join.
+	wpa_printf(MSG_DEBUG, "P2P: Stop any on-going P2P FIND before group join.");
+	wpas_p2p_stop_find(wpa_s);
+
+	if (pending_scan_res_join_callback != NULL) {
+		wpa_printf(MSG_WARNING, "P2P: Renew scan result callback with new request.");
+	}
+
+	pending_join_scan_callback =
+		[wpa_s, ssid, peer_address, freq]() {
+		if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) {
+			return;
+		}
+		int operating_freq = 0;
+		struct wpa_bss *bss = findBssBySsidFromAnyInterface(
+			wpa_s->global->ifaces, peer_address.data(), ssid.data(), ssid.size());
+		if (bss != NULL) {
+			wpa_printf(MSG_DEBUG, "P2P: Found Group owner " MACSTR "in scan cache",
+				MAC2STR(bss->bssid));
+			operating_freq = bss->freq;
+		}
+
+		int ret = joinScanReq(wpa_s, ssid, freq, operating_freq);
+		// for BUSY case, the scan might be occupied by WiFi.
+		// Do not give up immediately, but try again later.
+		if (-EBUSY == ret) {
+			// re-schedule this join scan
+			eloop_cancel_timeout(joinScanWrapper, wpa_s, NULL);
+			eloop_register_timeout(0, P2P_JOIN_SINGLE_CHANNEL_SCAN_INTERVAL_USECS,
+					joinScanWrapper, wpa_s, NULL);
+		} else if (0 != ret) {
+			notifyGroupJoinFailure(wpa_s);
+			pending_scan_res_join_callback = NULL;
+		}
+	};
+
+	pending_scan_res_join_callback = [wpa_s, ssid, passphrase, peer_address, freq, this]() {
+		if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) {
+			return;
+		}
+
+		wpa_printf(MSG_DEBUG, "P2P: Scan results received for join (reinvoke).");
+
+		struct wpa_bss *bss = findBssBySsid(
+			wpa_s, peer_address.data(), ssid.data(), ssid.size());
+		if (bss) {
+			wpa_s->global->p2p_go_found_external_scan = 1;
+			if (0 != joinGroup(wpa_s, bss->bssid, ssid, passphrase)) {
+				wpa_printf(MSG_ERROR, "P2P: Failed to join a group.");
+				wpa_s->global->p2p_go_found_external_scan = 0;
+			}
+			// no need to notify group join failure here,
+			// it will be handled by wpas_p2p_group_add_persistent
+			// called in joinGroup.
+			pending_scan_res_join_callback = NULL;
+			return;
+		}
+		wpa_printf(MSG_DEBUG, "P2P: Join scan count %d.", wpa_s->p2p_join_scan_count);
+		eloop_cancel_timeout(joinScanWrapper, wpa_s, NULL);
+		if (wpa_s->p2p_join_scan_count < P2P_MAX_JOIN_SCAN_ATTEMPTS) {
+			wpa_printf(MSG_DEBUG, "P2P: Try join again later.");
+			eloop_register_timeout(0, getP2pJoinScanIntervalUsecs(freq),
+				joinScanWrapper, wpa_s, this);
+			return;
+		}
+
+		wpa_printf(MSG_ERROR, "P2P: Failed to find the group with "
+			"network name %s - stop join attempt",
+			wpa_ssid_txt(ssid.data(), ssid.size()));
+		notifyGroupJoinFailure(wpa_s);
+		pending_scan_res_join_callback = NULL;
+	};
+
+	wpa_s->p2p_join_scan_count = 0;
+	pending_join_scan_callback();
+	if (pending_scan_res_join_callback == NULL) {
+		return createStatusWithMsg(SupplicantStatusCode::FAILURE_UNKNOWN,
+			"Failed to start scan.");
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::setMacRandomizationInternal(bool enable)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	bool currentEnabledState = !!wpa_s->conf->p2p_device_random_mac_addr;
+	u8 *addr = NULL;
+
+	// The same state, no change is needed.
+	if (currentEnabledState == enable) {
+		wpa_printf(MSG_DEBUG, "The random MAC is %s already.",
+			(enable) ? "enabled" : "disabled");
+		return ndk::ScopedAStatus::ok();
+	}
+
+	if (enable) {
+		wpa_s->conf->p2p_device_random_mac_addr = 1;
+		wpa_s->conf->p2p_interface_random_mac_addr = 1;
+
+		// restore config if it failed to set up MAC address.
+		if (wpas_p2p_mac_setup(wpa_s) < 0) {
+			wpa_s->conf->p2p_device_random_mac_addr = 0;
+			wpa_s->conf->p2p_interface_random_mac_addr = 0;
+			return createStatusWithMsg(SupplicantStatusCode::FAILURE_UNKNOWN,
+				"Failed to set up MAC address.");
+		}
+	} else {
+		// disable random MAC will use original MAC address
+		// regardless of any saved persistent groups.
+		if (wpa_drv_set_mac_addr(wpa_s, NULL) < 0) {
+			wpa_printf(MSG_ERROR, "Failed to restore MAC address");
+			return createStatusWithMsg(SupplicantStatusCode::FAILURE_UNKNOWN,
+				"Failed to restore MAC address.");
+		}
+
+		if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
+			wpa_printf(MSG_INFO, "Could not update MAC address information");
+			return createStatusWithMsg(SupplicantStatusCode::FAILURE_UNKNOWN,
+				"Failed to update MAC address.");
+		}
+		wpa_s->conf->p2p_device_random_mac_addr = 0;
+		wpa_s->conf->p2p_interface_random_mac_addr = 0;
+	}
+
+	// update internal data to send out correct device address in action frame.
+	os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN);
+	os_memcpy(wpa_s->global->p2p->cfg->dev_addr, wpa_s->global->p2p_dev_addr, ETH_ALEN);
+
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::setEdmgInternal(bool enable)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	wpa_printf(MSG_DEBUG, "set p2p_go_edmg to %d", enable);
+	wpa_s->conf->p2p_go_edmg = enable ? 1 : 0;
+	wpa_s->p2p_go_edmg = enable ? 1 : 0;
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<bool, ndk::ScopedAStatus> P2pIface::getEdmgInternal()
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	return {(wpa_s->p2p_go_edmg == 1), ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus P2pIface::setWfdR2DeviceInfoInternal(
+	const std::vector<uint8_t>& info)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	uint32_t wfd_r2_device_info_hex_len = info.size() * 2 + 1;
+	std::vector<char> wfd_r2_device_info_hex(wfd_r2_device_info_hex_len);
+	wpa_snprintf_hex(
+		wfd_r2_device_info_hex.data(), wfd_r2_device_info_hex.size(),
+		info.data(),info.size());
+	std::string wfd_r2_device_info_set_cmd_str =
+		 std::to_string(kWfdR2DeviceInfoSubelemId) + " " +
+		 wfd_r2_device_info_hex.data();
+	std::vector<char> wfd_r2_device_info_set_cmd(
+		 wfd_r2_device_info_set_cmd_str.c_str(),
+		 wfd_r2_device_info_set_cmd_str.c_str() +
+		 wfd_r2_device_info_set_cmd_str.size() + 1);
+	if (wifi_display_subelem_set(
+		wpa_s->global, wfd_r2_device_info_set_cmd.data())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::removeClientInternal(
+    const std::vector<uint8_t>& peer_address, bool isLegacyClient)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	wpas_p2p_remove_client(wpa_s, peer_address.data(), isLegacyClient? 1 : 0);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::findOnSocialChannelsInternal(uint32_t timeout_in_sec)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+	uint32_t search_delay = wpas_p2p_search_delay(wpa_s);
+	if (wpas_p2p_find(
+		wpa_s, timeout_in_sec, P2P_FIND_ONLY_SOCIAL, 0, nullptr,
+		nullptr, search_delay, 0, nullptr, 0)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::findOnSpecificFrequencyInternal(
+	uint32_t freq, uint32_t timeout_in_sec)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+	uint32_t search_delay = wpas_p2p_search_delay(wpa_s);
+	if (wpas_p2p_find(
+		wpa_s, timeout_in_sec, P2P_FIND_START_WITH_FULL, 0, nullptr,
+		nullptr, search_delay, 0, nullptr, freq)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus P2pIface::setVendorElementsInternal(
+	P2pFrameTypeMask frameTypeMask,
+	const std::vector<uint8_t>& vendorElemBytes)
+{
+	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
+	for (int i = 0; i < NUM_VENDOR_ELEM_FRAMES; i++) {
+		uint32_t bit = convertWpaP2pFrameTypeToHalP2pFrameTypeBit(i);
+		if (0 == bit) continue;
+
+		if (static_cast<uint32_t>(frameTypeMask) & bit) {
+			updateP2pVendorElem(wpa_s, (enum wpa_vendor_elem_frame) i, vendorElemBytes);
+		}
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+/**
+ * Retrieve the underlying |wpa_supplicant| struct
+ * pointer for this iface.
+ * If the underlying iface is removed, then all RPC method calls on this object
+ * will return failure.
+ */
+wpa_supplicant* P2pIface::retrieveIfacePtr()
+{
+	return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
+}
+
+/**
+ * Retrieve the underlying |wpa_supplicant| struct
+ * pointer for this group iface.
+ */
+wpa_supplicant* P2pIface::retrieveGroupIfacePtr(const std::string& group_ifname)
+{
+	return wpa_supplicant_get_iface(wpa_global_, group_ifname.c_str());
+}
+
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wpa_supplicant/aidl/p2p_iface.h b/wpa_supplicant/aidl/p2p_iface.h
new file mode 100644
index 0000000..5f9903c
--- /dev/null
+++ b/wpa_supplicant/aidl/p2p_iface.h
@@ -0,0 +1,316 @@
+/*
+ * WPA Supplicant - P2P Iface Aidl interface
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef WPA_SUPPLICANT_AIDL_P2P_IFACE_H
+#define WPA_SUPPLICANT_AIDL_P2P_IFACE_H
+
+#include <array>
+#include <vector>
+
+#include <android-base/macros.h>
+
+#include <aidl/android/hardware/wifi/supplicant/BnSupplicantP2pIface.h>
+#include <aidl/android/hardware/wifi/supplicant/FreqRange.h>
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantP2pIfaceCallback.h>
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantP2pNetwork.h>
+#include <aidl/android/hardware/wifi/supplicant/MiracastMode.h>
+#include <aidl/android/hardware/wifi/supplicant/WpsProvisionMethod.h>
+
+extern "C"
+{
+#include "utils/common.h"
+#include "utils/includes.h"
+#include "p2p/p2p.h"
+#include "p2p/p2p_i.h"
+#include "p2p_supplicant.h"
+#include "p2p_supplicant.h"
+#include "config.h"
+}
+
+#define P2P_MGMT_DEVICE_PREFIX	   "p2p-dev-"
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+
+/**
+ * Implementation of P2pIface aidl object. Each unique aidl
+ * object is used for control operations on a specific interface
+ * controlled by wpa_supplicant.
+ */
+class P2pIface : public BnSupplicantP2pIface
+{
+public:
+	P2pIface(struct wpa_global* wpa_global, const char ifname[]);
+	~P2pIface() override = default;
+	// Refer to |StaIface::invalidate()|.
+	void invalidate();
+	bool isValid();
+
+	// Aidl methods exposed.
+	::ndk::ScopedAStatus getName(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getType(IfaceType* _aidl_return) override;
+	::ndk::ScopedAStatus addNetwork(
+		std::shared_ptr<ISupplicantP2pNetwork>* _aidl_return) override;
+	::ndk::ScopedAStatus removeNetwork(int32_t in_id) override;
+	::ndk::ScopedAStatus getNetwork(
+		int32_t in_id, std::shared_ptr<ISupplicantP2pNetwork>* _aidl_return) override;
+	::ndk::ScopedAStatus listNetworks(std::vector<int32_t>* _aidl_return) override;
+	::ndk::ScopedAStatus registerCallback(
+		const std::shared_ptr<ISupplicantP2pIfaceCallback>& in_callback) override;
+	::ndk::ScopedAStatus getDeviceAddress(std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus setSsidPostfix(const std::vector<uint8_t>& in_postfix) override;
+	::ndk::ScopedAStatus setGroupIdle(
+		const std::string& in_groupIfName, int32_t in_timeoutInSec) override;
+	::ndk::ScopedAStatus setPowerSave(
+		const std::string& in_groupIfName, bool in_enable) override;
+	::ndk::ScopedAStatus find(int32_t in_timeoutInSec) override;
+	::ndk::ScopedAStatus stopFind() override;
+	::ndk::ScopedAStatus flush() override;
+	::ndk::ScopedAStatus connect(
+		const std::vector<uint8_t>& in_peerAddress, WpsProvisionMethod in_provisionMethod,
+		const std::string& in_preSelectedPin, bool in_joinExistingGroup,
+		bool in_persistent, int32_t in_goIntent, std::string* _aidl_return) override;
+	::ndk::ScopedAStatus cancelConnect() override;
+	::ndk::ScopedAStatus provisionDiscovery(
+		const std::vector<uint8_t>& in_peerAddress,
+		WpsProvisionMethod in_provisionMethod) override;
+	::ndk::ScopedAStatus addGroup(bool in_persistent, int32_t in_persistentNetworkId) override;
+	::ndk::ScopedAStatus addGroupWithConfig(
+		const std::vector<uint8_t>& in_ssid, const std::string& in_pskPassphrase,
+		bool in_persistent, int32_t in_freq, const std::vector<uint8_t>& in_peerAddress,
+		bool in_joinExistingGroup) override;
+	::ndk::ScopedAStatus removeGroup(const std::string& in_groupIfName) override;
+	::ndk::ScopedAStatus reject(const std::vector<uint8_t>& in_peerAddress) override;
+	::ndk::ScopedAStatus invite(
+		const std::string& in_groupIfName,
+		const std::vector<uint8_t>& in_goDeviceAddress,
+		const std::vector<uint8_t>& in_peerAddress) override;
+	::ndk::ScopedAStatus reinvoke(
+		int32_t in_persistentNetworkId,
+		const std::vector<uint8_t>& in_peerAddress) override;
+	::ndk::ScopedAStatus configureExtListen(
+		int32_t in_periodInMillis, int32_t in_intervalInMillis) override;
+	::ndk::ScopedAStatus setListenChannel(
+		int32_t in_channel, int32_t in_operatingClass) override;
+	::ndk::ScopedAStatus setDisallowedFrequencies(
+		const std::vector<FreqRange>& in_ranges) override;
+	::ndk::ScopedAStatus getSsid(
+		const std::vector<uint8_t>& in_peerAddress,
+		std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus getGroupCapability(
+		const std::vector<uint8_t>& in_peerAddress,
+		P2pGroupCapabilityMask* _aidl_return) override;
+	::ndk::ScopedAStatus addBonjourService(
+		const std::vector<uint8_t>& in_query,
+		const std::vector<uint8_t>& in_response) override;
+	::ndk::ScopedAStatus removeBonjourService(
+		const std::vector<uint8_t>& in_query) override;
+	::ndk::ScopedAStatus addUpnpService(
+		int32_t in_version, const std::string& in_serviceName) override;
+	::ndk::ScopedAStatus removeUpnpService(
+		int32_t in_version, const std::string& in_serviceName) override;
+	::ndk::ScopedAStatus flushServices() override;
+	::ndk::ScopedAStatus requestServiceDiscovery(
+		const std::vector<uint8_t>& in_peerAddress,
+		const std::vector<uint8_t>& in_query, int64_t* _aidl_return) override;
+	::ndk::ScopedAStatus cancelServiceDiscovery(int64_t in_identifier) override;
+	::ndk::ScopedAStatus setMiracastMode(MiracastMode in_mode) override;
+	::ndk::ScopedAStatus startWpsPbc(
+		const std::string& in_groupIfName,
+		const std::vector<uint8_t>& in_bssid) override;
+	::ndk::ScopedAStatus startWpsPinKeypad(
+		const std::string& in_groupIfName, const std::string& in_pin) override;
+	::ndk::ScopedAStatus startWpsPinDisplay(
+		const std::string& in_groupIfName,
+		const std::vector<uint8_t>& in_bssid,
+		std::string* _aidl_return) override;
+	::ndk::ScopedAStatus cancelWps(const std::string& in_groupIfName) override;
+	::ndk::ScopedAStatus setWpsDeviceName(
+		const std::string& in_name) override;
+	::ndk::ScopedAStatus setWpsDeviceType(
+		const std::vector<uint8_t>& in_type) override;
+	::ndk::ScopedAStatus setWpsManufacturer(
+		const std::string& in_manufacturer) override;
+	::ndk::ScopedAStatus setWpsModelName(
+		const std::string& in_modelName) override;
+	::ndk::ScopedAStatus setWpsModelNumber(
+		const std::string& in_modelNumber) override;
+	::ndk::ScopedAStatus setWpsSerialNumber(
+		const std::string& in_serialNumber) override;
+	::ndk::ScopedAStatus setWpsConfigMethods(
+		WpsConfigMethods in_configMethods) override;
+	::ndk::ScopedAStatus enableWfd(bool in_enable) override;
+	::ndk::ScopedAStatus setWfdDeviceInfo(
+		const std::vector<uint8_t>& in_info) override;
+	::ndk::ScopedAStatus createNfcHandoverRequestMessage(
+		std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus createNfcHandoverSelectMessage(
+		std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus reportNfcHandoverInitiation(
+		const std::vector<uint8_t>& in_select) override;
+	::ndk::ScopedAStatus reportNfcHandoverResponse(
+		const std::vector<uint8_t>& in_request) override;
+	::ndk::ScopedAStatus saveConfig() override;
+	::ndk::ScopedAStatus setMacRandomization(bool in_enable) override;
+	::ndk::ScopedAStatus setEdmg(bool in_enable) override;
+	::ndk::ScopedAStatus getEdmg(bool* _aidl_return) override;
+	::ndk::ScopedAStatus setWfdR2DeviceInfo(
+		const std::vector<uint8_t>& in_info) override;
+	::ndk::ScopedAStatus removeClient(
+		const std::vector<uint8_t>& peer_address, bool isLegacyClient) override;
+	::ndk::ScopedAStatus findOnSocialChannels(int32_t in_timeoutInSec) override;
+	::ndk::ScopedAStatus findOnSpecificFrequency(
+		int32_t in_freq, int32_t in_timeoutInSec) override;
+	::ndk::ScopedAStatus setVendorElements(
+		P2pFrameTypeMask in_frameTypeMask,
+		const std::vector<uint8_t>& in_vendorElemBytes) override;
+
+private:
+	// Corresponding worker functions for the AIDL methods.
+	std::pair<std::string, ndk::ScopedAStatus> getNameInternal();
+	std::pair<IfaceType, ndk::ScopedAStatus> getTypeInternal();
+	std::pair<std::shared_ptr<ISupplicantP2pNetwork>, ndk::ScopedAStatus>
+		addNetworkInternal();
+	ndk::ScopedAStatus removeNetworkInternal(int32_t id);
+	std::pair<std::shared_ptr<ISupplicantP2pNetwork>, ndk::ScopedAStatus>
+		getNetworkInternal(int32_t id);
+	std::pair<std::vector<int32_t>, ndk::ScopedAStatus>
+		listNetworksInternal();
+	ndk::ScopedAStatus registerCallbackInternal(
+		const std::shared_ptr<ISupplicantP2pIfaceCallback>& callback);
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+		getDeviceAddressInternal();
+	ndk::ScopedAStatus setSsidPostfixInternal(
+		const std::vector<uint8_t>& postfix);
+	ndk::ScopedAStatus setGroupIdleInternal(
+		const std::string& group_ifname, uint32_t timeout_in_sec);
+	ndk::ScopedAStatus setPowerSaveInternal(
+		const std::string& group_ifname, bool enable);
+	ndk::ScopedAStatus findInternal(uint32_t timeout_in_sec);
+	ndk::ScopedAStatus stopFindInternal();
+	ndk::ScopedAStatus flushInternal();
+	std::pair<std::string, ndk::ScopedAStatus> connectInternal(
+		const std::vector<uint8_t>& peer_address,
+		WpsProvisionMethod provision_method,
+		const std::string& pre_selected_pin, bool join_existing_group,
+		bool persistent, uint32_t go_intent);
+	ndk::ScopedAStatus cancelConnectInternal();
+	ndk::ScopedAStatus provisionDiscoveryInternal(
+		const std::vector<uint8_t>& peer_address,
+		WpsProvisionMethod provision_method);
+	ndk::ScopedAStatus addGroupInternal(bool in_persistent, int32_t in_persistentNetworkId);
+	ndk::ScopedAStatus addGroupWithConfigInternal(
+		const std::vector<uint8_t>& ssid, const std::string& passphrase,
+		bool persistent, uint32_t freq, const std::vector<uint8_t>& peer_address,
+		bool joinExistingGroup);
+	ndk::ScopedAStatus removeGroupInternal(const std::string& group_ifname);
+	ndk::ScopedAStatus rejectInternal(
+		const std::vector<uint8_t>& peer_address);
+	ndk::ScopedAStatus inviteInternal(
+		const std::string& group_ifname,
+		const std::vector<uint8_t>& go_device_address,
+		const std::vector<uint8_t>& peer_address);
+	ndk::ScopedAStatus reinvokeInternal(
+		int32_t persistent_network_id,
+		const std::vector<uint8_t>& peer_address);
+	ndk::ScopedAStatus configureExtListenInternal(
+		uint32_t period_in_millis, uint32_t interval_in_millis);
+	ndk::ScopedAStatus setListenChannelInternal(
+		uint32_t channel, uint32_t operating_class);
+	ndk::ScopedAStatus setDisallowedFrequenciesInternal(
+		const std::vector<FreqRange>& ranges);
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> getSsidInternal(
+		const std::vector<uint8_t>& peer_address);
+	std::pair<P2pGroupCapabilityMask, ndk::ScopedAStatus> getGroupCapabilityInternal(
+		const std::vector<uint8_t>& peer_address);
+	ndk::ScopedAStatus addBonjourServiceInternal(
+		const std::vector<uint8_t>& query,
+		const std::vector<uint8_t>& response);
+	ndk::ScopedAStatus removeBonjourServiceInternal(
+		const std::vector<uint8_t>& query);
+	ndk::ScopedAStatus addUpnpServiceInternal(
+		uint32_t version, const std::string& service_name);
+	ndk::ScopedAStatus removeUpnpServiceInternal(
+		uint32_t version, const std::string& service_name);
+	ndk::ScopedAStatus flushServicesInternal();
+	std::pair<uint64_t, ndk::ScopedAStatus> requestServiceDiscoveryInternal(
+		const std::vector<uint8_t>& peer_address,
+		const std::vector<uint8_t>& query);
+	ndk::ScopedAStatus cancelServiceDiscoveryInternal(uint64_t identifier);
+	ndk::ScopedAStatus setMiracastModeInternal(
+		MiracastMode mode);
+	ndk::ScopedAStatus startWpsPbcInternal(
+		const std::string& group_ifname,
+		const std::vector<uint8_t>& bssid);
+	ndk::ScopedAStatus startWpsPinKeypadInternal(
+		const std::string& group_ifname, const std::string& pin);
+	std::pair<std::string, ndk::ScopedAStatus> startWpsPinDisplayInternal(
+		const std::string& group_ifname,
+		const std::vector<uint8_t>& bssid);
+	ndk::ScopedAStatus cancelWpsInternal(const std::string& group_ifname);
+	ndk::ScopedAStatus setWpsDeviceNameInternal(const std::string& name);
+	ndk::ScopedAStatus setWpsDeviceTypeInternal(
+		const std::vector<uint8_t>& type);
+	ndk::ScopedAStatus setWpsManufacturerInternal(
+		const std::string& manufacturer);
+	ndk::ScopedAStatus setWpsModelNameInternal(const std::string& model_name);
+	ndk::ScopedAStatus setWpsModelNumberInternal(
+		const std::string& model_number);
+	ndk::ScopedAStatus setWpsSerialNumberInternal(
+		const std::string& serial_number);
+	ndk::ScopedAStatus setWpsConfigMethodsInternal(WpsConfigMethods config_methods);
+	ndk::ScopedAStatus enableWfdInternal(bool enable);
+	ndk::ScopedAStatus setWfdDeviceInfoInternal(
+		const std::vector<uint8_t>& info);
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+		createNfcHandoverRequestMessageInternal();
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+		createNfcHandoverSelectMessageInternal();
+	ndk::ScopedAStatus reportNfcHandoverResponseInternal(
+		const std::vector<uint8_t>& request);
+	ndk::ScopedAStatus reportNfcHandoverInitiationInternal(
+		const std::vector<uint8_t>& select);
+	ndk::ScopedAStatus saveConfigInternal();
+	ndk::ScopedAStatus setMacRandomizationInternal(bool enable);
+	ndk::ScopedAStatus setEdmgInternal(bool enable);
+	std::pair<bool, ndk::ScopedAStatus> getEdmgInternal();
+	ndk::ScopedAStatus setWfdR2DeviceInfoInternal(
+		const std::vector<uint8_t>& info);
+	ndk::ScopedAStatus removeClientInternal(
+		const std::vector<uint8_t>& peer_address, bool isLegacyClient);
+	ndk::ScopedAStatus findOnSocialChannelsInternal(uint32_t timeout_in_sec);
+	ndk::ScopedAStatus findOnSpecificFrequencyInternal(
+		uint32_t freq, uint32_t timeout_in_sec);
+	ndk::ScopedAStatus setVendorElementsInternal(
+		P2pFrameTypeMask frameTypeMask,
+		const std::vector<uint8_t>& vendorElemBytes);
+
+	struct wpa_supplicant* retrieveIfacePtr();
+	struct wpa_supplicant* retrieveGroupIfacePtr(
+		const std::string& group_ifname);
+
+	// Reference to the global wpa_struct. This is assumed to be valid for
+	// the lifetime of the process.
+	struct wpa_global* wpa_global_;
+	// Name of the iface this aidl object controls
+	const std::string ifname_;
+	bool is_valid_;
+
+	DISALLOW_COPY_AND_ASSIGN(P2pIface);
+};
+
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WPA_SUPPLICANT_AIDL_P2P_IFACE_H
diff --git a/wpa_supplicant/aidl/p2p_network.cpp b/wpa_supplicant/aidl/p2p_network.cpp
new file mode 100644
index 0000000..9288382
--- /dev/null
+++ b/wpa_supplicant/aidl/p2p_network.cpp
@@ -0,0 +1,252 @@
+/*
+ * WPA Supplicant - P2P network Aidl interface
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "aidl_manager.h"
+#include "aidl_return_util.h"
+#include "misc_utils.h"
+#include "p2p_network.h"
+
+extern "C"
+{
+#include "config_ssid.h"
+}
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+using aidl_return_util::validateAndCall;
+using misc_utils::createStatus;
+
+P2pNetwork::P2pNetwork(
+	struct wpa_global *wpa_global, const char ifname[], int network_id)
+	: wpa_global_(wpa_global),
+	  ifname_(ifname),
+	  network_id_(network_id),
+	  is_valid_(true)
+{}
+
+void P2pNetwork::invalidate() { is_valid_ = false; }
+bool P2pNetwork::isValid()
+{
+	return (is_valid_ && (retrieveNetworkPtr() != nullptr));
+}
+
+::ndk::ScopedAStatus P2pNetwork::getId(
+	int32_t* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pNetwork::getIdInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pNetwork::getInterfaceName(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pNetwork::getInterfaceNameInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pNetwork::getType(
+	IfaceType* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pNetwork::getTypeInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pNetwork::getSsid(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pNetwork::getSsidInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pNetwork::getBssid(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pNetwork::getBssidInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pNetwork::isCurrent(
+	bool* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pNetwork::isCurrentInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pNetwork::isPersistent(
+	bool* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pNetwork::isPersistentInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pNetwork::isGroupOwner(
+	bool* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pNetwork::isGroupOwnerInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus P2pNetwork::setClientList(
+	const std::vector<MacAddress>& in_clients)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pNetwork::setClientListInternal, in_clients);
+}
+
+::ndk::ScopedAStatus P2pNetwork::getClientList(
+	std::vector<MacAddress>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&P2pNetwork::getClientListInternal, _aidl_return);
+}
+
+std::pair<uint32_t, ndk::ScopedAStatus> P2pNetwork::getIdInternal()
+{
+	return {network_id_, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> P2pNetwork::getInterfaceNameInternal()
+{
+	return {ifname_, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<IfaceType, ndk::ScopedAStatus> P2pNetwork::getTypeInternal()
+{
+	return {IfaceType::P2P, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> P2pNetwork::getSsidInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	std::vector<uint8_t> ssid(
+		wpa_ssid->ssid, wpa_ssid->ssid + wpa_ssid->ssid_len);
+	return {ssid, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+P2pNetwork::getBssidInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	std::vector<uint8_t> bssid;
+	if (wpa_ssid->bssid_set) {
+		bssid.assign(wpa_ssid->bssid, wpa_ssid->bssid + ETH_ALEN);
+	}
+	return {bssid, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<bool, ndk::ScopedAStatus> P2pNetwork::isCurrentInternal()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	return {(wpa_s->current_ssid == wpa_ssid),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<bool, ndk::ScopedAStatus> P2pNetwork::isPersistentInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	return {(wpa_ssid->disabled == 2), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<bool, ndk::ScopedAStatus> P2pNetwork::isGroupOwnerInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	return {(wpa_ssid->mode == wpas_mode::WPAS_MODE_P2P_GO),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus P2pNetwork::setClientListInternal(
+	const std::vector<MacAddress> &clients)
+{
+	for (const auto &client : clients) {
+		if (client.data.size() != ETH_ALEN) {
+			return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+		}
+	}
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	os_free(wpa_ssid->p2p_client_list);
+	// Internal representation uses a generic MAC addr/mask storage format
+	// (even though the mask is always 0xFF'ed for p2p_client_list). So, the
+	// first 6 bytes holds the client MAC address and the next 6 bytes are
+	// OxFF'ed.
+	wpa_ssid->p2p_client_list =
+		(u8 *)os_malloc(ETH_ALEN * 2 * clients.size());
+	if (!wpa_ssid->p2p_client_list) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	u8 *list = wpa_ssid->p2p_client_list;
+	for (const auto &client : clients) {
+		os_memcpy(list, client.data.data(), ETH_ALEN);
+		list += ETH_ALEN;
+		os_memset(list, 0xFF, ETH_ALEN);
+		list += ETH_ALEN;
+	}
+	wpa_ssid->num_p2p_clients = clients.size();
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::vector<MacAddress>, ndk::ScopedAStatus>
+P2pNetwork::getClientListInternal()
+{
+	std::vector<MacAddress> clients;
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->p2p_client_list) {
+		return {clients, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	u8 *list = wpa_ssid->p2p_client_list;
+	for (size_t i = 0; i < wpa_ssid->num_p2p_clients; i++) {
+		MacAddress client = MacAddress{};
+		client.data = std::vector<uint8_t>(list, list + ETH_ALEN);
+		clients.emplace_back(client);
+		list += 2 * ETH_ALEN;
+	}
+	return {clients, ndk::ScopedAStatus::ok()};
+}
+
+/**
+ * Retrieve the underlying |wpa_ssid| struct pointer for
+ * this network.
+ * If the underlying network is removed or the interface
+ * this network belong to is removed, all RPC method calls
+ * on this object will return failure.
+ */
+struct wpa_ssid *P2pNetwork::retrieveNetworkPtr()
+{
+	wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (!wpa_s)
+		return nullptr;
+	return wpa_config_get_network(wpa_s->conf, network_id_);
+}
+
+/**
+ * Retrieve the underlying |wpa_supplicant| struct
+ * pointer for this network.
+ */
+struct wpa_supplicant *P2pNetwork::retrieveIfacePtr()
+{
+	return wpa_supplicant_get_iface(
+		(struct wpa_global *)wpa_global_, ifname_.c_str());
+}
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wpa_supplicant/aidl/p2p_network.h b/wpa_supplicant/aidl/p2p_network.h
new file mode 100644
index 0000000..3b7ec5a
--- /dev/null
+++ b/wpa_supplicant/aidl/p2p_network.h
@@ -0,0 +1,94 @@
+/*
+ * WPA Supplicant - P2P network Aidl interface
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef WPA_SUPPLICANT_AIDL_P2P_NETWORK_H
+#define WPA_SUPPLICANT_AIDL_P2P_NETWORK_H
+
+#include <android-base/macros.h>
+
+#include <aidl/android/hardware/wifi/supplicant/BnSupplicantP2pNetwork.h>
+
+extern "C"
+{
+#include "utils/common.h"
+#include "utils/includes.h"
+#include "wpa_supplicant_i.h"
+}
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+
+/**
+ * Implementation of P2pNetwork aidl object. Each unique aidl
+ * object is used for control operations on a specific network
+ * controlled by wpa_supplicant.
+ */
+class P2pNetwork : public BnSupplicantP2pNetwork
+{
+public:
+	P2pNetwork(
+		struct wpa_global* wpa_global, const char ifname[], int network_id);
+	~P2pNetwork() override = default;
+	// Refer to |StaIface::invalidate()|.
+	void invalidate();
+	bool isValid();
+
+	// Aidl methods exposed.
+  	::ndk::ScopedAStatus getId(int32_t* _aidl_return) override;
+	::ndk::ScopedAStatus getInterfaceName(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getType(IfaceType* _aidl_return) override;
+	::ndk::ScopedAStatus getSsid(std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus getBssid(std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus isCurrent(bool* _aidl_return) override;
+	::ndk::ScopedAStatus isPersistent(bool* _aidl_return) override;
+	::ndk::ScopedAStatus isGroupOwner(bool* _aidl_return) override;
+	::ndk::ScopedAStatus setClientList(
+		const std::vector<MacAddress>& in_clients) override;
+	::ndk::ScopedAStatus getClientList(
+		std::vector<MacAddress>* _aidl_return) override;
+
+private:
+	// Corresponding worker functions for the AIDL methods.
+	std::pair<uint32_t, ndk::ScopedAStatus> getIdInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getInterfaceNameInternal();
+	std::pair<IfaceType, ndk::ScopedAStatus> getTypeInternal();
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> getSsidInternal();
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> getBssidInternal();
+	std::pair<bool, ndk::ScopedAStatus> isCurrentInternal();
+	std::pair<bool, ndk::ScopedAStatus> isPersistentInternal();
+	std::pair<bool, ndk::ScopedAStatus> isGroupOwnerInternal();
+	ndk::ScopedAStatus setClientListInternal(
+		const std::vector<MacAddress>& clients);
+	std::pair<std::vector<MacAddress>, ndk::ScopedAStatus>
+		getClientListInternal();
+
+	struct wpa_ssid* retrieveNetworkPtr();
+	struct wpa_supplicant* retrieveIfacePtr();
+
+	// Reference to the global wpa_struct. This is assumed to be valid
+	// for the lifetime of the process.
+	const struct wpa_global* wpa_global_;
+	// Name of the iface this network belongs to.
+	const std::string ifname_;
+	// Id of the network this aidl object controls.
+	const int network_id_;
+	bool is_valid_;
+
+	DISALLOW_COPY_AND_ASSIGN(P2pNetwork);
+};
+
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WPA_SUPPLICANT_AIDL_P2P_NETWORK_H
diff --git a/wpa_supplicant/aidl/sta_iface.cpp b/wpa_supplicant/aidl/sta_iface.cpp
new file mode 100644
index 0000000..084ea2c
--- /dev/null
+++ b/wpa_supplicant/aidl/sta_iface.cpp
@@ -0,0 +1,1842 @@
+/*
+ * WPA Supplicant - Sta Iface Aidl interface
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "aidl_manager.h"
+#include "aidl_return_util.h"
+#include "iface_config_utils.h"
+#include "misc_utils.h"
+#include "sta_iface.h"
+
+extern "C"
+{
+#include "utils/eloop.h"
+#include "gas_query.h"
+#include "interworking.h"
+#include "hs20_supplicant.h"
+#include "wps_supplicant.h"
+#include "dpp.h"
+#include "dpp_supplicant.h"
+#include "rsn_supp/wpa.h"
+#include "rsn_supp/pmksa_cache.h"
+}
+
+namespace {
+using aidl::android::hardware::wifi::supplicant::AidlManager;
+using aidl::android::hardware::wifi::supplicant::BtCoexistenceMode;
+using aidl::android::hardware::wifi::supplicant::ConnectionCapabilities;
+using aidl::android::hardware::wifi::supplicant::DppCurve;
+using aidl::android::hardware::wifi::supplicant::DppResponderBootstrapInfo;
+using aidl::android::hardware::wifi::supplicant::ISupplicant;
+using aidl::android::hardware::wifi::supplicant::ISupplicantStaIface;
+using aidl::android::hardware::wifi::supplicant::ISupplicantStaNetwork;
+using aidl::android::hardware::wifi::supplicant::KeyMgmtMask;
+using aidl::android::hardware::wifi::supplicant::LegacyMode;
+using aidl::android::hardware::wifi::supplicant::RxFilterType;
+using aidl::android::hardware::wifi::supplicant::SupplicantStatusCode;
+using aidl::android::hardware::wifi::supplicant::WifiTechnology;
+using aidl::android::hardware::wifi::supplicant::misc_utils::createStatus;
+
+// TODO (b/204810426): Import from wifi vendor AIDL interface when it exists
+enum WifiChannelWidthInMhz {
+  WIDTH_20	= 0,
+  WIDTH_40	= 1,
+  WIDTH_80	= 2,
+  WIDTH_160   = 3,
+  WIDTH_80P80 = 4,
+  WIDTH_5	 = 5,
+  WIDTH_10	= 6,
+  WIDTH_INVALID = -1
+};
+
+constexpr uint32_t kMaxAnqpElems = 100;
+constexpr char kGetMacAddress[] = "MACADDR";
+constexpr char kStartRxFilter[] = "RXFILTER-START";
+constexpr char kStopRxFilter[] = "RXFILTER-STOP";
+constexpr char kAddRxFilter[] = "RXFILTER-ADD";
+constexpr char kRemoveRxFilter[] = "RXFILTER-REMOVE";
+constexpr char kSetBtCoexistenceMode[] = "BTCOEXMODE";
+constexpr char kSetBtCoexistenceScanStart[] = "BTCOEXSCAN-START";
+constexpr char kSetBtCoexistenceScanStop[] = "BTCOEXSCAN-STOP";
+constexpr char kSetSupendModeEnabled[] = "SETSUSPENDMODE 1";
+constexpr char kSetSupendModeDisabled[] = "SETSUSPENDMODE 0";
+constexpr char kSetCountryCode[] = "COUNTRY";
+constexpr uint32_t kExtRadioWorkDefaultTimeoutInSec =
+	static_cast<uint32_t>(ISupplicant::EXT_RADIO_WORK_TIMEOUT_IN_SECS);
+constexpr char kExtRadioWorkNamePrefix[] = "ext:";
+
+uint8_t convertAidlRxFilterTypeToInternal(
+	RxFilterType type)
+{
+	switch (type) {
+	case RxFilterType::V4_MULTICAST:
+		return 2;
+	case RxFilterType::V6_MULTICAST:
+		return 3;
+	};
+	WPA_ASSERT(false);
+}
+
+uint8_t convertAidlBtCoexModeToInternal(
+	BtCoexistenceMode mode)
+{
+	switch (mode) {
+	case BtCoexistenceMode::ENABLED:
+		return 0;
+	case BtCoexistenceMode::DISABLED:
+		return 1;
+	case BtCoexistenceMode::SENSE:
+		return 2;
+	};
+	WPA_ASSERT(false);
+}
+
+ndk::ScopedAStatus doZeroArgDriverCommand(
+	struct wpa_supplicant *wpa_s, const char *cmd)
+{
+	std::vector<char> cmd_vec(cmd, cmd + strlen(cmd) + 1);
+	char driver_cmd_reply_buf[4096] = {};
+	if (wpa_drv_driver_cmd(
+		wpa_s, cmd_vec.data(), driver_cmd_reply_buf,
+		sizeof(driver_cmd_reply_buf))) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus doOneArgDriverCommand(
+	struct wpa_supplicant *wpa_s, const char *cmd, uint8_t arg)
+{
+	std::string cmd_str = std::string(cmd) + " " + std::to_string(arg);
+	return doZeroArgDriverCommand(wpa_s, cmd_str.c_str());
+}
+
+ndk::ScopedAStatus doOneArgDriverCommand(
+	struct wpa_supplicant *wpa_s, const char *cmd, const std::string &arg)
+{
+	std::string cmd_str = std::string(cmd) + " " + arg;
+	return doZeroArgDriverCommand(wpa_s, cmd_str.c_str());
+}
+
+void endExtRadioWork(struct wpa_radio_work *work)
+{
+	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
+	work->wpa_s->ext_work_in_progress = 0;
+	radio_work_done(work);
+	os_free(ework);
+}
+
+void extRadioWorkTimeoutCb(void *eloop_ctx, void *timeout_ctx)
+{
+	auto *work = static_cast<struct wpa_radio_work *>(eloop_ctx);
+	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
+	wpa_dbg(
+		work->wpa_s, MSG_DEBUG, "Timing out external radio work %u (%s)",
+		ework->id, work->type);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	WPA_ASSERT(aidl_manager);
+	aidl_manager->notifyExtRadioWorkTimeout(work->wpa_s, ework->id);
+
+	endExtRadioWork(work);
+}
+
+void startExtRadioWork(struct wpa_radio_work *work)
+{
+	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
+	work->wpa_s->ext_work_in_progress = 1;
+	if (!ework->timeout) {
+		ework->timeout = kExtRadioWorkDefaultTimeoutInSec;
+	}
+	eloop_register_timeout(
+		ework->timeout, 0, extRadioWorkTimeoutCb, work, nullptr);
+}
+
+void extRadioWorkStartCb(struct wpa_radio_work *work, int deinit)
+{
+	// deinit==1 is invoked during interface removal. Since the AIDL
+	// interface does not support interface addition/removal, we don't
+	// need to handle this scenario.
+	WPA_ASSERT(!deinit);
+
+	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
+	wpa_dbg(
+		work->wpa_s, MSG_DEBUG, "Starting external radio work %u (%s)",
+		ework->id, ework->type);
+
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	WPA_ASSERT(aidl_manager);
+	aidl_manager->notifyExtRadioWorkStart(work->wpa_s, ework->id);
+
+	startExtRadioWork(work);
+}
+
+KeyMgmtMask convertWpaKeyMgmtCapabilitiesToAidl (
+	struct wpa_supplicant *wpa_s, struct wpa_driver_capa *capa) {
+
+	uint32_t mask = 0;
+	/* Logic from ctrl_iface.c, NONE and IEEE8021X have no capability
+	 * flags and always enabled.
+	 */
+	mask |=
+		(static_cast<uint32_t>(KeyMgmtMask::NONE) |
+		 static_cast<uint32_t>(KeyMgmtMask::IEEE8021X));
+
+	if (capa->key_mgmt &
+		(WPA_DRIVER_CAPA_KEY_MGMT_WPA | WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
+		mask |= static_cast<uint32_t>(KeyMgmtMask::WPA_EAP);
+	}
+
+	if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
+				 WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
+		mask |= static_cast<uint32_t>(KeyMgmtMask::WPA_PSK);
+	}
+#ifdef CONFIG_SUITEB192
+	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192) {
+		mask |= static_cast<uint32_t>(KeyMgmtMask::SUITE_B_192);
+	}
+#endif /* CONFIG_SUITEB192 */
+#ifdef CONFIG_OWE
+	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OWE) {
+		mask |= static_cast<uint32_t>(KeyMgmtMask::OWE);
+	}
+#endif /* CONFIG_OWE */
+#ifdef CONFIG_SAE
+	if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE) {
+		mask |= static_cast<uint32_t>(KeyMgmtMask::SAE);
+	}
+#endif /* CONFIG_SAE */
+#ifdef CONFIG_DPP
+	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_DPP) {
+		mask |= static_cast<uint32_t>(KeyMgmtMask::DPP);
+	}
+#endif
+#ifdef CONFIG_WAPI_INTERFACE
+	mask |= static_cast<uint32_t>(KeyMgmtMask::WAPI_PSK);
+	mask |= static_cast<uint32_t>(KeyMgmtMask::WAPI_CERT);
+#endif /* CONFIG_WAPI_INTERFACE */
+#ifdef CONFIG_FILS
+	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256) {
+		mask |= static_cast<uint32_t>(KeyMgmtMask::FILS_SHA256);
+	}
+	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384) {
+		mask |= static_cast<uint32_t>(KeyMgmtMask::FILS_SHA384);
+	}
+#endif /* CONFIG_FILS */
+	return static_cast<KeyMgmtMask>(mask);
+}
+
+const std::string getDppListenChannel(struct wpa_supplicant *wpa_s, int32_t *listen_channel)
+{
+	struct hostapd_hw_modes *mode;
+	int chan44 = 0, chan149 = 0;
+	*listen_channel = 0;
+
+	/* Check if device support 2.4GHz band*/
+	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
+			HOSTAPD_MODE_IEEE80211G, 0);
+	if (mode) {
+		*listen_channel = 6;
+		return "81/6";
+	}
+	/* Check if device support 5GHz band */
+	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
+			HOSTAPD_MODE_IEEE80211A, 0);
+	if (mode) {
+		for (int i = 0; i < mode->num_channels; i++) {
+			struct hostapd_channel_data *chan = &mode->channels[i];
+
+			if (chan->flag & (HOSTAPD_CHAN_DISABLED |
+					  HOSTAPD_CHAN_RADAR))
+				continue;
+			if (chan->freq == 5220)
+				chan44 = 1;
+			if (chan->freq == 5745)
+				chan149 = 1;
+		}
+		if (chan149) {
+			*listen_channel = 149;
+			return "124/149";
+		} else if (chan44) {
+			*listen_channel = 44;
+			return "115/44";
+		}
+	}
+
+	return "";
+}
+
+const std::string convertCurveTypeToName(DppCurve curve)
+{
+	switch (curve) {
+	case DppCurve::PRIME256V1:
+		return "prime256v1";
+	case DppCurve::SECP384R1:
+		return "secp384r1";
+	case DppCurve::SECP521R1:
+		return "secp521r1";
+	case DppCurve::BRAINPOOLP256R1:
+		return "brainpoolP256r1";
+	case DppCurve::BRAINPOOLP384R1:
+		return "brainpoolP384r1";
+	case DppCurve::BRAINPOOLP512R1:
+		return "brainpoolP512r1";
+	}
+	WPA_ASSERT(false);
+}
+
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+using aidl_return_util::validateAndCall;
+using misc_utils::createStatus;
+
+StaIface::StaIface(struct wpa_global *wpa_global, const char ifname[])
+	: wpa_global_(wpa_global), ifname_(ifname), is_valid_(true)
+{}
+
+void StaIface::invalidate() { is_valid_ = false; }
+bool StaIface::isValid()
+{
+	return (is_valid_ && (retrieveIfacePtr() != nullptr));
+}
+
+::ndk::ScopedAStatus StaIface::getName(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::getNameInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaIface::getType(
+	IfaceType* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::getTypeInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaIface::addNetwork(
+	std::shared_ptr<ISupplicantStaNetwork>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::addNetworkInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaIface::removeNetwork(
+	int32_t in_id)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::removeNetworkInternal, in_id);
+}
+
+::ndk::ScopedAStatus StaIface::filsHlpFlushRequest()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::filsHlpFlushRequestInternal);
+}
+
+::ndk::ScopedAStatus StaIface::filsHlpAddRequest(
+	const std::vector<uint8_t>& in_dst_mac,
+	const std::vector<uint8_t>& in_pkt)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::filsHlpAddRequestInternal, in_dst_mac, in_pkt);
+}
+
+::ndk::ScopedAStatus StaIface::getNetwork(
+	int32_t in_id, std::shared_ptr<ISupplicantStaNetwork>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::getNetworkInternal, _aidl_return, in_id);
+}
+
+::ndk::ScopedAStatus StaIface::listNetworks(
+	std::vector<int32_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::listNetworksInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaIface::registerCallback(
+	const std::shared_ptr<ISupplicantStaIfaceCallback>& in_callback)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::registerCallbackInternal, in_callback);
+}
+
+::ndk::ScopedAStatus StaIface::reassociate()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::reassociateInternal);
+}
+
+::ndk::ScopedAStatus StaIface::reconnect()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::reconnectInternal);
+}
+
+::ndk::ScopedAStatus StaIface::disconnect()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::disconnectInternal);
+}
+
+::ndk::ScopedAStatus StaIface::setPowerSave(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setPowerSaveInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaIface::initiateTdlsDiscover(
+	const std::vector<uint8_t>& in_macAddress)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::initiateTdlsDiscoverInternal, in_macAddress);
+}
+
+::ndk::ScopedAStatus StaIface::initiateTdlsSetup(
+	const std::vector<uint8_t>& in_macAddress)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::initiateTdlsSetupInternal, in_macAddress);
+}
+
+::ndk::ScopedAStatus StaIface::initiateTdlsTeardown(
+	const std::vector<uint8_t>& in_macAddress)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::initiateTdlsTeardownInternal, in_macAddress);
+}
+
+::ndk::ScopedAStatus StaIface::initiateAnqpQuery(
+	const std::vector<uint8_t>& in_macAddress,
+	const std::vector<AnqpInfoId>& in_infoElements,
+	const std::vector<Hs20AnqpSubtypes>& in_subTypes)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::initiateAnqpQueryInternal, in_macAddress,
+		in_infoElements, in_subTypes);
+}
+
+::ndk::ScopedAStatus StaIface::initiateVenueUrlAnqpQuery(
+	const std::vector<uint8_t>& in_macAddress)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::initiateVenueUrlAnqpQueryInternal, in_macAddress);
+}
+
+::ndk::ScopedAStatus StaIface::initiateHs20IconQuery(
+	const std::vector<uint8_t>& in_macAddress,
+	const std::string& in_fileName)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::initiateHs20IconQueryInternal, in_macAddress,
+		in_fileName);
+}
+
+::ndk::ScopedAStatus StaIface::getMacAddress(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::getMacAddressInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaIface::startRxFilter()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::startRxFilterInternal);
+}
+
+::ndk::ScopedAStatus StaIface::stopRxFilter()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::stopRxFilterInternal);
+}
+
+::ndk::ScopedAStatus StaIface::addRxFilter(
+	RxFilterType in_type)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::addRxFilterInternal, in_type);
+}
+
+::ndk::ScopedAStatus StaIface::removeRxFilter(
+	RxFilterType in_type)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::removeRxFilterInternal, in_type);
+}
+
+::ndk::ScopedAStatus StaIface::setBtCoexistenceMode(
+	BtCoexistenceMode in_mode)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setBtCoexistenceModeInternal, in_mode);
+}
+
+::ndk::ScopedAStatus StaIface::setBtCoexistenceScanModeEnabled(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setBtCoexistenceScanModeEnabledInternal,
+		in_enable);
+}
+
+::ndk::ScopedAStatus StaIface::setSuspendModeEnabled(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setSuspendModeEnabledInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaIface::setCountryCode(
+	const std::vector<uint8_t>& in_code)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setCountryCodeInternal, in_code);
+}
+
+::ndk::ScopedAStatus StaIface::startWpsRegistrar(
+	const std::vector<uint8_t>& in_bssid,
+	const std::string& in_pin)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::startWpsRegistrarInternal, in_bssid, in_pin);
+}
+
+::ndk::ScopedAStatus StaIface::startWpsPbc(
+	const std::vector<uint8_t>& in_bssid)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::startWpsPbcInternal, in_bssid);
+}
+
+::ndk::ScopedAStatus StaIface::startWpsPinKeypad(
+	const std::string& in_pin)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::startWpsPinKeypadInternal, in_pin);
+}
+
+::ndk::ScopedAStatus StaIface::startWpsPinDisplay(
+	const std::vector<uint8_t>& in_bssid,
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::startWpsPinDisplayInternal, _aidl_return, in_bssid);
+}
+
+::ndk::ScopedAStatus StaIface::cancelWps()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::cancelWpsInternal);
+}
+
+::ndk::ScopedAStatus StaIface::setWpsDeviceName(
+	const std::string& in_name)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setWpsDeviceNameInternal, in_name);
+}
+
+::ndk::ScopedAStatus StaIface::setWpsDeviceType(
+	const std::vector<uint8_t>& in_type)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setWpsDeviceTypeInternal, in_type);
+}
+
+::ndk::ScopedAStatus StaIface::setWpsManufacturer(
+	const std::string& in_manufacturer)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setWpsManufacturerInternal, in_manufacturer);
+}
+
+::ndk::ScopedAStatus StaIface::setWpsModelName(
+	const std::string& in_modelName)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setWpsModelNameInternal, in_modelName);
+}
+
+::ndk::ScopedAStatus StaIface::setWpsModelNumber(
+	const std::string& in_modelNumber)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setWpsModelNumberInternal, in_modelNumber);
+}
+
+::ndk::ScopedAStatus StaIface::setWpsSerialNumber(
+	const std::string& in_serialNumber)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setWpsSerialNumberInternal, in_serialNumber);
+}
+
+::ndk::ScopedAStatus StaIface::setWpsConfigMethods(
+	WpsConfigMethods in_configMethods)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setWpsConfigMethodsInternal, in_configMethods);
+}
+
+::ndk::ScopedAStatus StaIface::setExternalSim(
+	bool in_useExternalSim)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::setExternalSimInternal, in_useExternalSim);
+}
+
+::ndk::ScopedAStatus StaIface::addExtRadioWork(
+	const std::string& in_name, int32_t in_freqInMhz,
+	int32_t in_timeoutInSec,
+	int32_t* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::addExtRadioWorkInternal, _aidl_return, in_name, in_freqInMhz,
+		in_timeoutInSec);
+}
+
+::ndk::ScopedAStatus StaIface::removeExtRadioWork(
+	int32_t in_id)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::removeExtRadioWorkInternal, in_id);
+}
+
+::ndk::ScopedAStatus StaIface::enableAutoReconnect(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::enableAutoReconnectInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaIface::getKeyMgmtCapabilities(
+	KeyMgmtMask* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaIface::getKeyMgmtCapabilitiesInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaIface::addDppPeerUri(
+	const std::string& in_uri, int32_t* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaIface::addDppPeerUriInternal, _aidl_return, in_uri);
+}
+
+::ndk::ScopedAStatus StaIface::removeDppUri(
+	int32_t in_id)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaIface::removeDppUriInternal, in_id);
+}
+
+::ndk::ScopedAStatus StaIface::startDppConfiguratorInitiator(
+	int32_t in_peerBootstrapId, int32_t in_ownBootstrapId,
+	const std::string& in_ssid, const std::string& in_password,
+	const std::string& in_psk, DppNetRole in_netRole,
+	DppAkm in_securityAkm, const std::vector<uint8_t>& in_privEcKey,
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaIface::startDppConfiguratorInitiatorInternal, _aidl_return,
+		in_peerBootstrapId,in_ownBootstrapId, in_ssid, in_password,
+		in_psk, in_netRole, in_securityAkm, in_privEcKey);
+}
+
+::ndk::ScopedAStatus StaIface::startDppEnrolleeInitiator(
+	int32_t in_peerBootstrapId, int32_t in_ownBootstrapId)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaIface::startDppEnrolleeInitiatorInternal, in_peerBootstrapId,
+		in_ownBootstrapId);
+}
+
+::ndk::ScopedAStatus StaIface::stopDppInitiator()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaIface::stopDppInitiatorInternal);
+}
+
+::ndk::ScopedAStatus StaIface::getConnectionCapabilities(
+	ConnectionCapabilities* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::getConnectionCapabilitiesInternal,
+		_aidl_return);
+}
+
+::ndk::ScopedAStatus StaIface::generateDppBootstrapInfoForResponder(
+	const std::vector<uint8_t>& in_macAddress, const std::string& in_deviceInfo,
+	DppCurve in_curve, DppResponderBootstrapInfo* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::generateDppBootstrapInfoForResponderInternal, _aidl_return, 
+		in_macAddress, in_deviceInfo, in_curve);
+}
+
+::ndk::ScopedAStatus StaIface::startDppEnrolleeResponder(
+	int32_t in_listenChannel)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::startDppEnrolleeResponderInternal, in_listenChannel);
+}
+
+::ndk::ScopedAStatus StaIface::stopDppResponder(
+	int32_t in_ownBootstrapId)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::stopDppResponderInternal, in_ownBootstrapId);
+}
+
+::ndk::ScopedAStatus StaIface::generateSelfDppConfiguration(
+	const std::string& in_ssid, const std::vector<uint8_t>& in_privEcKey)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&StaIface::generateSelfDppConfigurationInternal, in_ssid, in_privEcKey);
+}
+
+::ndk::ScopedAStatus StaIface::getWpaDriverCapabilities(
+	WpaDriverCapabilitiesMask* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::getWpaDriverCapabilitiesInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaIface::setMboCellularDataStatus(
+	bool in_available)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::setMboCellularDataStatusInternal, in_available);
+}
+
+::ndk::ScopedAStatus StaIface::setQosPolicyFeatureEnabled(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::setQosPolicyFeatureEnabledInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaIface::sendQosPolicyResponse(
+	bool in_morePolicies,
+	const std::vector<QosPolicyStatus>& in_qosPolicyStatusList)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::sendQosPolicyResponseInternal, in_morePolicies,
+		in_qosPolicyStatusList);
+}
+
+::ndk::ScopedAStatus StaIface::removeAllQosPolicies()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::removeAllQosPoliciesInternal);
+}
+
+::ndk::ScopedAStatus StaIface::getConnectionMloLinksInfo(MloLinksInfo* _aidl_return) {
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::getConnectionMloLinksInfoInternal, _aidl_return);
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaIface::getNameInternal()
+{
+	return {ifname_, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<IfaceType, ndk::ScopedAStatus> StaIface::getTypeInternal()
+{
+	return {IfaceType::STA, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaIface::filsHlpFlushRequestInternal()
+{
+#ifdef CONFIG_FILS
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+
+	wpas_flush_fils_hlp_req(wpa_s);
+	return ndk::ScopedAStatus::ok();
+#else /* CONFIG_FILS */
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN, "");
+#endif /* CONFIG_FILS */
+}
+
+ndk::ScopedAStatus StaIface::filsHlpAddRequestInternal(
+	const std::vector<uint8_t> &dst_mac, const std::vector<uint8_t> &pkt)
+{
+#ifdef CONFIG_FILS
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	struct fils_hlp_req *req;
+
+	if (!pkt.size())
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	if (dst_mac.size() != ETH_ALEN)
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+
+
+	req = (struct fils_hlp_req *)os_zalloc(sizeof(*req));
+	if (!req)
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+
+	os_memcpy(req->dst, dst_mac.data(), ETH_ALEN);
+
+	req->pkt = wpabuf_alloc_copy(pkt.data(), pkt.size());
+	if (!req->pkt) {
+		os_free(req);
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	dl_list_add_tail(&wpa_s->fils_hlp_req, &req->list);
+	return ndk::ScopedAStatus::ok();
+#else /* CONFIG_FILS */
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+#endif /* CONFIG_FILS */
+}
+
+std::pair<std::shared_ptr<ISupplicantStaNetwork>, ndk::ScopedAStatus>
+StaIface::addNetworkInternal()
+{
+	std::shared_ptr<ISupplicantStaNetwork> network;
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	struct wpa_ssid *ssid = wpa_supplicant_add_network(wpa_s);
+	if (!ssid) {
+		return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager ||
+		aidl_manager->getStaNetworkAidlObjectByIfnameAndNetworkId(
+		wpa_s->ifname, ssid->id, &network)) {
+		return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {network, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaIface::removeNetworkInternal(int32_t id)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	int result = wpa_supplicant_remove_network(wpa_s, id);
+	if (result == -1) {
+		return createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN);
+	}
+	if (result != 0) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::shared_ptr<ISupplicantStaNetwork>, ndk::ScopedAStatus>
+StaIface::getNetworkInternal(int32_t id)
+{
+	std::shared_ptr<ISupplicantStaNetwork> network;
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, id);
+	if (!ssid) {
+		return {network, createStatus(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN)};
+	}
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager ||
+		aidl_manager->getStaNetworkAidlObjectByIfnameAndNetworkId(
+		wpa_s->ifname, ssid->id, &network)) {
+		return {network, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {network, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<int32_t>, ndk::ScopedAStatus>
+StaIface::listNetworksInternal()
+{
+	std::vector<int32_t> network_ids;
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	for (struct wpa_ssid *wpa_ssid = wpa_s->conf->ssid; wpa_ssid;
+		 wpa_ssid = wpa_ssid->next) {
+		network_ids.emplace_back(wpa_ssid->id);
+	}
+	return {std::move(network_ids), ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaIface::registerCallbackInternal(
+	const std::shared_ptr<ISupplicantStaIfaceCallback> &callback)
+{
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager ||
+		aidl_manager->addStaIfaceCallbackAidlObject(ifname_, callback)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::reassociateInternal()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+	wpas_request_connection(wpa_s);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::reconnectInternal()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+	if (!wpa_s->disconnected) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_NOT_DISCONNECTED);
+	}
+	wpas_request_connection(wpa_s);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::disconnectInternal()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+	wpas_request_disconnection(wpa_s);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::setPowerSaveInternal(bool enable)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+	if (wpa_drv_set_p2p_powersave(wpa_s, enable, -1, -1)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::initiateTdlsDiscoverInternal(
+	const std::vector<uint8_t> &mac_address)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	int ret;
+	const u8 *peer = mac_address.data();
+	if (wpa_tdls_is_external_setup(wpa_s->wpa)) {
+		ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer);
+	} else {
+		ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
+	}
+	if (ret) {
+		wpa_printf(MSG_INFO, "StaIface: TDLS discover failed: %d", ret);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::initiateTdlsSetupInternal(
+	const std::vector<uint8_t> &mac_address)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	int ret;
+	const u8 *peer = mac_address.data();
+	if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
+		!(wpa_s->conf->tdls_external_control)) {
+		wpa_tdls_remove(wpa_s->wpa, peer);
+		ret = wpa_tdls_start(wpa_s->wpa, peer);
+	} else {
+		ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
+	}
+	if (ret) {
+		wpa_printf(MSG_INFO, "StaIface: TDLS setup failed: %d", ret);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::initiateTdlsTeardownInternal(
+	const std::vector<uint8_t> &mac_address)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	int ret;
+	const u8 *peer = mac_address.data();
+	if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
+		!(wpa_s->conf->tdls_external_control)) {
+		ret = wpa_tdls_teardown_link(
+			wpa_s->wpa, peer, WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
+	} else {
+		ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
+	}
+	if (ret) {
+		wpa_printf(MSG_INFO, "StaIface: TDLS teardown failed: %d", ret);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::initiateAnqpQueryInternal(
+	const std::vector<uint8_t> &mac_address,
+	const std::vector<AnqpInfoId> &info_elements,
+	const std::vector<Hs20AnqpSubtypes> &sub_types)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (info_elements.size() > kMaxAnqpElems) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	uint16_t info_elems_buf[kMaxAnqpElems];
+	uint32_t num_info_elems = 0;
+	for (const auto &info_element : info_elements) {
+		info_elems_buf[num_info_elems++] =
+			static_cast<std::underlying_type<
+			AnqpInfoId>::type>(info_element);
+	}
+	uint32_t sub_types_bitmask = 0;
+	for (const auto &type : sub_types) {
+		sub_types_bitmask |= BIT(
+			static_cast<std::underlying_type<
+			Hs20AnqpSubtypes>::type>(type));
+	}
+
+	if (anqp_send_req(
+		wpa_s, mac_address.data(), 0, info_elems_buf, num_info_elems,
+		sub_types_bitmask, 0)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::initiateVenueUrlAnqpQueryInternal(
+	const std::vector<uint8_t> &mac_address)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	uint16_t info_elems_buf[1] = {ANQP_VENUE_URL};
+
+	if (anqp_send_req(
+		wpa_s, mac_address.data(), 0, info_elems_buf, 1, 0, 0)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::initiateHs20IconQueryInternal(
+	const std::vector<uint8_t> &mac_address, const std::string &file_name)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	wpa_s->fetch_osu_icon_in_progress = 0;
+	if (hs20_anqp_send_req(
+		wpa_s, mac_address.data(), BIT(HS20_STYPE_ICON_REQUEST),
+		reinterpret_cast<const uint8_t *>(file_name.c_str()),
+		file_name.size(), true)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+StaIface::getMacAddressInternal()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	std::vector<char> cmd(
+		kGetMacAddress, kGetMacAddress + sizeof(kGetMacAddress));
+	char driver_cmd_reply_buf[4096] = {};
+	int ret = wpa_drv_driver_cmd(
+		wpa_s, cmd.data(), driver_cmd_reply_buf,
+		sizeof(driver_cmd_reply_buf));
+	// Reply is of the format: "Macaddr = XX:XX:XX:XX:XX:XX"
+	std::string reply_str = driver_cmd_reply_buf;
+	if (ret < 0 || reply_str.empty() ||
+		reply_str.find("=") == std::string::npos) {
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	// Remove all whitespace first and then split using the delimiter "=".
+	reply_str.erase(
+		remove_if(reply_str.begin(), reply_str.end(), isspace),
+		reply_str.end());
+	std::string mac_addr_str =
+		reply_str.substr(reply_str.find("=") + 1, reply_str.size());
+	std::vector<uint8_t> mac_addr(6);
+	if (hwaddr_aton(mac_addr_str.c_str(), mac_addr.data())) {
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {mac_addr, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaIface::startRxFilterInternal()
+{
+	return doZeroArgDriverCommand(retrieveIfacePtr(), kStartRxFilter);
+}
+
+ndk::ScopedAStatus StaIface::stopRxFilterInternal()
+{
+	return doZeroArgDriverCommand(retrieveIfacePtr(), kStopRxFilter);
+}
+
+ndk::ScopedAStatus StaIface::addRxFilterInternal(
+	RxFilterType type)
+{
+	return doOneArgDriverCommand(
+		retrieveIfacePtr(), kAddRxFilter,
+		convertAidlRxFilterTypeToInternal(type));
+}
+
+ndk::ScopedAStatus StaIface::removeRxFilterInternal(
+	RxFilterType type)
+{
+	return doOneArgDriverCommand(
+		retrieveIfacePtr(), kRemoveRxFilter,
+		convertAidlRxFilterTypeToInternal(type));
+}
+
+ndk::ScopedAStatus StaIface::setBtCoexistenceModeInternal(
+	BtCoexistenceMode mode)
+{
+	return doOneArgDriverCommand(
+		retrieveIfacePtr(), kSetBtCoexistenceMode,
+		convertAidlBtCoexModeToInternal(mode));
+}
+
+ndk::ScopedAStatus StaIface::setBtCoexistenceScanModeEnabledInternal(bool enable)
+{
+	const char *cmd;
+	if (enable) {
+		cmd = kSetBtCoexistenceScanStart;
+	} else {
+		cmd = kSetBtCoexistenceScanStop;
+	}
+	return doZeroArgDriverCommand(retrieveIfacePtr(), cmd);
+}
+
+ndk::ScopedAStatus StaIface::setSuspendModeEnabledInternal(bool enable)
+{
+	const char *cmd;
+	if (enable) {
+		cmd = kSetSupendModeEnabled;
+	} else {
+		cmd = kSetSupendModeDisabled;
+	}
+	return doZeroArgDriverCommand(retrieveIfacePtr(), cmd);
+}
+
+ndk::ScopedAStatus StaIface::setCountryCodeInternal(
+	const std::vector<uint8_t> &code)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	ndk::ScopedAStatus status = doOneArgDriverCommand(
+		wpa_s, kSetCountryCode,
+		std::string(std::begin(code), std::end(code)));
+	if (!status.isOk()) {
+		return status;
+	}
+	struct p2p_data *p2p = wpa_s->global->p2p;
+	if (p2p) {
+		char country[3];
+		country[0] = code[0];
+		country[1] = code[1];
+		country[2] = 0x04;
+		p2p_set_country(p2p, country);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::startWpsRegistrarInternal(
+	const std::vector<uint8_t> &bssid, const std::string &pin)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpas_wps_start_reg(wpa_s, bssid.data(), pin.c_str(), nullptr)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::startWpsPbcInternal(
+	const std::vector<uint8_t> &bssid)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	const uint8_t *bssid_addr =
+		is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
+	if (wpas_wps_start_pbc(wpa_s, bssid_addr, 0, 0)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::startWpsPinKeypadInternal(const std::string &pin)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpas_wps_start_pin(
+		wpa_s, nullptr, pin.c_str(), 0, DEV_PW_DEFAULT)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaIface::startWpsPinDisplayInternal(
+	const std::vector<uint8_t> &bssid)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	const uint8_t *bssid_addr =
+		is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
+	int pin =
+		wpas_wps_start_pin(wpa_s, bssid_addr, nullptr, 0, DEV_PW_DEFAULT);
+	if (pin < 0) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::convertWpsPinToString(pin),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaIface::cancelWpsInternal()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpas_wps_cancel(wpa_s)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::setWpsDeviceNameInternal(const std::string &name)
+{
+	return iface_config_utils::setWpsDeviceName(retrieveIfacePtr(), name);
+}
+
+ndk::ScopedAStatus StaIface::setWpsDeviceTypeInternal(
+	const std::vector<uint8_t> &type)
+{
+	std::array<uint8_t, 8> type_arr;
+	std::copy_n(type.begin(), 8, type_arr.begin());
+	return iface_config_utils::setWpsDeviceType(retrieveIfacePtr(), type_arr);
+}
+
+ndk::ScopedAStatus StaIface::setWpsManufacturerInternal(
+	const std::string &manufacturer)
+{
+	return iface_config_utils::setWpsManufacturer(
+		retrieveIfacePtr(), manufacturer);
+}
+
+ndk::ScopedAStatus StaIface::setWpsModelNameInternal(
+	const std::string &model_name)
+{
+	return iface_config_utils::setWpsModelName(
+		retrieveIfacePtr(), model_name);
+}
+
+ndk::ScopedAStatus StaIface::setWpsModelNumberInternal(
+	const std::string &model_number)
+{
+	return iface_config_utils::setWpsModelNumber(
+		retrieveIfacePtr(), model_number);
+}
+
+ndk::ScopedAStatus StaIface::setWpsSerialNumberInternal(
+	const std::string &serial_number)
+{
+	return iface_config_utils::setWpsSerialNumber(
+		retrieveIfacePtr(), serial_number);
+}
+
+ndk::ScopedAStatus StaIface::setWpsConfigMethodsInternal(WpsConfigMethods config_methods)
+{
+	return iface_config_utils::setWpsConfigMethods(
+		retrieveIfacePtr(), static_cast<uint16_t>(config_methods));
+}
+
+ndk::ScopedAStatus StaIface::setExternalSimInternal(bool useExternalSim)
+{
+	return iface_config_utils::setExternalSim(
+		retrieveIfacePtr(), useExternalSim);
+}
+
+std::pair<uint32_t, ndk::ScopedAStatus> StaIface::addExtRadioWorkInternal(
+	const std::string &name, uint32_t freq_in_mhz, uint32_t timeout_in_sec)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	auto *ework = static_cast<struct wpa_external_work *>(
+		os_zalloc(sizeof(struct wpa_external_work)));
+	if (!ework) {
+		return {UINT32_MAX, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+
+	std::string radio_work_name = kExtRadioWorkNamePrefix + name;
+	os_strlcpy(ework->type, radio_work_name.c_str(), sizeof(ework->type));
+	ework->timeout = timeout_in_sec;
+	wpa_s->ext_work_id++;
+	if (wpa_s->ext_work_id == 0) {
+		wpa_s->ext_work_id++;
+	}
+	ework->id = wpa_s->ext_work_id;
+
+	if (radio_add_work(
+		wpa_s, freq_in_mhz, ework->type, 0, extRadioWorkStartCb,
+		ework)) {
+		os_free(ework);
+		return {UINT32_MAX, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {ework->id, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaIface::removeExtRadioWorkInternal(uint32_t id)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	struct wpa_radio_work *work;
+	dl_list_for_each(work, &wpa_s->radio->work, struct wpa_radio_work, list)
+	{
+		if (os_strncmp(
+			work->type, kExtRadioWorkNamePrefix,
+			sizeof(kExtRadioWorkNamePrefix)) != 0)
+			continue;
+
+		auto *ework =
+			static_cast<struct wpa_external_work *>(work->ctx);
+		if (ework->id != id)
+			continue;
+
+		wpa_dbg(
+			wpa_s, MSG_DEBUG, "Completed external radio work %u (%s)",
+			ework->id, ework->type);
+		eloop_cancel_timeout(extRadioWorkTimeoutCb, work, NULL);
+		endExtRadioWork(work);
+
+		return ndk::ScopedAStatus::ok();
+	}
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+}
+
+ndk::ScopedAStatus StaIface::enableAutoReconnectInternal(bool enable)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	wpa_s->auto_reconnect_disabled = enable ? 0 : 1;
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<uint32_t, ndk::ScopedAStatus>
+StaIface::addDppPeerUriInternal(const std::string& uri)
+{
+#ifdef CONFIG_DPP
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	int32_t id;
+
+	id = wpas_dpp_qr_code(wpa_s, uri.c_str());
+
+	if (id > 0) {
+		return {id, ndk::ScopedAStatus::ok()};
+	}
+#endif
+	return {-1, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+}
+
+ndk::ScopedAStatus StaIface::removeDppUriInternal(uint32_t bootstrap_id)
+{
+#ifdef CONFIG_DPP
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	std::string bootstrap_id_str;
+
+	if (bootstrap_id == 0) {
+		bootstrap_id_str = "*";
+	}
+	else {
+		bootstrap_id_str = std::to_string(bootstrap_id);
+	}
+
+	if (dpp_bootstrap_remove(wpa_s->dpp, bootstrap_id_str.c_str()) >= 0) {
+		return ndk::ScopedAStatus::ok();
+	}
+#endif
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+StaIface::startDppConfiguratorInitiatorInternal(
+		uint32_t peer_bootstrap_id, uint32_t own_bootstrap_id,
+		const std::string& ssid, const std::string& password,
+		const std::string& psk, DppNetRole net_role, DppAkm security_akm,
+		const std::vector<uint8_t> &privEcKey)
+{
+#ifdef CONFIG_DPP
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	std::string cmd = "";
+
+	if (net_role != DppNetRole::AP &&
+			net_role != DppNetRole::STA) {
+		wpa_printf(MSG_ERROR,
+			   "DPP: Error: Invalid network role specified: %d", net_role);
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+
+	cmd += " peer=" + std::to_string(peer_bootstrap_id);
+	cmd += (own_bootstrap_id > 0) ?
+			" own=" + std::to_string(own_bootstrap_id) : "";
+
+	/* Check for supported AKMs */
+	if (security_akm != DppAkm::PSK && security_akm != DppAkm::SAE &&
+			security_akm != DppAkm::PSK_SAE && security_akm != DppAkm::DPP) {
+		wpa_printf(MSG_ERROR, "DPP: Error: invalid AKM specified: %d",
+				security_akm);
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+
+	/* SAE AKM requires SSID and password to be initialized */
+	if ((security_akm == DppAkm::SAE ||
+			security_akm == DppAkm::PSK_SAE) &&
+			(ssid.empty() || password.empty())) {
+		wpa_printf(MSG_ERROR, "DPP: Error: Password or SSID not specified");
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	} else if (security_akm == DppAkm::PSK ||
+			security_akm == DppAkm::PSK_SAE) {
+		/* PSK AKM requires SSID and password/psk to be initialized */
+		if (ssid.empty()) {
+			wpa_printf(MSG_ERROR, "DPP: Error: SSID not specified");
+			return {std::vector<uint8_t>(),
+				createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+		}
+		if (password.empty() && psk.empty()) {
+			wpa_printf(MSG_ERROR, "DPP: Error: Password or PSK not specified");
+			return {std::vector<uint8_t>(),
+				createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+		}
+	}
+
+	cmd += " role=configurator";
+	cmd += (ssid.empty()) ? "" : " ssid=" + ssid;
+
+	if (!psk.empty()) {
+		cmd += " psk=" + psk;
+	} else {
+		cmd += (password.empty()) ? "" : " pass=" + password;
+	}
+
+	std::string role = "";
+	if (net_role == DppNetRole::AP) {
+		role = "ap-";
+	}
+	else {
+		role = "sta-";
+	}
+
+	switch (security_akm) {
+	case DppAkm::PSK:
+		role += "psk";
+		break;
+
+	case DppAkm::SAE:
+		role += "sae";
+		break;
+
+	case DppAkm::PSK_SAE:
+		role += "psk-sae";
+		break;
+
+	// TODO add code to handle DPP AKM
+	case DppAkm::DPP:
+	default:
+		wpa_printf(MSG_ERROR,
+			   "DPP: Invalid or unsupported security AKM specified: %d", security_akm);
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+
+	cmd += " conf=";
+	cmd += role;
+
+	if (net_role == DppNetRole::STA) {
+		/* DPP R2 connection status request */
+		cmd += " conn_status=1";
+	}
+
+	wpa_printf(MSG_DEBUG,
+		   "DPP initiator command: %s", cmd.c_str());
+
+	if (wpas_dpp_auth_init(wpa_s, cmd.c_str()) == 0) {
+		return {std::vector<uint8_t>(), ndk::ScopedAStatus::ok()};
+	}
+#endif
+	return {std::vector<uint8_t>(), createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+}
+
+ndk::ScopedAStatus StaIface::startDppEnrolleeInitiatorInternal(
+	uint32_t peer_bootstrap_id, uint32_t own_bootstrap_id) {
+#ifdef CONFIG_DPP
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	std::string cmd = "";
+
+	/* Report received configuration to AIDL and create an internal profile */
+	wpa_s->conf->dpp_config_processing = 1;
+
+	cmd += " peer=" + std::to_string(peer_bootstrap_id);
+	cmd += (own_bootstrap_id > 0) ?
+			" own=" + std::to_string(own_bootstrap_id) : "";
+
+	cmd += " role=enrollee";
+
+	wpa_printf(MSG_DEBUG,
+		   "DPP initiator command: %s", cmd.c_str());
+
+	if (wpas_dpp_auth_init(wpa_s, cmd.c_str()) == 0) {
+		return ndk::ScopedAStatus::ok();
+	}
+#endif
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+}
+ndk::ScopedAStatus StaIface::stopDppInitiatorInternal()
+{
+#ifdef CONFIG_DPP
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+
+	wpas_dpp_stop(wpa_s);
+	return ndk::ScopedAStatus::ok();
+#else
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+#endif
+}
+
+std::pair<DppResponderBootstrapInfo, ndk::ScopedAStatus>
+StaIface::generateDppBootstrapInfoForResponderInternal(
+	const std::vector<uint8_t> &mac_address, 
+	const std::string& device_info, DppCurve curve)
+{
+#ifdef CONFIG_DPP
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	std::string cmd = "type=qrcode";
+	int32_t id;
+	int32_t listen_channel = 0;
+	DppResponderBootstrapInfo bootstrap_info;
+	const char *uri;
+	std::string listen_channel_str;
+	std::string mac_addr_str;
+	char buf[3] = {0};
+
+	cmd += (device_info.empty()) ? "" : " info=" + device_info;
+
+	listen_channel_str = getDppListenChannel(wpa_s, &listen_channel);
+	if (listen_channel == 0) {
+		wpa_printf(MSG_ERROR, "StaIface: Failed to derive DPP listen channel");
+		return {bootstrap_info, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	cmd += " chan=" + listen_channel_str;
+
+	cmd += " mac=";
+	for (int i = 0;i < 6;i++) {
+		snprintf(buf, sizeof(buf), "%02x", mac_address[i]);
+		mac_addr_str.append(buf);
+	}
+	cmd += mac_addr_str;
+
+	cmd += " curve=" + convertCurveTypeToName(curve);
+
+	id = dpp_bootstrap_gen(wpa_s->dpp, cmd.c_str());
+	wpa_printf(MSG_DEBUG,
+		   "DPP generate bootstrap QR code command: %s id: %d", cmd.c_str(), id);
+	if (id > 0) {
+		uri = dpp_bootstrap_get_uri(wpa_s->dpp, id);
+		if (uri) {
+			wpa_printf(MSG_DEBUG, "DPP Bootstrap info: id: %d "
+				   "listen_channel: %d uri: %s", id, listen_channel, uri);
+			bootstrap_info.bootstrapId = id;
+			bootstrap_info.listenChannel = listen_channel;
+			bootstrap_info.uri = uri;
+			return {bootstrap_info, ndk::ScopedAStatus::ok()};
+		}
+	}
+	return {bootstrap_info, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+#else
+	return {bootstrap_info, createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED)};
+#endif
+}
+
+ndk::ScopedAStatus StaIface::startDppEnrolleeResponderInternal(uint32_t listen_channel)
+{
+#ifdef CONFIG_DPP
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	std::string cmd = "";
+	uint32_t freq = (listen_channel <= 14 ? 2407 : 5000) + listen_channel * 5;
+
+	/* Report received configuration to AIDL and create an internal profile */
+	wpa_s->conf->dpp_config_processing = 1;
+
+	cmd += std::to_string(freq);
+	cmd += " role=enrollee netrole=sta";
+
+	wpa_printf(MSG_DEBUG,
+		   "DPP Enrollee Responder command: %s", cmd.c_str());
+
+	if (wpas_dpp_listen(wpa_s, cmd.c_str()) == 0) {
+		return ndk::ScopedAStatus::ok();
+	}
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+#else
+	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+#endif
+}
+
+ndk::ScopedAStatus StaIface::stopDppResponderInternal(uint32_t own_bootstrap_id)
+{
+#ifdef CONFIG_DPP
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	std::string bootstrap_id_str;
+
+	if (own_bootstrap_id == 0) {
+		bootstrap_id_str = "*";
+	}
+	else {
+		bootstrap_id_str = std::to_string(own_bootstrap_id);
+	}
+
+	wpa_printf(MSG_DEBUG, "DPP Stop DPP Responder id: %d ", own_bootstrap_id);
+	wpas_dpp_stop(wpa_s);
+	wpas_dpp_listen_stop(wpa_s);
+
+	if (dpp_bootstrap_remove(wpa_s->dpp, bootstrap_id_str.c_str()) < 0) {
+		wpa_printf(MSG_ERROR, "StaIface: dpp_bootstrap_remove failed");
+	}
+
+	return ndk::ScopedAStatus::ok();
+#else
+	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+#endif
+}
+
+ndk::ScopedAStatus StaIface::generateSelfDppConfigurationInternal(const std::string& ssid,
+		const std::vector<uint8_t> &privEcKey)
+{
+#ifdef CONFIG_DPP
+    // TODO Implement this function
+    return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+#else
+	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+#endif
+}
+
+std::pair<ConnectionCapabilities, ndk::ScopedAStatus>
+StaIface::getConnectionCapabilitiesInternal()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	ConnectionCapabilities capa;
+
+	if (wpa_s->connection_set) {
+		capa.legacyMode = LegacyMode::UNKNOWN;
+		if (wpa_s->connection_he) {
+			capa.technology = WifiTechnology::HE;
+		} else if (wpa_s->connection_vht) {
+			capa.technology = WifiTechnology::VHT;
+		} else if (wpa_s->connection_ht) {
+			capa.technology = WifiTechnology::HT;
+		} else {
+			capa.technology = WifiTechnology::LEGACY;
+			if (wpas_freq_to_band(wpa_s->assoc_freq) == BAND_2_4_GHZ) {
+				capa.legacyMode = (wpa_s->connection_11b_only) ? LegacyMode::B_MODE
+						: LegacyMode::G_MODE; 
+			} else {
+				capa.legacyMode = LegacyMode::A_MODE;
+			}
+		}
+		switch (wpa_s->connection_channel_bandwidth) {
+		case CHAN_WIDTH_20:
+			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
+			break;
+		case CHAN_WIDTH_40:
+			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_40;
+			break;
+		case CHAN_WIDTH_80:
+			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_80;
+			break;
+		case CHAN_WIDTH_160:
+			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_160;
+			break;
+		case CHAN_WIDTH_80P80:
+			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_80P80;
+			break;
+		default:
+			capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
+			break;
+		}
+		capa.maxNumberRxSpatialStreams = wpa_s->connection_max_nss_rx;
+		capa.maxNumberTxSpatialStreams = wpa_s->connection_max_nss_tx;
+	} else {
+		capa.technology = WifiTechnology::UNKNOWN;
+		capa.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
+		capa.maxNumberTxSpatialStreams = 1;
+		capa.maxNumberRxSpatialStreams = 1;
+		capa.legacyMode = LegacyMode::UNKNOWN;
+	}
+	return {capa, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<WpaDriverCapabilitiesMask, ndk::ScopedAStatus>
+StaIface::getWpaDriverCapabilitiesInternal()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	uint32_t mask = 0;
+
+#ifdef CONFIG_MBO
+	/* MBO has no capability flags. It's mainly legacy 802.11v BSS
+	 * transition + Cellular steering. 11v is a default feature in
+	 * supplicant. And cellular steering is handled in framework.
+	 */
+	mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::MBO);
+	if (wpa_s->enable_oce & OCE_STA) {
+		mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::OCE);
+	}
+#endif
+#ifdef CONFIG_SAE_PK
+	mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::SAE_PK);
+#endif
+	mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::WFD_R2);
+
+	mask |= static_cast<uint32_t>(WpaDriverCapabilitiesMask::TRUST_ON_FIRST_USE);
+
+	wpa_printf(MSG_DEBUG, "Driver capability mask: 0x%x", mask);
+
+	return {static_cast<WpaDriverCapabilitiesMask>(mask),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaIface::setMboCellularDataStatusInternal(bool available)
+{
+#ifdef CONFIG_MBO
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	enum mbo_cellular_capa mbo_cell_capa;
+
+	if (available) {
+		mbo_cell_capa = MBO_CELL_CAPA_AVAILABLE;
+	} else {
+		mbo_cell_capa = MBO_CELL_CAPA_NOT_AVAILABLE;
+	}
+
+#ifdef ENABLE_PRIV_CMD_UPDATE_MBO_CELL_STATUS
+	char mbo_cmd[32];
+	char buf[32];
+
+	os_snprintf(mbo_cmd, sizeof(mbo_cmd), "%s %d", "MBO CELL_DATA_CAP", mbo_cell_capa);
+	if (wpa_drv_driver_cmd(wpa_s, mbo_cmd, buf, sizeof(buf)) < 0) {
+		wpa_printf(MSG_ERROR, "MBO CELL_DATA_CAP cmd failed CAP:%d", mbo_cell_capa);
+	}
+#else
+	wpas_mbo_update_cell_capa(wpa_s, mbo_cell_capa);
+#endif
+
+	return ndk::ScopedAStatus::ok();
+#else
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+#endif
+}
+
+std::pair<KeyMgmtMask, ndk::ScopedAStatus>
+StaIface::getKeyMgmtCapabilitiesInternal()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	struct wpa_driver_capa capa;
+
+	/* Get capabilities from driver and populate the key management mask */
+	if (wpa_drv_get_capa(wpa_s, &capa) < 0) {
+		return {static_cast<KeyMgmtMask>(0),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+
+	return {convertWpaKeyMgmtCapabilitiesToAidl(wpa_s, &capa),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaIface::setQosPolicyFeatureEnabledInternal(bool enable)
+{
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::sendQosPolicyResponseInternal(
+	bool more_policies, const std::vector<QosPolicyStatus>& qos_policy_status_list)
+{
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaIface::removeAllQosPoliciesInternal()
+{
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<MloLinksInfo, ndk::ScopedAStatus> StaIface::getConnectionMloLinksInfoInternal()
+{
+	MloLinksInfo linksInfo;
+	return {linksInfo, ndk::ScopedAStatus::ok()};
+}
+
+/**
+ * Retrieve the underlying |wpa_supplicant| struct
+ * pointer for this iface.
+ * If the underlying iface is removed, then all RPC method calls on this object
+ * will return failure.
+ */
+wpa_supplicant *StaIface::retrieveIfacePtr()
+{
+	return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
+}
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wpa_supplicant/aidl/sta_iface.h b/wpa_supplicant/aidl/sta_iface.h
new file mode 100644
index 0000000..44e3ef5
--- /dev/null
+++ b/wpa_supplicant/aidl/sta_iface.h
@@ -0,0 +1,280 @@
+/*
+ * WPA Supplicant - Sta Iface Aidl interface
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef WPA_SUPPLICANT_AIDL_STA_IFACE_H
+#define WPA_SUPPLICANT_AIDL_STA_IFACE_H
+
+#include <array>
+#include <vector>
+
+#include <android-base/macros.h>
+
+#include <aidl/android/hardware/wifi/supplicant/AnqpInfoId.h>
+#include <aidl/android/hardware/wifi/supplicant/BnSupplicantStaIface.h>
+#include <aidl/android/hardware/wifi/supplicant/BtCoexistenceMode.h>
+#include <aidl/android/hardware/wifi/supplicant/Hs20AnqpSubtypes.h>
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantStaIfaceCallback.h>
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantStaNetwork.h>
+#include <aidl/android/hardware/wifi/supplicant/MloLinksInfo.h>
+#include <aidl/android/hardware/wifi/supplicant/QosPolicyStatus.h>
+#include <aidl/android/hardware/wifi/supplicant/RxFilterType.h>
+
+extern "C"
+{
+#include "utils/common.h"
+#include "utils/includes.h"
+#include "wpa_supplicant_i.h"
+#include "config.h"
+#include "driver_i.h"
+#include "wpa.h"
+}
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+
+/**
+ * Implementation of StaIface aidl object. Each unique aidl
+ * object is used for control operations on a specific interface
+ * controlled by wpa_supplicant.
+ */
+class StaIface : public BnSupplicantStaIface
+{
+public:
+	StaIface(struct wpa_global* wpa_global, const char ifname[]);
+	~StaIface() override = default;
+	// AIDL does not provide a built-in mechanism to let the server
+	// invalidate a AIDL interface object after creation. If any client
+	// process holds onto a reference to the object in their context,
+	// any method calls on that reference will continue to be directed to
+	// the server.
+	// However Supplicant HAL needs to control the lifetime of these
+	// objects. So, add a public |invalidate| method to all |Iface| and
+	// |Network| objects.
+	// This will be used to mark an object invalid when the corresponding
+	// iface or network is removed.
+	// All AIDL method implementations should check if the object is still
+	// marked valid before processing them.
+	void invalidate();
+	bool isValid();
+
+	// Aidl methods exposed.
+  	::ndk::ScopedAStatus getName(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getType(IfaceType* _aidl_return) override;
+	::ndk::ScopedAStatus addNetwork(
+		std::shared_ptr<ISupplicantStaNetwork>* _aidl_return) override;
+	::ndk::ScopedAStatus removeNetwork(int32_t in_id) override;
+	::ndk::ScopedAStatus filsHlpFlushRequest() override;
+	::ndk::ScopedAStatus filsHlpAddRequest(
+		const std::vector<uint8_t>& in_dst_mac,
+		const std::vector<uint8_t>& in_pkt) override;
+	::ndk::ScopedAStatus getNetwork(
+		int32_t in_id, std::shared_ptr<ISupplicantStaNetwork>* _aidl_return) override;
+	::ndk::ScopedAStatus listNetworks(std::vector<int32_t>* _aidl_return) override;
+	::ndk::ScopedAStatus registerCallback(
+		const std::shared_ptr<ISupplicantStaIfaceCallback>& in_callback) override;
+	::ndk::ScopedAStatus reassociate() override;
+	::ndk::ScopedAStatus reconnect() override;
+	::ndk::ScopedAStatus disconnect() override;
+	::ndk::ScopedAStatus setPowerSave(bool in_enable) override;
+	::ndk::ScopedAStatus initiateTdlsDiscover(
+		const std::vector<uint8_t>& in_macAddress) override;
+	::ndk::ScopedAStatus initiateTdlsSetup(
+		const std::vector<uint8_t>& in_macAddress) override;
+	::ndk::ScopedAStatus initiateTdlsTeardown(
+		const std::vector<uint8_t>& in_macAddress) override;
+	::ndk::ScopedAStatus initiateAnqpQuery(
+		const std::vector<uint8_t>& in_macAddress,
+		const std::vector<AnqpInfoId>& in_infoElements,
+		const std::vector<Hs20AnqpSubtypes>& in_subTypes) override;
+	::ndk::ScopedAStatus initiateVenueUrlAnqpQuery(
+		const std::vector<uint8_t>& in_macAddress) override;
+	::ndk::ScopedAStatus initiateHs20IconQuery(
+		const std::vector<uint8_t>& in_macAddress, const std::string& in_fileName) override;
+	::ndk::ScopedAStatus getMacAddress(std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus startRxFilter() override;
+	::ndk::ScopedAStatus stopRxFilter() override;
+	::ndk::ScopedAStatus addRxFilter(RxFilterType in_type) override;
+	::ndk::ScopedAStatus removeRxFilter(RxFilterType in_type) override;
+	::ndk::ScopedAStatus setBtCoexistenceMode(BtCoexistenceMode in_mode) override;
+	::ndk::ScopedAStatus setBtCoexistenceScanModeEnabled(bool in_enable) override;
+	::ndk::ScopedAStatus setSuspendModeEnabled(bool in_enable) override;
+	::ndk::ScopedAStatus setCountryCode(const std::vector<uint8_t>& in_code) override;
+	::ndk::ScopedAStatus startWpsRegistrar(
+		const std::vector<uint8_t>& in_bssid, const std::string& in_pin) override;
+	::ndk::ScopedAStatus startWpsPbc(const std::vector<uint8_t>& in_bssid) override;
+	::ndk::ScopedAStatus startWpsPinDisplay(
+		const std::vector<uint8_t>& in_bssid, std::string* _aidl_return) override;
+	::ndk::ScopedAStatus startWpsPinKeypad(const std::string& in_pin) override;
+	::ndk::ScopedAStatus cancelWps() override;
+	::ndk::ScopedAStatus setWpsDeviceName(const std::string& in_name) override;
+	::ndk::ScopedAStatus setWpsDeviceType(const std::vector<uint8_t>& in_type) override;
+	::ndk::ScopedAStatus setWpsManufacturer(const std::string& in_manufacturer) override;
+	::ndk::ScopedAStatus setWpsModelName(const std::string& in_modelName) override;
+	::ndk::ScopedAStatus setWpsModelNumber(const std::string& in_modelNumber) override;
+	::ndk::ScopedAStatus setWpsSerialNumber(const std::string& in_serialNumber) override;
+	::ndk::ScopedAStatus setWpsConfigMethods(WpsConfigMethods in_configMethods) override;
+	::ndk::ScopedAStatus setExternalSim(bool in_useExternalSim) override;
+	::ndk::ScopedAStatus addExtRadioWork(
+		const std::string& in_name, int32_t in_freqInMhz,
+		int32_t in_timeoutInSec, int32_t* _aidl_return) override;
+	::ndk::ScopedAStatus removeExtRadioWork(int32_t in_id) override;
+	::ndk::ScopedAStatus enableAutoReconnect(bool in_enable) override;
+	::ndk::ScopedAStatus getKeyMgmtCapabilities(KeyMgmtMask* _aidl_return) override;
+	::ndk::ScopedAStatus addDppPeerUri(
+		const std::string& in_uri, int32_t* _aidl_return) override;
+	::ndk::ScopedAStatus removeDppUri(int32_t in_id) override;
+	::ndk::ScopedAStatus startDppConfiguratorInitiator(
+		int32_t in_peerBootstrapId, int32_t in_ownBootstrapId,
+		const std::string& in_ssid, const std::string& in_password,
+		const std::string& in_psk, DppNetRole in_netRole, DppAkm in_securityAkm,
+		const std::vector<uint8_t>& in_privEcKey,
+		std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus startDppEnrolleeInitiator(
+		int32_t in_peerBootstrapId, int32_t in_ownBootstrapId) override;
+	::ndk::ScopedAStatus stopDppInitiator() override;
+	::ndk::ScopedAStatus getConnectionCapabilities(ConnectionCapabilities* _aidl_return) override;
+	::ndk::ScopedAStatus getWpaDriverCapabilities(WpaDriverCapabilitiesMask* _aidl_return) override;
+	::ndk::ScopedAStatus setMboCellularDataStatus(bool in_available) override;
+	::ndk::ScopedAStatus generateDppBootstrapInfoForResponder(
+		const std::vector<uint8_t>& in_macAddress,
+		const std::string& in_deviceInfo, DppCurve in_curve,
+		DppResponderBootstrapInfo* _aidl_return) override;
+	::ndk::ScopedAStatus startDppEnrolleeResponder(int32_t in_listenChannel) override;
+	::ndk::ScopedAStatus stopDppResponder(int32_t in_ownBootstrapId) override;
+	::ndk::ScopedAStatus generateSelfDppConfiguration(
+		const std::string& in_ssid, const std::vector<uint8_t>& in_privEcKey) override;
+	::ndk::ScopedAStatus setQosPolicyFeatureEnabled(bool in_enable) override;
+	::ndk::ScopedAStatus sendQosPolicyResponse(
+		bool in_morePolicies, const std::vector<QosPolicyStatus>& in_qosPolicyStatusList) override;
+	::ndk::ScopedAStatus removeAllQosPolicies() override;
+	::ndk::ScopedAStatus getConnectionMloLinksInfo(MloLinksInfo* _aidl_return) override;
+
+private:
+	// Corresponding worker functions for the AIDL methods.
+	std::pair<std::string, ndk::ScopedAStatus> getNameInternal();
+	std::pair<IfaceType, ndk::ScopedAStatus> getTypeInternal();
+	std::pair<std::shared_ptr<ISupplicantStaNetwork>, ndk::ScopedAStatus>
+		addNetworkInternal();
+	ndk::ScopedAStatus filsHlpFlushRequestInternal();
+	ndk::ScopedAStatus filsHlpAddRequestInternal(
+		const std::vector<uint8_t>& dst_mac,
+		const std::vector<uint8_t>& pkt);
+	ndk::ScopedAStatus removeNetworkInternal(int32_t id);
+	std::pair<std::shared_ptr<ISupplicantStaNetwork>, ndk::ScopedAStatus>
+		getNetworkInternal(int32_t id);
+	std::pair<std::vector<int32_t>, ndk::ScopedAStatus>
+		listNetworksInternal();
+	ndk::ScopedAStatus registerCallbackInternal(
+		const std::shared_ptr<ISupplicantStaIfaceCallback>& callback);
+	ndk::ScopedAStatus reassociateInternal();
+	ndk::ScopedAStatus reconnectInternal();
+	ndk::ScopedAStatus disconnectInternal();
+	ndk::ScopedAStatus setPowerSaveInternal(bool enable);
+	ndk::ScopedAStatus initiateTdlsDiscoverInternal(
+		const std::vector<uint8_t>& mac_address);
+	ndk::ScopedAStatus initiateTdlsSetupInternal(
+		const std::vector<uint8_t>& mac_address);
+	ndk::ScopedAStatus initiateTdlsTeardownInternal(
+		const std::vector<uint8_t>& mac_address);
+	ndk::ScopedAStatus initiateAnqpQueryInternal(
+		const std::vector<uint8_t>& mac_address,
+		const std::vector<AnqpInfoId>& info_elements,
+		const std::vector<Hs20AnqpSubtypes>&
+		sub_types);
+	ndk::ScopedAStatus initiateVenueUrlAnqpQueryInternal(
+		const std::vector<uint8_t>& mac_address);
+	ndk::ScopedAStatus initiateHs20IconQueryInternal(
+		const std::vector<uint8_t>& mac_address,
+		const std::string& file_name);
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+		getMacAddressInternal();
+	ndk::ScopedAStatus startRxFilterInternal();
+	ndk::ScopedAStatus stopRxFilterInternal();
+	ndk::ScopedAStatus addRxFilterInternal(
+		RxFilterType type);
+	ndk::ScopedAStatus removeRxFilterInternal(
+		RxFilterType type);
+	ndk::ScopedAStatus setBtCoexistenceModeInternal(
+		BtCoexistenceMode mode);
+	ndk::ScopedAStatus setBtCoexistenceScanModeEnabledInternal(bool enable);
+	ndk::ScopedAStatus setSuspendModeEnabledInternal(bool enable);
+	ndk::ScopedAStatus setCountryCodeInternal(
+		const std::vector<uint8_t>& code);
+	ndk::ScopedAStatus startWpsRegistrarInternal(
+		const std::vector<uint8_t>& bssid, const std::string& pin);
+	ndk::ScopedAStatus startWpsPbcInternal(
+		const std::vector<uint8_t>& bssid);
+	ndk::ScopedAStatus startWpsPinKeypadInternal(const std::string& pin);
+	std::pair<std::string, ndk::ScopedAStatus> startWpsPinDisplayInternal(
+		const std::vector<uint8_t>& bssid);
+	ndk::ScopedAStatus cancelWpsInternal();
+	ndk::ScopedAStatus setWpsDeviceNameInternal(const std::string& name);
+	ndk::ScopedAStatus setWpsDeviceTypeInternal(
+		const std::vector<uint8_t>& type);
+	ndk::ScopedAStatus setWpsManufacturerInternal(
+		const std::string& manufacturer);
+	ndk::ScopedAStatus setWpsModelNameInternal(const std::string& model_name);
+	ndk::ScopedAStatus setWpsModelNumberInternal(
+		const std::string& model_number);
+	ndk::ScopedAStatus setWpsSerialNumberInternal(
+		const std::string& serial_number);
+	ndk::ScopedAStatus setWpsConfigMethodsInternal(WpsConfigMethods config_methods);
+	ndk::ScopedAStatus setExternalSimInternal(bool useExternalSim);
+	std::pair<uint32_t, ndk::ScopedAStatus> addExtRadioWorkInternal(
+		const std::string& name, uint32_t freq_in_mhz,
+		uint32_t timeout_in_sec);
+	ndk::ScopedAStatus removeExtRadioWorkInternal(uint32_t id);
+	ndk::ScopedAStatus enableAutoReconnectInternal(bool enable);
+	std::pair<KeyMgmtMask, ndk::ScopedAStatus> getKeyMgmtCapabilitiesInternal();
+	std::pair<uint32_t, ndk::ScopedAStatus> addDppPeerUriInternal(const std::string& uri);
+	ndk::ScopedAStatus removeDppUriInternal(uint32_t bootstrap_id);
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> startDppConfiguratorInitiatorInternal(
+		uint32_t peer_bootstrap_id, uint32_t own_bootstrap_id, const std::string& ssid,
+		const std::string& password, const std::string& psk, DppNetRole net_role,
+		DppAkm security_akm, const std::vector<uint8_t> &privEcKey);
+	ndk::ScopedAStatus startDppEnrolleeInitiatorInternal(uint32_t peer_bootstrap_id,
+			uint32_t own_bootstrap_id);
+	ndk::ScopedAStatus stopDppInitiatorInternal();
+	std::pair<ConnectionCapabilities, ndk::ScopedAStatus> getConnectionCapabilitiesInternal();
+	std::pair<WpaDriverCapabilitiesMask, ndk::ScopedAStatus> getWpaDriverCapabilitiesInternal();
+	ndk::ScopedAStatus setMboCellularDataStatusInternal(bool available);
+	std::pair<DppResponderBootstrapInfo, ndk::ScopedAStatus>
+			generateDppBootstrapInfoForResponderInternal(
+			const std::vector<uint8_t>& mac_address, const std::string& device_info,
+			DppCurve curve);
+	ndk::ScopedAStatus startDppEnrolleeResponderInternal(uint32_t listen_channel);
+	ndk::ScopedAStatus stopDppResponderInternal(uint32_t own_bootstrap_id);
+	ndk::ScopedAStatus generateSelfDppConfigurationInternal(
+		const std::string& ssid, const std::vector<uint8_t> &privEcKey);
+	ndk::ScopedAStatus setQosPolicyFeatureEnabledInternal(bool enable);
+	ndk::ScopedAStatus sendQosPolicyResponseInternal(
+		bool more_policies, const std::vector<QosPolicyStatus>& qos_policy_status_list);
+	ndk::ScopedAStatus removeAllQosPoliciesInternal();
+	std::pair<MloLinksInfo, ndk::ScopedAStatus> getConnectionMloLinksInfoInternal();
+	struct wpa_supplicant* retrieveIfacePtr();
+
+	// Reference to the global wpa_struct. This is assumed to be valid for
+	// the lifetime of the process.
+	struct wpa_global* wpa_global_;
+	// Name of the iface this aidl object controls
+	const std::string ifname_;
+	bool is_valid_;
+
+	DISALLOW_COPY_AND_ASSIGN(StaIface);
+};
+
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WPA_SUPPLICANT_AIDL_STA_IFACE_H
diff --git a/wpa_supplicant/aidl/sta_network.cpp b/wpa_supplicant/aidl/sta_network.cpp
new file mode 100644
index 0000000..da5decd
--- /dev/null
+++ b/wpa_supplicant/aidl/sta_network.cpp
@@ -0,0 +1,2515 @@
+/*
+ * WPA Supplicant - Sta network Aidl interface
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "aidl_manager.h"
+#include "aidl_return_util.h"
+#include "misc_utils.h"
+#include "sta_network.h"
+
+extern "C"
+{
+#include "wps_supplicant.h"
+}
+
+namespace {
+using aidl::android::hardware::wifi::supplicant::AuthAlgMask;
+using aidl::android::hardware::wifi::supplicant::EapMethod;
+using aidl::android::hardware::wifi::supplicant::EapPhase2Method;
+using aidl::android::hardware::wifi::supplicant::GroupCipherMask;
+using aidl::android::hardware::wifi::supplicant::GroupMgmtCipherMask;
+using aidl::android::hardware::wifi::supplicant::ISupplicantStaNetwork;
+using aidl::android::hardware::wifi::supplicant::KeyMgmtMask;
+using aidl::android::hardware::wifi::supplicant::PairwiseCipherMask;
+using aidl::android::hardware::wifi::supplicant::ProtoMask;
+
+constexpr uint8_t kZeroBssid[6] = {0, 0, 0, 0, 0, 0};
+
+constexpr uint32_t kAllowedKeyMgmtMask =
+	(static_cast<uint32_t>(KeyMgmtMask::NONE) |
+	 static_cast<uint32_t>(KeyMgmtMask::WPA_PSK) |
+	 static_cast<uint32_t>(KeyMgmtMask::WPA_EAP) |
+	 static_cast<uint32_t>(KeyMgmtMask::IEEE8021X) |
+	 static_cast<uint32_t>(KeyMgmtMask::FT_EAP) |
+	 static_cast<uint32_t>(KeyMgmtMask::FT_PSK) |
+	 static_cast<uint32_t>(KeyMgmtMask::OSEN) |
+	 static_cast<uint32_t>(KeyMgmtMask::SAE) |
+	 static_cast<uint32_t>(KeyMgmtMask::SUITE_B_192) |
+	 static_cast<uint32_t>(KeyMgmtMask::OWE) |
+	 static_cast<uint32_t>(KeyMgmtMask::WPA_PSK_SHA256) |
+	 static_cast<uint32_t>(KeyMgmtMask::WPA_EAP_SHA256) |
+	 static_cast<uint32_t>(KeyMgmtMask::WAPI_PSK) |
+	 static_cast<uint32_t>(KeyMgmtMask::WAPI_CERT) |
+	 static_cast<uint32_t>(KeyMgmtMask::FILS_SHA256) |
+	 static_cast<uint32_t>(KeyMgmtMask::FILS_SHA384));
+constexpr uint32_t kAllowedProtoMask =
+	(static_cast<uint32_t>(ProtoMask::WPA) |
+	 static_cast<uint32_t>(ProtoMask::RSN) |
+	 static_cast<uint32_t>(ProtoMask::OSEN) |
+	 static_cast<uint32_t>(ProtoMask::WAPI));
+constexpr uint32_t kAllowedAuthAlgMask =
+	(static_cast<uint32_t>(AuthAlgMask::OPEN) |
+	 static_cast<uint32_t>(AuthAlgMask::SHARED) |
+	 static_cast<uint32_t>(AuthAlgMask::LEAP) |
+	 static_cast<uint32_t>(AuthAlgMask::SAE));
+constexpr uint32_t kAllowedGroupCipherMask =
+	(static_cast<uint32_t>(GroupCipherMask::WEP40) |
+	 static_cast<uint32_t>(GroupCipherMask::WEP104) |
+	 static_cast<uint32_t>(GroupCipherMask::TKIP) |
+	 static_cast<uint32_t>(GroupCipherMask::CCMP) |
+	 static_cast<uint32_t>(
+	 GroupCipherMask::GTK_NOT_USED) |
+	 static_cast<uint32_t>(GroupCipherMask::GCMP_256) |
+	 static_cast<uint32_t>(GroupCipherMask::SMS4) |
+	 static_cast<uint32_t>(GroupCipherMask::GCMP_128));
+constexpr uint32_t kAllowedPairwisewCipherMask =
+	(static_cast<uint32_t>(PairwiseCipherMask::NONE) |
+	 static_cast<uint32_t>(PairwiseCipherMask::TKIP) |
+	 static_cast<uint32_t>(PairwiseCipherMask::CCMP) |
+	 static_cast<uint32_t>(
+	 PairwiseCipherMask::GCMP_256) |
+	 static_cast<uint32_t>(
+	 PairwiseCipherMask::SMS4) |
+	 static_cast<uint32_t>(PairwiseCipherMask::GCMP_128));
+constexpr uint32_t kAllowedGroupMgmtCipherMask =
+	(static_cast<uint32_t>(
+			GroupMgmtCipherMask::BIP_GMAC_128) |
+	 static_cast<uint32_t>(
+			 GroupMgmtCipherMask::BIP_GMAC_256) |
+	 static_cast<uint32_t>(
+			 GroupMgmtCipherMask::BIP_CMAC_256));
+
+constexpr uint32_t kEapMethodMax =
+	static_cast<uint32_t>(EapMethod::WFA_UNAUTH_TLS) + 1;
+constexpr char const *kEapMethodStrings[kEapMethodMax] = {
+	"PEAP", "TLS", "TTLS", "PWD", "SIM", "AKA", "AKA'", "WFA-UNAUTH-TLS"};
+constexpr uint32_t kEapPhase2MethodMax =
+	static_cast<uint32_t>(EapPhase2Method::AKA_PRIME) + 1;
+constexpr char const *kEapPhase2MethodStrings[kEapPhase2MethodMax] = {
+	"", "PAP", "MSCHAP", "MSCHAPV2", "GTC", "SIM", "AKA", "AKA'"};
+constexpr char kEapPhase2AuthPrefix[] = "auth=";
+constexpr char kEapPhase2AuthEapPrefix[] = "autheap=";
+constexpr char kNetworkEapSimGsmAuthResponse[] = "GSM-AUTH";
+constexpr char kNetworkEapSimUmtsAuthResponse[] = "UMTS-AUTH";
+constexpr char kNetworkEapSimUmtsAutsResponse[] = "UMTS-AUTS";
+constexpr char kNetworkEapSimGsmAuthFailure[] = "GSM-FAIL";
+constexpr char kNetworkEapSimUmtsAuthFailure[] = "UMTS-FAIL";
+
+#ifdef CONFIG_WAPI_INTERFACE
+std::string dummyWapiCertSuite;
+std::vector<uint8_t> dummyWapiPsk;
+#endif /* CONFIG_WAPI_INTERFACE */
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+using aidl_return_util::validateAndCall;
+using misc_utils::createStatus;
+using misc_utils::createStatusWithMsg;
+
+StaNetwork::StaNetwork(
+	struct wpa_global *wpa_global, const char ifname[], int network_id)
+	: wpa_global_(wpa_global),
+	  ifname_(ifname),
+	  network_id_(network_id),
+	  is_valid_(true)
+{}
+
+void StaNetwork::invalidate() { is_valid_ = false; }
+bool StaNetwork::isValid()
+{
+	return (is_valid_ && (retrieveNetworkPtr() != nullptr));
+}
+
+::ndk::ScopedAStatus StaNetwork::getId(
+	int32_t* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getIdInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getInterfaceName(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getInterfaceNameInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getType(
+	IfaceType* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getTypeInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::registerCallback(
+	const std::shared_ptr<ISupplicantStaNetworkCallback>& in_callback)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::registerCallbackInternal, in_callback);
+}
+
+::ndk::ScopedAStatus StaNetwork::setSsid(
+	const std::vector<uint8_t>& in_ssid)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setSsidInternal, in_ssid);
+}
+
+::ndk::ScopedAStatus StaNetwork::setBssid(
+	const std::vector<uint8_t>& in_bssid)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setBssidInternal, in_bssid);
+}
+
+::ndk::ScopedAStatus StaNetwork::setDppKeys(const DppConnectionKeys& in_keys)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setDppKeysInternal, in_keys);
+}
+
+::ndk::ScopedAStatus StaNetwork::setScanSsid(bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setScanSsidInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaNetwork::setKeyMgmt(
+	KeyMgmtMask in_keyMgmtMask)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setKeyMgmtInternal, in_keyMgmtMask);
+}
+
+::ndk::ScopedAStatus StaNetwork::setProto(
+	ProtoMask in_protoMask)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setProtoInternal, in_protoMask);
+}
+
+::ndk::ScopedAStatus StaNetwork::setAuthAlg(
+	AuthAlgMask in_authAlgMask)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setAuthAlgInternal, in_authAlgMask);
+}
+
+::ndk::ScopedAStatus StaNetwork::setGroupCipher(
+	GroupCipherMask in_groupCipherMask)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setGroupCipherInternal, in_groupCipherMask);
+}
+
+::ndk::ScopedAStatus StaNetwork::setPairwiseCipher(
+	PairwiseCipherMask in_pairwiseCipherMask)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setPairwiseCipherInternal,
+		in_pairwiseCipherMask);
+}
+
+::ndk::ScopedAStatus StaNetwork::setPskPassphrase(
+	const std::string& in_psk)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setPskPassphraseInternal, in_psk);
+}
+
+::ndk::ScopedAStatus StaNetwork::setPsk(
+	const std::vector<uint8_t>& in_psk)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setPskInternal, in_psk);
+}
+
+::ndk::ScopedAStatus StaNetwork::setWepKey(
+	int32_t in_keyIdx, const std::vector<uint8_t>& in_wepKey)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setWepKeyInternal, in_keyIdx, in_wepKey);
+}
+
+::ndk::ScopedAStatus StaNetwork::setWepTxKeyIdx(
+	int32_t in_keyIdx)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setWepTxKeyIdxInternal, in_keyIdx);
+}
+
+::ndk::ScopedAStatus StaNetwork::setRequirePmf(bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setRequirePmfInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapMethod(
+	EapMethod in_method)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapMethodInternal, in_method);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapPhase2Method(
+	EapPhase2Method in_method)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapPhase2MethodInternal, in_method);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapIdentity(
+	const std::vector<uint8_t>& in_identity)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapIdentityInternal, in_identity);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapEncryptedImsiIdentity(
+	const std::vector<uint8_t>& in_identity)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapEncryptedImsiIdentityInternal,
+		in_identity);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapAnonymousIdentity(
+	const std::vector<uint8_t>& in_identity)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapAnonymousIdentityInternal, in_identity);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapPassword(
+	const std::vector<uint8_t>& in_password)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapPasswordInternal, in_password);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapCACert(
+	const std::string& in_path)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapCACertInternal, in_path);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapCAPath(
+	const std::string& in_path)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapCAPathInternal, in_path);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapClientCert(
+	const std::string& in_path)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapClientCertInternal, in_path);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapPrivateKeyId(
+	const std::string& in_id)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapPrivateKeyIdInternal, in_id);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapSubjectMatch(
+	const std::string& in_match)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapSubjectMatchInternal, in_match);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapAltSubjectMatch(
+	const std::string& in_match)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapAltSubjectMatchInternal, in_match);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapEngine(bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapEngineInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapEngineID(
+	const std::string& in_id)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapEngineIDInternal, in_id);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapDomainSuffixMatch(
+	const std::string& in_match)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapDomainSuffixMatchInternal, in_match);
+}
+
+::ndk::ScopedAStatus StaNetwork::setProactiveKeyCaching(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setProactiveKeyCachingInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaNetwork::setIdStr(
+	const std::string& in_idStr)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setIdStrInternal, in_idStr);
+}
+
+::ndk::ScopedAStatus StaNetwork::setUpdateIdentifier(
+	int32_t in_id)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setUpdateIdentifierInternal, in_id);
+}
+
+::ndk::ScopedAStatus StaNetwork::setWapiCertSuite(
+	const std::string& in_suite)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setWapiCertSuiteInternal, in_suite);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEdmg(bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEdmgInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaNetwork::getSsid(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getSsidInternal, _aidl_return);
+}
+
+ndk::ScopedAStatus StaNetwork::getBssid(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getBssidInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getScanSsid(
+	bool* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getScanSsidInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getKeyMgmt(
+	KeyMgmtMask* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getKeyMgmtInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getProto(
+	ProtoMask* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getProtoInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getAuthAlg(
+	AuthAlgMask* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getAuthAlgInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getGroupCipher(
+	GroupCipherMask* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getGroupCipherInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getPairwiseCipher(
+	PairwiseCipherMask* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getPairwiseCipherInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getPskPassphrase(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getPskPassphraseInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getPsk(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getPskInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getSaePassword(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getSaePasswordInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getSaePasswordId(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getSaePasswordIdInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getWepKey(
+	int32_t in_keyIdx,
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getWepKeyInternal, _aidl_return, in_keyIdx);
+}
+
+::ndk::ScopedAStatus StaNetwork::getWepTxKeyIdx(
+	int32_t* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getWepTxKeyIdxInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getRequirePmf(
+	bool* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getRequirePmfInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapMethod(
+	EapMethod* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapMethodInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapPhase2Method(
+	EapPhase2Method* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapPhase2MethodInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapIdentity(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapIdentityInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapAnonymousIdentity(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapAnonymousIdentityInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapPassword(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapPasswordInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapCACert(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapCACertInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapCAPath(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapCAPathInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapClientCert(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapClientCertInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapPrivateKeyId(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapPrivateKeyIdInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapSubjectMatch(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapSubjectMatchInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapAltSubjectMatch(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapAltSubjectMatchInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapEngine(
+	bool* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapEngineInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapEngineId(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapEngineIdInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEapDomainSuffixMatch(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEapDomainSuffixMatchInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getIdStr(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getIdStrInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getWpsNfcConfigurationToken(
+	std::vector<uint8_t>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getWpsNfcConfigurationTokenInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getWapiCertSuite(
+	std::string* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getWapiCertSuiteInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::getEdmg(
+	bool* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getEdmgInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::enable(bool in_noConnect)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::enableInternal, in_noConnect);
+}
+
+::ndk::ScopedAStatus StaNetwork::disable()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::disableInternal);
+}
+
+::ndk::ScopedAStatus StaNetwork::select()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::selectInternal);
+}
+
+::ndk::ScopedAStatus StaNetwork::sendNetworkEapSimGsmAuthResponse(
+	const std::vector<NetworkResponseEapSimGsmAuthParams>& in_params)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::sendNetworkEapSimGsmAuthResponseInternal,
+		in_params);
+}
+
+::ndk::ScopedAStatus StaNetwork::sendNetworkEapSimGsmAuthFailure()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::sendNetworkEapSimGsmAuthFailureInternal);
+}
+
+::ndk::ScopedAStatus StaNetwork::sendNetworkEapSimUmtsAuthResponse(
+	const NetworkResponseEapSimUmtsAuthParams& in_params)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::sendNetworkEapSimUmtsAuthResponseInternal,
+		in_params);
+}
+
+::ndk::ScopedAStatus StaNetwork::sendNetworkEapSimUmtsAutsResponse(
+	const std::vector<uint8_t>& in_auts)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::sendNetworkEapSimUmtsAutsResponseInternal,
+		in_auts);
+}
+
+::ndk::ScopedAStatus StaNetwork::sendNetworkEapSimUmtsAuthFailure()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::sendNetworkEapSimUmtsAuthFailureInternal);
+}
+
+::ndk::ScopedAStatus StaNetwork::sendNetworkEapIdentityResponse(
+	const std::vector<uint8_t>& in_identity,
+	const std::vector<uint8_t>& in_encryptedIdentity)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::sendNetworkEapIdentityResponseInternal,
+		in_identity, in_encryptedIdentity);
+}
+
+::ndk::ScopedAStatus StaNetwork::setGroupMgmtCipher(
+	GroupMgmtCipherMask in_groupMgmtCipherMask)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setGroupMgmtCipherInternal,
+		in_groupMgmtCipherMask);
+}
+
+::ndk::ScopedAStatus StaNetwork::getGroupMgmtCipher(
+	GroupMgmtCipherMask* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getGroupMgmtCipherInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::enableTlsSuiteBEapPhase1Param(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::enableTlsSuiteBEapPhase1ParamInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaNetwork::enableSuiteBEapOpenSslCiphers()
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::enableSuiteBEapOpenSslCiphersInternal);
+}
+
+::ndk::ScopedAStatus StaNetwork::setSaePassword(
+	const std::string& in_saePassword)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setSaePasswordInternal, in_saePassword);
+}
+
+::ndk::ScopedAStatus StaNetwork::setSaePasswordId(
+	const std::string& in_saePasswordId)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setSaePasswordIdInternal, in_saePasswordId);
+}
+
+::ndk::ScopedAStatus StaNetwork::setOcsp(
+	OcspType in_ocspType)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setOcspInternal, in_ocspType);
+}
+
+::ndk::ScopedAStatus StaNetwork::getOcsp(
+	OcspType* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::getOcspInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus StaNetwork::setPmkCache(
+	const std::vector<uint8_t>& in_serializedEntry)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setPmkCacheInternal, in_serializedEntry);
+}
+
+::ndk::ScopedAStatus StaNetwork::setEapErp(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setEapErpInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaNetwork::setSaeH2eMode(
+	SaeH2eMode in_mode)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setSaeH2eModeInternal, in_mode);
+}
+
+::ndk::ScopedAStatus StaNetwork::enableSaePkOnlyMode(
+	bool in_enable)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::enableSaePkOnlyModeInternal, in_enable);
+}
+
+::ndk::ScopedAStatus StaNetwork::setRoamingConsortiumSelection(
+	const std::vector<uint8_t>& in_selectedRcoi)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaNetwork::setRoamingConsortiumSelectionInternal, in_selectedRcoi);
+}
+
+std::pair<uint32_t, ndk::ScopedAStatus> StaNetwork::getIdInternal()
+{
+	return {network_id_, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaNetwork::getInterfaceNameInternal()
+{
+	return {ifname_, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<IfaceType, ndk::ScopedAStatus> StaNetwork::getTypeInternal()
+{
+	return {IfaceType::STA, ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaNetwork::registerCallbackInternal(
+	const std::shared_ptr<ISupplicantStaNetworkCallback> &callback)
+{
+	AidlManager *aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager || aidl_manager->addStaNetworkCallbackAidlObject(
+				 ifname_, network_id_, callback)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setSsidInternal(const std::vector<uint8_t> &ssid)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (ssid.size() == 0 ||
+		ssid.size() >
+		static_cast<uint32_t>(ISupplicantStaNetwork::
+					  SSID_MAX_LEN_IN_BYTES)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	if (setByteArrayFieldAndResetState(
+		ssid.data(), ssid.size(), &(wpa_ssid->ssid),
+		&(wpa_ssid->ssid_len), "ssid")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	if (wpa_ssid->passphrase) {
+		wpa_config_update_psk(wpa_ssid);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setBssidInternal(
+	const std::vector<uint8_t> &bssid)
+{
+	if (bssid.size() != ETH_ALEN) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	int prev_bssid_set = wpa_ssid->bssid_set;
+	u8 prev_bssid[ETH_ALEN];
+	os_memcpy(prev_bssid, wpa_ssid->bssid, ETH_ALEN);
+	// Zero'ed array is used to clear out the BSSID value.
+	if (os_memcmp(bssid.data(), kZeroBssid, ETH_ALEN) == 0) {
+		wpa_ssid->bssid_set = 0;
+		wpa_printf(MSG_MSGDUMP, "BSSID any");
+	} else {
+		os_memcpy(wpa_ssid->bssid, bssid.data(), ETH_ALEN);
+		wpa_ssid->bssid_set = 1;
+		wpa_hexdump(MSG_MSGDUMP, "BSSID", wpa_ssid->bssid, ETH_ALEN);
+	}
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if ((wpa_ssid->bssid_set != prev_bssid_set ||
+		 os_memcmp(wpa_ssid->bssid, prev_bssid, ETH_ALEN) != 0)) {
+		wpas_notify_network_bssid_set_changed(wpa_s, wpa_ssid);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setDppKeysInternal(const DppConnectionKeys& keys)
+{
+#ifdef CONFIG_DPP
+    // TODO Implement the function
+    return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+#else
+    return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+#endif
+}
+
+ndk::ScopedAStatus StaNetwork::setScanSsidInternal(bool enable)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	wpa_ssid->scan_ssid = enable ? 1 : 0;
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setAuthAlgInternal(
+	AuthAlgMask mask)
+{
+	uint32_t auth_alg_mask = static_cast<uint32_t>(mask);
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (auth_alg_mask & ~kAllowedAuthAlgMask) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	wpa_ssid->auth_alg = auth_alg_mask;
+	wpa_printf(MSG_MSGDUMP, "auth_alg: 0x%x", wpa_ssid->auth_alg);
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEdmgInternal(bool enable)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	wpa_ssid->enable_edmg = enable ? 1 : 0;
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setPskPassphraseInternal(const std::string &rawPsk)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	std::string psk = rawPsk;
+#ifdef CONFIG_WAPI_INTERFACE
+	if (wpa_ssid->key_mgmt & WPA_KEY_MGMT_WAPI_PSK) {
+		if (rawPsk.size() > 2 && rawPsk.front()== '"' && rawPsk.back() == '"') {
+			psk = rawPsk.substr(1, rawPsk.size() - 2);
+		} else {
+			if ((rawPsk.size() & 1)) {
+				return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+			}
+			size_t len = psk.size() / 2;
+			uint8_t *buf = (uint8_t *) os_malloc(len);
+			if (hexstr2bin(psk.c_str(), buf, len) < 0) {
+					os_free(buf);
+				return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+			}
+			std::vector<uint8_t> bytes(buf, buf + len);
+			os_free(buf);
+			return setWapiPskInternal(bytes);
+		}
+	}
+#endif
+	if (isPskPassphraseValid(psk)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	if (wpa_ssid->passphrase &&
+		os_strlen(wpa_ssid->passphrase) == psk.size() &&
+		os_memcmp(wpa_ssid->passphrase, psk.c_str(), psk.size()) == 0) {
+		return ndk::ScopedAStatus::ok();
+	}
+	// Flag to indicate if raw psk is calculated or not using
+	// |wpa_config_update_psk|. Deferred if ssid not already set.
+	wpa_ssid->psk_set = 0;
+	if (setStringKeyFieldAndResetState(
+		psk.c_str(), &(wpa_ssid->passphrase), "psk passphrase")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	if (wpa_ssid->ssid_len) {
+		wpa_config_update_psk(wpa_ssid);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setPskInternal(const std::vector<uint8_t> &psk)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	WPA_ASSERT(psk.size() == sizeof(wpa_ssid->psk));
+	str_clear_free(wpa_ssid->passphrase);
+	wpa_ssid->passphrase = nullptr;
+	os_memcpy(wpa_ssid->psk, psk.data(), sizeof(wpa_ssid->psk));
+	wpa_ssid->psk_set = 1;
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setWepKeyInternal(
+	uint32_t key_idx, const std::vector<uint8_t> &wep_key)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (key_idx >=
+		static_cast<uint32_t>(
+		ISupplicantStaNetwork::WEP_KEYS_MAX_NUM)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	if (wep_key.size() !=
+		static_cast<uint32_t>(ISupplicantStaNetwork::
+					  WEP40_KEY_LEN_IN_BYTES) &&
+		wep_key.size() !=
+		static_cast<uint32_t>(ISupplicantStaNetwork::
+					  WEP104_KEY_LEN_IN_BYTES)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	os_memcpy(wpa_ssid->wep_key[key_idx], wep_key.data(), wep_key.size());
+	wpa_ssid->wep_key_len[key_idx] = wep_key.size();
+	std::string msg_dump_title("wep_key" + std::to_string(key_idx));
+	wpa_hexdump_key(
+		MSG_MSGDUMP, msg_dump_title.c_str(), wpa_ssid->wep_key[key_idx],
+		wpa_ssid->wep_key_len[key_idx]);
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setWepTxKeyIdxInternal(uint32_t key_idx)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (key_idx >=
+		static_cast<uint32_t>(
+		ISupplicantStaNetwork::WEP_KEYS_MAX_NUM)) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	wpa_ssid->wep_tx_keyidx = key_idx;
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setRequirePmfInternal(bool enable)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (enable) {
+		wpa_ssid->ieee80211w = MGMT_FRAME_PROTECTION_REQUIRED;
+	}
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapMethodInternal(
+	EapMethod method)
+{
+	uint32_t eap_method_idx = static_cast<
+		std::underlying_type<EapMethod>::type>(
+		method);
+	if (eap_method_idx >= kEapMethodMax) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	int retrieved_vendor, retrieved_method;
+	const char *method_str = kEapMethodStrings[eap_method_idx];
+	// This string lookup is needed to check if the device supports the
+	// corresponding EAP type.
+	retrieved_method = eap_peer_get_type(method_str, &retrieved_vendor);
+	if (retrieved_vendor == EAP_VENDOR_IETF &&
+		retrieved_method == EAP_TYPE_NONE) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	if (wpa_ssid->eap.eap_methods) {
+		os_free(wpa_ssid->eap.eap_methods);
+	}
+	// wpa_supplicant can support setting multiple eap methods for each
+	// network. But, this is not really used by Android. So, just adding
+	// support for setting one EAP method for each network. The additional
+	// |eap_method_type| member in the array is used to indicate the end
+	// of list.
+	wpa_ssid->eap.eap_methods =
+		(eap_method_type *)os_malloc(sizeof(eap_method_type) * 2);
+	if (!wpa_ssid->eap.eap_methods) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	wpa_ssid->eap.eap_methods[0].vendor = retrieved_vendor;
+	wpa_ssid->eap.eap_methods[0].method = retrieved_method;
+	wpa_ssid->eap.eap_methods[1].vendor = EAP_VENDOR_IETF;
+	wpa_ssid->eap.eap_methods[1].method = EAP_TYPE_NONE;
+
+	wpa_ssid->leap = 0;
+	wpa_ssid->non_leap = 0;
+	if (retrieved_vendor == EAP_VENDOR_IETF &&
+		retrieved_method == EAP_TYPE_LEAP) {
+		wpa_ssid->leap++;
+	} else {
+		wpa_ssid->non_leap++;
+	}
+	wpa_hexdump(
+		MSG_MSGDUMP, "eap methods", (u8 *)wpa_ssid->eap.eap_methods,
+		sizeof(eap_method_type) * 2);
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapPhase2MethodInternal(
+	EapPhase2Method method)
+{
+	uint32_t eap_phase2_method_idx = static_cast<
+		std::underlying_type<EapPhase2Method>::type>(
+		method);
+	if (eap_phase2_method_idx >= kEapPhase2MethodMax) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	// EAP method needs to be set for us to construct the eap
+	// phase 2 method string.
+	ndk::ScopedAStatus status;
+	EapMethod eap_method;
+	std::tie(eap_method, status) = getEapMethodInternal();
+	if (!status.isOk()) {
+		return createStatusWithMsg(SupplicantStatusCode::FAILURE_UNKNOWN,
+			"EAP method not set");
+	}
+	std::string eap_phase2_str;
+	if (method == EapPhase2Method::NONE) {
+		eap_phase2_str = "";
+	} else if (
+		eap_method == EapMethod::TTLS &&
+		method == EapPhase2Method::GTC) {
+		eap_phase2_str = kEapPhase2AuthEapPrefix;
+	} else {
+		eap_phase2_str = kEapPhase2AuthPrefix;
+	}
+	eap_phase2_str += kEapPhase2MethodStrings[eap_phase2_method_idx];
+	if (setStringFieldAndResetState(
+		eap_phase2_str.c_str(), &(wpa_ssid->eap.phase2),
+		"eap phase2")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapIdentityInternal(
+	const std::vector<uint8_t> &identity)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setByteArrayFieldAndResetState(
+		identity.data(), identity.size(), &(wpa_ssid->eap.identity),
+		&(wpa_ssid->eap.identity_len), "eap identity")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	// plain IMSI identity
+	if (setByteArrayFieldAndResetState(
+		identity.data(), identity.size(),
+		&(wpa_ssid->eap.imsi_identity),
+		&(wpa_ssid->eap.imsi_identity_len), "eap imsi identity")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapEncryptedImsiIdentityInternal(
+	const std::vector<uint8_t> &identity)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	// encrypted IMSI identity
+	if (setByteArrayFieldAndResetState(
+		identity.data(), identity.size(), &(wpa_ssid->eap.identity),
+		&(wpa_ssid->eap.identity_len), "eap encrypted imsi identity")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapAnonymousIdentityInternal(
+	const std::vector<uint8_t> &identity)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setByteArrayFieldAndResetState(
+		identity.data(), identity.size(),
+		&(wpa_ssid->eap.anonymous_identity),
+		&(wpa_ssid->eap.anonymous_identity_len),
+		"eap anonymous_identity")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapPasswordInternal(
+	const std::vector<uint8_t> &password)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setByteArrayKeyFieldAndResetState(
+		password.data(), password.size(), &(wpa_ssid->eap.password),
+		&(wpa_ssid->eap.password_len), "eap password")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	wpa_ssid->eap.flags &= ~EAP_CONFIG_FLAGS_PASSWORD_NTHASH;
+	wpa_ssid->eap.flags &= ~EAP_CONFIG_FLAGS_EXT_PASSWORD;
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapCACertInternal(const std::string &path)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setStringFieldAndResetState(
+		path.c_str(), &(wpa_ssid->eap.cert.ca_cert), "eap ca_cert")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapCAPathInternal(const std::string &path)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setStringFieldAndResetState(
+		path.c_str(), &(wpa_ssid->eap.cert.ca_path), "eap ca_path")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapClientCertInternal(const std::string &path)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setStringFieldAndResetState(
+		path.c_str(), &(wpa_ssid->eap.cert.client_cert),
+		"eap client_cert")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapPrivateKeyIdInternal(const std::string &id)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setStringFieldAndResetState(
+		id.c_str(), &(wpa_ssid->eap.cert.key_id), "eap key_id")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapSubjectMatchInternal(
+	const std::string &match)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setStringFieldAndResetState(
+		match.c_str(), &(wpa_ssid->eap.cert.subject_match),
+		"eap subject_match")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapAltSubjectMatchInternal(
+	const std::string &match)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setStringFieldAndResetState(
+		match.c_str(), &(wpa_ssid->eap.cert.altsubject_match),
+		"eap altsubject_match")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapEngineInternal(bool enable)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	wpa_ssid->eap.cert.engine = enable ? 1 : 0;
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapEngineIDInternal(const std::string &id)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setStringFieldAndResetState(
+		id.c_str(), &(wpa_ssid->eap.cert.engine_id), "eap engine_id")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setEapDomainSuffixMatchInternal(
+	const std::string &match)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setStringFieldAndResetState(
+		match.c_str(), &(wpa_ssid->eap.cert.domain_suffix_match),
+		"eap domain_suffix_match")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setProactiveKeyCachingInternal(bool enable)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	wpa_ssid->proactive_key_caching = enable ? 1 : 0;
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setIdStrInternal(const std::string &id_str)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (setStringFieldAndResetState(
+		id_str.c_str(), &(wpa_ssid->id_str), "id_str")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setUpdateIdentifierInternal(uint32_t id)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	wpa_ssid->update_identifier = id;
+	wpa_printf(
+		MSG_MSGDUMP, "update_identifier: %d", wpa_ssid->update_identifier);
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setWapiCertSuiteInternal(const std::string &suite)
+{
+#ifdef CONFIG_WAPI_INTERFACE
+	// Dummy implementation
+	dummyWapiCertSuite = suite;
+	return ndk::ScopedAStatus::ok();
+#else
+	return createStatusWithMsg(SupplicantStatusCode::FAILURE_UNKNOWN, "Not implemented");
+#endif
+}
+
+ndk::ScopedAStatus StaNetwork::setWapiPskInternal(const std::vector<uint8_t> &psk)
+{
+#ifdef CONFIG_WAPI_INTERFACE
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	str_clear_free(wpa_ssid->passphrase);
+	wpa_ssid->passphrase = nullptr;
+
+	// Dummy implementation
+	dummyWapiPsk = psk;
+
+	wpa_ssid->psk_set = 1;
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+#else
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+#endif
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> StaNetwork::getSsidInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	std::vector<uint8_t> ssid(
+		wpa_ssid->ssid,
+		wpa_ssid->ssid + wpa_ssid->ssid_len);
+	return {std::move(ssid), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+StaNetwork::getBssidInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	std::vector<uint8_t> bssid(kZeroBssid, kZeroBssid + ETH_ALEN);
+	if (wpa_ssid->bssid_set) {
+		bssid.assign(wpa_ssid->bssid, wpa_ssid->bssid + ETH_ALEN);
+	}
+	return {std::move(bssid), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<bool, ndk::ScopedAStatus> StaNetwork::getScanSsidInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	return {(wpa_ssid->scan_ssid == 1), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<AuthAlgMask, ndk::ScopedAStatus>
+StaNetwork::getAuthAlgInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	uint32_t auth_alg_mask = wpa_ssid->auth_alg & kAllowedAuthAlgMask;
+	return {static_cast<AuthAlgMask>(auth_alg_mask), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaNetwork::getPskPassphraseInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+#ifdef CONFIG_WAPI_INTERFACE
+	if (wpa_ssid->key_mgmt & WPA_KEY_MGMT_WAPI_PSK) {
+		if (wpa_ssid->psk_set) {
+			std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> ret = getWapiPskInternal();
+			std::string psk;
+			char buf[3] = {0};
+			for (int i = 0; i < ret.second.size(); i++) {
+				snprintf(buf, sizeof(buf), "%02x", ret.second[i]);
+				psk.append(buf);
+			}
+			return {psk, ndk::ScopedAStatus::ok()};
+		} else {
+			if (!wpa_ssid->passphrase) {
+				return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+			}
+			std::string passphrase;
+			passphrase.append("\"");
+			passphrase.append(wpa_ssid->passphrase);
+			passphrase.append("\"");
+			return {passphrase, ndk::ScopedAStatus::ok()};
+		}
+	}
+#endif
+	if (!wpa_ssid->passphrase) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {wpa_ssid->passphrase, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+StaNetwork::getPskInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	WPA_ASSERT(psk.size() == sizeof(wpa_ssid->psk));
+	if (!wpa_ssid->psk_set) {
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	std::vector<uint8_t> psk(wpa_ssid->psk, wpa_ssid->psk + 32);
+	return {psk, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaNetwork::getSaePasswordInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->sae_password) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(wpa_ssid->sae_password),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaNetwork::getSaePasswordIdInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->sae_password_id) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(wpa_ssid->sae_password_id),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> StaNetwork::getWepKeyInternal(
+	uint32_t key_idx)
+{
+	std::vector<uint8_t> wep_key;
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (key_idx >=
+		static_cast<uint32_t>(
+		ISupplicantStaNetwork::WEP_KEYS_MAX_NUM)) {
+		return {wep_key,
+			createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID)};
+	}
+	wep_key.assign(
+		wpa_ssid->wep_key[key_idx],
+		wpa_ssid->wep_key[key_idx] + wpa_ssid->wep_key_len[key_idx]);
+	return {std::move(wep_key), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<uint32_t, ndk::ScopedAStatus> StaNetwork::getWepTxKeyIdxInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	return {wpa_ssid->wep_tx_keyidx, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<bool, ndk::ScopedAStatus> StaNetwork::getRequirePmfInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	return {(wpa_ssid->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<EapMethod, ndk::ScopedAStatus>
+StaNetwork::getEapMethodInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.eap_methods) {
+		return {static_cast<EapMethod>(0),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	// wpa_supplicant can support setting multiple eap methods for each
+	// network. But, this is not really used by Android. So, just reading
+	// the first EAP method for each network.
+	const std::string eap_method_str = eap_get_name(
+		wpa_ssid->eap.eap_methods[0].vendor,
+		static_cast<enum eap_type>(wpa_ssid->eap.eap_methods[0].method));
+	size_t eap_method_idx =
+		std::find(
+		std::begin(kEapMethodStrings), std::end(kEapMethodStrings),
+		eap_method_str) -
+		std::begin(kEapMethodStrings);
+	if (eap_method_idx >= kEapMethodMax) {
+		return {static_cast<EapMethod>(0),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {static_cast<EapMethod>(eap_method_idx), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<EapPhase2Method, ndk::ScopedAStatus>
+StaNetwork::getEapPhase2MethodInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.phase2) {
+		return {static_cast<EapPhase2Method>(0),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	const std::string eap_phase2_method_str_with_prefix =
+		wpa_ssid->eap.phase2;
+	std::string eap_phase2_method_str;
+	// Strip out the phase 2 method prefix before doing a reverse lookup
+	// of phase 2 string to the Eap Phase 2 type.
+	if (eap_phase2_method_str_with_prefix.find(kEapPhase2AuthPrefix) == 0) {
+		eap_phase2_method_str =
+			eap_phase2_method_str_with_prefix.substr(
+			strlen(kEapPhase2AuthPrefix),
+			eap_phase2_method_str_with_prefix.size());
+	} else if (
+		eap_phase2_method_str_with_prefix.find(kEapPhase2AuthEapPrefix) ==
+		0) {
+		eap_phase2_method_str =
+			eap_phase2_method_str_with_prefix.substr(
+			strlen(kEapPhase2AuthEapPrefix),
+			eap_phase2_method_str_with_prefix.size());
+	}
+	size_t eap_phase2_method_idx =
+		std::find(
+		std::begin(kEapPhase2MethodStrings),
+		std::end(kEapPhase2MethodStrings), eap_phase2_method_str) -
+		std::begin(kEapPhase2MethodStrings);
+	if (eap_phase2_method_idx >= kEapPhase2MethodMax) {
+		return {static_cast<EapPhase2Method>(0),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {static_cast<EapPhase2Method>(eap_phase2_method_idx),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+StaNetwork::getEapIdentityInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.identity) {
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {std::vector<uint8_t>(
+			wpa_ssid->eap.identity,
+			wpa_ssid->eap.identity + wpa_ssid->eap.identity_len),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+StaNetwork::getEapAnonymousIdentityInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.anonymous_identity) {
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {std::vector<uint8_t>(
+			wpa_ssid->eap.anonymous_identity,
+			wpa_ssid->eap.anonymous_identity +
+			wpa_ssid->eap.anonymous_identity_len),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+StaNetwork::getEapPasswordInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.password) {
+		return {std::vector<uint8_t>(), createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {std::vector<uint8_t>(
+			wpa_ssid->eap.password,
+			wpa_ssid->eap.password + wpa_ssid->eap.password_len),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaNetwork::getEapCACertInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.cert.ca_cert) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(wpa_ssid->eap.cert.ca_cert),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaNetwork::getEapCAPathInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.cert.ca_path) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(wpa_ssid->eap.cert.ca_path),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaNetwork::getEapClientCertInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.cert.client_cert) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(wpa_ssid->eap.cert.client_cert),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus>
+StaNetwork::getEapPrivateKeyIdInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.cert.key_id) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(reinterpret_cast<char *>(wpa_ssid->eap.cert.key_id)),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus>
+StaNetwork::getEapSubjectMatchInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.cert.subject_match) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(wpa_ssid->eap.cert.subject_match),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus>
+StaNetwork::getEapAltSubjectMatchInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.cert.altsubject_match) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(wpa_ssid->eap.cert.altsubject_match),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<bool, ndk::ScopedAStatus> StaNetwork::getEapEngineInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	return {wpa_ssid->eap.cert.engine == 1, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaNetwork::getEapEngineIdInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.cert.engine_id) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(wpa_ssid->eap.cert.engine_id),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus>
+StaNetwork::getEapDomainSuffixMatchInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->eap.cert.domain_suffix_match) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(wpa_ssid->eap.cert.domain_suffix_match),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaNetwork::getIdStrInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid->id_str) {
+		return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::charBufToString(wpa_ssid->id_str),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<bool, ndk::ScopedAStatus> StaNetwork::getEdmgInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	return {(wpa_ssid->enable_edmg == 1), ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+StaNetwork::getWpsNfcConfigurationTokenInternal()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	auto token_buf = misc_utils::createWpaBufUniquePtr(
+		wpas_wps_network_config_token(wpa_s, 0, wpa_ssid));
+	if (!token_buf) {
+		return {std::vector<uint8_t>(),
+			createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {misc_utils::convertWpaBufToVector(token_buf.get()),
+		ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::string, ndk::ScopedAStatus> StaNetwork::getWapiCertSuiteInternal()
+{
+#ifdef CONFIG_WAPI_INTERFACE
+	// Dummy implementation
+	return {dummyWapiCertSuite, ndk::ScopedAStatus::ok()};
+#else
+	return {"", createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+#endif
+}
+
+std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> StaNetwork::getWapiPskInternal()
+{
+#ifdef CONFIG_WAPI_INTERFACE
+	// Dummy implementation
+	return {dummyWapiPsk, ndk::ScopedAStatus::ok()};
+#else
+	return {std::vector<uint8_t>(),
+		createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+#endif
+}
+
+ndk::ScopedAStatus StaNetwork::enableInternal(bool no_connect)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (wpa_ssid->disabled == 2) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (no_connect) {
+		wpa_ssid->disabled = 0;
+	} else {
+		wpa_s->scan_min_time.sec = 0;
+		wpa_s->scan_min_time.usec = 0;
+		wpa_supplicant_enable_network(wpa_s, wpa_ssid);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::disableInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (wpa_ssid->disabled == 2) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	wpa_supplicant_disable_network(wpa_s, wpa_ssid);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::selectInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (wpa_ssid->disabled == 2) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	wpa_s->scan_min_time.sec = 0;
+	wpa_s->scan_min_time.usec = 0;
+	wpa_supplicant_select_network(wpa_s, wpa_ssid);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::sendNetworkEapSimGsmAuthResponseInternal(
+	const std::vector<NetworkResponseEapSimGsmAuthParams>
+	&vec_params)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	// Convert the incoming parameters to a string to pass to
+	// wpa_supplicant.
+	std::string ctrl_rsp_param = std::string(kNetworkEapSimGsmAuthResponse);
+	for (const auto &params : vec_params) {
+		uint32_t kc_hex_len = params.kc.size() * 2 + 1;
+		std::vector<char> kc_hex(kc_hex_len);
+		uint32_t sres_hex_len = params.sres.size() * 2 + 1;
+		std::vector<char> sres_hex(sres_hex_len);
+		wpa_snprintf_hex(
+			kc_hex.data(), kc_hex.size(), params.kc.data(),
+			params.kc.size());
+		wpa_snprintf_hex(
+			sres_hex.data(), sres_hex.size(), params.sres.data(),
+			params.sres.size());
+		ctrl_rsp_param += ":" + std::string(kc_hex.data()) + ":" +
+				  std::string(sres_hex.data());
+	}
+	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpa_supplicant_ctrl_rsp_handle(
+		wpa_s, wpa_ssid, rtype, ctrl_rsp_param.c_str(),
+		ctrl_rsp_param.size())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	eapol_sm_notify_ctrl_response(wpa_s->eapol);
+	wpa_hexdump_ascii_key(
+		MSG_DEBUG, "network sim gsm auth response param",
+		(const u8 *)ctrl_rsp_param.c_str(), ctrl_rsp_param.size());
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::sendNetworkEapSimGsmAuthFailureInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
+	if (wpa_supplicant_ctrl_rsp_handle(
+		wpa_s, wpa_ssid, rtype, kNetworkEapSimGsmAuthFailure,
+		strlen(kNetworkEapSimGsmAuthFailure))) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	eapol_sm_notify_ctrl_response(wpa_s->eapol);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::sendNetworkEapSimUmtsAuthResponseInternal(
+	const NetworkResponseEapSimUmtsAuthParams &params)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	// Convert the incoming parameters to a string to pass to
+	// wpa_supplicant.
+	uint32_t ik_hex_len = params.ik.size() * 2 + 1;
+	std::vector<char> ik_hex(ik_hex_len);
+	uint32_t ck_hex_len = params.ck.size() * 2 + 1;
+	std::vector<char> ck_hex(ck_hex_len);
+	uint32_t res_hex_len = params.res.size() * 2 + 1;
+	std::vector<char> res_hex(res_hex_len);
+	wpa_snprintf_hex(
+		ik_hex.data(), ik_hex.size(), params.ik.data(), params.ik.size());
+	wpa_snprintf_hex(
+		ck_hex.data(), ck_hex.size(), params.ck.data(), params.ck.size());
+	wpa_snprintf_hex(
+		res_hex.data(), res_hex.size(), params.res.data(),
+		params.res.size());
+	std::string ctrl_rsp_param =
+		std::string(kNetworkEapSimUmtsAuthResponse) + ":" +
+		std::string(ik_hex.data()) + ":" + std::string(ck_hex.data()) +
+		":" + std::string(res_hex.data());
+	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpa_supplicant_ctrl_rsp_handle(
+		wpa_s, wpa_ssid, rtype, ctrl_rsp_param.c_str(),
+		ctrl_rsp_param.size())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	eapol_sm_notify_ctrl_response(wpa_s->eapol);
+	wpa_hexdump_ascii_key(
+		MSG_DEBUG, "network sim umts auth response param",
+		(const u8 *)ctrl_rsp_param.c_str(), ctrl_rsp_param.size());
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::sendNetworkEapSimUmtsAutsResponseInternal(
+	const std::vector<uint8_t> &auts)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	uint32_t auts_hex_len = auts.size() * 2 + 1;
+	std::vector<char> auts_hex(auts_hex_len);
+	wpa_snprintf_hex(
+		auts_hex.data(), auts_hex.size(), auts.data(), auts.size());
+	std::string ctrl_rsp_param =
+		std::string(kNetworkEapSimUmtsAutsResponse) + ":" +
+		std::string(auts_hex.data());
+	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpa_supplicant_ctrl_rsp_handle(
+		wpa_s, wpa_ssid, rtype, ctrl_rsp_param.c_str(),
+		ctrl_rsp_param.size())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	eapol_sm_notify_ctrl_response(wpa_s->eapol);
+	wpa_hexdump_ascii_key(
+		MSG_DEBUG, "network sim umts auts response param",
+		(const u8 *)ctrl_rsp_param.c_str(), ctrl_rsp_param.size());
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::sendNetworkEapSimUmtsAuthFailureInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
+	if (wpa_supplicant_ctrl_rsp_handle(
+		wpa_s, wpa_ssid, rtype, kNetworkEapSimUmtsAuthFailure,
+		strlen(kNetworkEapSimUmtsAuthFailure))) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	eapol_sm_notify_ctrl_response(wpa_s->eapol);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::sendNetworkEapIdentityResponseInternal(
+	const std::vector<uint8_t> &identity,
+	const std::vector<uint8_t> &encrypted_imsi_identity)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	std::string ctrl_rsp_param(identity.begin(), identity.end());
+	// If encrypted identity is included, format is:
+	// plain identity + ":" + encrypted_identity
+	if (encrypted_imsi_identity.size() != 0) {
+		ctrl_rsp_param += ":" + std::string(
+			encrypted_imsi_identity.begin(), encrypted_imsi_identity.end());
+	}
+	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_EAP_IDENTITY;
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpa_supplicant_ctrl_rsp_handle(
+		wpa_s, wpa_ssid, rtype, ctrl_rsp_param.c_str(),
+		ctrl_rsp_param.size())) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	eapol_sm_notify_ctrl_response(wpa_s->eapol);
+	wpa_hexdump_ascii_key(
+		MSG_DEBUG, "network identity response param",
+		(const u8 *)ctrl_rsp_param.c_str(), ctrl_rsp_param.size());
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::enableTlsSuiteBEapPhase1ParamInternal(bool enable)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	int val = enable == true ? 1 : 0;
+	std::string suiteb_phase1("tls_suiteb=" + std::to_string(val));
+
+	if (setStringKeyFieldAndResetState(
+		suiteb_phase1.c_str(), &(wpa_ssid->eap.phase1), "phase1")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::enableSuiteBEapOpenSslCiphersInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	const char openssl_suiteb_cipher[] = "SUITEB192";
+
+	if (setStringKeyFieldAndResetState(
+		openssl_suiteb_cipher, &(wpa_ssid->eap.openssl_ciphers),
+		"openssl_ciphers")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setSaePasswordInternal(
+	const std::string &sae_password)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (sae_password.length() < 1) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	if (wpa_ssid->sae_password &&
+		os_strlen(wpa_ssid->sae_password) == sae_password.length() &&
+		os_memcmp(
+		wpa_ssid->sae_password, sae_password.c_str(),
+		sae_password.length()) == 0) {
+		return ndk::ScopedAStatus::ok();
+	}
+	wpa_ssid->psk_set = 1;
+	if (setStringKeyFieldAndResetState(
+		sae_password.c_str(), &(wpa_ssid->sae_password),
+		"sae password")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setSaePasswordIdInternal(
+	const std::string &sae_password_id)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (sae_password_id.length() < 1) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	if (wpa_ssid->sae_password_id &&
+		os_strlen(wpa_ssid->sae_password_id) == sae_password_id.length() &&
+		os_memcmp(
+		wpa_ssid->sae_password_id, sae_password_id.c_str(),
+		sae_password_id.length()) == 0) {
+		return ndk::ScopedAStatus::ok();
+	}
+	wpa_ssid->psk_set = 1;
+	if (setStringKeyFieldAndResetState(
+		sae_password_id.c_str(), &(wpa_ssid->sae_password_id),
+		"sae password id")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setGroupMgmtCipherInternal(
+		GroupMgmtCipherMask mask)
+{
+	uint32_t group_mgmt_cipher_mask = static_cast<uint32_t>(mask);
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (group_mgmt_cipher_mask & ~kAllowedGroupMgmtCipherMask) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	wpa_ssid->group_mgmt_cipher = group_mgmt_cipher_mask;
+	wpa_printf(MSG_MSGDUMP, "group_mgmt_cipher: 0x%x",
+			wpa_ssid->group_mgmt_cipher);
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<GroupMgmtCipherMask, ndk::ScopedAStatus>
+StaNetwork::getGroupMgmtCipherInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	uint32_t group_mgmt_cipher_mask =
+			wpa_ssid->group_mgmt_cipher & kAllowedGroupMgmtCipherMask;
+	return {static_cast<GroupMgmtCipherMask>(group_mgmt_cipher_mask),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaNetwork::setOcspInternal(OcspType ocspType) {
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (ocspType < OcspType::NONE || ocspType > OcspType::REQUIRE_ALL_CERTS_STATUS) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	wpa_ssid->eap.cert.ocsp = (int) ocspType;
+	wpa_printf(
+		MSG_MSGDUMP, "ocsp: %d", wpa_ssid->eap.cert.ocsp);
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<OcspType, ndk::ScopedAStatus> StaNetwork::getOcspInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	return {static_cast<OcspType>(wpa_ssid->eap.cert.ocsp),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaNetwork::setPmkCacheInternal(const std::vector<uint8_t>& serializedEntry) {
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	struct rsn_pmksa_cache_entry *new_entry = NULL;
+
+	new_entry = (struct rsn_pmksa_cache_entry *) os_zalloc(sizeof(*new_entry));
+	if (!new_entry) {
+		return createStatusWithMsg(SupplicantStatusCode::FAILURE_UNKNOWN,
+			"Allocating memory failed");
+	}
+
+	std::stringstream ss(
+		std::stringstream::in | std::stringstream::out | std::stringstream::binary);
+	ss.write((char *) serializedEntry.data(), std::streamsize(serializedEntry.size()));
+	misc_utils::deserializePmkCacheEntry(ss, new_entry);
+	new_entry->network_ctx = wpa_ssid;
+
+	// If there is an entry has a later expiration, ignore this one.
+	struct rsn_pmksa_cache_entry *existing_entry = wpa_sm_pmksa_cache_get(
+		wpa_s->wpa, new_entry->aa, NULL, NULL, new_entry->akmp);
+	if (NULL != existing_entry &&
+		existing_entry->expiration >= new_entry->expiration) {
+		return ndk::ScopedAStatus::ok();
+	}
+
+	wpa_sm_pmksa_cache_add_entry(wpa_s->wpa, new_entry);
+
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::setKeyMgmtInternal(
+	KeyMgmtMask mask)
+{
+	uint32_t key_mgmt_mask = static_cast<uint32_t>(mask);
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (key_mgmt_mask & ~kAllowedKeyMgmtMask) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	setFastTransitionKeyMgmt(key_mgmt_mask);
+
+	if (key_mgmt_mask & WPA_KEY_MGMT_OWE) {
+		// Do not allow to connect to Open network when OWE is selected
+		wpa_ssid->owe_only = 1;
+	}
+	wpa_ssid->key_mgmt = key_mgmt_mask;
+	wpa_printf(MSG_MSGDUMP, "key_mgmt: 0x%x", wpa_ssid->key_mgmt);
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<KeyMgmtMask, ndk::ScopedAStatus>
+StaNetwork::getKeyMgmtInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	uint32_t key_mgmt_mask = wpa_ssid->key_mgmt & kAllowedKeyMgmtMask;
+
+	resetFastTransitionKeyMgmt(key_mgmt_mask);
+	return {static_cast<KeyMgmtMask>(key_mgmt_mask),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaNetwork::setProtoInternal(
+	ProtoMask mask)
+{
+	uint32_t proto_mask = static_cast<uint32_t>(mask);
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (proto_mask & ~kAllowedProtoMask) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	wpa_ssid->proto = proto_mask;
+	wpa_printf(MSG_MSGDUMP, "proto: 0x%x", wpa_ssid->proto);
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<ProtoMask, ndk::ScopedAStatus>
+StaNetwork::getProtoInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	uint32_t proto_mask = wpa_ssid->proto & kAllowedProtoMask;
+	return {static_cast<ProtoMask>(proto_mask), ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaNetwork::setGroupCipherInternal(
+	GroupCipherMask mask)
+{
+	uint32_t group_cipher_mask = static_cast<uint32_t>(mask);
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (group_cipher_mask & ~kAllowedGroupCipherMask) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	wpa_ssid->group_cipher = group_cipher_mask;
+	wpa_printf(MSG_MSGDUMP, "group_cipher: 0x%x", wpa_ssid->group_cipher);
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<GroupCipherMask, ndk::ScopedAStatus>
+StaNetwork::getGroupCipherInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	uint32_t group_cipher_mask = wpa_ssid->group_cipher & kAllowedGroupCipherMask;
+	return {static_cast<GroupCipherMask>(group_cipher_mask),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaNetwork::setPairwiseCipherInternal(
+	PairwiseCipherMask mask)
+{
+	uint32_t pairwise_cipher_mask = static_cast<uint32_t>(mask);
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (pairwise_cipher_mask & ~kAllowedPairwisewCipherMask) {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	wpa_ssid->pairwise_cipher = pairwise_cipher_mask;
+	wpa_printf(
+		MSG_MSGDUMP, "pairwise_cipher: 0x%x", wpa_ssid->pairwise_cipher);
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<PairwiseCipherMask, ndk::ScopedAStatus>
+StaNetwork::getPairwiseCipherInternal()
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	uint32_t pairwise_cipher_mask = wpa_ssid->pairwise_cipher & kAllowedPairwisewCipherMask;
+	return {static_cast<PairwiseCipherMask>(pairwise_cipher_mask),
+		ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus StaNetwork::setRoamingConsortiumSelectionInternal(
+	const std::vector<uint8_t> &selectedRcoi)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (wpa_ssid == NULL) {
+		return createStatus(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (setByteArrayFieldAndResetState(
+		selectedRcoi.data(), selectedRcoi.size(),
+		&(wpa_ssid->roaming_consortium_selection),
+		&(wpa_ssid->roaming_consortium_selection_len),
+		"roaming_consortium_selection")) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+/**
+ * Retrieve the underlying |wpa_ssid| struct pointer for
+ * this network.
+ * If the underlying network is removed or the interface
+ * this network belong to
+ * is removed, all RPC method calls on this object will
+ * return failure.
+ */
+struct wpa_ssid *StaNetwork::retrieveNetworkPtr()
+{
+	wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (!wpa_s)
+		return nullptr;
+	return wpa_config_get_network(wpa_s->conf, network_id_);
+}
+
+/**
+ * Retrieve the underlying |wpa_supplicant| struct
+ * pointer for
+ * this network.
+ */
+struct wpa_supplicant *StaNetwork::retrieveIfacePtr()
+{
+	return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
+}
+
+/**
+ * Check if the provided psk passhrase is valid or not.
+ *
+ * Returns 0 if valid, 1 otherwise.
+ */
+int StaNetwork::isPskPassphraseValid(const std::string &psk)
+{
+	if (psk.size() <
+		static_cast<uint32_t>(ISupplicantStaNetwork::
+					  PSK_PASSPHRASE_MIN_LEN_IN_BYTES) ||
+		psk.size() >
+		static_cast<uint32_t>(ISupplicantStaNetwork::
+					  PSK_PASSPHRASE_MAX_LEN_IN_BYTES)) {
+		return 1;
+	}
+	if (has_ctrl_char((u8 *)psk.c_str(), psk.size())) {
+		return 1;
+	}
+	return 0;
+}
+
+/**
+ * Reset internal wpa_supplicant state machine state
+ * after params update (except
+ * bssid).
+ */
+void StaNetwork::resetInternalStateAfterParamsUpdate()
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+
+	wpa_sm_pmksa_cache_flush(wpa_s->wpa, wpa_ssid);
+
+	if (wpa_s->current_ssid == wpa_ssid || wpa_s->current_ssid == NULL) {
+		/*
+		 * Invalidate the EAP session cache if
+		 * anything in the
+		 * current or previously used
+		 * configuration changes.
+		 */
+		eapol_sm_invalidate_cached_session(wpa_s->eapol);
+	}
+}
+
+/**
+ * Helper function to set value in a string field in |wpa_ssid| structue
+ * instance for this network.
+ * This function frees any existing data in these fields.
+ */
+int StaNetwork::setStringFieldAndResetState(
+	const char *value, uint8_t **to_update_field, const char *hexdump_prefix)
+{
+	return setStringFieldAndResetState(
+		value, (char **)to_update_field, hexdump_prefix);
+}
+
+/**
+ * Helper function to set value in a string field in |wpa_ssid| structue
+ * instance for this network.
+ * This function frees any existing data in these fields.
+ */
+int StaNetwork::setStringFieldAndResetState(
+	const char *value, char **to_update_field, const char *hexdump_prefix)
+{
+	int value_len = strlen(value);
+	if (*to_update_field) {
+		os_free(*to_update_field);
+	}
+	*to_update_field = dup_binstr(value, value_len);
+	if (!(*to_update_field)) {
+		return 1;
+	}
+	wpa_hexdump_ascii(
+		MSG_MSGDUMP, hexdump_prefix, *to_update_field, value_len);
+	resetInternalStateAfterParamsUpdate();
+	return 0;
+}
+
+/**
+ * Helper function to set value in a string key field in |wpa_ssid| structue
+ * instance for this network.
+ * This function frees any existing data in these fields.
+ */
+int StaNetwork::setStringKeyFieldAndResetState(
+	const char *value, char **to_update_field, const char *hexdump_prefix)
+{
+	int value_len = strlen(value);
+	if (*to_update_field) {
+		str_clear_free(*to_update_field);
+	}
+	*to_update_field = dup_binstr(value, value_len);
+	if (!(*to_update_field)) {
+		return 1;
+	}
+	wpa_hexdump_ascii_key(
+		MSG_MSGDUMP, hexdump_prefix, *to_update_field, value_len);
+	resetInternalStateAfterParamsUpdate();
+	return 0;
+}
+
+/**
+ * Helper function to set value in a string field with a corresponding length
+ * field in |wpa_ssid| structure instance for this network.
+ * This function frees any existing data in these fields.
+ */
+int StaNetwork::setByteArrayFieldAndResetState(
+	const uint8_t *value, const size_t value_len, uint8_t **to_update_field,
+	size_t *to_update_field_len, const char *hexdump_prefix)
+{
+	if (*to_update_field) {
+		os_free(*to_update_field);
+	}
+	*to_update_field = (uint8_t *)os_malloc(value_len);
+	if (!(*to_update_field)) {
+		return 1;
+	}
+	os_memcpy(*to_update_field, value, value_len);
+	*to_update_field_len = value_len;
+
+	wpa_hexdump_ascii(
+		MSG_MSGDUMP, hexdump_prefix, *to_update_field,
+		*to_update_field_len);
+	resetInternalStateAfterParamsUpdate();
+	return 0;
+}
+
+/**
+ * Helper function to set value in a string key field with a corresponding
+ * length field in |wpa_ssid| structue instance for this network.
+ * This function frees any existing data in these fields.
+ */
+int StaNetwork::setByteArrayKeyFieldAndResetState(
+	const uint8_t *value, const size_t value_len, uint8_t **to_update_field,
+	size_t *to_update_field_len, const char *hexdump_prefix)
+{
+	if (*to_update_field) {
+		bin_clear_free(*to_update_field, *to_update_field_len);
+	}
+	*to_update_field = (uint8_t *)os_malloc(value_len);
+	if (!(*to_update_field)) {
+		return 1;
+	}
+	os_memcpy(*to_update_field, value, value_len);
+	*to_update_field_len = value_len;
+
+	wpa_hexdump_ascii_key(
+		MSG_MSGDUMP, hexdump_prefix, *to_update_field,
+		*to_update_field_len);
+	resetInternalStateAfterParamsUpdate();
+	return 0;
+}
+
+/**
+ * Helper function to set the fast transition bits in the key management
+ * bitmask, to allow FT support when possible.
+ */
+void StaNetwork::setFastTransitionKeyMgmt(uint32_t &key_mgmt_mask)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	int res;
+	struct wpa_driver_capa capa;
+
+	if (key_mgmt_mask & WPA_KEY_MGMT_PSK) {
+		key_mgmt_mask |= WPA_KEY_MGMT_FT_PSK;
+	}
+
+	if (key_mgmt_mask & WPA_KEY_MGMT_IEEE8021X) {
+		key_mgmt_mask |= WPA_KEY_MGMT_FT_IEEE8021X;
+	}
+
+	res = wpa_drv_get_capa(wpa_s, &capa);
+	if (res == 0) {
+#ifdef CONFIG_IEEE80211R
+#ifdef CONFIG_SAE
+		if ((key_mgmt_mask & WPA_KEY_MGMT_SAE) &&
+			(capa.key_mgmt_iftype[WPA_IF_STATION] & WPA_DRIVER_CAPA_KEY_MGMT_FT_SAE)) {
+			key_mgmt_mask |= WPA_KEY_MGMT_FT_SAE;
+		}
+#endif
+#endif
+	}
+
+}
+
+/**
+ * Helper function to reset the fast transition bits in the key management
+ * bitmask.
+ */
+void StaNetwork::resetFastTransitionKeyMgmt(uint32_t &key_mgmt_mask)
+{
+	if (key_mgmt_mask & WPA_KEY_MGMT_PSK) {
+		key_mgmt_mask &= ~WPA_KEY_MGMT_FT_PSK;
+	}
+
+	if (key_mgmt_mask & WPA_KEY_MGMT_IEEE8021X) {
+		key_mgmt_mask &= ~WPA_KEY_MGMT_FT_IEEE8021X;
+	}
+#ifdef CONFIG_IEEE80211R
+#ifdef CONFIG_SAE
+	if (key_mgmt_mask & WPA_KEY_MGMT_SAE) {
+		key_mgmt_mask &= ~WPA_KEY_MGMT_FT_SAE;
+	}
+#endif
+#endif
+}
+
+/**
+ * Helper function to enable erp keys generation while connecting to FILS
+ * enabled APs.
+ */
+ndk::ScopedAStatus StaNetwork::setEapErpInternal(bool enable)
+{
+#ifdef CONFIG_FILS
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	wpa_ssid->eap.erp = enable ? 1 : 0;
+	return ndk::ScopedAStatus::ok();
+#else /* CONFIG_FILS */
+	return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+#endif /* CONFIG_FILS */
+}
+
+ndk::ScopedAStatus StaNetwork::setSaeH2eModeInternal(
+	SaeH2eMode mode)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	switch (mode) {
+	case SaeH2eMode::DISABLED:
+		wpa_s->conf->sae_pwe = 0;
+		break;
+	case SaeH2eMode::H2E_MANDATORY:
+		wpa_s->conf->sae_pwe = 1;
+		break;
+	case SaeH2eMode::H2E_OPTIONAL:
+		wpa_s->conf->sae_pwe = 2;
+		break;
+	}
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus StaNetwork::enableSaePkOnlyModeInternal(bool enable)
+{
+#ifdef CONFIG_SAE_PK
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	wpa_ssid->sae_pk = enable ? SAE_PK_MODE_ONLY : SAE_PK_MODE_AUTOMATIC;
+	resetInternalStateAfterParamsUpdate();
+	return ndk::ScopedAStatus::ok();
+#else
+	return createStatus(SupplicantStatusCode::FAILURE_UNSUPPORTED);
+#endif
+}
+
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wpa_supplicant/aidl/sta_network.h b/wpa_supplicant/aidl/sta_network.h
new file mode 100644
index 0000000..5105669
--- /dev/null
+++ b/wpa_supplicant/aidl/sta_network.h
@@ -0,0 +1,349 @@
+/*
+ * WPA Supplicant - Sta network Aidl interface
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef WPA_SUPPLICANT_AIDL_STA_NETWORK_H
+#define WPA_SUPPLICANT_AIDL_STA_NETWORK_H
+
+#include <array>
+#include <vector>
+
+#include <android-base/macros.h>
+
+#include <aidl/android/hardware/wifi/supplicant/BnSupplicantStaNetwork.h>
+#include <aidl/android/hardware/wifi/supplicant/EapMethod.h>
+#include <aidl/android/hardware/wifi/supplicant/EapPhase2Method.h>
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantStaNetworkCallback.h>
+#include <aidl/android/hardware/wifi/supplicant/NetworkRequestEapSimUmtsAuthParams.h>
+#include <aidl/android/hardware/wifi/supplicant/NetworkResponseEapSimUmtsAuthParams.h>
+#include <aidl/android/hardware/wifi/supplicant/SaeH2eMode.h>
+#include <aidl/android/hardware/wifi/supplicant/DppConnectionKeys.h>
+
+extern "C"
+{
+#include "utils/common.h"
+#include "utils/includes.h"
+#include "config.h"
+#include "wpa_supplicant_i.h"
+#include "notify.h"
+#include "eapol_supp/eapol_supp_sm.h"
+#include "eap_peer/eap.h"
+#include "rsn_supp/wpa.h"
+}
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+
+/**
+ * Implementation of StaNetwork aidl object. Each unique aidl
+ * object is used for control operations on a specific network
+ * controlled by wpa_supplicant.
+ */
+class StaNetwork : public BnSupplicantStaNetwork
+{
+public:
+	StaNetwork(
+		struct wpa_global* wpa_global, const char ifname[], int network_id);
+	~StaNetwork() override = default;
+	// Refer to |StaIface::invalidate()|.
+	void invalidate();
+	bool isValid();
+
+	// Aidl methods exposed.
+  	::ndk::ScopedAStatus getId(int32_t* _aidl_return) override;
+	::ndk::ScopedAStatus getInterfaceName(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getType(IfaceType* _aidl_return) override;
+	::ndk::ScopedAStatus registerCallback(
+		const std::shared_ptr<ISupplicantStaNetworkCallback>& in_callback) override;
+	::ndk::ScopedAStatus setSsid(const std::vector<uint8_t>& in_ssid) override;
+	::ndk::ScopedAStatus setBssid(const std::vector<uint8_t>& in_bssid) override;
+	::ndk::ScopedAStatus setDppKeys(const DppConnectionKeys& in_keys) override;
+	::ndk::ScopedAStatus setScanSsid(bool in_enable) override;
+	::ndk::ScopedAStatus setKeyMgmt(KeyMgmtMask in_keyMgmtMask) override;
+	::ndk::ScopedAStatus setProto(ProtoMask in_protoMask) override;
+	::ndk::ScopedAStatus setAuthAlg(AuthAlgMask in_authAlgMask) override;
+	::ndk::ScopedAStatus setGroupCipher(GroupCipherMask in_groupCipherMask) override;
+	::ndk::ScopedAStatus setPairwiseCipher(
+		PairwiseCipherMask in_pairwiseCipherMask) override;
+	::ndk::ScopedAStatus setPskPassphrase(const std::string& in_psk) override;
+	::ndk::ScopedAStatus setPsk(const std::vector<uint8_t>& in_psk) override;
+	::ndk::ScopedAStatus setWepKey(
+		int32_t in_keyIdx, const std::vector<uint8_t>& in_wepKey) override;
+	::ndk::ScopedAStatus setWepTxKeyIdx(int32_t in_keyIdx) override;
+	::ndk::ScopedAStatus setRequirePmf(bool in_enable) override;
+	::ndk::ScopedAStatus setEapMethod(EapMethod in_method) override;
+	::ndk::ScopedAStatus setEapPhase2Method(EapPhase2Method in_method) override;
+	::ndk::ScopedAStatus setEapIdentity(
+		const std::vector<uint8_t>& in_identity) override;
+	::ndk::ScopedAStatus setEapEncryptedImsiIdentity(
+		const std::vector<uint8_t>& in_identity) override;
+	::ndk::ScopedAStatus setEapAnonymousIdentity(
+		const std::vector<uint8_t>& in_identity) override;
+	::ndk::ScopedAStatus setEapPassword(
+		const std::vector<uint8_t>& in_password) override;
+	::ndk::ScopedAStatus setEapCACert(const std::string& in_path) override;
+	::ndk::ScopedAStatus setEapCAPath(const std::string& in_path) override;
+	::ndk::ScopedAStatus setEapClientCert(const std::string& in_path) override;
+	::ndk::ScopedAStatus setEapPrivateKeyId(const std::string& in_id) override;
+	::ndk::ScopedAStatus setEapSubjectMatch(const std::string& in_match) override;
+	::ndk::ScopedAStatus setEapAltSubjectMatch(const std::string& in_match) override;
+	::ndk::ScopedAStatus setEapEngine(bool in_enable) override;
+	::ndk::ScopedAStatus setEapEngineID(const std::string& in_id) override;
+	::ndk::ScopedAStatus setEapDomainSuffixMatch(
+		const std::string& in_match) override;
+	::ndk::ScopedAStatus setProactiveKeyCaching(bool in_enable) override;
+	::ndk::ScopedAStatus setIdStr(const std::string& in_idStr) override;
+	::ndk::ScopedAStatus setUpdateIdentifier(int32_t in_id) override;
+	::ndk::ScopedAStatus setEdmg(bool in_enable) override;
+	::ndk::ScopedAStatus getSsid(std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus getBssid(std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus getScanSsid(bool* _aidl_return) override;
+	::ndk::ScopedAStatus getKeyMgmt(KeyMgmtMask* _aidl_return) override;
+	::ndk::ScopedAStatus getProto(ProtoMask* _aidl_return) override;
+	::ndk::ScopedAStatus getAuthAlg(AuthAlgMask* _aidl_return) override;
+	::ndk::ScopedAStatus getGroupCipher(GroupCipherMask* _aidl_return) override;
+	::ndk::ScopedAStatus getPairwiseCipher(PairwiseCipherMask* _aidl_return) override;
+	::ndk::ScopedAStatus getPskPassphrase(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getPsk(std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus getSaePassword(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getSaePasswordId(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getWepKey(
+		int32_t in_keyIdx, std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus getWepTxKeyIdx(int32_t* _aidl_return) override;
+	::ndk::ScopedAStatus getRequirePmf(bool* _aidl_return) override;
+	::ndk::ScopedAStatus getEapMethod(EapMethod* _aidl_return) override;
+	::ndk::ScopedAStatus getEapPhase2Method(EapPhase2Method* _aidl_return) override;
+	::ndk::ScopedAStatus getEapIdentity(std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus getEapAnonymousIdentity(
+		std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus getEapPassword(std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus getEapCACert(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getEapCAPath(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getEapClientCert(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getEapPrivateKeyId(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getEapSubjectMatch(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getEapAltSubjectMatch(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getEapEngine(bool* _aidl_return) override;
+	::ndk::ScopedAStatus getEapEngineId(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getEapDomainSuffixMatch(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getIdStr(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus getWpsNfcConfigurationToken(
+		std::vector<uint8_t>* _aidl_return) override;
+	::ndk::ScopedAStatus getEdmg(bool* _aidl_return) override;
+	::ndk::ScopedAStatus enable(bool in_noConnect) override;
+	::ndk::ScopedAStatus disable() override;
+	::ndk::ScopedAStatus select() override;
+	::ndk::ScopedAStatus sendNetworkEapSimGsmAuthResponse(
+		const std::vector<NetworkResponseEapSimGsmAuthParams>& in_params) override;
+	::ndk::ScopedAStatus sendNetworkEapSimGsmAuthFailure() override;
+	::ndk::ScopedAStatus sendNetworkEapSimUmtsAuthResponse(
+		const NetworkResponseEapSimUmtsAuthParams& in_params) override;
+	::ndk::ScopedAStatus sendNetworkEapSimUmtsAutsResponse(
+		const std::vector<uint8_t>& in_auts) override;
+	::ndk::ScopedAStatus sendNetworkEapSimUmtsAuthFailure() override;
+	::ndk::ScopedAStatus sendNetworkEapIdentityResponse(
+		const std::vector<uint8_t>& in_identity,
+		const std::vector<uint8_t>& in_encryptedIdentity) override;
+	::ndk::ScopedAStatus setGroupMgmtCipher(
+		GroupMgmtCipherMask in_groupMgmtCipherMask) override;
+	::ndk::ScopedAStatus getGroupMgmtCipher(
+		GroupMgmtCipherMask* _aidl_return) override;
+	::ndk::ScopedAStatus enableTlsSuiteBEapPhase1Param(
+		bool in_enable) override;
+	::ndk::ScopedAStatus enableSuiteBEapOpenSslCiphers() override;
+	::ndk::ScopedAStatus setSaePassword(
+		const std::string& in_saePassword) override;
+	::ndk::ScopedAStatus setSaePasswordId(
+		const std::string& in_saePasswordId) override;
+	::ndk::ScopedAStatus setOcsp(OcspType in_ocspType) override;
+	::ndk::ScopedAStatus getOcsp(OcspType* _aidl_return) override;
+	::ndk::ScopedAStatus setPmkCache(
+		const std::vector<uint8_t>& in_serializedEntry) override;
+	::ndk::ScopedAStatus setWapiCertSuite(const std::string& in_suite) override;
+	::ndk::ScopedAStatus getWapiCertSuite(std::string* _aidl_return) override;
+	::ndk::ScopedAStatus setEapErp(bool in_enable) override;
+	::ndk::ScopedAStatus setSaeH2eMode(SaeH2eMode in_mode) override;
+	::ndk::ScopedAStatus enableSaePkOnlyMode(bool in_enable) override;
+	::ndk::ScopedAStatus setRoamingConsortiumSelection(
+		const std::vector<uint8_t>& in_selectedRcoi) override;
+
+private:
+	// Corresponding worker functions for the AIDL methods.
+	std::pair<uint32_t, ndk::ScopedAStatus> getIdInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getInterfaceNameInternal();
+	std::pair<IfaceType, ndk::ScopedAStatus> getTypeInternal();
+	ndk::ScopedAStatus registerCallbackInternal(
+		const std::shared_ptr<ISupplicantStaNetworkCallback>& callback);
+	ndk::ScopedAStatus setSsidInternal(const std::vector<uint8_t>& ssid);
+	ndk::ScopedAStatus setBssidInternal(const std::vector<uint8_t>& bssid);
+	ndk::ScopedAStatus setDppKeysInternal(const DppConnectionKeys& keys);
+	ndk::ScopedAStatus setScanSsidInternal(bool enable);
+	ndk::ScopedAStatus setKeyMgmtInternal(
+		KeyMgmtMask mask);
+	ndk::ScopedAStatus setProtoInternal(
+		ProtoMask mask);
+	ndk::ScopedAStatus setAuthAlgInternal(
+		AuthAlgMask mask);
+	ndk::ScopedAStatus setGroupCipherInternal(
+		GroupCipherMask mask);
+	ndk::ScopedAStatus setPairwiseCipherInternal(
+		PairwiseCipherMask mask);
+	ndk::ScopedAStatus setPskPassphraseInternal(const std::string& psk);
+	ndk::ScopedAStatus setPskInternal(const std::vector<uint8_t>& psk);
+	ndk::ScopedAStatus setWepKeyInternal(
+		uint32_t key_idx, const std::vector<uint8_t>& wep_key);
+	ndk::ScopedAStatus setWepTxKeyIdxInternal(uint32_t key_idx);
+	ndk::ScopedAStatus setRequirePmfInternal(bool enable);
+	ndk::ScopedAStatus setEapMethodInternal(
+		EapMethod method);
+	ndk::ScopedAStatus setEapPhase2MethodInternal(
+		EapPhase2Method method);
+	ndk::ScopedAStatus setEapIdentityInternal(
+		const std::vector<uint8_t>& identity);
+	ndk::ScopedAStatus setEapEncryptedImsiIdentityInternal(
+		const std::vector<uint8_t>& identity);
+	ndk::ScopedAStatus setEapAnonymousIdentityInternal(
+		const std::vector<uint8_t>& identity);
+	ndk::ScopedAStatus setEapPasswordInternal(
+		const std::vector<uint8_t>& password);
+	ndk::ScopedAStatus setEapCACertInternal(const std::string& path);
+	ndk::ScopedAStatus setEapCAPathInternal(const std::string& path);
+	ndk::ScopedAStatus setEapClientCertInternal(const std::string& path);
+	ndk::ScopedAStatus setEapPrivateKeyIdInternal(const std::string& id);
+	ndk::ScopedAStatus setEapSubjectMatchInternal(const std::string& match);
+	ndk::ScopedAStatus setEapAltSubjectMatchInternal(
+		const std::string& match);
+	ndk::ScopedAStatus setEapEngineInternal(bool enable);
+	ndk::ScopedAStatus setEapEngineIDInternal(const std::string& id);
+	ndk::ScopedAStatus setEapDomainSuffixMatchInternal(
+		const std::string& match);
+	ndk::ScopedAStatus setProactiveKeyCachingInternal(bool enable);
+	ndk::ScopedAStatus setIdStrInternal(const std::string& id_str);
+	ndk::ScopedAStatus setUpdateIdentifierInternal(uint32_t id);
+	ndk::ScopedAStatus setEdmgInternal(bool enable);
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> getSsidInternal();
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> getBssidInternal();
+	std::pair<bool, ndk::ScopedAStatus> getScanSsidInternal();
+	std::pair<KeyMgmtMask, ndk::ScopedAStatus> getKeyMgmtInternal();
+	std::pair<ProtoMask, ndk::ScopedAStatus> getProtoInternal();
+	std::pair<AuthAlgMask, ndk::ScopedAStatus> getAuthAlgInternal();
+	std::pair<GroupCipherMask, ndk::ScopedAStatus> getGroupCipherInternal();
+	std::pair<PairwiseCipherMask, ndk::ScopedAStatus> getPairwiseCipherInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getPskPassphraseInternal();
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> getPskInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getSaePasswordInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getSaePasswordIdInternal();
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> getWepKeyInternal(
+		uint32_t key_idx);
+	std::pair<uint32_t, ndk::ScopedAStatus> getWepTxKeyIdxInternal();
+	std::pair<bool, ndk::ScopedAStatus> getRequirePmfInternal();
+	std::pair<EapMethod, ndk::ScopedAStatus> getEapMethodInternal();
+	std::pair<EapPhase2Method, ndk::ScopedAStatus>
+		getEapPhase2MethodInternal();
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+		getEapIdentityInternal();
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+		getEapAnonymousIdentityInternal();
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+		getEapPasswordInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getEapCACertInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getEapCAPathInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getEapClientCertInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getEapPrivateKeyIdInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getEapSubjectMatchInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getEapAltSubjectMatchInternal();
+	std::pair<bool, ndk::ScopedAStatus> getEapEngineInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getEapEngineIdInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getEapDomainSuffixMatchInternal();
+	std::pair<std::string, ndk::ScopedAStatus> getIdStrInternal();
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
+		getWpsNfcConfigurationTokenInternal();
+	std::pair<bool, ndk::ScopedAStatus> getEdmgInternal();
+	ndk::ScopedAStatus enableInternal(bool no_connect);
+	ndk::ScopedAStatus disableInternal();
+	ndk::ScopedAStatus selectInternal();
+	ndk::ScopedAStatus sendNetworkEapSimGsmAuthResponseInternal(
+		const std::vector<NetworkResponseEapSimGsmAuthParams>&
+		vec_params);
+	ndk::ScopedAStatus sendNetworkEapSimGsmAuthFailureInternal();
+	ndk::ScopedAStatus sendNetworkEapSimUmtsAuthResponseInternal(
+		const NetworkResponseEapSimUmtsAuthParams& params);
+	ndk::ScopedAStatus sendNetworkEapSimUmtsAutsResponseInternal(
+		const std::vector<uint8_t>& auts);
+	ndk::ScopedAStatus sendNetworkEapSimUmtsAuthFailureInternal();
+	ndk::ScopedAStatus sendNetworkEapIdentityResponseInternal(
+		const std::vector<uint8_t>& identity,
+		const std::vector<uint8_t>& imsi_identity);
+	ndk::ScopedAStatus enableTlsSuiteBEapPhase1ParamInternal(bool enable);
+	ndk::ScopedAStatus enableSuiteBEapOpenSslCiphersInternal();
+	ndk::ScopedAStatus setSaePasswordInternal(
+		const std::string& sae_password);
+	ndk::ScopedAStatus setSaePasswordIdInternal(
+		const std::string& sae_password_id);
+	ndk::ScopedAStatus setGroupMgmtCipherInternal(
+		GroupMgmtCipherMask mask);
+	std::pair<GroupMgmtCipherMask, ndk::ScopedAStatus>
+		getGroupMgmtCipherInternal();
+	ndk::ScopedAStatus setOcspInternal(OcspType ocspType);
+	std::pair<OcspType, ndk::ScopedAStatus> getOcspInternal();
+	ndk::ScopedAStatus setPmkCacheInternal(const std::vector<uint8_t>& serializedEntry);
+	ndk::ScopedAStatus setWapiCertSuiteInternal(const std::string& suite);
+	std::pair<std::string, ndk::ScopedAStatus> getWapiCertSuiteInternal();
+	ndk::ScopedAStatus setWapiPskInternal(const std::vector<uint8_t>& psk);
+	std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> getWapiPskInternal();
+	ndk::ScopedAStatus setSaeH2eModeInternal(SaeH2eMode mode);
+	ndk::ScopedAStatus enableSaePkOnlyModeInternal(bool enable);
+	ndk::ScopedAStatus setRoamingConsortiumSelectionInternal(
+		const std::vector<uint8_t>& selectedRcoi);
+
+	struct wpa_ssid* retrieveNetworkPtr();
+	struct wpa_supplicant* retrieveIfacePtr();
+	int isPskPassphraseValid(const std::string& psk);
+	void resetInternalStateAfterParamsUpdate();
+	int setStringFieldAndResetState(
+		const char* value, uint8_t** to_update_field,
+		const char* hexdump_prefix);
+	int setStringFieldAndResetState(
+		const char* value, char** to_update_field,
+		const char* hexdump_prefix);
+	int setStringKeyFieldAndResetState(
+		const char* value, char** to_update_field,
+		const char* hexdump_prefix);
+	int setByteArrayFieldAndResetState(
+		const uint8_t* value, const size_t value_len,
+		uint8_t** to_update_field, size_t* to_update_field_len,
+		const char* hexdump_prefix);
+	int setByteArrayKeyFieldAndResetState(
+		const uint8_t* value, const size_t value_len,
+		uint8_t** to_update_field, size_t* to_update_field_len,
+		const char* hexdump_prefix);
+	void setFastTransitionKeyMgmt(uint32_t &key_mgmt_mask);
+	void resetFastTransitionKeyMgmt(uint32_t &key_mgmt_mask);
+	ndk::ScopedAStatus setEapErpInternal(bool enable);
+
+	// Reference to the global wpa_struct. This is assumed to be valid
+	// for the lifetime of the process.
+	struct wpa_global* wpa_global_;
+	// Name of the iface this network belongs to.
+	const std::string ifname_;
+	// Id of the network this aidl object controls.
+	const int network_id_;
+	bool is_valid_;
+
+	DISALLOW_COPY_AND_ASSIGN(StaNetwork);
+};
+
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WPA_SUPPLICANT_AIDL_STA_NETWORK_H
diff --git a/wpa_supplicant/aidl/supplicant.cpp b/wpa_supplicant/aidl/supplicant.cpp
new file mode 100644
index 0000000..208491c
--- /dev/null
+++ b/wpa_supplicant/aidl/supplicant.cpp
@@ -0,0 +1,544 @@
+/*
+ * WPA Supplicant - Supplicant Aidl interface
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include "aidl_manager.h"
+#include "aidl_return_util.h"
+#include "misc_utils.h"
+#include "supplicant.h"
+#include "p2p_iface.h"
+
+#include <android-base/file.h>
+#include <fcntl.h>
+#include <sys/stat.h>
+
+namespace {
+
+// Pre-populated interface params for interfaces controlled by wpa_supplicant.
+// Note: This may differ for other OEM's. So, modify this accordingly.
+constexpr char kIfaceDriverName[] = "nl80211";
+constexpr char kStaIfaceConfPath[] =
+	"/data/vendor/wifi/wpa/wpa_supplicant.conf";
+static const char* kStaIfaceConfOverlayPaths[] = {
+    "/apex/com.android.wifi.hal/etc/wifi/wpa_supplicant_overlay.conf",
+    "/vendor/etc/wifi/wpa_supplicant_overlay.conf",
+};
+constexpr char kP2pIfaceConfPath[] =
+	"/data/vendor/wifi/wpa/p2p_supplicant.conf";
+static const char* kP2pIfaceConfOverlayPaths[] = {
+    "/apex/com.android.wifi.hal/etc/wifi/p2p_supplicant_overlay.conf",
+    "/vendor/etc/wifi/p2p_supplicant_overlay.conf",
+};
+// Migrate conf files for existing devices.
+static const char* kTemplateConfPaths[] = {
+    "/apex/com.android.wifi.hal/etc/wifi/wpa_supplicant.conf",
+    "/vendor/etc/wifi/wpa_supplicant.conf",
+    "/system/etc/wifi/wpa_supplicant.conf",
+};
+constexpr char kOldStaIfaceConfPath[] = "/data/misc/wifi/wpa_supplicant.conf";
+constexpr char kOldP2pIfaceConfPath[] = "/data/misc/wifi/p2p_supplicant.conf";
+constexpr mode_t kConfigFileMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
+
+const char* resolvePath(const char* paths[], size_t size)
+{
+	for (int i = 0; i < size; ++i) {
+		if (access(paths[i], R_OK) == 0) {
+			return paths[i];
+		}
+	}
+	return nullptr;
+}
+
+int copyFile(
+	const std::string& src_file_path, const std::string& dest_file_path)
+{
+	std::string file_contents;
+	if (!android::base::ReadFileToString(src_file_path, &file_contents)) {
+		wpa_printf(
+			MSG_ERROR, "Failed to read from %s. Errno: %s",
+			src_file_path.c_str(), strerror(errno));
+		return -1;
+	}
+	if (!android::base::WriteStringToFile(
+		file_contents, dest_file_path, kConfigFileMode, getuid(),
+		getgid())) {
+		wpa_printf(
+			MSG_ERROR, "Failed to write to %s. Errno: %s",
+			dest_file_path.c_str(), strerror(errno));
+		return -1;
+	}
+	return 0;
+}
+
+/**
+ * Copy |src_file_path| to |dest_file_path| if it exists.
+ *
+ * Returns 1 if |src_file_path| does not exist or not accessible,
+ * Returns -1 if the copy fails.
+ * Returns 0 if the copy succeeds.
+ */
+int copyFileIfItExists(
+	const std::string& src_file_path, const std::string& dest_file_path)
+{
+	int ret = access(src_file_path.c_str(), R_OK);
+	// Sepolicy denial (2018+ device) will return EACCESS instead of ENOENT.
+	if ((ret != 0) && ((errno == ENOENT) || (errno == EACCES))) {
+		return 1;
+	}
+	ret = copyFile(src_file_path, dest_file_path);
+	if (ret != 0) {
+		wpa_printf(
+			MSG_ERROR, "Failed copying %s to %s.",
+			src_file_path.c_str(), dest_file_path.c_str());
+		return -1;
+	}
+	return 0;
+}
+
+/**
+ * Ensure that the specified config file pointed by |config_file_path| exists.
+ * a) If the |config_file_path| exists with the correct permissions, return.
+ * b) If the |config_file_path| does not exist, but |old_config_file_path|
+ * exists, copy over the contents of the |old_config_file_path| to
+ * |config_file_path|.
+ * c) If the |config_file_path| & |old_config_file_path|
+ * does not exists, copy over the contents of |template_config_file_path|.
+ */
+int ensureConfigFileExists(
+	const std::string& config_file_path,
+	const std::string& old_config_file_path)
+{
+	int ret = access(config_file_path.c_str(), R_OK | W_OK);
+	if (ret == 0) {
+		return 0;
+	}
+	if (errno == EACCES) {
+		ret = chmod(config_file_path.c_str(), kConfigFileMode);
+		if (ret == 0) {
+			return 0;
+		} else {
+			wpa_printf(
+				MSG_ERROR, "Cannot set RW to %s. Errno: %s",
+				config_file_path.c_str(), strerror(errno));
+			return -1;
+		}
+	} else if (errno != ENOENT) {
+		wpa_printf(
+			MSG_ERROR, "Cannot acces %s. Errno: %s",
+			config_file_path.c_str(), strerror(errno));
+		return -1;
+	}
+	ret = copyFileIfItExists(old_config_file_path, config_file_path);
+	if (ret == 0) {
+		wpa_printf(
+			MSG_INFO, "Migrated conf file from %s to %s",
+			old_config_file_path.c_str(), config_file_path.c_str());
+		unlink(old_config_file_path.c_str());
+		return 0;
+	} else if (ret == -1) {
+		unlink(config_file_path.c_str());
+		return -1;
+	}
+	const char* path =
+	    resolvePath(kTemplateConfPaths, sizeof(kTemplateConfPaths));
+	if (path != nullptr) {
+		ret = copyFileIfItExists(path, config_file_path);
+		if (ret == 0) {
+			wpa_printf(
+			    MSG_INFO, "Copied template conf file from %s to %s",
+			    path, config_file_path.c_str());
+			return 0;
+		} else if (ret == -1) {
+			unlink(config_file_path.c_str());
+			return -1;
+		}
+	}
+	// Did not create the conf file.
+	return -1;
+}
+}  // namespace
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+using aidl_return_util::validateAndCall;
+using misc_utils::createStatus;
+using misc_utils::createStatusWithMsg;
+
+Supplicant::Supplicant(struct wpa_global* global) : wpa_global_(global) {}
+bool Supplicant::isValid()
+{
+	// This top level object cannot be invalidated.
+	return true;
+}
+
+::ndk::ScopedAStatus Supplicant::addP2pInterface(
+	const std::string& in_name,
+	std::shared_ptr<ISupplicantP2pIface>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&Supplicant::addP2pInterfaceInternal, _aidl_return, in_name);
+}
+
+::ndk::ScopedAStatus Supplicant::addStaInterface(
+	const std::string& in_name,
+	std::shared_ptr<ISupplicantStaIface>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&Supplicant::addStaInterfaceInternal, _aidl_return, in_name);
+}
+
+::ndk::ScopedAStatus Supplicant::removeInterface(
+	const IfaceInfo& in_ifaceInfo)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&Supplicant::removeInterfaceInternal, in_ifaceInfo);
+}
+
+::ndk::ScopedAStatus Supplicant::getP2pInterface(
+	const std::string& in_name,
+	std::shared_ptr<ISupplicantP2pIface>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&Supplicant::getP2pInterfaceInternal, _aidl_return, in_name);
+}
+
+::ndk::ScopedAStatus Supplicant::getStaInterface(
+	const std::string& in_name,
+	std::shared_ptr<ISupplicantStaIface>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&Supplicant::getStaInterfaceInternal, _aidl_return, in_name);
+}
+
+::ndk::ScopedAStatus Supplicant::listInterfaces(
+	std::vector<IfaceInfo>* _aidl_return)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&Supplicant::listInterfacesInternal, _aidl_return);
+}
+
+::ndk::ScopedAStatus Supplicant::registerCallback(
+	const std::shared_ptr<ISupplicantCallback>& in_callback)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&Supplicant::registerCallbackInternal, in_callback);
+}
+
+::ndk::ScopedAStatus Supplicant::setDebugParams(
+	DebugLevel in_level, bool in_showTimestamp,
+	bool in_showKeys)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&Supplicant::setDebugParamsInternal, in_level,
+		in_showTimestamp, in_showKeys);
+}
+
+::ndk::ScopedAStatus Supplicant::setConcurrencyPriority(
+	IfaceType in_type)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
+		&Supplicant::setConcurrencyPriorityInternal, in_type);
+}
+
+::ndk::ScopedAStatus Supplicant::getDebugLevel(DebugLevel* _aidl_return)
+{
+	*_aidl_return = static_cast<DebugLevel>(wpa_debug_level);
+	return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Supplicant::isDebugShowTimestampEnabled(bool* _aidl_return)
+{
+	*_aidl_return = ((wpa_debug_timestamp != 0) ? true : false);
+	return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Supplicant::isDebugShowKeysEnabled(bool* _aidl_return)
+{
+	*_aidl_return = ((wpa_debug_show_keys != 0) ? true : false);
+	return ndk::ScopedAStatus::ok();
+}
+
+::ndk::ScopedAStatus Supplicant::terminate()
+{
+	wpa_printf(MSG_INFO, "Terminating...");
+	wpa_supplicant_terminate_proc(wpa_global_);
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Supplicant::addP2pDevInterface(struct wpa_interface iface_params)
+{
+	char primary_ifname[IFNAMSIZ];
+	u32 primary_ifname_len =
+		strlen(iface_params.ifname) - strlen(P2P_MGMT_DEVICE_PREFIX);
+
+	if(primary_ifname_len > IFNAMSIZ) {
+		wpa_printf(MSG_DEBUG, "%s, Invalid primary iface name ", __FUNCTION__);
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+
+	strncpy(primary_ifname, iface_params.ifname +
+		strlen(P2P_MGMT_DEVICE_PREFIX), primary_ifname_len);
+	wpa_printf(MSG_DEBUG, "%s, Initialize p2p-dev-wlan0 iface with"
+		"primary_iface = %s", __FUNCTION__, primary_ifname);
+	struct wpa_supplicant* wpa_s =
+		wpa_supplicant_get_iface(wpa_global_, primary_ifname);
+	if (!wpa_s) {
+		wpa_printf(MSG_DEBUG, "%s,NULL wpa_s for wlan0", __FUNCTION__);
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
+	}
+	if (wpas_p2p_add_p2pdev_interface(
+		wpa_s, wpa_s->global->params.conf_p2p_dev) < 0) {
+		wpa_printf(MSG_INFO,
+			"Failed to enable P2P Device");
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::shared_ptr<ISupplicantP2pIface>, ndk::ScopedAStatus>
+Supplicant::addP2pInterfaceInternal(const std::string& name)
+{
+	std::shared_ptr<ISupplicantP2pIface> iface;
+
+	// Check if required |ifname| argument is empty.
+	if (name.empty()) {
+		return {nullptr, createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID)};
+	}
+	// Try to get the wpa_supplicant record for this iface, return
+	// the iface object with the appropriate status code if it exists.
+	ndk::ScopedAStatus status;
+	std::tie(iface, status) = getP2pInterfaceInternal(name);
+	if (status.isOk()) {
+		wpa_printf(MSG_INFO, "Iface already exists, return existing");
+		return {iface, ndk::ScopedAStatus::ok()};
+	}
+
+	struct wpa_interface iface_params = {};
+	iface_params.driver = kIfaceDriverName;
+	if (ensureConfigFileExists(
+		kP2pIfaceConfPath, kOldP2pIfaceConfPath) != 0) {
+		wpa_printf(
+			MSG_ERROR, "Conf file does not exists: %s",
+			kP2pIfaceConfPath);
+		return {nullptr, createStatusWithMsg(
+			SupplicantStatusCode::FAILURE_UNKNOWN, "Conf file does not exist")};
+	}
+	iface_params.confname = kP2pIfaceConfPath;
+	const char* path = resolvePath(
+		    kP2pIfaceConfOverlayPaths,
+		    sizeof(kP2pIfaceConfOverlayPaths));
+	if (path != nullptr) {
+		iface_params.confanother = path;
+	}
+
+	iface_params.ifname = name.c_str();
+	if (strncmp(iface_params.ifname, P2P_MGMT_DEVICE_PREFIX,
+		strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
+		status = addP2pDevInterface(iface_params);
+		if (!status.isOk()) {
+			return {iface, createStatus(static_cast<SupplicantStatusCode>(
+				status.getServiceSpecificError()))};
+		}
+	} else {
+		struct wpa_supplicant* wpa_s =
+			wpa_supplicant_add_iface(wpa_global_, &iface_params, NULL);
+		if (!wpa_s) {
+			return {nullptr, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+		}
+		// Request the current scan results from the driver and update
+		// the local BSS list wpa_s->bss. This is to avoid a full scan
+		// while processing the connect request on newly created interface.
+		wpa_supplicant_update_scan_results(wpa_s);
+	}
+	// The supplicant core creates a corresponding aidl object via
+	// AidlManager when |wpa_supplicant_add_iface| is called.
+	return getP2pInterfaceInternal(name);
+}
+
+std::pair<std::shared_ptr<ISupplicantStaIface>, ndk::ScopedAStatus>
+Supplicant::addStaInterfaceInternal(const std::string& name)
+{
+	std::shared_ptr<ISupplicantStaIface> iface;
+
+	// Check if required |ifname| argument is empty.
+	if (name.empty()) {
+		return {nullptr, createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID)};
+	}
+	// Try to get the wpa_supplicant record for this iface, return
+	// the iface object with the appropriate status code if it exists.
+	ndk::ScopedAStatus status;
+	std::tie(iface, status) = getStaInterfaceInternal(name);
+	if (status.isOk()) {
+		wpa_printf(MSG_INFO, "Iface already exists, return existing");
+		return {iface, ndk::ScopedAStatus::ok()};
+	}
+
+	struct wpa_interface iface_params = {};
+	iface_params.driver = kIfaceDriverName;
+	if (ensureConfigFileExists(
+		kStaIfaceConfPath, kOldStaIfaceConfPath) != 0) {
+		wpa_printf(
+			MSG_ERROR, "Conf file does not exists: %s",
+			kStaIfaceConfPath);
+		return {nullptr, createStatusWithMsg(
+			SupplicantStatusCode::FAILURE_UNKNOWN, "Conf file does not exist")};
+	}
+	iface_params.confname = kStaIfaceConfPath;
+	const char* path = resolvePath(
+		    kStaIfaceConfOverlayPaths,
+		    sizeof(kStaIfaceConfOverlayPaths));
+	if (path != nullptr) {
+		iface_params.confanother = path;
+	}
+
+	iface_params.ifname = name.c_str();
+	if (strncmp(iface_params.ifname, P2P_MGMT_DEVICE_PREFIX,
+		strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
+		status = addP2pDevInterface(iface_params);
+		if (!status.isOk()) {
+			return {iface, createStatus(static_cast<SupplicantStatusCode>(
+				status.getServiceSpecificError()))};
+		}
+	} else {
+		struct wpa_supplicant* wpa_s =
+			wpa_supplicant_add_iface(wpa_global_, &iface_params, NULL);
+		if (!wpa_s) {
+			return {nullptr, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+		}
+		// Request the current scan results from the driver and update
+		// the local BSS list wpa_s->bss. This is to avoid a full scan
+		// while processing the connect request on newly created interface.
+		wpa_supplicant_update_scan_results(wpa_s);
+	}
+	// The supplicant core creates a corresponding aidl object via
+	// AidlManager when |wpa_supplicant_add_iface| is called.
+	return getStaInterfaceInternal(name);
+}
+
+ndk::ScopedAStatus Supplicant::removeInterfaceInternal(
+	const IfaceInfo& iface_info)
+{
+	struct wpa_supplicant* wpa_s =
+		wpa_supplicant_get_iface(wpa_global_, iface_info.name.c_str());
+	if (!wpa_s) {
+		return createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
+	}
+	if (wpa_supplicant_remove_iface(wpa_global_, wpa_s, 0)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+std::pair<std::shared_ptr<ISupplicantP2pIface>, ndk::ScopedAStatus>
+Supplicant::getP2pInterfaceInternal(const std::string& name)
+{
+	struct wpa_supplicant* wpa_s =
+		wpa_supplicant_get_iface(wpa_global_, name.c_str());
+	if (!wpa_s) {
+		return {nullptr, createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN)};
+	}
+	AidlManager* aidl_manager = AidlManager::getInstance();
+	std::shared_ptr<ISupplicantP2pIface> iface;
+	if (!aidl_manager ||
+		aidl_manager->getP2pIfaceAidlObjectByIfname(
+		wpa_s->ifname, &iface)) {
+		return {iface, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	// Set this flag true here, since there is no AIDL initialize
+	// method for the p2p config, and the supplicant interface is
+	// not ready when the p2p iface is created.
+	wpa_s->conf->persistent_reconnect = true;
+	return {iface, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::shared_ptr<ISupplicantStaIface>, ndk::ScopedAStatus>
+Supplicant::getStaInterfaceInternal(const std::string& name)
+{
+	struct wpa_supplicant* wpa_s =
+		wpa_supplicant_get_iface(wpa_global_, name.c_str());
+	if (!wpa_s) {
+		return {nullptr, createStatus(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN)};
+	}
+	AidlManager* aidl_manager = AidlManager::getInstance();
+	std::shared_ptr<ISupplicantStaIface> iface;
+	if (!aidl_manager ||
+		aidl_manager->getStaIfaceAidlObjectByIfname(
+		wpa_s->ifname, &iface)) {
+		return {iface, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
+	}
+	return {iface, ndk::ScopedAStatus::ok()};
+}
+
+std::pair<std::vector<IfaceInfo>, ndk::ScopedAStatus>
+Supplicant::listInterfacesInternal()
+{
+	std::vector<IfaceInfo> ifaces;
+	for (struct wpa_supplicant* wpa_s = wpa_global_->ifaces; wpa_s;
+		 wpa_s = wpa_s->next) {
+		if (wpa_s->global->p2p_init_wpa_s == wpa_s) {
+			ifaces.emplace_back(IfaceInfo{
+				IfaceType::P2P, wpa_s->ifname});
+		} else {
+			ifaces.emplace_back(IfaceInfo{
+				IfaceType::STA, wpa_s->ifname});
+		}
+	}
+	return {std::move(ifaces), ndk::ScopedAStatus::ok()};
+}
+
+ndk::ScopedAStatus Supplicant::registerCallbackInternal(
+	const std::shared_ptr<ISupplicantCallback>& callback)
+{
+	AidlManager* aidl_manager = AidlManager::getInstance();
+	if (!aidl_manager ||
+		aidl_manager->addSupplicantCallbackAidlObject(callback)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Supplicant::setDebugParamsInternal(
+	DebugLevel level, bool show_timestamp, bool show_keys)
+{
+	if (wpa_supplicant_set_debug_params(
+		wpa_global_, static_cast<uint32_t>(level), show_timestamp,
+		show_keys)) {
+		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+
+ndk::ScopedAStatus Supplicant::setConcurrencyPriorityInternal(IfaceType type)
+{
+	if (type == IfaceType::STA) {
+		wpa_global_->conc_pref =
+			wpa_global::wpa_conc_pref::WPA_CONC_PREF_STA;
+	} else if (type == IfaceType::P2P) {
+		wpa_global_->conc_pref =
+			wpa_global::wpa_conc_pref::WPA_CONC_PREF_P2P;
+	} else {
+		return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	return ndk::ScopedAStatus::ok();
+}
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
diff --git a/wpa_supplicant/aidl/supplicant.h b/wpa_supplicant/aidl/supplicant.h
new file mode 100644
index 0000000..cbe9a67
--- /dev/null
+++ b/wpa_supplicant/aidl/supplicant.h
@@ -0,0 +1,111 @@
+/*
+ * WPA Supplicant - Supplicant Aidl interface
+ * Copyright (c) 2021, Google Inc. All rights reserved.
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#ifndef WPA_SUPPLICANT_AIDL_SUPPLICANT_H
+#define WPA_SUPPLICANT_AIDL_SUPPLICANT_H
+
+#include <aidl/android/hardware/wifi/supplicant/BnSupplicant.h>
+#include <aidl/android/hardware/wifi/supplicant/DebugLevel.h>
+#include <aidl/android/hardware/wifi/supplicant/IfaceInfo.h>
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantCallback.h>
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantP2pIface.h>
+#include <aidl/android/hardware/wifi/supplicant/ISupplicantStaIface.h>
+
+#include <android-base/macros.h>
+
+extern "C"
+{
+#include "utils/common.h"
+#include "utils/includes.h"
+#include "utils/wpa_debug.h"
+#include "wpa_supplicant_i.h"
+#include "scan.h"
+}
+
+namespace aidl {
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+
+/**
+ * Implementation of the supplicant aidl object. This aidl
+ * object is used core for global control operations on
+ * wpa_supplicant.
+ */
+class Supplicant : public BnSupplicant
+{
+public:
+	Supplicant(struct wpa_global* global);
+	~Supplicant() override = default;
+	bool isValid();
+
+	// Aidl methods exposed.
+  	::ndk::ScopedAStatus addP2pInterface(
+		  const std::string& in_name,
+		  std::shared_ptr<ISupplicantP2pIface>* _aidl_return) override;
+	::ndk::ScopedAStatus addStaInterface(
+		const std::string& in_name,
+		std::shared_ptr<ISupplicantStaIface>* _aidl_return) override;
+	::ndk::ScopedAStatus removeInterface(
+		const IfaceInfo& in_ifaceInfo) override;
+	::ndk::ScopedAStatus getP2pInterface(
+		const std::string& in_name,
+		std::shared_ptr<ISupplicantP2pIface>* _aidl_return) override;
+	::ndk::ScopedAStatus getStaInterface(
+		const std::string& in_name,
+		std::shared_ptr<ISupplicantStaIface>* _aidl_return) override;
+	::ndk::ScopedAStatus listInterfaces(
+		std::vector<IfaceInfo>* _aidl_return) override;
+	::ndk::ScopedAStatus registerCallback(
+		const std::shared_ptr<ISupplicantCallback>& in_callback) override;
+	::ndk::ScopedAStatus setDebugParams(
+		DebugLevel in_level, bool in_showTimestamp, bool in_showKeys) override;
+	::ndk::ScopedAStatus getDebugLevel(DebugLevel* _aidl_return) override;
+	::ndk::ScopedAStatus isDebugShowTimestampEnabled(bool* _aidl_return) override;
+	::ndk::ScopedAStatus isDebugShowKeysEnabled(bool* _aidl_return) override;
+	::ndk::ScopedAStatus setConcurrencyPriority(IfaceType in_type) override;
+	::ndk::ScopedAStatus terminate() override;
+
+private:
+	// Corresponding worker functions for the AIDL methods.
+	std::pair<std::shared_ptr<ISupplicantP2pIface>, ndk::ScopedAStatus>
+		addP2pInterfaceInternal(const std::string& name);
+	std::pair<std::shared_ptr<ISupplicantStaIface>, ndk::ScopedAStatus>
+		addStaInterfaceInternal(const std::string& name);
+	std::pair<std::shared_ptr<ISupplicantP2pIface>, ndk::ScopedAStatus>
+		getP2pInterfaceInternal(const std::string& name);
+	std::pair<std::shared_ptr<ISupplicantStaIface>, ndk::ScopedAStatus>
+		getStaInterfaceInternal(const std::string& name);
+	
+	ndk::ScopedAStatus removeInterfaceInternal(const IfaceInfo& iface_info);
+	std::pair<std::vector<IfaceInfo>, ndk::ScopedAStatus> listInterfacesInternal();
+	ndk::ScopedAStatus registerCallbackInternal(
+		const std::shared_ptr<ISupplicantCallback>& callback);
+	ndk::ScopedAStatus setDebugParamsInternal(
+		DebugLevel level, bool show_timestamp, bool show_keys);
+	ndk::ScopedAStatus setConcurrencyPriorityInternal(IfaceType type);
+	ndk::ScopedAStatus addP2pDevInterface(struct wpa_interface iface_params);
+
+	// Raw pointer to the global structure maintained by the core.
+	struct wpa_global* wpa_global_;
+	// Driver name to be used for creating interfaces.
+	static const char kDriverName[];
+	// wpa_supplicant.conf file location on the device.
+	static const char kConfigFilePath[];
+
+	DISALLOW_COPY_AND_ASSIGN(Supplicant);
+};
+
+}  // namespace supplicant
+}  // namespace wifi
+}  // namespace hardware
+}  // namespace android
+}  // namespace aidl
+
+#endif  // WPA_SUPPLICANT_AIDL_SUPPLICANT_H
diff --git a/wpa_supplicant/android.config b/wpa_supplicant/android.config
index 3c0431b..52e4c04 100644
--- a/wpa_supplicant/android.config
+++ b/wpa_supplicant/android.config
@@ -327,9 +327,9 @@
 # Add introspection support for new DBus control interface
 #CONFIG_CTRL_IFACE_DBUS_INTRO=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
 
 # Add support for loading EAP methods dynamically as shared libraries.
 # When this option is enabled, each EAP method can be either included
diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
index d935215..3e43635 100644
--- a/wpa_supplicant/dpp_supplicant.c
+++ b/wpa_supplicant/dpp_supplicant.c
@@ -27,7 +27,7 @@
 #include "scan.h"
 #include "notify.h"
 #include "dpp_supplicant.h"
-#include "hidl.h"
+#include "aidl.h"
 
 
 static int wpas_dpp_listen_start(struct wpa_supplicant *wpa_s,
diff --git a/wpa_supplicant/hidl/1.4/android.hardware.wifi.supplicant-service.rc b/wpa_supplicant/hidl/1.4/android.hardware.wifi.supplicant-service.rc
deleted file mode 100644
index 71318d4..0000000
--- a/wpa_supplicant/hidl/1.4/android.hardware.wifi.supplicant-service.rc
+++ /dev/null
@@ -1,16 +0,0 @@
-service wpa_supplicant /vendor/bin/hw/wpa_supplicant \
-    -O/data/vendor/wifi/wpa/sockets -dd \
-    -g@android:wpa_wlan0
-    #   we will start as root and wpa_supplicant will switch to user wifi
-    #   after setting up the capabilities required for WEXT
-    #   user wifi
-    #   group wifi inet keystore
-    interface android.hardware.wifi.supplicant@1.0::ISupplicant default
-    interface android.hardware.wifi.supplicant@1.1::ISupplicant default
-    interface android.hardware.wifi.supplicant@1.2::ISupplicant default
-    interface android.hardware.wifi.supplicant@1.3::ISupplicant default
-    interface android.hardware.wifi.supplicant@1.4::ISupplicant default
-    class main
-    socket wpa_wlan0 dgram 660 wifi wifi
-    disabled
-    oneshot
diff --git a/wpa_supplicant/hidl/1.4/android.hardware.wifi.supplicant.xml b/wpa_supplicant/hidl/1.4/android.hardware.wifi.supplicant.xml
deleted file mode 100644
index 772096c..0000000
--- a/wpa_supplicant/hidl/1.4/android.hardware.wifi.supplicant.xml
+++ /dev/null
@@ -1,11 +0,0 @@
-<manifest version="1.0" type="device">
-    <hal format="hidl">
-        <name>android.hardware.wifi.supplicant</name>
-        <transport>hwbinder</transport>
-        <version>1.4</version>
-        <interface>
-            <name>ISupplicant</name>
-            <instance>default</instance>
-        </interface>
-    </hal>
-</manifest>
diff --git a/wpa_supplicant/hidl/1.4/hidl.cpp b/wpa_supplicant/hidl/1.4/hidl.cpp
deleted file mode 100644
index 649772a..0000000
--- a/wpa_supplicant/hidl/1.4/hidl.cpp
+++ /dev/null
@@ -1,928 +0,0 @@
-/*
- * hidl interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, 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 "hidl_manager.h"
-
-extern "C"
-{
-#include "hidl.h"
-#include "hidl_i.h"
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "utils/includes.h"
-#include "dpp.h"
-}
-
-using android::hardware::configureRpcThreadpool;
-using android::hardware::handleTransportPoll;
-using android::hardware::setupTransportPolling;
-using android::hardware::wifi::supplicant::V1_3::DppFailureCode;
-using android::hardware::wifi::supplicant::V1_3::DppProgressCode;
-using android::hardware::wifi::supplicant::V1_3::DppSuccessCode;
-using android::hardware::wifi::supplicant::V1_4::implementation::HidlManager;
-
-static void wpas_hidl_notify_dpp_failure(struct wpa_supplicant *wpa_s, DppFailureCode code);
-static void wpas_hidl_notify_dpp_progress(struct wpa_supplicant *wpa_s, DppProgressCode code);
-static void wpas_hidl_notify_dpp_success(struct wpa_supplicant *wpa_s, DppSuccessCode code);
-
-void wpas_hidl_sock_handler(
-    int sock, void * /* eloop_ctx */, void * /* sock_ctx */)
-{
-	handleTransportPoll(sock);
-}
-
-struct wpas_hidl_priv *wpas_hidl_init(struct wpa_global *global)
-{
-	struct wpas_hidl_priv *priv;
-	HidlManager *hidl_manager;
-
-	priv = (wpas_hidl_priv *)os_zalloc(sizeof(*priv));
-	if (!priv)
-		return NULL;
-	priv->global = global;
-
-	wpa_printf(MSG_DEBUG, "Initing hidl control");
-
-	configureRpcThreadpool(1, true /* callerWillJoin */);
-	priv->hidl_fd = setupTransportPolling();
-	if (priv->hidl_fd < 0)
-		goto err;
-
-	wpa_printf(MSG_INFO, "Processing hidl events on FD %d", priv->hidl_fd);
-	// Look for read events from the hidl socket in the eloop.
-	if (eloop_register_read_sock(
-		priv->hidl_fd, wpas_hidl_sock_handler, global, priv) < 0)
-		goto err;
-
-	hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		goto err;
-	if (hidl_manager->registerHidlService(global)) {
-		goto err;
-	}
-	// We may not need to store this hidl manager reference in the
-	// global data strucure because we've made it a singleton class.
-	priv->hidl_manager = (void *)hidl_manager;
-
-	return priv;
-err:
-	wpas_hidl_deinit(priv);
-	return NULL;
-}
-
-void wpas_hidl_deinit(struct wpas_hidl_priv *priv)
-{
-	if (!priv)
-		return;
-
-	wpa_printf(MSG_DEBUG, "Deiniting hidl control");
-
-	HidlManager::destroyInstance();
-	eloop_unregister_read_sock(priv->hidl_fd);
-	os_free(priv);
-}
-
-int wpas_hidl_register_interface(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s || !wpa_s->global->hidl)
-		return 1;
-
-	wpa_printf(
-	    MSG_DEBUG, "Registering interface to hidl control: %s",
-	    wpa_s->ifname);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return 1;
-
-	return hidl_manager->registerInterface(wpa_s);
-}
-
-int wpas_hidl_unregister_interface(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s || !wpa_s->global->hidl)
-		return 1;
-
-	wpa_printf(
-	    MSG_DEBUG, "Deregistering interface from hidl control: %s",
-	    wpa_s->ifname);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return 1;
-
-	return hidl_manager->unregisterInterface(wpa_s);
-}
-
-int wpas_hidl_register_network(
-    struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
-{
-	if (!wpa_s || !wpa_s->global->hidl || !ssid)
-		return 1;
-
-	wpa_printf(
-	    MSG_DEBUG, "Registering network to hidl control: %d", ssid->id);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return 1;
-
-	return hidl_manager->registerNetwork(wpa_s, ssid);
-}
-
-int wpas_hidl_unregister_network(
-    struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
-{
-	if (!wpa_s || !wpa_s->global->hidl || !ssid)
-		return 1;
-
-	wpa_printf(
-	    MSG_DEBUG, "Deregistering network from hidl control: %d", ssid->id);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return 1;
-
-	return hidl_manager->unregisterNetwork(wpa_s, ssid);
-}
-
-int wpas_hidl_notify_state_changed(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s || !wpa_s->global->hidl)
-		return 1;
-
-	wpa_printf(
-	    MSG_DEBUG, "Notifying state change event to hidl control: %d",
-	    wpa_s->wpa_state);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return 1;
-
-	return hidl_manager->notifyStateChange(wpa_s);
-}
-
-int wpas_hidl_notify_network_request(
-    struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
-    enum wpa_ctrl_req_type rtype, const char *default_txt)
-{
-	if (!wpa_s || !wpa_s->global->hidl || !ssid)
-		return 1;
-
-	wpa_printf(
-	    MSG_DEBUG, "Notifying network request to hidl control: %d",
-	    ssid->id);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return 1;
-
-	return hidl_manager->notifyNetworkRequest(
-	    wpa_s, ssid, rtype, default_txt);
-}
-
-void wpas_hidl_notify_anqp_query_done(
-    struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
-    const struct wpa_bss_anqp *anqp)
-{
-	if (!wpa_s || !wpa_s->global->hidl || !bssid || !result || !anqp)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG,
-	    "Notifying ANQP query done to hidl control: " MACSTR "result: %s",
-	    MAC2STR(bssid), result);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyAnqpQueryDone(wpa_s, bssid, result, anqp);
-}
-
-void wpas_hidl_notify_hs20_icon_query_done(
-    struct wpa_supplicant *wpa_s, const u8 *bssid, const char *file_name,
-    const u8 *image, u32 image_length)
-{
-	if (!wpa_s || !wpa_s->global->hidl || !bssid || !file_name || !image)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG,
-	    "Notifying HS20 icon query done to hidl control: " MACSTR
-	    "file_name: %s",
-	    MAC2STR(bssid), file_name);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyHs20IconQueryDone(
-	    wpa_s, bssid, file_name, image, image_length);
-}
-
-void wpas_hidl_notify_hs20_rx_subscription_remediation(
-    struct wpa_supplicant *wpa_s, const char *url, u8 osu_method)
-{
-	if (!wpa_s || !wpa_s->global->hidl || !url)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG,
-	    "Notifying HS20 subscription remediation rx to hidl control: %s",
-	    url);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyHs20RxSubscriptionRemediation(
-	    wpa_s, url, osu_method);
-}
-
-void wpas_hidl_notify_hs20_rx_deauth_imminent_notice(
-    struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay, const char *url)
-{
-	if (!wpa_s || !wpa_s->global->hidl)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG,
-	    "Notifying HS20 deauth imminent notice rx to hidl control: %s",
-	    url ? url : "<no URL>");
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyHs20RxDeauthImminentNotice(
-	    wpa_s, code, reauth_delay, url);
-}
-
-void wpas_hidl_notify_hs20_rx_terms_and_conditions_acceptance(
-		struct wpa_supplicant *wpa_s, const char *url)
-{
-	if (!wpa_s || !wpa_s->global->hidl || !url)
-		return;
-
-	wpa_printf(MSG_DEBUG,
-			"Notifying HS20 terms and conditions acceptance rx to hidl control: %s",
-			url);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyHs20RxTermsAndConditionsAcceptance(wpa_s, url);
-}
-
-void wpas_hidl_notify_disconnect_reason(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG, "Notifying disconnect reason to hidl control: %d",
-	    wpa_s->disconnect_reason);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyDisconnectReason(wpa_s);
-}
-
-void wpas_hidl_notify_assoc_reject(struct wpa_supplicant *wpa_s,
-    const u8 *bssid, u8 timed_out, const u8 *assoc_resp_ie, size_t assoc_resp_ie_len)
-{
-	if (!wpa_s)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG, "Notifying assoc reject to hidl control: %d",
-	    wpa_s->assoc_status_code);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyAssocReject(wpa_s, bssid, timed_out, assoc_resp_ie, assoc_resp_ie_len);
-}
-
-void wpas_hidl_notify_auth_timeout(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s)
-		return;
-
-	wpa_printf(MSG_DEBUG, "Notifying auth timeout to hidl control");
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyAuthTimeout(wpa_s);
-}
-
-void wpas_hidl_notify_bssid_changed(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s)
-		return;
-
-	wpa_printf(MSG_DEBUG, "Notifying bssid changed to hidl control");
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyBssidChanged(wpa_s);
-}
-
-void wpas_hidl_notify_wps_event_fail(
-    struct wpa_supplicant *wpa_s, uint8_t *peer_macaddr, uint16_t config_error,
-    uint16_t error_indication)
-{
-	if (!wpa_s || !peer_macaddr)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG, "Notifying Wps event fail to hidl control: %d, %d",
-	    config_error, error_indication);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyWpsEventFail(
-	    wpa_s, peer_macaddr, config_error, error_indication);
-}
-
-void wpas_hidl_notify_wps_event_success(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s)
-		return;
-
-	wpa_printf(MSG_DEBUG, "Notifying Wps event success to hidl control");
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyWpsEventSuccess(wpa_s);
-}
-
-void wpas_hidl_notify_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG, "Notifying Wps event PBC overlap to hidl control");
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyWpsEventPbcOverlap(wpa_s);
-}
-
-void wpas_hidl_notify_p2p_device_found(
-    struct wpa_supplicant *wpa_s, const u8 *addr,
-    const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
-    u8 peer_wfd_device_info_len, const u8 *peer_wfd_r2_device_info,
-    u8 peer_wfd_r2_device_info_len)
-{
-	if (!wpa_s || !addr || !info)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG, "Notifying P2P device found to hidl control " MACSTR,
-	    MAC2STR(info->p2p_device_addr));
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyP2pDeviceFound(
-	    wpa_s, addr, info, peer_wfd_device_info,
-	    peer_wfd_device_info_len, peer_wfd_r2_device_info,
-	    peer_wfd_r2_device_info_len);
-}
-
-void wpas_hidl_notify_p2p_device_lost(
-    struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr)
-{
-	if (!wpa_s || !p2p_device_addr)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG, "Notifying P2P device lost to hidl control " MACSTR,
-	    MAC2STR(p2p_device_addr));
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyP2pDeviceLost(wpa_s, p2p_device_addr);
-}
-
-void wpas_hidl_notify_p2p_find_stopped(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s)
-		return;
-
-	wpa_printf(MSG_DEBUG, "Notifying P2P find stop to hidl control");
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyP2pFindStopped(wpa_s);
-}
-
-void wpas_hidl_notify_p2p_go_neg_req(
-    struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
-    u8 go_intent)
-{
-	if (!wpa_s || !src_addr)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG,
-	    "Notifying P2P GO negotiation request to hidl control " MACSTR,
-	    MAC2STR(src_addr));
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyP2pGoNegReq(
-	    wpa_s, src_addr, dev_passwd_id, go_intent);
-}
-
-void wpas_hidl_notify_p2p_go_neg_completed(
-    struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res)
-{
-	if (!wpa_s || !res)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG,
-	    "Notifying P2P GO negotiation completed to hidl control: %d",
-	    res->status);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyP2pGoNegCompleted(wpa_s, res);
-}
-
-void wpas_hidl_notify_p2p_group_formation_failure(
-    struct wpa_supplicant *wpa_s, const char *reason)
-{
-	if (!wpa_s || !reason)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG,
-	    "Notifying P2P Group formation failure to hidl control: %s",
-	    reason);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyP2pGroupFormationFailure(wpa_s, reason);
-}
-
-void wpas_hidl_notify_p2p_group_started(
-    struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid, int persistent,
-    int client)
-{
-	if (!wpa_s || !ssid)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG, "Notifying P2P Group start to hidl control: %d",
-	    ssid->id);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyP2pGroupStarted(wpa_s, ssid, persistent, client);
-}
-
-void wpas_hidl_notify_p2p_group_removed(
-    struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid, const char *role)
-{
-	if (!wpa_s || !ssid || !role)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG, "Notifying P2P Group removed to hidl control: %d",
-	    ssid->id);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyP2pGroupRemoved(wpa_s, ssid, role);
-}
-
-void wpas_hidl_notify_p2p_invitation_received(
-    struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
-    const u8 *bssid, int id, int op_freq)
-{
-	if (!wpa_s || !sa || !go_dev_addr || !bssid)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG,
-	    "Notifying P2P invitation received to hidl control: %d " MACSTR, id,
-	    MAC2STR(bssid));
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyP2pInvitationReceived(
-	    wpa_s, sa, go_dev_addr, bssid, id, op_freq);
-}
-
-void wpas_hidl_notify_p2p_invitation_result(
-    struct wpa_supplicant *wpa_s, int status, const u8 *bssid)
-{
-	if (!wpa_s)
-		return;
-	if (bssid) {
-		wpa_printf(
-		    MSG_DEBUG,
-		    "Notifying P2P invitation result to hidl control: " MACSTR,
-		    MAC2STR(bssid));
-	} else {
-		wpa_printf(
-		    MSG_DEBUG,
-		    "Notifying P2P invitation result to hidl control: NULL "
-		    "bssid");
-	}
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyP2pInvitationResult(wpa_s, status, bssid);
-}
-
-void wpas_hidl_notify_p2p_provision_discovery(
-    struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
-    enum p2p_prov_disc_status status, u16 config_methods,
-    unsigned int generated_pin)
-{
-	if (!wpa_s || !dev_addr)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG,
-	    "Notifying P2P provision discovery to hidl control " MACSTR,
-	    MAC2STR(dev_addr));
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyP2pProvisionDiscovery(
-	    wpa_s, dev_addr, request, status, config_methods, generated_pin);
-}
-
-void wpas_hidl_notify_p2p_sd_response(
-    struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
-    const u8 *tlvs, size_t tlvs_len)
-{
-	if (!wpa_s || !sa || !tlvs)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG,
-	    "Notifying P2P service discovery response to hidl control " MACSTR,
-	    MAC2STR(sa));
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyP2pSdResponse(
-	    wpa_s, sa, update_indic, tlvs, tlvs_len);
-}
-
-void wpas_hidl_notify_ap_sta_authorized(
-    struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
-{
-	if (!wpa_s || !sta)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG,
-	    "Notifying P2P AP STA authorized to hidl control " MACSTR,
-	    MAC2STR(sta));
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyApStaAuthorized(wpa_s, sta, p2p_dev_addr);
-}
-
-void wpas_hidl_notify_ap_sta_deauthorized(
-    struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
-{
-	if (!wpa_s || !sta)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG,
-	    "Notifying P2P AP STA deauthorized to hidl control " MACSTR,
-	    MAC2STR(sta));
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyApStaDeauthorized(wpa_s, sta, p2p_dev_addr);
-}
-
-void wpas_hidl_notify_eap_error(struct wpa_supplicant *wpa_s, int error_code)
-{
-	if (!wpa_s)
-		return;
-
-	wpa_printf(MSG_DEBUG, "Notifying EAP Error: %d ", error_code);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyEapError(wpa_s, error_code);
-}
-
-void wpas_hidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
-	    struct wpa_ssid *ssid)
-{
-	if (!wpa_s || !ssid)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG,
-	    "Notifying DPP configuration received for SSID %d", ssid->id);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyDppConfigReceived(wpa_s, ssid);
-}
-
-void wpas_hidl_notify_dpp_config_sent(struct wpa_supplicant *wpa_s)
-{
-	wpas_hidl_notify_dpp_success(wpa_s, DppSuccessCode::CONFIGURATION_SENT);
-}
-
-/* DPP Progress notifications */
-void wpas_hidl_notify_dpp_auth_success(struct wpa_supplicant *wpa_s)
-{
-	wpas_hidl_notify_dpp_progress(wpa_s, DppProgressCode::AUTHENTICATION_SUCCESS);
-}
-
-void wpas_hidl_notify_dpp_resp_pending(struct wpa_supplicant *wpa_s)
-{
-	wpas_hidl_notify_dpp_progress(wpa_s, DppProgressCode::RESPONSE_PENDING);
-}
-
-/* DPP Failure notifications */
-void wpas_hidl_notify_dpp_not_compatible(struct wpa_supplicant *wpa_s)
-{
-	wpas_hidl_notify_dpp_failure(wpa_s, DppFailureCode::NOT_COMPATIBLE);
-}
-
-void wpas_hidl_notify_dpp_missing_auth(struct wpa_supplicant *wpa_s)
-{
-	wpas_hidl_notify_dpp_failure(wpa_s, DppFailureCode::AUTHENTICATION);
-}
-
-void wpas_hidl_notify_dpp_configuration_failure(struct wpa_supplicant *wpa_s)
-{
-	wpas_hidl_notify_dpp_failure(wpa_s, DppFailureCode::CONFIGURATION);
-}
-
-void wpas_hidl_notify_dpp_timeout(struct wpa_supplicant *wpa_s)
-{
-	wpas_hidl_notify_dpp_failure(wpa_s, DppFailureCode::TIMEOUT);
-}
-
-void wpas_hidl_notify_dpp_auth_failure(struct wpa_supplicant *wpa_s)
-{
-	wpas_hidl_notify_dpp_failure(wpa_s, DppFailureCode::AUTHENTICATION);
-}
-
-void wpas_hidl_notify_dpp_fail(struct wpa_supplicant *wpa_s)
-{
-	wpas_hidl_notify_dpp_failure(wpa_s, DppFailureCode::FAILURE);
-}
-
-void wpas_hidl_notify_dpp_config_sent_wait_response(struct wpa_supplicant *wpa_s)
-{
-	wpas_hidl_notify_dpp_progress(wpa_s, DppProgressCode::CONFIGURATION_SENT_WAITING_RESPONSE);
-}
-
-/* DPP notification helper functions */
-static void wpas_hidl_notify_dpp_failure(struct wpa_supplicant *wpa_s, DppFailureCode code)
-{
-	if (!wpa_s)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG,
-	    "Notifying DPP failure event %d", code);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyDppFailure(wpa_s, code);
-}
-
-static void wpas_hidl_notify_dpp_progress(struct wpa_supplicant *wpa_s, DppProgressCode code)
-{
-	if (!wpa_s)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG,
-	    "Notifying DPP progress event %d", code);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyDppProgress(wpa_s, code);
-}
-
-void wpas_hidl_notify_dpp_config_accepted(struct wpa_supplicant *wpa_s)
-{
-	wpas_hidl_notify_dpp_progress(wpa_s, DppProgressCode::CONFIGURATION_ACCEPTED);
-}
-
-static void wpas_hidl_notify_dpp_config_applied(struct wpa_supplicant *wpa_s)
-{
-	wpas_hidl_notify_dpp_success(wpa_s, DppSuccessCode::CONFIGURATION_APPLIED);
-}
-
-static void wpas_hidl_notify_dpp_success(struct wpa_supplicant *wpa_s, DppSuccessCode code)
-{
-	if (!wpa_s)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG,
-	    "Notifying DPP progress event %d", code);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyDppSuccess(wpa_s, code);
-}
-
-void wpas_hidl_notify_dpp_config_rejected(struct wpa_supplicant *wpa_s)
-{
-	wpas_hidl_notify_dpp_failure(wpa_s, DppFailureCode::CONFIGURATION_REJECTED);
-}
-
-static void wpas_hidl_notify_dpp_no_ap_failure(struct wpa_supplicant *wpa_s,
-		const char *ssid, const char *channel_list, unsigned short band_list[],
-		int size)
-{
-	if (!wpa_s)
-		return;
-
-	wpa_printf(MSG_DEBUG,
-			"Notifying DPP NO AP event for SSID %s\nTried channels: %s",
-			ssid ? ssid : "N/A", channel_list ? channel_list : "N/A");
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyDppFailure(wpa_s, DppFailureCode::CANNOT_FIND_NETWORK,
-			ssid, channel_list, band_list, size);
-}
-
-void wpas_hidl_notify_dpp_enrollee_auth_failure(struct wpa_supplicant *wpa_s,
-		const char *ssid, unsigned short band_list[], int size)
-{
-	if (!wpa_s)
-		return;
-
-	wpa_printf(MSG_DEBUG,
-			"Notifying DPP Enrollee authentication failure, SSID %s",
-			ssid ? ssid : "N/A");
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyDppFailure(wpa_s, DppFailureCode::ENROLLEE_AUTHENTICATION,
-			ssid, NULL, band_list, size);
-}
-
-
-void wpas_hidl_notify_dpp_conn_status(struct wpa_supplicant *wpa_s, enum dpp_status_error status,
-		const char *ssid, const char *channel_list, unsigned short band_list[], int size)
-{
-	switch (status)
-	{
-	case DPP_STATUS_OK:
-		wpas_hidl_notify_dpp_config_applied(wpa_s);
-		break;
-
-	case DPP_STATUS_NO_AP:
-		wpas_hidl_notify_dpp_no_ap_failure(wpa_s, ssid, channel_list, band_list, size);
-		break;
-
-	case DPP_STATUS_AUTH_FAILURE:
-		wpas_hidl_notify_dpp_enrollee_auth_failure(wpa_s, ssid, band_list, size);
-		break;
-
-	default:
-		break;
-	}
-}
-
-void wpas_hidl_notify_pmk_cache_added(
-    struct wpa_supplicant *wpa_s,
-    struct rsn_pmksa_cache_entry *pmksa_entry)
-{
-	if (!wpa_s || !pmksa_entry)
-		return;
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG,
-	    "Notifying PMK cache added event");
-
-	hidl_manager->notifyPmkCacheAdded(wpa_s, pmksa_entry);
-}
-
-void wpas_hidl_notify_bss_tm_status(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s)
-		return;
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	wpa_printf(MSG_DEBUG, "Notifying BSS transition status");
-
-	hidl_manager->notifyBssTmStatus(wpa_s);
-}
-
-void wpas_hidl_notify_transition_disable(struct wpa_supplicant *wpa_s,
-					    struct wpa_ssid *ssid,
-					    u8 bitmap)
-{
-	if (!wpa_s || !ssid)
-		return;
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyTransitionDisable(wpa_s, ssid, bitmap);
-}
-
-void wpas_hidl_notify_network_not_found(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s)
-		return;
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	wpa_printf(MSG_DEBUG, "Notify network not found");
-
-	hidl_manager->notifyNetworkNotFound(wpa_s);
-}
diff --git a/wpa_supplicant/hidl/1.4/hidl.h b/wpa_supplicant/hidl/1.4/hidl.h
deleted file mode 100644
index 0974048..0000000
--- a/wpa_supplicant/hidl/1.4/hidl.h
+++ /dev/null
@@ -1,288 +0,0 @@
-/*
- * hidl interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WPA_SUPPLICANT_HIDL_HIDL_H
-#define WPA_SUPPLICANT_HIDL_HIDL_H
-
-#ifdef _cplusplus
-extern "C"
-{
-#endif  // _cplusplus
-
-	/**
-	 * This is the hidl RPC interface entry point to the wpa_supplicant
-	 * core. This initializes the hidl driver & HidlManager instance and
-	 * then forwards all the notifcations from the supplicant core to the
-	 * HidlManager.
-	 */
-	struct wpas_hidl_priv;
-	struct wpa_global;
-
-	struct wpas_hidl_priv *wpas_hidl_init(struct wpa_global *global);
-	void wpas_hidl_deinit(struct wpas_hidl_priv *priv);
-
-#ifdef CONFIG_CTRL_IFACE_HIDL
-	int wpas_hidl_register_interface(struct wpa_supplicant *wpa_s);
-	int wpas_hidl_unregister_interface(struct wpa_supplicant *wpa_s);
-	int wpas_hidl_register_network(
-	    struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
-	int wpas_hidl_unregister_network(
-	    struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
-	int wpas_hidl_notify_state_changed(struct wpa_supplicant *wpa_s);
-	int wpas_hidl_notify_network_request(
-	    struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
-	    enum wpa_ctrl_req_type rtype, const char *default_txt);
-	void wpas_hidl_notify_anqp_query_done(
-	    struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
-	    const struct wpa_bss_anqp *anqp);
-	void wpas_hidl_notify_hs20_icon_query_done(
-	    struct wpa_supplicant *wpa_s, const u8 *bssid,
-	    const char *file_name, const u8 *image, u32 image_length);
-	void wpas_hidl_notify_hs20_rx_subscription_remediation(
-	    struct wpa_supplicant *wpa_s, const char *url, u8 osu_method);
-	void wpas_hidl_notify_hs20_rx_deauth_imminent_notice(
-	    struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay,
-	    const char *url);
-	void wpas_hidl_notify_hs20_rx_terms_and_conditions_acceptance(
-			struct wpa_supplicant *wpa_s, const char *url);
-	void wpas_hidl_notify_disconnect_reason(struct wpa_supplicant *wpa_s);
-	void wpas_hidl_notify_assoc_reject(struct wpa_supplicant *wpa_s, const u8 *bssid,
-	    u8 timed_out, const u8 *assoc_resp_ie, size_t assoc_resp_ie_len);
-	void wpas_hidl_notify_auth_timeout(struct wpa_supplicant *wpa_s);
-	void wpas_hidl_notify_bssid_changed(struct wpa_supplicant *wpa_s);
-	void wpas_hidl_notify_wps_event_fail(
-	    struct wpa_supplicant *wpa_s, uint8_t *peer_macaddr,
-	    uint16_t config_error, uint16_t error_indication);
-	void wpas_hidl_notify_wps_event_success(struct wpa_supplicant *wpa_s);
-	void wpas_hidl_notify_wps_event_pbc_overlap(
-	    struct wpa_supplicant *wpa_s);
-	void wpas_hidl_notify_p2p_device_found(
-	    struct wpa_supplicant *wpa_s, const u8 *addr,
-	    const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
-	    u8 peer_wfd_device_info_len, const u8 *peer_wfd_r2_device_info,
-	    u8 peer_wfd_r2_device_info_len);
-	void wpas_hidl_notify_p2p_device_lost(
-	    struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr);
-	void wpas_hidl_notify_p2p_find_stopped(struct wpa_supplicant *wpa_s);
-	void wpas_hidl_notify_p2p_go_neg_req(
-	    struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
-	    u8 go_intent);
-	void wpas_hidl_notify_p2p_go_neg_completed(
-	    struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res);
-	void wpas_hidl_notify_p2p_group_formation_failure(
-	    struct wpa_supplicant *wpa_s, const char *reason);
-	void wpas_hidl_notify_p2p_group_started(
-	    struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid,
-	    int persistent, int client);
-	void wpas_hidl_notify_p2p_group_removed(
-	    struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid,
-	    const char *role);
-	void wpas_hidl_notify_p2p_invitation_received(
-	    struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
-	    const u8 *bssid, int id, int op_freq);
-	void wpas_hidl_notify_p2p_invitation_result(
-	    struct wpa_supplicant *wpa_s, int status, const u8 *bssid);
-	void wpas_hidl_notify_p2p_provision_discovery(
-	    struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
-	    enum p2p_prov_disc_status status, u16 config_methods,
-	    unsigned int generated_pin);
-	void wpas_hidl_notify_p2p_sd_response(
-	    struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
-	    const u8 *tlvs, size_t tlvs_len);
-	void wpas_hidl_notify_ap_sta_authorized(
-	    struct wpa_supplicant *wpa_s, const u8 *sta,
-	    const u8 *p2p_dev_addr);
-	void wpas_hidl_notify_ap_sta_deauthorized(
-	    struct wpa_supplicant *wpa_s, const u8 *sta,
-	    const u8 *p2p_dev_addr);
-	void wpas_hidl_notify_eap_error(
-	    struct wpa_supplicant *wpa_s, int error_code);
-	void wpas_hidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
-		    struct wpa_ssid *ssid);
-	void wpas_hidl_notify_dpp_config_sent(struct wpa_supplicant *wpa_s);
-	void wpas_hidl_notify_dpp_auth_success(struct wpa_supplicant *wpa_s);
-	void wpas_hidl_notify_dpp_resp_pending(struct wpa_supplicant *wpa_s);
-	void wpas_hidl_notify_dpp_not_compatible(struct wpa_supplicant *wpa_s);
-	void wpas_hidl_notify_dpp_missing_auth(struct wpa_supplicant *wpa_s);
-	void wpas_hidl_notify_dpp_configuration_failure(struct wpa_supplicant *wpa_s);
-	void wpas_hidl_notify_dpp_invalid_uri(struct wpa_supplicant *wpa_s);
-	void wpas_hidl_notify_dpp_timeout(struct wpa_supplicant *wpa_s);
-	void wpas_hidl_notify_dpp_auth_failure(struct wpa_supplicant *wpa_s);
-	void wpas_hidl_notify_dpp_fail(struct wpa_supplicant *wpa_s);
-	void wpas_hidl_notify_dpp_config_sent_wait_response(struct wpa_supplicant *wpa_s);
-	void wpas_hidl_notify_dpp_config_accepted(struct wpa_supplicant *wpa_s);
-	void wpas_hidl_notify_dpp_config_rejected(struct wpa_supplicant *wpa_s);
-	void wpas_hidl_notify_dpp_conn_status(struct wpa_supplicant *wpa_s,
-	    enum dpp_status_error status, const char *ssid,
-	    const char *channel_list, unsigned short band_list[], int size);
-	void wpas_hidl_notify_pmk_cache_added(
-	    struct wpa_supplicant *wpas, struct rsn_pmksa_cache_entry *pmksa_entry);
-	void wpas_hidl_notify_bss_tm_status(struct wpa_supplicant *wpa_s);
-	void wpas_hidl_notify_transition_disable(
-	    struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, u8 bitmap);
-	void wpas_hidl_notify_network_not_found(struct wpa_supplicant *wpa_s);
-#else   // CONFIG_CTRL_IFACE_HIDL
-static inline int wpas_hidl_register_interface(struct wpa_supplicant *wpa_s)
-{
-	return 0;
-}
-static inline int wpas_hidl_unregister_interface(struct wpa_supplicant *wpa_s)
-{
-	return 0;
-}
-static inline int wpas_hidl_register_network(
-    struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
-{
-	return 0;
-}
-static inline int wpas_hidl_unregister_network(
-    struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
-{
-	return 0;
-}
-static inline int wpas_hidl_notify_state_changed(struct wpa_supplicant *wpa_s)
-{
-	return 0;
-}
-static inline int wpas_hidl_notify_network_request(
-    struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
-    enum wpa_ctrl_req_type rtype, const char *default_txt)
-{
-	return 0;
-}
-static void wpas_hidl_notify_anqp_query_done(
-    struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
-    const struct wpa_bss_anqp *anqp)
-{}
-static void wpas_hidl_notify_hs20_icon_query_done(
-    struct wpa_supplicant *wpa_s, const u8 *bssid, const char *file_name,
-    const u8 *image, u32 image_length)
-{}
-static void wpas_hidl_notify_hs20_rx_subscription_remediation(
-    struct wpa_supplicant *wpa_s, const char *url, u8 osu_method)
-{}
-static void wpas_hidl_notify_hs20_rx_deauth_imminent_notice(
-    struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay, const char *url)
-{}
-void wpas_hidl_notify_hs20_rx_terms_and_conditions_acceptance(
-		struct wpa_supplicant *wpa_s, const char *url)
-{}
-static void wpas_hidl_notify_disconnect_reason(struct wpa_supplicant *wpa_s) {}
-static void wpas_hidl_notify_assoc_reject(struct wpa_supplicant *wpa_s, const u8 *bssid,
-    u8 timed_out, const u8 *assoc_resp_ie, size_t assoc_resp_ie_len) {}
-static void wpas_hidl_notify_auth_timeout(struct wpa_supplicant *wpa_s) {}
-static void wpas_hidl_notify_wps_event_fail(
-    struct wpa_supplicant *wpa_s, uint8_t *peer_macaddr, uint16_t config_error,
-    uint16_t error_indication)
-{}
-static void wpas_hidl_notify_bssid_changed(struct wpa_supplicant *wpa_s) {}
-static void wpas_hidl_notify_wps_event_success(struct wpa_supplicant *wpa_s) {}
-static void wpas_hidl_notify_wps_event_pbc_overlap(struct wpa_supplicant *wpa_s)
-{}
-static void wpas_hidl_notify_p2p_device_found(
-    struct wpa_supplicant *wpa_s, const u8 *addr,
-    const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
-    u8 peer_wfd_device_info_len);
-{}
-static void wpas_hidl_notify_p2p_device_lost(
-    struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr)
-{}
-static void wpas_hidl_notify_p2p_find_stopped(struct wpa_supplicant *wpa_s) {}
-static void wpas_hidl_notify_p2p_go_neg_req(
-    struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
-    u8 go_intent)
-{}
-static void wpas_hidl_notify_p2p_go_neg_completed(
-    struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res)
-{}
-static void wpas_hidl_notify_p2p_group_formation_failure(
-    struct wpa_supplicant *wpa_s, const char *reason)
-{}
-static void wpas_hidl_notify_p2p_group_started(
-    struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid, int persistent,
-    int client)
-{}
-static void wpas_hidl_notify_p2p_group_removed(
-    struct wpa_supplicant *wpa_s, const struct wpa_ssid *ssid, const char *role)
-{}
-static void wpas_hidl_notify_p2p_invitation_received(
-    struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
-    const u8 *bssid, int id, int op_freq)
-{}
-static void wpas_hidl_notify_p2p_invitation_result(
-    struct wpa_supplicant *wpa_s, int status, const u8 *bssid)
-{}
-static void wpas_hidl_notify_p2p_provision_discovery(
-    struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
-    enum p2p_prov_disc_status status, u16 config_methods,
-    unsigned int generated_pin)
-{}
-static void wpas_hidl_notify_p2p_sd_response(
-    struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
-    const u8 *tlvs, size_t tlvs_len)
-{}
-static void wpas_hidl_notify_ap_sta_authorized(
-    struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
-{}
-static void wpas_hidl_notify_ap_sta_deauthorized(
-    struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
-{}
-static void wpas_hidl_notify_eap_error(
-    struct wpa_supplicant *wpa_s, int error_code)
-{}
-static void wpas_hidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
-	    struct wpa_ssid *ssid)
-{}
-static void wpas_hidl_notify_dpp_config_received(struct wpa_supplicant *wpa_s,
-	    struct wpa_ssid *ssid);
-static void wpas_hidl_notify_dpp_config_sent(struct wpa_supplicant *wpa_s)
-{}
-static void wpas_hidl_notify_dpp_auth_success(struct wpa_supplicant *wpa_s)
-{}
-static void wpas_hidl_notify_dpp_resp_pending(struct wpa_supplicant *wpa_s)
-{}
-static void wpas_hidl_notify_dpp_not_compatible(struct wpa_supplicant *wpa_s)
-{}
-static void wpas_hidl_notify_dpp_missing_auth(struct wpa_supplicant *wpa_s)
-{}
-static void wpas_hidl_notify_dpp_configuration_failure(struct wpa_supplicant *wpa_s)
-{}
-static void wpas_hidl_notify_dpp_invalid_uri(struct wpa_supplicant *wpa_s)
-{}
-static void wpas_hidl_notify_dpp_timeout(struct wpa_supplicant *wpa_s)
-{}
-static void wpas_hidl_notify_dpp_failure(struct wpa_supplicant *wpa_s)
-{}
-void wpas_hidl_notify_dpp_config_sent_wait_response(struct wpa_supplicant *wpa_s)
-{}
-void wpas_hidl_notify_dpp_config_accepted(struct wpa_supplicant *wpa_s)
-{}
-void wpas_hidl_notify_dpp_config_applied(struct wpa_supplicant *wpa_s)
-{}
-void wpas_hidl_notify_dpp_config_rejected(struct wpa_supplicant *wpa_s)
-{}
-static void wpas_hidl_notify_pmk_cache_added(struct wpa_supplicant *wpas,
-					     struct rsn_pmksa_cache_entry *pmksa_entry)
-{}
-void wpas_hidl_notify_bss_tm_status(struct wpa_supplicant *wpa_s)
-{}
-static void wpas_hidl_notify_transition_disable(struct wpa_supplicant *wpa_s,
-					    struct wpa_ssid *ssid,
-					    u8 bitmap)
-{}
-static void wpas_hidl_notify_network_not_found(struct wpa_supplicant *wpa_s)
-{}
-}
-#endif  // CONFIG_CTRL_IFACE_HIDL
-
-#ifdef _cplusplus
-}
-#endif  // _cplusplus
-
-#endif  // WPA_SUPPLICANT_HIDL_HIDL_H
diff --git a/wpa_supplicant/hidl/1.4/hidl_constants.h b/wpa_supplicant/hidl/1.4/hidl_constants.h
deleted file mode 100644
index 988a590..0000000
--- a/wpa_supplicant/hidl/1.4/hidl_constants.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * hidl interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WPA_SUPPLICANT_HIDL_HIDL_CONSTANTS_H
-#define WPA_SUPPLICANT_HIDL_HIDL_CONSTANTS_H
-
-namespace wpa_supplicant_hidl {
-namespace hidl_constants {
-
-extern const char kServiceName[];
-
-} /* namespace hidl_constants */
-} /* namespace wpa_supplicant_hidl */
-
-#endif /* WPA_SUPPLICANT_HIDL_HIDL_CONSTANTS_H */
diff --git a/wpa_supplicant/hidl/1.4/hidl_i.h b/wpa_supplicant/hidl/1.4/hidl_i.h
deleted file mode 100644
index 9cff40d..0000000
--- a/wpa_supplicant/hidl/1.4/hidl_i.h
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * hidl interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef HIDL_I_H
-#define HIDL_I_H
-
-#ifdef _cplusplus
-extern "C"
-{
-#endif  // _cplusplus
-
-	struct wpas_hidl_priv
-	{
-		int hidl_fd;
-		struct wpa_global *global;
-		void *hidl_manager;
-	};
-
-#ifdef _cplusplus
-}
-#endif  // _cplusplus
-
-#endif  // HIDL_I_H
diff --git a/wpa_supplicant/hidl/1.4/hidl_manager.cpp b/wpa_supplicant/hidl/1.4/hidl_manager.cpp
deleted file mode 100644
index 0a5fceb..0000000
--- a/wpa_supplicant/hidl/1.4/hidl_manager.cpp
+++ /dev/null
@@ -1,2496 +0,0 @@
-/*
- * hidl interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include <algorithm>
-#include <iostream>
-#include <regex>
-
-#include "hidl_manager.h"
-#include "misc_utils.h"
-
-extern "C" {
-#include "scan.h"
-#include "src/eap_common/eap_sim_common.h"
-#include "list.h"
-}
-
-namespace {
-using android::hardware::hidl_array;
-
-constexpr uint8_t kWfdDeviceInfoLen = 6;
-constexpr uint8_t kWfdR2DeviceInfoLen = 2;
-// GSM-AUTH:<RAND1>:<RAND2>[:<RAND3>]
-constexpr char kGsmAuthRegex2[] = "GSM-AUTH:([0-9a-f]+):([0-9a-f]+)";
-constexpr char kGsmAuthRegex3[] =
-    "GSM-AUTH:([0-9a-f]+):([0-9a-f]+):([0-9a-f]+)";
-// UMTS-AUTH:<RAND>:<AUTN>
-constexpr char kUmtsAuthRegex[] = "UMTS-AUTH:([0-9a-f]+):([0-9a-f]+)";
-constexpr size_t kGsmRandLenBytes = GSM_RAND_LEN;
-constexpr size_t kUmtsRandLenBytes = EAP_AKA_RAND_LEN;
-constexpr size_t kUmtsAutnLenBytes = EAP_AKA_AUTN_LEN;
-constexpr u8 kZeroBssid[6] = {0, 0, 0, 0, 0, 0};
-
-/**
- * Check if the provided |wpa_supplicant| structure represents a P2P iface or
- * not.
- */
-constexpr bool isP2pIface(const struct wpa_supplicant *wpa_s)
-{
-	return (wpa_s->global->p2p_init_wpa_s == wpa_s);
-}
-
-/**
- * Creates a unique key for the network using the provided |ifname| and
- * |network_id| to be used in the internal map of |ISupplicantNetwork| objects.
- * This is of the form |ifname|_|network_id|. For ex: "wlan0_1".
- *
- * @param ifname Name of the corresponding interface.
- * @param network_id ID of the corresponding network.
- */
-const std::string getNetworkObjectMapKey(
-    const std::string &ifname, int network_id)
-{
-	return ifname + "_" + std::to_string(network_id);
-}
-
-/**
- * Add callback to the corresponding list after linking to death on the
- * corresponding hidl object reference.
- */
-template <class CallbackType>
-int registerForDeathAndAddCallbackHidlObjectToList(
-    const android::sp<DeathNotifier> &death_notifier,
-    const android::sp<CallbackType> &callback,
-    std::vector<android::sp<CallbackType>> &callback_list)
-{
-	if (!callback->linkToDeath(death_notifier, 0)) {
-		wpa_printf(
-		    MSG_ERROR,
-		    "Error registering for death notification for "
-		    "supplicant callback object");
-		return 1;
-	}
-	callback_list.push_back(callback);
-	return 0;
-}
-
-template <class ObjectType>
-int addHidlObjectToMap(
-    const std::string &key, const android::sp<ObjectType> object,
-    std::map<const std::string, android::sp<ObjectType>> &object_map)
-{
-	// Return failure if we already have an object for that |key|.
-	if (object_map.find(key) != object_map.end())
-		return 1;
-	object_map[key] = object;
-	if (!object_map[key].get())
-		return 1;
-	return 0;
-}
-
-template <class ObjectType>
-int removeHidlObjectFromMap(
-    const std::string &key,
-    std::map<const std::string, android::sp<ObjectType>> &object_map)
-{
-	// Return failure if we dont have an object for that |key|.
-	const auto &object_iter = object_map.find(key);
-	if (object_iter == object_map.end())
-		return 1;
-	object_iter->second->invalidate();
-	object_map.erase(object_iter);
-	return 0;
-}
-
-template <class CallbackType>
-int addIfaceCallbackHidlObjectToMap(
-    const android::sp<DeathNotifier> &death_notifier,
-    const std::string &ifname, const android::sp<CallbackType> &callback,
-    std::map<const std::string, std::vector<android::sp<CallbackType>>>
-	&callbacks_map)
-{
-	if (ifname.empty())
-		return 1;
-
-	auto iface_callback_map_iter = callbacks_map.find(ifname);
-	if (iface_callback_map_iter == callbacks_map.end())
-		return 1;
-	auto &iface_callback_list = iface_callback_map_iter->second;
-
-	// Register for death notification before we add it to our list.
-	return registerForDeathAndAddCallbackHidlObjectToList<CallbackType>(
-	    death_notifier, callback, iface_callback_list);
-}
-
-template <class CallbackType>
-int addNetworkCallbackHidlObjectToMap(
-    const android::sp<DeathNotifier> &death_notifier,
-    const std::string &ifname, int network_id,
-    const android::sp<CallbackType> &callback,
-    std::map<const std::string, std::vector<android::sp<CallbackType>>>
-	&callbacks_map)
-{
-	if (ifname.empty() || network_id < 0)
-		return 1;
-
-	// Generate the key to be used to lookup the network.
-	const std::string network_key =
-	    getNetworkObjectMapKey(ifname, network_id);
-	auto network_callback_map_iter = callbacks_map.find(network_key);
-	if (network_callback_map_iter == callbacks_map.end())
-		return 1;
-	auto &network_callback_list = network_callback_map_iter->second;
-
-	// Register for death notification before we add it to our list.
-	return registerForDeathAndAddCallbackHidlObjectToList<CallbackType>(
-	    death_notifier, callback, network_callback_list);
-}
-
-template <class CallbackType>
-int removeAllIfaceCallbackHidlObjectsFromMap(
-    const android::sp<DeathNotifier> &death_notifier,
-    const std::string &ifname,
-    std::map<const std::string, std::vector<android::sp<CallbackType>>>
-	&callbacks_map)
-{
-	auto iface_callback_map_iter = callbacks_map.find(ifname);
-	if (iface_callback_map_iter == callbacks_map.end())
-		return 1;
-	const auto &iface_callback_list = iface_callback_map_iter->second;
-	for (const auto &callback : iface_callback_list) {
-		if (!callback->unlinkToDeath(death_notifier)) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Error deregistering for death notification for "
-			    "iface callback object");
-		}
-	}
-	callbacks_map.erase(iface_callback_map_iter);
-	return 0;
-}
-
-template <class CallbackType>
-int removeAllNetworkCallbackHidlObjectsFromMap(
-    const android::sp<DeathNotifier> &death_notifier,
-    const std::string &network_key,
-    std::map<const std::string, std::vector<android::sp<CallbackType>>>
-	&callbacks_map)
-{
-	auto network_callback_map_iter = callbacks_map.find(network_key);
-	if (network_callback_map_iter == callbacks_map.end())
-		return 1;
-	const auto &network_callback_list = network_callback_map_iter->second;
-	for (const auto &callback : network_callback_list) {
-		if (!callback->unlinkToDeath(death_notifier)) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Error deregistering for death "
-			    "notification for "
-			    "network callback object");
-		}
-	}
-	callbacks_map.erase(network_callback_map_iter);
-	return 0;
-}
-
-template <class CallbackType>
-void removeIfaceCallbackHidlObjectFromMap(
-    const std::string &ifname, const android::sp<CallbackType> &callback,
-    std::map<const std::string, std::vector<android::sp<CallbackType>>>
-	&callbacks_map)
-{
-	if (ifname.empty())
-		return;
-
-	auto iface_callback_map_iter = callbacks_map.find(ifname);
-	if (iface_callback_map_iter == callbacks_map.end())
-		return;
-
-	auto &iface_callback_list = iface_callback_map_iter->second;
-	iface_callback_list.erase(
-	    std::remove(
-		iface_callback_list.begin(), iface_callback_list.end(),
-		callback),
-	    iface_callback_list.end());
-}
-
-template <class CallbackType>
-void removeNetworkCallbackHidlObjectFromMap(
-    const std::string &ifname, int network_id,
-    const android::sp<CallbackType> &callback,
-    std::map<const std::string, std::vector<android::sp<CallbackType>>>
-	&callbacks_map)
-{
-	if (ifname.empty() || network_id < 0)
-		return;
-
-	// Generate the key to be used to lookup the network.
-	const std::string network_key =
-	    getNetworkObjectMapKey(ifname, network_id);
-
-	auto network_callback_map_iter = callbacks_map.find(network_key);
-	if (network_callback_map_iter == callbacks_map.end())
-		return;
-
-	auto &network_callback_list = network_callback_map_iter->second;
-	network_callback_list.erase(
-	    std::remove(
-		network_callback_list.begin(), network_callback_list.end(),
-		callback),
-	    network_callback_list.end());
-}
-
-template <class CallbackType>
-void callWithEachIfaceCallback(
-    const std::string &ifname,
-    const std::function<
-	android::hardware::Return<void>(android::sp<CallbackType>)> &method,
-    const std::map<const std::string, std::vector<android::sp<CallbackType>>>
-	&callbacks_map)
-{
-	if (ifname.empty())
-		return;
-
-	auto iface_callback_map_iter = callbacks_map.find(ifname);
-	if (iface_callback_map_iter == callbacks_map.end())
-		return;
-	const auto &iface_callback_list = iface_callback_map_iter->second;
-	for (const auto &callback : iface_callback_list) {
-		if (!method(callback).isOk()) {
-			wpa_printf(
-			    MSG_ERROR, "Failed to invoke HIDL iface callback");
-		}
-	}
-}
-
-template <class CallbackTypeBase, class CallbackTypeDerived>
-void callWithEachIfaceCallbackDerived(
-    const std::string &ifname,
-    const std::function<
-	android::hardware::Return<void>(android::sp<CallbackTypeDerived>)> &method,
-    const std::map<
-	const std::string, std::vector<android::sp<CallbackTypeBase>>>
-	&callbacks_map)
-{
-	if (ifname.empty())
-		return;
-
-	auto iface_callback_map_iter = callbacks_map.find(ifname);
-	if (iface_callback_map_iter == callbacks_map.end())
-		return;
-	const auto &iface_callback_list = iface_callback_map_iter->second;
-	for (const auto &callback : iface_callback_list) {
-		android::sp<CallbackTypeDerived> callback_derived =
-		    CallbackTypeDerived::castFrom(callback);
-		if (callback_derived == nullptr)
-			continue;
-
-		if (!method(callback_derived).isOk()) {
-			wpa_printf(
-			    MSG_ERROR, "Failed to invoke HIDL iface callback");
-		}
-	}
-}
-
-template <class CallbackType>
-void callWithEachNetworkCallback(
-    const std::string &ifname, int network_id,
-    const std::function<
-	android::hardware::Return<void>(android::sp<CallbackType>)> &method,
-    const std::map<const std::string, std::vector<android::sp<CallbackType>>>
-	&callbacks_map)
-{
-	if (ifname.empty() || network_id < 0)
-		return;
-
-	// Generate the key to be used to lookup the network.
-	const std::string network_key =
-	    getNetworkObjectMapKey(ifname, network_id);
-	auto network_callback_map_iter = callbacks_map.find(network_key);
-	if (network_callback_map_iter == callbacks_map.end())
-		return;
-	const auto &network_callback_list = network_callback_map_iter->second;
-	for (const auto &callback : network_callback_list) {
-		if (!method(callback).isOk()) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Failed to invoke HIDL network callback");
-		}
-	}
-}
-
-template <class CallbackTypeBase, class CallbackTypeDerived>
-void callWithEachNetworkCallbackDerived(
-    const std::string &ifname, int network_id,
-    const std::function<
-	android::hardware::Return<void>(android::sp<CallbackTypeDerived>)> &method,
-    const std::map<
-	const std::string, std::vector<android::sp<CallbackTypeBase>>>
-	&callbacks_map)
-{
-	if (ifname.empty())
-		return;
-
-	// Generate the key to be used to lookup the network.
-	const std::string network_key =
-	    getNetworkObjectMapKey(ifname, network_id);
-	auto network_callback_map_iter = callbacks_map.find(network_key);
-	if (network_callback_map_iter == callbacks_map.end())
-		return;
-	const auto &network_callback_list = network_callback_map_iter->second;
-	for (const auto &callback : network_callback_list) {
-		android::sp<CallbackTypeDerived> callback_derived =
-		    CallbackTypeDerived::castFrom(callback);
-		if (callback_derived == nullptr)
-			continue;
-		if (!method(callback_derived).isOk()) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Failed to invoke HIDL network callback");
-		}
-	}
-}
-
-int parseGsmAuthNetworkRequest(
-    const std::string &params_str,
-    std::vector<hidl_array<uint8_t, kGsmRandLenBytes>> *out_rands)
-{
-	std::smatch matches;
-	std::regex params_gsm_regex2(kGsmAuthRegex2);
-	std::regex params_gsm_regex3(kGsmAuthRegex3);
-	if (!std::regex_match(params_str, matches, params_gsm_regex3) &&
-	    !std::regex_match(params_str, matches, params_gsm_regex2)) {
-		return 1;
-	}
-	for (uint32_t i = 1; i < matches.size(); i++) {
-		hidl_array<uint8_t, kGsmRandLenBytes> rand;
-		const auto &match = matches[i];
-		WPA_ASSERT(match.size() >= 2 * rand.size());
-		if (hexstr2bin(match.str().c_str(), rand.data(), rand.size())) {
-			wpa_printf(
-			    MSG_ERROR, "Failed to parse GSM auth params");
-			return 1;
-		}
-		out_rands->push_back(rand);
-	}
-	return 0;
-}
-
-int parseUmtsAuthNetworkRequest(
-    const std::string &params_str,
-    hidl_array<uint8_t, kUmtsRandLenBytes> *out_rand,
-    hidl_array<uint8_t, kUmtsAutnLenBytes> *out_autn)
-{
-	std::smatch matches;
-	std::regex params_umts_regex(kUmtsAuthRegex);
-	if (!std::regex_match(params_str, matches, params_umts_regex)) {
-		return 1;
-	}
-	WPA_ASSERT(matches[1].size() >= 2 * out_rand->size());
-	if (hexstr2bin(
-		matches[1].str().c_str(), out_rand->data(), out_rand->size())) {
-		wpa_printf(MSG_ERROR, "Failed to parse UMTS auth params");
-		return 1;
-	}
-	WPA_ASSERT(matches[2].size() >= 2 * out_autn->size());
-	if (hexstr2bin(
-		matches[2].str().c_str(), out_autn->data(), out_autn->size())) {
-		wpa_printf(MSG_ERROR, "Failed to parse UMTS auth params");
-		return 1;
-	}
-	return 0;
-}
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_4 {
-namespace implementation {
-using V1_0::ISupplicantStaIfaceCallback;
-using V1_0::ISupplicantP2pIfaceCallback;
-using ISupplicantP2pIfaceCallbackV1_4 = V1_4::ISupplicantP2pIfaceCallback;
-
-HidlManager *HidlManager::instance_ = NULL;
-
-HidlManager *HidlManager::getInstance()
-{
-	if (!instance_)
-		instance_ = new HidlManager();
-	return instance_;
-}
-
-void HidlManager::destroyInstance()
-{
-	if (instance_)
-		delete instance_;
-	instance_ = NULL;
-}
-
-int HidlManager::registerHidlService(struct wpa_global *global)
-{
-	// Create the main hidl service object and register it.
-	supplicant_object_ = new Supplicant(global);
-	wpa_global_ = global;
-	death_notifier_ = sp<DeathNotifier>::make(global);
-	if (supplicant_object_->registerAsService() != android::NO_ERROR) {
-		return 1;
-	}
-	return 0;
-}
-
-/**
- * Register an interface to hidl manager.
- *
- * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
- *
- * @return 0 on success, 1 on failure.
- */
-int HidlManager::registerInterface(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s)
-		return 1;
-
-	if (isP2pIface(wpa_s)) {
-		if (addHidlObjectToMap<P2pIface>(
-			wpa_s->ifname,
-			new P2pIface(wpa_s->global, wpa_s->ifname),
-			p2p_iface_object_map_)) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Failed to register P2P interface with HIDL "
-			    "control: %s",
-			    wpa_s->ifname);
-			return 1;
-		}
-		p2p_iface_callbacks_map_[wpa_s->ifname] =
-		    std::vector<android::sp<ISupplicantP2pIfaceCallback>>();
-	} else {
-		if (addHidlObjectToMap<StaIface>(
-			wpa_s->ifname,
-			new StaIface(wpa_s->global, wpa_s->ifname),
-			sta_iface_object_map_)) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Failed to register STA interface with HIDL "
-			    "control: %s",
-			    wpa_s->ifname);
-			return 1;
-		}
-		sta_iface_callbacks_map_[wpa_s->ifname] =
-		    std::vector<android::sp<ISupplicantStaIfaceCallback>>();
-		// Turn on Android specific customizations for STA interfaces
-		// here!
-		//
-		// Turn on scan mac randomization only if driver supports.
-		if (wpa_s->mac_addr_rand_supported & MAC_ADDR_RAND_SCAN) {
-			if (wpas_mac_addr_rand_scan_set(
-				wpa_s, MAC_ADDR_RAND_SCAN, nullptr, nullptr)) {
-				wpa_printf(
-				    MSG_ERROR,
-				    "Failed to enable scan mac randomization");
-			}
-		}
-
-		// Enable randomized source MAC address for GAS/ANQP
-		// Set the lifetime to 0, guarantees a unique address for each GAS
-		// session
-		wpa_s->conf->gas_rand_mac_addr = 1;
-		wpa_s->conf->gas_rand_addr_lifetime = 0;
-	}
-
-	// Invoke the |onInterfaceCreated| method on all registered callbacks.
-	callWithEachSupplicantCallback(std::bind(
-	    &ISupplicantCallback::onInterfaceCreated, std::placeholders::_1,
-	    wpa_s->ifname));
-	return 0;
-}
-
-/**
- * Unregister an interface from hidl manager.
- *
- * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
- *
- * @return 0 on success, 1 on failure.
- */
-int HidlManager::unregisterInterface(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s)
-		return 1;
-
-	// Check if this interface is present in P2P map first, else check in
-	// STA map.
-	// Note: We can't use isP2pIface() here because interface
-	// pointers (wpa_s->global->p2p_init_wpa_s == wpa_s) used by the helper
-	// function is cleared by the core before notifying the HIDL interface.
-	bool success =
-	    !removeHidlObjectFromMap(wpa_s->ifname, p2p_iface_object_map_);
-	if (success) {  // assumed to be P2P
-		success = !removeAllIfaceCallbackHidlObjectsFromMap(
-		    death_notifier_, wpa_s->ifname, p2p_iface_callbacks_map_);
-	} else {  // assumed to be STA
-		success = !removeHidlObjectFromMap(
-		    wpa_s->ifname, sta_iface_object_map_);
-		if (success) {
-			success = !removeAllIfaceCallbackHidlObjectsFromMap(
-			    death_notifier_, wpa_s->ifname, sta_iface_callbacks_map_);
-		}
-	}
-	if (!success) {
-		wpa_printf(
-		    MSG_ERROR,
-		    "Failed to unregister interface with HIDL "
-		    "control: %s",
-		    wpa_s->ifname);
-		return 1;
-	}
-
-	// Invoke the |onInterfaceRemoved| method on all registered callbacks.
-	callWithEachSupplicantCallback(std::bind(
-	    &ISupplicantCallback::onInterfaceRemoved, std::placeholders::_1,
-	    wpa_s->ifname));
-	return 0;
-}
-
-/**
- * Register a network to hidl manager.
- *
- * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
- * the network is added.
- * @param ssid |wpa_ssid| struct corresponding to the network being added.
- *
- * @return 0 on success, 1 on failure.
- */
-int HidlManager::registerNetwork(
-    struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
-{
-	if (!wpa_s || !ssid)
-		return 1;
-
-	// Generate the key to be used to lookup the network.
-	const std::string network_key =
-	    getNetworkObjectMapKey(wpa_s->ifname, ssid->id);
-
-	if (isP2pIface(wpa_s)) {
-		if (addHidlObjectToMap<P2pNetwork>(
-			network_key,
-			new P2pNetwork(wpa_s->global, wpa_s->ifname, ssid->id),
-			p2p_network_object_map_)) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Failed to register P2P network with HIDL "
-			    "control: %d",
-			    ssid->id);
-			return 1;
-		}
-		p2p_network_callbacks_map_[network_key] =
-		    std::vector<android::sp<ISupplicantP2pNetworkCallback>>();
-		// Invoke the |onNetworkAdded| method on all registered
-		// callbacks.
-		callWithEachP2pIfaceCallback(
-		    wpa_s->ifname,
-		    std::bind(
-			&ISupplicantP2pIfaceCallback::onNetworkAdded,
-			std::placeholders::_1, ssid->id));
-	} else {
-		if (addHidlObjectToMap<StaNetwork>(
-			network_key,
-			new StaNetwork(wpa_s->global, wpa_s->ifname, ssid->id),
-			sta_network_object_map_)) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Failed to register STA network with HIDL "
-			    "control: %d",
-			    ssid->id);
-			return 1;
-		}
-		sta_network_callbacks_map_[network_key] =
-		    std::vector<android::sp<ISupplicantStaNetworkCallback>>();
-		// Invoke the |onNetworkAdded| method on all registered
-		// callbacks.
-		callWithEachStaIfaceCallback(
-		    wpa_s->ifname,
-		    std::bind(
-			&ISupplicantStaIfaceCallback::onNetworkAdded,
-			std::placeholders::_1, ssid->id));
-	}
-	return 0;
-}
-
-/**
- * Unregister a network from hidl manager.
- *
- * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
- * the network is added.
- * @param ssid |wpa_ssid| struct corresponding to the network being added.
- *
- * @return 0 on success, 1 on failure.
- */
-int HidlManager::unregisterNetwork(
-    struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
-{
-	if (!wpa_s || !ssid)
-		return 1;
-
-	// Generate the key to be used to lookup the network.
-	const std::string network_key =
-	    getNetworkObjectMapKey(wpa_s->ifname, ssid->id);
-
-	if (isP2pIface(wpa_s)) {
-		if (removeHidlObjectFromMap(
-			network_key, p2p_network_object_map_)) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Failed to unregister P2P network with HIDL "
-			    "control: %d",
-			    ssid->id);
-			return 1;
-		}
-		if (removeAllNetworkCallbackHidlObjectsFromMap(
-			death_notifier_, network_key, p2p_network_callbacks_map_))
-			return 1;
-
-		// Invoke the |onNetworkRemoved| method on all registered
-		// callbacks.
-		callWithEachP2pIfaceCallback(
-		    wpa_s->ifname,
-		    std::bind(
-			&ISupplicantP2pIfaceCallback::onNetworkRemoved,
-			std::placeholders::_1, ssid->id));
-	} else {
-		if (removeHidlObjectFromMap(
-			network_key, sta_network_object_map_)) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Failed to unregister STA network with HIDL "
-			    "control: %d",
-			    ssid->id);
-			return 1;
-		}
-		if (removeAllNetworkCallbackHidlObjectsFromMap(
-			death_notifier_, network_key, sta_network_callbacks_map_))
-			return 1;
-
-		// Invoke the |onNetworkRemoved| method on all registered
-		// callbacks.
-		callWithEachStaIfaceCallback(
-		    wpa_s->ifname,
-		    std::bind(
-			&ISupplicantStaIfaceCallback::onNetworkRemoved,
-			std::placeholders::_1, ssid->id));
-	}
-	return 0;
-}
-
-/**
- * Notify all listeners about any state changes on a particular interface.
- *
- * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
- * the state change event occured.
- */
-int HidlManager::notifyStateChange(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s)
-		return 1;
-
-	if (sta_iface_object_map_.find(wpa_s->ifname) ==
-	    sta_iface_object_map_.end())
-		return 1;
-
-	// Invoke the |onStateChanged| method on all registered callbacks.
-	uint32_t hidl_network_id = UINT32_MAX;
-	std::vector<uint8_t> hidl_ssid;
-	if (wpa_s->current_ssid) {
-		hidl_network_id = wpa_s->current_ssid->id;
-		hidl_ssid.assign(
-		    wpa_s->current_ssid->ssid,
-		    wpa_s->current_ssid->ssid + wpa_s->current_ssid->ssid_len);
-	}
-	uint8_t *bssid;
-	// wpa_supplicant sets the |pending_bssid| field when it starts a
-	// connection. Only after association state does it update the |bssid|
-	// field. So, in the HIDL callback send the appropriate bssid.
-	if (wpa_s->wpa_state <= WPA_ASSOCIATED) {
-		bssid = wpa_s->pending_bssid;
-	} else {
-		bssid = wpa_s->bssid;
-	}
-	bool fils_hlp_sent =
-		(wpa_auth_alg_fils(wpa_s->auth_alg) &&
-		 !dl_list_empty(&wpa_s->fils_hlp_req) &&
-		 (wpa_s->wpa_state == WPA_COMPLETED)) ? true : false;
-
-	// Invoke the |onStateChanged_1_3| method on all registered callbacks.
-	const std::function<
-		Return<void>(android::sp<V1_3::ISupplicantStaIfaceCallback>)>
-		func = std::bind(
-			&V1_3::ISupplicantStaIfaceCallback::onStateChanged_1_3,
-			std::placeholders::_1,
-			static_cast<ISupplicantStaIfaceCallback::State>(
-				wpa_s->wpa_state),
-				bssid, hidl_network_id, hidl_ssid,
-				fils_hlp_sent);
-	callWithEachStaIfaceCallbackDerived(wpa_s->ifname, func);
-	return 0;
-}
-
-/**
- * Notify all listeners about a request on a particular network.
- *
- * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
- * the network is present.
- * @param ssid |wpa_ssid| struct corresponding to the network.
- * @param type type of request.
- * @param param addition params associated with the request.
- */
-int HidlManager::notifyNetworkRequest(
-    struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int type,
-    const char *param)
-{
-	if (!wpa_s || !ssid)
-		return 1;
-
-	const std::string network_key =
-	    getNetworkObjectMapKey(wpa_s->ifname, ssid->id);
-	if (sta_network_object_map_.find(network_key) ==
-	    sta_network_object_map_.end())
-		return 1;
-
-	if (type == WPA_CTRL_REQ_EAP_IDENTITY) {
-		callWithEachStaNetworkCallback(
-		    wpa_s->ifname, ssid->id,
-		    std::bind(
-			&ISupplicantStaNetworkCallback::
-			    onNetworkEapIdentityRequest,
-			std::placeholders::_1));
-		return 0;
-	}
-	if (type == WPA_CTRL_REQ_SIM) {
-		std::vector<hidl_array<uint8_t, 16>> gsm_rands;
-		hidl_array<uint8_t, 16> umts_rand;
-		hidl_array<uint8_t, 16> umts_autn;
-		if (!parseGsmAuthNetworkRequest(param, &gsm_rands)) {
-			ISupplicantStaNetworkCallback::
-			    NetworkRequestEapSimGsmAuthParams hidl_params;
-			hidl_params.rands = gsm_rands;
-			callWithEachStaNetworkCallback(
-			    wpa_s->ifname, ssid->id,
-			    std::bind(
-				&ISupplicantStaNetworkCallback::
-				    onNetworkEapSimGsmAuthRequest,
-				std::placeholders::_1, hidl_params));
-			return 0;
-		}
-		if (!parseUmtsAuthNetworkRequest(
-			param, &umts_rand, &umts_autn)) {
-			ISupplicantStaNetworkCallback::
-			    NetworkRequestEapSimUmtsAuthParams hidl_params;
-			hidl_params.rand = umts_rand;
-			hidl_params.autn = umts_autn;
-			callWithEachStaNetworkCallback(
-			    wpa_s->ifname, ssid->id,
-			    std::bind(
-				&ISupplicantStaNetworkCallback::
-				    onNetworkEapSimUmtsAuthRequest,
-				std::placeholders::_1, hidl_params));
-			return 0;
-		}
-	}
-	return 1;
-}
-
-/**
- * Notify all listeners about the end of an ANQP query.
- *
- * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
- * @param bssid BSSID of the access point.
- * @param result Result of the operation ("SUCCESS" or "FAILURE").
- * @param anqp |wpa_bss_anqp| ANQP data fetched.
- */
-void HidlManager::notifyAnqpQueryDone(
-    struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
-    const struct wpa_bss_anqp *anqp)
-{
-	if (!wpa_s || !bssid || !result || !anqp)
-		return;
-
-	if (sta_iface_object_map_.find(wpa_s->ifname) ==
-	    sta_iface_object_map_.end())
-		return;
-
-	V1_4::ISupplicantStaIfaceCallback::AnqpData hidl_anqp_data;
-	ISupplicantStaIfaceCallback::Hs20AnqpData hidl_hs20_anqp_data;
-	if (std::string(result) == "SUCCESS") {
-		hidl_anqp_data.V1_0.venueName =
-		    misc_utils::convertWpaBufToVector(anqp->venue_name);
-		hidl_anqp_data.V1_0.roamingConsortium =
-		    misc_utils::convertWpaBufToVector(anqp->roaming_consortium);
-		hidl_anqp_data.V1_0.ipAddrTypeAvailability =
-		    misc_utils::convertWpaBufToVector(
-			anqp->ip_addr_type_availability);
-		hidl_anqp_data.V1_0.naiRealm =
-		    misc_utils::convertWpaBufToVector(anqp->nai_realm);
-		hidl_anqp_data.V1_0.anqp3gppCellularNetwork =
-		    misc_utils::convertWpaBufToVector(anqp->anqp_3gpp);
-		hidl_anqp_data.V1_0.domainName =
-		    misc_utils::convertWpaBufToVector(anqp->domain_name);
-
-		struct wpa_bss_anqp_elem *elem;
-		dl_list_for_each(elem, &anqp->anqp_elems, struct wpa_bss_anqp_elem,
-				 list) {
-			if (elem->infoid == ANQP_VENUE_URL && elem->protected_response) {
-				hidl_anqp_data.venueUrl =
-						    misc_utils::convertWpaBufToVector(elem->payload);
-				break;
-			}
-		}
-
-		hidl_hs20_anqp_data.operatorFriendlyName =
-		    misc_utils::convertWpaBufToVector(
-			anqp->hs20_operator_friendly_name);
-		hidl_hs20_anqp_data.wanMetrics =
-		    misc_utils::convertWpaBufToVector(anqp->hs20_wan_metrics);
-		hidl_hs20_anqp_data.connectionCapability =
-		    misc_utils::convertWpaBufToVector(
-			anqp->hs20_connection_capability);
-		hidl_hs20_anqp_data.osuProvidersList =
-		    misc_utils::convertWpaBufToVector(
-			anqp->hs20_osu_providers_list);
-	}
-
-	callWithEachStaIfaceCallback_1_4(
-	    wpa_s->ifname, std::bind(
-			       &V1_4::ISupplicantStaIfaceCallback::onAnqpQueryDone_1_4,
-			       std::placeholders::_1, bssid, hidl_anqp_data,
-			       hidl_hs20_anqp_data));
-}
-
-/**
- * Notify all listeners about the end of an HS20 icon query.
- *
- * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
- * @param bssid BSSID of the access point.
- * @param file_name Name of the icon file.
- * @param image Raw bytes of the icon file.
- * @param image_length Size of the the icon file.
- */
-void HidlManager::notifyHs20IconQueryDone(
-    struct wpa_supplicant *wpa_s, const u8 *bssid, const char *file_name,
-    const u8 *image, u32 image_length)
-{
-	if (!wpa_s || !bssid || !file_name || !image)
-		return;
-
-	if (sta_iface_object_map_.find(wpa_s->ifname) ==
-	    sta_iface_object_map_.end())
-		return;
-
-	callWithEachStaIfaceCallback(
-	    wpa_s->ifname,
-	    std::bind(
-		&ISupplicantStaIfaceCallback::onHs20IconQueryDone,
-		std::placeholders::_1, bssid, file_name,
-		std::vector<uint8_t>(image, image + image_length)));
-}
-
-/**
- * Notify all listeners about the reception of HS20 subscription
- * remediation notification from the server.
- *
- * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
- * @param url URL of the server.
- * @param osu_method OSU method (OMA_DM or SOAP_XML_SPP).
- */
-void HidlManager::notifyHs20RxSubscriptionRemediation(
-    struct wpa_supplicant *wpa_s, const char *url, u8 osu_method)
-{
-	if (!wpa_s || !url)
-		return;
-
-	if (sta_iface_object_map_.find(wpa_s->ifname) ==
-	    sta_iface_object_map_.end())
-		return;
-
-	ISupplicantStaIfaceCallback::OsuMethod hidl_osu_method = {};
-	if (osu_method & 0x1) {
-		hidl_osu_method =
-		    ISupplicantStaIfaceCallback::OsuMethod::OMA_DM;
-	} else if (osu_method & 0x2) {
-		hidl_osu_method =
-		    ISupplicantStaIfaceCallback::OsuMethod::SOAP_XML_SPP;
-	}
-	callWithEachStaIfaceCallback(
-	    wpa_s->ifname,
-	    std::bind(
-		&ISupplicantStaIfaceCallback::onHs20SubscriptionRemediation,
-		std::placeholders::_1, wpa_s->bssid, hidl_osu_method, url));
-}
-
-/**
- * Notify all listeners about the reception of HS20 imminent deauth
- * notification from the server.
- *
- * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
- * @param code Deauth reason code sent from server.
- * @param reauth_delay Reauthentication delay in seconds sent from server.
- * @param url URL of the server containing the reason text.
- */
-void HidlManager::notifyHs20RxDeauthImminentNotice(
-    struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay, const char *url)
-{
-	if (!wpa_s)
-		return;
-
-	if (sta_iface_object_map_.find(wpa_s->ifname) ==
-	    sta_iface_object_map_.end())
-		return;
-
-	callWithEachStaIfaceCallback(
-	    wpa_s->ifname,
-	    std::bind(
-		&ISupplicantStaIfaceCallback::onHs20DeauthImminentNotice,
-		std::placeholders::_1, wpa_s->bssid, code, reauth_delay, url));
-}
-
-/**
- * Notify all listeners about the reception of HS20 terms and conditions
- * acceptance notification from the server.
- *
- * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
- * @param url URL of the T&C server.
- */
-void HidlManager::notifyHs20RxTermsAndConditionsAcceptance(
-    struct wpa_supplicant *wpa_s, const char *url)
-{
-	if (!wpa_s || !url)
-		return;
-
-	if (sta_iface_object_map_.find(wpa_s->ifname)
-			== sta_iface_object_map_.end())
-		return;
-
-	callWithEachStaIfaceCallback_1_4(wpa_s->ifname,
-			std::bind(
-					&V1_4::ISupplicantStaIfaceCallback
-					::onHs20TermsAndConditionsAcceptanceRequestedNotification,
-					std::placeholders::_1, wpa_s->bssid, url));
-}
-
-/**
- * Notify all listeners about the reason code for disconnection from the
- * currently connected network.
- *
- * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
- * the network is present.
- */
-void HidlManager::notifyDisconnectReason(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s)
-		return;
-
-	if (sta_iface_object_map_.find(wpa_s->ifname) ==
-	    sta_iface_object_map_.end())
-		return;
-
-	const u8 *bssid = wpa_s->bssid;
-	if (is_zero_ether_addr(bssid)) {
-		bssid = wpa_s->pending_bssid;
-	}
-
-	callWithEachStaIfaceCallback(
-	    wpa_s->ifname,
-	    std::bind(
-		&ISupplicantStaIfaceCallback::onDisconnected,
-		std::placeholders::_1, bssid, wpa_s->disconnect_reason < 0,
-		static_cast<ISupplicantStaIfaceCallback::ReasonCode>(
-		    abs(wpa_s->disconnect_reason))));
-}
-
-/**
- * Notify all listeners about association reject from the access point to which
- * we are attempting to connect.
- *
- * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
- * the network is present.
- * @param bssid bssid of AP that rejected the association.
- * @param timed_out flag to indicate failure is due to timeout
- * (auth, assoc, ...) rather than explicit rejection response from the AP.
- * @param assoc_resp_ie Association response IE.
- * @param assoc_resp_ie_len Association response IE length.
- */
-void HidlManager::notifyAssocReject(struct wpa_supplicant *wpa_s,
-    const u8 *bssid, u8 timed_out, const u8 *assoc_resp_ie, size_t assoc_resp_ie_len)
-{
-	std::string hidl_ifname = wpa_s->ifname;
-#ifdef CONFIG_MBO
-	struct wpa_bss *reject_bss;
-#endif /* CONFIG_MBO */
-	V1_4::ISupplicantStaIfaceCallback::AssociationRejectionData hidl_assoc_reject_data = {};
-
-	if (!wpa_s)
-		return;
-
-	if (sta_iface_object_map_.find(wpa_s->ifname) ==
-	    sta_iface_object_map_.end())
-		return;
-	if (wpa_s->current_ssid) {
-		std::vector < uint8_t > hidl_ssid;
-		hidl_ssid.assign(
-		    wpa_s->current_ssid->ssid,
-		    wpa_s->current_ssid->ssid + wpa_s->current_ssid->ssid_len);
-		hidl_assoc_reject_data.ssid = hidl_ssid;
-	}
-	hidl_assoc_reject_data.bssid = bssid;
-	hidl_assoc_reject_data.statusCode = static_cast<ISupplicantStaIfaceCallback::StatusCode>(
-					    wpa_s->assoc_status_code);
-	if (timed_out) {
-		hidl_assoc_reject_data.timedOut = true;
-	}
-#ifdef CONFIG_MBO
-	if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SME) {
-		reject_bss = wpa_s->current_bss;
-	} else {
-		reject_bss = wpa_bss_get_bssid(wpa_s, bssid);
-	}
-	if (reject_bss && assoc_resp_ie && assoc_resp_ie_len > 0) {
-		if (wpa_s->assoc_status_code ==
-		    WLAN_STATUS_DENIED_POOR_CHANNEL_CONDITIONS) {
-			const u8 *rssi_rej;
-			rssi_rej = mbo_get_attr_from_ies(
-				    assoc_resp_ie,
-				    assoc_resp_ie_len,
-				    OCE_ATTR_ID_RSSI_BASED_ASSOC_REJECT);
-			if (rssi_rej && rssi_rej[1] == 2) {
-				wpa_printf(MSG_INFO,
-					   "OCE: RSSI-based association rejection from "
-					   MACSTR " Delta RSSI: %u, Retry Delay: %u bss rssi: %d",
-					   MAC2STR(reject_bss->bssid),
-					   rssi_rej[2], rssi_rej[3], reject_bss->level);
-				hidl_assoc_reject_data.isOceRssiBasedAssocRejectAttrPresent = true;
-				hidl_assoc_reject_data.oceRssiBasedAssocRejectData.deltaRssi
-					    = rssi_rej[2];
-				hidl_assoc_reject_data.oceRssiBasedAssocRejectData.retryDelayS
-					    = rssi_rej[3];
-			}
-		} else if (wpa_s->assoc_status_code == WLAN_STATUS_ASSOC_REJECTED_TEMPORARILY
-			  || wpa_s->assoc_status_code == WLAN_STATUS_AP_UNABLE_TO_HANDLE_NEW_STA) {
-			const u8 *assoc_disallowed;
-			assoc_disallowed = mbo_get_attr_from_ies(
-						    assoc_resp_ie,
-						    assoc_resp_ie_len,
-						    MBO_ATTR_ID_ASSOC_DISALLOW);
-			if (assoc_disallowed && assoc_disallowed[1] == 1) {
-				wpa_printf(MSG_INFO,
-				    "MBO: association disallowed indication from "
-				    MACSTR " Reason: %d",
-				    MAC2STR(reject_bss->bssid),
-				    assoc_disallowed[2]);
-				hidl_assoc_reject_data.isMboAssocDisallowedReasonCodePresent = true;
-				hidl_assoc_reject_data.mboAssocDisallowedReason
-				    = static_cast<V1_4::ISupplicantStaIfaceCallback
-					    ::MboAssocDisallowedReasonCode>(assoc_disallowed[2]);
-			}
-		}
-	}
-#endif /* CONFIG_MBO */
-
-	const std::function<
-		    Return<void>(android::sp<V1_4::ISupplicantStaIfaceCallback>)>
-		    func = std::bind(
-		    &V1_4::ISupplicantStaIfaceCallback::onAssociationRejected_1_4,
-		    std::placeholders::_1, hidl_assoc_reject_data);
-	callWithEachStaIfaceCallbackDerived(hidl_ifname, func);
-}
-
-void HidlManager::notifyAuthTimeout(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s)
-		return;
-
-	const std::string ifname(wpa_s->ifname);
-	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
-		return;
-
-	const u8 *bssid = wpa_s->bssid;
-	if (is_zero_ether_addr(bssid)) {
-		bssid = wpa_s->pending_bssid;
-	}
-	callWithEachStaIfaceCallback(
-	    wpa_s->ifname,
-	    std::bind(
-		&ISupplicantStaIfaceCallback::onAuthenticationTimeout,
-		std::placeholders::_1, bssid));
-}
-
-void HidlManager::notifyBssidChanged(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s)
-		return;
-
-	const std::string ifname(wpa_s->ifname);
-	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
-		return;
-
-	// wpa_supplicant does not explicitly give us the reason for bssid
-	// change, but we figure that out from what is set out of |wpa_s->bssid|
-	// & |wpa_s->pending_bssid|.
-	const u8 *bssid;
-	ISupplicantStaIfaceCallback::BssidChangeReason reason;
-	if (is_zero_ether_addr(wpa_s->bssid) &&
-	    !is_zero_ether_addr(wpa_s->pending_bssid)) {
-		bssid = wpa_s->pending_bssid;
-		reason =
-		    ISupplicantStaIfaceCallback::BssidChangeReason::ASSOC_START;
-	} else if (
-	    !is_zero_ether_addr(wpa_s->bssid) &&
-	    is_zero_ether_addr(wpa_s->pending_bssid)) {
-		bssid = wpa_s->bssid;
-		reason = ISupplicantStaIfaceCallback::BssidChangeReason::
-		    ASSOC_COMPLETE;
-	} else if (
-	    is_zero_ether_addr(wpa_s->bssid) &&
-	    is_zero_ether_addr(wpa_s->pending_bssid)) {
-		bssid = wpa_s->pending_bssid;
-		reason =
-		    ISupplicantStaIfaceCallback::BssidChangeReason::DISASSOC;
-	} else {
-		wpa_printf(MSG_ERROR, "Unknown bssid change reason");
-		return;
-	}
-
-	callWithEachStaIfaceCallback(
-	    wpa_s->ifname, std::bind(
-			       &ISupplicantStaIfaceCallback::onBssidChanged,
-			       std::placeholders::_1, reason, bssid));
-}
-
-void HidlManager::notifyWpsEventFail(
-    struct wpa_supplicant *wpa_s, uint8_t *peer_macaddr, uint16_t config_error,
-    uint16_t error_indication)
-{
-	if (!wpa_s || !peer_macaddr)
-		return;
-
-	if (sta_iface_object_map_.find(wpa_s->ifname) ==
-	    sta_iface_object_map_.end())
-		return;
-
-	callWithEachStaIfaceCallback(
-	    wpa_s->ifname,
-	    std::bind(
-		&ISupplicantStaIfaceCallback::onWpsEventFail,
-		std::placeholders::_1, peer_macaddr,
-		static_cast<ISupplicantStaIfaceCallback::WpsConfigError>(
-		    config_error),
-		static_cast<ISupplicantStaIfaceCallback::WpsErrorIndication>(
-		    error_indication)));
-}
-
-void HidlManager::notifyWpsEventSuccess(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s)
-		return;
-
-	if (sta_iface_object_map_.find(wpa_s->ifname) ==
-	    sta_iface_object_map_.end())
-		return;
-
-	callWithEachStaIfaceCallback(
-	    wpa_s->ifname, std::bind(
-			       &ISupplicantStaIfaceCallback::onWpsEventSuccess,
-			       std::placeholders::_1));
-}
-
-void HidlManager::notifyWpsEventPbcOverlap(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s)
-		return;
-
-	if (sta_iface_object_map_.find(wpa_s->ifname) ==
-	    sta_iface_object_map_.end())
-		return;
-
-	callWithEachStaIfaceCallback(
-	    wpa_s->ifname,
-	    std::bind(
-		&ISupplicantStaIfaceCallback::onWpsEventPbcOverlap,
-		std::placeholders::_1));
-}
-
-void HidlManager::notifyP2pDeviceFound(
-    struct wpa_supplicant *wpa_s, const u8 *addr,
-    const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
-    u8 peer_wfd_device_info_len, const u8 *peer_wfd_r2_device_info,
-    u8 peer_wfd_r2_device_info_len)
-{
-	if (!wpa_s || !addr || !info)
-		return;
-
-	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
-	    p2p_iface_object_map_.end())
-		return;
-
-	std::array<uint8_t, kWfdDeviceInfoLen> hidl_peer_wfd_device_info{};
-	if (peer_wfd_device_info) {
-		if (peer_wfd_device_info_len != kWfdDeviceInfoLen) {
-			wpa_printf(
-			    MSG_ERROR, "Unexpected WFD device info len: %d",
-			    peer_wfd_device_info_len);
-		} else {
-			os_memcpy(
-			    hidl_peer_wfd_device_info.data(),
-			    peer_wfd_device_info, kWfdDeviceInfoLen);
-		}
-	}
-
-	std::array<uint8_t, kWfdR2DeviceInfoLen> hidl_peer_wfd_r2_device_info{};
-	if (peer_wfd_r2_device_info) {
-		if (peer_wfd_r2_device_info_len != kWfdR2DeviceInfoLen) {
-			wpa_printf(
-			    MSG_ERROR, "Unexpected WFD R2 device info len: %d",
-			    peer_wfd_r2_device_info_len);
-			return;
-		} else {
-			os_memcpy(
-			    hidl_peer_wfd_r2_device_info.data(),
-			    peer_wfd_r2_device_info, kWfdR2DeviceInfoLen);
-		}
-	}
-
-	if (peer_wfd_r2_device_info_len == kWfdR2DeviceInfoLen) {
-		const std::function<
-		    Return<void>(android::sp<V1_4::ISupplicantP2pIfaceCallback>)>
-		    func = std::bind(
-			&ISupplicantP2pIfaceCallbackV1_4::onR2DeviceFound,
-			std::placeholders::_1, addr, info->p2p_device_addr,
-			info->pri_dev_type, info->device_name, info->config_methods,
-			info->dev_capab, info->group_capab, hidl_peer_wfd_device_info,
-			hidl_peer_wfd_r2_device_info);
-		callWithEachP2pIfaceCallbackDerived(wpa_s->ifname, func);
-	} else {
-		callWithEachP2pIfaceCallback(
-		    wpa_s->ifname,
-		    std::bind(
-			&ISupplicantP2pIfaceCallback::onDeviceFound,
-			std::placeholders::_1, addr, info->p2p_device_addr,
-			info->pri_dev_type, info->device_name, info->config_methods,
-			info->dev_capab, info->group_capab, hidl_peer_wfd_device_info));
-	}
-}
-
-void HidlManager::notifyP2pDeviceLost(
-    struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr)
-{
-	if (!wpa_s || !p2p_device_addr)
-		return;
-
-	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
-	    p2p_iface_object_map_.end())
-		return;
-
-	callWithEachP2pIfaceCallback(
-	    wpa_s->ifname, std::bind(
-			       &ISupplicantP2pIfaceCallback::onDeviceLost,
-			       std::placeholders::_1, p2p_device_addr));
-}
-
-void HidlManager::notifyP2pFindStopped(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s)
-		return;
-
-	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
-	    p2p_iface_object_map_.end())
-		return;
-
-	callWithEachP2pIfaceCallback(
-	    wpa_s->ifname, std::bind(
-			       &ISupplicantP2pIfaceCallback::onFindStopped,
-			       std::placeholders::_1));
-}
-
-void HidlManager::notifyP2pGoNegReq(
-    struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
-    u8 /* go_intent */)
-{
-	if (!wpa_s || !src_addr)
-		return;
-
-	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
-	    p2p_iface_object_map_.end())
-		return;
-
-	callWithEachP2pIfaceCallback(
-	    wpa_s->ifname,
-	    std::bind(
-		&ISupplicantP2pIfaceCallback::onGoNegotiationRequest,
-		std::placeholders::_1, src_addr,
-		static_cast<ISupplicantP2pIfaceCallback::WpsDevPasswordId>(
-		    dev_passwd_id)));
-}
-
-void HidlManager::notifyP2pGoNegCompleted(
-    struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res)
-{
-	if (!wpa_s || !res)
-		return;
-
-	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
-	    p2p_iface_object_map_.end())
-		return;
-
-	callWithEachP2pIfaceCallback(
-	    wpa_s->ifname,
-	    std::bind(
-		&ISupplicantP2pIfaceCallback::onGoNegotiationCompleted,
-		std::placeholders::_1,
-		static_cast<ISupplicantP2pIfaceCallback::P2pStatusCode>(
-		    res->status)));
-}
-
-void HidlManager::notifyP2pGroupFormationFailure(
-    struct wpa_supplicant *wpa_s, const char *reason)
-{
-	if (!wpa_s || !reason)
-		return;
-
-	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
-	    p2p_iface_object_map_.end())
-		return;
-
-	callWithEachP2pIfaceCallback(
-	    wpa_s->ifname,
-	    std::bind(
-		&ISupplicantP2pIfaceCallback::onGroupFormationFailure,
-		std::placeholders::_1, reason));
-}
-
-void HidlManager::notifyP2pGroupStarted(
-    struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
-    int persistent, int client)
-{
-	if (!wpa_group_s || !wpa_group_s->parent || !ssid)
-		return;
-
-	// For group notifications, need to use the parent iface for callbacks.
-	struct wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
-	if (!wpa_s)
-		return;
-
-	uint32_t hidl_freq = wpa_group_s->current_bss
-				 ? wpa_group_s->current_bss->freq
-				 : wpa_group_s->assoc_freq;
-	std::array<uint8_t, 32> hidl_psk;
-	if (ssid->psk_set) {
-		os_memcpy(hidl_psk.data(), ssid->psk, 32);
-	}
-	bool hidl_is_go = (client == 0 ? true : false);
-	bool hidl_is_persistent = (persistent == 1 ? true : false);
-
-	// notify the group device again to ensure the framework knowing this device.
-	struct p2p_data *p2p = wpa_s->global->p2p;
-	struct p2p_device *dev = p2p_get_device(p2p, wpa_group_s->go_dev_addr);
-	if (NULL != dev) {
-		wpa_printf(MSG_DEBUG, "P2P: Update GO device on group started.");
-		p2p->cfg->dev_found(p2p->cfg->cb_ctx, wpa_group_s->go_dev_addr,
-				&dev->info, !(dev->flags & P2P_DEV_REPORTED_ONCE));
-		dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE;
-	}
-
-	callWithEachP2pIfaceCallback(
-	    wpa_s->ifname,
-	    std::bind(
-		&ISupplicantP2pIfaceCallback::onGroupStarted,
-		std::placeholders::_1, wpa_group_s->ifname, hidl_is_go,
-		std::vector<uint8_t>{ssid->ssid, ssid->ssid + ssid->ssid_len},
-		hidl_freq, hidl_psk, ssid->passphrase, wpa_group_s->go_dev_addr,
-		hidl_is_persistent));
-}
-
-void HidlManager::notifyP2pGroupRemoved(
-    struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
-    const char *role)
-{
-	if (!wpa_group_s || !wpa_group_s->parent || !ssid || !role)
-		return;
-
-	// For group notifications, need to use the parent iface for callbacks.
-	struct wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
-	if (!wpa_s)
-		return;
-
-	bool hidl_is_go = (std::string(role) == "GO");
-
-	callWithEachP2pIfaceCallback(
-	    wpa_s->ifname,
-	    std::bind(
-		&ISupplicantP2pIfaceCallback::onGroupRemoved,
-		std::placeholders::_1, wpa_group_s->ifname, hidl_is_go));
-}
-
-void HidlManager::notifyP2pInvitationReceived(
-    struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
-    const u8 *bssid, int id, int op_freq)
-{
-	if (!wpa_s || !sa || !go_dev_addr || !bssid)
-		return;
-
-	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
-	    p2p_iface_object_map_.end())
-		return;
-
-	SupplicantNetworkId hidl_network_id;
-	if (id < 0) {
-		hidl_network_id = UINT32_MAX;
-	}
-	hidl_network_id = id;
-
-	callWithEachP2pIfaceCallback(
-	    wpa_s->ifname,
-	    std::bind(
-		&ISupplicantP2pIfaceCallback::onInvitationReceived,
-		std::placeholders::_1, sa, go_dev_addr, bssid, hidl_network_id,
-		op_freq));
-}
-
-void HidlManager::notifyP2pInvitationResult(
-    struct wpa_supplicant *wpa_s, int status, const u8 *bssid)
-{
-	if (!wpa_s)
-		return;
-
-	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
-	    p2p_iface_object_map_.end())
-		return;
-
-	callWithEachP2pIfaceCallback(
-	    wpa_s->ifname,
-	    std::bind(
-		&ISupplicantP2pIfaceCallback::onInvitationResult,
-		std::placeholders::_1, bssid ? bssid : kZeroBssid,
-		static_cast<ISupplicantP2pIfaceCallback::P2pStatusCode>(
-		    status)));
-}
-
-void HidlManager::notifyP2pProvisionDiscovery(
-    struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
-    enum p2p_prov_disc_status status, u16 config_methods,
-    unsigned int generated_pin)
-{
-	if (!wpa_s || !dev_addr)
-		return;
-
-	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
-	    p2p_iface_object_map_.end())
-		return;
-
-	std::string hidl_generated_pin;
-	if (generated_pin > 0) {
-		hidl_generated_pin =
-		    misc_utils::convertWpsPinToString(generated_pin);
-	}
-	bool hidl_is_request = (request == 1 ? true : false);
-
-	callWithEachP2pIfaceCallback(
-	    wpa_s->ifname,
-	    std::bind(
-		&ISupplicantP2pIfaceCallback::onProvisionDiscoveryCompleted,
-		std::placeholders::_1, dev_addr, hidl_is_request,
-		static_cast<ISupplicantP2pIfaceCallback::P2pProvDiscStatusCode>(
-		    status),
-		config_methods, hidl_generated_pin));
-}
-
-void HidlManager::notifyP2pSdResponse(
-    struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
-    const u8 *tlvs, size_t tlvs_len)
-{
-	if (!wpa_s || !sa || !tlvs)
-		return;
-
-	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
-	    p2p_iface_object_map_.end())
-		return;
-
-	callWithEachP2pIfaceCallback(
-	    wpa_s->ifname,
-	    std::bind(
-		&ISupplicantP2pIfaceCallback::onServiceDiscoveryResponse,
-		std::placeholders::_1, sa, update_indic,
-		std::vector<uint8_t>{tlvs, tlvs + tlvs_len}));
-}
-
-void HidlManager::notifyApStaAuthorized(
-    struct wpa_supplicant *wpa_group_s, const u8 *sta, const u8 *p2p_dev_addr)
-{
-	if (!wpa_group_s || !wpa_group_s->parent || !sta)
-		return;
-	wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
-	if (!wpa_s)
-		return;
-	callWithEachP2pIfaceCallback(
-	    wpa_s->ifname,
-	    std::bind(
-		&ISupplicantP2pIfaceCallback::onStaAuthorized,
-		std::placeholders::_1, sta,
-		p2p_dev_addr ? p2p_dev_addr : kZeroBssid));
-}
-
-void HidlManager::notifyApStaDeauthorized(
-    struct wpa_supplicant *wpa_group_s, const u8 *sta, const u8 *p2p_dev_addr)
-{
-	if (!wpa_group_s || !wpa_group_s->parent || !sta)
-		return;
-	wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
-	if (!wpa_s)
-		return;
-
-	callWithEachP2pIfaceCallback(
-	    wpa_s->ifname,
-	    std::bind(
-		&ISupplicantP2pIfaceCallback::onStaDeauthorized,
-		std::placeholders::_1, sta,
-		p2p_dev_addr ? p2p_dev_addr : kZeroBssid));
-}
-
-void HidlManager::notifyExtRadioWorkStart(
-    struct wpa_supplicant *wpa_s, uint32_t id)
-{
-	if (!wpa_s)
-		return;
-
-	if (sta_iface_object_map_.find(wpa_s->ifname) ==
-	    sta_iface_object_map_.end())
-		return;
-
-	callWithEachStaIfaceCallback(
-	    wpa_s->ifname,
-	    std::bind(
-		&ISupplicantStaIfaceCallback::onExtRadioWorkStart,
-		std::placeholders::_1, id));
-}
-
-void HidlManager::notifyExtRadioWorkTimeout(
-    struct wpa_supplicant *wpa_s, uint32_t id)
-{
-	if (!wpa_s)
-		return;
-
-	if (sta_iface_object_map_.find(wpa_s->ifname) ==
-	    sta_iface_object_map_.end())
-		return;
-
-	callWithEachStaIfaceCallback(
-	    wpa_s->ifname,
-	    std::bind(
-		&ISupplicantStaIfaceCallback::onExtRadioWorkTimeout,
-		std::placeholders::_1, id));
-}
-
-void HidlManager::notifyEapError(struct wpa_supplicant *wpa_s, int error_code)
-{
-	if (!wpa_s)
-		return;
-
-	callWithEachStaIfaceCallback_1_3(
-	    wpa_s->ifname,
-	    std::bind(
-		&V1_3::ISupplicantStaIfaceCallback::onEapFailure_1_3,
-		std::placeholders::_1, error_code));
-}
-
-/**
- * Notify listener about a new DPP configuration received success event
- *
- * @param ifname Interface name
- * @param config Configuration object
- */
-void HidlManager::notifyDppConfigReceived(struct wpa_supplicant *wpa_s,
-		struct wpa_ssid *config)
-{
-	DppAkm securityAkm;
-	char *password;
-	std::string hidl_ifname = wpa_s->ifname;
-
-	if ((config->key_mgmt & WPA_KEY_MGMT_SAE) &&
-			(wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE)) {
-		securityAkm = DppAkm::SAE;
-	} else if (config->key_mgmt & WPA_KEY_MGMT_PSK) {
-			securityAkm = DppAkm::PSK;
-	} else {
-		/* Unsupported AKM */
-		wpa_printf(MSG_ERROR, "DPP: Error: Unsupported AKM 0x%X",
-				config->key_mgmt);
-		notifyDppFailure(wpa_s,
-				android::hardware::wifi::supplicant::V1_3::DppFailureCode
-				::NOT_SUPPORTED);
-		return;
-	}
-
-	password = config->passphrase;
-	std::vector < uint8_t > hidl_ssid;
-	hidl_ssid.assign(config->ssid, config->ssid + config->ssid_len);
-
-	/* At this point, the network is already registered, notify about new
-	 * received configuration
-	 */
-	callWithEachStaIfaceCallback_1_2(hidl_ifname,
-			std::bind(
-					&V1_2::ISupplicantStaIfaceCallback::onDppSuccessConfigReceived,
-					std::placeholders::_1, hidl_ssid, password, config->psk,
-					securityAkm));
-}
-
-/**
- * Notify listener about a DPP configuration sent success event
- *
- * @param ifname Interface name
- */
-void HidlManager::notifyDppConfigSent(struct wpa_supplicant *wpa_s)
-{
-	std::string hidl_ifname = wpa_s->ifname;
-
-	callWithEachStaIfaceCallback_1_2(hidl_ifname,
-			std::bind(&V1_2::ISupplicantStaIfaceCallback::onDppSuccessConfigSent,
-					std::placeholders::_1));
-}
-
-/**
- * Notify listener about a DPP failure event
- *
- * @param ifname Interface name
- * @param code Status code
- */
-void HidlManager::notifyDppFailure(struct wpa_supplicant *wpa_s,
-		android::hardware::wifi::supplicant::V1_3::DppFailureCode code) {
-	std::string hidl_ifname = wpa_s->ifname;
-
-	notifyDppFailure(wpa_s, code, NULL, NULL, NULL, 0);
-}
-
-/**
- * Notify listener about a DPP failure event
- *
- * @param ifname Interface name
- * @param code Status code
- */
-void HidlManager::notifyDppFailure(struct wpa_supplicant *wpa_s,
-		android::hardware::wifi::supplicant::V1_3::DppFailureCode code,
-		const char *ssid, const char *channel_list, unsigned short band_list[],
-		int size) {
-	std::string hidl_ifname = wpa_s->ifname;
-	std::vector<uint16_t> band_list_vec(band_list, band_list + size);
-
-	callWithEachStaIfaceCallback_1_3(hidl_ifname,
-			std::bind(&V1_3::ISupplicantStaIfaceCallback::onDppFailure_1_3,
-					std::placeholders::_1, code, ssid, channel_list, band_list_vec));
-}
-
-/**
- * Notify listener about a DPP progress event
- *
- * @param ifname Interface name
- * @param code Status code
- */
-void HidlManager::notifyDppProgress(struct wpa_supplicant *wpa_s,
-		android::hardware::wifi::supplicant::V1_3::DppProgressCode code) {
-	std::string hidl_ifname = wpa_s->ifname;
-
-	callWithEachStaIfaceCallback_1_3(hidl_ifname,
-			std::bind(&V1_3::ISupplicantStaIfaceCallback::onDppProgress_1_3,
-					std::placeholders::_1, code));
-}
-
-/**
- * Notify listener about a DPP success event
- *
- * @param ifname Interface name
- * @param code Status code
- */
-void HidlManager::notifyDppSuccess(struct wpa_supplicant *wpa_s, V1_3::DppSuccessCode code)
-{
-	std::string hidl_ifname = wpa_s->ifname;
-
-	callWithEachStaIfaceCallback_1_3(hidl_ifname,
-			std::bind(&V1_3::ISupplicantStaIfaceCallback::onDppSuccess,
-					std::placeholders::_1, code));
-}
-
-/**
- * Notify listener about a PMK cache added event
- *
- * @param ifname Interface name
- * @param entry PMK cache entry
- */
-void HidlManager::notifyPmkCacheAdded(
-    struct wpa_supplicant *wpa_s, struct rsn_pmksa_cache_entry *pmksa_entry)
-{
-	std::string hidl_ifname = wpa_s->ifname;
-
-	// Serialize PmkCacheEntry into blob.
-	std::stringstream ss(
-	    std::stringstream::in | std::stringstream::out | std::stringstream::binary);
-	misc_utils::serializePmkCacheEntry(ss, pmksa_entry);
-	std::vector<uint8_t> serializedEntry(
-		std::istreambuf_iterator<char>(ss), {});
-
-	const std::function<
-	    Return<void>(android::sp<V1_3::ISupplicantStaIfaceCallback>)>
-	    func = std::bind(
-		&V1_3::ISupplicantStaIfaceCallback::onPmkCacheAdded,
-		std::placeholders::_1, pmksa_entry->expiration, serializedEntry);
-	callWithEachStaIfaceCallbackDerived(hidl_ifname, func);
-}
-
-#ifdef CONFIG_WNM
-V1_3::ISupplicantStaIfaceCallback::BssTmStatusCode convertSupplicantBssTmStatusToHidl(
-    enum bss_trans_mgmt_status_code bss_tm_status)
-{
-	switch (bss_tm_status) {
-		case WNM_BSS_TM_ACCEPT:
-			return V1_3::ISupplicantStaIfaceCallback::BssTmStatusCode::ACCEPT;
-		case WNM_BSS_TM_REJECT_UNSPECIFIED:
-			return V1_3::ISupplicantStaIfaceCallback::
-			    BssTmStatusCode::REJECT_UNSPECIFIED;
-		case WNM_BSS_TM_REJECT_INSUFFICIENT_BEACON:
-			return V1_3::ISupplicantStaIfaceCallback::
-			    BssTmStatusCode::REJECT_INSUFFICIENT_BEACON;
-		case WNM_BSS_TM_REJECT_INSUFFICIENT_CAPABITY:
-			return V1_3::ISupplicantStaIfaceCallback::
-			    BssTmStatusCode::REJECT_INSUFFICIENT_CAPABITY;
-		case WNM_BSS_TM_REJECT_UNDESIRED:
-			return V1_3::ISupplicantStaIfaceCallback::
-			    BssTmStatusCode::REJECT_BSS_TERMINATION_UNDESIRED;
-		case WNM_BSS_TM_REJECT_DELAY_REQUEST:
-			return V1_3::ISupplicantStaIfaceCallback::
-			    BssTmStatusCode::REJECT_BSS_TERMINATION_DELAY_REQUEST;
-		case WNM_BSS_TM_REJECT_STA_CANDIDATE_LIST_PROVIDED:
-			return V1_3::ISupplicantStaIfaceCallback::
-			    BssTmStatusCode::REJECT_STA_CANDIDATE_LIST_PROVIDED;
-		case WNM_BSS_TM_REJECT_NO_SUITABLE_CANDIDATES:
-			return V1_3::ISupplicantStaIfaceCallback::
-			    BssTmStatusCode::REJECT_NO_SUITABLE_CANDIDATES;
-		case WNM_BSS_TM_REJECT_LEAVING_ESS:
-			return V1_3::ISupplicantStaIfaceCallback::
-			    BssTmStatusCode::REJECT_LEAVING_ESS;
-		default:
-			return V1_3::ISupplicantStaIfaceCallback::
-			    BssTmStatusCode::REJECT_UNSPECIFIED;
-	}
-}
-
-uint32_t setBssTmDataFlagsMask(struct wpa_supplicant *wpa_s)
-{
-	uint32_t flags = 0;
-
-	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED) {
-		flags |= V1_3::ISupplicantStaIfaceCallback::
-		    BssTmDataFlagsMask::WNM_MODE_BSS_TERMINATION_INCLUDED;
-	}
-	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_ESS_DISASSOC_IMMINENT) {
-		flags |= V1_3::ISupplicantStaIfaceCallback::
-		    BssTmDataFlagsMask::WNM_MODE_ESS_DISASSOCIATION_IMMINENT;
-	}
-	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_DISASSOC_IMMINENT) {
-		flags |= V1_3::ISupplicantStaIfaceCallback::
-		    BssTmDataFlagsMask::WNM_MODE_DISASSOCIATION_IMMINENT;
-	}
-	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_ABRIDGED) {
-		flags |= V1_3::ISupplicantStaIfaceCallback::
-		    BssTmDataFlagsMask::WNM_MODE_ABRIDGED;
-	}
-	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_PREF_CAND_LIST_INCLUDED) {
-		flags |= V1_3::ISupplicantStaIfaceCallback::
-		    BssTmDataFlagsMask::WNM_MODE_PREFERRED_CANDIDATE_LIST_INCLUDED;
-	}
-#ifdef CONFIG_MBO
-	if (wpa_s->wnm_mbo_assoc_retry_delay_present) {
-		flags |= V1_3::ISupplicantStaIfaceCallback::
-		    BssTmDataFlagsMask::MBO_ASSOC_RETRY_DELAY_INCLUDED;
-	}
-	if (wpa_s->wnm_mbo_trans_reason_present) {
-		flags |= V1_3::ISupplicantStaIfaceCallback::
-		    BssTmDataFlagsMask::MBO_TRANSITION_REASON_CODE_INCLUDED;
-	}
-	if (wpa_s->wnm_mbo_cell_pref_present) {
-		flags |= V1_3::ISupplicantStaIfaceCallback::
-		    BssTmDataFlagsMask::MBO_CELLULAR_DATA_CONNECTION_PREFERENCE_INCLUDED;
-	}
-#endif
-	return flags;
-}
-
-uint32_t getBssTmDataAssocRetryDelayMs(struct wpa_supplicant *wpa_s)
-{
-	uint32_t beacon_int;
-	uint32_t duration_ms = 0;
-
-	if (wpa_s->current_bss)
-		beacon_int = wpa_s->current_bss->beacon_int;
-	else
-		beacon_int = 100; /* best guess */
-
-	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_DISASSOC_IMMINENT) {
-		// number of tbtts to milliseconds
-		duration_ms = wpa_s->wnm_dissoc_timer * beacon_int * 128 / 125;
-	}
-	if (wpa_s->wnm_mode & WNM_BSS_TM_REQ_BSS_TERMINATION_INCLUDED) {
-		//wnm_bss_termination_duration contains 12 bytes of BSS
-		//termination duration subelement. Format of IE is
-		// Sub eid | Length | BSS termination TSF | Duration
-		//    1	 1	     8		2
-		// Duration indicates number of minutes for which BSS is not
-		// present.
-		duration_ms = WPA_GET_LE16(wpa_s->wnm_bss_termination_duration + 10);
-		// minutes to milliseconds
-		duration_ms = duration_ms * 60 * 1000;
-	}
-#ifdef CONFIG_MBO
-	if (wpa_s->wnm_mbo_assoc_retry_delay_present) {
-		// number of seconds to milliseconds
-		duration_ms = wpa_s->wnm_mbo_assoc_retry_delay_sec * 1000;
-	}
-#endif
-
-	return duration_ms;
-}
-#endif
-
-/**
- * Notify listener about the status of BSS transition management
- * request frame handling.
- *
- * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
- * the network is present.
- */
-void HidlManager::notifyBssTmStatus(struct wpa_supplicant *wpa_s)
-{
-#ifdef CONFIG_WNM
-	std::string hidl_ifname = wpa_s->ifname;
-	V1_3::ISupplicantStaIfaceCallback::BssTmData hidl_bsstm_data = {};
-
-	hidl_bsstm_data.status = convertSupplicantBssTmStatusToHidl(wpa_s->bss_tm_status);
-	hidl_bsstm_data.flags = setBssTmDataFlagsMask(wpa_s);
-	hidl_bsstm_data.assocRetryDelayMs = getBssTmDataAssocRetryDelayMs(wpa_s);
-#ifdef CONFIG_MBO
-	if (wpa_s->wnm_mbo_cell_pref_present) {
-		hidl_bsstm_data.mboCellPreference = static_cast
-		    <V1_3::ISupplicantStaIfaceCallback::MboCellularDataConnectionPrefValue>
-		    (wpa_s->wnm_mbo_cell_preference);
-	}
-	if (wpa_s->wnm_mbo_trans_reason_present) {
-		hidl_bsstm_data.mboTransitionReason =
-		    static_cast<V1_3::ISupplicantStaIfaceCallback::MboTransitionReasonCode>
-		    (wpa_s->wnm_mbo_transition_reason);
-	}
-#endif
-
-	const std::function<
-	    Return<void>(android::sp<V1_3::ISupplicantStaIfaceCallback>)>
-	    func = std::bind(
-		&V1_3::ISupplicantStaIfaceCallback::onBssTmHandlingDone,
-		std::placeholders::_1, hidl_bsstm_data);
-	callWithEachStaIfaceCallbackDerived(hidl_ifname, func);
-#endif
-}
-
-uint32_t setTransitionDisableFlagsMask(u8 bitmap)
-{
-	uint32_t flags = 0;
-
-	if (bitmap & TRANSITION_DISABLE_WPA3_PERSONAL) {
-		flags |= V1_4::ISupplicantStaNetworkCallback::
-			TransitionDisableIndication::
-			USE_WPA3_PERSONAL;
-		bitmap &= ~TRANSITION_DISABLE_WPA3_PERSONAL;
-	}
-	if (bitmap & TRANSITION_DISABLE_SAE_PK) {
-		flags |= V1_4::ISupplicantStaNetworkCallback::
-			TransitionDisableIndication::
-			USE_SAE_PK;
-		bitmap &= ~TRANSITION_DISABLE_SAE_PK;
-	}
-	if (bitmap & TRANSITION_DISABLE_WPA3_ENTERPRISE) {
-		flags |= V1_4::ISupplicantStaNetworkCallback::
-			TransitionDisableIndication::
-			USE_WPA3_ENTERPRISE;
-		bitmap &= ~TRANSITION_DISABLE_WPA3_ENTERPRISE;
-	}
-	if (bitmap & TRANSITION_DISABLE_ENHANCED_OPEN) {
-		flags |= V1_4::ISupplicantStaNetworkCallback::
-			TransitionDisableIndication::
-			USE_ENHANCED_OPEN;
-		bitmap &= ~TRANSITION_DISABLE_ENHANCED_OPEN;
-	}
-
-	if (bitmap != 0) {
-		wpa_printf(MSG_WARNING, "Unhandled transition disable bit: 0x%x", bitmap);
-	}
-
-	return flags;
-}
-
-void HidlManager::notifyTransitionDisable(struct wpa_supplicant *wpa_s,
-    struct wpa_ssid *ssid, u8 bitmap)
-{
-	uint32_t flag = setTransitionDisableFlagsMask(bitmap);
-	const std::function<
-	    Return<void>(android::sp<V1_4::ISupplicantStaNetworkCallback>)>
-	    func = std::bind(
-		&V1_4::ISupplicantStaNetworkCallback::onTransitionDisable,
-		std::placeholders::_1, flag);
-
-	callWithEachStaNetworkCallbackDerived(wpa_s->ifname, ssid->id, func);
-}
-
-void HidlManager::notifyNetworkNotFound(struct wpa_supplicant *wpa_s)
-{
-	std::vector<uint8_t> hidl_ssid;
-
-	if (!wpa_s->current_ssid) {
-		wpa_printf(MSG_ERROR, "Current network NULL. Drop WPA_EVENT_NETWORK_NOT_FOUND!");
-		return;
-	}
-
-	hidl_ssid.assign(
-		    wpa_s->current_ssid->ssid,
-		    wpa_s->current_ssid->ssid + wpa_s->current_ssid->ssid_len);
-
-	const std::function<
-	    Return<void>(android::sp<V1_4::ISupplicantStaIfaceCallback>)>
-	    func = std::bind(
-		&V1_4::ISupplicantStaIfaceCallback::onNetworkNotFound,
-		std::placeholders::_1, hidl_ssid);
-	callWithEachStaIfaceCallbackDerived(wpa_s->ifname, func);
-}
-
-/**
- * Retrieve the |ISupplicantP2pIface| hidl object reference using the provided
- * ifname.
- *
- * @param ifname Name of the corresponding interface.
- * @param iface_object Hidl reference corresponding to the iface.
- *
- * @return 0 on success, 1 on failure.
- */
-int HidlManager::getP2pIfaceHidlObjectByIfname(
-    const std::string &ifname, android::sp<ISupplicantP2pIface> *iface_object)
-{
-	if (ifname.empty() || !iface_object)
-		return 1;
-
-	auto iface_object_iter = p2p_iface_object_map_.find(ifname);
-	if (iface_object_iter == p2p_iface_object_map_.end())
-		return 1;
-
-	*iface_object = iface_object_iter->second;
-	return 0;
-}
-
-/**
- * Retrieve the |ISupplicantStaIface| hidl object reference using the provided
- * ifname.
- *
- * @param ifname Name of the corresponding interface.
- * @param iface_object Hidl reference corresponding to the iface.
- *
- * @return 0 on success, 1 on failure.
- */
-int HidlManager::getStaIfaceHidlObjectByIfname(
-    const std::string &ifname, android::sp<V1_1::ISupplicantStaIface> *iface_object)
-{
-	if (ifname.empty() || !iface_object)
-		return 1;
-
-	auto iface_object_iter = sta_iface_object_map_.find(ifname);
-	if (iface_object_iter == sta_iface_object_map_.end())
-		return 1;
-
-	*iface_object = iface_object_iter->second;
-	return 0;
-}
-
-/**
- * Retrieve the |ISupplicantP2pNetwork| hidl object reference using the provided
- * ifname and network_id.
- *
- * @param ifname Name of the corresponding interface.
- * @param network_id ID of the corresponding network.
- * @param network_object Hidl reference corresponding to the network.
- *
- * @return 0 on success, 1 on failure.
- */
-int HidlManager::getP2pNetworkHidlObjectByIfnameAndNetworkId(
-    const std::string &ifname, int network_id,
-    android::sp<ISupplicantP2pNetwork> *network_object)
-{
-	if (ifname.empty() || network_id < 0 || !network_object)
-		return 1;
-
-	// Generate the key to be used to lookup the network.
-	const std::string network_key =
-	    getNetworkObjectMapKey(ifname, network_id);
-
-	auto network_object_iter = p2p_network_object_map_.find(network_key);
-	if (network_object_iter == p2p_network_object_map_.end())
-		return 1;
-
-	*network_object = network_object_iter->second;
-	return 0;
-}
-
-/**
- * Retrieve the |ISupplicantStaNetwork| hidl object reference using the provided
- * ifname and network_id.
- *
- * @param ifname Name of the corresponding interface.
- * @param network_id ID of the corresponding network.
- * @param network_object Hidl reference corresponding to the network.
- *
- * @return 0 on success, 1 on failure.
- */
-int HidlManager::getStaNetworkHidlObjectByIfnameAndNetworkId(
-    const std::string &ifname, int network_id,
-    android::sp<V1_3::ISupplicantStaNetwork> *network_object)
-{
-	if (ifname.empty() || network_id < 0 || !network_object)
-		return 1;
-
-	// Generate the key to be used to lookup the network.
-	const std::string network_key =
-	    getNetworkObjectMapKey(ifname, network_id);
-
-	auto network_object_iter = sta_network_object_map_.find(network_key);
-	if (network_object_iter == sta_network_object_map_.end())
-		return 1;
-
-	*network_object = network_object_iter->second;
-	return 0;
-}
-
-/**
- * Add a new |ISupplicantCallback| hidl object reference to our
- * global callback list.
- *
- * @param callback Hidl reference of the |ISupplicantCallback| object.
- *
- * @return 0 on success, 1 on failure.
- */
-int HidlManager::addSupplicantCallbackHidlObject(
-    const android::sp<ISupplicantCallback> &callback)
-{
-	return registerForDeathAndAddCallbackHidlObjectToList<
-	    ISupplicantCallback>(
-	    death_notifier_, callback, supplicant_callbacks_);
-}
-
-/**
- * Add a new iface callback hidl object reference to our
- * interface callback list.
- *
- * @param ifname Name of the corresponding interface.
- * @param callback Hidl reference of the callback object.
- *
- * @return 0 on success, 1 on failure.
- */
-int HidlManager::addP2pIfaceCallbackHidlObject(
-    const std::string &ifname,
-    const android::sp<ISupplicantP2pIfaceCallback> &callback)
-{
-	return addIfaceCallbackHidlObjectToMap(
-	    death_notifier_, ifname, callback, p2p_iface_callbacks_map_);
-}
-
-/**
- * Add a new iface callback hidl object reference to our
- * interface callback list.
- *
- * @param ifname Name of the corresponding interface.
- * @param callback Hidl reference of the callback object.
- *
- * @return 0 on success, 1 on failure.
- */
-int HidlManager::addStaIfaceCallbackHidlObject(
-    const std::string &ifname,
-    const android::sp<ISupplicantStaIfaceCallback> &callback)
-{
-	return addIfaceCallbackHidlObjectToMap(
-	    death_notifier_, ifname, callback, sta_iface_callbacks_map_);
-}
-
-/**
- * Add a new network callback hidl object reference to our network callback
- * list.
- *
- * @param ifname Name of the corresponding interface.
- * @param network_id ID of the corresponding network.
- * @param callback Hidl reference of the callback object.
- *
- * @return 0 on success, 1 on failure.
- */
-int HidlManager::addP2pNetworkCallbackHidlObject(
-    const std::string &ifname, int network_id,
-    const android::sp<ISupplicantP2pNetworkCallback> &callback)
-{
-	return addNetworkCallbackHidlObjectToMap(
-	    death_notifier_, ifname, network_id, callback,
-	    p2p_network_callbacks_map_);
-}
-
-/**
- * Add a new network callback hidl object reference to our network callback
- * list.
- *
- * @param ifname Name of the corresponding interface.
- * @param network_id ID of the corresponding network.
- * @param callback Hidl reference of the callback object.
- *
- * @return 0 on success, 1 on failure.
- */
-int HidlManager::addStaNetworkCallbackHidlObject(
-    const std::string &ifname, int network_id,
-    const android::sp<ISupplicantStaNetworkCallback> &callback)
-{
-	return addNetworkCallbackHidlObjectToMap(
-	    death_notifier_, ifname, network_id, callback,
-	    sta_network_callbacks_map_);
-}
-
-/**
- * Finds the correct |wpa_supplicant| object for P2P notifications
- *
- * @param wpa_s the |wpa_supplicant| that triggered the P2P event.
- * @return appropriate |wpa_supplicant| object or NULL if not found.
- */
-struct wpa_supplicant *HidlManager::getTargetP2pIfaceForGroup(
-	    struct wpa_supplicant *wpa_group_s)
-{
-	if (!wpa_group_s || !wpa_group_s->parent)
-		return NULL;
-
-	struct wpa_supplicant *target_wpa_s = wpa_group_s->parent;
-
-	// check wpa_supplicant object is a p2p device interface
-	if ((wpa_group_s == wpa_group_s->p2pdev) && wpa_group_s->p2p_mgmt) {
-		if (p2p_iface_object_map_.find(wpa_group_s->ifname) !=
-		    p2p_iface_object_map_.end())
-			return wpa_group_s;
-	}
-
-	if (p2p_iface_object_map_.find(target_wpa_s->ifname) !=
-	    p2p_iface_object_map_.end())
-		return target_wpa_s;
-
-	// try P2P device if available
-	if (!target_wpa_s->p2pdev || !target_wpa_s->p2pdev->p2p_mgmt)
-		return NULL;
-
-	target_wpa_s = target_wpa_s->p2pdev;
-	if (p2p_iface_object_map_.find(target_wpa_s->ifname) !=
-	    p2p_iface_object_map_.end())
-		return target_wpa_s;
-
-	return NULL;
-}
-
-/**
- * Removes the provided |ISupplicantCallback| hidl object reference
- * from our global callback list.
- *
- * @param callback Hidl reference of the |ISupplicantCallback| object.
- */
-void HidlManager::removeSupplicantCallbackHidlObject(
-    const android::sp<ISupplicantCallback> &callback)
-{
-	supplicant_callbacks_.erase(
-	    std::remove(
-		supplicant_callbacks_.begin(), supplicant_callbacks_.end(),
-		callback),
-	    supplicant_callbacks_.end());
-}
-
-/**
- * Removes the provided iface callback hidl object reference from
- * our interface callback list.
- *
- * @param ifname Name of the corresponding interface.
- * @param callback Hidl reference of the callback object.
- */
-void HidlManager::removeP2pIfaceCallbackHidlObject(
-    const std::string &ifname,
-    const android::sp<ISupplicantP2pIfaceCallback> &callback)
-{
-	return removeIfaceCallbackHidlObjectFromMap(
-	    ifname, callback, p2p_iface_callbacks_map_);
-}
-
-/**
- * Removes the provided iface callback hidl object reference from
- * our interface callback list.
- *
- * @param ifname Name of the corresponding interface.
- * @param callback Hidl reference of the callback object.
- */
-void HidlManager::removeStaIfaceCallbackHidlObject(
-    const std::string &ifname,
-    const android::sp<ISupplicantStaIfaceCallback> &callback)
-{
-	return removeIfaceCallbackHidlObjectFromMap(
-	    ifname, callback, sta_iface_callbacks_map_);
-}
-
-/**
- * Removes the provided network callback hidl object reference from
- * our network callback list.
- *
- * @param ifname Name of the corresponding interface.
- * @param network_id ID of the corresponding network.
- * @param callback Hidl reference of the callback object.
- */
-void HidlManager::removeP2pNetworkCallbackHidlObject(
-    const std::string &ifname, int network_id,
-    const android::sp<ISupplicantP2pNetworkCallback> &callback)
-{
-	return removeNetworkCallbackHidlObjectFromMap(
-	    ifname, network_id, callback, p2p_network_callbacks_map_);
-}
-
-/**
- * Removes the provided network callback hidl object reference from
- * our network callback list.
- *
- * @param ifname Name of the corresponding interface.
- * @param network_id ID of the corresponding network.
- * @param callback Hidl reference of the callback object.
- */
-void HidlManager::removeStaNetworkCallbackHidlObject(
-    const std::string &ifname, int network_id,
-    const android::sp<ISupplicantStaNetworkCallback> &callback)
-{
-	return removeNetworkCallbackHidlObjectFromMap(
-	    ifname, network_id, callback, sta_network_callbacks_map_);
-}
-
-/**
- * Helper function to invoke the provided callback method on all the
- * registered |ISupplicantCallback| callback hidl objects.
- *
- * @param method Pointer to the required hidl method from
- * |ISupplicantCallback|.
- */
-void HidlManager::callWithEachSupplicantCallback(
-    const std::function<Return<void>(android::sp<ISupplicantCallback>)> &method)
-{
-	for (const auto &callback : supplicant_callbacks_) {
-		if (!method(callback).isOk()) {
-			wpa_printf(MSG_ERROR, "Failed to invoke HIDL callback");
-		}
-	}
-}
-
-/**
- * Helper fucntion to invoke the provided callback method on all the
- * registered iface callback hidl objects for the specified
- * |ifname|.
- *
- * @param ifname Name of the corresponding interface.
- * @param method Pointer to the required hidl method from
- * |ISupplicantIfaceCallback|.
- */
-void HidlManager::callWithEachP2pIfaceCallback(
-    const std::string &ifname,
-    const std::function<Return<void>(android::sp<ISupplicantP2pIfaceCallback>)>
-	&method)
-{
-	callWithEachIfaceCallback(ifname, method, p2p_iface_callbacks_map_);
-}
-
-/**
- * Helper function to invoke the provided callback method on all the
- * registered derived interface callback hidl objects for the specified
- * |ifname|.
- *
- * @param ifname Name of the corresponding interface.
- * @param method Pointer to the required hidl method from
- * derived |V1_x::ISupplicantIfaceCallback|.
- */
-template <class CallbackTypeDerived>
-void HidlManager::callWithEachP2pIfaceCallbackDerived(
-    const std::string &ifname,
-    const std::function<
-	Return<void>(android::sp<CallbackTypeDerived>)> &method)
-{
-	callWithEachIfaceCallbackDerived(ifname, method, p2p_iface_callbacks_map_);
-}
-
-/**
- * Helper function to invoke the provided callback method on all the
- * registered V1.1 interface callback hidl objects for the specified
- * |ifname|.
- *
- * @param ifname Name of the corresponding interface.
- * @param method Pointer to the required hidl method from
- * |V1_1::ISupplicantIfaceCallback|.
- */
-void HidlManager::callWithEachStaIfaceCallback_1_1(
-    const std::string &ifname,
-    const std::function<
-	Return<void>(android::sp<V1_1::ISupplicantStaIfaceCallback>)> &method)
-{
-	callWithEachIfaceCallbackDerived(ifname, method, sta_iface_callbacks_map_);
-}
-
-/**
- * Helper function to invoke the provided callback method on all the
- * registered V1.2 interface callback hidl objects for the specified
- * |ifname|.
- *
- * @param ifname Name of the corresponding interface.
- * @param method Pointer to the required hidl method from
- * |V1_2::ISupplicantIfaceCallback|.
- */
-void HidlManager::callWithEachStaIfaceCallback_1_2(
-    const std::string &ifname,
-    const std::function<
-	Return<void>(android::sp<V1_2::ISupplicantStaIfaceCallback>)> &method)
-{
-	callWithEachIfaceCallbackDerived(ifname, method, sta_iface_callbacks_map_);
-}
-
-/**
- * Helper function to invoke the provided callback method on all the
- * registered V1.3 interface callback hidl objects for the specified
- * |ifname|.
- *
- * @param ifname Name of the corresponding interface.
- * @param method Pointer to the required hidl method from
- * |V1_3::ISupplicantIfaceCallback|.
- */
-void HidlManager::callWithEachStaIfaceCallback_1_3(
-    const std::string &ifname,
-    const std::function<
-	Return<void>(android::sp<V1_3::ISupplicantStaIfaceCallback>)> &method)
-{
-	callWithEachIfaceCallbackDerived(ifname, method, sta_iface_callbacks_map_);
-}
-
-/**
- * Helper function to invoke the provided callback method on all the
- * registered V1.4 interface callback hidl objects for the specified
- * |ifname|.
- *
- * @param ifname Name of the corresponding interface.
- * @param method Pointer to the required hidl method from
- * |V1_4::ISupplicantIfaceCallback|.
- */
-void HidlManager::callWithEachStaIfaceCallback_1_4(
-    const std::string &ifname,
-    const std::function<
-	Return<void>(android::sp<V1_4::ISupplicantStaIfaceCallback>)> &method)
-{
-	callWithEachIfaceCallbackDerived(ifname, method, sta_iface_callbacks_map_);
-}
-
-/**
- * Helper function to invoke the provided callback method on all the
- * registered derived interface callback hidl objects for the specified
- * |ifname|.
- *
- * @param ifname Name of the corresponding interface.
- * @param method Pointer to the required hidl method from
- * derived |V1_x::ISupplicantIfaceCallback|.
- */
-template <class CallbackTypeDerived>
-void HidlManager::callWithEachStaIfaceCallbackDerived(
-    const std::string &ifname,
-    const std::function<
-	Return<void>(android::sp<CallbackTypeDerived>)> &method)
-{
-	callWithEachIfaceCallbackDerived(ifname, method, sta_iface_callbacks_map_);
-}
-
-/**
- * Helper function to invoke the provided callback method on all the
- * registered interface callback hidl objects for the specified
- * |ifname|.
- *
- * @param ifname Name of the corresponding interface.
- * @param method Pointer to the required hidl method from
- * |ISupplicantIfaceCallback|.
- */
-void HidlManager::callWithEachStaIfaceCallback(
-    const std::string &ifname,
-    const std::function<Return<void>(android::sp<ISupplicantStaIfaceCallback>)>
-	&method)
-{
-	callWithEachIfaceCallback(ifname, method, sta_iface_callbacks_map_);
-}
-
-/**
- * Helper function to invoke the provided callback method on all the
- * registered network callback hidl objects for the specified
- * |ifname| & |network_id|.
- *
- * @param ifname Name of the corresponding interface.
- * @param network_id ID of the corresponding network.
- * @param method Pointer to the required hidl method from
- * |ISupplicantP2pNetworkCallback| or |ISupplicantStaNetworkCallback| .
- */
-void HidlManager::callWithEachP2pNetworkCallback(
-    const std::string &ifname, int network_id,
-    const std::function<
-	Return<void>(android::sp<ISupplicantP2pNetworkCallback>)> &method)
-{
-	callWithEachNetworkCallback(
-	    ifname, network_id, method, p2p_network_callbacks_map_);
-}
-
-/**
- * Helper function to invoke the provided callback method on all the
- * registered network callback hidl objects for the specified
- * |ifname| & |network_id|.
- *
- * @param ifname Name of the corresponding interface.
- * @param network_id ID of the corresponding network.
- * @param method Pointer to the required hidl method from
- * |ISupplicantP2pNetworkCallback| or |ISupplicantStaNetworkCallback| .
- */
-void HidlManager::callWithEachStaNetworkCallback(
-    const std::string &ifname, int network_id,
-    const std::function<
-	Return<void>(android::sp<ISupplicantStaNetworkCallback>)> &method)
-{
-	callWithEachNetworkCallback(
-	    ifname, network_id, method, sta_network_callbacks_map_);
-}
-
-/**
- * Helper function to invoke the provided callback method on all the
- * registered derived interface callback hidl objects for the specified
- * |ifname|.
- *
- * @param ifname Name of the corresponding interface.
- * @param method Pointer to the required hidl method from
- * derived |V1_x::ISupplicantIfaceCallback|.
- */
-template <class CallbackTypeDerived>
-void HidlManager::callWithEachStaNetworkCallbackDerived(
-    const std::string &ifname, int network_id,
-    const std::function<
-	Return<void>(android::sp<CallbackTypeDerived>)> &method)
-{
-	callWithEachNetworkCallbackDerived(ifname, network_id, method, sta_network_callbacks_map_);
-}
-}  // namespace implementation
-}  // namespace V1_4
-}  // namespace supplicant
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wpa_supplicant/hidl/1.4/hidl_manager.h b/wpa_supplicant/hidl/1.4/hidl_manager.h
deleted file mode 100644
index ccde11c..0000000
--- a/wpa_supplicant/hidl/1.4/hidl_manager.h
+++ /dev/null
@@ -1,783 +0,0 @@
-/*
- * hidl interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WPA_SUPPLICANT_HIDL_HIDL_MANAGER_H
-#define WPA_SUPPLICANT_HIDL_HIDL_MANAGER_H
-
-#include <map>
-#include <string>
-
-#include <android/hardware/wifi/supplicant/1.0/ISupplicantCallback.h>
-#include <android/hardware/wifi/supplicant/1.0/ISupplicantP2pIfaceCallback.h>
-#include <android/hardware/wifi/supplicant/1.0/ISupplicantP2pNetworkCallback.h>
-#include <android/hardware/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.h>
-#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaNetworkCallback.h>
-#include <android/hardware/wifi/supplicant/1.4/ISupplicantStaNetworkCallback.h>
-
-#include "p2p_iface.h"
-#include "p2p_network.h"
-#include "rsn_supp/pmksa_cache.h"
-#include "sta_iface.h"
-#include "sta_network.h"
-#include "supplicant.h"
-
-extern "C"
-{
-#include "utils/common.h"
-#include "utils/includes.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-}
-
-class DeathNotifier : public android::hardware::hidl_death_recipient
-{
-public:
-	DeathNotifier(struct wpa_global *wpa_global)
-	    : wpa_global_(wpa_global)
-	{}
-
-	void serviceDied(
-	    uint64_t /*cookie*/,
-	    const android::wp<android::hidl::base::V1_0::IBase>
-		& /* who */) override
-	{
-		wpa_printf(MSG_ERROR, "Client died. Terminating...");
-		wpa_supplicant_terminate_proc(wpa_global_);
-	}
-
-private:
-	struct wpa_global *wpa_global_;
-};
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_4 {
-namespace implementation {
-using V1_0::ISupplicant;
-using V1_0::ISupplicantP2pIface;
-using V1_0::ISupplicantStaIface;
-using V1_0::ISupplicantStaIfaceCallback;
-using V1_0::P2pGroupCapabilityMask;
-using V1_0::WpsConfigMethods;
-
-/**
- * HidlManager is responsible for managing the lifetime of all
- * hidl objects created by wpa_supplicant. This is a singleton
- * class which is created by the supplicant core and can be used
- * to get references to the hidl objects.
- */
-class HidlManager
-{
-public:
-	static HidlManager *getInstance();
-	static void destroyInstance();
-
-	// Methods called from wpa_supplicant core.
-	int registerHidlService(struct wpa_global *global);
-	int registerInterface(struct wpa_supplicant *wpa_s);
-	int unregisterInterface(struct wpa_supplicant *wpa_s);
-	int registerNetwork(
-	    struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
-	int unregisterNetwork(
-	    struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid);
-	int notifyStateChange(struct wpa_supplicant *wpa_s);
-	int notifyNetworkRequest(
-	    struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid, int type,
-	    const char *param);
-	void notifyAnqpQueryDone(
-	    struct wpa_supplicant *wpa_s, const u8 *bssid, const char *result,
-	    const struct wpa_bss_anqp *anqp);
-	void notifyHs20IconQueryDone(
-	    struct wpa_supplicant *wpa_s, const u8 *bssid,
-	    const char *file_name, const u8 *image, u32 image_length);
-	void notifyHs20RxSubscriptionRemediation(
-	    struct wpa_supplicant *wpa_s, const char *url, u8 osu_method);
-	void notifyHs20RxDeauthImminentNotice(
-	    struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay,
-		const char *url);
-	void notifyHs20RxTermsAndConditionsAcceptance(
-			struct wpa_supplicant *wpa_s, const char *url);
-	void notifyDisconnectReason(struct wpa_supplicant *wpa_s);
-	void notifyAssocReject(struct wpa_supplicant *wpa_s, const u8 *bssid,
-	    u8 timed_out, const u8 *assoc_resp_ie, size_t assoc_resp_ie_len);
-	void notifyAuthTimeout(struct wpa_supplicant *wpa_s);
-	void notifyBssidChanged(struct wpa_supplicant *wpa_s);
-	void notifyWpsEventFail(
-	    struct wpa_supplicant *wpa_s, uint8_t *peer_macaddr,
-	    uint16_t config_error, uint16_t error_indication);
-	void notifyWpsEventSuccess(struct wpa_supplicant *wpa_s);
-	void notifyWpsEventPbcOverlap(struct wpa_supplicant *wpa_s);
-	void notifyP2pDeviceFound(
-	    struct wpa_supplicant *wpa_s, const u8 *addr,
-	    const struct p2p_peer_info *info, const u8 *peer_wfd_device_info,
-	    u8 peer_wfd_device_info_len, const u8 *peer_wfd_r2_device_info,
-	    u8 peer_wfd_r2_device_info_len);
-	void notifyP2pDeviceLost(
-	    struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr);
-	void notifyP2pFindStopped(struct wpa_supplicant *wpa_s);
-	void notifyP2pGoNegReq(
-	    struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
-	    u8 go_intent);
-	void notifyP2pGoNegCompleted(
-	    struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res);
-	void notifyP2pGroupFormationFailure(
-	    struct wpa_supplicant *wpa_s, const char *reason);
-	void notifyP2pGroupStarted(
-	    struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
-	    int persistent, int client);
-	void notifyP2pGroupRemoved(
-	    struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
-	    const char *role);
-	void notifyP2pInvitationReceived(
-	    struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
-	    const u8 *bssid, int id, int op_freq);
-	void notifyP2pInvitationResult(
-	    struct wpa_supplicant *wpa_s, int status, const u8 *bssid);
-	void notifyP2pProvisionDiscovery(
-	    struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
-	    enum p2p_prov_disc_status status, u16 config_methods,
-	    unsigned int generated_pin);
-	void notifyP2pSdResponse(
-	    struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
-	    const u8 *tlvs, size_t tlvs_len);
-	void notifyApStaAuthorized(
-	    struct wpa_supplicant *wpa_s, const u8 *sta,
-	    const u8 *p2p_dev_addr);
-	void notifyApStaDeauthorized(
-	    struct wpa_supplicant *wpa_s, const u8 *sta,
-	    const u8 *p2p_dev_addr);
-	void notifyEapError(struct wpa_supplicant *wpa_s, int error_code);
-	void notifyDppConfigReceived(struct wpa_supplicant *wpa_s,
-			struct wpa_ssid *config);
-	void notifyDppConfigSent(struct wpa_supplicant *wpa_s);
-	void notifyDppSuccess(struct wpa_supplicant *wpa_s, V1_3::DppSuccessCode code);
-	void notifyDppFailure(struct wpa_supplicant *wpa_s,
-			android::hardware::wifi::supplicant::V1_3::DppFailureCode code);
-	void notifyDppFailure(struct wpa_supplicant *wpa_s,
-			android::hardware::wifi::supplicant::V1_3::DppFailureCode code,
-			const char *ssid, const char *channel_list, unsigned short band_list[],
-			int size);
-	void notifyDppProgress(struct wpa_supplicant *wpa_s,
-			android::hardware::wifi::supplicant::V1_3::DppProgressCode code);
-	void notifyPmkCacheAdded(struct wpa_supplicant *wpa_s,
-			struct rsn_pmksa_cache_entry *pmksa_entry);
-	void notifyBssTmStatus(struct wpa_supplicant *wpa_s);
-	void notifyTransitionDisable(struct wpa_supplicant *wpa_s,
-			struct wpa_ssid *ssid,
-			u8 bitmap);
-	void notifyNetworkNotFound(struct wpa_supplicant *wpa_s);
-
-	// Methods called from hidl objects.
-	void notifyExtRadioWorkStart(struct wpa_supplicant *wpa_s, uint32_t id);
-	void notifyExtRadioWorkTimeout(
-	    struct wpa_supplicant *wpa_s, uint32_t id);
-
-	int getP2pIfaceHidlObjectByIfname(
-	    const std::string &ifname,
-	    android::sp<ISupplicantP2pIface> *iface_object);
-	int getStaIfaceHidlObjectByIfname(
-	    const std::string &ifname,
-	    android::sp<V1_1::ISupplicantStaIface> *iface_object);
-	int getP2pNetworkHidlObjectByIfnameAndNetworkId(
-	    const std::string &ifname, int network_id,
-	    android::sp<ISupplicantP2pNetwork> *network_object);
-	int getStaNetworkHidlObjectByIfnameAndNetworkId(
-	    const std::string &ifname, int network_id,
-	    android::sp<V1_3::ISupplicantStaNetwork> *network_object);
-	int addSupplicantCallbackHidlObject(
-	    const android::sp<ISupplicantCallback> &callback);
-	int addP2pIfaceCallbackHidlObject(
-	    const std::string &ifname,
-	    const android::sp<ISupplicantP2pIfaceCallback> &callback);
-	int addStaIfaceCallbackHidlObject(
-	    const std::string &ifname,
-	    const android::sp<ISupplicantStaIfaceCallback> &callback);
-	int addP2pNetworkCallbackHidlObject(
-	    const std::string &ifname, int network_id,
-	    const android::sp<ISupplicantP2pNetworkCallback> &callback);
-	int addStaNetworkCallbackHidlObject(
-	    const std::string &ifname, int network_id,
-	    const android::sp<ISupplicantStaNetworkCallback> &callback);
-
-private:
-	HidlManager() = default;
-	~HidlManager() = default;
-	HidlManager(const HidlManager &) = default;
-	HidlManager &operator=(const HidlManager &) = default;
-
-	struct wpa_supplicant *getTargetP2pIfaceForGroup(
-	    struct wpa_supplicant *wpa_s);
-	void removeSupplicantCallbackHidlObject(
-	    const android::sp<ISupplicantCallback> &callback);
-	void removeP2pIfaceCallbackHidlObject(
-	    const std::string &ifname,
-	    const android::sp<ISupplicantP2pIfaceCallback> &callback);
-	void removeStaIfaceCallbackHidlObject(
-	    const std::string &ifname,
-	    const android::sp<ISupplicantStaIfaceCallback> &callback);
-	void removeP2pNetworkCallbackHidlObject(
-	    const std::string &ifname, int network_id,
-	    const android::sp<ISupplicantP2pNetworkCallback> &callback);
-	void removeStaNetworkCallbackHidlObject(
-	    const std::string &ifname, int network_id,
-	    const android::sp<ISupplicantStaNetworkCallback> &callback);
-
-	void callWithEachSupplicantCallback(
-	    const std::function<android::hardware::Return<void>(
-		android::sp<ISupplicantCallback>)> &method);
-	void callWithEachP2pIfaceCallback(
-	    const std::string &ifname,
-	    const std::function<android::hardware::Return<void>(
-		android::sp<ISupplicantP2pIfaceCallback>)> &method);
-	template <class CallbackTypeDerived>
-	void callWithEachP2pIfaceCallbackDerived(
-	    const std::string &ifname,
-	    const std::function<
-		Return<void>(android::sp<CallbackTypeDerived>)> &method);
-	void callWithEachStaIfaceCallback(
-	    const std::string &ifname,
-	    const std::function<android::hardware::Return<void>(
-		android::sp<ISupplicantStaIfaceCallback>)> &method);
-	void callWithEachStaIfaceCallback_1_1(
-	    const std::string &ifname,
-	    const std::function<android::hardware::Return<void>(
-		android::sp<V1_1::ISupplicantStaIfaceCallback>)> &method);
-	void callWithEachStaIfaceCallback_1_2(
-	    const std::string &ifname,
-	    const std::function<android::hardware::Return<void>(
-	    android::sp<V1_2::ISupplicantStaIfaceCallback>)> &method);
-	void callWithEachStaIfaceCallback_1_3(
-	    const std::string &ifname,
-	    const std::function<android::hardware::Return<void>(
-	    android::sp<V1_3::ISupplicantStaIfaceCallback>)> &method);
-	void callWithEachStaIfaceCallback_1_4(
-	    const std::string &ifname,
-	    const std::function<android::hardware::Return<void>(
-	    android::sp<V1_4::ISupplicantStaIfaceCallback>)> &method);
-	template <class CallbackTypeDerived>
-	void callWithEachStaIfaceCallbackDerived(
-	    const std::string &ifname,
-	    const std::function<
-		Return<void>(android::sp<CallbackTypeDerived>)> &method);
-	void callWithEachP2pNetworkCallback(
-	    const std::string &ifname, int network_id,
-	    const std::function<android::hardware::Return<void>(
-		android::sp<ISupplicantP2pNetworkCallback>)> &method);
-	void callWithEachStaNetworkCallback(
-	    const std::string &ifname, int network_id,
-	    const std::function<android::hardware::Return<void>(
-		android::sp<ISupplicantStaNetworkCallback>)> &method);
-	template <class CallbackTypeDerived>
-	void callWithEachStaNetworkCallbackDerived(
-	    const std::string &ifname, int network_id,
-	    const std::function<
-		Return<void>(android::sp<CallbackTypeDerived>)> &method);
-
-	// Singleton instance of this class.
-	static HidlManager *instance_;
-	// Raw pointer to the global structure maintained by the core.
-	struct wpa_global *wpa_global_;
-	// Death notifier.
-	android::sp<DeathNotifier> death_notifier_;
-	// The main hidl service object.
-	android::sp<Supplicant> supplicant_object_;
-	// Map of all the P2P interface specific hidl objects controlled by
-	// wpa_supplicant. This map is keyed in by the corresponding
-	// |ifname|.
-	std::map<const std::string, android::sp<P2pIface>>
-	    p2p_iface_object_map_;
-	// Map of all the STA interface specific hidl objects controlled by
-	// wpa_supplicant. This map is keyed in by the corresponding
-	// |ifname|.
-	std::map<const std::string, android::sp<StaIface>>
-	    sta_iface_object_map_;
-	// Map of all the P2P network specific hidl objects controlled by
-	// wpa_supplicant. This map is keyed in by the corresponding
-	// |ifname| & |network_id|.
-	std::map<const std::string, android::sp<P2pNetwork>>
-	    p2p_network_object_map_;
-	// Map of all the STA network specific hidl objects controlled by
-	// wpa_supplicant. This map is keyed in by the corresponding
-	// |ifname| & |network_id|.
-	std::map<const std::string, android::sp<StaNetwork>>
-	    sta_network_object_map_;
-
-	// Callback registered for the main hidl service object.
-	std::vector<android::sp<ISupplicantCallback>> supplicant_callbacks_;
-	// Map of all the callbacks registered for P2P interface specific
-	// hidl objects controlled by wpa_supplicant.  This map is keyed in by
-	// the corresponding |ifname|.
-	std::map<
-	    const std::string,
-	    std::vector<android::sp<ISupplicantP2pIfaceCallback>>>
-	    p2p_iface_callbacks_map_;
-	// Map of all the callbacks registered for STA interface specific
-	// hidl objects controlled by wpa_supplicant.  This map is keyed in by
-	// the corresponding |ifname|.
-	std::map<
-	    const std::string,
-	    std::vector<android::sp<ISupplicantStaIfaceCallback>>>
-	    sta_iface_callbacks_map_;
-	// Map of all the callbacks registered for P2P network specific
-	// hidl objects controlled by wpa_supplicant.  This map is keyed in by
-	// the corresponding |ifname| & |network_id|.
-	std::map<
-	    const std::string,
-	    std::vector<android::sp<ISupplicantP2pNetworkCallback>>>
-	    p2p_network_callbacks_map_;
-	// Map of all the callbacks registered for STA network specific
-	// hidl objects controlled by wpa_supplicant.  This map is keyed in by
-	// the corresponding |ifname| & |network_id|.
-	std::map<
-	    const std::string,
-	    std::vector<android::sp<ISupplicantStaNetworkCallback>>>
-	    sta_network_callbacks_map_;
-};
-
-// The hidl interface uses some values which are the same as internal ones to
-// avoid nasty runtime conversion functions. So, adding compile time asserts
-// to guard against any internal changes breaking the hidl interface.
-static_assert(
-    static_cast<uint32_t>(ISupplicant::DebugLevel::EXCESSIVE) == MSG_EXCESSIVE,
-    "Debug level value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicant::DebugLevel::ERROR) == MSG_ERROR,
-    "Debug level value mismatch");
-
-static_assert(
-    static_cast<uint32_t>(V1_0::ISupplicantStaNetwork::KeyMgmtMask::NONE) ==
-	WPA_KEY_MGMT_NONE,
-    "KeyMgmt value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_0::ISupplicantStaNetwork::KeyMgmtMask::WPA_PSK) ==
-	WPA_KEY_MGMT_PSK,
-    "KeyMgmt value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_0::ISupplicantStaNetwork::KeyMgmtMask::WPA_EAP) ==
-	WPA_KEY_MGMT_IEEE8021X,
-    "KeyMgmt value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_0::ISupplicantStaNetwork::KeyMgmtMask::IEEE8021X) ==
-	WPA_KEY_MGMT_IEEE8021X_NO_WPA,
-    "KeyMgmt value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_0::ISupplicantStaNetwork::KeyMgmtMask::FT_EAP) ==
-	WPA_KEY_MGMT_FT_IEEE8021X,
-    "KeyMgmt value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_0::ISupplicantStaNetwork::KeyMgmtMask::FT_PSK) ==
-	WPA_KEY_MGMT_FT_PSK,
-    "KeyMgmt value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_0::ISupplicantStaNetwork::KeyMgmtMask::OSEN) ==
-	WPA_KEY_MGMT_OSEN,
-    "KeyMgmt value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_2::ISupplicantStaNetwork::KeyMgmtMask::SAE) ==
-	WPA_KEY_MGMT_SAE,
-    "KeyMgmt value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_2::ISupplicantStaNetwork::KeyMgmtMask::SUITE_B_192) ==
-	WPA_KEY_MGMT_IEEE8021X_SUITE_B_192,
-    "KeyMgmt value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_2::ISupplicantStaNetwork::KeyMgmtMask::OWE) ==
-	WPA_KEY_MGMT_OWE,
-    "KeyMgmt value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_2::ISupplicantStaNetwork::KeyMgmtMask::WPA_PSK_SHA256) ==
-	WPA_KEY_MGMT_PSK_SHA256,
-    "KeyMgmt value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_2::ISupplicantStaNetwork::KeyMgmtMask::WPA_EAP_SHA256) ==
-	WPA_KEY_MGMT_IEEE8021X_SHA256,
-    "KeyMgmt value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_3::ISupplicantStaNetwork::KeyMgmtMask::WAPI_PSK) ==
-	WPA_KEY_MGMT_WAPI_PSK,
-    "KeyMgmt value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_3::ISupplicantStaNetwork::KeyMgmtMask::WAPI_CERT) ==
-	WPA_KEY_MGMT_WAPI_CERT,
-    "KeyMgmt value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_0::ISupplicantStaNetwork::ProtoMask::WPA) ==
-	WPA_PROTO_WPA,
-    "Proto value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_0::ISupplicantStaNetwork::ProtoMask::RSN) ==
-	WPA_PROTO_RSN,
-    "Proto value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_0::ISupplicantStaNetwork::ProtoMask::OSEN) ==
-	WPA_PROTO_OSEN,
-    "Proto value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_3::ISupplicantStaNetwork::ProtoMask::WAPI) ==
-	WPA_PROTO_WAPI,
-    "Proto value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_0::ISupplicantStaNetwork::AuthAlgMask::OPEN) ==
-	WPA_AUTH_ALG_OPEN,
-    "AuthAlg value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_0::ISupplicantStaNetwork::AuthAlgMask::SHARED) ==
-	WPA_AUTH_ALG_SHARED,
-    "AuthAlg value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_0::ISupplicantStaNetwork::AuthAlgMask::LEAP) ==
-	WPA_AUTH_ALG_LEAP,
-    "AuthAlg value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_0::ISupplicantStaNetwork::GroupCipherMask::WEP40) ==
-	WPA_CIPHER_WEP40,
-    "GroupCipher value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_0::ISupplicantStaNetwork::GroupCipherMask::WEP104) ==
-	WPA_CIPHER_WEP104,
-    "GroupCipher value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_0::ISupplicantStaNetwork::GroupCipherMask::TKIP) ==
-	WPA_CIPHER_TKIP,
-    "GroupCipher value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_0::ISupplicantStaNetwork::GroupCipherMask::CCMP) ==
-	WPA_CIPHER_CCMP,
-    "GroupCipher value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_2::ISupplicantStaNetwork::GroupCipherMask::GCMP_256) ==
-	WPA_CIPHER_GCMP_256,
-    "GroupCipher value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_3::ISupplicantStaNetwork::GroupCipherMask::SMS4) ==
-	WPA_CIPHER_SMS4,
-    "GroupCipher value mismatch");
-static_assert(
-    static_cast<uint32_t>(
-	V1_0::ISupplicantStaNetwork::GroupCipherMask::GTK_NOT_USED) ==
-	WPA_CIPHER_GTK_NOT_USED,
-    "GroupCipher value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_0::ISupplicantStaNetwork::PairwiseCipherMask::NONE) ==
-	WPA_CIPHER_NONE,
-    "PairwiseCipher value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_0::ISupplicantStaNetwork::PairwiseCipherMask::TKIP) ==
-	WPA_CIPHER_TKIP,
-    "PairwiseCipher value mismatch");
-static_assert(
-    static_cast<uint32_t>(V1_0::ISupplicantStaNetwork::PairwiseCipherMask::CCMP) ==
-	WPA_CIPHER_CCMP,
-    "PairwiseCipher value mismatch");
-static_assert(
-    static_cast<uint32_t>(
-	V1_2::ISupplicantStaNetwork::PairwiseCipherMask::GCMP_256) ==
-	WPA_CIPHER_GCMP_256,
-    "PairwiseCipher value mismatch");
-static_assert(
-    static_cast<uint32_t>(
-	V1_3::ISupplicantStaNetwork::PairwiseCipherMask::SMS4) ==
-	WPA_CIPHER_SMS4,
-    "PairwiseCipher value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaIfaceCallback::State::DISCONNECTED) ==
-	WPA_DISCONNECTED,
-    "State value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaIfaceCallback::State::COMPLETED) ==
-	WPA_COMPLETED,
-    "State value mismatch");
-
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaIface::AnqpInfoId::VENUE_NAME) ==
-	ANQP_VENUE_NAME,
-    "ANQP ID value mismatch");
-static_assert(
-    static_cast<uint32_t>(
-	ISupplicantStaIface::AnqpInfoId::ROAMING_CONSORTIUM) ==
-	ANQP_ROAMING_CONSORTIUM,
-    "ANQP ID value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaIface::AnqpInfoId::NAI_REALM) ==
-	ANQP_NAI_REALM,
-    "ANQP ID value mismatch");
-static_assert(
-    static_cast<uint32_t>(
-	ISupplicantStaIface::AnqpInfoId::IP_ADDR_TYPE_AVAILABILITY) ==
-	ANQP_IP_ADDR_TYPE_AVAILABILITY,
-    "ANQP ID value mismatch");
-static_assert(
-    static_cast<uint32_t>(
-	ISupplicantStaIface::AnqpInfoId::ANQP_3GPP_CELLULAR_NETWORK) ==
-	ANQP_3GPP_CELLULAR_NETWORK,
-    "ANQP ID value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaIface::AnqpInfoId::DOMAIN_NAME) ==
-	ANQP_DOMAIN_NAME,
-    "ANQP ID value mismatch");
-static_assert(
-    static_cast<uint32_t>(
-	ISupplicantStaIface::Hs20AnqpSubtypes::OPERATOR_FRIENDLY_NAME) ==
-	HS20_STYPE_OPERATOR_FRIENDLY_NAME,
-    "HS Subtype value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaIface::Hs20AnqpSubtypes::WAN_METRICS) ==
-	HS20_STYPE_WAN_METRICS,
-    "HS Subtype value mismatch");
-static_assert(
-    static_cast<uint32_t>(
-	ISupplicantStaIface::Hs20AnqpSubtypes::CONNECTION_CAPABILITY) ==
-	HS20_STYPE_CONNECTION_CAPABILITY,
-    "HS Subtype value mismatch");
-static_assert(
-    static_cast<uint32_t>(
-	ISupplicantStaIface::Hs20AnqpSubtypes::OSU_PROVIDERS_LIST) ==
-	HS20_STYPE_OSU_PROVIDERS_LIST,
-    "HS Subtype value mismatch");
-
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantStaIfaceCallback::WpsConfigError::NO_ERROR) ==
-	WPS_CFG_NO_ERROR,
-    "Wps config error value mismatch");
-static_assert(
-    static_cast<uint16_t>(ISupplicantStaIfaceCallback::WpsConfigError::
-			      PUBLIC_KEY_HASH_MISMATCH) ==
-	WPS_CFG_PUBLIC_KEY_HASH_MISMATCH,
-    "Wps config error value mismatch");
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantStaIfaceCallback::WpsErrorIndication::NO_ERROR) ==
-	WPS_EI_NO_ERROR,
-    "Wps error indication value mismatch");
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantStaIfaceCallback::WpsErrorIndication::AUTH_FAILURE) ==
-	WPS_EI_AUTH_FAILURE,
-    "Wps error indication value mismatch");
-
-static_assert(
-    static_cast<uint32_t>(WpsConfigMethods::USBA) == WPS_CONFIG_USBA,
-    "Wps config value mismatch");
-static_assert(
-    static_cast<uint32_t>(WpsConfigMethods::ETHERNET) == WPS_CONFIG_ETHERNET,
-    "Wps config value mismatch");
-static_assert(
-    static_cast<uint32_t>(WpsConfigMethods::LABEL) == WPS_CONFIG_LABEL,
-    "Wps config value mismatch");
-static_assert(
-    static_cast<uint32_t>(WpsConfigMethods::DISPLAY) == WPS_CONFIG_DISPLAY,
-    "Wps config value mismatch");
-static_assert(
-    static_cast<uint32_t>(WpsConfigMethods::INT_NFC_TOKEN) ==
-	WPS_CONFIG_INT_NFC_TOKEN,
-    "Wps config value mismatch");
-static_assert(
-    static_cast<uint32_t>(WpsConfigMethods::EXT_NFC_TOKEN) ==
-	WPS_CONFIG_EXT_NFC_TOKEN,
-    "Wps config value mismatch");
-static_assert(
-    static_cast<uint32_t>(WpsConfigMethods::NFC_INTERFACE) ==
-	WPS_CONFIG_NFC_INTERFACE,
-    "Wps config value mismatch");
-static_assert(
-    static_cast<uint32_t>(WpsConfigMethods::PUSHBUTTON) ==
-	WPS_CONFIG_PUSHBUTTON,
-    "Wps config value mismatch");
-static_assert(
-    static_cast<uint32_t>(WpsConfigMethods::KEYPAD) == WPS_CONFIG_KEYPAD,
-    "Wps config value mismatch");
-static_assert(
-    static_cast<uint32_t>(WpsConfigMethods::VIRT_PUSHBUTTON) ==
-	WPS_CONFIG_VIRT_PUSHBUTTON,
-    "Wps config value mismatch");
-static_assert(
-    static_cast<uint32_t>(WpsConfigMethods::PHY_PUSHBUTTON) ==
-	WPS_CONFIG_PHY_PUSHBUTTON,
-    "Wps config value mismatch");
-static_assert(
-    static_cast<uint32_t>(WpsConfigMethods::P2PS) == WPS_CONFIG_P2PS,
-    "Wps config value mismatch");
-static_assert(
-    static_cast<uint32_t>(WpsConfigMethods::VIRT_DISPLAY) ==
-	WPS_CONFIG_VIRT_DISPLAY,
-    "Wps config value mismatch");
-static_assert(
-    static_cast<uint32_t>(WpsConfigMethods::PHY_DISPLAY) ==
-	WPS_CONFIG_PHY_DISPLAY,
-    "Wps config value mismatch");
-
-static_assert(
-    static_cast<uint32_t>(P2pGroupCapabilityMask::GROUP_OWNER) ==
-	P2P_GROUP_CAPAB_GROUP_OWNER,
-    "P2P capability value mismatch");
-static_assert(
-    static_cast<uint32_t>(P2pGroupCapabilityMask::PERSISTENT_GROUP) ==
-	P2P_GROUP_CAPAB_PERSISTENT_GROUP,
-    "P2P capability value mismatch");
-static_assert(
-    static_cast<uint32_t>(P2pGroupCapabilityMask::GROUP_LIMIT) ==
-	P2P_GROUP_CAPAB_GROUP_LIMIT,
-    "P2P capability value mismatch");
-static_assert(
-    static_cast<uint32_t>(P2pGroupCapabilityMask::INTRA_BSS_DIST) ==
-	P2P_GROUP_CAPAB_INTRA_BSS_DIST,
-    "P2P capability value mismatch");
-static_assert(
-    static_cast<uint32_t>(P2pGroupCapabilityMask::CROSS_CONN) ==
-	P2P_GROUP_CAPAB_CROSS_CONN,
-    "P2P capability value mismatch");
-static_assert(
-    static_cast<uint32_t>(P2pGroupCapabilityMask::PERSISTENT_RECONN) ==
-	P2P_GROUP_CAPAB_PERSISTENT_RECONN,
-    "P2P capability value mismatch");
-static_assert(
-    static_cast<uint32_t>(P2pGroupCapabilityMask::GROUP_FORMATION) ==
-	P2P_GROUP_CAPAB_GROUP_FORMATION,
-    "P2P capability value mismatch");
-
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::WpsDevPasswordId::DEFAULT) ==
-	DEV_PW_DEFAULT,
-    "Wps dev password id value mismatch");
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::WpsDevPasswordId::USER_SPECIFIED) ==
-	DEV_PW_USER_SPECIFIED,
-    "Wps dev password id value mismatch");
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::WpsDevPasswordId::MACHINE_SPECIFIED) ==
-	DEV_PW_MACHINE_SPECIFIED,
-    "Wps dev password id value mismatch");
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::WpsDevPasswordId::REKEY) == DEV_PW_REKEY,
-    "Wps dev password id value mismatch");
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::WpsDevPasswordId::PUSHBUTTON) ==
-	DEV_PW_PUSHBUTTON,
-    "Wps dev password id value mismatch");
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::WpsDevPasswordId::REGISTRAR_SPECIFIED) ==
-	DEV_PW_REGISTRAR_SPECIFIED,
-    "Wps dev password id value mismatch");
-static_assert(
-    static_cast<uint16_t>(ISupplicantP2pIfaceCallback::WpsDevPasswordId::
-			      NFC_CONNECTION_HANDOVER) ==
-	DEV_PW_NFC_CONNECTION_HANDOVER,
-    "Wps dev password id value mismatch");
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::WpsDevPasswordId::P2PS_DEFAULT) ==
-	DEV_PW_P2PS_DEFAULT,
-    "Wps dev password id value mismatch");
-
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::P2pStatusCode::SUCCESS) == P2P_SC_SUCCESS,
-    "P2P status code value mismatch");
-static_assert(
-    static_cast<uint16_t>(ISupplicantP2pIfaceCallback::P2pStatusCode::
-			      FAIL_INFO_CURRENTLY_UNAVAILABLE) ==
-	P2P_SC_FAIL_INFO_CURRENTLY_UNAVAILABLE,
-    "P2P status code value mismatch");
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::P2pStatusCode::FAIL_INCOMPATIBLE_PARAMS) ==
-	P2P_SC_FAIL_INCOMPATIBLE_PARAMS,
-    "P2P status code value mismatch");
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::P2pStatusCode::FAIL_LIMIT_REACHED) ==
-	P2P_SC_FAIL_LIMIT_REACHED,
-    "P2P status code value mismatch");
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::P2pStatusCode::FAIL_INVALID_PARAMS) ==
-	P2P_SC_FAIL_INVALID_PARAMS,
-    "P2P status code value mismatch");
-static_assert(
-    static_cast<uint16_t>(ISupplicantP2pIfaceCallback::P2pStatusCode::
-			      FAIL_UNABLE_TO_ACCOMMODATE) ==
-	P2P_SC_FAIL_UNABLE_TO_ACCOMMODATE,
-    "P2P status code value mismatch");
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::P2pStatusCode::FAIL_PREV_PROTOCOL_ERROR) ==
-	P2P_SC_FAIL_PREV_PROTOCOL_ERROR,
-    "P2P status code value mismatch");
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::P2pStatusCode::FAIL_NO_COMMON_CHANNELS) ==
-	P2P_SC_FAIL_NO_COMMON_CHANNELS,
-    "P2P status code value mismatch");
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::P2pStatusCode::FAIL_UNKNOWN_GROUP) ==
-	P2P_SC_FAIL_UNKNOWN_GROUP,
-    "P2P status code value mismatch");
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::P2pStatusCode::FAIL_BOTH_GO_INTENT_15) ==
-	P2P_SC_FAIL_BOTH_GO_INTENT_15,
-    "P2P status code value mismatch");
-static_assert(
-    static_cast<uint16_t>(ISupplicantP2pIfaceCallback::P2pStatusCode::
-			      FAIL_INCOMPATIBLE_PROV_METHOD) ==
-	P2P_SC_FAIL_INCOMPATIBLE_PROV_METHOD,
-    "P2P status code value mismatch");
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::P2pStatusCode::FAIL_REJECTED_BY_USER) ==
-	P2P_SC_FAIL_REJECTED_BY_USER,
-    "P2P status code value mismatch");
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::P2pStatusCode::SUCCESS_DEFERRED) ==
-	P2P_SC_SUCCESS_DEFERRED,
-    "P2P status code value mismatch");
-
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::P2pProvDiscStatusCode::SUCCESS) ==
-	P2P_PROV_DISC_SUCCESS,
-    "P2P status code value mismatch");
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::P2pProvDiscStatusCode::TIMEOUT) ==
-	P2P_PROV_DISC_TIMEOUT,
-    "P2P status code value mismatch");
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::P2pProvDiscStatusCode::REJECTED) ==
-	P2P_PROV_DISC_REJECTED,
-    "P2P status code value mismatch");
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::P2pProvDiscStatusCode::TIMEOUT_JOIN) ==
-	P2P_PROV_DISC_TIMEOUT_JOIN,
-    "P2P status code value mismatch");
-static_assert(
-    static_cast<uint16_t>(
-	ISupplicantP2pIfaceCallback::P2pProvDiscStatusCode::INFO_UNAVAILABLE) ==
-	P2P_PROV_DISC_INFO_UNAVAILABLE,
-    "P2P status code value mismatch");
-}  // namespace implementation
-}  // namespace V1_4
-}  // namespace supplicant
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-#endif  // WPA_SUPPLICANT_HIDL_HIDL_MANAGER_H
diff --git a/wpa_supplicant/hidl/1.4/hidl_return_util.h b/wpa_supplicant/hidl/1.4/hidl_return_util.h
deleted file mode 100644
index 217f215..0000000
--- a/wpa_supplicant/hidl/1.4/hidl_return_util.h
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- * hidl interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, 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_
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_4 {
-namespace implementation {
-namespace hidl_return_util {
-
-/**
- * These utility functions are used to invoke a method on the provided
- * HIDL interface object.
- * These functions checks if the provided HIDL interface object is valid.
- * a) if valid, Invokes the corresponding internal implementation function of
- * the HIDL method. It then invokes the HIDL continuation callback with
- * the status and any returned values.
- * b) if invalid, invokes the HIDL continuation callback with the
- * provided error status and default values.
- */
-// Use for HIDL methods which return only an instance of SupplicantStatus.
-template <typename ObjT, typename SupplicantStatusCodeT, typename WorkFuncT,
-    typename SupplicantStatusT, typename... Args>
-Return<void> validateAndCall(
-    ObjT* obj, SupplicantStatusCodeT status_code_if_invalid, WorkFuncT&& work,
-    const std::function<void(const SupplicantStatusT&)>& hidl_cb, Args&&... args)
-{
-	if (obj->isValid()) {
-		hidl_cb((obj->*work)(std::forward<Args>(args)...));
-	} else {
-		hidl_cb({status_code_if_invalid, ""});
-	}
-	return Void();
-}
-
-// Use for HIDL methods which return instance of SupplicantStatus and a single
-// return value.
-template <typename ObjT, typename SupplicantStatusCodeT, typename WorkFuncT,
-    typename SupplicantStatusT, typename ReturnT, typename... Args>
-Return<void> validateAndCall(
-    ObjT* obj, SupplicantStatusCodeT status_code_if_invalid, WorkFuncT&& work,
-    const std::function<void(const SupplicantStatusT&, ReturnT)>& hidl_cb,
-    Args&&... args)
-{
-	if (obj->isValid()) {
-		const auto& ret_pair =
-		    (obj->*work)(std::forward<Args>(args)...);
-		const SupplicantStatusT& status = std::get<0>(ret_pair);
-		const auto& ret_value = std::get<1>(ret_pair);
-		hidl_cb(status, ret_value);
-	} else {
-		hidl_cb(
-		    {status_code_if_invalid, ""},
-		    typename std::remove_reference<ReturnT>::type());
-	}
-	return Void();
-}
-
-// Use for HIDL methods which return instance of SupplicantStatus and 2 return
-// values.
-template <
-    typename ObjT, typename SupplicantStatusCodeT, typename WorkFuncT,
-    typename SupplicantStatusT, typename ReturnT1, typename ReturnT2, typename... Args>
-Return<void> validateAndCall(
-    ObjT* obj, SupplicantStatusCodeT status_code_if_invalid, WorkFuncT&& work,
-    const std::function<void(const SupplicantStatusT&, ReturnT1, ReturnT2)>&
-	hidl_cb,
-    Args&&... args)
-{
-	if (obj->isValid()) {
-		const auto& ret_tuple =
-		    (obj->*work)(std::forward<Args>(args)...);
-		const SupplicantStatusT& status = std::get<0>(ret_tuple);
-		const auto& ret_value1 = std::get<1>(ret_tuple);
-		const auto& ret_value2 = std::get<2>(ret_tuple);
-		hidl_cb(status, ret_value1, ret_value2);
-	} else {
-		hidl_cb(
-		    {status_code_if_invalid, ""},
-		    typename std::remove_reference<ReturnT1>::type(),
-		    typename std::remove_reference<ReturnT2>::type());
-	}
-	return Void();
-}
-
-}  // namespace hidl_return_util
-}  // namespace implementation
-}  // namespace V1_4
-}  // namespace supplicant
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-#endif  // HIDL_RETURN_UTIL_H_
diff --git a/wpa_supplicant/hidl/1.4/iface_config_utils.cpp b/wpa_supplicant/hidl/1.4/iface_config_utils.cpp
deleted file mode 100644
index 9af3ea9..0000000
--- a/wpa_supplicant/hidl/1.4/iface_config_utils.cpp
+++ /dev/null
@@ -1,185 +0,0 @@
-/*
- * hidl interface for wpa_supplicant daemon
- * Copyright (struct wpa_supplicant* wpa_s, c) 2004-2016, Jouni Malinen
- * <j@w1.fi>
- * Copyright (struct wpa_supplicant* wpa_s, c) 2004-2016, Roshan Pius
- * <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "hidl_manager.h"
-#include "hidl_return_util.h"
-#include "iface_config_utils.h"
-
-namespace {
-using android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
-using android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
-
-constexpr uint32_t kMaxWpsDeviceNameSize = WPS_DEV_NAME_MAX_LEN;
-constexpr uint32_t kMaxWpsManufacturerSize = WPS_MANUFACTURER_MAX_LEN;
-constexpr uint32_t kMaxWpsModelNameSize = WPS_MODEL_NAME_MAX_LEN;
-constexpr uint32_t kMaxWpsModelNumberSize = WPS_MODEL_NUMBER_MAX_LEN;
-constexpr uint32_t kMaxWpsSerialNumberSize = WPS_SERIAL_NUMBER_MAX_LEN;
-
-void processConfigUpdate(struct wpa_supplicant* wpa_s, uint32_t changed_param)
-{
-	wpa_s->conf->changed_parameters |= changed_param;
-	wpa_supplicant_update_config(wpa_s);
-}
-
-// Free any existing pointer stored in |dst| and store the provided string value
-// there.
-int freeAndSetStringConfigParam(
-    struct wpa_supplicant* wpa_s, const std::string& value, uint32_t max_size,
-    uint32_t changed_param, char** dst)
-{
-	if (value.size() > max_size) {
-		return -1;
-	}
-	WPA_ASSERT(dst);
-	os_free(static_cast<void*>(*dst));
-	*dst = os_strdup(value.c_str());
-	processConfigUpdate(wpa_s, changed_param);
-	return 0;
-}
-
-std::string convertWpsConfigMethodsMaskToString(uint16_t config_methods)
-{
-	using WpsConfigMethods =
-	    android::hardware::wifi::supplicant::V1_0::WpsConfigMethods;
-	std::string config_methods_str;
-	for (const auto& flag_and_name :
-	     {std::make_pair(WpsConfigMethods::USBA, "usba"),
-	      {WpsConfigMethods::ETHERNET, "ethernet"},
-	      {WpsConfigMethods::LABEL, "label"},
-	      {WpsConfigMethods::DISPLAY, "display"},
-	      {WpsConfigMethods::INT_NFC_TOKEN, "int_nfc_token"},
-	      {WpsConfigMethods::EXT_NFC_TOKEN, "ext_nfc_token"},
-	      {WpsConfigMethods::NFC_INTERFACE, "nfc_interface"},
-	      {WpsConfigMethods::PUSHBUTTON, "push_button"},
-	      {WpsConfigMethods::KEYPAD, "keypad"},
-	      {WpsConfigMethods::VIRT_PUSHBUTTON, "virtual_push_button"},
-	      {WpsConfigMethods::PHY_PUSHBUTTON, "physical_push_button"},
-	      {WpsConfigMethods::P2PS, "p2ps"},
-	      {WpsConfigMethods::VIRT_DISPLAY, "virtual_display"},
-	      {WpsConfigMethods::PHY_DISPLAY, "physical_display"}}) {
-		const auto flag =
-		    static_cast<std::underlying_type<WpsConfigMethods>::type>(
-			flag_and_name.first);
-		if ((config_methods & flag) == flag) {
-			config_methods_str += flag_and_name.second;
-			config_methods_str += " ";
-		}
-	}
-	return config_methods_str;
-}
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_4 {
-namespace implementation {
-namespace iface_config_utils {
-using V1_0::SupplicantStatusCode;
-
-SupplicantStatus setWpsDeviceName(
-    struct wpa_supplicant* wpa_s, const std::string& name)
-{
-	WPA_ASSERT(wpa_s);
-	if (freeAndSetStringConfigParam(
-		wpa_s, name, kMaxWpsDeviceNameSize, CFG_CHANGED_DEVICE_NAME,
-		&wpa_s->conf->device_name)) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus setWpsDeviceType(
-    struct wpa_supplicant* wpa_s, const std::array<uint8_t, 8>& type)
-{
-	WPA_ASSERT(wpa_s);
-	WPA_ASSERT(type.size() == WPS_DEV_TYPE_LEN);
-	os_memcpy(wpa_s->conf->device_type, type.data(), WPS_DEV_TYPE_LEN);
-	processConfigUpdate(wpa_s, CFG_CHANGED_DEVICE_TYPE);
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus setWpsManufacturer(
-    struct wpa_supplicant* wpa_s, const std::string& manufacturer)
-{
-	WPA_ASSERT(wpa_s);
-	if (freeAndSetStringConfigParam(
-		wpa_s, manufacturer, kMaxWpsManufacturerSize,
-		CFG_CHANGED_WPS_STRING, &wpa_s->conf->manufacturer)) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus setWpsModelName(
-    struct wpa_supplicant* wpa_s, const std::string& model_name)
-{
-	WPA_ASSERT(wpa_s);
-	if (freeAndSetStringConfigParam(
-		wpa_s, model_name, kMaxWpsModelNameSize, CFG_CHANGED_WPS_STRING,
-		&wpa_s->conf->model_name)) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus setWpsModelNumber(
-    struct wpa_supplicant* wpa_s, const std::string& model_number)
-{
-	WPA_ASSERT(wpa_s);
-	if (freeAndSetStringConfigParam(
-		wpa_s, model_number, kMaxWpsModelNumberSize,
-		CFG_CHANGED_WPS_STRING, &wpa_s->conf->model_number)) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus setWpsSerialNumber(
-    struct wpa_supplicant* wpa_s, const std::string& serial_number)
-{
-	WPA_ASSERT(wpa_s);
-	if (freeAndSetStringConfigParam(
-		wpa_s, serial_number, kMaxWpsSerialNumberSize,
-		CFG_CHANGED_WPS_STRING, &wpa_s->conf->serial_number)) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus setWpsConfigMethods(
-    struct wpa_supplicant* wpa_s, uint16_t config_methods)
-{
-	WPA_ASSERT(wpa_s);
-	if (freeAndSetStringConfigParam(
-		wpa_s, convertWpsConfigMethodsMaskToString(config_methods),
-		UINT32_MAX, CFG_CHANGED_CONFIG_METHODS,
-		&wpa_s->conf->config_methods)) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus setExternalSim(
-    struct wpa_supplicant* wpa_s, bool useExternalSim)
-{
-	WPA_ASSERT(wpa_s);
-	wpa_s->conf->external_sim = useExternalSim ? 1 : 0;
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-}  // namespace iface_config_utils
-}  // namespace implementation
-}  // namespace V1_4
-}  // namespace supplicant
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wpa_supplicant/hidl/1.4/iface_config_utils.h b/wpa_supplicant/hidl/1.4/iface_config_utils.h
deleted file mode 100644
index a94feb5..0000000
--- a/wpa_supplicant/hidl/1.4/iface_config_utils.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * hidl interface for wpa_supplicant daemon
- * Copyright (struct wpa_supplicant* wpa_s, c) 2004-2016, Jouni Malinen
- * <j@w1.fi>
- * Copyright (struct wpa_supplicant* wpa_s, c) 2004-2016, Roshan Pius
- * <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WPA_SUPPLICANT_HIDL_IFACE_CONFIG_UTILS_H
-#define WPA_SUPPLICANT_HIDL_IFACE_CONFIG_UTILS_H
-
-#include <android-base/macros.h>
-
-extern "C"
-{
-#include "utils/common.h"
-#include "utils/includes.h"
-#include "wpa_supplicant_i.h"
-#include "config.h"
-}
-
-/**
- * Utility functions to set various config parameters of an iface via HIDL
- * methods.
- */
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_4 {
-namespace implementation {
-namespace iface_config_utils {
-SupplicantStatus setWpsDeviceName(
-    struct wpa_supplicant* wpa_s, const std::string& name);
-SupplicantStatus setWpsDeviceType(
-    struct wpa_supplicant* wpa_s, const std::array<uint8_t, 8>& type);
-SupplicantStatus setWpsManufacturer(
-    struct wpa_supplicant* wpa_s, const std::string& manufacturer);
-SupplicantStatus setWpsModelName(
-    struct wpa_supplicant* wpa_s, const std::string& model_name);
-SupplicantStatus setWpsModelNumber(
-    struct wpa_supplicant* wpa_s, const std::string& model_number);
-SupplicantStatus setWpsSerialNumber(
-    struct wpa_supplicant* wpa_s, const std::string& serial_number);
-SupplicantStatus setWpsConfigMethods(
-    struct wpa_supplicant* wpa_s, uint16_t config_methods);
-SupplicantStatus setExternalSim(
-    struct wpa_supplicant* wpa_s, bool useExternalSim);
-}  // namespace iface_config_utils
-}  // namespace implementation
-}  // namespace V1_4
-}  // namespace supplicant
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WPA_SUPPLICANT_HIDL_IFACE_CONFIG_UTILS_H
diff --git a/wpa_supplicant/hidl/1.4/p2p_iface.cpp b/wpa_supplicant/hidl/1.4/p2p_iface.cpp
deleted file mode 100644
index cabcccb..0000000
--- a/wpa_supplicant/hidl/1.4/p2p_iface.cpp
+++ /dev/null
@@ -1,1985 +0,0 @@
-/*
- * hidl interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- * Copyright (C) 2017 Sony Mobile Communications Inc.
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "hidl_manager.h"
-#include "hidl_return_util.h"
-#include "iface_config_utils.h"
-#include "misc_utils.h"
-#include "p2p_iface.h"
-#include "sta_network.h"
-
-extern "C"
-{
-#include "ap.h"
-#include "wps_supplicant.h"
-#include "wifi_display.h"
-#include "utils/eloop.h"
-#include "wpa_supplicant_i.h"
-#include "driver_i.h"
-}
-
-#define P2P_MAX_JOIN_SCAN_ATTEMPTS 3
-// Wait time before triggering the single channel scan to discover Auto GO.
-// Use a shorter wait time when the given frequency is GO operating frequency.
-// The idea is to quickly finish scans and return the status to application.
-#define P2P_JOIN_SINGLE_CHANNEL_SCAN_INTERVAL_USECS 200000
-// Wait time before triggering the multiple channel scan to discover Auto GO.
-#define P2P_JOIN_MULTIPLE_CHANNEL_SCAN_INTERVAL_USECS 1000000
-
-namespace {
-const char kConfigMethodStrPbc[] = "pbc";
-const char kConfigMethodStrDisplay[] = "display";
-const char kConfigMethodStrKeypad[] = "keypad";
-constexpr char kSetMiracastMode[] = "MIRACAST ";
-constexpr uint8_t kWfdDeviceInfoSubelemId = 0;
-constexpr uint8_t kWfdR2DeviceInfoSubelemId = 11;
-constexpr char kWfdDeviceInfoSubelemLenHexStr[] = "0006";
-
-std::function<void()> pending_join_scan_callback = NULL;
-std::function<void()> pending_scan_res_join_callback = NULL;
-
-using android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIface;
-using android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork;
-uint8_t convertHidlMiracastModeToInternal(
-    ISupplicantP2pIface::MiracastMode mode)
-{
-	switch (mode) {
-	case ISupplicantP2pIface::MiracastMode::DISABLED:
-		return 0;
-	case ISupplicantP2pIface::MiracastMode::SOURCE:
-		return 1;
-	case ISupplicantP2pIface::MiracastMode::SINK:
-		return 2;
-	};
-	WPA_ASSERT(false);
-}
-
-/**
- * Check if the provided ssid is valid or not.
- *
- * Returns 1 if valid, 0 otherwise.
- */
-int isSsidValid(const std::vector<uint8_t>& ssid)
-{
-	if (ssid.size() == 0 ||
-	    ssid.size() >
-		static_cast<uint32_t>(ISupplicantStaNetwork::ParamSizeLimits::
-					  SSID_MAX_LEN_IN_BYTES)) {
-		return 0;
-	}
-	return 1;
-}
-
-/**
- * Check if the provided psk passhrase is valid or not.
- *
- * Returns 1 if valid, 0 otherwise.
- */
-int isPskPassphraseValid(const std::string &psk)
-{
-	if (psk.size() <
-		static_cast<uint32_t>(ISupplicantStaNetwork::ParamSizeLimits::
-					  PSK_PASSPHRASE_MIN_LEN_IN_BYTES) ||
-	    psk.size() >
-		static_cast<uint32_t>(ISupplicantStaNetwork::ParamSizeLimits::
-					  PSK_PASSPHRASE_MAX_LEN_IN_BYTES)) {
-		return 0;
-	}
-	if (has_ctrl_char((u8 *)psk.c_str(), psk.size())) {
-		return 0;
-	}
-	return 1;
-}
-
-static int setBandScanFreqsList(
-    struct wpa_supplicant *wpa_s,
-    enum hostapd_hw_mode hw_mode,
-    bool exclude_dfs,
-    struct wpa_driver_scan_params *params)
-{
-	struct hostapd_hw_modes *mode;
-	int count, i;
-
-	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes, hw_mode, 0);
-	if (mode == NULL || !mode->num_channels) {
-		wpa_printf(MSG_ERROR,
-		    "P2P: No channels supported in this hw_mode: %d", hw_mode);
-		return -1;
-	}
-
-	/*
-	 * Allocate memory for frequency array, allocate one extra
-	 * slot for the zero-terminator.
-	 */
-	params->freqs = (int *) os_calloc(mode->num_channels + 1, sizeof(int));
-	if (params->freqs == NULL) {
-		return -ENOMEM;
-	}
-	for (count = 0, i = 0; i < mode->num_channels; i++) {
-		if (mode->channels[i].flag & HOSTAPD_CHAN_DISABLED) {
-			continue;
-		}
-		if (exclude_dfs && (mode->channels[i].flag & HOSTAPD_CHAN_RADAR)) {
-			continue;
-		}
-		params->freqs[count++] = mode->channels[i].freq;
-	}
-	if (!count && params->freqs) {
-		wpa_printf(MSG_ERROR,
-		    "P2P: All channels(exclude_dfs: %d) are disabled in this hw_mode: %d",
-		    exclude_dfs, hw_mode);
-		os_free(params->freqs);
-		return -1;
-	}
-	return 0;
-}
-
-static int setP2pCliOptimizedScanFreqsList(struct wpa_supplicant *wpa_s,
-    struct wpa_driver_scan_params *params, int freq)
-{
-	if (freq == 2 || freq == 5) {
-		enum hostapd_hw_mode mode;
-		int ret;
-		if (wpa_s->hw.modes == NULL) {
-			wpa_printf(MSG_DEBUG,
-				   "P2P: Unknown what %dG channels the driver supports.", freq);
-			return 0;
-		}
-		mode = freq == 5 ? HOSTAPD_MODE_IEEE80211A : HOSTAPD_MODE_IEEE80211G;
-		if (wpa_s->p2p_join_scan_count < 2) {
-			// scan all non DFS channels in the first two attempts
-			ret = setBandScanFreqsList(wpa_s, mode, true, params);
-			if (ret < 0 && (-ENOMEM != ret)) {
-				// try to scan all channels before returning error
-				ret = setBandScanFreqsList(wpa_s, mode, false, params);
-			}
-		} else {
-			// scan all channels
-			ret = setBandScanFreqsList(wpa_s, mode, false, params);
-		}
-		return ret;
-	} else {
-		if (disabled_freq(wpa_s, freq)) {
-			wpa_printf(MSG_ERROR,
-				   "P2P: freq %d is not supported for a client.", freq);
-			return -1;
-		}
-		/*
-		 * Allocate memory for frequency array, allocate one extra
-		 * slot for the zero-terminator.
-		 */
-		params->freqs = (int *) os_calloc(2, sizeof(int));
-		if (params->freqs) {
-			params->freqs[0] = freq;
-		} else {
-			return -ENOMEM;
-		}
-	}
-	return 0;
-}
-
-/**
- * getP2pJoinScanInterval - Get the delay in triggering the scan to discover
- * Auto GO.
- */
-static int getP2pJoinScanIntervalUsecs(int freq)
-{
-	if (freq == 5 || freq == 2 || freq == 0) {
-		return P2P_JOIN_MULTIPLE_CHANNEL_SCAN_INTERVAL_USECS;
-	} else {
-		return P2P_JOIN_SINGLE_CHANNEL_SCAN_INTERVAL_USECS;
-	}
-}
-
-/*
- * isAnyEtherAddr - match any ether address
- *
- */
-int isAnyEtherAddr(const u8 *a)
-{
-	// 02:00:00:00:00:00
-	return (a[0] == 2) && !(a[1] | a[2] | a[3] | a[4] | a[5]);
-}
-
-/**
- * findBssBySsid - Fetch a BSS table entry based on SSID and optional BSSID.
- * @wpa_s: Pointer to wpa_supplicant data
- * @bssid: BSSID, 02:00:00:00:00:00 matches any bssid
- * @ssid: SSID
- * @ssid_len: Length of @ssid
- * Returns: Pointer to the BSS entry or %NULL if not found
- */
-struct wpa_bss* findBssBySsid(
-    struct wpa_supplicant *wpa_s, const u8 *bssid,
-    const u8 *ssid, size_t ssid_len)
-{
-	struct wpa_bss *bss;
-	dl_list_for_each(bss, &wpa_s->bss, struct wpa_bss, list) {
-		if ((isAnyEtherAddr(bssid) ||
-		    os_memcmp(bss->bssid, bssid, ETH_ALEN) == 0) &&
-		    bss->ssid_len == ssid_len &&
-		    os_memcmp(bss->ssid, ssid, ssid_len) == 0)
-			return bss;
-	}
-	return NULL;
-}
-
-struct wpa_ssid* addGroupClientNetwork(
-    struct wpa_supplicant* wpa_s,
-    uint8_t *group_owner_bssid,
-    const std::vector<uint8_t>& ssid,
-    const std::string& passphrase)
-{
-	struct wpa_ssid* wpa_network = wpa_config_add_network(wpa_s->conf);
-	if (!wpa_network) {
-		return NULL;
-	}
-	// set general network defaults
-	wpa_config_set_network_defaults(wpa_network);
-
-	// set P2p network defaults
-	wpa_network->p2p_group = 1;
-	wpa_network->mode = wpas_mode::WPAS_MODE_INFRA;
-
-	wpa_network->auth_alg = WPA_AUTH_ALG_OPEN;
-	wpa_network->key_mgmt = WPA_KEY_MGMT_PSK;
-	wpa_network->proto = WPA_PROTO_RSN;
-	wpa_network->pairwise_cipher = WPA_CIPHER_CCMP;
-	wpa_network->group_cipher = WPA_CIPHER_CCMP;
-	wpa_network->disabled = 2;
-
-	// set necessary fields
-	os_memcpy(wpa_network->bssid, group_owner_bssid, ETH_ALEN);
-	wpa_network->bssid_set = 1;
-
-	wpa_network->ssid = (uint8_t *)os_malloc(ssid.size());
-	if (wpa_network->ssid == NULL) {
-		wpa_config_remove_network(wpa_s->conf, wpa_network->id);
-		return  NULL;
-	}
-	memcpy(wpa_network->ssid, ssid.data(), ssid.size());
-	wpa_network->ssid_len = ssid.size();
-
-	wpa_network->psk_set = 0;
-	wpa_network->passphrase = dup_binstr(passphrase.c_str(), passphrase.length());
-	if (wpa_network->passphrase == NULL) {
-		wpa_config_remove_network(wpa_s->conf, wpa_network->id);
-		return  NULL;
-	}
-	wpa_config_update_psk(wpa_network);
-
-	return wpa_network;
-
-}
-
-void joinScanWrapper(void *eloop_ctx, void *timeout_ctx)
-{
-	struct wpa_supplicant *wpa_s = (struct wpa_supplicant *) eloop_ctx;
-
-	if (pending_join_scan_callback != NULL) {
-		pending_join_scan_callback();
-	}
-}
-
-void scanResJoinWrapper(
-    struct wpa_supplicant *wpa_s,
-    struct wpa_scan_results *scan_res)
-{
-	if (wpa_s->p2p_scan_work) {
-		struct wpa_radio_work *work = wpa_s->p2p_scan_work;
-		wpa_s->p2p_scan_work = NULL;
-		radio_work_done(work);
-	}
-
-	if (pending_scan_res_join_callback) {
-		pending_scan_res_join_callback();
-	}
-}
-
-int joinScanReq(
-    struct wpa_supplicant* wpa_s,
-    const std::vector<uint8_t>& ssid,
-    int freq)
-{
-	int ret;
-	struct wpa_driver_scan_params params;
-	struct wpabuf *ies;
-	size_t ielen;
-	unsigned int bands;
-
-	if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) {
-		wpa_printf(MSG_ERROR,
-		    "P2P: P2P interface is gone, cancel join scan");
-		return -ENXIO;
-	}
-
-	os_memset(&params, 0, sizeof(params));
-	if (ssid.size() > 0) {
-		params.ssids[0].ssid = ssid.data();
-		params.ssids[0].ssid_len = ssid.size();
-	} else {
-		params.ssids[0].ssid = (u8 *) P2P_WILDCARD_SSID;
-		params.ssids[0].ssid_len = P2P_WILDCARD_SSID_LEN;
-	}
-	wpa_printf(MSG_DEBUG, "Scan SSID %s for join with frequency %d (reinvoke)",
-	    wpa_ssid_txt(params.ssids[0].ssid, params.ssids[0].ssid_len), freq);
-
-	/* Construct an optimized p2p scan channel list */
-	if (freq > 0) {
-		ret = setP2pCliOptimizedScanFreqsList(wpa_s, &params, freq);
-		if (ret < 0) {
-			wpa_printf(MSG_ERROR,
-				   "Failed to set frequency in p2p scan params, error = %d", ret);
-			return -1;
-		}
-	}
-
-	ielen = p2p_scan_ie_buf_len(wpa_s->global->p2p);
-	ies = wpabuf_alloc(ielen);
-	if (ies == NULL) {
-		if (params.freqs) {
-			os_free(params.freqs);
-		}
-		return -1;
-	}
-
-	bands = wpas_get_bands(wpa_s, params.freqs);
-	p2p_scan_ie(wpa_s->global->p2p, ies, NULL, bands);
-
-	params.p2p_probe = 1;
-	params.extra_ies = (u8 *) wpabuf_head(ies);
-	params.extra_ies_len = wpabuf_len(ies);
-	if (wpa_s->clear_driver_scan_cache) {
-		wpa_printf(MSG_DEBUG,
-		    "Request driver to clear scan cache due to local BSS flush");
-		params.only_new_results = 1;
-	}
-
-	ret = wpa_drv_scan(wpa_s, &params);
-	if (!ret) {
-		os_get_reltime(&wpa_s->scan_trigger_time);
-		if (wpa_s->scan_res_handler) {
-			wpa_printf(MSG_DEBUG, "Replace current running scan result handler");
-		}
-		wpa_s->p2p_join_scan_count++;
-		wpa_s->scan_res_handler = scanResJoinWrapper;
-		wpa_s->own_scan_requested = 1;
-		wpa_s->clear_driver_scan_cache = 0;
-	}
-
-	if (params.freqs) {
-		os_free(params.freqs);
-	}
-
-	wpabuf_free(ies);
-
-	return ret;
-}
-
-int joinGroup(
-    struct wpa_supplicant* wpa_s,
-    uint8_t *group_owner_bssid,
-    const std::vector<uint8_t>& ssid,
-    const std::string& passphrase)
-{
-	int ret = 0;
-	int he = wpa_s->conf->p2p_go_he;
-	int vht = wpa_s->conf->p2p_go_vht;
-	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
-
-	// Construct a network for adding group.
-	// Group client follows the persistent attribute of Group Owner.
-	// If joined group is persistent, it adds a persistent network on GroupStarted.
-	struct wpa_ssid *wpa_network = addGroupClientNetwork(
-	    wpa_s, group_owner_bssid, ssid, passphrase);
-	if (wpa_network == NULL) {
-		wpa_printf(MSG_ERROR, "P2P: Cannot construct a network for group join.");
-		return -1;
-	}
-
-	// this is temporary network only for establishing the connection.
-	wpa_network->temporary = 1;
-
-	if (wpas_p2p_group_add_persistent(
-		wpa_s, wpa_network, 0, 0, 0, 0, ht40, vht,
-		CHANWIDTH_USE_HT, he, 0, NULL, 0, 0)) {
-		ret = -1;
-	}
-
-	// Always remove this temporary network at the end.
-	wpa_config_remove_network(wpa_s->conf, wpa_network->id);
-	return ret;
-}
-
-void notifyGroupJoinFailure(
-    struct wpa_supplicant* wpa_s)
-{
-	u8 zero_addr[ETH_ALEN] = {0};
-	std::vector<uint8_t> ssid = {'D', 'I', 'R', 'E','C', 'T', '-'};
-	std::string passphrase = "";
-	struct wpa_ssid *wpa_network = addGroupClientNetwork(
-	    wpa_s, zero_addr, ssid, passphrase);
-	if (wpa_network) {
-		wpa_network->temporary = 1;
-		wpas_notify_p2p_group_formation_failure(wpa_s, "Failed to find the group.");
-		wpas_notify_p2p_group_removed(
-		    wpa_s, wpa_network, "client");
-		wpa_config_remove_network(
-		    wpa_s->conf, wpa_network->id);
-	} else {
-		wpa_printf(MSG_ERROR,
-		    "P2P: Cannot construct a network.");
-	}
-}
-
-void scanResJoinIgnore(struct wpa_supplicant *wpa_s, struct wpa_scan_results *scan_res) {
-	wpa_printf(MSG_DEBUG, "P2P: Ignore group join scan results.");
-
-	if (wpa_s->p2p_scan_work) {
-		struct wpa_radio_work *work = wpa_s->p2p_scan_work;
-		wpa_s->p2p_scan_work = NULL;
-		radio_work_done(work);
-	}
-
-}
-
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_4 {
-namespace implementation {
-using hidl_return_util::validateAndCall;
-using V1_0::SupplicantStatusCode;
-
-P2pIface::P2pIface(struct wpa_global* wpa_global, const char ifname[])
-    : wpa_global_(wpa_global), ifname_(ifname), is_valid_(true)
-{}
-
-void P2pIface::invalidate() { is_valid_ = false; }
-bool P2pIface::isValid()
-{
-	return (is_valid_ && (retrieveIfacePtr() != nullptr));
-}
-Return<void> P2pIface::getName(getName_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::getNameInternal, _hidl_cb);
-}
-
-Return<void> P2pIface::getType(getType_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::getTypeInternal, _hidl_cb);
-}
-
-Return<void> P2pIface::addNetwork(addNetwork_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::addNetworkInternal, _hidl_cb);
-}
-
-Return<void> P2pIface::removeNetwork(
-    SupplicantNetworkId id, removeNetwork_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::removeNetworkInternal, _hidl_cb, id);
-}
-
-Return<void> P2pIface::getNetwork(
-    SupplicantNetworkId id, getNetwork_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::getNetworkInternal, _hidl_cb, id);
-}
-
-Return<void> P2pIface::listNetworks(listNetworks_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::listNetworksInternal, _hidl_cb);
-}
-
-Return<void> P2pIface::registerCallback(
-    const sp<ISupplicantP2pIfaceCallback>& callback,
-    registerCallback_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::registerCallbackInternal, _hidl_cb, callback);
-}
-
-Return<void> P2pIface::getDeviceAddress(getDeviceAddress_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::getDeviceAddressInternal, _hidl_cb);
-}
-
-Return<void> P2pIface::setSsidPostfix(
-    const hidl_vec<uint8_t>& postfix, setSsidPostfix_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::setSsidPostfixInternal, _hidl_cb, postfix);
-}
-
-Return<void> P2pIface::setGroupIdle(
-    const hidl_string& group_ifname, uint32_t timeout_in_sec,
-    setGroupIdle_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::setGroupIdleInternal, _hidl_cb, group_ifname,
-	    timeout_in_sec);
-}
-
-Return<void> P2pIface::setPowerSave(
-    const hidl_string& group_ifname, bool enable, setPowerSave_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::setPowerSaveInternal, _hidl_cb, group_ifname, enable);
-}
-
-Return<void> P2pIface::find(uint32_t timeout_in_sec, find_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::findInternal, _hidl_cb, timeout_in_sec);
-}
-
-Return<void> P2pIface::stopFind(stopFind_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::stopFindInternal, _hidl_cb);
-}
-
-Return<void> P2pIface::flush(flush_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::flushInternal, _hidl_cb);
-}
-
-Return<void> P2pIface::connect(
-    const hidl_array<uint8_t, 6>& peer_address,
-    ISupplicantP2pIface::WpsProvisionMethod provision_method,
-    const hidl_string& pre_selected_pin, bool join_existing_group,
-    bool persistent, uint32_t go_intent, connect_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::connectInternal, _hidl_cb, peer_address,
-	    provision_method, pre_selected_pin, join_existing_group, persistent,
-	    go_intent);
-}
-
-Return<void> P2pIface::cancelConnect(cancelConnect_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::cancelConnectInternal, _hidl_cb);
-}
-
-Return<void> P2pIface::provisionDiscovery(
-    const hidl_array<uint8_t, 6>& peer_address,
-    ISupplicantP2pIface::WpsProvisionMethod provision_method,
-    provisionDiscovery_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::provisionDiscoveryInternal, _hidl_cb, peer_address,
-	    provision_method);
-}
-
-Return<void> P2pIface::addGroup(
-    bool persistent, SupplicantNetworkId persistent_network_id,
-    addGroup_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::addGroupInternal, _hidl_cb, persistent,
-	    persistent_network_id);
-}
-
-Return<void> P2pIface::removeGroup(
-    const hidl_string& group_ifname, removeGroup_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::removeGroupInternal, _hidl_cb, group_ifname);
-}
-
-Return<void> P2pIface::reject(
-    const hidl_array<uint8_t, 6>& peer_address, reject_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::rejectInternal, _hidl_cb, peer_address);
-}
-
-Return<void> P2pIface::invite(
-    const hidl_string& group_ifname,
-    const hidl_array<uint8_t, 6>& go_device_address,
-    const hidl_array<uint8_t, 6>& peer_address, invite_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::inviteInternal, _hidl_cb, group_ifname,
-	    go_device_address, peer_address);
-}
-
-Return<void> P2pIface::reinvoke(
-    SupplicantNetworkId persistent_network_id,
-    const hidl_array<uint8_t, 6>& peer_address, reinvoke_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::reinvokeInternal, _hidl_cb, persistent_network_id,
-	    peer_address);
-}
-
-Return<void> P2pIface::configureExtListen(
-    uint32_t period_in_millis, uint32_t interval_in_millis,
-    configureExtListen_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::configureExtListenInternal, _hidl_cb, period_in_millis,
-	    interval_in_millis);
-}
-
-Return<void> P2pIface::setListenChannel(
-    uint32_t channel, uint32_t operating_class, setListenChannel_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::setListenChannelInternal, _hidl_cb, channel,
-	    operating_class);
-}
-
-Return<void> P2pIface::setDisallowedFrequencies(
-    const hidl_vec<FreqRange>& ranges, setDisallowedFrequencies_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::setDisallowedFrequenciesInternal, _hidl_cb, ranges);
-}
-
-Return<void> P2pIface::getSsid(
-    const hidl_array<uint8_t, 6>& peer_address, getSsid_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::getSsidInternal, _hidl_cb, peer_address);
-}
-
-Return<void> P2pIface::getGroupCapability(
-    const hidl_array<uint8_t, 6>& peer_address, getGroupCapability_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::getGroupCapabilityInternal, _hidl_cb, peer_address);
-}
-
-Return<void> P2pIface::addBonjourService(
-    const hidl_vec<uint8_t>& query, const hidl_vec<uint8_t>& response,
-    addBonjourService_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::addBonjourServiceInternal, _hidl_cb, query, response);
-}
-
-Return<void> P2pIface::removeBonjourService(
-    const hidl_vec<uint8_t>& query, removeBonjourService_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::removeBonjourServiceInternal, _hidl_cb, query);
-}
-
-Return<void> P2pIface::addUpnpService(
-    uint32_t version, const hidl_string& service_name,
-    addUpnpService_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::addUpnpServiceInternal, _hidl_cb, version, service_name);
-}
-
-Return<void> P2pIface::removeUpnpService(
-    uint32_t version, const hidl_string& service_name,
-    removeUpnpService_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::removeUpnpServiceInternal, _hidl_cb, version,
-	    service_name);
-}
-
-Return<void> P2pIface::flushServices(flushServices_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::flushServicesInternal, _hidl_cb);
-}
-
-Return<void> P2pIface::requestServiceDiscovery(
-    const hidl_array<uint8_t, 6>& peer_address, const hidl_vec<uint8_t>& query,
-    requestServiceDiscovery_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::requestServiceDiscoveryInternal, _hidl_cb, peer_address,
-	    query);
-}
-
-Return<void> P2pIface::cancelServiceDiscovery(
-    uint64_t identifier, cancelServiceDiscovery_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::cancelServiceDiscoveryInternal, _hidl_cb, identifier);
-}
-
-Return<void> P2pIface::setMiracastMode(
-    ISupplicantP2pIface::MiracastMode mode, setMiracastMode_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::setMiracastModeInternal, _hidl_cb, mode);
-}
-
-Return<void> P2pIface::startWpsPbc(
-    const hidl_string& group_ifname, const hidl_array<uint8_t, 6>& bssid,
-    startWpsPbc_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::startWpsPbcInternal, _hidl_cb, group_ifname, bssid);
-}
-
-Return<void> P2pIface::startWpsPinKeypad(
-    const hidl_string& group_ifname, const hidl_string& pin,
-    startWpsPinKeypad_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::startWpsPinKeypadInternal, _hidl_cb, group_ifname, pin);
-}
-
-Return<void> P2pIface::startWpsPinDisplay(
-    const hidl_string& group_ifname, const hidl_array<uint8_t, 6>& bssid,
-    startWpsPinDisplay_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::startWpsPinDisplayInternal, _hidl_cb, group_ifname,
-	    bssid);
-}
-
-Return<void> P2pIface::cancelWps(
-    const hidl_string& group_ifname, cancelWps_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::cancelWpsInternal, _hidl_cb, group_ifname);
-}
-
-Return<void> P2pIface::setWpsDeviceName(
-    const hidl_string& name, setWpsDeviceName_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::setWpsDeviceNameInternal, _hidl_cb, name);
-}
-
-Return<void> P2pIface::setWpsDeviceType(
-    const hidl_array<uint8_t, 8>& type, setWpsDeviceType_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::setWpsDeviceTypeInternal, _hidl_cb, type);
-}
-
-Return<void> P2pIface::setWpsManufacturer(
-    const hidl_string& manufacturer, setWpsManufacturer_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::setWpsManufacturerInternal, _hidl_cb, manufacturer);
-}
-
-Return<void> P2pIface::setWpsModelName(
-    const hidl_string& model_name, setWpsModelName_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::setWpsModelNameInternal, _hidl_cb, model_name);
-}
-
-Return<void> P2pIface::setWpsModelNumber(
-    const hidl_string& model_number, setWpsModelNumber_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::setWpsModelNumberInternal, _hidl_cb, model_number);
-}
-
-Return<void> P2pIface::setWpsSerialNumber(
-    const hidl_string& serial_number, setWpsSerialNumber_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::setWpsSerialNumberInternal, _hidl_cb, serial_number);
-}
-
-Return<void> P2pIface::setWpsConfigMethods(
-    uint16_t config_methods, setWpsConfigMethods_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::setWpsConfigMethodsInternal, _hidl_cb, config_methods);
-}
-
-Return<void> P2pIface::enableWfd(bool enable, enableWfd_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::enableWfdInternal, _hidl_cb, enable);
-}
-
-Return<void> P2pIface::setWfdDeviceInfo(
-    const hidl_array<uint8_t, 6>& info, setWfdDeviceInfo_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::setWfdDeviceInfoInternal, _hidl_cb, info);
-}
-
-Return<void> P2pIface::createNfcHandoverRequestMessage(
-    createNfcHandoverRequestMessage_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::createNfcHandoverRequestMessageInternal, _hidl_cb);
-}
-
-Return<void> P2pIface::createNfcHandoverSelectMessage(
-    createNfcHandoverSelectMessage_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::createNfcHandoverSelectMessageInternal, _hidl_cb);
-}
-
-Return<void> P2pIface::reportNfcHandoverResponse(
-    const hidl_vec<uint8_t>& request, reportNfcHandoverResponse_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::reportNfcHandoverResponseInternal, _hidl_cb, request);
-}
-
-Return<void> P2pIface::reportNfcHandoverInitiation(
-    const hidl_vec<uint8_t>& select, reportNfcHandoverInitiation_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::reportNfcHandoverInitiationInternal, _hidl_cb, select);
-}
-
-Return<void> P2pIface::saveConfig(saveConfig_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::saveConfigInternal, _hidl_cb);
-}
-
-Return<void> P2pIface::addGroup_1_2(
-    const hidl_vec<uint8_t>& ssid, const hidl_string& passphrase,
-    bool persistent, uint32_t freq, const hidl_array<uint8_t, 6>& peer_address,
-    bool join, addGroup_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::addGroup_1_2Internal, _hidl_cb,
-	    ssid, passphrase, persistent, freq, peer_address, join);
-}
-
-Return<void> P2pIface::setMacRandomization(bool enable, setMacRandomization_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::setMacRandomizationInternal, _hidl_cb, enable);
-}
-
-Return<void> P2pIface::setEdmg(bool enable, setEdmg_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, V1_4::SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &P2pIface::setEdmgInternal, _hidl_cb, enable);
-}
-
-Return<void> P2pIface::getEdmg(getEdmg_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, V1_4::SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &P2pIface::getEdmgInternal, _hidl_cb);
-}
-
-Return<void> P2pIface::registerCallback_1_4(
-    const sp<V1_4::ISupplicantP2pIfaceCallback>& callback,
-    registerCallback_1_4_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, V1_4::SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::registerCallback_1_4Internal, _hidl_cb, callback);
-}
-
-Return<void> P2pIface::setWfdR2DeviceInfo(
-    const hidl_array<uint8_t, 4>& info, setWfdR2DeviceInfo_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, V1_4::SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &P2pIface::setWfdR2DeviceInfoInternal, _hidl_cb, info);
-}
-
-std::pair<SupplicantStatus, std::string> P2pIface::getNameInternal()
-{
-	return {{SupplicantStatusCode::SUCCESS, ""}, ifname_};
-}
-
-std::pair<SupplicantStatus, IfaceType> P2pIface::getTypeInternal()
-{
-	return {{SupplicantStatusCode::SUCCESS, ""}, IfaceType::P2P};
-}
-
-std::pair<SupplicantStatus, sp<ISupplicantP2pNetwork>>
-P2pIface::addNetworkInternal()
-{
-	android::sp<ISupplicantP2pNetwork> network;
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	struct wpa_ssid* ssid = wpa_supplicant_add_network(wpa_s);
-	if (!ssid) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
-	}
-	HidlManager* hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager ||
-	    hidl_manager->getP2pNetworkHidlObjectByIfnameAndNetworkId(
-		wpa_s->ifname, ssid->id, &network)) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, network};
-}
-
-SupplicantStatus P2pIface::removeNetworkInternal(SupplicantNetworkId id)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	int result = wpa_supplicant_remove_network(wpa_s, id);
-	if (result == -1) {
-		return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""};
-	}
-	if (result != 0) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-std::pair<SupplicantStatus, sp<ISupplicantP2pNetwork>>
-P2pIface::getNetworkInternal(SupplicantNetworkId id)
-{
-	android::sp<ISupplicantP2pNetwork> network;
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	struct wpa_ssid* ssid = wpa_config_get_network(wpa_s->conf, id);
-	if (!ssid) {
-		return {{SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""},
-			network};
-	}
-	HidlManager* hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager ||
-	    hidl_manager->getP2pNetworkHidlObjectByIfnameAndNetworkId(
-		wpa_s->ifname, ssid->id, &network)) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, network};
-}
-
-std::pair<SupplicantStatus, std::vector<SupplicantNetworkId>>
-P2pIface::listNetworksInternal()
-{
-	std::vector<SupplicantNetworkId> network_ids;
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	for (struct wpa_ssid* wpa_ssid = wpa_s->conf->ssid; wpa_ssid;
-	     wpa_ssid = wpa_ssid->next) {
-		network_ids.emplace_back(wpa_ssid->id);
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, std::move(network_ids)};
-}
-
-SupplicantStatus P2pIface::registerCallbackInternal(
-    const sp<ISupplicantP2pIfaceCallback>& callback)
-{
-	HidlManager* hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager ||
-	    hidl_manager->addP2pIfaceCallbackHidlObject(ifname_, callback)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-std::pair<SupplicantStatus, std::array<uint8_t, 6>>
-P2pIface::getDeviceAddressInternal()
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	std::array<uint8_t, 6> addr;
-	static_assert(ETH_ALEN == addr.size(), "Size mismatch");
-	os_memcpy(addr.data(), wpa_s->global->p2p_dev_addr, ETH_ALEN);
-	return {{SupplicantStatusCode::SUCCESS, ""}, addr};
-}
-
-SupplicantStatus P2pIface::setSsidPostfixInternal(
-    const std::vector<uint8_t>& postfix)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	if (p2p_set_ssid_postfix(
-		wpa_s->global->p2p, postfix.data(), postfix.size())) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::setGroupIdleInternal(
-    const std::string& group_ifname, uint32_t timeout_in_sec)
-{
-	struct wpa_supplicant* wpa_group_s =
-	    retrieveGroupIfacePtr(group_ifname);
-	if (!wpa_group_s) {
-		return {SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""};
-	}
-	wpa_group_s->conf->p2p_group_idle = timeout_in_sec;
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::setPowerSaveInternal(
-    const std::string& group_ifname, bool enable)
-{
-	struct wpa_supplicant* wpa_group_s =
-	    retrieveGroupIfacePtr(group_ifname);
-	if (!wpa_group_s) {
-		return {SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""};
-	}
-	if (wpa_drv_set_p2p_powersave(wpa_group_s, enable, -1, -1)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::findInternal(uint32_t timeout_in_sec)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
-		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
-	}
-	uint32_t search_delay = wpas_p2p_search_delay(wpa_s);
-	if (wpas_p2p_find(
-		wpa_s, timeout_in_sec, P2P_FIND_START_WITH_FULL, 0, nullptr,
-		nullptr, search_delay, 0, nullptr, 0)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::stopFindInternal()
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
-		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
-	}
-	if (wpa_s->scan_res_handler == scanResJoinWrapper) {
-		wpa_printf(MSG_DEBUG, "P2P: Stop pending group scan for stopping find).");
-		pending_scan_res_join_callback = NULL;
-		wpa_s->scan_res_handler = scanResJoinIgnore;
-	}
-	wpas_p2p_stop_find(wpa_s);
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::flushInternal()
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
-	wpa_s->force_long_sd = 0;
-	wpas_p2p_stop_find(wpa_s);
-	wpa_s->parent->p2ps_method_config_any = 0;
-	if (wpa_s->global->p2p)
-		p2p_flush(wpa_s->global->p2p);
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-// This method only implements support for subset (needed by Android framework)
-// of parameters that can be specified for connect.
-std::pair<SupplicantStatus, std::string> P2pIface::connectInternal(
-    const std::array<uint8_t, 6>& peer_address,
-    ISupplicantP2pIface::WpsProvisionMethod provision_method,
-    const std::string& pre_selected_pin, bool join_existing_group,
-    bool persistent, uint32_t go_intent)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	if (go_intent > 15) {
-		return {{SupplicantStatusCode::FAILURE_ARGS_INVALID, ""}, {}};
-	}
-	int go_intent_signed = join_existing_group ? -1 : go_intent;
-	p2p_wps_method wps_method = {};
-	switch (provision_method) {
-	case WpsProvisionMethod::PBC:
-		wps_method = WPS_PBC;
-		break;
-	case WpsProvisionMethod::DISPLAY:
-		wps_method = WPS_PIN_DISPLAY;
-		break;
-	case WpsProvisionMethod::KEYPAD:
-		wps_method = WPS_PIN_KEYPAD;
-		break;
-	}
-	int he = wpa_s->conf->p2p_go_he;
-	int vht = wpa_s->conf->p2p_go_vht;
-	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
-	const char* pin =
-	    pre_selected_pin.length() > 0 ? pre_selected_pin.data() : nullptr;
-	bool auto_join = !join_existing_group;
-	int new_pin = wpas_p2p_connect(
-	    wpa_s, peer_address.data(), pin, wps_method, persistent, auto_join,
-	    join_existing_group, false, go_intent_signed, 0, 0, -1, false, ht40,
-	    vht, CHANWIDTH_USE_HT, he, 0, nullptr, 0);
-	if (new_pin < 0) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	std::string pin_ret;
-	if (provision_method == WpsProvisionMethod::DISPLAY &&
-	    pre_selected_pin.empty()) {
-		pin_ret = misc_utils::convertWpsPinToString(new_pin);
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, pin_ret};
-}
-
-SupplicantStatus P2pIface::cancelConnectInternal()
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	if (wpa_s->scan_res_handler == scanResJoinWrapper) {
-		wpa_printf(MSG_DEBUG, "P2P: Stop pending group scan for canceling connect");
-		pending_scan_res_join_callback = NULL;
-		wpa_s->scan_res_handler = scanResJoinIgnore;
-	}
-	if (wpas_p2p_cancel(wpa_s)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::provisionDiscoveryInternal(
-    const std::array<uint8_t, 6>& peer_address,
-    ISupplicantP2pIface::WpsProvisionMethod provision_method)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	p2ps_provision* prov_param;
-	const char* config_method_str = nullptr;
-	switch (provision_method) {
-	case WpsProvisionMethod::PBC:
-		config_method_str = kConfigMethodStrPbc;
-		break;
-	case WpsProvisionMethod::DISPLAY:
-		config_method_str = kConfigMethodStrDisplay;
-		break;
-	case WpsProvisionMethod::KEYPAD:
-		config_method_str = kConfigMethodStrKeypad;
-		break;
-	}
-	if (wpas_p2p_prov_disc(
-		wpa_s, peer_address.data(), config_method_str,
-		WPAS_P2P_PD_FOR_GO_NEG, nullptr)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::addGroupInternal(
-    bool persistent, SupplicantNetworkId persistent_network_id)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	int he = wpa_s->conf->p2p_go_he;
-	int vht = wpa_s->conf->p2p_go_vht;
-	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
-	struct wpa_ssid* ssid =
-	    wpa_config_get_network(wpa_s->conf, persistent_network_id);
-	if (ssid == NULL) {
-		if (wpas_p2p_group_add(
-			wpa_s, persistent, 0, 0, ht40, vht,
-			CHANWIDTH_USE_HT, he, 0)) {
-			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-		} else {
-			return {SupplicantStatusCode::SUCCESS, ""};
-		}
-	} else if (ssid->disabled == 2) {
-		if (wpas_p2p_group_add_persistent(
-			wpa_s, ssid, 0, 0, 0, 0, ht40, vht,
-			CHANWIDTH_USE_HT, he, 0, NULL, 0, 0)) {
-			return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN,
-				""};
-		} else {
-			return {SupplicantStatusCode::SUCCESS, ""};
-		}
-	}
-	return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-}
-
-SupplicantStatus P2pIface::removeGroupInternal(const std::string& group_ifname)
-{
-	struct wpa_supplicant* wpa_group_s =
-	    retrieveGroupIfacePtr(group_ifname);
-	if (!wpa_group_s) {
-		return {SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""};
-	}
-	wpa_group_s->global->p2p_go_found_external_scan = 0;
-	if (wpas_p2p_group_remove(wpa_group_s, group_ifname.c_str())) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::rejectInternal(
-    const std::array<uint8_t, 6>& peer_address)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL) {
-		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
-	}
-	if (wpas_p2p_reject(wpa_s, peer_address.data())) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::inviteInternal(
-    const std::string& group_ifname,
-    const std::array<uint8_t, 6>& go_device_address,
-    const std::array<uint8_t, 6>& peer_address)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	if (wpas_p2p_invite_group(
-		wpa_s, group_ifname.c_str(), peer_address.data(),
-		go_device_address.data())) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::reinvokeInternal(
-    SupplicantNetworkId persistent_network_id,
-    const std::array<uint8_t, 6>& peer_address)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	int he = wpa_s->conf->p2p_go_he;
-	int vht = wpa_s->conf->p2p_go_vht;
-	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
-	struct wpa_ssid* ssid =
-	    wpa_config_get_network(wpa_s->conf, persistent_network_id);
-	if (ssid == NULL || ssid->disabled != 2) {
-		return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""};
-	}
-	if (wpas_p2p_invite(
-		wpa_s, peer_address.data(), ssid, NULL, 0, 0, ht40, vht,
-		CHANWIDTH_USE_HT, 0, he, 0)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::configureExtListenInternal(
-    uint32_t period_in_millis, uint32_t interval_in_millis)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	if (wpas_p2p_ext_listen(wpa_s, period_in_millis, interval_in_millis)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::setListenChannelInternal(
-    uint32_t channel, uint32_t operating_class)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	if (p2p_set_listen_channel(
-		wpa_s->global->p2p, operating_class, channel, 1)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::setDisallowedFrequenciesInternal(
-    const std::vector<FreqRange>& ranges)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	using DestT = struct wpa_freq_range_list::wpa_freq_range;
-	DestT* freq_ranges = nullptr;
-	// Empty ranges is used to enable all frequencies.
-	if (ranges.size() != 0) {
-		freq_ranges = static_cast<DestT*>(
-		    os_malloc(sizeof(DestT) * ranges.size()));
-		if (!freq_ranges) {
-			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-		}
-		uint32_t i = 0;
-		for (const auto& range : ranges) {
-			freq_ranges[i].min = range.min;
-			freq_ranges[i].max = range.max;
-			i++;
-		}
-	}
-
-	os_free(wpa_s->global->p2p_disallow_freq.range);
-	wpa_s->global->p2p_disallow_freq.range = freq_ranges;
-	wpa_s->global->p2p_disallow_freq.num = ranges.size();
-	wpas_p2p_update_channel_list(wpa_s, WPAS_P2P_CHANNEL_UPDATE_DISALLOW);
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-std::pair<SupplicantStatus, std::vector<uint8_t>> P2pIface::getSsidInternal(
-    const std::array<uint8_t, 6>& peer_address)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	const struct p2p_peer_info* info =
-	    p2p_get_peer_info(wpa_s->global->p2p, peer_address.data(), 0);
-	if (!info) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	const struct p2p_device* dev =
-	    reinterpret_cast<const struct p2p_device*>(
-		(reinterpret_cast<const uint8_t*>(info)) -
-		offsetof(struct p2p_device, info));
-	std::vector<uint8_t> ssid;
-	if (dev && dev->oper_ssid_len) {
-		ssid.assign(
-		    dev->oper_ssid, dev->oper_ssid + dev->oper_ssid_len);
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, ssid};
-}
-
-std::pair<SupplicantStatus, uint32_t> P2pIface::getGroupCapabilityInternal(
-    const std::array<uint8_t, 6>& peer_address)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	const struct p2p_peer_info* info =
-	    p2p_get_peer_info(wpa_s->global->p2p, peer_address.data(), 0);
-	if (!info) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, info->group_capab};
-}
-
-SupplicantStatus P2pIface::addBonjourServiceInternal(
-    const std::vector<uint8_t>& query, const std::vector<uint8_t>& response)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	auto query_buf = misc_utils::convertVectorToWpaBuf(query);
-	auto response_buf = misc_utils::convertVectorToWpaBuf(response);
-	if (!query_buf || !response_buf) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	if (wpas_p2p_service_add_bonjour(
-		wpa_s, query_buf.get(), response_buf.get())) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	// If successful, the wpabuf is referenced internally and hence should
-	// not be freed.
-	query_buf.release();
-	response_buf.release();
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::removeBonjourServiceInternal(
-    const std::vector<uint8_t>& query)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	auto query_buf = misc_utils::convertVectorToWpaBuf(query);
-	if (!query_buf) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	if (wpas_p2p_service_del_bonjour(wpa_s, query_buf.get())) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::addUpnpServiceInternal(
-    uint32_t version, const std::string& service_name)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	if (wpas_p2p_service_add_upnp(wpa_s, version, service_name.c_str())) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::removeUpnpServiceInternal(
-    uint32_t version, const std::string& service_name)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	if (wpas_p2p_service_del_upnp(wpa_s, version, service_name.c_str())) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::flushServicesInternal()
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	wpas_p2p_service_flush(wpa_s);
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-std::pair<SupplicantStatus, uint64_t> P2pIface::requestServiceDiscoveryInternal(
-    const std::array<uint8_t, 6>& peer_address,
-    const std::vector<uint8_t>& query)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	auto query_buf = misc_utils::convertVectorToWpaBuf(query);
-	if (!query_buf) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	const uint8_t* dst_addr = is_zero_ether_addr(peer_address.data())
-				      ? nullptr
-				      : peer_address.data();
-	uint64_t identifier =
-	    wpas_p2p_sd_request(wpa_s, dst_addr, query_buf.get());
-	if (identifier == 0) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, identifier};
-}
-
-SupplicantStatus P2pIface::cancelServiceDiscoveryInternal(uint64_t identifier)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	if (wpas_p2p_sd_cancel_request(wpa_s, identifier)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::setMiracastModeInternal(
-    ISupplicantP2pIface::MiracastMode mode)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	uint8_t mode_internal = convertHidlMiracastModeToInternal(mode);
-	const std::string cmd_str =
-	    kSetMiracastMode + std::to_string(mode_internal);
-	std::vector<char> cmd(
-	    cmd_str.c_str(), cmd_str.c_str() + cmd_str.size() + 1);
-	char driver_cmd_reply_buf[4096] = {};
-	if (wpa_drv_driver_cmd(
-		wpa_s, cmd.data(), driver_cmd_reply_buf,
-		sizeof(driver_cmd_reply_buf))) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::startWpsPbcInternal(
-    const std::string& group_ifname, const std::array<uint8_t, 6>& bssid)
-{
-	struct wpa_supplicant* wpa_group_s =
-	    retrieveGroupIfacePtr(group_ifname);
-	if (!wpa_group_s) {
-		return {SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""};
-	}
-	const uint8_t* bssid_addr =
-	    is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
-#ifdef CONFIG_AP
-	if (wpa_group_s->ap_iface) {
-		if (wpa_supplicant_ap_wps_pbc(wpa_group_s, bssid_addr, NULL)) {
-			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-		}
-		return {SupplicantStatusCode::SUCCESS, ""};
-	}
-#endif /* CONFIG_AP */
-	if (wpas_wps_start_pbc(wpa_group_s, bssid_addr, 0, 0)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::startWpsPinKeypadInternal(
-    const std::string& group_ifname, const std::string& pin)
-{
-	struct wpa_supplicant* wpa_group_s =
-	    retrieveGroupIfacePtr(group_ifname);
-	if (!wpa_group_s) {
-		return {SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""};
-	}
-#ifdef CONFIG_AP
-	if (wpa_group_s->ap_iface) {
-		if (wpa_supplicant_ap_wps_pin(
-			wpa_group_s, nullptr, pin.c_str(), nullptr, 0, 0) < 0) {
-			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-		}
-		return {SupplicantStatusCode::SUCCESS, ""};
-	}
-#endif /* CONFIG_AP */
-	if (wpas_wps_start_pin(
-		wpa_group_s, nullptr, pin.c_str(), 0, DEV_PW_DEFAULT)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-std::pair<SupplicantStatus, std::string> P2pIface::startWpsPinDisplayInternal(
-    const std::string& group_ifname, const std::array<uint8_t, 6>& bssid)
-{
-	struct wpa_supplicant* wpa_group_s =
-	    retrieveGroupIfacePtr(group_ifname);
-	if (!wpa_group_s) {
-		return {{SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""}, ""};
-	}
-	const uint8_t* bssid_addr =
-	    is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
-	int pin = wpas_wps_start_pin(
-	    wpa_group_s, bssid_addr, nullptr, 0, DEV_PW_DEFAULT);
-	if (pin < 0) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, ""};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		misc_utils::convertWpsPinToString(pin)};
-}
-
-SupplicantStatus P2pIface::cancelWpsInternal(const std::string& group_ifname)
-{
-	struct wpa_supplicant* wpa_group_s =
-	    retrieveGroupIfacePtr(group_ifname);
-	if (!wpa_group_s) {
-		return {SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""};
-	}
-	if (wpas_wps_cancel(wpa_group_s)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::setWpsDeviceNameInternal(const std::string& name)
-{
-	return iface_config_utils::setWpsDeviceName(retrieveIfacePtr(), name);
-}
-
-SupplicantStatus P2pIface::setWpsDeviceTypeInternal(
-    const std::array<uint8_t, 8>& type)
-{
-	return iface_config_utils::setWpsDeviceType(retrieveIfacePtr(), type);
-}
-
-SupplicantStatus P2pIface::setWpsManufacturerInternal(
-    const std::string& manufacturer)
-{
-	return iface_config_utils::setWpsManufacturer(
-	    retrieveIfacePtr(), manufacturer);
-}
-
-SupplicantStatus P2pIface::setWpsModelNameInternal(
-    const std::string& model_name)
-{
-	return iface_config_utils::setWpsModelName(
-	    retrieveIfacePtr(), model_name);
-}
-
-SupplicantStatus P2pIface::setWpsModelNumberInternal(
-    const std::string& model_number)
-{
-	return iface_config_utils::setWpsModelNumber(
-	    retrieveIfacePtr(), model_number);
-}
-
-SupplicantStatus P2pIface::setWpsSerialNumberInternal(
-    const std::string& serial_number)
-{
-	return iface_config_utils::setWpsSerialNumber(
-	    retrieveIfacePtr(), serial_number);
-}
-
-SupplicantStatus P2pIface::setWpsConfigMethodsInternal(uint16_t config_methods)
-{
-	return iface_config_utils::setWpsConfigMethods(
-	    retrieveIfacePtr(), config_methods);
-}
-
-SupplicantStatus P2pIface::enableWfdInternal(bool enable)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	wifi_display_enable(wpa_s->global, enable);
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::setWfdDeviceInfoInternal(
-    const std::array<uint8_t, 6>& info)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	std::vector<char> wfd_device_info_hex(info.size() * 2 + 1);
-	wpa_snprintf_hex(
-	    wfd_device_info_hex.data(), wfd_device_info_hex.size(), info.data(),
-	    info.size());
-	// |wifi_display_subelem_set| expects the first 2 bytes
-	// to hold the lenght of the subelement. In this case it's
-	// fixed to 6, so prepend that.
-	std::string wfd_device_info_set_cmd_str =
-	    std::to_string(kWfdDeviceInfoSubelemId) + " " +
-	    kWfdDeviceInfoSubelemLenHexStr + wfd_device_info_hex.data();
-	std::vector<char> wfd_device_info_set_cmd(
-	    wfd_device_info_set_cmd_str.c_str(),
-	    wfd_device_info_set_cmd_str.c_str() +
-		wfd_device_info_set_cmd_str.size() + 1);
-	if (wifi_display_subelem_set(
-		wpa_s->global, wfd_device_info_set_cmd.data())) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-std::pair<SupplicantStatus, std::vector<uint8_t>>
-P2pIface::createNfcHandoverRequestMessageInternal()
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	auto buf = misc_utils::createWpaBufUniquePtr(
-	    wpas_p2p_nfc_handover_req(wpa_s, 1));
-	if (!buf) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		misc_utils::convertWpaBufToVector(buf.get())};
-}
-
-std::pair<SupplicantStatus, std::vector<uint8_t>>
-P2pIface::createNfcHandoverSelectMessageInternal()
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	auto buf = misc_utils::createWpaBufUniquePtr(
-	    wpas_p2p_nfc_handover_sel(wpa_s, 1, 0));
-	if (!buf) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		misc_utils::convertWpaBufToVector(buf.get())};
-}
-
-SupplicantStatus P2pIface::reportNfcHandoverResponseInternal(
-    const std::vector<uint8_t>& request)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	auto req = misc_utils::convertVectorToWpaBuf(request);
-	auto sel = misc_utils::convertVectorToWpaBuf(std::vector<uint8_t>{0});
-	if (!req || !sel) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-
-	if (wpas_p2p_nfc_report_handover(wpa_s, 0, req.get(), sel.get(), 0)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::reportNfcHandoverInitiationInternal(
-    const std::vector<uint8_t>& select)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	auto req = misc_utils::convertVectorToWpaBuf(std::vector<uint8_t>{0});
-	auto sel = misc_utils::convertVectorToWpaBuf(select);
-	if (!req || !sel) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-
-	if (wpas_p2p_nfc_report_handover(wpa_s, 1, req.get(), sel.get(), 0)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::saveConfigInternal()
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	if (!wpa_s->conf->update_config) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	if (wpa_config_write(wpa_s->confname, wpa_s->conf)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::addGroup_1_2Internal(
-    const std::vector<uint8_t>& ssid, const std::string& passphrase,
-    bool persistent, uint32_t freq, const std::array<uint8_t, 6>& peer_address,
-    bool joinExistingGroup)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	int he = wpa_s->conf->p2p_go_he;
-	int vht = wpa_s->conf->p2p_go_vht;
-	int ht40 = wpa_s->conf->p2p_go_ht40 || vht;
-
-	if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) {
-		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
-	}
-
-	if (!isSsidValid(ssid)) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, "SSID is invalid."};
-	}
-
-	if (!isPskPassphraseValid(passphrase)) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, "passphrase is invalid."};
-	}
-
-	if (!joinExistingGroup) {
-		struct p2p_data *p2p = wpa_s->global->p2p;
-		os_memcpy(p2p->ssid, ssid.data(), ssid.size());
-		p2p->ssid_len = ssid.size();
-		p2p->ssid_set = 1;
-
-		os_memset(p2p->passphrase, 0, sizeof(p2p->passphrase));
-		os_memcpy(p2p->passphrase, passphrase.c_str(), passphrase.length());
-		p2p->passphrase_set = 1;
-
-		if (wpas_p2p_group_add(
-		    wpa_s, persistent, freq, 0, ht40, vht,
-		    CHANWIDTH_USE_HT, he, 0)) {
-			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-		}
-		return {SupplicantStatusCode::SUCCESS, ""};
-	}
-
-	// The rest is for group join.
-	wpa_printf(MSG_DEBUG, "P2P: Stop any on-going P2P FIND before group join.");
-	wpas_p2p_stop_find(wpa_s);
-
-	struct wpa_bss *bss = findBssBySsid(
-	    wpa_s, peer_address.data(),
-	    ssid.data(), ssid.size());
-	if (bss != NULL) {
-		wpa_printf(MSG_DEBUG, "P2P: Join group with Group Owner " MACSTR,
-		    MAC2STR(bss->bssid));
-		if (0 != joinGroup(wpa_s, bss->bssid, ssid, passphrase)) {
-			// no need to notify group join failure here,
-			// it will be handled by wpas_p2p_group_add_persistent
-			// called in joinGroup.
-			return {SupplicantStatusCode::FAILURE_UNKNOWN, "Failed to join a group."};
-		}
-		return {SupplicantStatusCode::SUCCESS, ""};
-	}
-
-	wpa_printf(MSG_INFO, "No matched BSS exists, try to find it by scan");
-
-	if (pending_scan_res_join_callback != NULL) {
-		wpa_printf(MSG_WARNING, "P2P: Renew scan result callback with new request.");
-	}
-
-	pending_join_scan_callback =
-	    [wpa_s, ssid, freq]() {
-		if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) {
-			return;
-		}
-		int ret = joinScanReq(wpa_s, ssid, freq);
-		// for BUSY case, the scan might be occupied by WiFi.
-		// Do not give up immediately, but try again later.
-		if (-EBUSY == ret) {
-			// re-schedule this join scan and don't consume retry count.
-			if (pending_scan_res_join_callback) {
-				pending_scan_res_join_callback();
-			}
-		} else if (0 != ret) {
-			notifyGroupJoinFailure(wpa_s);
-			pending_scan_res_join_callback = NULL;
-		}
-	};
-
-	pending_scan_res_join_callback = [wpa_s, ssid, passphrase, peer_address, freq, this]() {
-		if (wpa_s->global->p2p == NULL || wpa_s->global->p2p_disabled) {
-			return;
-		}
-
-		wpa_printf(MSG_DEBUG, "P2P: Scan results received for join (reinvoke).");
-
-		struct wpa_bss *bss = findBssBySsid(
-		    wpa_s, peer_address.data(), ssid.data(), ssid.size());
-		if (bss) {
-			wpa_s->global->p2p_go_found_external_scan = 1;
-			if (0 != joinGroup(wpa_s, bss->bssid, ssid, passphrase)) {
-				wpa_printf(MSG_ERROR, "P2P: Failed to join a group.");
-				wpa_s->global->p2p_go_found_external_scan = 0;
-			}
-			// no need to notify group join failure here,
-			// it will be handled by wpas_p2p_group_add_persistent
-			// called in joinGroup.
-			pending_scan_res_join_callback = NULL;
-			return;
-		}
-		wpa_printf(MSG_DEBUG, "P2P: Join scan count %d.", wpa_s->p2p_join_scan_count);
-		eloop_cancel_timeout(joinScanWrapper, wpa_s, NULL);
-		if (wpa_s->p2p_join_scan_count < P2P_MAX_JOIN_SCAN_ATTEMPTS) {
-			wpa_printf(MSG_DEBUG, "P2P: Try join again later.");
-			eloop_register_timeout(0, getP2pJoinScanIntervalUsecs(freq),
-			    joinScanWrapper, wpa_s, this);
-			return;
-		}
-
-		wpa_printf(MSG_ERROR, "P2P: Failed to find the group with "
-		    "network name %s - stop join attempt",
-		    ssid.data());
-		notifyGroupJoinFailure(wpa_s);
-		pending_scan_res_join_callback = NULL;
-	};
-
-	wpa_s->p2p_join_scan_count = 0;
-	pending_join_scan_callback();
-	if (pending_scan_res_join_callback == NULL) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, "Failed to start scan."};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::setMacRandomizationInternal(bool enable)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	bool currentEnabledState = !!wpa_s->conf->p2p_device_random_mac_addr;
-	u8 *addr = NULL;
-
-	// The same state, no change is needed.
-	if (currentEnabledState == enable) {
-		wpa_printf(MSG_DEBUG, "The random MAC is %s already.",
-		    (enable) ? "enabled" : "disabled");
-		return {SupplicantStatusCode::SUCCESS, ""};
-	}
-
-	if (enable) {
-		wpa_s->conf->p2p_device_random_mac_addr = 1;
-		wpa_s->conf->p2p_interface_random_mac_addr = 1;
-
-		// restore config if it failed to set up MAC address.
-		if (wpas_p2p_mac_setup(wpa_s) < 0) {
-			wpa_s->conf->p2p_device_random_mac_addr = 0;
-			wpa_s->conf->p2p_interface_random_mac_addr = 0;
-			return {SupplicantStatusCode::FAILURE_UNKNOWN,
-			    "Failed to set up MAC address."};
-		}
-	} else {
-		// disable random MAC will use original MAC address
-		// regardless of any saved persistent groups.
-		if (wpa_drv_set_mac_addr(wpa_s, NULL) < 0) {
-			wpa_printf(MSG_ERROR, "Failed to restore MAC address");
-			return {SupplicantStatusCode::FAILURE_UNKNOWN,
-			    "Failed to restore MAC address."};
-		}
-
-		if (wpa_supplicant_update_mac_addr(wpa_s) < 0) {
-			wpa_printf(MSG_INFO, "Could not update MAC address information");
-			return {SupplicantStatusCode::FAILURE_UNKNOWN,
-			    "Failed to update MAC address."};
-		}
-		wpa_s->conf->p2p_device_random_mac_addr = 0;
-		wpa_s->conf->p2p_interface_random_mac_addr = 0;
-	}
-
-	// update internal data to send out correct device address in action frame.
-	os_memcpy(wpa_s->global->p2p_dev_addr, wpa_s->own_addr, ETH_ALEN);
-	os_memcpy(wpa_s->global->p2p->cfg->dev_addr, wpa_s->global->p2p_dev_addr, ETH_ALEN);
-
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-V1_4::SupplicantStatus P2pIface::setEdmgInternal(bool enable)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	wpa_printf(MSG_DEBUG, "set p2p_go_edmg to %d", enable);
-	wpa_s->conf->p2p_go_edmg = enable ? 1 : 0;
-	wpa_s->p2p_go_edmg = enable ? 1 : 0;
-	return {V1_4::SupplicantStatusCode::SUCCESS, ""};
-}
-
-std::pair<V1_4::SupplicantStatus, bool> P2pIface::getEdmgInternal()
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	return {{V1_4::SupplicantStatusCode::SUCCESS, ""},
-		(wpa_s->p2p_go_edmg == 1)};
-}
-
-V1_4::SupplicantStatus P2pIface::registerCallback_1_4Internal(
-    const sp<V1_4::ISupplicantP2pIfaceCallback>& callback)
-{
-	HidlManager* hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager ||
-	    hidl_manager->addP2pIfaceCallbackHidlObject(ifname_, callback)) {
-		return {V1_4::SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {V1_4::SupplicantStatusCode::SUCCESS, ""};
-}
-
-V1_4::SupplicantStatus P2pIface::setWfdR2DeviceInfoInternal(
-    const std::array<uint8_t, 4>& info)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	uint32_t wfd_r2_device_info_hex_len = info.size() * 2 + 1;
-	std::vector<char> wfd_r2_device_info_hex(wfd_r2_device_info_hex_len);
-	wpa_snprintf_hex(
-	    wfd_r2_device_info_hex.data(), wfd_r2_device_info_hex.size(),
-	    info.data(),info.size());
-	std::string wfd_r2_device_info_set_cmd_str =
-	     std::to_string(kWfdR2DeviceInfoSubelemId) + " " +
-	     wfd_r2_device_info_hex.data();
-	std::vector<char> wfd_r2_device_info_set_cmd(
-	     wfd_r2_device_info_set_cmd_str.c_str(),
-	     wfd_r2_device_info_set_cmd_str.c_str() +
-	     wfd_r2_device_info_set_cmd_str.size() + 1);
-	if (wifi_display_subelem_set(
-		wpa_s->global, wfd_r2_device_info_set_cmd.data())) {
-		return {V1_4::SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {V1_4::SupplicantStatusCode::SUCCESS, ""};
-}
-
-/**
- * Retrieve the underlying |wpa_supplicant| struct
- * pointer for this iface.
- * If the underlying iface is removed, then all RPC method calls on this object
- * will return failure.
- */
-wpa_supplicant* P2pIface::retrieveIfacePtr()
-{
-	return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
-}
-
-/**
- * Retrieve the underlying |wpa_supplicant| struct
- * pointer for this group iface.
- */
-wpa_supplicant* P2pIface::retrieveGroupIfacePtr(const std::string& group_ifname)
-{
-	return wpa_supplicant_get_iface(wpa_global_, group_ifname.c_str());
-}
-
-}  // namespace implementation
-}  // namespace V1_4
-}  // namespace supplicant
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wpa_supplicant/hidl/1.4/p2p_iface.h b/wpa_supplicant/hidl/1.4/p2p_iface.h
deleted file mode 100644
index c8ddc01..0000000
--- a/wpa_supplicant/hidl/1.4/p2p_iface.h
+++ /dev/null
@@ -1,346 +0,0 @@
-/*
- * hidl interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WPA_SUPPLICANT_HIDL_P2P_IFACE_H
-#define WPA_SUPPLICANT_HIDL_P2P_IFACE_H
-
-#include <array>
-#include <vector>
-
-#include <android-base/macros.h>
-
-#include <android/hardware/wifi/supplicant/1.4/ISupplicantP2pIface.h>
-#include <android/hardware/wifi/supplicant/1.0/ISupplicantP2pIfaceCallback.h>
-#include <android/hardware/wifi/supplicant/1.0/ISupplicantP2pNetwork.h>
-
-extern "C"
-{
-#include "utils/common.h"
-#include "utils/includes.h"
-#include "p2p/p2p.h"
-#include "p2p/p2p_i.h"
-#include "p2p_supplicant.h"
-#include "p2p_supplicant.h"
-#include "config.h"
-}
-
-#define P2P_MGMT_DEVICE_PREFIX       "p2p-dev-"
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_4 {
-namespace implementation {
-using V1_0::SupplicantNetworkId;
-using V1_0::SupplicantStatus;
-using V1_0::IfaceType;
-using V1_0::ISupplicantP2pIfaceCallback;
-using V1_0::ISupplicantP2pNetwork;
-
-/**
- * Implementation of P2pIface hidl object. Each unique hidl
- * object is used for control operations on a specific interface
- * controlled by wpa_supplicant.
- */
-class P2pIface : public V1_4::ISupplicantP2pIface
-{
-public:
-	P2pIface(struct wpa_global* wpa_global, const char ifname[]);
-	~P2pIface() override = default;
-	// Refer to |StaIface::invalidate()|.
-	void invalidate();
-	bool isValid();
-
-	// Hidl methods exposed.
-	Return<void> getName(getName_cb _hidl_cb) override;
-	Return<void> getType(getType_cb _hidl_cb) override;
-	Return<void> addNetwork(addNetwork_cb _hidl_cb) override;
-	Return<void> removeNetwork(
-	    SupplicantNetworkId id, removeNetwork_cb _hidl_cb) override;
-	Return<void> getNetwork(
-	    SupplicantNetworkId id, getNetwork_cb _hidl_cb) override;
-	Return<void> listNetworks(listNetworks_cb _hidl_cb) override;
-	Return<void> registerCallback(
-	    const sp<ISupplicantP2pIfaceCallback>& callback,
-	    registerCallback_cb _hidl_cb) override;
-	Return<void> getDeviceAddress(getDeviceAddress_cb _hidl_cb) override;
-	Return<void> setSsidPostfix(
-	    const hidl_vec<uint8_t>& postfix,
-	    setSsidPostfix_cb _hidl_cb) override;
-	Return<void> setGroupIdle(
-	    const hidl_string& group_ifname, uint32_t timeout_in_sec,
-	    setGroupIdle_cb _hidl_cb) override;
-	Return<void> setPowerSave(
-	    const hidl_string& group_ifname, bool enable,
-	    setPowerSave_cb _hidl_cb) override;
-	Return<void> find(uint32_t timeout_in_sec, find_cb _hidl_cb) override;
-	Return<void> stopFind(stopFind_cb _hidl_cb) override;
-	Return<void> flush(flush_cb _hidl_cb) override;
-	Return<void> connect(
-	    const hidl_array<uint8_t, 6>& peer_address,
-	    ISupplicantP2pIface::WpsProvisionMethod provision_method,
-	    const hidl_string& pre_selected_pin, bool join_existing_group,
-	    bool persistent, uint32_t go_intent, connect_cb _hidl_cb) override;
-	Return<void> cancelConnect(cancelConnect_cb _hidl_cb) override;
-	Return<void> provisionDiscovery(
-	    const hidl_array<uint8_t, 6>& peer_address,
-	    ISupplicantP2pIface::WpsProvisionMethod provision_method,
-	    provisionDiscovery_cb _hidl_cb) override;
-	Return<void> addGroup(
-	    bool persistent, SupplicantNetworkId persistent_network_id,
-	    addGroup_cb _hidl_cb) override;
-	Return<void> removeGroup(
-	    const hidl_string& group_ifname, removeGroup_cb _hidl_cb) override;
-	Return<void> reject(
-	    const hidl_array<uint8_t, 6>& peer_address,
-	    reject_cb _hidl_cb) override;
-	Return<void> invite(
-	    const hidl_string& group_ifname,
-	    const hidl_array<uint8_t, 6>& go_device_address,
-	    const hidl_array<uint8_t, 6>& peer_address,
-	    invite_cb _hidl_cb) override;
-	Return<void> reinvoke(
-	    SupplicantNetworkId persistent_network_id,
-	    const hidl_array<uint8_t, 6>& peer_address,
-	    reinvoke_cb _hidl_cb) override;
-	Return<void> configureExtListen(
-	    uint32_t period_in_millis, uint32_t interval_in_millis,
-	    configureExtListen_cb _hidl_cb) override;
-	Return<void> setListenChannel(
-	    uint32_t channel, uint32_t operating_class,
-	    setListenChannel_cb _hidl_cb) override;
-	Return<void> setDisallowedFrequencies(
-	    const hidl_vec<FreqRange>& ranges,
-	    setDisallowedFrequencies_cb _hidl_cb) override;
-	Return<void> getSsid(
-	    const hidl_array<uint8_t, 6>& peer_address,
-	    getSsid_cb _hidl_cb) override;
-	Return<void> getGroupCapability(
-	    const hidl_array<uint8_t, 6>& peer_address,
-	    getGroupCapability_cb _hidl_cb) override;
-	Return<void> addBonjourService(
-	    const hidl_vec<uint8_t>& query, const hidl_vec<uint8_t>& response,
-	    addBonjourService_cb _hidl_cb) override;
-	Return<void> removeBonjourService(
-	    const hidl_vec<uint8_t>& query,
-	    removeBonjourService_cb _hidl_cb) override;
-	Return<void> addUpnpService(
-	    uint32_t version, const hidl_string& service_name,
-	    addUpnpService_cb _hidl_cb) override;
-	Return<void> removeUpnpService(
-	    uint32_t version, const hidl_string& service_name,
-	    removeUpnpService_cb _hidl_cb) override;
-	Return<void> flushServices(flushServices_cb _hidl_cb) override;
-	Return<void> requestServiceDiscovery(
-	    const hidl_array<uint8_t, 6>& peer_address,
-	    const hidl_vec<uint8_t>& query,
-	    requestServiceDiscovery_cb _hidl_cb) override;
-	Return<void> cancelServiceDiscovery(
-	    uint64_t identifier, cancelServiceDiscovery_cb _hidl_cb) override;
-	Return<void> setMiracastMode(
-	    ISupplicantP2pIface::MiracastMode mode,
-	    setMiracastMode_cb _hidl_cb) override;
-	Return<void> startWpsPbc(
-	    const hidl_string& groupIfName, const hidl_array<uint8_t, 6>& bssid,
-	    startWpsPbc_cb _hidl_cb) override;
-	Return<void> startWpsPinKeypad(
-	    const hidl_string& groupIfName, const hidl_string& pin,
-	    startWpsPinKeypad_cb _hidl_cb) override;
-	Return<void> startWpsPinDisplay(
-	    const hidl_string& groupIfName, const hidl_array<uint8_t, 6>& bssid,
-	    startWpsPinDisplay_cb _hidl_cb) override;
-	Return<void> cancelWps(
-	    const hidl_string& groupIfName, cancelWps_cb _hidl_cb) override;
-	Return<void> setWpsDeviceName(
-	    const hidl_string& name, setWpsDeviceName_cb _hidl_cb) override;
-	Return<void> setWpsDeviceType(
-	    const hidl_array<uint8_t, 8>& type,
-	    setWpsDeviceType_cb _hidl_cb) override;
-	Return<void> setWpsManufacturer(
-	    const hidl_string& manufacturer,
-	    setWpsManufacturer_cb _hidl_cb) override;
-	Return<void> setWpsModelName(
-	    const hidl_string& model_name,
-	    setWpsModelName_cb _hidl_cb) override;
-	Return<void> setWpsModelNumber(
-	    const hidl_string& model_number,
-	    setWpsModelNumber_cb _hidl_cb) override;
-	Return<void> setWpsSerialNumber(
-	    const hidl_string& serial_number,
-	    setWpsSerialNumber_cb _hidl_cb) override;
-	Return<void> setWpsConfigMethods(
-	    uint16_t config_methods, setWpsConfigMethods_cb _hidl_cb) override;
-	Return<void> enableWfd(bool enable, enableWfd_cb _hidl_cb) override;
-	Return<void> setWfdDeviceInfo(
-	    const hidl_array<uint8_t, 6>& info,
-	    setWfdDeviceInfo_cb _hidl_cb) override;
-	Return<void> createNfcHandoverRequestMessage(
-	    createNfcHandoverRequestMessage_cb _hidl_cb) override;
-	Return<void> createNfcHandoverSelectMessage(
-	    createNfcHandoverSelectMessage_cb _hidl_cb) override;
-	Return<void> reportNfcHandoverResponse(
-	    const hidl_vec<uint8_t>& request,
-	    reportNfcHandoverResponse_cb _hidl_cb) override;
-	Return<void> reportNfcHandoverInitiation(
-	    const hidl_vec<uint8_t>& select,
-	    reportNfcHandoverInitiation_cb _hidl_cb) override;
-	Return<void> saveConfig(saveConfig_cb _hidl_cb) override;
-	Return<void> addGroup_1_2(
-	    const hidl_vec<uint8_t>& ssid, const hidl_string& passphrase,
-	    bool persistent, uint32_t freq, const hidl_array<uint8_t, 6>& peer_address,
-	    bool joinExistingGroup, addGroup_1_2_cb _hidl_cb) override;
-	Return<void> setMacRandomization(
-	    bool enable, setMacRandomization_cb _hidl_cb) override;
-	Return<void> setEdmg(bool enable, setEdmg_cb _hidl_cb) override;
-	Return<void> getEdmg(getEdmg_cb _hidl_cb) override;
-	Return<void> registerCallback_1_4(
-	    const sp<V1_4::ISupplicantP2pIfaceCallback>& callback,
-	    registerCallback_1_4_cb _hidl_cb) override;
-	Return<void> setWfdR2DeviceInfo(
-	    const hidl_array<uint8_t, 4>& info,
-	    setWfdR2DeviceInfo_cb _hidl_cb) override;
-
-private:
-	// Corresponding worker functions for the HIDL methods.
-	std::pair<SupplicantStatus, std::string> getNameInternal();
-	std::pair<SupplicantStatus, IfaceType> getTypeInternal();
-	std::pair<SupplicantStatus, sp<ISupplicantP2pNetwork>>
-	addNetworkInternal();
-	SupplicantStatus removeNetworkInternal(SupplicantNetworkId id);
-	std::pair<SupplicantStatus, sp<ISupplicantP2pNetwork>>
-	getNetworkInternal(SupplicantNetworkId id);
-	std::pair<SupplicantStatus, std::vector<SupplicantNetworkId>>
-	listNetworksInternal();
-	SupplicantStatus registerCallbackInternal(
-	    const sp<ISupplicantP2pIfaceCallback>& callback);
-	std::pair<SupplicantStatus, std::array<uint8_t, 6>>
-	getDeviceAddressInternal();
-	SupplicantStatus setSsidPostfixInternal(
-	    const std::vector<uint8_t>& postfix);
-	SupplicantStatus setGroupIdleInternal(
-	    const std::string& group_ifname, uint32_t timeout_in_sec);
-	SupplicantStatus setPowerSaveInternal(
-	    const std::string& group_ifname, bool enable);
-	SupplicantStatus findInternal(uint32_t timeout_in_sec);
-	SupplicantStatus stopFindInternal();
-	SupplicantStatus flushInternal();
-	std::pair<SupplicantStatus, std::string> connectInternal(
-	    const std::array<uint8_t, 6>& peer_address,
-	    ISupplicantP2pIface::WpsProvisionMethod provision_method,
-	    const std::string& pre_selected_pin, bool join_existing_group,
-	    bool persistent, uint32_t go_intent);
-	SupplicantStatus cancelConnectInternal();
-	SupplicantStatus provisionDiscoveryInternal(
-	    const std::array<uint8_t, 6>& peer_address,
-	    ISupplicantP2pIface::WpsProvisionMethod provision_method);
-	SupplicantStatus addGroupInternal(
-	    bool persistent, SupplicantNetworkId persistent_network_id);
-	SupplicantStatus removeGroupInternal(const std::string& group_ifname);
-	SupplicantStatus rejectInternal(
-	    const std::array<uint8_t, 6>& peer_address);
-	SupplicantStatus inviteInternal(
-	    const std::string& group_ifname,
-	    const std::array<uint8_t, 6>& go_device_address,
-	    const std::array<uint8_t, 6>& peer_address);
-	SupplicantStatus reinvokeInternal(
-	    SupplicantNetworkId persistent_network_id,
-	    const std::array<uint8_t, 6>& peer_address);
-	SupplicantStatus configureExtListenInternal(
-	    uint32_t period_in_millis, uint32_t interval_in_millis);
-	SupplicantStatus setListenChannelInternal(
-	    uint32_t channel, uint32_t operating_class);
-	SupplicantStatus setDisallowedFrequenciesInternal(
-	    const std::vector<FreqRange>& ranges);
-	std::pair<SupplicantStatus, std::vector<uint8_t>> getSsidInternal(
-	    const std::array<uint8_t, 6>& peer_address);
-	std::pair<SupplicantStatus, uint32_t> getGroupCapabilityInternal(
-	    const std::array<uint8_t, 6>& peer_address);
-	SupplicantStatus addBonjourServiceInternal(
-	    const std::vector<uint8_t>& query,
-	    const std::vector<uint8_t>& response);
-	SupplicantStatus removeBonjourServiceInternal(
-	    const std::vector<uint8_t>& query);
-	SupplicantStatus addUpnpServiceInternal(
-	    uint32_t version, const std::string& service_name);
-	SupplicantStatus removeUpnpServiceInternal(
-	    uint32_t version, const std::string& service_name);
-	SupplicantStatus flushServicesInternal();
-	std::pair<SupplicantStatus, uint64_t> requestServiceDiscoveryInternal(
-	    const std::array<uint8_t, 6>& peer_address,
-	    const std::vector<uint8_t>& query);
-	SupplicantStatus cancelServiceDiscoveryInternal(uint64_t identifier);
-	SupplicantStatus setMiracastModeInternal(
-	    ISupplicantP2pIface::MiracastMode mode);
-	SupplicantStatus startWpsPbcInternal(
-	    const std::string& group_ifname,
-	    const std::array<uint8_t, 6>& bssid);
-	SupplicantStatus startWpsPinKeypadInternal(
-	    const std::string& group_ifname, const std::string& pin);
-	std::pair<SupplicantStatus, std::string> startWpsPinDisplayInternal(
-	    const std::string& group_ifname,
-	    const std::array<uint8_t, 6>& bssid);
-	SupplicantStatus cancelWpsInternal(const std::string& group_ifname);
-	SupplicantStatus setWpsDeviceNameInternal(const std::string& name);
-	SupplicantStatus setWpsDeviceTypeInternal(
-	    const std::array<uint8_t, 8>& type);
-	SupplicantStatus setWpsManufacturerInternal(
-	    const std::string& manufacturer);
-	SupplicantStatus setWpsModelNameInternal(const std::string& model_name);
-	SupplicantStatus setWpsModelNumberInternal(
-	    const std::string& model_number);
-	SupplicantStatus setWpsSerialNumberInternal(
-	    const std::string& serial_number);
-	SupplicantStatus setWpsConfigMethodsInternal(uint16_t config_methods);
-	SupplicantStatus enableWfdInternal(bool enable);
-	SupplicantStatus setWfdDeviceInfoInternal(
-	    const std::array<uint8_t, 6>& info);
-	std::pair<SupplicantStatus, std::vector<uint8_t>>
-	createNfcHandoverRequestMessageInternal();
-	std::pair<SupplicantStatus, std::vector<uint8_t>>
-	createNfcHandoverSelectMessageInternal();
-	SupplicantStatus reportNfcHandoverResponseInternal(
-	    const std::vector<uint8_t>& request);
-	SupplicantStatus reportNfcHandoverInitiationInternal(
-	    const std::vector<uint8_t>& select);
-	SupplicantStatus saveConfigInternal();
-	SupplicantStatus addGroup_1_2Internal(
-	    const std::vector<uint8_t>& ssid, const std::string& passphrase,
-	    bool persistent, uint32_t freq, const std::array<uint8_t, 6>& peer_address,
-	    bool joinExistingGroup);
-	SupplicantStatus setMacRandomizationInternal(bool enable);
-	V1_4::SupplicantStatus setEdmgInternal(bool enable);
-	std::pair<V1_4::SupplicantStatus, bool> getEdmgInternal();
-	V1_4::SupplicantStatus registerCallback_1_4Internal(
-	    const sp<V1_4::ISupplicantP2pIfaceCallback>& callback);
-	V1_4::SupplicantStatus setWfdR2DeviceInfoInternal(
-	    const std::array<uint8_t, 4>& info);
-
-	struct wpa_supplicant* retrieveIfacePtr();
-	struct wpa_supplicant* retrieveGroupIfacePtr(
-	    const std::string& group_ifname);
-
-	// Reference to the global wpa_struct. This is assumed to be valid for
-	// the lifetime of the process.
-	struct wpa_global* wpa_global_;
-	// Name of the iface this hidl object controls
-	const std::string ifname_;
-	bool is_valid_;
-
-	DISALLOW_COPY_AND_ASSIGN(P2pIface);
-};
-
-}  // namespace implementation
-}  // namespace V1_4
-}  // namespace supplicant
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WPA_SUPPLICANT_HIDL_P2P_IFACE_H
diff --git a/wpa_supplicant/hidl/1.4/p2p_network.cpp b/wpa_supplicant/hidl/1.4/p2p_network.cpp
deleted file mode 100644
index cba2fdd..0000000
--- a/wpa_supplicant/hidl/1.4/p2p_network.cpp
+++ /dev/null
@@ -1,257 +0,0 @@
-/*
- * hidl interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "hidl_manager.h"
-#include "hidl_return_util.h"
-#include "p2p_network.h"
-
-extern "C"
-{
-#include "config_ssid.h"
-}
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_4 {
-namespace implementation {
-using hidl_return_util::validateAndCall;
-using V1_0::SupplicantStatusCode;
-
-P2pNetwork::P2pNetwork(
-    struct wpa_global *wpa_global, const char ifname[], int network_id)
-    : wpa_global_(wpa_global),
-      ifname_(ifname),
-      network_id_(network_id),
-      is_valid_(true)
-{}
-
-void P2pNetwork::invalidate() { is_valid_ = false; }
-bool P2pNetwork::isValid()
-{
-	return (is_valid_ && (retrieveNetworkPtr() != nullptr));
-}
-
-Return<void> P2pNetwork::getId(getId_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &P2pNetwork::getIdInternal, _hidl_cb);
-}
-
-Return<void> P2pNetwork::getInterfaceName(getInterfaceName_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &P2pNetwork::getInterfaceNameInternal, _hidl_cb);
-}
-
-Return<void> P2pNetwork::getType(getType_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &P2pNetwork::getTypeInternal, _hidl_cb);
-}
-
-Return<void> P2pNetwork::registerCallback(
-    const sp<ISupplicantP2pNetworkCallback> &callback,
-    registerCallback_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &P2pNetwork::registerCallbackInternal, _hidl_cb, callback);
-}
-
-Return<void> P2pNetwork::getSsid(getSsid_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &P2pNetwork::getSsidInternal, _hidl_cb);
-}
-
-Return<void> P2pNetwork::getBssid(getBssid_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &P2pNetwork::getBssidInternal, _hidl_cb);
-}
-
-Return<void> P2pNetwork::isCurrent(isCurrent_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &P2pNetwork::isCurrentInternal, _hidl_cb);
-}
-
-Return<void> P2pNetwork::isPersistent(isPersistent_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &P2pNetwork::isPersistentInternal, _hidl_cb);
-}
-
-Return<void> P2pNetwork::isGo(isGo_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &P2pNetwork::isGoInternal, _hidl_cb);
-}
-
-Return<void> P2pNetwork::setClientList(
-    const hidl_vec<hidl_array<uint8_t, 6>> &clients, setClientList_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &P2pNetwork::setClientListInternal, _hidl_cb, clients);
-}
-
-Return<void> P2pNetwork::getClientList(getClientList_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &P2pNetwork::getClientListInternal, _hidl_cb);
-}
-
-std::pair<SupplicantStatus, uint32_t> P2pNetwork::getIdInternal()
-{
-	return {{SupplicantStatusCode::SUCCESS, ""}, network_id_};
-}
-
-std::pair<SupplicantStatus, std::string> P2pNetwork::getInterfaceNameInternal()
-{
-	return {{SupplicantStatusCode::SUCCESS, ""}, ifname_};
-}
-
-std::pair<SupplicantStatus, IfaceType> P2pNetwork::getTypeInternal()
-{
-	return {{SupplicantStatusCode::SUCCESS, ""}, IfaceType::P2P};
-}
-
-SupplicantStatus P2pNetwork::registerCallbackInternal(
-    const sp<ISupplicantP2pNetworkCallback> &callback)
-{
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager || hidl_manager->addP2pNetworkCallbackHidlObject(
-				 ifname_, network_id_, callback)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-std::pair<SupplicantStatus, std::vector<uint8_t>> P2pNetwork::getSsidInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		{wpa_ssid->ssid, wpa_ssid->ssid + wpa_ssid->ssid_len}};
-}
-
-std::pair<SupplicantStatus, std::array<uint8_t, 6>>
-P2pNetwork::getBssidInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	std::array<uint8_t, 6> bssid{};
-	if (wpa_ssid->bssid_set) {
-		os_memcpy(bssid.data(), wpa_ssid->bssid, ETH_ALEN);
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, bssid};
-}
-
-std::pair<SupplicantStatus, bool> P2pNetwork::isCurrentInternal()
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		(wpa_s->current_ssid == wpa_ssid)};
-}
-
-std::pair<SupplicantStatus, bool> P2pNetwork::isPersistentInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	return {{SupplicantStatusCode::SUCCESS, ""}, (wpa_ssid->disabled == 2)};
-}
-
-std::pair<SupplicantStatus, bool> P2pNetwork::isGoInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		(wpa_ssid->mode == wpas_mode::WPAS_MODE_P2P_GO)};
-}
-
-SupplicantStatus P2pNetwork::setClientListInternal(
-    const std::vector<hidl_array<uint8_t, 6>> &clients)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	os_free(wpa_ssid->p2p_client_list);
-	// Internal representation uses a generic MAC addr/mask storage format
-	// (even though the mask is always 0xFF'ed for p2p_client_list). So, the
-	// first 6 bytes holds the client MAC address and the next 6 bytes are
-	// OxFF'ed.
-	wpa_ssid->p2p_client_list =
-	    (u8 *)os_malloc(ETH_ALEN * 2 * clients.size());
-	if (!wpa_ssid->p2p_client_list) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	u8 *list = wpa_ssid->p2p_client_list;
-	for (const auto &client : clients) {
-		os_memcpy(list, client.data(), ETH_ALEN);
-		list += ETH_ALEN;
-		os_memset(list, 0xFF, ETH_ALEN);
-		list += ETH_ALEN;
-	}
-	wpa_ssid->num_p2p_clients = clients.size();
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-std::pair<SupplicantStatus, std::vector<hidl_array<uint8_t, 6>>>
-P2pNetwork::getClientListInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->p2p_client_list) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	std::vector<hidl_array<uint8_t, 6>> clients;
-	u8 *list = wpa_ssid->p2p_client_list;
-	for (size_t i = 0; i < wpa_ssid->num_p2p_clients; i++) {
-		clients.emplace_back(list);
-		list += 2 * ETH_ALEN;
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, clients};
-}
-
-/**
- * Retrieve the underlying |wpa_ssid| struct pointer for
- * this network.
- * If the underlying network is removed or the interface
- * this network belong to is removed, all RPC method calls
- * on this object will return failure.
- */
-struct wpa_ssid *P2pNetwork::retrieveNetworkPtr()
-{
-	wpa_supplicant *wpa_s = retrieveIfacePtr();
-	if (!wpa_s)
-		return nullptr;
-	return wpa_config_get_network(wpa_s->conf, network_id_);
-}
-
-/**
- * Retrieve the underlying |wpa_supplicant| struct
- * pointer for this network.
- */
-struct wpa_supplicant *P2pNetwork::retrieveIfacePtr()
-{
-	return wpa_supplicant_get_iface(
-	    (struct wpa_global *)wpa_global_, ifname_.c_str());
-}
-}  // namespace implementation
-}  // namespace V1_4
-}  // namespace supplicant
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wpa_supplicant/hidl/1.4/p2p_network.h b/wpa_supplicant/hidl/1.4/p2p_network.h
deleted file mode 100644
index 94e3763..0000000
--- a/wpa_supplicant/hidl/1.4/p2p_network.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * hidl interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WPA_SUPPLICANT_HIDL_P2P_NETWORK_H
-#define WPA_SUPPLICANT_HIDL_P2P_NETWORK_H
-
-#include <android-base/macros.h>
-
-#include <android/hardware/wifi/supplicant/1.0/ISupplicantP2pNetwork.h>
-#include <android/hardware/wifi/supplicant/1.0/ISupplicantP2pNetworkCallback.h>
-
-extern "C"
-{
-#include "utils/common.h"
-#include "utils/includes.h"
-#include "wpa_supplicant_i.h"
-}
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_4 {
-namespace implementation {
-using V1_0::ISupplicantP2pNetwork;
-using V1_0::ISupplicantP2pNetworkCallback;
-
-/**
- * Implementation of P2pNetwork hidl object. Each unique hidl
- * object is used for control operations on a specific network
- * controlled by wpa_supplicant.
- */
-class P2pNetwork : public ISupplicantP2pNetwork
-{
-public:
-	P2pNetwork(
-	    struct wpa_global* wpa_global, const char ifname[], int network_id);
-	~P2pNetwork() override = default;
-	// Refer to |StaIface::invalidate()|.
-	void invalidate();
-	bool isValid();
-
-	// Hidl methods exposed.
-	Return<void> getId(getId_cb _hidl_cb) override;
-	Return<void> getInterfaceName(getInterfaceName_cb _hidl_cb) override;
-	Return<void> getType(getType_cb _hidl_cb) override;
-	Return<void> registerCallback(
-	    const sp<ISupplicantP2pNetworkCallback>& callback,
-	    registerCallback_cb _hidl_cb) override;
-	Return<void> getSsid(getSsid_cb _hidl_cb) override;
-	Return<void> getBssid(getBssid_cb _hidl_cb) override;
-	Return<void> isCurrent(isCurrent_cb _hidl_cb) override;
-	Return<void> isPersistent(isPersistent_cb _hidl_cb) override;
-	Return<void> isGo(isGo_cb _hidl_cb) override;
-	Return<void> setClientList(
-	    const hidl_vec<hidl_array<uint8_t, 6>>& clients,
-	    setClientList_cb _hidl_cb) override;
-	Return<void> getClientList(getClientList_cb _hidl_cb) override;
-
-private:
-	// Corresponding worker functions for the HIDL methods.
-	std::pair<SupplicantStatus, uint32_t> getIdInternal();
-	std::pair<SupplicantStatus, std::string> getInterfaceNameInternal();
-	std::pair<SupplicantStatus, IfaceType> getTypeInternal();
-	SupplicantStatus registerCallbackInternal(
-	    const sp<ISupplicantP2pNetworkCallback>& callback);
-	std::pair<SupplicantStatus, std::vector<uint8_t>> getSsidInternal();
-	std::pair<SupplicantStatus, std::array<uint8_t, 6>> getBssidInternal();
-	std::pair<SupplicantStatus, bool> isCurrentInternal();
-	std::pair<SupplicantStatus, bool> isPersistentInternal();
-	std::pair<SupplicantStatus, bool> isGoInternal();
-	SupplicantStatus setClientListInternal(
-	    const std::vector<hidl_array<uint8_t, 6>>& clients);
-	std::pair<SupplicantStatus, std::vector<hidl_array<uint8_t, 6>>>
-	getClientListInternal();
-
-	struct wpa_ssid* retrieveNetworkPtr();
-	struct wpa_supplicant* retrieveIfacePtr();
-
-	// Reference to the global wpa_struct. This is assumed to be valid
-	// for the lifetime of the process.
-	const struct wpa_global* wpa_global_;
-	// Name of the iface this network belongs to.
-	const std::string ifname_;
-	// Id of the network this hidl object controls.
-	const int network_id_;
-	bool is_valid_;
-
-	DISALLOW_COPY_AND_ASSIGN(P2pNetwork);
-};
-
-}  // namespace implementation
-}  // namespace V1_4
-}  // namespace supplicant
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WPA_SUPPLICANT_HIDL_P2P_NETWORK_H
diff --git a/wpa_supplicant/hidl/1.4/sta_iface.cpp b/wpa_supplicant/hidl/1.4/sta_iface.cpp
deleted file mode 100644
index 1bf279e..0000000
--- a/wpa_supplicant/hidl/1.4/sta_iface.cpp
+++ /dev/null
@@ -1,1827 +0,0 @@
-/*
- * hidl interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "hidl_manager.h"
-#include "hidl_return_util.h"
-#include "iface_config_utils.h"
-#include "misc_utils.h"
-#include "sta_iface.h"
-
-extern "C"
-{
-#include "utils/eloop.h"
-#include "gas_query.h"
-#include "interworking.h"
-#include "hs20_supplicant.h"
-#include "wps_supplicant.h"
-#include "dpp.h"
-#include "dpp_supplicant.h"
-#include "rsn_supp/wpa.h"
-#include "rsn_supp/pmksa_cache.h"
-}
-
-namespace {
-using ISupplicantStaNetworkV1_2 =
-	android::hardware::wifi::supplicant::V1_2::ISupplicantStaNetwork;
-using ISupplicantStaNetworkV1_3 =
-	android::hardware::wifi::supplicant::V1_3::ISupplicantStaNetwork;
-using android::hardware::wifi::V1_0::WifiChannelWidthInMhz;
-using android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
-using android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
-using android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork;
-using android::hardware::wifi::supplicant::V1_3::WifiTechnology;
-using android::hardware::wifi::supplicant::V1_4::ISupplicantStaIface;
-using android::hardware::wifi::supplicant::V1_4::ConnectionCapabilities;
-using android::hardware::wifi::supplicant::V1_4::LegacyMode;
-using android::hardware::wifi::supplicant::V1_4::implementation::HidlManager;
-using android::hardware::wifi::supplicant::V1_4::DppResponderBootstrapInfo;
-using android::hardware::wifi::supplicant::V1_4::DppCurve;
-
-constexpr uint32_t kMaxAnqpElems = 100;
-constexpr char kGetMacAddress[] = "MACADDR";
-constexpr char kStartRxFilter[] = "RXFILTER-START";
-constexpr char kStopRxFilter[] = "RXFILTER-STOP";
-constexpr char kAddRxFilter[] = "RXFILTER-ADD";
-constexpr char kRemoveRxFilter[] = "RXFILTER-REMOVE";
-constexpr char kSetBtCoexistenceMode[] = "BTCOEXMODE";
-constexpr char kSetBtCoexistenceScanStart[] = "BTCOEXSCAN-START";
-constexpr char kSetBtCoexistenceScanStop[] = "BTCOEXSCAN-STOP";
-constexpr char kSetSupendModeEnabled[] = "SETSUSPENDMODE 1";
-constexpr char kSetSupendModeDisabled[] = "SETSUSPENDMODE 0";
-constexpr char kSetCountryCode[] = "COUNTRY";
-constexpr uint32_t kExtRadioWorkDefaultTimeoutInSec = static_cast<uint32_t>(
-    ISupplicantStaIface::ExtRadioWorkDefaults::TIMEOUT_IN_SECS);
-constexpr char kExtRadioWorkNamePrefix[] = "ext:";
-
-uint8_t convertHidlRxFilterTypeToInternal(
-    ISupplicantStaIface::RxFilterType type)
-{
-	switch (type) {
-	case ISupplicantStaIface::RxFilterType::V4_MULTICAST:
-		return 2;
-	case ISupplicantStaIface::RxFilterType::V6_MULTICAST:
-		return 3;
-	};
-	WPA_ASSERT(false);
-}
-
-uint8_t convertHidlBtCoexModeToInternal(
-    ISupplicantStaIface::BtCoexistenceMode mode)
-{
-	switch (mode) {
-	case ISupplicantStaIface::BtCoexistenceMode::ENABLED:
-		return 0;
-	case ISupplicantStaIface::BtCoexistenceMode::DISABLED:
-		return 1;
-	case ISupplicantStaIface::BtCoexistenceMode::SENSE:
-		return 2;
-	};
-	WPA_ASSERT(false);
-}
-
-SupplicantStatus doZeroArgDriverCommand(
-    struct wpa_supplicant *wpa_s, const char *cmd)
-{
-	std::vector<char> cmd_vec(cmd, cmd + strlen(cmd) + 1);
-	char driver_cmd_reply_buf[4096] = {};
-	if (wpa_drv_driver_cmd(
-		wpa_s, cmd_vec.data(), driver_cmd_reply_buf,
-		sizeof(driver_cmd_reply_buf))) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus doOneArgDriverCommand(
-    struct wpa_supplicant *wpa_s, const char *cmd, uint8_t arg)
-{
-	std::string cmd_str = std::string(cmd) + " " + std::to_string(arg);
-	return doZeroArgDriverCommand(wpa_s, cmd_str.c_str());
-}
-
-SupplicantStatus doOneArgDriverCommand(
-    struct wpa_supplicant *wpa_s, const char *cmd, const std::string &arg)
-{
-	std::string cmd_str = std::string(cmd) + " " + arg;
-	return doZeroArgDriverCommand(wpa_s, cmd_str.c_str());
-}
-
-void endExtRadioWork(struct wpa_radio_work *work)
-{
-	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
-	work->wpa_s->ext_work_in_progress = 0;
-	radio_work_done(work);
-	os_free(ework);
-}
-
-void extRadioWorkTimeoutCb(void *eloop_ctx, void *timeout_ctx)
-{
-	auto *work = static_cast<struct wpa_radio_work *>(eloop_ctx);
-	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
-	wpa_dbg(
-	    work->wpa_s, MSG_DEBUG, "Timing out external radio work %u (%s)",
-	    ework->id, work->type);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	WPA_ASSERT(hidl_manager);
-	hidl_manager->notifyExtRadioWorkTimeout(work->wpa_s, ework->id);
-
-	endExtRadioWork(work);
-}
-
-void startExtRadioWork(struct wpa_radio_work *work)
-{
-	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
-	work->wpa_s->ext_work_in_progress = 1;
-	if (!ework->timeout) {
-		ework->timeout = kExtRadioWorkDefaultTimeoutInSec;
-	}
-	eloop_register_timeout(
-	    ework->timeout, 0, extRadioWorkTimeoutCb, work, nullptr);
-}
-
-void extRadioWorkStartCb(struct wpa_radio_work *work, int deinit)
-{
-	// deinit==1 is invoked during interface removal. Since the HIDL
-	// interface does not support interface addition/removal, we don't
-	// need to handle this scenario.
-	WPA_ASSERT(!deinit);
-
-	auto *ework = static_cast<struct wpa_external_work *>(work->ctx);
-	wpa_dbg(
-	    work->wpa_s, MSG_DEBUG, "Starting external radio work %u (%s)",
-	    ework->id, ework->type);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	WPA_ASSERT(hidl_manager);
-	hidl_manager->notifyExtRadioWorkStart(work->wpa_s, ework->id);
-
-	startExtRadioWork(work);
-}
-
-uint32_t convertWpaKeyMgmtCapabilitiesToHidl (
-    struct wpa_supplicant *wpa_s, struct wpa_driver_capa *capa) {
-
-	uint32_t mask = 0;
-	/* Logic from ctrl_iface.c, NONE and IEEE8021X have no capability
-	 * flags and always enabled.
-	 */
-	mask |=
-	    (ISupplicantStaNetwork::KeyMgmtMask::NONE |
-	     ISupplicantStaNetwork::KeyMgmtMask::IEEE8021X);
-
-	if (capa->key_mgmt &
-	    (WPA_DRIVER_CAPA_KEY_MGMT_WPA | WPA_DRIVER_CAPA_KEY_MGMT_WPA2)) {
-		mask |= ISupplicantStaNetwork::KeyMgmtMask::WPA_EAP;
-	}
-
-	if (capa->key_mgmt & (WPA_DRIVER_CAPA_KEY_MGMT_WPA_PSK |
-			     WPA_DRIVER_CAPA_KEY_MGMT_WPA2_PSK)) {
-		mask |= ISupplicantStaNetwork::KeyMgmtMask::WPA_PSK;
-	}
-#ifdef CONFIG_SUITEB192
-	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_SUITE_B_192) {
-		mask |= ISupplicantStaNetworkV1_2::ISupplicantStaNetwork::KeyMgmtMask::SUITE_B_192;
-	}
-#endif /* CONFIG_SUITEB192 */
-#ifdef CONFIG_OWE
-	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_OWE) {
-		mask |= ISupplicantStaNetworkV1_2::ISupplicantStaNetwork::KeyMgmtMask::OWE;
-	}
-#endif /* CONFIG_OWE */
-#ifdef CONFIG_SAE
-	if (wpa_s->drv_flags & WPA_DRIVER_FLAGS_SAE) {
-		mask |= ISupplicantStaNetworkV1_2::ISupplicantStaNetwork::KeyMgmtMask::SAE;
-	}
-#endif /* CONFIG_SAE */
-#ifdef CONFIG_DPP
-	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_DPP) {
-		mask |= ISupplicantStaNetworkV1_2::ISupplicantStaNetwork::KeyMgmtMask::DPP;
-	}
-#endif
-#ifdef CONFIG_WAPI_INTERFACE
-	mask |= ISupplicantStaNetworkV1_3::ISupplicantStaNetwork::KeyMgmtMask::WAPI_PSK;
-	mask |= ISupplicantStaNetworkV1_3::ISupplicantStaNetwork::KeyMgmtMask::WAPI_CERT;
-#endif /* CONFIG_WAPI_INTERFACE */
-#ifdef CONFIG_FILS
-	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA256) {
-		mask |= ISupplicantStaNetworkV1_3::ISupplicantStaNetwork::KeyMgmtMask::FILS_SHA256;
-	}
-	if (capa->key_mgmt & WPA_DRIVER_CAPA_KEY_MGMT_FILS_SHA384) {
-		mask |= ISupplicantStaNetworkV1_3::ISupplicantStaNetwork::KeyMgmtMask::FILS_SHA384;
-	}
-#endif /* CONFIG_FILS */
-	return mask;
-}
-
-const std::string getDppListenChannel(struct wpa_supplicant *wpa_s, int32_t *listen_channel)
-{
-	struct hostapd_hw_modes *mode;
-	int chan44 = 0, chan149 = 0;
-	*listen_channel = 0;
-
-	/* Check if device support 2.4GHz band*/
-	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
-			HOSTAPD_MODE_IEEE80211G, 0);
-	if (mode) {
-		*listen_channel = 6;
-		return "81/6";
-	}
-	/* Check if device support 5GHz band */
-	mode = get_mode(wpa_s->hw.modes, wpa_s->hw.num_modes,
-			HOSTAPD_MODE_IEEE80211A, 0);
-	if (mode) {
-		for (int i = 0; i < mode->num_channels; i++) {
-			struct hostapd_channel_data *chan = &mode->channels[i];
-
-			if (chan->flag & (HOSTAPD_CHAN_DISABLED |
-					  HOSTAPD_CHAN_RADAR))
-				continue;
-			if (chan->freq == 5220)
-				chan44 = 1;
-			if (chan->freq == 5745)
-				chan149 = 1;
-		}
-		if (chan149) {
-			*listen_channel = 149;
-			return "124/149";
-		} else if (chan44) {
-			*listen_channel = 44;
-			return "115/44";
-		}
-	}
-
-	return "";
-}
-
-const std::string convertCurveTypeToName(DppCurve curve)
-{
-	switch (curve) {
-	case DppCurve::PRIME256V1:
-		return "prime256v1";
-	case DppCurve::SECP384R1:
-		return "secp384r1";
-	case DppCurve::SECP521R1:
-		return "secp521r1";
-	case DppCurve::BRAINPOOLP256R1:
-		return "brainpoolP256r1";
-	case DppCurve::BRAINPOOLP384R1:
-		return "brainpoolP384r1";
-	case DppCurve::BRAINPOOLP512R1:
-		return "brainpoolP512r1";
-	}
-	WPA_ASSERT(false);
-}
-
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_4 {
-namespace implementation {
-using hidl_return_util::validateAndCall;
-using V1_0::ISupplicantStaIfaceCallback;
-using V1_0::SupplicantStatusCode;
-
-StaIface::StaIface(struct wpa_global *wpa_global, const char ifname[])
-    : wpa_global_(wpa_global), ifname_(ifname), is_valid_(true)
-{}
-
-void StaIface::invalidate() { is_valid_ = false; }
-bool StaIface::isValid()
-{
-	return (is_valid_ && (retrieveIfacePtr() != nullptr));
-}
-
-Return<void> StaIface::getName(getName_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::getNameInternal, _hidl_cb);
-}
-
-Return<void> StaIface::getType(getType_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::getTypeInternal, _hidl_cb);
-}
-
-Return<void> StaIface::addNetwork(addNetwork_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::addNetworkInternal, _hidl_cb);
-}
-
-Return<void> StaIface::removeNetwork(
-    SupplicantNetworkId id, removeNetwork_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::removeNetworkInternal, _hidl_cb, id);
-}
-
-Return<void> StaIface::filsHlpFlushRequest(filsHlpFlushRequest_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::filsHlpFlushRequestInternal, _hidl_cb);
-}
-
-Return<void> StaIface::filsHlpAddRequest(
-    const hidl_array<uint8_t, 6> &dst_mac, const hidl_vec<uint8_t> &pkt,
-    filsHlpAddRequest_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::filsHlpAddRequestInternal, _hidl_cb, dst_mac, pkt);
-}
-
-Return<void> StaIface::getNetwork(
-    SupplicantNetworkId id, getNetwork_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::getNetworkInternal, _hidl_cb, id);
-}
-
-Return<void> StaIface::listNetworks(listNetworks_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::listNetworksInternal, _hidl_cb);
-}
-
-Return<void> StaIface::registerCallback(
-    const sp<ISupplicantStaIfaceCallback> &callback,
-    registerCallback_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::registerCallbackInternal, _hidl_cb, callback);
-}
-
-Return<void> StaIface::registerCallback_1_1(
-    const sp<V1_1::ISupplicantStaIfaceCallback> &callback,
-    registerCallback_cb _hidl_cb)
-{
-	sp<V1_0::ISupplicantStaIfaceCallback> callback_1_0 = callback;
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::registerCallbackInternal, _hidl_cb, callback_1_0);
-}
-
-Return<void> StaIface::registerCallback_1_2(
-    const sp<V1_2::ISupplicantStaIfaceCallback> &callback,
-    registerCallback_cb _hidl_cb)
-{
-	sp<V1_1::ISupplicantStaIfaceCallback> callback_1_1 = callback;
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::registerCallbackInternal, _hidl_cb, callback_1_1);
-}
-
-Return<void> StaIface::registerCallback_1_3(
-    const sp<V1_3::ISupplicantStaIfaceCallback> &callback,
-    registerCallback_cb _hidl_cb)
-{
-	sp<V1_3::ISupplicantStaIfaceCallback> callback_1_3 = callback;
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::registerCallbackInternal, _hidl_cb, callback_1_3);
-}
-
-Return<void> StaIface::registerCallback_1_4(
-    const sp<V1_4::ISupplicantStaIfaceCallback> &callback,
-    registerCallback_1_4_cb _hidl_cb)
-{
-	sp<V1_4::ISupplicantStaIfaceCallback> callback_1_4 = callback;
-	return validateAndCall(
-	    this, V1_4::SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::registerCallbackInternal_1_4, _hidl_cb, callback_1_4);
-}
-
-Return<void> StaIface::reassociate(reassociate_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::reassociateInternal, _hidl_cb);
-}
-
-Return<void> StaIface::reconnect(reconnect_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::reconnectInternal, _hidl_cb);
-}
-
-Return<void> StaIface::disconnect(disconnect_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::disconnectInternal, _hidl_cb);
-}
-
-Return<void> StaIface::setPowerSave(bool enable, setPowerSave_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::setPowerSaveInternal, _hidl_cb, enable);
-}
-
-Return<void> StaIface::initiateTdlsDiscover(
-    const hidl_array<uint8_t, 6> &mac_address, initiateTdlsDiscover_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::initiateTdlsDiscoverInternal, _hidl_cb, mac_address);
-}
-
-Return<void> StaIface::initiateTdlsSetup(
-    const hidl_array<uint8_t, 6> &mac_address, initiateTdlsSetup_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::initiateTdlsSetupInternal, _hidl_cb, mac_address);
-}
-
-Return<void> StaIface::initiateTdlsTeardown(
-    const hidl_array<uint8_t, 6> &mac_address, initiateTdlsTeardown_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::initiateTdlsTeardownInternal, _hidl_cb, mac_address);
-}
-Return<void> StaIface::initiateAnqpQuery(
-    const hidl_array<uint8_t, 6> &mac_address,
-    const hidl_vec<V1_0::ISupplicantStaIface::AnqpInfoId> &info_elements,
-    const hidl_vec<ISupplicantStaIface::Hs20AnqpSubtypes> &sub_types,
-    initiateAnqpQuery_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::initiateAnqpQueryInternal, _hidl_cb, mac_address,
-	    info_elements, sub_types);
-}
-
-Return<void> StaIface::initiateVenueUrlAnqpQuery(
-    const hidl_array<uint8_t, 6> &mac_address,
-	initiateVenueUrlAnqpQuery_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, V1_4::SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::initiateVenueUrlAnqpQueryInternal, _hidl_cb, mac_address);
-}
-
-Return<void> StaIface::initiateHs20IconQuery(
-    const hidl_array<uint8_t, 6> &mac_address, const hidl_string &file_name,
-    initiateHs20IconQuery_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::initiateHs20IconQueryInternal, _hidl_cb, mac_address,
-	    file_name);
-}
-
-Return<void> StaIface::getMacAddress(getMacAddress_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::getMacAddressInternal, _hidl_cb);
-}
-
-Return<void> StaIface::startRxFilter(startRxFilter_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::startRxFilterInternal, _hidl_cb);
-}
-
-Return<void> StaIface::stopRxFilter(stopRxFilter_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::stopRxFilterInternal, _hidl_cb);
-}
-
-Return<void> StaIface::addRxFilter(
-    ISupplicantStaIface::RxFilterType type, addRxFilter_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::addRxFilterInternal, _hidl_cb, type);
-}
-
-Return<void> StaIface::removeRxFilter(
-    ISupplicantStaIface::RxFilterType type, removeRxFilter_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::removeRxFilterInternal, _hidl_cb, type);
-}
-
-Return<void> StaIface::setBtCoexistenceMode(
-    ISupplicantStaIface::BtCoexistenceMode mode,
-    setBtCoexistenceMode_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::setBtCoexistenceModeInternal, _hidl_cb, mode);
-}
-
-Return<void> StaIface::setBtCoexistenceScanModeEnabled(
-    bool enable, setBtCoexistenceScanModeEnabled_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::setBtCoexistenceScanModeEnabledInternal, _hidl_cb,
-	    enable);
-}
-
-Return<void> StaIface::setSuspendModeEnabled(
-    bool enable, setSuspendModeEnabled_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::setSuspendModeEnabledInternal, _hidl_cb, enable);
-}
-
-Return<void> StaIface::setCountryCode(
-    const hidl_array<int8_t, 2> &code, setCountryCode_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::setCountryCodeInternal, _hidl_cb, code);
-}
-
-Return<void> StaIface::startWpsRegistrar(
-    const hidl_array<uint8_t, 6> &bssid, const hidl_string &pin,
-    startWpsRegistrar_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::startWpsRegistrarInternal, _hidl_cb, bssid, pin);
-}
-
-Return<void> StaIface::startWpsPbc(
-    const hidl_array<uint8_t, 6> &bssid, startWpsPbc_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::startWpsPbcInternal, _hidl_cb, bssid);
-}
-
-Return<void> StaIface::startWpsPinKeypad(
-    const hidl_string &pin, startWpsPinKeypad_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::startWpsPinKeypadInternal, _hidl_cb, pin);
-}
-
-Return<void> StaIface::startWpsPinDisplay(
-    const hidl_array<uint8_t, 6> &bssid, startWpsPinDisplay_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::startWpsPinDisplayInternal, _hidl_cb, bssid);
-}
-
-Return<void> StaIface::cancelWps(cancelWps_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::cancelWpsInternal, _hidl_cb);
-}
-
-Return<void> StaIface::setWpsDeviceName(
-    const hidl_string &name, setWpsDeviceName_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::setWpsDeviceNameInternal, _hidl_cb, name);
-}
-
-Return<void> StaIface::setWpsDeviceType(
-    const hidl_array<uint8_t, 8> &type, setWpsDeviceType_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::setWpsDeviceTypeInternal, _hidl_cb, type);
-}
-
-Return<void> StaIface::setWpsManufacturer(
-    const hidl_string &manufacturer, setWpsManufacturer_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::setWpsManufacturerInternal, _hidl_cb, manufacturer);
-}
-
-Return<void> StaIface::setWpsModelName(
-    const hidl_string &model_name, setWpsModelName_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::setWpsModelNameInternal, _hidl_cb, model_name);
-}
-
-Return<void> StaIface::setWpsModelNumber(
-    const hidl_string &model_number, setWpsModelNumber_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::setWpsModelNumberInternal, _hidl_cb, model_number);
-}
-
-Return<void> StaIface::setWpsSerialNumber(
-    const hidl_string &serial_number, setWpsSerialNumber_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::setWpsSerialNumberInternal, _hidl_cb, serial_number);
-}
-
-Return<void> StaIface::setWpsConfigMethods(
-    uint16_t config_methods, setWpsConfigMethods_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::setWpsConfigMethodsInternal, _hidl_cb, config_methods);
-}
-
-Return<void> StaIface::setExternalSim(
-    bool useExternalSim, setExternalSim_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::setExternalSimInternal, _hidl_cb, useExternalSim);
-}
-
-Return<void> StaIface::addExtRadioWork(
-    const hidl_string &name, uint32_t freq_in_mhz, uint32_t timeout_in_sec,
-    addExtRadioWork_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::addExtRadioWorkInternal, _hidl_cb, name, freq_in_mhz,
-	    timeout_in_sec);
-}
-
-Return<void> StaIface::removeExtRadioWork(
-    uint32_t id, removeExtRadioWork_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::removeExtRadioWorkInternal, _hidl_cb, id);
-}
-
-Return<void> StaIface::enableAutoReconnect(
-    bool enable, enableAutoReconnect_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::enableAutoReconnectInternal, _hidl_cb, enable);
-}
-
-Return<void> StaIface::getKeyMgmtCapabilities(
-    getKeyMgmtCapabilities_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaIface::getKeyMgmtCapabilitiesInternal, _hidl_cb);
-}
-
-Return<void> StaIface::addDppPeerUri(const hidl_string& uri,
-		addDppPeerUri_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaIface::addDppPeerUriInternal, _hidl_cb, uri);
-}
-
-Return<void> StaIface::removeDppUri(uint32_t bootstrap_id,
-		removeDppUri_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaIface::removeDppUriInternal, _hidl_cb, bootstrap_id);
-}
-
-Return<void> StaIface::startDppConfiguratorInitiator(uint32_t peer_bootstrap_id,
-		uint32_t own_bootstrap_id, const hidl_string& ssid,
-		const hidl_string& password, const hidl_string& psk,
-		DppNetRole net_role, DppAkm security_akm,
-		startDppConfiguratorInitiator_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaIface::startDppConfiguratorInitiatorInternal, _hidl_cb, peer_bootstrap_id,
-		own_bootstrap_id, ssid, password, psk, net_role, security_akm);
-}
-
-Return<void> StaIface::startDppEnrolleeInitiator(uint32_t peer_bootstrap_id,
-		uint32_t own_bootstrap_id, startDppConfiguratorInitiator_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaIface::startDppEnrolleeInitiatorInternal, _hidl_cb, peer_bootstrap_id,
-		own_bootstrap_id);
-}
-
-Return<void> StaIface::stopDppInitiator(stopDppInitiator_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaIface::stopDppInitiatorInternal, _hidl_cb);
-}
-
-Return<void> StaIface::generateDppBootstrapInfoForResponder(
-		const hidl_array<uint8_t, 6> &mac_address, const hidl_string& device_info,
-		DppCurve curve, generateDppBootstrapInfoForResponder_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, V1_4::SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::generateDppBootstrapInfoForResponderInternal, _hidl_cb, mac_address,
-	    device_info, curve);
-}
-
-Return<void> StaIface::startDppEnrolleeResponder(
-		uint32_t listen_channel, startDppEnrolleeResponder_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, V1_4::SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::startDppEnrolleeResponderInternal, _hidl_cb, listen_channel);
-}
-
-Return<void> StaIface::stopDppResponder(uint32_t own_bootstrap_id, stopDppResponder_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, V1_4::SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &StaIface::stopDppResponderInternal, _hidl_cb, own_bootstrap_id);
-}
-
-Return<void> StaIface::getWpaDriverCapabilities(
-		getWpaDriverCapabilities_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_UNKNOWN,
-	    &StaIface::getWpaDriverCapabilitiesInternal, _hidl_cb);
-}
-
-Return<void> StaIface::getWpaDriverCapabilities_1_4(
-		getWpaDriverCapabilities_1_4_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, V1_4::SupplicantStatusCode::FAILURE_UNKNOWN,
-	    &StaIface::getWpaDriverCapabilitiesInternal_1_4, _hidl_cb);
-}
-
-Return<void> StaIface::setMboCellularDataStatus(bool available,
-		setMboCellularDataStatus_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_UNKNOWN,
-	    &StaIface::setMboCellularDataStatusInternal, _hidl_cb, available);
-}
-
-Return<void> StaIface::getKeyMgmtCapabilities_1_3(
-    getKeyMgmtCapabilities_1_3_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaIface::getKeyMgmtCapabilitiesInternal_1_3, _hidl_cb);
-}
-
-std::pair<SupplicantStatus, std::string> StaIface::getNameInternal()
-{
-	return {{SupplicantStatusCode::SUCCESS, ""}, ifname_};
-}
-
-std::pair<SupplicantStatus, IfaceType> StaIface::getTypeInternal()
-{
-	return {{SupplicantStatusCode::SUCCESS, ""}, IfaceType::STA};
-}
-
-SupplicantStatus StaIface::filsHlpFlushRequestInternal()
-{
-#ifdef CONFIG_FILS
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-
-	wpas_flush_fils_hlp_req(wpa_s);
-	return {SupplicantStatusCode::SUCCESS, ""};
-#else /* CONFIG_FILS */
-	return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-#endif /* CONFIG_FILS */
-}
-
-SupplicantStatus StaIface::filsHlpAddRequestInternal(
-    const std::array<uint8_t, 6> &dst_mac, const std::vector<uint8_t> &pkt)
-{
-#ifdef CONFIG_FILS
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	struct fils_hlp_req *req;
-
-	if (!pkt.size())
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-
-
-	req = (struct fils_hlp_req *)os_zalloc(sizeof(*req));
-	if (!req)
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-
-	os_memcpy(req->dst, dst_mac.data(), ETH_ALEN);
-
-	req->pkt = wpabuf_alloc_copy(pkt.data(), pkt.size());
-	if (!req->pkt) {
-		os_free(req);
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-
-	dl_list_add_tail(&wpa_s->fils_hlp_req, &req->list);
-	return {SupplicantStatusCode::SUCCESS, ""};
-#else /* CONFIG_FILS */
-	return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-#endif /* CONFIG_FILS */
-}
-
-std::pair<SupplicantStatus, sp<ISupplicantNetwork>>
-StaIface::addNetworkInternal()
-{
-	android::sp<V1_3::ISupplicantStaNetwork> network;
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	struct wpa_ssid *ssid = wpa_supplicant_add_network(wpa_s);
-	if (!ssid) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
-	}
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager ||
-	    hidl_manager->getStaNetworkHidlObjectByIfnameAndNetworkId(
-		wpa_s->ifname, ssid->id, &network)) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, network};
-}
-
-Return<void> StaIface::getConnectionCapabilities(
-    getConnectionCapabilities_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_UNKNOWN,
-	    &StaIface::getConnectionCapabilitiesInternal, _hidl_cb);
-}
-
-Return<void> StaIface::getConnectionCapabilities_1_4(
-    getConnectionCapabilities_1_4_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, V1_4::SupplicantStatusCode::FAILURE_UNKNOWN,
-	    &StaIface::getConnectionCapabilitiesInternal_1_4, _hidl_cb);
-}
-
-SupplicantStatus StaIface::removeNetworkInternal(SupplicantNetworkId id)
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	int result = wpa_supplicant_remove_network(wpa_s, id);
-	if (result == -1) {
-		return {SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""};
-	}
-	if (result != 0) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-std::pair<SupplicantStatus, sp<ISupplicantNetwork>>
-StaIface::getNetworkInternal(SupplicantNetworkId id)
-{
-	android::sp<V1_3::ISupplicantStaNetwork> network;
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, id);
-	if (!ssid) {
-		return {{SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, ""},
-			network};
-	}
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager ||
-	    hidl_manager->getStaNetworkHidlObjectByIfnameAndNetworkId(
-		wpa_s->ifname, ssid->id, &network)) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, network};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, network};
-}
-
-std::pair<SupplicantStatus, std::vector<SupplicantNetworkId>>
-StaIface::listNetworksInternal()
-{
-	std::vector<SupplicantNetworkId> network_ids;
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	for (struct wpa_ssid *wpa_ssid = wpa_s->conf->ssid; wpa_ssid;
-	     wpa_ssid = wpa_ssid->next) {
-		network_ids.emplace_back(wpa_ssid->id);
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, std::move(network_ids)};
-}
-
-SupplicantStatus StaIface::registerCallbackInternal(
-    const sp<ISupplicantStaIfaceCallback> &callback)
-{
-	return {SupplicantStatusCode::FAILURE_UNKNOWN, "deprecated"};
-}
-
-V1_4::SupplicantStatus StaIface::registerCallbackInternal_1_4(
-    const sp<V1_4::ISupplicantStaIfaceCallback> &callback)
-{
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager ||
-	    hidl_manager->addStaIfaceCallbackHidlObject(ifname_, callback)) {
-		return {V1_4::SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {V1_4::SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaIface::reassociateInternal()
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
-		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
-	}
-	wpas_request_connection(wpa_s);
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaIface::reconnectInternal()
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
-		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
-	}
-	if (!wpa_s->disconnected) {
-		return {SupplicantStatusCode::FAILURE_IFACE_NOT_DISCONNECTED,
-			""};
-	}
-	wpas_request_connection(wpa_s);
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaIface::disconnectInternal()
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
-		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
-	}
-	wpas_request_disconnection(wpa_s);
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaIface::setPowerSaveInternal(bool enable)
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
-		return {SupplicantStatusCode::FAILURE_IFACE_DISABLED, ""};
-	}
-	if (wpa_drv_set_p2p_powersave(wpa_s, enable, -1, -1)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaIface::initiateTdlsDiscoverInternal(
-    const std::array<uint8_t, 6> &mac_address)
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	int ret;
-	const u8 *peer = mac_address.data();
-	if (wpa_tdls_is_external_setup(wpa_s->wpa)) {
-		ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer);
-	} else {
-		ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
-	}
-	if (ret) {
-		wpa_printf(MSG_INFO, "StaIface: TDLS discover failed: %d", ret);
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaIface::initiateTdlsSetupInternal(
-    const std::array<uint8_t, 6> &mac_address)
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	int ret;
-	const u8 *peer = mac_address.data();
-	if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
-	    !(wpa_s->conf->tdls_external_control)) {
-		wpa_tdls_remove(wpa_s->wpa, peer);
-		ret = wpa_tdls_start(wpa_s->wpa, peer);
-	} else {
-		ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
-	}
-	if (ret) {
-		wpa_printf(MSG_INFO, "StaIface: TDLS setup failed: %d", ret);
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaIface::initiateTdlsTeardownInternal(
-    const std::array<uint8_t, 6> &mac_address)
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	int ret;
-	const u8 *peer = mac_address.data();
-	if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
-	    !(wpa_s->conf->tdls_external_control)) {
-		ret = wpa_tdls_teardown_link(
-		    wpa_s->wpa, peer, WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
-	} else {
-		ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
-	}
-	if (ret) {
-		wpa_printf(MSG_INFO, "StaIface: TDLS teardown failed: %d", ret);
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaIface::initiateAnqpQueryInternal(
-    const std::array<uint8_t, 6> &mac_address,
-    const std::vector<ISupplicantStaIface::AnqpInfoId> &info_elements,
-    const std::vector<ISupplicantStaIface::Hs20AnqpSubtypes> &sub_types)
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	if (info_elements.size() > kMaxAnqpElems) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	uint16_t info_elems_buf[kMaxAnqpElems];
-	uint32_t num_info_elems = 0;
-	for (const auto &info_element : info_elements) {
-		info_elems_buf[num_info_elems++] =
-		    static_cast<std::underlying_type<
-			ISupplicantStaIface::AnqpInfoId>::type>(info_element);
-	}
-	uint32_t sub_types_bitmask = 0;
-	for (const auto &type : sub_types) {
-		sub_types_bitmask |= BIT(
-		    static_cast<std::underlying_type<
-			ISupplicantStaIface::Hs20AnqpSubtypes>::type>(type));
-	}
-
-	if (anqp_send_req(
-		wpa_s, mac_address.data(), 0, info_elems_buf, num_info_elems,
-		sub_types_bitmask, 0)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-V1_4::SupplicantStatus StaIface::initiateVenueUrlAnqpQueryInternal(
-    const std::array<uint8_t, 6> &mac_address)
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	uint16_t info_elems_buf[1] = {ANQP_VENUE_URL};
-
-	if (anqp_send_req(
-		wpa_s, mac_address.data(), 0, info_elems_buf, 1, 0, 0)) {
-		return {V1_4::SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {V1_4::SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaIface::initiateHs20IconQueryInternal(
-    const std::array<uint8_t, 6> &mac_address, const std::string &file_name)
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	wpa_s->fetch_osu_icon_in_progress = 0;
-	if (hs20_anqp_send_req(
-		wpa_s, mac_address.data(), BIT(HS20_STYPE_ICON_REQUEST),
-		reinterpret_cast<const uint8_t *>(file_name.c_str()),
-		file_name.size(), true)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-std::pair<SupplicantStatus, std::array<uint8_t, 6>>
-StaIface::getMacAddressInternal()
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	std::vector<char> cmd(
-	    kGetMacAddress, kGetMacAddress + sizeof(kGetMacAddress));
-	char driver_cmd_reply_buf[4096] = {};
-	int ret = wpa_drv_driver_cmd(
-	    wpa_s, cmd.data(), driver_cmd_reply_buf,
-	    sizeof(driver_cmd_reply_buf));
-	// Reply is of the format: "Macaddr = XX:XX:XX:XX:XX:XX"
-	std::string reply_str = driver_cmd_reply_buf;
-	if (ret < 0 || reply_str.empty() ||
-	    reply_str.find("=") == std::string::npos) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	// Remove all whitespace first and then split using the delimiter "=".
-	reply_str.erase(
-	    remove_if(reply_str.begin(), reply_str.end(), isspace),
-	    reply_str.end());
-	std::string mac_addr_str =
-	    reply_str.substr(reply_str.find("=") + 1, reply_str.size());
-	std::array<uint8_t, 6> mac_addr;
-	if (hwaddr_aton(mac_addr_str.c_str(), mac_addr.data())) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, mac_addr};
-}
-
-SupplicantStatus StaIface::startRxFilterInternal()
-{
-	return doZeroArgDriverCommand(retrieveIfacePtr(), kStartRxFilter);
-}
-
-SupplicantStatus StaIface::stopRxFilterInternal()
-{
-	return doZeroArgDriverCommand(retrieveIfacePtr(), kStopRxFilter);
-}
-
-SupplicantStatus StaIface::addRxFilterInternal(
-    ISupplicantStaIface::RxFilterType type)
-{
-	return doOneArgDriverCommand(
-	    retrieveIfacePtr(), kAddRxFilter,
-	    convertHidlRxFilterTypeToInternal(type));
-}
-
-SupplicantStatus StaIface::removeRxFilterInternal(
-    ISupplicantStaIface::RxFilterType type)
-{
-	return doOneArgDriverCommand(
-	    retrieveIfacePtr(), kRemoveRxFilter,
-	    convertHidlRxFilterTypeToInternal(type));
-}
-
-SupplicantStatus StaIface::setBtCoexistenceModeInternal(
-    ISupplicantStaIface::BtCoexistenceMode mode)
-{
-	return doOneArgDriverCommand(
-	    retrieveIfacePtr(), kSetBtCoexistenceMode,
-	    convertHidlBtCoexModeToInternal(mode));
-}
-
-SupplicantStatus StaIface::setBtCoexistenceScanModeEnabledInternal(bool enable)
-{
-	const char *cmd;
-	if (enable) {
-		cmd = kSetBtCoexistenceScanStart;
-	} else {
-		cmd = kSetBtCoexistenceScanStop;
-	}
-	return doZeroArgDriverCommand(retrieveIfacePtr(), cmd);
-}
-
-SupplicantStatus StaIface::setSuspendModeEnabledInternal(bool enable)
-{
-	const char *cmd;
-	if (enable) {
-		cmd = kSetSupendModeEnabled;
-	} else {
-		cmd = kSetSupendModeDisabled;
-	}
-	return doZeroArgDriverCommand(retrieveIfacePtr(), cmd);
-}
-
-SupplicantStatus StaIface::setCountryCodeInternal(
-    const std::array<int8_t, 2> &code)
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	SupplicantStatus status = doOneArgDriverCommand(
-	    wpa_s, kSetCountryCode,
-	    std::string(std::begin(code), std::end(code)));
-	if (status.code != SupplicantStatusCode::SUCCESS) {
-		return status;
-	}
-	struct p2p_data *p2p = wpa_s->global->p2p;
-	if (p2p) {
-		char country[3];
-		country[0] = code[0];
-		country[1] = code[1];
-		country[2] = 0x04;
-		p2p_set_country(p2p, country);
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaIface::startWpsRegistrarInternal(
-    const std::array<uint8_t, 6> &bssid, const std::string &pin)
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	if (wpas_wps_start_reg(wpa_s, bssid.data(), pin.c_str(), nullptr)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaIface::startWpsPbcInternal(
-    const std::array<uint8_t, 6> &bssid)
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	const uint8_t *bssid_addr =
-	    is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
-	if (wpas_wps_start_pbc(wpa_s, bssid_addr, 0, 0)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaIface::startWpsPinKeypadInternal(const std::string &pin)
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	if (wpas_wps_start_pin(
-		wpa_s, nullptr, pin.c_str(), 0, DEV_PW_DEFAULT)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-std::pair<SupplicantStatus, std::string> StaIface::startWpsPinDisplayInternal(
-    const std::array<uint8_t, 6> &bssid)
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	const uint8_t *bssid_addr =
-	    is_zero_ether_addr(bssid.data()) ? nullptr : bssid.data();
-	int pin =
-	    wpas_wps_start_pin(wpa_s, bssid_addr, nullptr, 0, DEV_PW_DEFAULT);
-	if (pin < 0) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, ""};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		misc_utils::convertWpsPinToString(pin)};
-}
-
-SupplicantStatus StaIface::cancelWpsInternal()
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	if (wpas_wps_cancel(wpa_s)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaIface::setWpsDeviceNameInternal(const std::string &name)
-{
-	return iface_config_utils::setWpsDeviceName(retrieveIfacePtr(), name);
-}
-
-SupplicantStatus StaIface::setWpsDeviceTypeInternal(
-    const std::array<uint8_t, 8> &type)
-{
-	return iface_config_utils::setWpsDeviceType(retrieveIfacePtr(), type);
-}
-
-SupplicantStatus StaIface::setWpsManufacturerInternal(
-    const std::string &manufacturer)
-{
-	return iface_config_utils::setWpsManufacturer(
-	    retrieveIfacePtr(), manufacturer);
-}
-
-SupplicantStatus StaIface::setWpsModelNameInternal(
-    const std::string &model_name)
-{
-	return iface_config_utils::setWpsModelName(
-	    retrieveIfacePtr(), model_name);
-}
-
-SupplicantStatus StaIface::setWpsModelNumberInternal(
-    const std::string &model_number)
-{
-	return iface_config_utils::setWpsModelNumber(
-	    retrieveIfacePtr(), model_number);
-}
-
-SupplicantStatus StaIface::setWpsSerialNumberInternal(
-    const std::string &serial_number)
-{
-	return iface_config_utils::setWpsSerialNumber(
-	    retrieveIfacePtr(), serial_number);
-}
-
-SupplicantStatus StaIface::setWpsConfigMethodsInternal(uint16_t config_methods)
-{
-	return iface_config_utils::setWpsConfigMethods(
-	    retrieveIfacePtr(), config_methods);
-}
-
-SupplicantStatus StaIface::setExternalSimInternal(bool useExternalSim)
-{
-	return iface_config_utils::setExternalSim(
-	    retrieveIfacePtr(), useExternalSim);
-}
-
-std::pair<SupplicantStatus, uint32_t> StaIface::addExtRadioWorkInternal(
-    const std::string &name, uint32_t freq_in_mhz, uint32_t timeout_in_sec)
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	auto *ework = static_cast<struct wpa_external_work *>(
-	    os_zalloc(sizeof(struct wpa_external_work)));
-	if (!ework) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""},
-			UINT32_MAX};
-	}
-
-	std::string radio_work_name = kExtRadioWorkNamePrefix + name;
-	os_strlcpy(ework->type, radio_work_name.c_str(), sizeof(ework->type));
-	ework->timeout = timeout_in_sec;
-	wpa_s->ext_work_id++;
-	if (wpa_s->ext_work_id == 0) {
-		wpa_s->ext_work_id++;
-	}
-	ework->id = wpa_s->ext_work_id;
-
-	if (radio_add_work(
-		wpa_s, freq_in_mhz, ework->type, 0, extRadioWorkStartCb,
-		ework)) {
-		os_free(ework);
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""},
-			UINT32_MAX};
-	}
-	return {SupplicantStatus{SupplicantStatusCode::SUCCESS, ""}, ework->id};
-}
-
-SupplicantStatus StaIface::removeExtRadioWorkInternal(uint32_t id)
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	struct wpa_radio_work *work;
-	dl_list_for_each(work, &wpa_s->radio->work, struct wpa_radio_work, list)
-	{
-		if (os_strncmp(
-			work->type, kExtRadioWorkNamePrefix,
-			sizeof(kExtRadioWorkNamePrefix)) != 0)
-			continue;
-
-		auto *ework =
-		    static_cast<struct wpa_external_work *>(work->ctx);
-		if (ework->id != id)
-			continue;
-
-		wpa_dbg(
-		    wpa_s, MSG_DEBUG, "Completed external radio work %u (%s)",
-		    ework->id, ework->type);
-		eloop_cancel_timeout(extRadioWorkTimeoutCb, work, NULL);
-		endExtRadioWork(work);
-
-		return {SupplicantStatusCode::SUCCESS, ""};
-	}
-	return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-}
-
-SupplicantStatus StaIface::enableAutoReconnectInternal(bool enable)
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	wpa_s->auto_reconnect_disabled = enable ? 0 : 1;
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-std::pair<SupplicantStatus, uint32_t>
-StaIface::getKeyMgmtCapabilitiesInternal()
-{
-	return {{SupplicantStatusCode::FAILURE_UNKNOWN, "deprecated"}, 0};
-}
-
-std::pair<SupplicantStatus, uint32_t>
-StaIface::addDppPeerUriInternal(const std::string& uri)
-{
-#ifdef CONFIG_DPP
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	int32_t id;
-
-	id = wpas_dpp_qr_code(wpa_s, uri.c_str());
-
-	if (id > 0) {
-		return {{SupplicantStatusCode::SUCCESS, ""}, id};
-	}
-#endif
-	return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, -1};
-}
-
-SupplicantStatus StaIface::removeDppUriInternal(uint32_t bootstrap_id)
-{
-#ifdef CONFIG_DPP
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	std::string bootstrap_id_str;
-
-	if (bootstrap_id == 0) {
-		bootstrap_id_str = "*";
-	}
-	else {
-		bootstrap_id_str = std::to_string(bootstrap_id);
-	}
-
-	if (dpp_bootstrap_remove(wpa_s->dpp, bootstrap_id_str.c_str()) >= 0) {
-		return {SupplicantStatusCode::SUCCESS, ""};
-	}
-#endif
-	return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-}
-
-SupplicantStatus StaIface::startDppConfiguratorInitiatorInternal(
-		uint32_t peer_bootstrap_id,	uint32_t own_bootstrap_id,
-		const std::string& ssid, const std::string& password,
-		const std::string& psk, DppNetRole net_role, DppAkm security_akm)
-{
-#ifdef CONFIG_DPP
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	std::string cmd = "";
-
-	if (net_role != DppNetRole::AP &&
-			net_role != DppNetRole::STA) {
-		wpa_printf(MSG_ERROR,
-			   "DPP: Error: Invalid network role specified: %d", net_role);
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-
-	cmd += " peer=" + std::to_string(peer_bootstrap_id);
-	cmd += (own_bootstrap_id > 0) ?
-			" own=" + std::to_string(own_bootstrap_id) : "";
-
-	/* Check for supported AKMs */
-	if (security_akm != DppAkm::PSK && security_akm != DppAkm::SAE &&
-			security_akm != DppAkm::PSK_SAE) {
-		wpa_printf(MSG_ERROR, "DPP: Error: invalid AKM specified: %d",
-				security_akm);
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-
-	/* SAE AKM requires SSID and password to be initialized */
-	if ((security_akm == DppAkm::SAE ||
-			security_akm == DppAkm::PSK_SAE) &&
-			(ssid.empty() || password.empty())) {
-		wpa_printf(MSG_ERROR, "DPP: Error: Password or SSID not specified");
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	} else if (security_akm == DppAkm::PSK ||
-			security_akm == DppAkm::PSK_SAE) {
-		/* PSK AKM requires SSID and password/psk to be initialized */
-		if (ssid.empty()) {
-			wpa_printf(MSG_ERROR, "DPP: Error: SSID not specified");
-			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-		}
-		if (password.empty() && psk.empty()) {
-			wpa_printf(MSG_ERROR, "DPP: Error: Password or PSK not specified");
-			return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-		}
-	}
-
-	cmd += " role=configurator";
-	cmd += (ssid.empty()) ? "" : " ssid=" + ssid;
-
-	if (!psk.empty()) {
-		cmd += " psk=" + psk;
-	} else {
-		cmd += (password.empty()) ? "" : " pass=" + password;
-	}
-
-	std::string role = "";
-	if (net_role == DppNetRole::AP) {
-		role = "ap-";
-	}
-	else {
-		role = "sta-";
-	}
-
-	switch (security_akm) {
-	case DppAkm::PSK:
-		role += "psk";
-		break;
-
-	case DppAkm::SAE:
-		role += "sae";
-		break;
-
-	case DppAkm::PSK_SAE:
-		role += "psk-sae";
-		break;
-
-	default:
-		wpa_printf(MSG_ERROR,
-			   "DPP: Invalid or unsupported security AKM specified: %d", security_akm);
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-
-	cmd += " conf=";
-	cmd += role;
-
-	if (net_role == DppNetRole::STA) {
-		/* DPP R2 connection status request */
-		cmd += " conn_status=1";
-	}
-
-	wpa_printf(MSG_DEBUG,
-		   "DPP initiator command: %s", cmd.c_str());
-
-	if (wpas_dpp_auth_init(wpa_s, cmd.c_str()) == 0) {
-		return {SupplicantStatusCode::SUCCESS, ""};
-	}
-#endif
-	return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-}
-
-SupplicantStatus StaIface::startDppEnrolleeInitiatorInternal(uint32_t peer_bootstrap_id,
-			uint32_t own_bootstrap_id) {
-#ifdef CONFIG_DPP
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	std::string cmd = "";
-
-	/* Report received configuration to HIDL and create an internal profile */
-	wpa_s->conf->dpp_config_processing = 1;
-
-	cmd += " peer=" + std::to_string(peer_bootstrap_id);
-	cmd += (own_bootstrap_id > 0) ?
-			" own=" + std::to_string(own_bootstrap_id) : "";
-
-	cmd += " role=enrollee";
-
-	wpa_printf(MSG_DEBUG,
-		   "DPP initiator command: %s", cmd.c_str());
-
-	if (wpas_dpp_auth_init(wpa_s, cmd.c_str()) == 0) {
-		return {SupplicantStatusCode::SUCCESS, ""};
-	}
-#endif
-	return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-}
-SupplicantStatus StaIface::stopDppInitiatorInternal()
-{
-#ifdef CONFIG_DPP
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-
-	wpas_dpp_stop(wpa_s);
-	return {SupplicantStatusCode::SUCCESS, ""};
-#else
-	return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-#endif
-}
-
-std::pair<V1_4::SupplicantStatus, DppResponderBootstrapInfo>
-StaIface::generateDppBootstrapInfoForResponderInternal(const std::array<uint8_t, 6> &mac_address,
-		const std::string& device_info, DppCurve curve)
-{
-#ifdef CONFIG_DPP
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	std::string cmd = "type=qrcode";
-	int32_t id;
-	int32_t listen_channel = 0;
-	struct DppResponderBootstrapInfo bootstrap_info;
-	const char *uri;
-	std::string listen_channel_str;
-	std::string mac_addr_str;
-	char buf[3] = {0};
-
-	cmd += (device_info.empty()) ? "" : " info=" + device_info;
-
-	listen_channel_str = getDppListenChannel(wpa_s, &listen_channel);
-	if (listen_channel == 0) {
-		wpa_printf(MSG_ERROR, "StaIface: Failed to derive DPP listen channel");
-		return {{V1_4::SupplicantStatusCode::FAILURE_UNKNOWN, ""}, bootstrap_info};
-	}
-	cmd += " chan=" + listen_channel_str;
-
-	cmd += " mac=";
-	for (int i = 0;i < 6;i++) {
-		snprintf(buf, sizeof(buf), "%02x", mac_address[i]);
-		mac_addr_str.append(buf);
-	}
-	cmd += mac_addr_str;
-
-	cmd += " curve=" + convertCurveTypeToName(curve);
-
-	id = dpp_bootstrap_gen(wpa_s->dpp, cmd.c_str());
-	wpa_printf(MSG_DEBUG,
-		   "DPP generate bootstrap QR code command: %s id: %d", cmd.c_str(), id);
-	if (id > 0) {
-		uri = dpp_bootstrap_get_uri(wpa_s->dpp, id);
-		if (uri) {
-			wpa_printf(MSG_DEBUG, "DPP Bootstrap info: id: %d "
-				   "listen_channel: %d uri: %s", id, listen_channel, uri);
-			bootstrap_info.bootstrapId = id;
-			bootstrap_info.listenChannel = listen_channel;
-			bootstrap_info.uri = uri;
-			return {{V1_4::SupplicantStatusCode::SUCCESS, ""}, bootstrap_info};
-		}
-	}
-	return {{V1_4::SupplicantStatusCode::FAILURE_UNKNOWN, ""}, bootstrap_info};
-#else
-	return {{V1_4::SupplicantStatusCode::FAILURE_UNSUPPORTED, ""}, bootstrap_info};
-#endif
-}
-
-V1_4::SupplicantStatus StaIface::startDppEnrolleeResponderInternal(uint32_t listen_channel)
-{
-#ifdef CONFIG_DPP
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	std::string cmd = "";
-	uint32_t freq = (listen_channel <= 14 ? 2407 : 5000) + listen_channel * 5;
-
-	/* Report received configuration to HIDL and create an internal profile */
-	wpa_s->conf->dpp_config_processing = 1;
-
-	cmd += std::to_string(freq);
-	cmd += " role=enrollee netrole=sta";
-
-	wpa_printf(MSG_DEBUG,
-		   "DPP Enrollee Responder command: %s", cmd.c_str());
-
-	if (wpas_dpp_listen(wpa_s, cmd.c_str()) == 0) {
-		return {V1_4::SupplicantStatusCode::SUCCESS, ""};
-	}
-	return {V1_4::SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-#else
-	return {V1_4::SupplicantStatusCode::FAILURE_UNSUPPORTED, ""};
-#endif
-}
-
-V1_4::SupplicantStatus StaIface::stopDppResponderInternal(uint32_t own_bootstrap_id)
-{
-#ifdef CONFIG_DPP
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	std::string bootstrap_id_str;
-
-	if (own_bootstrap_id == 0) {
-		bootstrap_id_str = "*";
-	}
-	else {
-		bootstrap_id_str = std::to_string(own_bootstrap_id);
-	}
-
-	wpa_printf(MSG_DEBUG, "DPP Stop DPP Responder id: %d ", own_bootstrap_id);
-	wpas_dpp_stop(wpa_s);
-	wpas_dpp_listen_stop(wpa_s);
-
-	if (dpp_bootstrap_remove(wpa_s->dpp, bootstrap_id_str.c_str()) < 0) {
-		wpa_printf(MSG_ERROR, "StaIface: dpp_bootstrap_remove failed");
-	}
-
-	return {V1_4::SupplicantStatusCode::SUCCESS, ""};
-#else
-	return {V1_4::SupplicantStatusCode::FAILURE_UNSUPPORTED, ""};
-#endif
-}
-
-std::pair<SupplicantStatus, android::hardware::wifi::supplicant::V1_3::ConnectionCapabilities>
-StaIface::getConnectionCapabilitiesInternal()
-{
-  struct android::hardware::wifi::supplicant::V1_3::ConnectionCapabilities capa;
-	return {{SupplicantStatusCode::FAILURE_UNKNOWN, "deprecated"}, capa};
-}
-
-std::pair<V1_4::SupplicantStatus, ConnectionCapabilities>
-StaIface::getConnectionCapabilitiesInternal_1_4()
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	struct ConnectionCapabilities capa;
-
-	if (wpa_s->connection_set) {
-		capa.legacyMode = LegacyMode::UNKNOWN;
-		if (wpa_s->connection_he) {
-			capa.V1_3.technology = WifiTechnology::HE;
-		} else if (wpa_s->connection_vht) {
-			capa.V1_3.technology = WifiTechnology::VHT;
-		} else if (wpa_s->connection_ht) {
-			capa.V1_3.technology = WifiTechnology::HT;
-		} else {
-			capa.V1_3.technology = WifiTechnology::LEGACY;
-			if (wpas_freq_to_band(wpa_s->assoc_freq) == BAND_2_4_GHZ) {
-				capa.legacyMode = (wpa_s->connection_11b_only) ? LegacyMode::B_MODE
-						: LegacyMode::G_MODE; 
-			} else {
-				capa.legacyMode = LegacyMode::A_MODE;
-			}
-		}
-		switch (wpa_s->connection_channel_bandwidth) {
-		case CHAN_WIDTH_20:
-			capa.V1_3.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
-			break;
-		case CHAN_WIDTH_40:
-			capa.V1_3.channelBandwidth = WifiChannelWidthInMhz::WIDTH_40;
-			break;
-		case CHAN_WIDTH_80:
-			capa.V1_3.channelBandwidth = WifiChannelWidthInMhz::WIDTH_80;
-			break;
-		case CHAN_WIDTH_160:
-			capa.V1_3.channelBandwidth = WifiChannelWidthInMhz::WIDTH_160;
-			break;
-		case CHAN_WIDTH_80P80:
-			capa.V1_3.channelBandwidth = WifiChannelWidthInMhz::WIDTH_80P80;
-			break;
-		default:
-			capa.V1_3.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
-			break;
-		}
-		capa.V1_3.maxNumberRxSpatialStreams = wpa_s->connection_max_nss_rx;
-		capa.V1_3.maxNumberTxSpatialStreams = wpa_s->connection_max_nss_tx;
-	} else {
-		capa.V1_3.technology = WifiTechnology::UNKNOWN;
-		capa.V1_3.channelBandwidth = WifiChannelWidthInMhz::WIDTH_20;
-		capa.V1_3.maxNumberTxSpatialStreams = 1;
-		capa.V1_3.maxNumberRxSpatialStreams = 1;
-		capa.legacyMode = LegacyMode::UNKNOWN;
-	}
-	return {{V1_4::SupplicantStatusCode::SUCCESS, ""}, capa};
-}
-
-std::pair<SupplicantStatus, uint32_t>
-StaIface::getWpaDriverCapabilitiesInternal()
-{
-	return {{SupplicantStatusCode::FAILURE_UNKNOWN, "deprecated"}, 0};
-}
-
-std::pair<V1_4::SupplicantStatus, uint32_t>
-StaIface::getWpaDriverCapabilitiesInternal_1_4()
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	uint32_t mask = 0;
-
-#ifdef CONFIG_MBO
-	/* MBO has no capability flags. It's mainly legacy 802.11v BSS
-	 * transition + Cellular steering. 11v is a default feature in
-	 * supplicant. And cellular steering is handled in framework.
-	 */
-	mask |= V1_3::WpaDriverCapabilitiesMask::MBO;
-	if (wpa_s->enable_oce & OCE_STA) {
-		mask |= V1_3::WpaDriverCapabilitiesMask::OCE;
-	}
-#endif
-#ifdef CONFIG_SAE_PK
-	mask |= V1_4::WpaDriverCapabilitiesMask::SAE_PK;
-#endif
-	mask |= V1_4::WpaDriverCapabilitiesMask::WFD_R2;
-
-	wpa_printf(MSG_DEBUG, "Driver capability mask: 0x%x", mask);
-
-	return {{V1_4::SupplicantStatusCode::SUCCESS, ""}, mask};
-}
-
-SupplicantStatus StaIface::setMboCellularDataStatusInternal(bool available)
-{
-#ifdef CONFIG_MBO
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	enum mbo_cellular_capa mbo_cell_capa;
-
-	if (available) {
-		mbo_cell_capa = MBO_CELL_CAPA_AVAILABLE;
-	} else {
-		mbo_cell_capa = MBO_CELL_CAPA_NOT_AVAILABLE;
-	}
-
-#ifdef ENABLE_PRIV_CMD_UPDATE_MBO_CELL_STATUS
-	char mbo_cmd[32];
-	char buf[32];
-
-	os_snprintf(mbo_cmd, sizeof(mbo_cmd), "%s %d", "MBO CELL_DATA_CAP", mbo_cell_capa);
-	if (wpa_drv_driver_cmd(wpa_s, mbo_cmd, buf, sizeof(buf)) < 0) {
-		wpa_printf(MSG_ERROR, "MBO CELL_DATA_CAP cmd failed CAP:%d", mbo_cell_capa);
-	}
-#else
-	wpas_mbo_update_cell_capa(wpa_s, mbo_cell_capa);
-#endif
-
-	return {SupplicantStatusCode::SUCCESS, ""};
-#else
-	return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-#endif
-}
-
-std::pair<SupplicantStatus, uint32_t>
-StaIface::getKeyMgmtCapabilitiesInternal_1_3()
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	struct wpa_driver_capa capa;
-	uint32_t mask = 0;
-
-	/* Get capabilities from driver and populate the key management mask */
-	if (wpa_drv_get_capa(wpa_s, &capa) < 0) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, mask};
-	}
-
-	return {{SupplicantStatusCode::SUCCESS, ""},
-	    convertWpaKeyMgmtCapabilitiesToHidl(wpa_s, &capa)};
-}
-
-/**
- * Retrieve the underlying |wpa_supplicant| struct
- * pointer for this iface.
- * If the underlying iface is removed, then all RPC method calls on this object
- * will return failure.
- */
-wpa_supplicant *StaIface::retrieveIfacePtr()
-{
-	return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
-}
-}  // namespace implementation
-}  // namespace V1_4
-}  // namespace supplicant
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wpa_supplicant/hidl/1.4/sta_iface.h b/wpa_supplicant/hidl/1.4/sta_iface.h
deleted file mode 100644
index d49e469..0000000
--- a/wpa_supplicant/hidl/1.4/sta_iface.h
+++ /dev/null
@@ -1,339 +0,0 @@
-/*
- * hidl interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WPA_SUPPLICANT_HIDL_STA_IFACE_H
-#define WPA_SUPPLICANT_HIDL_STA_IFACE_H
-
-#include <array>
-#include <vector>
-
-#include <android-base/macros.h>
-
-#include <android/hardware/wifi/supplicant/1.4/ISupplicantStaIface.h>
-#include <android/hardware/wifi/supplicant/1.4/ISupplicantStaIfaceCallback.h>
-#include <android/hardware/wifi/supplicant/1.3/ISupplicantStaNetwork.h>
-
-extern "C"
-{
-#include "utils/common.h"
-#include "utils/includes.h"
-#include "wpa_supplicant_i.h"
-#include "config.h"
-#include "driver_i.h"
-#include "wpa.h"
-}
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_4 {
-namespace implementation {
-using V1_0::ISupplicantNetwork;
-using android::hardware::wifi::supplicant::V1_2::DppAkm;
-using android::hardware::wifi::supplicant::V1_2::DppNetRole;
-
-/**
- * Implementation of StaIface hidl object. Each unique hidl
- * object is used for control operations on a specific interface
- * controlled by wpa_supplicant.
- */
-class StaIface : public V1_4::ISupplicantStaIface
-{
-public:
-	StaIface(struct wpa_global* wpa_global, const char ifname[]);
-	~StaIface() override = default;
-	// HIDL does not provide a built-in mechanism to let the server
-	// invalidate a HIDL interface object after creation. If any client
-	// process holds onto a reference to the object in their context,
-	// any method calls on that reference will continue to be directed to
-	// the server.
-	// However Supplicant HAL needs to control the lifetime of these
-	// objects. So, add a public |invalidate| method to all |Iface| and
-	// |Network| objects.
-	// This will be used to mark an object invalid when the corresponding
-	// iface or network is removed.
-	// All HIDL method implementations should check if the object is still
-	// marked valid before processing them.
-	void invalidate();
-	bool isValid();
-
-	// Hidl methods exposed.
-	Return<void> getName(getName_cb _hidl_cb) override;
-	Return<void> getType(getType_cb _hidl_cb) override;
-	Return<void> addNetwork(addNetwork_cb _hidl_cb) override;
-	Return<void> removeNetwork(
-	    SupplicantNetworkId id, removeNetwork_cb _hidl_cb) override;
-	Return<void> filsHlpFlushRequest(
-	    filsHlpFlushRequest_cb _hidl_cb) override;
-	Return<void> filsHlpAddRequest(
-	    const hidl_array<uint8_t, 6>& dst_mac, const hidl_vec<uint8_t>& pkt,
-	    filsHlpAddRequest_cb _hidl_cb) override;
-	Return<void> getNetwork(
-	    SupplicantNetworkId id, getNetwork_cb _hidl_cb) override;
-	Return<void> listNetworks(listNetworks_cb _hidl_cb) override;
-	Return<void> registerCallback(
-	    const sp<V1_0::ISupplicantStaIfaceCallback>& callback,
-	    registerCallback_cb _hidl_cb) override;
-	Return<void> registerCallback_1_1(
-	    const sp<V1_1::ISupplicantStaIfaceCallback>& callback,
-	    registerCallback_cb _hidl_cb) override;
-	Return<void> registerCallback_1_2(
-	    const sp<V1_2::ISupplicantStaIfaceCallback>& callback,
-	    registerCallback_cb _hidl_cb) override;
-	Return<void> registerCallback_1_3(
-	    const sp<V1_3::ISupplicantStaIfaceCallback>& callback,
-	    registerCallback_cb _hidl_cb) override;
-	Return<void> registerCallback_1_4(
-	    const sp<V1_4::ISupplicantStaIfaceCallback> &callback,
-	    registerCallback_1_4_cb _hidl_cb) override;
-	Return<void> reassociate(reassociate_cb _hidl_cb) override;
-	Return<void> reconnect(reconnect_cb _hidl_cb) override;
-	Return<void> disconnect(disconnect_cb _hidl_cb) override;
-	Return<void> setPowerSave(
-	    bool enable, setPowerSave_cb _hidl_cb) override;
-	Return<void> initiateTdlsDiscover(
-	    const hidl_array<uint8_t, 6>& mac_address,
-	    initiateTdlsDiscover_cb _hidl_cb) override;
-	Return<void> initiateTdlsSetup(
-	    const hidl_array<uint8_t, 6>& mac_address,
-	    initiateTdlsSetup_cb _hidl_cb) override;
-	Return<void> initiateTdlsTeardown(
-	    const hidl_array<uint8_t, 6>& mac_address,
-	    initiateTdlsTeardown_cb _hidl_cb) override;
-	Return<void> initiateAnqpQuery(
-	    const hidl_array<uint8_t, 6>& mac_address,
-	    const hidl_vec<V1_0::ISupplicantStaIface::AnqpInfoId>& info_elements,
-	    const hidl_vec<ISupplicantStaIface::Hs20AnqpSubtypes>& sub_types,
-	    initiateAnqpQuery_cb _hidl_cb) override;
-	Return<void> initiateVenueUrlAnqpQuery(
-	    const hidl_array<uint8_t, 6>& mac_address,
-		initiateVenueUrlAnqpQuery_cb _hidl_cb) override;
-	Return<void> initiateHs20IconQuery(
-	    const hidl_array<uint8_t, 6>& mac_address,
-	    const hidl_string& file_name,
-	    initiateHs20IconQuery_cb _hidl_cb) override;
-	Return<void> getMacAddress(getMacAddress_cb _hidl_cb) override;
-	Return<void> startRxFilter(startRxFilter_cb _hidl_cb) override;
-	Return<void> stopRxFilter(stopRxFilter_cb _hidl_cb) override;
-	Return<void> addRxFilter(
-	    ISupplicantStaIface::RxFilterType type,
-	    addRxFilter_cb _hidl_cb) override;
-	Return<void> removeRxFilter(
-	    ISupplicantStaIface::RxFilterType type,
-	    removeRxFilter_cb _hidl_cb) override;
-	Return<void> setBtCoexistenceMode(
-	    ISupplicantStaIface::BtCoexistenceMode mode,
-	    setBtCoexistenceMode_cb _hidl_cb) override;
-	Return<void> setBtCoexistenceScanModeEnabled(
-	    bool enable, setBtCoexistenceScanModeEnabled_cb _hidl_cb) override;
-	Return<void> setSuspendModeEnabled(
-	    bool enable, setSuspendModeEnabled_cb _hidl_cb) override;
-	Return<void> setCountryCode(
-	    const hidl_array<int8_t, 2>& code,
-	    setCountryCode_cb _hidl_cb) override;
-	Return<void> startWpsRegistrar(
-	    const hidl_array<uint8_t, 6>& bssid, const hidl_string& pin,
-	    startWpsRegistrar_cb _hidl_cb) override;
-	Return<void> startWpsPbc(
-	    const hidl_array<uint8_t, 6>& bssid,
-	    startWpsPbc_cb _hidl_cb) override;
-	Return<void> startWpsPinKeypad(
-	    const hidl_string& pin, startWpsPinKeypad_cb _hidl_cb) override;
-	Return<void> startWpsPinDisplay(
-	    const hidl_array<uint8_t, 6>& bssid,
-	    startWpsPinDisplay_cb _hidl_cb) override;
-	Return<void> cancelWps(cancelWps_cb _hidl_cb) override;
-	Return<void> setWpsDeviceName(
-	    const hidl_string& name, setWpsDeviceName_cb _hidl_cb) override;
-	Return<void> setWpsDeviceType(
-	    const hidl_array<uint8_t, 8>& type,
-	    setWpsDeviceType_cb _hidl_cb) override;
-	Return<void> setWpsManufacturer(
-	    const hidl_string& manufacturer,
-	    setWpsManufacturer_cb _hidl_cb) override;
-	Return<void> setWpsModelName(
-	    const hidl_string& model_name,
-	    setWpsModelName_cb _hidl_cb) override;
-	Return<void> setWpsModelNumber(
-	    const hidl_string& model_number,
-	    setWpsModelNumber_cb _hidl_cb) override;
-	Return<void> setWpsSerialNumber(
-	    const hidl_string& serial_number,
-	    setWpsSerialNumber_cb _hidl_cb) override;
-	Return<void> setWpsConfigMethods(
-	    uint16_t config_methods, setWpsConfigMethods_cb _hidl_cb) override;
-	Return<void> setExternalSim(
-	    bool useExternalSim, setExternalSim_cb _hidl_cb) override;
-	Return<void> addExtRadioWork(
-	    const hidl_string& name, uint32_t freq_in_mhz,
-	    uint32_t timeout_in_sec, addExtRadioWork_cb _hidl_cb) override;
-	Return<void> removeExtRadioWork(
-	    uint32_t id, removeExtRadioWork_cb _hidl_cb) override;
-	Return<void> enableAutoReconnect(
-	    bool enable, enableAutoReconnect_cb _hidl_cb) override;
-	Return<void> getKeyMgmtCapabilities(
-	    getKeyMgmtCapabilities_cb _hidl_cb) override;
-	Return<void> addDppPeerUri(const hidl_string& uri,
-			addDppPeerUri_cb _hidl_cb) override;
-	Return<void> removeDppUri(uint32_t bootstrap_id,
-			removeDppUri_cb _hidl_cb) override;
-	Return<void> startDppConfiguratorInitiator(uint32_t peer_bootstrap_id,
-			uint32_t own_bootstrap_id, const hidl_string& ssid,
-			const hidl_string& password, const hidl_string& psk,
-			DppNetRole net_role, DppAkm security_akm,
-			startDppConfiguratorInitiator_cb _hidl_cb) override;
-	Return<void> startDppEnrolleeInitiator(uint32_t peer_bootstrap_id,
-			uint32_t own_bootstrap_id,
-			startDppConfiguratorInitiator_cb _hidl_cb) override;
-	Return<void> stopDppInitiator(stopDppInitiator_cb _hidl_cb) override;
-	Return<void> getConnectionCapabilities(
-	    getConnectionCapabilities_cb _hidl_cb) override;
-	Return<void> getConnectionCapabilities_1_4(
-	    getConnectionCapabilities_1_4_cb _hidl_cb) override;
-	Return<void> getWpaDriverCapabilities(
-	    getWpaDriverCapabilities_cb _hidl_cb) override;
-	Return<void> setMboCellularDataStatus(bool available,
-	    setMboCellularDataStatus_cb _hidl_cb) override;
-	Return<void> getKeyMgmtCapabilities_1_3(
-	    getKeyMgmtCapabilities_1_3_cb _hidl_cb) override;
-	Return<void> getWpaDriverCapabilities_1_4(
-	    getWpaDriverCapabilities_1_4_cb _hidl_cb) override;
-	Return<void> generateDppBootstrapInfoForResponder(const hidl_array<uint8_t, 6> &mac_address,
-			const hidl_string& device_info, DppCurve curve,
-			generateDppBootstrapInfoForResponder_cb _hidl_cb) override;
-	Return<void> startDppEnrolleeResponder(uint32_t listen_channel,
-			startDppEnrolleeResponder_cb _hidl_cb) override;
-	Return<void> stopDppResponder(uint32_t own_bootstrap_id,
-			stopDppResponder_cb _hidl_cb) override;
-
-private:
-	// Corresponding worker functions for the HIDL methods.
-	std::pair<SupplicantStatus, std::string> getNameInternal();
-	std::pair<SupplicantStatus, IfaceType> getTypeInternal();
-	std::pair<SupplicantStatus, sp<ISupplicantNetwork>>
-	addNetworkInternal();
-	SupplicantStatus filsHlpFlushRequestInternal();
-	SupplicantStatus filsHlpAddRequestInternal(
-	    const std::array<uint8_t, 6>& dst_mac,
-	    const std::vector<uint8_t>& pkt);
-	SupplicantStatus removeNetworkInternal(SupplicantNetworkId id);
-	std::pair<SupplicantStatus, sp<ISupplicantNetwork>> getNetworkInternal(
-	    SupplicantNetworkId id);
-	std::pair<SupplicantStatus, std::vector<SupplicantNetworkId>>
-	listNetworksInternal();
-	SupplicantStatus registerCallbackInternal(
-	    const sp<V1_0::ISupplicantStaIfaceCallback>& callback);
-	SupplicantStatus registerCallbackInternal_1_1(
-	    const sp<V1_1::ISupplicantStaIfaceCallback>& callback);
-	V1_4::SupplicantStatus registerCallbackInternal_1_4(
-	    const sp<V1_4::ISupplicantStaIfaceCallback>& callback);
-	SupplicantStatus reassociateInternal();
-	SupplicantStatus reconnectInternal();
-	SupplicantStatus disconnectInternal();
-	SupplicantStatus setPowerSaveInternal(bool enable);
-	SupplicantStatus initiateTdlsDiscoverInternal(
-	    const std::array<uint8_t, 6>& mac_address);
-	SupplicantStatus initiateTdlsSetupInternal(
-	    const std::array<uint8_t, 6>& mac_address);
-	SupplicantStatus initiateTdlsTeardownInternal(
-	    const std::array<uint8_t, 6>& mac_address);
-	SupplicantStatus initiateAnqpQueryInternal(
-	    const std::array<uint8_t, 6>& mac_address,
-	    const std::vector<ISupplicantStaIface::AnqpInfoId>& info_elements,
-	    const std::vector<ISupplicantStaIface::Hs20AnqpSubtypes>&
-		sub_types);
-	V1_4::SupplicantStatus initiateVenueUrlAnqpQueryInternal(
-	    const std::array<uint8_t, 6>& mac_address);
-	SupplicantStatus initiateHs20IconQueryInternal(
-	    const std::array<uint8_t, 6>& mac_address,
-	    const std::string& file_name);
-	std::pair<SupplicantStatus, std::array<uint8_t, 6>>
-	getMacAddressInternal();
-	SupplicantStatus startRxFilterInternal();
-	SupplicantStatus stopRxFilterInternal();
-	SupplicantStatus addRxFilterInternal(
-	    ISupplicantStaIface::RxFilterType type);
-	SupplicantStatus removeRxFilterInternal(
-	    ISupplicantStaIface::RxFilterType type);
-	SupplicantStatus setBtCoexistenceModeInternal(
-	    ISupplicantStaIface::BtCoexistenceMode mode);
-	SupplicantStatus setBtCoexistenceScanModeEnabledInternal(bool enable);
-	SupplicantStatus setSuspendModeEnabledInternal(bool enable);
-	SupplicantStatus setCountryCodeInternal(
-	    const std::array<int8_t, 2>& code);
-	SupplicantStatus startWpsRegistrarInternal(
-	    const std::array<uint8_t, 6>& bssid, const std::string& pin);
-	SupplicantStatus startWpsPbcInternal(
-	    const std::array<uint8_t, 6>& bssid);
-	SupplicantStatus startWpsPinKeypadInternal(const std::string& pin);
-	std::pair<SupplicantStatus, std::string> startWpsPinDisplayInternal(
-	    const std::array<uint8_t, 6>& bssid);
-	SupplicantStatus cancelWpsInternal();
-	SupplicantStatus setWpsDeviceNameInternal(const std::string& name);
-	SupplicantStatus setWpsDeviceTypeInternal(
-	    const std::array<uint8_t, 8>& type);
-	SupplicantStatus setWpsManufacturerInternal(
-	    const std::string& manufacturer);
-	SupplicantStatus setWpsModelNameInternal(const std::string& model_name);
-	SupplicantStatus setWpsModelNumberInternal(
-	    const std::string& model_number);
-	SupplicantStatus setWpsSerialNumberInternal(
-	    const std::string& serial_number);
-	SupplicantStatus setWpsConfigMethodsInternal(uint16_t config_methods);
-	SupplicantStatus setExternalSimInternal(bool useExternalSim);
-	std::pair<SupplicantStatus, uint32_t> addExtRadioWorkInternal(
-	    const std::string& name, uint32_t freq_in_mhz,
-	    uint32_t timeout_in_sec);
-	SupplicantStatus removeExtRadioWorkInternal(uint32_t id);
-	SupplicantStatus enableAutoReconnectInternal(bool enable);
-	std::pair<SupplicantStatus, uint32_t> getKeyMgmtCapabilitiesInternal();
-	std::pair<SupplicantStatus, uint32_t> addDppPeerUriInternal(const std::string& uri);
-	SupplicantStatus removeDppUriInternal(uint32_t bootstrap_id);
-	SupplicantStatus startDppConfiguratorInitiatorInternal(uint32_t peer_bootstrap_id,
-			uint32_t own_bootstrap_id,
-		    const std::string& ssid, const std::string& password,
-			const std::string& psk, DppNetRole net_role, DppAkm security_akm);
-	SupplicantStatus startDppEnrolleeInitiatorInternal(uint32_t peer_bootstrap_id,
-			uint32_t own_bootstrap_id);
-	SupplicantStatus stopDppInitiatorInternal();
-	std::pair<SupplicantStatus, V1_3::ConnectionCapabilities> getConnectionCapabilitiesInternal();
-	std::pair<V1_4::SupplicantStatus, V1_4::ConnectionCapabilities>
-			getConnectionCapabilitiesInternal_1_4();
-	std::pair<SupplicantStatus, uint32_t> getWpaDriverCapabilitiesInternal();
-	SupplicantStatus setMboCellularDataStatusInternal(bool available);
-	std::pair<SupplicantStatus, uint32_t> getKeyMgmtCapabilitiesInternal_1_3();
-	std::pair<V1_4::SupplicantStatus, uint32_t> getWpaDriverCapabilitiesInternal_1_4();
-	std::pair<V1_4::SupplicantStatus, V1_4::DppResponderBootstrapInfo>
-			generateDppBootstrapInfoForResponderInternal(
-			const std::array<uint8_t, 6>& mac_address, const std::string& device_info,
-			DppCurve curve);
-	V1_4::SupplicantStatus startDppEnrolleeResponderInternal(uint32_t listen_channel);
-	V1_4::SupplicantStatus stopDppResponderInternal(uint32_t own_bootstrap_id);
-
-	struct wpa_supplicant* retrieveIfacePtr();
-
-	// Reference to the global wpa_struct. This is assumed to be valid for
-	// the lifetime of the process.
-	struct wpa_global* wpa_global_;
-	// Name of the iface this hidl object controls
-	const std::string ifname_;
-	bool is_valid_;
-
-	DISALLOW_COPY_AND_ASSIGN(StaIface);
-};
-
-}  // namespace implementation
-}  // namespace V1_4
-}  // namespace supplicant
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WPA_SUPPLICANT_HIDL_STA_IFACE_H
diff --git a/wpa_supplicant/hidl/1.4/sta_network.cpp b/wpa_supplicant/hidl/1.4/sta_network.cpp
deleted file mode 100644
index ee132ac..0000000
--- a/wpa_supplicant/hidl/1.4/sta_network.cpp
+++ /dev/null
@@ -1,2657 +0,0 @@
-/*
- * hidl interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "hidl_manager.h"
-#include "hidl_return_util.h"
-#include "misc_utils.h"
-#include "sta_network.h"
-
-extern "C"
-{
-#include "wps_supplicant.h"
-}
-
-namespace {
-using android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
-using android::hardware::wifi::supplicant::V1_0::ISupplicantStaNetwork;
-using ISupplicantStaNetworkV1_2 = android::hardware::wifi::supplicant::V1_2::ISupplicantStaNetwork;
-using ISupplicantStaNetworkV1_3 = android::hardware::wifi::supplicant::V1_3::ISupplicantStaNetwork;
-using ISupplicantStaNetworkV1_4 = android::hardware::wifi::supplicant::V1_4::ISupplicantStaNetwork;
-
-constexpr uint8_t kZeroBssid[6] = {0, 0, 0, 0, 0, 0};
-
-constexpr uint32_t kAllowedKeyMgmtMask =
-    (static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::NONE) |
-     static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::WPA_PSK) |
-     static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::WPA_EAP) |
-     static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::IEEE8021X) |
-     static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::FT_EAP) |
-     static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::FT_PSK) |
-     static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::OSEN) |
-     static_cast<uint32_t>(ISupplicantStaNetworkV1_2::KeyMgmtMask::SAE) |
-     static_cast<uint32_t>(ISupplicantStaNetworkV1_2::KeyMgmtMask::SUITE_B_192) |
-     static_cast<uint32_t>(ISupplicantStaNetworkV1_2::KeyMgmtMask::OWE) |
-     static_cast<uint32_t>(ISupplicantStaNetworkV1_2::KeyMgmtMask::WPA_PSK_SHA256) |
-     static_cast<uint32_t>(ISupplicantStaNetworkV1_2::KeyMgmtMask::WPA_EAP_SHA256) |
-     static_cast<uint32_t>(ISupplicantStaNetworkV1_3::KeyMgmtMask::WAPI_PSK) |
-     static_cast<uint32_t>(ISupplicantStaNetworkV1_3::KeyMgmtMask::WAPI_CERT) |
-     static_cast<uint32_t>(ISupplicantStaNetworkV1_3::KeyMgmtMask::FILS_SHA256) |
-     static_cast<uint32_t>(ISupplicantStaNetworkV1_3::KeyMgmtMask::FILS_SHA384));
-constexpr uint32_t kAllowedProtoMask =
-    (static_cast<uint32_t>(ISupplicantStaNetwork::ProtoMask::WPA) |
-     static_cast<uint32_t>(ISupplicantStaNetwork::ProtoMask::RSN) |
-     static_cast<uint32_t>(ISupplicantStaNetwork::ProtoMask::OSEN) |
-     static_cast<uint32_t>(ISupplicantStaNetworkV1_3::ProtoMask::WAPI));
-constexpr uint32_t kAllowedAuthAlgMask =
-    (static_cast<uint32_t>(ISupplicantStaNetwork::AuthAlgMask::OPEN) |
-     static_cast<uint32_t>(ISupplicantStaNetwork::AuthAlgMask::SHARED) |
-     static_cast<uint32_t>(ISupplicantStaNetwork::AuthAlgMask::LEAP) |
-	 static_cast<uint32_t>(ISupplicantStaNetworkV1_3::AuthAlgMask::SAE));
-constexpr uint32_t kAllowedGroupCipherMask =
-    (static_cast<uint32_t>(ISupplicantStaNetwork::GroupCipherMask::WEP40) |
-     static_cast<uint32_t>(ISupplicantStaNetwork::GroupCipherMask::WEP104) |
-     static_cast<uint32_t>(ISupplicantStaNetwork::GroupCipherMask::TKIP) |
-     static_cast<uint32_t>(ISupplicantStaNetwork::GroupCipherMask::CCMP) |
-     static_cast<uint32_t>(
-	 ISupplicantStaNetwork::GroupCipherMask::GTK_NOT_USED) |
-     static_cast<uint32_t>(ISupplicantStaNetworkV1_2::GroupCipherMask::GCMP_256) |
-     static_cast<uint32_t>(ISupplicantStaNetworkV1_3::GroupCipherMask::SMS4) |
-     static_cast<uint32_t>(ISupplicantStaNetworkV1_4::GroupCipherMask::GCMP_128));
-constexpr uint32_t kAllowedPairwisewCipherMask =
-    (static_cast<uint32_t>(ISupplicantStaNetwork::PairwiseCipherMask::NONE) |
-     static_cast<uint32_t>(ISupplicantStaNetwork::PairwiseCipherMask::TKIP) |
-     static_cast<uint32_t>(ISupplicantStaNetwork::PairwiseCipherMask::CCMP) |
-     static_cast<uint32_t>(
-	 ISupplicantStaNetworkV1_2::PairwiseCipherMask::GCMP_256) |
-     static_cast<uint32_t>(
-	 ISupplicantStaNetworkV1_3::PairwiseCipherMask::SMS4) |
-     static_cast<uint32_t>(ISupplicantStaNetworkV1_4::PairwiseCipherMask::GCMP_128));
-constexpr uint32_t kAllowedGroupMgmtCipherMask =
-	(static_cast<uint32_t>(
-			ISupplicantStaNetworkV1_2::GroupMgmtCipherMask::BIP_GMAC_128) |
-	 static_cast<uint32_t>(
-			 ISupplicantStaNetworkV1_2::GroupMgmtCipherMask::BIP_GMAC_256) |
-	 static_cast<uint32_t>(
-			 ISupplicantStaNetworkV1_2::GroupMgmtCipherMask::BIP_CMAC_256));
-
-constexpr uint32_t kEapMethodMax =
-    static_cast<uint32_t>(ISupplicantStaNetwork::EapMethod::WFA_UNAUTH_TLS) + 1;
-constexpr char const *kEapMethodStrings[kEapMethodMax] = {
-    "PEAP", "TLS", "TTLS", "PWD", "SIM", "AKA", "AKA'", "WFA-UNAUTH-TLS"};
-constexpr uint32_t kEapPhase2MethodMax =
-    static_cast<uint32_t>(ISupplicantStaNetwork::EapPhase2Method::AKA_PRIME) +
-    1;
-constexpr char const *kEapPhase2MethodStrings[kEapPhase2MethodMax] = {
-    "", "PAP", "MSCHAP", "MSCHAPV2", "GTC", "SIM", "AKA", "AKA'"};
-constexpr char kEapPhase2AuthPrefix[] = "auth=";
-constexpr char kEapPhase2AuthEapPrefix[] = "autheap=";
-constexpr char kNetworkEapSimGsmAuthResponse[] = "GSM-AUTH";
-constexpr char kNetworkEapSimUmtsAuthResponse[] = "UMTS-AUTH";
-constexpr char kNetworkEapSimUmtsAutsResponse[] = "UMTS-AUTS";
-constexpr char kNetworkEapSimGsmAuthFailure[] = "GSM-FAIL";
-constexpr char kNetworkEapSimUmtsAuthFailure[] = "UMTS-FAIL";
-
-#ifdef CONFIG_WAPI_INTERFACE
-std::string dummyWapiCertSuite;
-std::vector<uint8_t> dummyWapiPsk;
-#endif /* CONFIG_WAPI_INTERFACE */
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_4 {
-namespace implementation {
-using hidl_return_util::validateAndCall;
-using V1_0::SupplicantStatus;
-using V1_0::SupplicantStatusCode;
-
-StaNetwork::StaNetwork(
-    struct wpa_global *wpa_global, const char ifname[], int network_id)
-    : wpa_global_(wpa_global),
-      ifname_(ifname),
-      network_id_(network_id),
-      is_valid_(true)
-{}
-
-void StaNetwork::invalidate() { is_valid_ = false; }
-bool StaNetwork::isValid()
-{
-	return (is_valid_ && (retrieveNetworkPtr() != nullptr));
-}
-
-Return<void> StaNetwork::getId(getId_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getIdInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getInterfaceName(getInterfaceName_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getInterfaceNameInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getType(getType_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getTypeInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::registerCallback(
-    const sp<ISupplicantStaNetworkCallback> &callback,
-    registerCallback_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::registerCallbackInternal, _hidl_cb, callback);
-}
-
-Return<void> StaNetwork::registerCallback_1_4(
-    const sp<V1_4::ISupplicantStaNetworkCallback> &callback,
-    registerCallback_1_4_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, V1_4::SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::registerCallback_1_4Internal, _hidl_cb, callback);
-}
-
-Return<void> StaNetwork::setSsid(
-    const hidl_vec<uint8_t> &ssid, setSsid_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setSsidInternal, _hidl_cb, ssid);
-}
-
-Return<void> StaNetwork::setBssid(
-    const hidl_array<uint8_t, 6> &bssid, setBssid_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setBssidInternal, _hidl_cb, bssid);
-}
-
-Return<void> StaNetwork::setScanSsid(bool enable, setScanSsid_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setScanSsidInternal, _hidl_cb, enable);
-}
-
-Return<void> StaNetwork::setKeyMgmt(
-    uint32_t key_mgmt_mask, setKeyMgmt_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setKeyMgmtInternal, _hidl_cb, key_mgmt_mask);
-}
-
-Return<void> StaNetwork::setProto(uint32_t proto_mask, setProto_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setProtoInternal, _hidl_cb, proto_mask);
-}
-
-Return<void> StaNetwork::setAuthAlg(
-    uint32_t auth_alg_mask,
-    std::function<void(const SupplicantStatus &status)> _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setAuthAlgInternal, _hidl_cb, auth_alg_mask);
-}
-
-Return<void> StaNetwork::setGroupCipher(
-    uint32_t group_cipher_mask, setGroupCipher_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setGroupCipherInternal, _hidl_cb, group_cipher_mask);
-}
-
-Return<void> StaNetwork::setPairwiseCipher(
-    uint32_t pairwise_cipher_mask, setPairwiseCipher_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setPairwiseCipherInternal, _hidl_cb,
-	    pairwise_cipher_mask);
-}
-
-Return<void> StaNetwork::setPskPassphrase(
-    const hidl_string &psk, setPskPassphrase_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setPskPassphraseInternal, _hidl_cb, psk);
-}
-
-Return<void> StaNetwork::setPsk(
-    const hidl_array<uint8_t, 32> &psk, setPsk_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setPskInternal, _hidl_cb, psk);
-}
-
-Return<void> StaNetwork::setWepKey(
-    uint32_t key_idx, const hidl_vec<uint8_t> &wep_key, setWepKey_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setWepKeyInternal, _hidl_cb, key_idx, wep_key);
-}
-
-Return<void> StaNetwork::setWepTxKeyIdx(
-    uint32_t key_idx, setWepTxKeyIdx_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setWepTxKeyIdxInternal, _hidl_cb, key_idx);
-}
-
-Return<void> StaNetwork::setRequirePmf(bool enable, setRequirePmf_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setRequirePmfInternal, _hidl_cb, enable);
-}
-
-Return<void> StaNetwork::setEapMethod(
-    ISupplicantStaNetwork::EapMethod method, setEapMethod_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setEapMethodInternal, _hidl_cb, method);
-}
-
-Return<void> StaNetwork::setEapPhase2Method(
-    ISupplicantStaNetwork::EapPhase2Method method,
-    setEapPhase2Method_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setEapPhase2MethodInternal, _hidl_cb, method);
-}
-
-Return<void> StaNetwork::setEapIdentity(
-    const hidl_vec<uint8_t> &identity, setEapIdentity_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setEapIdentityInternal, _hidl_cb, identity);
-}
-
-Return<void> StaNetwork::setEapEncryptedImsiIdentity(
-    const EapSimEncryptedIdentity &identity,
-    setEapEncryptedImsiIdentity_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setEapEncryptedImsiIdentityInternal, _hidl_cb,
-	    identity);
-}
-
-Return<void> StaNetwork::setEapAnonymousIdentity(
-    const hidl_vec<uint8_t> &identity, setEapAnonymousIdentity_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setEapAnonymousIdentityInternal, _hidl_cb, identity);
-}
-
-Return<void> StaNetwork::setEapPassword(
-    const hidl_vec<uint8_t> &password, setEapPassword_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setEapPasswordInternal, _hidl_cb, password);
-}
-
-Return<void> StaNetwork::setEapCACert(
-    const hidl_string &path, setEapCACert_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setEapCACertInternal, _hidl_cb, path);
-}
-
-Return<void> StaNetwork::setEapCAPath(
-    const hidl_string &path, setEapCAPath_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setEapCAPathInternal, _hidl_cb, path);
-}
-
-Return<void> StaNetwork::setEapClientCert(
-    const hidl_string &path, setEapClientCert_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setEapClientCertInternal, _hidl_cb, path);
-}
-
-Return<void> StaNetwork::setEapPrivateKeyId(
-    const hidl_string &id, setEapPrivateKeyId_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setEapPrivateKeyIdInternal, _hidl_cb, id);
-}
-
-Return<void> StaNetwork::setEapSubjectMatch(
-    const hidl_string &match, setEapSubjectMatch_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setEapSubjectMatchInternal, _hidl_cb, match);
-}
-
-Return<void> StaNetwork::setEapAltSubjectMatch(
-    const hidl_string &match, setEapAltSubjectMatch_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setEapAltSubjectMatchInternal, _hidl_cb, match);
-}
-
-Return<void> StaNetwork::setEapEngine(bool enable, setEapEngine_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setEapEngineInternal, _hidl_cb, enable);
-}
-
-Return<void> StaNetwork::setEapEngineID(
-    const hidl_string &id, setEapEngineID_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setEapEngineIDInternal, _hidl_cb, id);
-}
-
-Return<void> StaNetwork::setEapDomainSuffixMatch(
-    const hidl_string &match, setEapDomainSuffixMatch_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setEapDomainSuffixMatchInternal, _hidl_cb, match);
-}
-
-Return<void> StaNetwork::setProactiveKeyCaching(
-    bool enable, setProactiveKeyCaching_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setProactiveKeyCachingInternal, _hidl_cb, enable);
-}
-
-Return<void> StaNetwork::setIdStr(
-    const hidl_string &id_str, setIdStr_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setIdStrInternal, _hidl_cb, id_str);
-}
-
-Return<void> StaNetwork::setUpdateIdentifier(
-    uint32_t id, setUpdateIdentifier_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setUpdateIdentifierInternal, _hidl_cb, id);
-}
-
-Return<void> StaNetwork::setWapiCertSuite(
-    const hidl_string& suite, setWapiCertSuite_cb _hidl_cb) {
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setWapiCertSuiteInternal, _hidl_cb, suite);
-}
-
-Return<void> StaNetwork::setEdmg(bool enable, setEdmg_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, V1_4::SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setEdmgInternal, _hidl_cb, enable);
-}
-
-Return<void> StaNetwork::getSsid(getSsid_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getSsidInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getBssid(getBssid_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getBssidInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getScanSsid(getScanSsid_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getScanSsidInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getKeyMgmt(getKeyMgmt_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getKeyMgmtInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getProto(getProto_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getProtoInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getAuthAlg(getAuthAlg_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getAuthAlgInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getGroupCipher(getGroupCipher_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getGroupCipherInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getPairwiseCipher(getPairwiseCipher_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getPairwiseCipherInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getPskPassphrase(getPskPassphrase_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getPskPassphraseInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getPsk(getPsk_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getPskInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getSaePassword(getSaePassword_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getSaePasswordInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getSaePasswordId(getSaePasswordId_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getSaePasswordIdInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getWepKey(uint32_t key_idx, getWepKey_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getWepKeyInternal, _hidl_cb, key_idx);
-}
-
-Return<void> StaNetwork::getWepTxKeyIdx(getWepTxKeyIdx_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getWepTxKeyIdxInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getRequirePmf(getRequirePmf_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getRequirePmfInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getEapMethod(getEapMethod_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getEapMethodInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getEapPhase2Method(getEapPhase2Method_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getEapPhase2MethodInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getEapIdentity(getEapIdentity_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getEapIdentityInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getEapAnonymousIdentity(
-    getEapAnonymousIdentity_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getEapAnonymousIdentityInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getEapPassword(getEapPassword_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getEapPasswordInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getEapCACert(getEapCACert_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getEapCACertInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getEapCAPath(getEapCAPath_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getEapCAPathInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getEapClientCert(getEapClientCert_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getEapClientCertInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getEapPrivateKeyId(getEapPrivateKeyId_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getEapPrivateKeyIdInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getEapSubjectMatch(getEapSubjectMatch_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getEapSubjectMatchInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getEapAltSubjectMatch(
-    getEapAltSubjectMatch_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getEapAltSubjectMatchInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getEapEngine(getEapEngine_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getEapEngineInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getEapEngineID(getEapEngineID_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getEapEngineIDInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getEapDomainSuffixMatch(
-    getEapDomainSuffixMatch_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getEapDomainSuffixMatchInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getIdStr(getIdStr_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getIdStrInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getWpsNfcConfigurationToken(
-    getWpsNfcConfigurationToken_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getWpsNfcConfigurationTokenInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getWapiCertSuite(getWapiCertSuite_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getWapiCertSuiteInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getEdmg(getEdmg_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, V1_4::SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getEdmgInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::enable(bool no_connect, enable_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::enableInternal, _hidl_cb, no_connect);
-}
-
-Return<void> StaNetwork::disable(disable_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::disableInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::select(select_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::selectInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::sendNetworkEapSimGsmAuthResponse(
-    const hidl_vec<ISupplicantStaNetwork::NetworkResponseEapSimGsmAuthParams>
-	&vec_params,
-    sendNetworkEapSimGsmAuthResponse_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::sendNetworkEapSimGsmAuthResponseInternal, _hidl_cb,
-	    vec_params);
-}
-
-Return<void> StaNetwork::sendNetworkEapSimGsmAuthFailure(
-    sendNetworkEapSimGsmAuthFailure_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::sendNetworkEapSimGsmAuthFailureInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::sendNetworkEapSimUmtsAuthResponse(
-    const ISupplicantStaNetwork::NetworkResponseEapSimUmtsAuthParams &params,
-    sendNetworkEapSimUmtsAuthResponse_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::sendNetworkEapSimUmtsAuthResponseInternal, _hidl_cb,
-	    params);
-}
-
-Return<void> StaNetwork::sendNetworkEapSimUmtsAutsResponse(
-    const hidl_array<uint8_t, 14> &auts,
-    sendNetworkEapSimUmtsAutsResponse_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::sendNetworkEapSimUmtsAutsResponseInternal, _hidl_cb,
-	    auts);
-}
-
-Return<void> StaNetwork::sendNetworkEapSimUmtsAuthFailure(
-    sendNetworkEapSimUmtsAuthFailure_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::sendNetworkEapSimUmtsAuthFailureInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::sendNetworkEapIdentityResponse(
-    const hidl_vec<uint8_t> &identity,
-    sendNetworkEapIdentityResponse_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::sendNetworkEapIdentityResponseInternal, _hidl_cb,
-	    identity);
-}
-
-Return<void> StaNetwork::sendNetworkEapIdentityResponse_1_1(
-    const EapSimIdentity &identity,
-    const EapSimEncryptedIdentity &encrypted_imsi_identity,
-    sendNetworkEapIdentityResponse_1_1_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::sendNetworkEapIdentityResponseInternal_1_1, _hidl_cb,
-	    identity, encrypted_imsi_identity);
-}
-
-Return<void> StaNetwork::setKeyMgmt_1_2(
-    uint32_t key_mgmt_mask, setKeyMgmt_1_2_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setKeyMgmtInternal, _hidl_cb, key_mgmt_mask);
-}
-
-Return<void> StaNetwork::setGroupCipher_1_2(
-    uint32_t group_cipher_mask, setGroupCipher_1_2_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setGroupCipherInternal, _hidl_cb, group_cipher_mask);
-}
-
-Return<void> StaNetwork::setGroupMgmtCipher(
-    uint32_t group_mgmt_cipher_mask, setGroupMgmtCipher_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setGroupMgmtCipherInternal,
-		_hidl_cb, group_mgmt_cipher_mask);
-}
-
-Return<void> StaNetwork::getGroupMgmtCipher(getGroupMgmtCipher_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getGroupMgmtCipherInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::setPairwiseCipher_1_2(
-    uint32_t pairwise_cipher_mask, setPairwiseCipher_1_2_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setPairwiseCipherInternal, _hidl_cb,
-	    pairwise_cipher_mask);
-}
-
-Return<void> StaNetwork::getKeyMgmt_1_2(getKeyMgmt_1_2_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getKeyMgmtInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getGroupCipher_1_2(getGroupCipher_1_2_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getGroupCipherInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getPairwiseCipher_1_2(
-    getPairwiseCipher_1_2_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getPairwiseCipherInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::enableTlsSuiteBEapPhase1Param(
-    bool enable, enableTlsSuiteBEapPhase1Param_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::enableTlsSuiteBEapPhase1ParamInternal, _hidl_cb, enable);
-}
-
-Return<void> StaNetwork::enableSuiteBEapOpenSslCiphers(
-    enableSuiteBEapOpenSslCiphers_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::enableSuiteBEapOpenSslCiphersInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::setSaePassword(
-    const hidl_string &sae_password, setSaePassword_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setSaePasswordInternal, _hidl_cb, sae_password);
-}
-
-Return<void> StaNetwork::setSaePasswordId(
-    const hidl_string &sae_password_id, setSaePasswordId_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setSaePasswordIdInternal, _hidl_cb, sae_password_id);
-}
-
-Return<void> StaNetwork::setOcsp(
-    V1_3::OcspType ocspType, setOcsp_cb _hidl_cb) {
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setOcspInternal, _hidl_cb, ocspType);
-}
-
-Return<void> StaNetwork::getOcsp(
-    getOcsp_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getOcspInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::setPmkCache(const hidl_vec<uint8_t> &serializedEntry,
-    setPmkCache_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setPmkCacheInternal, _hidl_cb, serializedEntry);
-}
-
-Return<void> StaNetwork::setKeyMgmt_1_3(
-    uint32_t key_mgmt_mask, setKeyMgmt_1_3_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setKeyMgmt_1_3Internal, _hidl_cb, key_mgmt_mask);
-}
-
-Return<void> StaNetwork::getKeyMgmt_1_3(getKeyMgmt_1_3_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getKeyMgmt_1_3Internal, _hidl_cb);
-}
-
-Return<void> StaNetwork::setProto_1_3(uint32_t proto_mask, setProto_1_3_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setProto_1_3Internal, _hidl_cb, proto_mask);
-}
-
-Return<void> StaNetwork::getProto_1_3(getProto_1_3_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getProto_1_3Internal, _hidl_cb);
-}
-
-Return<void> StaNetwork::setGroupCipher_1_3(
-    uint32_t group_cipher_mask, setGroupCipher_1_3_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setGroupCipher_1_3Internal, _hidl_cb, group_cipher_mask);
-}
-
-Return<void> StaNetwork::getGroupCipher_1_3(getGroupCipher_1_3_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getGroupCipher_1_3Internal, _hidl_cb);
-}
-
-Return<void> StaNetwork::setPairwiseCipher_1_3(
-    uint32_t pairwise_cipher_mask, setPairwiseCipher_1_3_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setPairwiseCipher_1_3Internal, _hidl_cb,
-	    pairwise_cipher_mask);
-}
-
-Return<void> StaNetwork::getPairwiseCipher_1_3(
-    getPairwiseCipher_1_3_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getPairwiseCipher_1_3Internal, _hidl_cb);
-}
-
-Return<void> StaNetwork::getAuthAlg_1_3(getAuthAlg_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getAuthAlgInternal, _hidl_cb);
-}
-
-Return<void> StaNetwork::setAuthAlg_1_3(
-    uint32_t auth_alg_mask,
-    std::function<void(const SupplicantStatus &status)> _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setAuthAlgInternal, _hidl_cb, auth_alg_mask);
-}
-
-Return<void> StaNetwork::setEapErp(bool enable, setEapErp_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setEapErpInternal, _hidl_cb, enable);
-}
-
-Return<void> StaNetwork::setGroupCipher_1_4(
-    uint32_t group_cipher_mask, setGroupCipher_1_4_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, V1_4::SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setGroupCipher_1_4Internal, _hidl_cb, group_cipher_mask);
-}
-
-Return<void> StaNetwork::getGroupCipher_1_4(getGroupCipher_1_4_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, V1_4::SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getGroupCipher_1_4Internal, _hidl_cb);
-}
-
-Return<void> StaNetwork::setPairwiseCipher_1_4(
-    uint32_t pairwise_cipher_mask, setPairwiseCipher_1_4_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, V1_4::SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setPairwiseCipher_1_4Internal, _hidl_cb,
-	    pairwise_cipher_mask);
-}
-
-Return<void> StaNetwork::getPairwiseCipher_1_4(
-    getPairwiseCipher_1_4_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, V1_4::SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::getPairwiseCipher_1_4Internal, _hidl_cb);
-}
-
-Return<void> StaNetwork::setSaeH2eMode(
-    ISupplicantStaNetworkV1_4::SaeH2eMode mode, setSaeH2eMode_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, V1_4::SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::setSaeH2eModeInternal, _hidl_cb, mode);
-}
-
-Return<void> StaNetwork::enableSaePkOnlyMode(bool enable, enableSaePkOnlyMode_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, V1_4::SupplicantStatusCode::FAILURE_NETWORK_INVALID,
-	    &StaNetwork::enableSaePkOnlyModeInternal, _hidl_cb, enable);
-}
-
-std::pair<SupplicantStatus, uint32_t> StaNetwork::getIdInternal()
-{
-	return {{SupplicantStatusCode::SUCCESS, ""}, network_id_};
-}
-
-std::pair<SupplicantStatus, std::string> StaNetwork::getInterfaceNameInternal()
-{
-	return {{SupplicantStatusCode::SUCCESS, ""}, ifname_};
-}
-
-std::pair<SupplicantStatus, IfaceType> StaNetwork::getTypeInternal()
-{
-	return {{SupplicantStatusCode::SUCCESS, ""}, IfaceType::STA};
-}
-
-SupplicantStatus StaNetwork::registerCallbackInternal(
-    const sp<ISupplicantStaNetworkCallback> &callback)
-{
-	return {SupplicantStatusCode::FAILURE_UNKNOWN, "deprecated"};
-}
-
-V1_4::SupplicantStatus StaNetwork::registerCallback_1_4Internal(
-    const sp<V1_4::ISupplicantStaNetworkCallback> &callback)
-{
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager || hidl_manager->addStaNetworkCallbackHidlObject(
-				 ifname_, network_id_, callback)) {
-		return {V1_4::SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {V1_4::SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setSsidInternal(const std::vector<uint8_t> &ssid)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (ssid.size() == 0 ||
-	    ssid.size() >
-		static_cast<uint32_t>(ISupplicantStaNetwork::ParamSizeLimits::
-					  SSID_MAX_LEN_IN_BYTES)) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	if (setByteArrayFieldAndResetState(
-		ssid.data(), ssid.size(), &(wpa_ssid->ssid),
-		&(wpa_ssid->ssid_len), "ssid")) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	if (wpa_ssid->passphrase) {
-		wpa_config_update_psk(wpa_ssid);
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setBssidInternal(
-    const std::array<uint8_t, 6> &bssid)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	int prev_bssid_set = wpa_ssid->bssid_set;
-	u8 prev_bssid[ETH_ALEN];
-	os_memcpy(prev_bssid, wpa_ssid->bssid, ETH_ALEN);
-	// Zero'ed array is used to clear out the BSSID value.
-	if (os_memcmp(bssid.data(), kZeroBssid, ETH_ALEN) == 0) {
-		wpa_ssid->bssid_set = 0;
-		wpa_printf(MSG_MSGDUMP, "BSSID any");
-	} else {
-		os_memcpy(wpa_ssid->bssid, bssid.data(), ETH_ALEN);
-		wpa_ssid->bssid_set = 1;
-		wpa_hexdump(MSG_MSGDUMP, "BSSID", wpa_ssid->bssid, ETH_ALEN);
-	}
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	if ((wpa_ssid->bssid_set != prev_bssid_set ||
-	     os_memcmp(wpa_ssid->bssid, prev_bssid, ETH_ALEN) != 0)) {
-		wpas_notify_network_bssid_set_changed(wpa_s, wpa_ssid);
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setScanSsidInternal(bool enable)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	wpa_ssid->scan_ssid = enable ? 1 : 0;
-	resetInternalStateAfterParamsUpdate();
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setKeyMgmtInternal(uint32_t key_mgmt_mask)
-{
-	return {SupplicantStatusCode::FAILURE_UNKNOWN, "deprecated"};
-}
-
-SupplicantStatus StaNetwork::setProtoInternal(uint32_t proto_mask)
-{
-	return {SupplicantStatusCode::FAILURE_UNKNOWN, "deprecated"};
-}
-
-SupplicantStatus StaNetwork::setAuthAlgInternal(uint32_t auth_alg_mask)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (auth_alg_mask & ~kAllowedAuthAlgMask) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	wpa_ssid->auth_alg = auth_alg_mask;
-	wpa_printf(MSG_MSGDUMP, "auth_alg: 0x%x", wpa_ssid->auth_alg);
-	resetInternalStateAfterParamsUpdate();
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-V1_4::SupplicantStatus StaNetwork::setEdmgInternal(bool enable)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	wpa_ssid->enable_edmg = enable ? 1 : 0;
-	resetInternalStateAfterParamsUpdate();
-	return {V1_4::SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setGroupCipherInternal(uint32_t group_cipher_mask)
-{
-	return {SupplicantStatusCode::FAILURE_UNKNOWN, "deprecated"};
-}
-
-SupplicantStatus StaNetwork::setPairwiseCipherInternal(
-    uint32_t pairwise_cipher_mask)
-{
-	return {SupplicantStatusCode::FAILURE_UNKNOWN, "deprecated"};
-}
-
-SupplicantStatus StaNetwork::setPskPassphraseInternal(const std::string &rawPsk)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	std::string psk = rawPsk;
-#ifdef CONFIG_WAPI_INTERFACE
-	if (wpa_ssid->key_mgmt & WPA_KEY_MGMT_WAPI_PSK) {
-		if (rawPsk.size() > 2 && rawPsk.front()== '"' && rawPsk.back() == '"') {
-			psk = rawPsk.substr(1, rawPsk.size() - 2);
-		} else {
-			if ((rawPsk.size() & 1)) {
-				return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-			}
-			size_t len = psk.size() / 2;
-			uint8_t *buf = (uint8_t *) os_malloc(len);
-			if (hexstr2bin(psk.c_str(), buf, len) < 0) {
-			        os_free(buf);
-				return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-			}
-			std::vector<uint8_t> bytes(buf, buf + len);
-			os_free(buf);
-			return setWapiPskInternal(bytes);
-		}
-	}
-#endif
-	if (isPskPassphraseValid(psk)) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	if (wpa_ssid->passphrase &&
-	    os_strlen(wpa_ssid->passphrase) == psk.size() &&
-	    os_memcmp(wpa_ssid->passphrase, psk.c_str(), psk.size()) == 0) {
-		return {SupplicantStatusCode::SUCCESS, ""};
-	}
-	// Flag to indicate if raw psk is calculated or not using
-	// |wpa_config_update_psk|. Deferred if ssid not already set.
-	wpa_ssid->psk_set = 0;
-	if (setStringKeyFieldAndResetState(
-		psk.c_str(), &(wpa_ssid->passphrase), "psk passphrase")) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	if (wpa_ssid->ssid_len) {
-		wpa_config_update_psk(wpa_ssid);
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setPskInternal(const std::array<uint8_t, 32> &psk)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	WPA_ASSERT(psk.size() == sizeof(wpa_ssid->psk));
-	str_clear_free(wpa_ssid->passphrase);
-	wpa_ssid->passphrase = nullptr;
-	os_memcpy(wpa_ssid->psk, psk.data(), sizeof(wpa_ssid->psk));
-	wpa_ssid->psk_set = 1;
-	resetInternalStateAfterParamsUpdate();
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setWepKeyInternal(
-    uint32_t key_idx, const std::vector<uint8_t> &wep_key)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (key_idx >=
-	    static_cast<uint32_t>(
-		ISupplicantStaNetwork::ParamSizeLimits::WEP_KEYS_MAX_NUM)) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	if (wep_key.size() !=
-		static_cast<uint32_t>(ISupplicantStaNetwork::ParamSizeLimits::
-					  WEP40_KEY_LEN_IN_BYTES) &&
-	    wep_key.size() !=
-		static_cast<uint32_t>(ISupplicantStaNetwork::ParamSizeLimits::
-					  WEP104_KEY_LEN_IN_BYTES)) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	os_memcpy(wpa_ssid->wep_key[key_idx], wep_key.data(), wep_key.size());
-	wpa_ssid->wep_key_len[key_idx] = wep_key.size();
-	std::string msg_dump_title("wep_key" + std::to_string(key_idx));
-	wpa_hexdump_key(
-	    MSG_MSGDUMP, msg_dump_title.c_str(), wpa_ssid->wep_key[key_idx],
-	    wpa_ssid->wep_key_len[key_idx]);
-	resetInternalStateAfterParamsUpdate();
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setWepTxKeyIdxInternal(uint32_t key_idx)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (key_idx >=
-	    static_cast<uint32_t>(
-		ISupplicantStaNetwork::ParamSizeLimits::WEP_KEYS_MAX_NUM)) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	wpa_ssid->wep_tx_keyidx = key_idx;
-	resetInternalStateAfterParamsUpdate();
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setRequirePmfInternal(bool enable)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (enable) {
-		wpa_ssid->ieee80211w = MGMT_FRAME_PROTECTION_REQUIRED;
-	}
-	resetInternalStateAfterParamsUpdate();
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setEapMethodInternal(
-    ISupplicantStaNetwork::EapMethod method)
-{
-	uint32_t eap_method_idx = static_cast<
-	    std::underlying_type<ISupplicantStaNetwork::EapMethod>::type>(
-	    method);
-	if (eap_method_idx >= kEapMethodMax) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	int retrieved_vendor, retrieved_method;
-	const char *method_str = kEapMethodStrings[eap_method_idx];
-	// This string lookup is needed to check if the device supports the
-	// corresponding EAP type.
-	retrieved_method = eap_peer_get_type(method_str, &retrieved_vendor);
-	if (retrieved_vendor == EAP_VENDOR_IETF &&
-	    retrieved_method == EAP_TYPE_NONE) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	if (wpa_ssid->eap.eap_methods) {
-		os_free(wpa_ssid->eap.eap_methods);
-	}
-	// wpa_supplicant can support setting multiple eap methods for each
-	// network. But, this is not really used by Android. So, just adding
-	// support for setting one EAP method for each network. The additional
-	// |eap_method_type| member in the array is used to indicate the end
-	// of list.
-	wpa_ssid->eap.eap_methods =
-	    (eap_method_type *)os_malloc(sizeof(eap_method_type) * 2);
-	if (!wpa_ssid->eap.eap_methods) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	wpa_ssid->eap.eap_methods[0].vendor = retrieved_vendor;
-	wpa_ssid->eap.eap_methods[0].method = retrieved_method;
-	wpa_ssid->eap.eap_methods[1].vendor = EAP_VENDOR_IETF;
-	wpa_ssid->eap.eap_methods[1].method = EAP_TYPE_NONE;
-
-	wpa_ssid->leap = 0;
-	wpa_ssid->non_leap = 0;
-	if (retrieved_vendor == EAP_VENDOR_IETF &&
-	    retrieved_method == EAP_TYPE_LEAP) {
-		wpa_ssid->leap++;
-	} else {
-		wpa_ssid->non_leap++;
-	}
-	wpa_hexdump(
-	    MSG_MSGDUMP, "eap methods", (u8 *)wpa_ssid->eap.eap_methods,
-	    sizeof(eap_method_type) * 2);
-	resetInternalStateAfterParamsUpdate();
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setEapPhase2MethodInternal(
-    ISupplicantStaNetwork::EapPhase2Method method)
-{
-	uint32_t eap_phase2_method_idx = static_cast<
-	    std::underlying_type<ISupplicantStaNetwork::EapPhase2Method>::type>(
-	    method);
-	if (eap_phase2_method_idx >= kEapPhase2MethodMax) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	// EAP method needs to be set for us to construct the eap
-	// phase 2 method string.
-	SupplicantStatus status;
-	ISupplicantStaNetwork::EapMethod eap_method;
-	std::tie(status, eap_method) = getEapMethodInternal();
-	if (status.code != SupplicantStatusCode::SUCCESS) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN,
-			"EAP method not set"};
-	}
-	std::string eap_phase2_str;
-	if (method == ISupplicantStaNetwork::EapPhase2Method::NONE) {
-		eap_phase2_str = "";
-	} else if (
-	    eap_method == ISupplicantStaNetwork::EapMethod::TTLS &&
-	    method == ISupplicantStaNetwork::EapPhase2Method::GTC) {
-		eap_phase2_str = kEapPhase2AuthEapPrefix;
-	} else {
-		eap_phase2_str = kEapPhase2AuthPrefix;
-	}
-	eap_phase2_str += kEapPhase2MethodStrings[eap_phase2_method_idx];
-	if (setStringFieldAndResetState(
-		eap_phase2_str.c_str(), &(wpa_ssid->eap.phase2),
-		"eap phase2")) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setEapIdentityInternal(
-    const std::vector<uint8_t> &identity)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (setByteArrayFieldAndResetState(
-		identity.data(), identity.size(), &(wpa_ssid->eap.identity),
-		&(wpa_ssid->eap.identity_len), "eap identity")) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	// plain IMSI identity
-	if (setByteArrayFieldAndResetState(
-		identity.data(), identity.size(),
-		&(wpa_ssid->eap.imsi_identity),
-		&(wpa_ssid->eap.imsi_identity_len), "eap imsi identity")) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setEapEncryptedImsiIdentityInternal(
-    const std::vector<uint8_t> &identity)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	// encrypted IMSI identity
-	if (setByteArrayFieldAndResetState(
-		identity.data(), identity.size(), &(wpa_ssid->eap.identity),
-		&(wpa_ssid->eap.identity_len), "eap encrypted imsi identity")) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setEapAnonymousIdentityInternal(
-    const std::vector<uint8_t> &identity)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (setByteArrayFieldAndResetState(
-		identity.data(), identity.size(),
-		&(wpa_ssid->eap.anonymous_identity),
-		&(wpa_ssid->eap.anonymous_identity_len),
-		"eap anonymous_identity")) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setEapPasswordInternal(
-    const std::vector<uint8_t> &password)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (setByteArrayKeyFieldAndResetState(
-		password.data(), password.size(), &(wpa_ssid->eap.password),
-		&(wpa_ssid->eap.password_len), "eap password")) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	wpa_ssid->eap.flags &= ~EAP_CONFIG_FLAGS_PASSWORD_NTHASH;
-	wpa_ssid->eap.flags &= ~EAP_CONFIG_FLAGS_EXT_PASSWORD;
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setEapCACertInternal(const std::string &path)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (setStringFieldAndResetState(
-		path.c_str(), &(wpa_ssid->eap.cert.ca_cert), "eap ca_cert")) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setEapCAPathInternal(const std::string &path)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (setStringFieldAndResetState(
-		path.c_str(), &(wpa_ssid->eap.cert.ca_path), "eap ca_path")) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setEapClientCertInternal(const std::string &path)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (setStringFieldAndResetState(
-		path.c_str(), &(wpa_ssid->eap.cert.client_cert),
-		"eap client_cert")) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setEapPrivateKeyIdInternal(const std::string &id)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (setStringFieldAndResetState(
-		id.c_str(), &(wpa_ssid->eap.cert.key_id), "eap key_id")) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setEapSubjectMatchInternal(
-    const std::string &match)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (setStringFieldAndResetState(
-		match.c_str(), &(wpa_ssid->eap.cert.subject_match),
-		"eap subject_match")) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setEapAltSubjectMatchInternal(
-    const std::string &match)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (setStringFieldAndResetState(
-		match.c_str(), &(wpa_ssid->eap.cert.altsubject_match),
-		"eap altsubject_match")) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setEapEngineInternal(bool enable)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	wpa_ssid->eap.cert.engine = enable ? 1 : 0;
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setEapEngineIDInternal(const std::string &id)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (setStringFieldAndResetState(
-		id.c_str(), &(wpa_ssid->eap.cert.engine_id), "eap engine_id")) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setEapDomainSuffixMatchInternal(
-    const std::string &match)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (setStringFieldAndResetState(
-		match.c_str(), &(wpa_ssid->eap.cert.domain_suffix_match),
-		"eap domain_suffix_match")) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setProactiveKeyCachingInternal(bool enable)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	wpa_ssid->proactive_key_caching = enable ? 1 : 0;
-	resetInternalStateAfterParamsUpdate();
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setIdStrInternal(const std::string &id_str)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (setStringFieldAndResetState(
-		id_str.c_str(), &(wpa_ssid->id_str), "id_str")) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setUpdateIdentifierInternal(uint32_t id)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	wpa_ssid->update_identifier = id;
-	wpa_printf(
-	    MSG_MSGDUMP, "update_identifier: %d", wpa_ssid->update_identifier);
-	resetInternalStateAfterParamsUpdate();
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setWapiCertSuiteInternal(const std::string &suite)
-{
-#ifdef CONFIG_WAPI_INTERFACE
-	dummyWapiCertSuite = suite;
-	return {SupplicantStatusCode::SUCCESS, "Dummy implementation"};
-#else
-	return {SupplicantStatusCode::FAILURE_UNKNOWN, "Not implemented"};
-#endif
-}
-
-SupplicantStatus StaNetwork::setWapiPskInternal(const std::vector<uint8_t> &psk)
-{
-#ifdef CONFIG_WAPI_INTERFACE
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	str_clear_free(wpa_ssid->passphrase);
-	wpa_ssid->passphrase = nullptr;
-
-	dummyWapiPsk = psk;
-
-	wpa_ssid->psk_set = 1;
-	resetInternalStateAfterParamsUpdate();
-	return {SupplicantStatusCode::SUCCESS, "Dummy implementation"};
-#else
-	return {SupplicantStatusCode::FAILURE_UNKNOWN, "Not implemented"};
-#endif
-}
-
-std::pair<SupplicantStatus, std::vector<uint8_t>> StaNetwork::getSsidInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	std::vector<uint8_t> ssid;
-	ssid.assign(wpa_ssid->ssid, wpa_ssid->ssid + wpa_ssid->ssid_len);
-	return {{SupplicantStatusCode::SUCCESS, ""}, std::move(ssid)};
-}
-
-std::pair<SupplicantStatus, std::array<uint8_t, 6>>
-StaNetwork::getBssidInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	std::array<uint8_t, 6> bssid{};
-	os_memcpy(bssid.data(), kZeroBssid, ETH_ALEN);
-	if (wpa_ssid->bssid_set) {
-		os_memcpy(bssid.data(), wpa_ssid->bssid, ETH_ALEN);
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, std::move(bssid)};
-}
-
-std::pair<SupplicantStatus, bool> StaNetwork::getScanSsidInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		(wpa_ssid->scan_ssid == 1)};
-}
-
-std::pair<SupplicantStatus, uint32_t> StaNetwork::getKeyMgmtInternal()
-{
-	return {{SupplicantStatusCode::FAILURE_UNKNOWN, "deprecated"}, 0};
-}
-
-std::pair<SupplicantStatus, uint32_t> StaNetwork::getProtoInternal()
-{
-	return {{SupplicantStatusCode::FAILURE_UNKNOWN, "deprecated"}, 0};
-}
-
-std::pair<SupplicantStatus, uint32_t> StaNetwork::getAuthAlgInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		wpa_ssid->auth_alg & kAllowedAuthAlgMask};
-}
-
-std::pair<SupplicantStatus, uint32_t> StaNetwork::getGroupCipherInternal()
-{
-	return {{SupplicantStatusCode::FAILURE_UNKNOWN, "deprecated"}, 0};
-}
-
-std::pair<SupplicantStatus, uint32_t> StaNetwork::getPairwiseCipherInternal()
-{
-	return {{SupplicantStatusCode::FAILURE_UNKNOWN, "deprecated"}, 0};
-}
-
-std::pair<SupplicantStatus, std::string> StaNetwork::getPskPassphraseInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-#ifdef CONFIG_WAPI_INTERFACE
-	if (wpa_ssid->key_mgmt & WPA_KEY_MGMT_WAPI_PSK) {
-		if (wpa_ssid->psk_set) {
-			std::pair<SupplicantStatus, std::vector<uint8_t>> ret = getWapiPskInternal();
-			std::string psk;
-			char buf[3] = {0};
-			for (int i = 0; i < ret.second.size(); i++) {
-				snprintf(buf, sizeof(buf), "%02x", ret.second[i]);
-				psk.append(buf);
-			}
-			return {{SupplicantStatusCode::SUCCESS, ""}, psk};
-		} else {
-			if (!wpa_ssid->passphrase) {
-				return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-			}
-			std::string passphrase;
-			passphrase.append("\"");
-			passphrase.append(wpa_ssid->passphrase);
-			passphrase.append("\"");
-			return {{SupplicantStatusCode::SUCCESS, ""}, passphrase};
-		}
-	}
-#endif
-	if (!wpa_ssid->passphrase) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, wpa_ssid->passphrase};
-}
-
-std::pair<SupplicantStatus, std::array<uint8_t, 32>>
-StaNetwork::getPskInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	WPA_ASSERT(psk.size() == sizeof(wpa_ssid->psk));
-	if (!wpa_ssid->psk_set) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	std::array<uint8_t, 32> psk;
-	os_memcpy(psk.data(), wpa_ssid->psk, psk.size());
-	return {{SupplicantStatusCode::SUCCESS, ""}, psk};
-}
-
-std::pair<SupplicantStatus, std::string> StaNetwork::getSaePasswordInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->sae_password) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, wpa_ssid->sae_password};
-}
-
-std::pair<SupplicantStatus, std::string> StaNetwork::getSaePasswordIdInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->sae_password_id) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, wpa_ssid->sae_password_id};
-}
-
-std::pair<SupplicantStatus, std::vector<uint8_t>> StaNetwork::getWepKeyInternal(
-    uint32_t key_idx)
-{
-	std::vector<uint8_t> wep_key;
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (key_idx >=
-	    static_cast<uint32_t>(
-		ISupplicantStaNetwork::ParamSizeLimits::WEP_KEYS_MAX_NUM)) {
-		return {{SupplicantStatusCode::FAILURE_ARGS_INVALID, ""},
-			wep_key};
-	}
-	wep_key.assign(
-	    wpa_ssid->wep_key[key_idx],
-	    wpa_ssid->wep_key[key_idx] + wpa_ssid->wep_key_len[key_idx]);
-	return {{SupplicantStatusCode::SUCCESS, ""}, std::move(wep_key)};
-}
-
-std::pair<SupplicantStatus, uint32_t> StaNetwork::getWepTxKeyIdxInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	return {{SupplicantStatusCode::SUCCESS, ""}, wpa_ssid->wep_tx_keyidx};
-}
-
-std::pair<SupplicantStatus, bool> StaNetwork::getRequirePmfInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		(wpa_ssid->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED)};
-}
-
-std::pair<SupplicantStatus, ISupplicantStaNetwork::EapMethod>
-StaNetwork::getEapMethodInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->eap.eap_methods) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	// wpa_supplicant can support setting multiple eap methods for each
-	// network. But, this is not really used by Android. So, just reading
-	// the first EAP method for each network.
-	const std::string eap_method_str = eap_get_name(
-	    wpa_ssid->eap.eap_methods[0].vendor,
-	    static_cast<enum eap_type>(wpa_ssid->eap.eap_methods[0].method));
-	size_t eap_method_idx =
-	    std::find(
-		std::begin(kEapMethodStrings), std::end(kEapMethodStrings),
-		eap_method_str) -
-	    std::begin(kEapMethodStrings);
-	if (eap_method_idx >= kEapMethodMax) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		static_cast<ISupplicantStaNetwork::EapMethod>(eap_method_idx)};
-}
-
-std::pair<SupplicantStatus, ISupplicantStaNetwork::EapPhase2Method>
-StaNetwork::getEapPhase2MethodInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->eap.phase2) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	const std::string eap_phase2_method_str_with_prefix =
-	    wpa_ssid->eap.phase2;
-	std::string eap_phase2_method_str;
-	// Strip out the phase 2 method prefix before doing a reverse lookup
-	// of phase 2 string to the Eap Phase 2 type.
-	if (eap_phase2_method_str_with_prefix.find(kEapPhase2AuthPrefix) == 0) {
-		eap_phase2_method_str =
-		    eap_phase2_method_str_with_prefix.substr(
-			strlen(kEapPhase2AuthPrefix),
-			eap_phase2_method_str_with_prefix.size());
-	} else if (
-	    eap_phase2_method_str_with_prefix.find(kEapPhase2AuthEapPrefix) ==
-	    0) {
-		eap_phase2_method_str =
-		    eap_phase2_method_str_with_prefix.substr(
-			strlen(kEapPhase2AuthEapPrefix),
-			eap_phase2_method_str_with_prefix.size());
-	}
-	size_t eap_phase2_method_idx =
-	    std::find(
-		std::begin(kEapPhase2MethodStrings),
-		std::end(kEapPhase2MethodStrings), eap_phase2_method_str) -
-	    std::begin(kEapPhase2MethodStrings);
-	if (eap_phase2_method_idx >= kEapPhase2MethodMax) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		static_cast<ISupplicantStaNetwork::EapPhase2Method>(
-		    eap_phase2_method_idx)};
-}
-
-std::pair<SupplicantStatus, std::vector<uint8_t>>
-StaNetwork::getEapIdentityInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->eap.identity) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		std::vector<uint8_t>(
-		    wpa_ssid->eap.identity,
-		    wpa_ssid->eap.identity + wpa_ssid->eap.identity_len)};
-}
-
-std::pair<SupplicantStatus, std::vector<uint8_t>>
-StaNetwork::getEapAnonymousIdentityInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->eap.anonymous_identity) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		std::vector<uint8_t>(
-		    wpa_ssid->eap.anonymous_identity,
-		    wpa_ssid->eap.anonymous_identity +
-			wpa_ssid->eap.anonymous_identity_len)};
-}
-
-std::pair<SupplicantStatus, std::vector<uint8_t>>
-StaNetwork::getEapPasswordInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->eap.password) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		std::vector<uint8_t>(
-		    wpa_ssid->eap.password,
-		    wpa_ssid->eap.password + wpa_ssid->eap.password_len)};
-}
-
-std::pair<SupplicantStatus, std::string> StaNetwork::getEapCACertInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->eap.cert.ca_cert) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		reinterpret_cast<char *>(wpa_ssid->eap.cert.ca_cert)};
-}
-
-std::pair<SupplicantStatus, std::string> StaNetwork::getEapCAPathInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->eap.cert.ca_path) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		reinterpret_cast<char *>(wpa_ssid->eap.cert.ca_path)};
-}
-
-std::pair<SupplicantStatus, std::string> StaNetwork::getEapClientCertInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->eap.cert.client_cert) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		reinterpret_cast<char *>(wpa_ssid->eap.cert.client_cert)};
-}
-
-std::pair<SupplicantStatus, std::string>
-StaNetwork::getEapPrivateKeyIdInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->eap.cert.key_id) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, wpa_ssid->eap.cert.key_id};
-}
-
-std::pair<SupplicantStatus, std::string>
-StaNetwork::getEapSubjectMatchInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->eap.cert.subject_match) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		reinterpret_cast<char *>(wpa_ssid->eap.cert.subject_match)};
-}
-
-std::pair<SupplicantStatus, std::string>
-StaNetwork::getEapAltSubjectMatchInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->eap.cert.altsubject_match) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		reinterpret_cast<char *>(wpa_ssid->eap.cert.altsubject_match)};
-}
-
-std::pair<SupplicantStatus, bool> StaNetwork::getEapEngineInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	return {{SupplicantStatusCode::SUCCESS, ""}, wpa_ssid->eap.cert.engine == 1};
-}
-
-std::pair<SupplicantStatus, std::string> StaNetwork::getEapEngineIDInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->eap.cert.engine_id) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, {wpa_ssid->eap.cert.engine_id}};
-}
-
-std::pair<SupplicantStatus, std::string>
-StaNetwork::getEapDomainSuffixMatchInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->eap.cert.domain_suffix_match) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		{wpa_ssid->eap.cert.domain_suffix_match}};
-}
-
-std::pair<SupplicantStatus, std::string> StaNetwork::getIdStrInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->id_str) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, {wpa_ssid->id_str}};
-}
-
-std::pair<V1_4::SupplicantStatus, bool> StaNetwork::getEdmgInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	return {{V1_4::SupplicantStatusCode::SUCCESS, ""},
-		(wpa_ssid->enable_edmg == 1)};
-}
-
-std::pair<SupplicantStatus, std::vector<uint8_t>>
-StaNetwork::getWpsNfcConfigurationTokenInternal()
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	auto token_buf = misc_utils::createWpaBufUniquePtr(
-	    wpas_wps_network_config_token(wpa_s, 0, wpa_ssid));
-	if (!token_buf) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		misc_utils::convertWpaBufToVector(token_buf.get())};
-}
-
-std::pair<SupplicantStatus, std::string> StaNetwork::getWapiCertSuiteInternal()
-{
-#ifdef CONFIG_WAPI_INTERFACE
-	return {{SupplicantStatusCode::SUCCESS, "Dummy implementation"}, dummyWapiCertSuite};
-#else
-	return {{SupplicantStatusCode::FAILURE_UNKNOWN, "Not implemented"}, {}};
-#endif
-}
-
-std::pair<SupplicantStatus, std::vector<uint8_t>> StaNetwork::getWapiPskInternal()
-{
-#ifdef CONFIG_WAPI_INTERFACE
-	return {{SupplicantStatusCode::SUCCESS, "Dummy implementation"}, dummyWapiPsk};
-#else
-	return {{SupplicantStatusCode::FAILURE_UNKNOWN, "Not implemented"}, {}};
-#endif
-}
-
-SupplicantStatus StaNetwork::enableInternal(bool no_connect)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (wpa_ssid->disabled == 2) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	if (no_connect) {
-		wpa_ssid->disabled = 0;
-	} else {
-		wpa_s->scan_min_time.sec = 0;
-		wpa_s->scan_min_time.usec = 0;
-		wpa_supplicant_enable_network(wpa_s, wpa_ssid);
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::disableInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (wpa_ssid->disabled == 2) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	wpa_supplicant_disable_network(wpa_s, wpa_ssid);
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::selectInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (wpa_ssid->disabled == 2) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	wpa_s->scan_min_time.sec = 0;
-	wpa_s->scan_min_time.usec = 0;
-	wpa_supplicant_select_network(wpa_s, wpa_ssid);
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::sendNetworkEapSimGsmAuthResponseInternal(
-    const std::vector<ISupplicantStaNetwork::NetworkResponseEapSimGsmAuthParams>
-	&vec_params)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	// Convert the incoming parameters to a string to pass to
-	// wpa_supplicant.
-	std::string ctrl_rsp_param = std::string(kNetworkEapSimGsmAuthResponse);
-	for (const auto &params : vec_params) {
-		uint32_t kc_hex_len = params.kc.size() * 2 + 1;
-		std::vector<char> kc_hex(kc_hex_len);
-		uint32_t sres_hex_len = params.sres.size() * 2 + 1;
-		std::vector<char> sres_hex(sres_hex_len);
-		wpa_snprintf_hex(
-		    kc_hex.data(), kc_hex.size(), params.kc.data(),
-		    params.kc.size());
-		wpa_snprintf_hex(
-		    sres_hex.data(), sres_hex.size(), params.sres.data(),
-		    params.sres.size());
-		ctrl_rsp_param += ":" + std::string(kc_hex.data()) + ":" +
-				  std::string(sres_hex.data());
-	}
-	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	if (wpa_supplicant_ctrl_rsp_handle(
-		wpa_s, wpa_ssid, rtype, ctrl_rsp_param.c_str(),
-		ctrl_rsp_param.size())) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	eapol_sm_notify_ctrl_response(wpa_s->eapol);
-	wpa_hexdump_ascii_key(
-	    MSG_DEBUG, "network sim gsm auth response param",
-	    (const u8 *)ctrl_rsp_param.c_str(), ctrl_rsp_param.size());
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::sendNetworkEapSimGsmAuthFailureInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
-	if (wpa_supplicant_ctrl_rsp_handle(
-		wpa_s, wpa_ssid, rtype, kNetworkEapSimGsmAuthFailure,
-		strlen(kNetworkEapSimGsmAuthFailure))) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	eapol_sm_notify_ctrl_response(wpa_s->eapol);
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::sendNetworkEapSimUmtsAuthResponseInternal(
-    const ISupplicantStaNetwork::NetworkResponseEapSimUmtsAuthParams &params)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	// Convert the incoming parameters to a string to pass to
-	// wpa_supplicant.
-	uint32_t ik_hex_len = params.ik.size() * 2 + 1;
-	std::vector<char> ik_hex(ik_hex_len);
-	uint32_t ck_hex_len = params.ck.size() * 2 + 1;
-	std::vector<char> ck_hex(ck_hex_len);
-	uint32_t res_hex_len = params.res.size() * 2 + 1;
-	std::vector<char> res_hex(res_hex_len);
-	wpa_snprintf_hex(
-	    ik_hex.data(), ik_hex.size(), params.ik.data(), params.ik.size());
-	wpa_snprintf_hex(
-	    ck_hex.data(), ck_hex.size(), params.ck.data(), params.ck.size());
-	wpa_snprintf_hex(
-	    res_hex.data(), res_hex.size(), params.res.data(),
-	    params.res.size());
-	std::string ctrl_rsp_param =
-	    std::string(kNetworkEapSimUmtsAuthResponse) + ":" +
-	    std::string(ik_hex.data()) + ":" + std::string(ck_hex.data()) +
-	    ":" + std::string(res_hex.data());
-	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	if (wpa_supplicant_ctrl_rsp_handle(
-		wpa_s, wpa_ssid, rtype, ctrl_rsp_param.c_str(),
-		ctrl_rsp_param.size())) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	eapol_sm_notify_ctrl_response(wpa_s->eapol);
-	wpa_hexdump_ascii_key(
-	    MSG_DEBUG, "network sim umts auth response param",
-	    (const u8 *)ctrl_rsp_param.c_str(), ctrl_rsp_param.size());
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::sendNetworkEapSimUmtsAutsResponseInternal(
-    const std::array<uint8_t, 14> &auts)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	uint32_t auts_hex_len = auts.size() * 2 + 1;
-	std::vector<char> auts_hex(auts_hex_len);
-	wpa_snprintf_hex(
-	    auts_hex.data(), auts_hex.size(), auts.data(), auts.size());
-	std::string ctrl_rsp_param =
-	    std::string(kNetworkEapSimUmtsAutsResponse) + ":" +
-	    std::string(auts_hex.data());
-	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	if (wpa_supplicant_ctrl_rsp_handle(
-		wpa_s, wpa_ssid, rtype, ctrl_rsp_param.c_str(),
-		ctrl_rsp_param.size())) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	eapol_sm_notify_ctrl_response(wpa_s->eapol);
-	wpa_hexdump_ascii_key(
-	    MSG_DEBUG, "network sim umts auts response param",
-	    (const u8 *)ctrl_rsp_param.c_str(), ctrl_rsp_param.size());
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::sendNetworkEapSimUmtsAuthFailureInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
-	if (wpa_supplicant_ctrl_rsp_handle(
-		wpa_s, wpa_ssid, rtype, kNetworkEapSimUmtsAuthFailure,
-		strlen(kNetworkEapSimUmtsAuthFailure))) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	eapol_sm_notify_ctrl_response(wpa_s->eapol);
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::sendNetworkEapIdentityResponseInternal(
-    const std::vector<uint8_t> &identity)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	std::string ctrl_rsp_param(identity.begin(), identity.end());
-	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_EAP_IDENTITY;
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	if (wpa_supplicant_ctrl_rsp_handle(
-		wpa_s, wpa_ssid, rtype, ctrl_rsp_param.c_str(),
-		ctrl_rsp_param.size())) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	eapol_sm_notify_ctrl_response(wpa_s->eapol);
-	wpa_hexdump_ascii_key(
-	    MSG_DEBUG, "network identity response param",
-	    (const u8 *)ctrl_rsp_param.c_str(), ctrl_rsp_param.size());
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::sendNetworkEapIdentityResponseInternal_1_1(
-    const std::vector<uint8_t> &identity,
-    const std::vector<uint8_t> &encrypted_imsi_identity)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	// format: plain identity + ":" + encrypted
-	// identity(encrypted_imsi_identity)
-	std::string ctrl_rsp_param =
-	    std::string(identity.begin(), identity.end()) + ":" +
-	    std::string(
-		encrypted_imsi_identity.begin(), encrypted_imsi_identity.end());
-	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_EAP_IDENTITY;
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	if (wpa_supplicant_ctrl_rsp_handle(
-		wpa_s, wpa_ssid, rtype, ctrl_rsp_param.c_str(),
-		ctrl_rsp_param.size())) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	eapol_sm_notify_ctrl_response(wpa_s->eapol);
-	wpa_hexdump_ascii_key(
-	    MSG_DEBUG, "network identity response param",
-	    (const u8 *)ctrl_rsp_param.c_str(), ctrl_rsp_param.size());
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::enableTlsSuiteBEapPhase1ParamInternal(bool enable)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	int val = enable == true ? 1 : 0;
-	std::string suiteb_phase1("tls_suiteb=" + std::to_string(val));
-
-	if (setStringKeyFieldAndResetState(
-		suiteb_phase1.c_str(), &(wpa_ssid->eap.phase1), "phase1")) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::enableSuiteBEapOpenSslCiphersInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	const char openssl_suiteb_cipher[] = "SUITEB192";
-
-	if (setStringKeyFieldAndResetState(
-		openssl_suiteb_cipher, &(wpa_ssid->eap.openssl_ciphers),
-		"openssl_ciphers")) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setSaePasswordInternal(
-    const std::string &sae_password)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (sae_password.length() < 1) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	if (wpa_ssid->sae_password &&
-	    os_strlen(wpa_ssid->sae_password) == sae_password.length() &&
-	    os_memcmp(
-		wpa_ssid->sae_password, sae_password.c_str(),
-		sae_password.length()) == 0) {
-		return {SupplicantStatusCode::SUCCESS, ""};
-	}
-	wpa_ssid->psk_set = 1;
-	if (setStringKeyFieldAndResetState(
-		sae_password.c_str(), &(wpa_ssid->sae_password),
-		"sae password")) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setSaePasswordIdInternal(
-    const std::string &sae_password_id)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (sae_password_id.length() < 1) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	if (wpa_ssid->sae_password_id &&
-	    os_strlen(wpa_ssid->sae_password_id) == sae_password_id.length() &&
-	    os_memcmp(
-		wpa_ssid->sae_password_id, sae_password_id.c_str(),
-		sae_password_id.length()) == 0) {
-		return {SupplicantStatusCode::SUCCESS, ""};
-	}
-	wpa_ssid->psk_set = 1;
-	if (setStringKeyFieldAndResetState(
-		sae_password_id.c_str(), &(wpa_ssid->sae_password_id),
-		"sae password id")) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setGroupMgmtCipherInternal(uint32_t
-		group_mgmt_cipher_mask)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (group_mgmt_cipher_mask & ~kAllowedGroupMgmtCipherMask) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	wpa_ssid->group_mgmt_cipher = group_mgmt_cipher_mask;
-	wpa_printf(MSG_MSGDUMP, "group_mgmt_cipher: 0x%x",
-			wpa_ssid->group_mgmt_cipher);
-	resetInternalStateAfterParamsUpdate();
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-std::pair<SupplicantStatus, uint32_t> StaNetwork::getGroupMgmtCipherInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		wpa_ssid->group_mgmt_cipher & kAllowedGroupMgmtCipherMask};
-}
-
-SupplicantStatus StaNetwork::setOcspInternal(V1_3::OcspType ocspType) {
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (ocspType < V1_3::OcspType::NONE || ocspType > V1_3::OcspType::REQUIRE_ALL_CERTS_STATUS) {
-		return{ SupplicantStatusCode::FAILURE_ARGS_INVALID, "" };
-	}
-	wpa_ssid->eap.cert.ocsp = (int) ocspType;
-	wpa_printf(
-	    MSG_MSGDUMP, "ocsp: %d", wpa_ssid->eap.cert.ocsp);
-	resetInternalStateAfterParamsUpdate();
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-std::pair<SupplicantStatus, V1_3::OcspType> StaNetwork::getOcspInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		(V1_3::OcspType) wpa_ssid->eap.cert.ocsp};
-}
-
-SupplicantStatus StaNetwork::setPmkCacheInternal(const std::vector<uint8_t>& serializedEntry) {
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	struct rsn_pmksa_cache_entry *new_entry = NULL;
-
-	new_entry = (struct rsn_pmksa_cache_entry *) os_zalloc(sizeof(*new_entry));
-	if (!new_entry) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, "Allocating memory failed"};
-	}
-
-	std::stringstream ss(
-	    std::stringstream::in | std::stringstream::out | std::stringstream::binary);
-	ss.write((char *) serializedEntry.data(), std::streamsize(serializedEntry.size()));
-	misc_utils::deserializePmkCacheEntry(ss, new_entry);
-	new_entry->network_ctx = wpa_ssid;
-	wpa_sm_pmksa_cache_add_entry(wpa_s->wpa, new_entry);
-
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setKeyMgmt_1_3Internal(uint32_t key_mgmt_mask)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (key_mgmt_mask & ~kAllowedKeyMgmtMask) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	setFastTransitionKeyMgmt(key_mgmt_mask);
-
-	if (key_mgmt_mask & WPA_KEY_MGMT_OWE) {
-		// Do not allow to connect to Open network when OWE is selected
-		wpa_ssid->owe_only = 1;
-	}
-	wpa_ssid->key_mgmt = key_mgmt_mask;
-	wpa_printf(MSG_MSGDUMP, "key_mgmt: 0x%x", wpa_ssid->key_mgmt);
-	resetInternalStateAfterParamsUpdate();
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-std::pair<SupplicantStatus, uint32_t> StaNetwork::getKeyMgmt_1_3Internal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	uint32_t key_mgmt_mask = wpa_ssid->key_mgmt & kAllowedKeyMgmtMask;
-
-	resetFastTransitionKeyMgmt(key_mgmt_mask);
-	return {{SupplicantStatusCode::SUCCESS, ""}, key_mgmt_mask};
-}
-
-SupplicantStatus StaNetwork::setProto_1_3Internal(uint32_t proto_mask)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (proto_mask & ~kAllowedProtoMask) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	wpa_ssid->proto = proto_mask;
-	wpa_printf(MSG_MSGDUMP, "proto: 0x%x", wpa_ssid->proto);
-	resetInternalStateAfterParamsUpdate();
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-std::pair<SupplicantStatus, uint32_t> StaNetwork::getProto_1_3Internal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		wpa_ssid->proto & kAllowedProtoMask};
-}
-
-SupplicantStatus StaNetwork::setGroupCipher_1_3Internal(uint32_t group_cipher_mask)
-{
-	return {SupplicantStatusCode::FAILURE_UNKNOWN, "deprecated"};
-}
-
-std::pair<SupplicantStatus, uint32_t> StaNetwork::getGroupCipher_1_3Internal()
-{
-	return {{SupplicantStatusCode::FAILURE_UNKNOWN, "deprecated"}, 0};
-}
-
-SupplicantStatus StaNetwork::setPairwiseCipher_1_3Internal(
-    uint32_t pairwise_cipher_mask)
-{
-	return {SupplicantStatusCode::FAILURE_UNKNOWN, "deprecated"};
-}
-
-std::pair<SupplicantStatus, uint32_t> StaNetwork::getPairwiseCipher_1_3Internal()
-{
-	return {{SupplicantStatusCode::FAILURE_UNKNOWN, "deprecated"}, 0};
-}
-
-V1_4::SupplicantStatus StaNetwork::setGroupCipher_1_4Internal(uint32_t group_cipher_mask)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (group_cipher_mask & ~kAllowedGroupCipherMask) {
-		return {V1_4::SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	wpa_ssid->group_cipher = group_cipher_mask;
-	wpa_printf(MSG_MSGDUMP, "group_cipher: 0x%x", wpa_ssid->group_cipher);
-	resetInternalStateAfterParamsUpdate();
-	return {V1_4::SupplicantStatusCode::SUCCESS, ""};
-}
-
-std::pair<V1_4::SupplicantStatus, uint32_t> StaNetwork::getGroupCipher_1_4Internal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	return {{V1_4::SupplicantStatusCode::SUCCESS, ""},
-		wpa_ssid->group_cipher & kAllowedGroupCipherMask};
-}
-
-V1_4::SupplicantStatus StaNetwork::setPairwiseCipher_1_4Internal(
-    uint32_t pairwise_cipher_mask)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (pairwise_cipher_mask & ~kAllowedPairwisewCipherMask) {
-		return {V1_4::SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	wpa_ssid->pairwise_cipher = pairwise_cipher_mask;
-	wpa_printf(
-	    MSG_MSGDUMP, "pairwise_cipher: 0x%x", wpa_ssid->pairwise_cipher);
-	resetInternalStateAfterParamsUpdate();
-	return {V1_4::SupplicantStatusCode::SUCCESS, ""};
-}
-
-std::pair<V1_4::SupplicantStatus, uint32_t> StaNetwork::getPairwiseCipher_1_4Internal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	return {{V1_4::SupplicantStatusCode::SUCCESS, ""},
-		wpa_ssid->pairwise_cipher & kAllowedPairwisewCipherMask};
-}
-
-/**
- * Retrieve the underlying |wpa_ssid| struct pointer for
- * this network.
- * If the underlying network is removed or the interface
- * this network belong to
- * is removed, all RPC method calls on this object will
- * return failure.
- */
-struct wpa_ssid *StaNetwork::retrieveNetworkPtr()
-{
-	wpa_supplicant *wpa_s = retrieveIfacePtr();
-	if (!wpa_s)
-		return nullptr;
-	return wpa_config_get_network(wpa_s->conf, network_id_);
-}
-
-/**
- * Retrieve the underlying |wpa_supplicant| struct
- * pointer for
- * this network.
- */
-struct wpa_supplicant *StaNetwork::retrieveIfacePtr()
-{
-	return wpa_supplicant_get_iface(wpa_global_, ifname_.c_str());
-}
-
-/**
- * Check if the provided psk passhrase is valid or not.
- *
- * Returns 0 if valid, 1 otherwise.
- */
-int StaNetwork::isPskPassphraseValid(const std::string &psk)
-{
-	if (psk.size() <
-		static_cast<uint32_t>(ISupplicantStaNetwork::ParamSizeLimits::
-					  PSK_PASSPHRASE_MIN_LEN_IN_BYTES) ||
-	    psk.size() >
-		static_cast<uint32_t>(ISupplicantStaNetwork::ParamSizeLimits::
-					  PSK_PASSPHRASE_MAX_LEN_IN_BYTES)) {
-		return 1;
-	}
-	if (has_ctrl_char((u8 *)psk.c_str(), psk.size())) {
-		return 1;
-	}
-	return 0;
-}
-
-/**
- * Reset internal wpa_supplicant state machine state
- * after params update (except
- * bssid).
- */
-void StaNetwork::resetInternalStateAfterParamsUpdate()
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-
-	wpa_sm_pmksa_cache_flush(wpa_s->wpa, wpa_ssid);
-
-	if (wpa_s->current_ssid == wpa_ssid || wpa_s->current_ssid == NULL) {
-		/*
-		 * Invalidate the EAP session cache if
-		 * anything in the
-		 * current or previously used
-		 * configuration changes.
-		 */
-		eapol_sm_invalidate_cached_session(wpa_s->eapol);
-	}
-}
-
-/**
- * Helper function to set value in a string field in |wpa_ssid| structue
- * instance for this network.
- * This function frees any existing data in these fields.
- */
-int StaNetwork::setStringFieldAndResetState(
-    const char *value, uint8_t **to_update_field, const char *hexdump_prefix)
-{
-	return setStringFieldAndResetState(
-	    value, (char **)to_update_field, hexdump_prefix);
-}
-
-/**
- * Helper function to set value in a string field in |wpa_ssid| structue
- * instance for this network.
- * This function frees any existing data in these fields.
- */
-int StaNetwork::setStringFieldAndResetState(
-    const char *value, char **to_update_field, const char *hexdump_prefix)
-{
-	int value_len = strlen(value);
-	if (*to_update_field) {
-		os_free(*to_update_field);
-	}
-	*to_update_field = dup_binstr(value, value_len);
-	if (!(*to_update_field)) {
-		return 1;
-	}
-	wpa_hexdump_ascii(
-	    MSG_MSGDUMP, hexdump_prefix, *to_update_field, value_len);
-	resetInternalStateAfterParamsUpdate();
-	return 0;
-}
-
-/**
- * Helper function to set value in a string key field in |wpa_ssid| structue
- * instance for this network.
- * This function frees any existing data in these fields.
- */
-int StaNetwork::setStringKeyFieldAndResetState(
-    const char *value, char **to_update_field, const char *hexdump_prefix)
-{
-	int value_len = strlen(value);
-	if (*to_update_field) {
-		str_clear_free(*to_update_field);
-	}
-	*to_update_field = dup_binstr(value, value_len);
-	if (!(*to_update_field)) {
-		return 1;
-	}
-	wpa_hexdump_ascii_key(
-	    MSG_MSGDUMP, hexdump_prefix, *to_update_field, value_len);
-	resetInternalStateAfterParamsUpdate();
-	return 0;
-}
-
-/**
- * Helper function to set value in a string field with a corresponding length
- * field in |wpa_ssid| structue instance for this network.
- * This function frees any existing data in these fields.
- */
-int StaNetwork::setByteArrayFieldAndResetState(
-    const uint8_t *value, const size_t value_len, uint8_t **to_update_field,
-    size_t *to_update_field_len, const char *hexdump_prefix)
-{
-	if (*to_update_field) {
-		os_free(*to_update_field);
-	}
-	*to_update_field = (uint8_t *)os_malloc(value_len);
-	if (!(*to_update_field)) {
-		return 1;
-	}
-	os_memcpy(*to_update_field, value, value_len);
-	*to_update_field_len = value_len;
-
-	wpa_hexdump_ascii(
-	    MSG_MSGDUMP, hexdump_prefix, *to_update_field,
-	    *to_update_field_len);
-	resetInternalStateAfterParamsUpdate();
-	return 0;
-}
-
-/**
- * Helper function to set value in a string key field with a corresponding
- * length field in |wpa_ssid| structue instance for this network.
- * This function frees any existing data in these fields.
- */
-int StaNetwork::setByteArrayKeyFieldAndResetState(
-    const uint8_t *value, const size_t value_len, uint8_t **to_update_field,
-    size_t *to_update_field_len, const char *hexdump_prefix)
-{
-	if (*to_update_field) {
-		bin_clear_free(*to_update_field, *to_update_field_len);
-	}
-	*to_update_field = (uint8_t *)os_malloc(value_len);
-	if (!(*to_update_field)) {
-		return 1;
-	}
-	os_memcpy(*to_update_field, value, value_len);
-	*to_update_field_len = value_len;
-
-	wpa_hexdump_ascii_key(
-	    MSG_MSGDUMP, hexdump_prefix, *to_update_field,
-	    *to_update_field_len);
-	resetInternalStateAfterParamsUpdate();
-	return 0;
-}
-
-/**
- * Helper function to set the fast transition bits in the key management
- * bitmask, to allow FT support when possible.
- */
-void StaNetwork::setFastTransitionKeyMgmt(uint32_t &key_mgmt_mask)
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	int res;
-	struct wpa_driver_capa capa;
-
-	if (key_mgmt_mask & WPA_KEY_MGMT_PSK) {
-		key_mgmt_mask |= WPA_KEY_MGMT_FT_PSK;
-	}
-
-	if (key_mgmt_mask & WPA_KEY_MGMT_IEEE8021X) {
-		key_mgmt_mask |= WPA_KEY_MGMT_FT_IEEE8021X;
-	}
-
-	res = wpa_drv_get_capa(wpa_s, &capa);
-	if (res == 0) {
-#ifdef CONFIG_IEEE80211R
-#ifdef CONFIG_SAE
-		if ((key_mgmt_mask & WPA_KEY_MGMT_SAE) &&
-		    (capa.key_mgmt_iftype[WPA_IF_STATION] & WPA_DRIVER_CAPA_KEY_MGMT_FT_SAE)) {
-			key_mgmt_mask |= WPA_KEY_MGMT_FT_SAE;
-		}
-#endif
-#endif
-	}
-
-}
-
-/**
- * Helper function to reset the fast transition bits in the key management
- * bitmask.
- */
-void StaNetwork::resetFastTransitionKeyMgmt(uint32_t &key_mgmt_mask)
-{
-	if (key_mgmt_mask & WPA_KEY_MGMT_PSK) {
-		key_mgmt_mask &= ~WPA_KEY_MGMT_FT_PSK;
-	}
-
-	if (key_mgmt_mask & WPA_KEY_MGMT_IEEE8021X) {
-		key_mgmt_mask &= ~WPA_KEY_MGMT_FT_IEEE8021X;
-	}
-#ifdef CONFIG_IEEE80211R
-#ifdef CONFIG_SAE
-	if (key_mgmt_mask & WPA_KEY_MGMT_SAE) {
-		key_mgmt_mask &= ~WPA_KEY_MGMT_FT_SAE;
-	}
-#endif
-#endif
-}
-
-/**
- * Helper function to enable erp keys generation while connecting to FILS
- * enabled APs.
- */
-SupplicantStatus StaNetwork::setEapErpInternal(bool enable)
-{
-#ifdef CONFIG_FILS
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	wpa_ssid->eap.erp = enable ? 1 : 0;
-	return {SupplicantStatusCode::SUCCESS, ""};
-#else /* CONFIG_FILS */
-	return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-#endif /* CONFIG_FILS */
-}
-
-V1_4::SupplicantStatus StaNetwork::setSaeH2eModeInternal(
-    ISupplicantStaNetworkV1_4::SaeH2eMode mode)
-{
-	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	switch (mode) {
-	case ISupplicantStaNetworkV1_4::SaeH2eMode::DISABLED:
-		wpa_s->conf->sae_pwe = 0;
-		break;
-	case ISupplicantStaNetworkV1_4::SaeH2eMode::H2E_MANDATORY:
-		wpa_s->conf->sae_pwe = 1;
-		break;
-	case ISupplicantStaNetworkV1_4::SaeH2eMode::H2E_OPTIONAL:
-		wpa_s->conf->sae_pwe = 2;
-		break;
-	}
-	resetInternalStateAfterParamsUpdate();
-	return {V1_4::SupplicantStatusCode::SUCCESS, ""};
-}
-
-V1_4::SupplicantStatus StaNetwork::enableSaePkOnlyModeInternal(bool enable)
-{
-#ifdef CONFIG_SAE_PK
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	wpa_ssid->sae_pk = enable ? SAE_PK_MODE_ONLY : SAE_PK_MODE_AUTOMATIC;
-	resetInternalStateAfterParamsUpdate();
-	return {V1_4::SupplicantStatusCode::SUCCESS, ""};
-#else
-	return {V1_4::SupplicantStatusCode::FAILURE_UNSUPPORTED, ""};
-#endif
-}
-
-}  // namespace implementation
-}  // namespace V1_4
-}  // namespace supplicant
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wpa_supplicant/hidl/1.4/sta_network.h b/wpa_supplicant/hidl/1.4/sta_network.h
deleted file mode 100644
index 152f00f..0000000
--- a/wpa_supplicant/hidl/1.4/sta_network.h
+++ /dev/null
@@ -1,465 +0,0 @@
-/*
- * hidl interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WPA_SUPPLICANT_HIDL_STA_NETWORK_H
-#define WPA_SUPPLICANT_HIDL_STA_NETWORK_H
-
-#include <array>
-#include <vector>
-
-#include <android-base/macros.h>
-
-#include <android/hardware/wifi/supplicant/1.4/ISupplicantStaNetwork.h>
-#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaNetworkCallback.h>
-
-extern "C"
-{
-#include "utils/common.h"
-#include "utils/includes.h"
-#include "config.h"
-#include "wpa_supplicant_i.h"
-#include "notify.h"
-#include "eapol_supp/eapol_supp_sm.h"
-#include "eap_peer/eap.h"
-#include "rsn_supp/wpa.h"
-}
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_4 {
-namespace implementation {
-using V1_0::ISupplicantStaNetworkCallback;
-using V1_2::DppFailureCode;
-using V1_2::DppProgressCode;
-
-/**
- * Implementation of StaNetwork hidl object. Each unique hidl
- * object is used for control operations on a specific network
- * controlled by wpa_supplicant.
- */
-class StaNetwork : public V1_4::ISupplicantStaNetwork
-{
-public:
-	StaNetwork(
-	    struct wpa_global* wpa_global, const char ifname[], int network_id);
-	~StaNetwork() override = default;
-	// Refer to |StaIface::invalidate()|.
-	void invalidate();
-	bool isValid();
-
-	// Hidl methods exposed.
-	Return<void> getId(getId_cb _hidl_cb) override;
-	Return<void> getInterfaceName(getInterfaceName_cb _hidl_cb) override;
-	Return<void> getType(getType_cb _hidl_cb) override;
-	Return<void> registerCallback(
-	    const sp<ISupplicantStaNetworkCallback>& callback,
-	    registerCallback_cb _hidl_cb) override;
-	Return<void> registerCallback_1_4(
-	    const sp<V1_4::ISupplicantStaNetworkCallback>& callback,
-	    registerCallback_1_4_cb _hidl_cb) override;
-	Return<void> setSsid(
-	    const hidl_vec<uint8_t>& ssid, setSsid_cb _hidl_cb) override;
-	Return<void> setBssid(
-	    const hidl_array<uint8_t, 6>& bssid, setBssid_cb _hidl_cb) override;
-	Return<void> setScanSsid(bool enable, setScanSsid_cb _hidl_cb) override;
-	Return<void> setKeyMgmt(
-	    uint32_t key_mgmt_mask, setKeyMgmt_cb _hidl_cb) override;
-	Return<void> setProto(
-	    uint32_t proto_mask, setProto_cb _hidl_cb) override;
-	Return<void> setAuthAlg(
-	    uint32_t auth_alg_mask, setAuthAlg_cb _hidl_cb) override;
-	Return<void> setGroupCipher(
-	    uint32_t group_cipher_mask, setGroupCipher_cb _hidl_cb) override;
-	Return<void> setPairwiseCipher(
-	    uint32_t pairwise_cipher_mask,
-	    setPairwiseCipher_cb _hidl_cb) override;
-	Return<void> setPskPassphrase(
-	    const hidl_string& psk, setPskPassphrase_cb _hidl_cb) override;
-	Return<void> setPsk(
-	    const hidl_array<uint8_t, 32>& psk, setPsk_cb _hidl_cb) override;
-	Return<void> setWepKey(
-	    uint32_t key_idx, const hidl_vec<uint8_t>& wep_key,
-	    setWepKey_cb _hidl_cb) override;
-	Return<void> setWepTxKeyIdx(
-	    uint32_t key_idx, setWepTxKeyIdx_cb _hidl_cb) override;
-	Return<void> setRequirePmf(
-	    bool enable, setRequirePmf_cb _hidl_cb) override;
-	Return<void> setEapMethod(
-	    ISupplicantStaNetwork::EapMethod method,
-	    setEapMethod_cb _hidl_cb) override;
-	Return<void> setEapPhase2Method(
-	    ISupplicantStaNetwork::EapPhase2Method method,
-	    setEapPhase2Method_cb _hidl_cb) override;
-	Return<void> setEapIdentity(
-	    const hidl_vec<uint8_t>& identity,
-	    setEapIdentity_cb _hidl_cb) override;
-	Return<void> setEapAnonymousIdentity(
-	    const hidl_vec<uint8_t>& identity,
-	    setEapAnonymousIdentity_cb _hidl_cb) override;
-	Return<void> setEapPassword(
-	    const hidl_vec<uint8_t>& password,
-	    setEapPassword_cb _hidl_cb) override;
-	Return<void> setEapCACert(
-	    const hidl_string& path, setEapCACert_cb _hidl_cb) override;
-	Return<void> setEapCAPath(
-	    const hidl_string& path, setEapCAPath_cb _hidl_cb) override;
-	Return<void> setEapClientCert(
-	    const hidl_string& path, setEapClientCert_cb _hidl_cb) override;
-	Return<void> setEapPrivateKeyId(
-	    const hidl_string& id, setEapPrivateKeyId_cb _hidl_cb) override;
-	Return<void> setEapEncryptedImsiIdentity(
-	    const EapSimEncryptedIdentity& identity,
-	    setEapEncryptedImsiIdentity_cb _hidl_cb) override;
-	Return<void> setEapSubjectMatch(
-	    const hidl_string& match, setEapSubjectMatch_cb _hidl_cb) override;
-	Return<void> setEapAltSubjectMatch(
-	    const hidl_string& match,
-	    setEapAltSubjectMatch_cb _hidl_cb) override;
-	Return<void> setEapEngine(
-	    bool enable, setEapEngine_cb _hidl_cb) override;
-	Return<void> setEapEngineID(
-	    const hidl_string& id, setEapEngineID_cb _hidl_cb) override;
-	Return<void> setEapDomainSuffixMatch(
-	    const hidl_string& match,
-	    setEapDomainSuffixMatch_cb _hidl_cb) override;
-	Return<void> setProactiveKeyCaching(
-	    bool enable, setProactiveKeyCaching_cb _hidl_cb) override;
-	Return<void> setIdStr(
-	    const hidl_string& id_str, setIdStr_cb _hidl_cb) override;
-	Return<void> setUpdateIdentifier(
-	    uint32_t id, setUpdateIdentifier_cb _hidl_cb) override;
-	Return<void> setEdmg(bool enable, setEdmg_cb _hidl_cb) override;
-	Return<void> getSsid(getSsid_cb _hidl_cb) override;
-	Return<void> getBssid(getBssid_cb _hidl_cb) override;
-	Return<void> getScanSsid(getScanSsid_cb _hidl_cb) override;
-	Return<void> getKeyMgmt(getKeyMgmt_cb _hidl_cb) override;
-	Return<void> getProto(getProto_cb _hidl_cb) override;
-	Return<void> getAuthAlg(getAuthAlg_cb _hidl_cb) override;
-	Return<void> getGroupCipher(getGroupCipher_cb _hidl_cb) override;
-	Return<void> getPairwiseCipher(getPairwiseCipher_cb _hidl_cb) override;
-	Return<void> getPskPassphrase(getPskPassphrase_cb _hidl_cb) override;
-	Return<void> getPsk(getPsk_cb _hidl_cb) override;
-	Return<void> getSaePassword(getSaePassword_cb _hidl_cb) override;
-	Return<void> getSaePasswordId(getSaePasswordId_cb _hidl_cb) override;
-	Return<void> getWepKey(
-	    uint32_t key_idx, getWepKey_cb _hidl_cb) override;
-	Return<void> getWepTxKeyIdx(getWepTxKeyIdx_cb _hidl_cb) override;
-	Return<void> getRequirePmf(getRequirePmf_cb _hidl_cb) override;
-	Return<void> getEapMethod(getEapMethod_cb _hidl_cb) override;
-	Return<void> getEapPhase2Method(
-	    getEapPhase2Method_cb _hidl_cb) override;
-	Return<void> getEapIdentity(getEapIdentity_cb _hidl_cb) override;
-	Return<void> getEapAnonymousIdentity(
-	    getEapAnonymousIdentity_cb _hidl_cb) override;
-	Return<void> getEapPassword(getEapPassword_cb _hidl_cb) override;
-	Return<void> getEapCACert(getEapCACert_cb _hidl_cb) override;
-	Return<void> getEapCAPath(getEapCAPath_cb _hidl_cb) override;
-	Return<void> getEapClientCert(getEapClientCert_cb _hidl_cb) override;
-	Return<void> getEapPrivateKeyId(
-	    getEapPrivateKeyId_cb _hidl_cb) override;
-	Return<void> getEapSubjectMatch(
-	    getEapSubjectMatch_cb _hidl_cb) override;
-	Return<void> getEapAltSubjectMatch(
-	    getEapAltSubjectMatch_cb _hidl_cb) override;
-	Return<void> getEapEngine(getEapEngine_cb _hidl_cb) override;
-	Return<void> getEapEngineID(getEapEngineID_cb _hidl_cb) override;
-	Return<void> getEapDomainSuffixMatch(
-	    getEapDomainSuffixMatch_cb _hidl_cb) override;
-	Return<void> getIdStr(getIdStr_cb _hidl_cb) override;
-	Return<void> getWpsNfcConfigurationToken(
-	    getWpsNfcConfigurationToken_cb _hidl_cb) override;
-	Return<void> getEdmg(getEdmg_cb _hidl_cb) override;
-	Return<void> enable(bool no_connect, enable_cb _hidl_cb) override;
-	Return<void> disable(disable_cb _hidl_cb) override;
-	Return<void> select(select_cb _hidl_cb) override;
-	Return<void> sendNetworkEapSimGsmAuthResponse(
-	    const hidl_vec<
-		ISupplicantStaNetwork::NetworkResponseEapSimGsmAuthParams>&
-		vec_params,
-	    sendNetworkEapSimGsmAuthResponse_cb _hidl_cb) override;
-	Return<void> sendNetworkEapSimGsmAuthFailure(
-	    sendNetworkEapSimGsmAuthFailure_cb _hidl_cb) override;
-	Return<void> sendNetworkEapSimUmtsAuthResponse(
-	    const ISupplicantStaNetwork::NetworkResponseEapSimUmtsAuthParams&
-		params,
-	    sendNetworkEapSimUmtsAuthResponse_cb _hidl_cb) override;
-	Return<void> sendNetworkEapSimUmtsAutsResponse(
-	    const hidl_array<uint8_t, 14>& auts,
-	    sendNetworkEapSimUmtsAutsResponse_cb _hidl_cb) override;
-	Return<void> sendNetworkEapSimUmtsAuthFailure(
-	    sendNetworkEapSimUmtsAuthFailure_cb _hidl_cb) override;
-	Return<void> sendNetworkEapIdentityResponse(
-	    const hidl_vec<uint8_t>& identity,
-	    sendNetworkEapIdentityResponse_cb _hidl_cb) override;
-	Return<void> sendNetworkEapIdentityResponse_1_1(
-	    const EapSimIdentity& identity,
-	    const EapSimEncryptedIdentity& imsiIdentity,
-	    sendNetworkEapIdentityResponse_1_1_cb _hidl_cb) override;
-	Return<void> setKeyMgmt_1_2(
-	    uint32_t key_mgmt_mask, setKeyMgmt_1_2_cb _hidl_cb) override;
-	Return<void> getKeyMgmt_1_2(getKeyMgmt_1_2_cb _hidl_cb) override;
-	Return<void> setPairwiseCipher_1_2(
-	    uint32_t pairwise_cipher_mask,
-	    setPairwiseCipher_1_2_cb _hidl_cb) override;
-	Return<void> getPairwiseCipher_1_2(
-	    getPairwiseCipher_1_2_cb _hidl_cb) override;
-	Return<void> setGroupCipher_1_2(
-	    uint32_t group_cipher_mask,
-	    setGroupCipher_1_2_cb _hidl_cb) override;
-	Return<void> getGroupCipher_1_2(
-	    getGroupCipher_1_2_cb _hidl_cb) override;
-	Return<void> setGroupMgmtCipher(
-	    uint32_t group_mgmt_cipher_mask,
-	    setGroupMgmtCipher_cb _hidl_cb) override;
-	Return<void> getGroupMgmtCipher(
-	    getGroupMgmtCipher_cb _hidl_cb) override;
-	Return<void> enableTlsSuiteBEapPhase1Param(
-	    bool enable, enableTlsSuiteBEapPhase1Param_cb _hidl_cb) override;
-	Return<void> enableSuiteBEapOpenSslCiphers(
-	    enableSuiteBEapOpenSslCiphers_cb _hidl_cb) override;
-	Return<void> setSaePassword(
-	    const hidl_string& sae_password,
-	    setSaePassword_cb _hidl_cb) override;
-	Return<void> setSaePasswordId(
-	    const hidl_string& sae_password_id,
-	    setSaePasswordId_cb _hidl_cb) override;
-	Return<void> setOcsp(
-	    V1_3::OcspType ocspType, setOcsp_cb _hidl_cb) override;
-	Return<void> getOcsp(
-	    getOcsp_cb _hidl_cb) override;
-	Return<void> setPmkCache(const hidl_vec<uint8_t>& serializedEntry,
-			setPmkCache_cb _hidl_cb) override;
-	Return<void> setKeyMgmt_1_3(
-	    uint32_t key_mgmt_mask, setKeyMgmt_1_3_cb _hidl_cb) override;
-	Return<void> getKeyMgmt_1_3(getKeyMgmt_1_3_cb _hidl_cb) override;
-	Return<void> setProto_1_3(
-	    uint32_t proto_mask, setProto_cb _hidl_cb) override;
-	Return<void> getProto_1_3(getProto_cb _hidl_cb) override;
-	Return<void> setPairwiseCipher_1_3(
-	    uint32_t pairwise_cipher_mask,
-	    setPairwiseCipher_1_3_cb _hidl_cb) override;
-	Return<void> getPairwiseCipher_1_3(
-	    getPairwiseCipher_1_3_cb _hidl_cb) override;
-	Return<void> setGroupCipher_1_3(
-	    uint32_t group_cipher_mask,
-	    setGroupCipher_1_3_cb _hidl_cb) override;
-	Return<void> getGroupCipher_1_3(
-	    getGroupCipher_1_3_cb _hidl_cb) override;
-	Return<void> setWapiCertSuite(
-	    const hidl_string& suite, setWapiCertSuite_cb _hidl_cb) override;
-	Return<void> getWapiCertSuite(getWapiCertSuite_cb _hidl_cb) override;
-	Return<void> getAuthAlg_1_3(getAuthAlg_cb _hidl_cb) override;
-	Return<void> setAuthAlg_1_3(uint32_t auth_alg_mask,
-			std::function<void(const SupplicantStatus &status)> _hidl_cb)
-					override;
-	Return<void> setEapErp(bool enable, setEapErp_cb _hidl_cb) override;
-	Return<void> setPairwiseCipher_1_4(
-	    uint32_t pairwise_cipher_mask,
-	    setPairwiseCipher_1_4_cb _hidl_cb) override;
-	Return<void> getPairwiseCipher_1_4(
-	    getPairwiseCipher_1_4_cb _hidl_cb) override;
-	Return<void> setGroupCipher_1_4(
-	    uint32_t group_cipher_mask,
-	    setGroupCipher_1_4_cb _hidl_cb) override;
-	Return<void> getGroupCipher_1_4(
-	    getGroupCipher_1_4_cb _hidl_cb) override;
-	Return<void> setSaeH2eMode(V1_4::ISupplicantStaNetwork::SaeH2eMode mode,
-	    setSaeH2eMode_cb _hidl_cb) override;
-	Return<void> enableSaePkOnlyMode(bool enable, enableSaePkOnlyMode_cb _hidl_cb) override;
-
-private:
-	// Corresponding worker functions for the HIDL methods.
-	std::pair<SupplicantStatus, uint32_t> getIdInternal();
-	std::pair<SupplicantStatus, std::string> getInterfaceNameInternal();
-	std::pair<SupplicantStatus, IfaceType> getTypeInternal();
-	SupplicantStatus registerCallbackInternal(
-	    const sp<ISupplicantStaNetworkCallback>& callback);
-	V1_4::SupplicantStatus registerCallback_1_4Internal(
-	    const sp<V1_4::ISupplicantStaNetworkCallback>& callback);
-	SupplicantStatus setSsidInternal(const std::vector<uint8_t>& ssid);
-	SupplicantStatus setBssidInternal(const std::array<uint8_t, 6>& bssid);
-	SupplicantStatus setScanSsidInternal(bool enable);
-	SupplicantStatus setKeyMgmtInternal(uint32_t key_mgmt_mask);
-	SupplicantStatus setProtoInternal(uint32_t proto_mask);
-	SupplicantStatus setAuthAlgInternal(uint32_t auth_alg_mask);
-	SupplicantStatus setGroupCipherInternal(uint32_t group_cipher_mask);
-	SupplicantStatus setPairwiseCipherInternal(
-	    uint32_t pairwise_cipher_mask);
-	SupplicantStatus setPskPassphraseInternal(const std::string& psk);
-	SupplicantStatus setPskInternal(const std::array<uint8_t, 32>& psk);
-	SupplicantStatus setWepKeyInternal(
-	    uint32_t key_idx, const std::vector<uint8_t>& wep_key);
-	SupplicantStatus setWepTxKeyIdxInternal(uint32_t key_idx);
-	SupplicantStatus setRequirePmfInternal(bool enable);
-	SupplicantStatus setEapMethodInternal(
-	    ISupplicantStaNetwork::EapMethod method);
-	SupplicantStatus setEapPhase2MethodInternal(
-	    ISupplicantStaNetwork::EapPhase2Method method);
-	SupplicantStatus setEapIdentityInternal(
-	    const std::vector<uint8_t>& identity);
-	SupplicantStatus setEapEncryptedImsiIdentityInternal(
-	    const std::vector<uint8_t>& identity);
-	SupplicantStatus setEapAnonymousIdentityInternal(
-	    const std::vector<uint8_t>& identity);
-	SupplicantStatus setEapPasswordInternal(
-	    const std::vector<uint8_t>& password);
-	SupplicantStatus setEapCACertInternal(const std::string& path);
-	SupplicantStatus setEapCAPathInternal(const std::string& path);
-	SupplicantStatus setEapClientCertInternal(const std::string& path);
-	SupplicantStatus setEapPrivateKeyIdInternal(const std::string& id);
-	SupplicantStatus setEapSubjectMatchInternal(const std::string& match);
-	SupplicantStatus setEapAltSubjectMatchInternal(
-	    const std::string& match);
-	SupplicantStatus setEapEngineInternal(bool enable);
-	SupplicantStatus setEapEngineIDInternal(const std::string& id);
-	SupplicantStatus setEapDomainSuffixMatchInternal(
-	    const std::string& match);
-	SupplicantStatus setProactiveKeyCachingInternal(bool enable);
-	SupplicantStatus setIdStrInternal(const std::string& id_str);
-	SupplicantStatus setUpdateIdentifierInternal(uint32_t id);
-	V1_4::SupplicantStatus setEdmgInternal(bool enable);
-	std::pair<SupplicantStatus, std::vector<uint8_t>> getSsidInternal();
-	std::pair<SupplicantStatus, std::array<uint8_t, 6>> getBssidInternal();
-	std::pair<SupplicantStatus, bool> getScanSsidInternal();
-	std::pair<SupplicantStatus, uint32_t> getKeyMgmtInternal();
-	std::pair<SupplicantStatus, uint32_t> getProtoInternal();
-	std::pair<SupplicantStatus, uint32_t> getAuthAlgInternal();
-	std::pair<SupplicantStatus, uint32_t> getGroupCipherInternal();
-	std::pair<SupplicantStatus, uint32_t> getPairwiseCipherInternal();
-	std::pair<SupplicantStatus, std::string> getPskPassphraseInternal();
-	std::pair<SupplicantStatus, std::array<uint8_t, 32>> getPskInternal();
-	std::pair<SupplicantStatus, std::string> getSaePasswordInternal();
-	std::pair<SupplicantStatus, std::string> getSaePasswordIdInternal();
-	std::pair<SupplicantStatus, std::vector<uint8_t>> getWepKeyInternal(
-	    uint32_t key_idx);
-	std::pair<SupplicantStatus, uint32_t> getWepTxKeyIdxInternal();
-	std::pair<SupplicantStatus, bool> getRequirePmfInternal();
-	std::pair<SupplicantStatus, ISupplicantStaNetwork::EapMethod>
-	getEapMethodInternal();
-	std::pair<SupplicantStatus, ISupplicantStaNetwork::EapPhase2Method>
-	getEapPhase2MethodInternal();
-	std::pair<SupplicantStatus, std::vector<uint8_t>>
-	getEapIdentityInternal();
-	std::pair<SupplicantStatus, std::vector<uint8_t>>
-	getEapAnonymousIdentityInternal();
-	std::pair<SupplicantStatus, std::vector<uint8_t>>
-	getEapPasswordInternal();
-	std::pair<SupplicantStatus, std::string> getEapCACertInternal();
-	std::pair<SupplicantStatus, std::string> getEapCAPathInternal();
-	std::pair<SupplicantStatus, std::string> getEapClientCertInternal();
-	std::pair<SupplicantStatus, std::string> getEapPrivateKeyIdInternal();
-	std::pair<SupplicantStatus, std::string> getEapSubjectMatchInternal();
-	std::pair<SupplicantStatus, std::string>
-	getEapAltSubjectMatchInternal();
-	std::pair<SupplicantStatus, bool> getEapEngineInternal();
-	std::pair<SupplicantStatus, std::string> getEapEngineIDInternal();
-	std::pair<SupplicantStatus, std::string>
-	getEapDomainSuffixMatchInternal();
-	std::pair<SupplicantStatus, std::string> getIdStrInternal();
-	std::pair<SupplicantStatus, std::vector<uint8_t>>
-	getWpsNfcConfigurationTokenInternal();
-	std::pair<V1_4::SupplicantStatus, bool> getEdmgInternal();
-	SupplicantStatus enableInternal(bool no_connect);
-	SupplicantStatus disableInternal();
-	SupplicantStatus selectInternal();
-	SupplicantStatus sendNetworkEapSimGsmAuthResponseInternal(
-	    const std::vector<
-		ISupplicantStaNetwork::NetworkResponseEapSimGsmAuthParams>&
-		vec_params);
-	SupplicantStatus sendNetworkEapSimGsmAuthFailureInternal();
-	SupplicantStatus sendNetworkEapSimUmtsAuthResponseInternal(
-	    const ISupplicantStaNetwork::NetworkResponseEapSimUmtsAuthParams&
-		params);
-	SupplicantStatus sendNetworkEapSimUmtsAutsResponseInternal(
-	    const std::array<uint8_t, 14>& auts);
-	SupplicantStatus sendNetworkEapSimUmtsAuthFailureInternal();
-	SupplicantStatus sendNetworkEapIdentityResponseInternal(
-	    const std::vector<uint8_t>& identity);
-	SupplicantStatus sendNetworkEapIdentityResponseInternal_1_1(
-	    const std::vector<uint8_t>& identity,
-	    const std::vector<uint8_t>& imsi_identity);
-	SupplicantStatus enableTlsSuiteBEapPhase1ParamInternal(bool enable);
-	SupplicantStatus enableSuiteBEapOpenSslCiphersInternal();
-	SupplicantStatus setSaePasswordInternal(
-	    const std::string& sae_password);
-	SupplicantStatus setSaePasswordIdInternal(
-	    const std::string& sae_password_id);
-	SupplicantStatus setGroupMgmtCipherInternal(uint32_t group_mgmt_cipher_mask);
-	std::pair<SupplicantStatus, uint32_t> getGroupMgmtCipherInternal();
-	SupplicantStatus setOcspInternal(V1_3::OcspType ocspType);
-	std::pair<SupplicantStatus, V1_3::OcspType> getOcspInternal();
-	SupplicantStatus setPmkCacheInternal(const std::vector<uint8_t>& serialziedEntry);
-	SupplicantStatus setWapiCertSuiteInternal(const std::string& suite);
-	std::pair<SupplicantStatus, std::string> getWapiCertSuiteInternal();
-	SupplicantStatus setKeyMgmt_1_3Internal(uint32_t key_mgmt_mask);
-	std::pair<SupplicantStatus, uint32_t> getKeyMgmt_1_3Internal();
-	SupplicantStatus setProto_1_3Internal(uint32_t proto_mask);
-	std::pair<SupplicantStatus, uint32_t> getProto_1_3Internal();
-	std::pair<SupplicantStatus, uint32_t> getGroupCipher_1_3Internal();
-	SupplicantStatus setGroupCipher_1_3Internal(uint32_t group_cipher_mask);
-	std::pair<SupplicantStatus, uint32_t> getPairwiseCipher_1_3Internal();
-	SupplicantStatus setPairwiseCipher_1_3Internal(
-	    uint32_t pairwise_cipher_mask);
-	SupplicantStatus setWapiPskInternal(const std::vector<uint8_t>& psk);
-	std::pair<SupplicantStatus, std::vector<uint8_t>> getWapiPskInternal();
-	std::pair<V1_4::SupplicantStatus, uint32_t> getGroupCipher_1_4Internal();
-	V1_4::SupplicantStatus setGroupCipher_1_4Internal(uint32_t group_cipher_mask);
-	std::pair<V1_4::SupplicantStatus, uint32_t> getPairwiseCipher_1_4Internal();
-	V1_4::SupplicantStatus setPairwiseCipher_1_4Internal(
-	    uint32_t pairwise_cipher_mask);
-	V1_4::SupplicantStatus setSaeH2eModeInternal(V1_4::ISupplicantStaNetwork::SaeH2eMode mode);
-	V1_4::SupplicantStatus enableSaePkOnlyModeInternal(bool enable);
-
-	struct wpa_ssid* retrieveNetworkPtr();
-	struct wpa_supplicant* retrieveIfacePtr();
-	int isPskPassphraseValid(const std::string& psk);
-	void resetInternalStateAfterParamsUpdate();
-	int setStringFieldAndResetState(
-	    const char* value, uint8_t** to_update_field,
-	    const char* hexdump_prefix);
-	int setStringFieldAndResetState(
-	    const char* value, char** to_update_field,
-	    const char* hexdump_prefix);
-	int setStringKeyFieldAndResetState(
-	    const char* value, char** to_update_field,
-	    const char* hexdump_prefix);
-	int setByteArrayFieldAndResetState(
-	    const uint8_t* value, const size_t value_len,
-	    uint8_t** to_update_field, size_t* to_update_field_len,
-	    const char* hexdump_prefix);
-	int setByteArrayKeyFieldAndResetState(
-	    const uint8_t* value, const size_t value_len,
-	    uint8_t** to_update_field, size_t* to_update_field_len,
-	    const char* hexdump_prefix);
-	void setFastTransitionKeyMgmt(uint32_t &key_mgmt_mask);
-	void resetFastTransitionKeyMgmt(uint32_t &key_mgmt_mask);
-	SupplicantStatus setEapErpInternal(bool enable);
-
-	// Reference to the global wpa_struct. This is assumed to be valid
-	// for the lifetime of the process.
-	struct wpa_global* wpa_global_;
-	// Name of the iface this network belongs to.
-	const std::string ifname_;
-	// Id of the network this hidl object controls.
-	const int network_id_;
-	bool is_valid_;
-
-	DISALLOW_COPY_AND_ASSIGN(StaNetwork);
-};
-
-}  // namespace implementation
-}  // namespace V1_4
-}  // namespace supplicant
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WPA_SUPPLICANT_HIDL_STA_NETWORK_H
diff --git a/wpa_supplicant/hidl/1.4/supplicant.cpp b/wpa_supplicant/hidl/1.4/supplicant.cpp
deleted file mode 100644
index d8b18bb..0000000
--- a/wpa_supplicant/hidl/1.4/supplicant.cpp
+++ /dev/null
@@ -1,484 +0,0 @@
-/*
- * hidl interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#include "hidl_manager.h"
-#include "hidl_return_util.h"
-#include "supplicant.h"
-#include "p2p_iface.h"
-
-#include <android-base/file.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-namespace {
-
-// Pre-populated interface params for interfaces controlled by wpa_supplicant.
-// Note: This may differ for other OEM's. So, modify this accordingly.
-constexpr char kIfaceDriverName[] = "nl80211";
-constexpr char kStaIfaceConfPath[] =
-    "/data/vendor/wifi/wpa/wpa_supplicant.conf";
-static const char* kStaIfaceConfOverlayPaths[] = {
-    "/apex/com.android.wifi.hal/etc/wifi/wpa_supplicant_overlay.conf",
-    "/vendor/etc/wifi/wpa_supplicant_overlay.conf",
-};
-constexpr char kP2pIfaceConfPath[] =
-    "/data/vendor/wifi/wpa/p2p_supplicant.conf";
-static const char* kP2pIfaceConfOverlayPaths[] = {
-    "/apex/com.android.wifi.hal/etc/wifi/p2p_supplicant_overlay.conf",
-    "/vendor/etc/wifi/p2p_supplicant_overlay.conf",
-};
-// Migrate conf files for existing devices.
-static const char* kTemplateConfPaths[] = {
-    "/apex/com.android.wifi.hal/etc/wifi/wpa_supplicant.conf",
-    "/vendor/etc/wifi/wpa_supplicant.conf",
-    "/system/etc/wifi/wpa_supplicant.conf",
-};
-constexpr char kOldStaIfaceConfPath[] = "/data/misc/wifi/wpa_supplicant.conf";
-constexpr char kOldP2pIfaceConfPath[] = "/data/misc/wifi/p2p_supplicant.conf";
-constexpr mode_t kConfigFileMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
-
-const char* resolvePath(const char* paths[], size_t size)
-{
-	for (int i = 0; i < size; ++i) {
-		if (access(paths[i], R_OK) == 0) {
-			return paths[i];
-		}
-	}
-	return nullptr;
-}
-
-int copyFile(
-    const std::string& src_file_path, const std::string& dest_file_path)
-{
-	std::string file_contents;
-	if (!android::base::ReadFileToString(src_file_path, &file_contents)) {
-		wpa_printf(
-		    MSG_ERROR, "Failed to read from %s. Errno: %s",
-		    src_file_path.c_str(), strerror(errno));
-		return -1;
-	}
-	if (!android::base::WriteStringToFile(
-		file_contents, dest_file_path, kConfigFileMode, getuid(),
-		getgid())) {
-		wpa_printf(
-		    MSG_ERROR, "Failed to write to %s. Errno: %s",
-		    dest_file_path.c_str(), strerror(errno));
-		return -1;
-	}
-	return 0;
-}
-
-/**
- * Copy |src_file_path| to |dest_file_path| if it exists.
- *
- * Returns 1 if |src_file_path| does not exist or not accessible,
- * Returns -1 if the copy fails.
- * Returns 0 if the copy succeeds.
- */
-int copyFileIfItExists(
-    const std::string& src_file_path, const std::string& dest_file_path)
-{
-	int ret = access(src_file_path.c_str(), R_OK);
-	// Sepolicy denial (2018+ device) will return EACCESS instead of ENOENT.
-	if ((ret != 0) && ((errno == ENOENT) || (errno == EACCES))) {
-		return 1;
-	}
-	ret = copyFile(src_file_path, dest_file_path);
-	if (ret != 0) {
-		wpa_printf(
-		    MSG_ERROR, "Failed copying %s to %s.",
-		    src_file_path.c_str(), dest_file_path.c_str());
-		return -1;
-	}
-	return 0;
-}
-
-/**
- * Ensure that the specified config file pointed by |config_file_path| exists.
- * a) If the |config_file_path| exists with the correct permissions, return.
- * b) If the |config_file_path| does not exist, but |old_config_file_path|
- * exists, copy over the contents of the |old_config_file_path| to
- * |config_file_path|.
- * c) If the |config_file_path| & |old_config_file_path|
- * does not exists, copy over the contents of |template_config_file_path|.
- */
-int ensureConfigFileExists(
-    const std::string& config_file_path,
-    const std::string& old_config_file_path)
-{
-	int ret = access(config_file_path.c_str(), R_OK | W_OK);
-	if (ret == 0) {
-		return 0;
-	}
-	if (errno == EACCES) {
-		ret = chmod(config_file_path.c_str(), kConfigFileMode);
-		if (ret == 0) {
-			return 0;
-		} else {
-			wpa_printf(
-			    MSG_ERROR, "Cannot set RW to %s. Errno: %s",
-			    config_file_path.c_str(), strerror(errno));
-			return -1;
-		}
-	} else if (errno != ENOENT) {
-		wpa_printf(
-		    MSG_ERROR, "Cannot acces %s. Errno: %s",
-		    config_file_path.c_str(), strerror(errno));
-		return -1;
-	}
-	ret = copyFileIfItExists(old_config_file_path, config_file_path);
-	if (ret == 0) {
-		wpa_printf(
-		    MSG_INFO, "Migrated conf file from %s to %s",
-		    old_config_file_path.c_str(), config_file_path.c_str());
-		unlink(old_config_file_path.c_str());
-		return 0;
-	} else if (ret == -1) {
-		unlink(config_file_path.c_str());
-		return -1;
-	}
-	const char* path =
-	    resolvePath(kTemplateConfPaths, sizeof(kTemplateConfPaths));
-	if (path != nullptr) {
-		ret = copyFileIfItExists(path, config_file_path);
-		if (ret == 0) {
-			wpa_printf(
-			    MSG_INFO, "Copied template conf file from %s to %s",
-			    path, config_file_path.c_str());
-			return 0;
-		} else if (ret == -1) {
-			unlink(config_file_path.c_str());
-			return -1;
-		}
-	}
-	// Did not create the conf file.
-	return -1;
-}
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_4 {
-namespace implementation {
-using hidl_return_util::validateAndCall;
-using V1_0::SupplicantStatusCode;
-
-Supplicant::Supplicant(struct wpa_global* global) : wpa_global_(global) {}
-bool Supplicant::isValid()
-{
-	// This top level object cannot be invalidated.
-	return true;
-}
-
-Return<void> Supplicant::addInterface(
-    const IfaceInfo& iface_info, addInterface_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &Supplicant::addInterfaceInternal, _hidl_cb, iface_info);
-}
-
-Return<void> Supplicant::removeInterface(
-    const IfaceInfo& iface_info, removeInterface_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &Supplicant::removeInterfaceInternal, _hidl_cb, iface_info);
-}
-
-Return<void> Supplicant::getInterface(
-    const IfaceInfo& iface_info, getInterface_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &Supplicant::getInterfaceInternal, _hidl_cb, iface_info);
-}
-
-Return<void> Supplicant::listInterfaces(listInterfaces_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &Supplicant::listInterfacesInternal, _hidl_cb);
-}
-
-Return<void> Supplicant::registerCallback(
-    const sp<ISupplicantCallback>& callback, registerCallback_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &Supplicant::registerCallbackInternal, _hidl_cb, callback);
-}
-
-Return<void> Supplicant::setDebugParams(
-    ISupplicant::DebugLevel level, bool show_timestamp, bool show_keys,
-    setDebugParams_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &Supplicant::setDebugParamsInternal, _hidl_cb, level,
-	    show_timestamp, show_keys);
-}
-
-Return<void> Supplicant::setConcurrencyPriority(
-    IfaceType type, setConcurrencyPriority_cb _hidl_cb)
-{
-	return validateAndCall(
-	    this, SupplicantStatusCode::FAILURE_IFACE_INVALID,
-	    &Supplicant::setConcurrencyPriorityInternal, _hidl_cb, type);
-}
-
-Return<ISupplicant::DebugLevel> Supplicant::getDebugLevel()
-{
-	// TODO: Add SupplicantStatus in this method return for uniformity with
-	// the other methods in supplicant HIDL interface.
-	return (ISupplicant::DebugLevel)wpa_debug_level;
-}
-
-Return<bool> Supplicant::isDebugShowTimestampEnabled()
-{
-	// TODO: Add SupplicantStatus in this method return for uniformity with
-	// the other methods in supplicant HIDL interface.
-	return ((wpa_debug_timestamp != 0) ? true : false);
-}
-
-Return<bool> Supplicant::isDebugShowKeysEnabled()
-{
-	// TODO: Add SupplicantStatus in this method return for uniformity with
-	// the other methods in supplicant HIDL interface.
-	return ((wpa_debug_show_keys != 0) ? true : false);
-}
-
-Return<void> Supplicant::terminate()
-{
-	wpa_printf(MSG_INFO, "Terminating...");
-	wpa_supplicant_terminate_proc(wpa_global_);
-	return Void();
-}
-
-std::pair<SupplicantStatus, sp<ISupplicantIface>>
-Supplicant::addP2pDevInterface(struct wpa_interface iface_params)
-{
-	char primary_ifname[IFNAMSIZ];
-	u32 primary_ifname_len =
-		strlen(iface_params.ifname) - strlen(P2P_MGMT_DEVICE_PREFIX);
-
-	if(primary_ifname_len > IFNAMSIZ) {
-		wpa_printf(MSG_DEBUG, "%s, Invalid primary iface name ", __FUNCTION__);
-		return {{SupplicantStatusCode::FAILURE_ARGS_INVALID, ""}, {}};
-	}
-
-	strncpy(primary_ifname, iface_params.ifname +
-		strlen(P2P_MGMT_DEVICE_PREFIX), primary_ifname_len);
-	wpa_printf(MSG_DEBUG, "%s, Initialize p2p-dev-wlan0 iface with"
-		"primary_iface = %s", __FUNCTION__, primary_ifname);
-	struct wpa_supplicant* wpa_s =
-		wpa_supplicant_get_iface(wpa_global_, primary_ifname);
-	if (!wpa_s) {
-		wpa_printf(MSG_DEBUG, "%s,NULL wpa_s for wlan0", __FUNCTION__);
-		return {{SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""},
-			nullptr};
-	}
-	if (wpas_p2p_add_p2pdev_interface(
-		wpa_s, wpa_s->global->params.conf_p2p_dev) < 0) {
-		wpa_printf(MSG_INFO,
-			"Failed to enable P2P Device");
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN,
-			"Enable P2P Device failed"}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS,""}, {}};
-}
-
-std::pair<SupplicantStatus, sp<ISupplicantIface>>
-Supplicant::addInterfaceInternal(const IfaceInfo& iface_info)
-{
-	android::sp<ISupplicantIface> iface;
-
-	// Check if required |ifname| argument is empty.
-	if (iface_info.name.empty()) {
-		return {{SupplicantStatusCode::FAILURE_ARGS_INVALID, ""}, {}};
-	}
-	// Try to get the wpa_supplicant record for this iface, return
-	// the iface object with the appropriate status code if it exists.
-	SupplicantStatus status;
-	std::tie(status, iface) = getInterfaceInternal(iface_info);
-	if (status.code == SupplicantStatusCode::SUCCESS) {
-		return {{SupplicantStatusCode::FAILURE_IFACE_EXISTS, ""},
-			iface};
-	}
-
-	struct wpa_interface iface_params = {};
-	iface_params.driver = kIfaceDriverName;
-	if (iface_info.type == IfaceType::P2P) {
-		if (ensureConfigFileExists(
-			kP2pIfaceConfPath, kOldP2pIfaceConfPath) != 0) {
-			wpa_printf(
-			    MSG_ERROR, "Conf file does not exists: %s",
-			    kP2pIfaceConfPath);
-			return {{SupplicantStatusCode::FAILURE_UNKNOWN,
-				 "Conf file does not exist"},
-				{}};
-		}
-		iface_params.confname = kP2pIfaceConfPath;
-		const char* path = resolvePath(
-		    kP2pIfaceConfOverlayPaths,
-		    sizeof(kP2pIfaceConfOverlayPaths));
-		if (path != nullptr) {
-			iface_params.confanother = path;
-		}
-	} else {
-		if (ensureConfigFileExists(
-			kStaIfaceConfPath, kOldStaIfaceConfPath) != 0) {
-			wpa_printf(
-			    MSG_ERROR, "Conf file does not exists: %s",
-			    kStaIfaceConfPath);
-			return {{SupplicantStatusCode::FAILURE_UNKNOWN,
-				 "Conf file does not exist"},
-				{}};
-		}
-		iface_params.confname = kStaIfaceConfPath;
-		const char* path = resolvePath(
-		    kStaIfaceConfOverlayPaths,
-		    sizeof(kStaIfaceConfOverlayPaths));
-		if (path != nullptr) {
-			iface_params.confanother = path;
-		}
-	}
-	iface_params.ifname = iface_info.name.c_str();
-	if (strncmp(iface_params.ifname, P2P_MGMT_DEVICE_PREFIX,
-		strlen(P2P_MGMT_DEVICE_PREFIX)) == 0) {
-		std::tie(status, iface) = addP2pDevInterface(iface_params);
-		if (status.code != SupplicantStatusCode::SUCCESS) {
-			return {{status.code,
-				status.debugMessage.c_str()}, iface};
-		}
-	} else {
-		struct wpa_supplicant* wpa_s =
-			wpa_supplicant_add_iface(wpa_global_, &iface_params, NULL);
-		if (!wpa_s) {
-			return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-		}
-		//Request the current scan results from the driver and updates
-		//the local BSS list wpa_s->bss. This is to avoid a full scan
-		//while processing the connect request on newly created interface.
-		wpa_supplicant_update_scan_results(wpa_s);
-	}
-	// The supplicant core creates a corresponding hidl object via
-	// HidlManager when |wpa_supplicant_add_iface| is called.
-	return getInterfaceInternal(iface_info);
-}
-
-SupplicantStatus Supplicant::removeInterfaceInternal(
-    const IfaceInfo& iface_info)
-{
-	struct wpa_supplicant* wpa_s =
-	    wpa_supplicant_get_iface(wpa_global_, iface_info.name.c_str());
-	if (!wpa_s) {
-		return {SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""};
-	}
-	if (wpa_supplicant_remove_iface(wpa_global_, wpa_s, 0)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-std::pair<SupplicantStatus, sp<ISupplicantIface>>
-Supplicant::getInterfaceInternal(const IfaceInfo& iface_info)
-{
-	struct wpa_supplicant* wpa_s =
-	    wpa_supplicant_get_iface(wpa_global_, iface_info.name.c_str());
-	if (!wpa_s) {
-		return {{SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, ""},
-			nullptr};
-	}
-	HidlManager* hidl_manager = HidlManager::getInstance();
-	if (iface_info.type == IfaceType::P2P) {
-		android::sp<ISupplicantP2pIface> iface;
-		if (!hidl_manager ||
-		    hidl_manager->getP2pIfaceHidlObjectByIfname(
-			wpa_s->ifname, &iface)) {
-			return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""},
-				iface};
-		}
-		// Set this flag true here, since there is no HIDL initialize
-		// method for the p2p config, and the supplicant interface is
-		// not ready when the p2p iface is created.
-		wpa_s->conf->persistent_reconnect = true;
-		return {{SupplicantStatusCode::SUCCESS, ""}, iface};
-	} else {
-		android::sp<V1_1::ISupplicantStaIface> iface;
-		if (!hidl_manager ||
-		    hidl_manager->getStaIfaceHidlObjectByIfname(
-			wpa_s->ifname, &iface)) {
-			return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""},
-				iface};
-		}
-		return {{SupplicantStatusCode::SUCCESS, ""}, iface};
-	}
-}
-
-std::pair<SupplicantStatus, std::vector<ISupplicant::IfaceInfo>>
-Supplicant::listInterfacesInternal()
-{
-	std::vector<ISupplicant::IfaceInfo> ifaces;
-	for (struct wpa_supplicant* wpa_s = wpa_global_->ifaces; wpa_s;
-	     wpa_s = wpa_s->next) {
-		if (wpa_s->global->p2p_init_wpa_s == wpa_s) {
-			ifaces.emplace_back(ISupplicant::IfaceInfo{
-			    IfaceType::P2P, wpa_s->ifname});
-		} else {
-			ifaces.emplace_back(ISupplicant::IfaceInfo{
-			    IfaceType::STA, wpa_s->ifname});
-		}
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, std::move(ifaces)};
-}
-
-SupplicantStatus Supplicant::registerCallbackInternal(
-    const sp<ISupplicantCallback>& callback)
-{
-	HidlManager* hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager ||
-	    hidl_manager->addSupplicantCallbackHidlObject(callback)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus Supplicant::setDebugParamsInternal(
-    ISupplicant::DebugLevel level, bool show_timestamp, bool show_keys)
-{
-	if (wpa_supplicant_set_debug_params(
-		wpa_global_, static_cast<uint32_t>(level), show_timestamp,
-		show_keys)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus Supplicant::setConcurrencyPriorityInternal(IfaceType type)
-{
-	if (type == IfaceType::STA) {
-		wpa_global_->conc_pref =
-		    wpa_global::wpa_conc_pref::WPA_CONC_PREF_STA;
-	} else if (type == IfaceType::P2P) {
-		wpa_global_->conc_pref =
-		    wpa_global::wpa_conc_pref::WPA_CONC_PREF_P2P;
-	} else {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	return SupplicantStatus{SupplicantStatusCode::SUCCESS, ""};
-}
-}  // namespace implementation
-}  // namespace V1_4
-}  // namespace supplicant
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
diff --git a/wpa_supplicant/hidl/1.4/supplicant.h b/wpa_supplicant/hidl/1.4/supplicant.h
deleted file mode 100644
index c2b172c..0000000
--- a/wpa_supplicant/hidl/1.4/supplicant.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
- * hidl interface for wpa_supplicant daemon
- * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
- * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
- *
- * This software may be distributed under the terms of the BSD license.
- * See README for more details.
- */
-
-#ifndef WPA_SUPPLICANT_HIDL_SUPPLICANT_H
-#define WPA_SUPPLICANT_HIDL_SUPPLICANT_H
-
-#include <android/hardware/wifi/supplicant/1.0/ISupplicantCallback.h>
-#include <android/hardware/wifi/supplicant/1.0/ISupplicantIface.h>
-#include <android/hardware/wifi/supplicant/1.0/types.h>
-#include <android/hardware/wifi/supplicant/1.4/ISupplicant.h>
-#include <android-base/macros.h>
-#include <hidl/Status.h>
-
-extern "C"
-{
-#include "utils/common.h"
-#include "utils/includes.h"
-#include "utils/wpa_debug.h"
-#include "wpa_supplicant_i.h"
-#include "scan.h"
-}
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_4 {
-namespace implementation {
-using V1_0::ISupplicantCallback;
-using V1_0::ISupplicantIface;
-
-/**
- * Implementation of the supplicant hidl object. This hidl
- * object is used core for global control operations on
- * wpa_supplicant.
- */
-class Supplicant : public V1_4::ISupplicant
-{
-public:
-	Supplicant(struct wpa_global* global);
-	~Supplicant() override = default;
-	bool isValid();
-
-	// Hidl methods exposed.
-	Return<void> addInterface(
-	    const IfaceInfo& iface_info, addInterface_cb _hidl_cb) override;
-	Return<void> removeInterface(
-	    const IfaceInfo& iface_info, removeInterface_cb _hidl_cb) override;
-	Return<void> getInterface(
-	    const IfaceInfo& iface_info, getInterface_cb _hidl_cb) override;
-	Return<void> listInterfaces(listInterfaces_cb _hidl_cb) override;
-	Return<void> registerCallback(
-	    const sp<ISupplicantCallback>& callback,
-	    registerCallback_cb _hidl_cb) override;
-	Return<void> setDebugParams(
-	    ISupplicant::DebugLevel level, bool show_timestamp, bool show_keys,
-	    setDebugParams_cb _hidl_cb) override;
-	Return<ISupplicant::DebugLevel> getDebugLevel() override;
-	Return<bool> isDebugShowTimestampEnabled() override;
-	Return<bool> isDebugShowKeysEnabled() override;
-	Return<void> setConcurrencyPriority(
-	    IfaceType type, setConcurrencyPriority_cb _hidl_cb) override;
-	Return<void> terminate() override;
-
-private:
-	// Corresponding worker functions for the HIDL methods.
-	std::pair<SupplicantStatus, sp<ISupplicantIface>> getInterfaceInternal(
-	    const IfaceInfo& iface_info);
-	std::pair<SupplicantStatus, sp<ISupplicantIface>> addInterfaceInternal(
-	    const IfaceInfo& iface_info);
-	SupplicantStatus removeInterfaceInternal(const IfaceInfo& iface_info);
-	std::pair<SupplicantStatus, std::vector<ISupplicant::IfaceInfo>>
-	listInterfacesInternal();
-	SupplicantStatus registerCallbackInternal(
-	    const sp<ISupplicantCallback>& callback);
-	SupplicantStatus setDebugParamsInternal(
-	    ISupplicant::DebugLevel level, bool show_timestamp, bool show_keys);
-	SupplicantStatus setConcurrencyPriorityInternal(IfaceType type);
-	std::pair<SupplicantStatus, sp<ISupplicantIface>> addP2pDevInterface(
-	    struct wpa_interface iface_params);
-
-	// Raw pointer to the global structure maintained by the core.
-	struct wpa_global* wpa_global_;
-	// Driver name to be used for creating interfaces.
-	static const char kDriverName[];
-	// wpa_supplicant.conf file location on the device.
-	static const char kConfigFilePath[];
-
-	DISALLOW_COPY_AND_ASSIGN(Supplicant);
-};
-
-}  // namespace implementation
-}  // namespace V1_4
-}  // namespace supplicant
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WPA_SUPPLICANT_HIDL_SUPPLICANT_H
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 5508f16..aaa2269 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -23,7 +23,7 @@
 #include "p2p_supplicant.h"
 #include "sme.h"
 #include "notify.h"
-#include "hidl.h"
+#include "aidl.h"
 
 int wpas_notify_supplicant_initialized(struct wpa_global *global)
 {
@@ -35,11 +35,11 @@
 	}
 #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
 
-#ifdef CONFIG_HIDL
-	global->hidl = wpas_hidl_init(global);
-	if (!global->hidl)
+#ifdef CONFIG_AIDL
+	global->aidl = wpas_aidl_init(global);
+	if (!global->aidl)
 		return -1;
-#endif /* CONFIG_HIDL */
+#endif /* CONFIG_AIDL */
 
 	return 0;
 }
@@ -52,10 +52,10 @@
 		wpas_dbus_deinit(global->dbus);
 #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
 
-#ifdef CONFIG_HIDL
-	if (global->hidl)
-		wpas_hidl_deinit(global->hidl);
-#endif /* CONFIG_HIDL */
+#ifdef CONFIG_AIDL
+	if (global->aidl)
+		wpas_aidl_deinit(global->aidl);
+#endif /* CONFIG_AIDL */
 }
 
 
@@ -67,7 +67,7 @@
 	}
 
 	/* HIDL interface wants to keep track of the P2P mgmt iface. */
-	if (wpas_hidl_register_interface(wpa_s))
+	if (wpas_aidl_register_interface(wpa_s))
 		return -1;
 
 	return 0;
@@ -82,7 +82,7 @@
 	}
 
 	/* HIDL interface wants to keep track of the P2P mgmt iface. */
-	wpas_hidl_unregister_interface(wpa_s);
+	wpas_aidl_unregister_interface(wpa_s);
 }
 
 
@@ -124,7 +124,7 @@
 				  wpa_s->current_ssid->ssid_len) : "");
 #endif /* ANDROID */
 
-	wpas_hidl_notify_state_changed(wpa_s);
+	wpas_aidl_notify_state_changed(wpa_s);
 }
 
 
@@ -135,7 +135,7 @@
 
 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_DISCONNECT_REASON);
 
-	wpas_hidl_notify_disconnect_reason(wpa_s);
+	wpas_aidl_notify_disconnect_reason(wpa_s);
 }
 
 
@@ -157,14 +157,14 @@
 
 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_ASSOC_STATUS_CODE);
 
-	wpas_hidl_notify_assoc_reject(wpa_s, bssid, timed_out, assoc_resp_ie, assoc_resp_ie_len);
+	wpas_aidl_notify_assoc_reject(wpa_s, bssid, timed_out, assoc_resp_ie, assoc_resp_ie_len);
 }
 
 void wpas_notify_auth_timeout(struct wpa_supplicant *wpa_s) {
 	if (wpa_s->p2p_mgmt)
 		return;
 
-	wpas_hidl_notify_auth_timeout(wpa_s);
+	wpas_aidl_notify_auth_timeout(wpa_s);
 }
 
 void wpas_notify_roam_time(struct wpa_supplicant *wpa_s)
@@ -202,7 +202,7 @@
 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_BSS_TM_STATUS);
 
 #ifdef CONFIG_WNM
-	wpas_hidl_notify_bss_tm_status(wpa_s);
+	wpas_aidl_notify_bss_tm_status(wpa_s);
 #endif
 }
 
@@ -232,7 +232,7 @@
 
 	wpas_dbus_signal_prop_changed(wpa_s, WPAS_DBUS_PROP_CURRENT_BSS);
 
-	wpas_hidl_notify_bssid_changed(wpa_s);
+	wpas_aidl_notify_bssid_changed(wpa_s);
 }
 
 
@@ -275,7 +275,7 @@
 
 	wpas_dbus_signal_network_request(wpa_s, ssid, rtype, default_txt);
 
-	wpas_hidl_notify_network_request(wpa_s, ssid, rtype, default_txt);
+	wpas_aidl_notify_network_request(wpa_s, ssid, rtype, default_txt);
 }
 
 
@@ -341,7 +341,7 @@
 #ifdef CONFIG_WPS
 	wpas_dbus_signal_wps_event_fail(wpa_s, fail);
 
-	wpas_hidl_notify_wps_event_fail(wpa_s, fail->peer_macaddr,
+	wpas_aidl_notify_wps_event_fail(wpa_s, fail->peer_macaddr,
 					fail->config_error,
 					fail->error_indication);
 #endif /* CONFIG_WPS */
@@ -356,7 +356,7 @@
 #ifdef CONFIG_WPS
 	wpas_dbus_signal_wps_event_success(wpa_s);
 
-	wpas_hidl_notify_wps_event_success(wpa_s);
+	wpas_aidl_notify_wps_event_success(wpa_s);
 #endif /* CONFIG_WPS */
 }
 
@@ -368,7 +368,7 @@
 #ifdef CONFIG_WPS
 	wpas_dbus_signal_wps_event_pbc_overlap(wpa_s);
 
-	wpas_hidl_notify_wps_event_pbc_overlap(wpa_s);
+	wpas_aidl_notify_wps_event_pbc_overlap(wpa_s);
 #endif /* CONFIG_WPS */
 }
 
@@ -387,7 +387,7 @@
 	 */
 	if (!ssid->p2p_group && wpa_s->global->p2p_group_formation != wpa_s) {
 		wpas_dbus_register_network(wpa_s, ssid);
-		wpas_hidl_register_network(wpa_s, ssid);
+		wpas_aidl_register_network(wpa_s, ssid);
 	}
 }
 
@@ -397,7 +397,7 @@
 {
 #ifdef CONFIG_P2P
 	wpas_dbus_register_persistent_group(wpa_s, ssid);
-	wpas_hidl_register_network(wpa_s, ssid);
+	wpas_aidl_register_network(wpa_s, ssid);
 #endif /* CONFIG_P2P */
 }
 
@@ -407,7 +407,7 @@
 {
 #ifdef CONFIG_P2P
 	wpas_dbus_unregister_persistent_group(wpa_s, ssid->id);
-	wpas_hidl_unregister_network(wpa_s, ssid);
+	wpas_aidl_unregister_network(wpa_s, ssid);
 #endif /* CONFIG_P2P */
 }
 
@@ -422,7 +422,7 @@
 	if (!ssid->p2p_group && wpa_s->global->p2p_group_formation != wpa_s &&
 	    !wpa_s->p2p_mgmt) {
 		wpas_dbus_unregister_network(wpa_s, ssid->id);
-		wpas_hidl_unregister_network(wpa_s, ssid);
+		wpas_aidl_unregister_network(wpa_s, ssid);
 	}
 	if (network_is_persistent_group(ssid))
 		wpas_notify_persistent_group_removed(wpa_s, ssid);
@@ -467,6 +467,8 @@
 		return;
 
 	wpas_dbus_bss_signal_prop_changed(wpa_s, WPAS_DBUS_BSS_PROP_FREQ, id);
+
+	wpas_aidl_notify_bss_freq_changed(wpa_s);
 }
 
 
@@ -640,7 +642,7 @@
 	/* Notify P2P find has stopped */
 	wpas_dbus_signal_p2p_find_stopped(wpa_s);
 
-	wpas_hidl_notify_p2p_find_stopped(wpa_s);
+	wpas_aidl_notify_p2p_find_stopped(wpa_s);
 }
 
 
@@ -658,7 +660,7 @@
 	/* Notify a new peer has been detected*/
 	wpas_dbus_signal_peer_device_found(wpa_s, info->p2p_device_addr);
 
-	wpas_hidl_notify_p2p_device_found(wpa_s, addr, info,
+	wpas_aidl_notify_p2p_device_found(wpa_s, addr, info,
 					  peer_wfd_device_info,
 					  peer_wfd_device_info_len,
 					  peer_wfd_r2_device_info,
@@ -674,7 +676,7 @@
 	/* Create signal on interface object*/
 	wpas_dbus_signal_peer_device_lost(wpa_s, dev_addr);
 
-	wpas_hidl_notify_p2p_device_lost(wpa_s, dev_addr);
+	wpas_aidl_notify_p2p_device_lost(wpa_s, dev_addr);
 }
 
 
@@ -686,7 +688,7 @@
 
 	wpas_dbus_unregister_p2p_group(wpa_s, ssid);
 
-	wpas_hidl_notify_p2p_group_removed(wpa_s, ssid, role);
+	wpas_aidl_notify_p2p_group_removed(wpa_s, ssid, role);
 }
 
 
@@ -695,7 +697,7 @@
 {
 	wpas_dbus_signal_p2p_go_neg_req(wpa_s, src, dev_passwd_id, go_intent);
 
-	wpas_hidl_notify_p2p_go_neg_req(wpa_s, src, dev_passwd_id, go_intent);
+	wpas_aidl_notify_p2p_go_neg_req(wpa_s, src, dev_passwd_id, go_intent);
 }
 
 
@@ -704,7 +706,7 @@
 {
 	wpas_dbus_signal_p2p_go_neg_resp(wpa_s, res);
 
-	wpas_hidl_notify_p2p_go_neg_completed(wpa_s, res);
+	wpas_aidl_notify_p2p_go_neg_completed(wpa_s, res);
 }
 
 
@@ -713,7 +715,7 @@
 {
 	wpas_dbus_signal_p2p_invitation_result(wpa_s, status, bssid);
 
-	wpas_hidl_notify_p2p_invitation_result(wpa_s, status, bssid);
+	wpas_aidl_notify_p2p_invitation_result(wpa_s, status, bssid);
 }
 
 
@@ -734,7 +736,7 @@
 	wpas_dbus_signal_p2p_sd_response(wpa_s, sa, update_indic,
 					 tlvs, tlvs_len);
 
-	wpas_hidl_notify_p2p_sd_response(wpa_s, sa, update_indic,
+	wpas_aidl_notify_p2p_sd_response(wpa_s, sa, update_indic,
 					 tlvs, tlvs_len);
 }
 
@@ -762,7 +764,7 @@
 						 status, config_methods,
 						 generated_pin);
 
-	wpas_hidl_notify_p2p_provision_discovery(wpa_s, dev_addr, request,
+	wpas_aidl_notify_p2p_provision_discovery(wpa_s, dev_addr, request,
 						 status, config_methods,
 						 generated_pin);
 
@@ -778,7 +780,7 @@
 
 	wpas_dbus_signal_p2p_group_started(wpa_s, client, persistent, ip);
 
-	wpas_hidl_notify_p2p_group_started(wpa_s, ssid, persistent, client);
+	wpas_aidl_notify_p2p_group_started(wpa_s, ssid, persistent, client);
 }
 
 
@@ -788,7 +790,7 @@
 	/* Notify a group formation failed */
 	wpas_dbus_signal_p2p_group_formation_failure(wpa_s, reason);
 
-	wpas_hidl_notify_p2p_group_formation_failure(wpa_s, reason);
+	wpas_aidl_notify_p2p_group_formation_failure(wpa_s, reason);
 }
 
 
@@ -807,7 +809,7 @@
 	wpas_dbus_signal_p2p_invitation_received(wpa_s, sa, go_dev_addr, bssid,
 						 id, op_freq);
 
-	wpas_hidl_notify_p2p_invitation_received(wpa_s, sa, go_dev_addr, bssid,
+	wpas_aidl_notify_p2p_invitation_received(wpa_s, sa, go_dev_addr, bssid,
 						 id, op_freq);
 }
 
@@ -835,7 +837,7 @@
 	/* Notify listeners a new station has been authorized */
 	wpas_dbus_signal_sta_authorized(wpa_s, sta);
 
-	wpas_hidl_notify_ap_sta_authorized(wpa_s, sta, p2p_dev_addr);
+	wpas_aidl_notify_ap_sta_authorized(wpa_s, sta, p2p_dev_addr);
 }
 
 
@@ -855,7 +857,7 @@
 	/* Notify listeners a station has been deauthorized */
 	wpas_dbus_signal_sta_deauthorized(wpa_s, sta);
 
-        wpas_hidl_notify_ap_sta_deauthorized(wpa_s, sta, p2p_dev_addr);
+        wpas_aidl_notify_ap_sta_deauthorized(wpa_s, sta, p2p_dev_addr);
 	/* Unregister the station */
 	wpas_dbus_unregister_sta(wpa_s, sta);
 }
@@ -904,6 +906,10 @@
 		wpa_msg(wpa_s, MSG_INFO, WPA_EVENT_EAP_PEER_ALT
 			"depth=%d %s", cert->depth, cert->altsubject[i]);
 
+	wpas_aidl_notify_ceritification(wpa_s, cert->depth, cert->subject,
+				       cert->altsubject, cert->num_altsubject,
+				       cert_hash, cert->cert);
+
 	/* notify the new DBus API */
 	wpas_dbus_signal_certification(wpa_s, cert->depth, cert->subject,
 				       cert->altsubject, cert->num_altsubject,
@@ -935,7 +941,7 @@
 {
 	wpa_dbg(wpa_s, MSG_ERROR,
 		"EAP Error code = %d", error_code);
-	wpas_hidl_notify_eap_error(wpa_s, error_code);
+	wpas_aidl_notify_eap_error(wpa_s, error_code);
 }
 
 
@@ -982,7 +988,7 @@
 	if (!wpa_s || !bssid || !anqp)
 		return;
 
-	wpas_hidl_notify_anqp_query_done(wpa_s, bssid, result, anqp);
+	wpas_aidl_notify_anqp_query_done(wpa_s, bssid, result, anqp);
 #endif /* CONFIG_INTERWORKING */
 }
 
@@ -994,7 +1000,7 @@
 	if (!wpa_s || !bssid || !file_name || !image)
 		return;
 
-	wpas_hidl_notify_hs20_icon_query_done(wpa_s, bssid, file_name, image,
+	wpas_aidl_notify_hs20_icon_query_done(wpa_s, bssid, file_name, image,
 					      image_length);
 #endif /* CONFIG_HS20 */
 }
@@ -1007,7 +1013,7 @@
 	if (!wpa_s || !url)
 		return;
 
-	wpas_hidl_notify_hs20_rx_subscription_remediation(wpa_s, url, osu_method);
+	wpas_aidl_notify_hs20_rx_subscription_remediation(wpa_s, url, osu_method);
 #endif /* CONFIG_HS20 */
 }
 
@@ -1019,7 +1025,7 @@
 	if (!wpa_s)
 		return;
 
-	wpas_hidl_notify_hs20_rx_deauth_imminent_notice(wpa_s, code, reauth_delay,
+	wpas_aidl_notify_hs20_rx_deauth_imminent_notice(wpa_s, code, reauth_delay,
 			url);
 #endif /* CONFIG_HS20 */
 }
@@ -1030,7 +1036,7 @@
 	if (!wpa_s || !url)
 		return;
 
-	wpas_hidl_notify_hs20_rx_terms_and_conditions_acceptance(wpa_s, url);
+	wpas_aidl_notify_hs20_rx_terms_and_conditions_acceptance(wpa_s, url);
 #endif /* CONFIG_HS20 */
 }
 
@@ -1092,7 +1098,7 @@
 	if (!wpa_s)
 		return;
 
-	wpas_hidl_notify_dpp_config_received(wpa_s, ssid);
+	wpas_aidl_notify_dpp_config_received(wpa_s, ssid);
 #endif /* CONFIG_DPP */
 }
 
@@ -1102,7 +1108,7 @@
 	if (!wpa_s)
 		return;
 
-	wpas_hidl_notify_dpp_config_sent(wpa_s);
+	wpas_aidl_notify_dpp_config_sent(wpa_s);
 #endif /* CONFIG_DPP */
 }
 
@@ -1113,7 +1119,7 @@
 	if (!wpa_s)
 		return;
 
-	wpas_hidl_notify_dpp_auth_success(wpa_s);
+	wpas_aidl_notify_dpp_auth_success(wpa_s);
 #endif /* CONFIG_DPP */
 }
 
@@ -1123,7 +1129,7 @@
 	if (!wpa_s)
 		return;
 
-	wpas_hidl_notify_dpp_resp_pending(wpa_s);
+	wpas_aidl_notify_dpp_resp_pending(wpa_s);
 #endif /* CONFIG_DPP */
 }
 
@@ -1134,7 +1140,7 @@
 	if (!wpa_s)
 		return;
 
-	wpas_hidl_notify_dpp_not_compatible(wpa_s);
+	wpas_aidl_notify_dpp_not_compatible(wpa_s);
 #endif /* CONFIG_DPP */
 }
 
@@ -1144,7 +1150,7 @@
 	if (!wpa_s)
 		return;
 
-	wpas_hidl_notify_dpp_missing_auth(wpa_s);
+	wpas_aidl_notify_dpp_missing_auth(wpa_s);
 #endif /* CONFIG_DPP */
 }
 
@@ -1154,7 +1160,7 @@
 	if (!wpa_s)
 		return;
 
-	wpas_hidl_notify_dpp_configuration_failure(wpa_s);
+	wpas_aidl_notify_dpp_configuration_failure(wpa_s);
 #endif /* CONFIG_DPP */
 }
 
@@ -1164,7 +1170,7 @@
 	if (!wpa_s)
 		return;
 
-	wpas_hidl_notify_dpp_timeout(wpa_s);
+	wpas_aidl_notify_dpp_timeout(wpa_s);
 #endif /* CONFIG_DPP */
 }
 
@@ -1174,7 +1180,7 @@
 	if (!wpa_s)
 		return;
 
-	wpas_hidl_notify_dpp_auth_failure(wpa_s);
+	wpas_aidl_notify_dpp_auth_failure(wpa_s);
 #endif /* CONFIG_DPP */
 }
 
@@ -1184,21 +1190,21 @@
 	if (!wpa_s)
 		return;
 
-	wpas_hidl_notify_dpp_fail(wpa_s);
+	wpas_aidl_notify_dpp_fail(wpa_s);
 #endif /* CONFIG_DPP */
 }
 
 void wpas_notify_dpp_config_sent_wait_response(struct wpa_supplicant *wpa_s)
 {
 #ifdef CONFIG_DPP2
-	wpas_hidl_notify_dpp_config_sent_wait_response(wpa_s);
+	wpas_aidl_notify_dpp_config_sent_wait_response(wpa_s);
 #endif /* CONFIG_DPP2 */
 }
 
 void wpas_notify_dpp_config_accepted(struct wpa_supplicant *wpa_s)
 {
 #ifdef CONFIG_DPP2
-	wpas_hidl_notify_dpp_config_accepted(wpa_s);
+	wpas_aidl_notify_dpp_config_accepted(wpa_s);
 #endif /* CONFIG_DPP2 */
 }
 
@@ -1207,14 +1213,14 @@
 		const char *channel_list, unsigned short band_list[], int size)
 {
 #ifdef CONFIG_DPP2
-	wpas_hidl_notify_dpp_conn_status(wpa_s, status, ssid, channel_list, band_list, size);
+	wpas_aidl_notify_dpp_conn_status(wpa_s, status, ssid, channel_list, band_list, size);
 #endif /* CONFIG_DPP2 */
 }
 
 void wpas_notify_dpp_config_rejected(struct wpa_supplicant *wpa_s)
 {
 #ifdef CONFIG_DPP2
-	wpas_hidl_notify_dpp_config_rejected(wpa_s);
+	wpas_aidl_notify_dpp_config_rejected(wpa_s);
 #endif /* CONFIG_DPP2 */
 }
 
@@ -1224,7 +1230,7 @@
 	if (!wpa_s)
 		return;
 
-	wpas_hidl_notify_pmk_cache_added(wpa_s, entry);
+	wpas_aidl_notify_pmk_cache_added(wpa_s, entry);
 }
 
 void wpas_notify_transition_disable(struct wpa_supplicant *wpa_s,
@@ -1237,7 +1243,7 @@
 	if (!ssid)
 		return;
 
-	wpas_hidl_notify_transition_disable(wpa_s, ssid, bitmap);
+	wpas_aidl_notify_transition_disable(wpa_s, ssid, bitmap);
 }
 
 void wpas_notify_network_not_found(struct wpa_supplicant *wpa_s)
@@ -1245,5 +1251,5 @@
 	if (!wpa_s)
 		return;
 
-	wpas_hidl_notify_network_not_found(wpa_s);
+	wpas_aidl_notify_network_not_found(wpa_s);
 }
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 643dd0d..bc55161 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -6103,7 +6103,25 @@
 		} else {
 			if (os_get_random((u8 *) &r, sizeof(r)) < 0)
 				return -1;
-			freq = 2412 + (r % 3) * 25;
+			int possible_2g_freqs[] = {
+				/* operating class 81 */
+				2412, 2437, 2462,
+			};
+			int possible_2g_freqs_num =
+			    sizeof(possible_2g_freqs)/sizeof(possible_2g_freqs[0]);
+			int i;
+			for (i = 0; i < possible_2g_freqs_num; i++, r++) {
+				freq = possible_2g_freqs[r % possible_2g_freqs_num];
+				if (p2p_supported_freq_go(wpa_s->global->p2p, freq)) {
+					break;
+				}
+			}
+
+			if (i >= possible_2g_freqs_num) {
+				wpa_printf(MSG_DEBUG, "P2P: Could not select "
+					   "2.4 GHz channel for P2P group");
+				return -1;
+			}
 			wpa_printf(MSG_DEBUG, "P2P: Use random 2.4 GHz band "
 				   "channel: %d MHz", freq);
 		}
diff --git a/wpa_supplicant/sme.c b/wpa_supplicant/sme.c
index 36f4d3c..5a771e8 100644
--- a/wpa_supplicant/sme.c
+++ b/wpa_supplicant/sme.c
@@ -663,7 +663,11 @@
 	}
 
 #ifdef CONFIG_HS20
-	if (is_hs20_config(wpa_s) && is_hs20_network(wpa_s, ssid, bss)) {
+	if (is_hs20_network(wpa_s, ssid, bss)
+#ifndef ANDROID /* Android does not use the native HS 2.0 config */
+			&& is_hs20_config(wpa_s)
+#endif /* ANDROID */
+	) {
 		struct wpabuf *hs20;
 
 		hs20 = wpabuf_alloc(20 + MAX_ROAMING_CONS_OI_LEN);
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 3471b99..54d223d 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -3046,7 +3046,11 @@
 	}
 
 #ifdef CONFIG_HS20
-	if (is_hs20_config(wpa_s) && is_hs20_network(wpa_s, ssid, bss)) {
+	if (is_hs20_network(wpa_s, ssid, bss)
+#ifndef ANDROID /* Android does not use the native HS 2.0 config */
+			&& is_hs20_config(wpa_s)
+#endif /* ANDROID */
+	) {
 		struct wpabuf *hs20;
 
 		hs20 = wpabuf_alloc(20 + MAX_ROAMING_CONS_OI_LEN);
@@ -7581,7 +7585,7 @@
 }
 
 
-#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW) || defined (CONFIG_CTRL_IFACE_HIDL)
+#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW) || defined (CONFIG_CTRL_IFACE_AIDL)
 int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
 					      struct wpa_ssid *ssid,
 					      const char *field,
@@ -7711,7 +7715,7 @@
 	return -1;
 #endif /* IEEE8021X_EAPOL */
 }
-#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW || CONFIG_CTRL_IFACE_HIDL */
+#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW || CONFIG_CTRL_IFACE_AIDL */
 
 
 int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
@@ -8107,7 +8111,7 @@
 	}
 
 #ifdef CONFIG_P2P
-	if (wpa_s->parent == wpa_s &&
+	if ((wpa_s->parent == wpa_s || (wpa_s == wpa_s->p2pdev && wpa_s->p2p_mgmt)) &&
 	    wpa_s->global->p2p &&
 	    !wpa_s->global->p2p_disabled)
 		p2p_set_vendor_elems(wpa_s->global->p2p, wpa_s->vendor_elem);
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 9ce3233..a04d32b 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -47,7 +47,7 @@
 struct ctrl_iface_priv;
 struct ctrl_iface_global_priv;
 struct wpas_dbus_priv;
-struct wpas_hidl_priv;
+struct wpas_aidl_priv;
 
 /**
  * struct wpa_interface - Parameters for wpa_supplicant_add_iface()
@@ -280,7 +280,7 @@
 	struct wpa_params params;
 	struct ctrl_iface_global_priv *ctrl_iface;
 	struct wpas_dbus_priv *dbus;
-	struct wpas_hidl_priv *hidl;
+	struct wpas_aidl_priv *aidl;
 	void **drv_priv;
 	size_t drv_count;
 	struct os_time suspend_time;
@@ -607,9 +607,9 @@
 	char *preq_notify_peer;
 #endif /* CONFIG_AP */
 #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
-#ifdef CONFIG_CTRL_IFACE_HIDL
-	const void *hidl_object_key;
-#endif /* CONFIG_CTRL_IFACE_HIDL */
+#ifdef CONFIG_CTRL_IFACE_AIDL
+	const void *aidl_object_key;
+#endif /* CONFIG_CTRL_IFACE_AIDL */
 	char bridge_ifname[16];
 
 	char *confname;
