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 0f9f83a..0ae8207 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..f9f0412
--- /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, std::vector<uint8_t>(), 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..f382285
--- /dev/null
+++ b/wpa_supplicant/aidl/sta_iface.cpp
@@ -0,0 +1,1843 @@
+/*
+ * 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(
+	int32_t in_qosPolicyRequestId, bool in_morePolicies,
+	const std::vector<QosPolicyStatus>& in_qosPolicyStatusList)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_UNKNOWN,
+		&StaIface::sendQosPolicyResponseInternal, in_qosPolicyRequestId,
+		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(
+	int32_t qos_policy_request_id, 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..0ed29d8
--- /dev/null
+++ b/wpa_supplicant/aidl/sta_iface.h
@@ -0,0 +1,282 @@
+/*
+ * 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(
+		int32_t in_qosPolicyRequestId, 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(
+		int32_t qos_policy_request_id, 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;
