diff --git a/wpa_supplicant/Android.bp b/wpa_supplicant/Android.bp
index 8f60cbd..eefce6e 100644
--- a/wpa_supplicant/Android.bp
+++ b/wpa_supplicant/Android.bp
@@ -59,16 +59,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",
@@ -79,11 +75,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",
     ],
 }
 
@@ -129,7 +125,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",
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index 553302c..03c7875 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -85,7 +85,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
@@ -1523,10 +1523,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
@@ -1786,17 +1785,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)
@@ -1840,11 +1836,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)/../COPYING $(LOCAL_PATH)/../NOTICE
@@ -1853,26 +1849,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 82%
rename from wpa_supplicant/hidl/1.4/Android.bp
rename to wpa_supplicant/aidl/Android.bp
index 418b108..0785fe1 100644
--- a/wpa_supplicant/hidl/1.4/Android.bp
+++ b/wpa_supplicant/aidl/Android.bp
@@ -22,24 +22,20 @@
 }
 
 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",
@@ -54,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..f3f04a3
--- /dev/null
+++ b/wpa_supplicant/aidl/aidl.cpp
@@ -0,0 +1,923 @@
+/*
+ * 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);
+}
diff --git a/wpa_supplicant/aidl/aidl.h b/wpa_supplicant/aidl/aidl.h
new file mode 100644
index 0000000..899f99cd
--- /dev/null
+++ b/wpa_supplicant/aidl/aidl.h
@@ -0,0 +1,286 @@
+/*
+ * 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);
+#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)
+{}
+#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..1ce9326
--- /dev/null
+++ b/wpa_supplicant/aidl/aidl_manager.cpp
@@ -0,0 +1,2241 @@
+/*
+ * 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(kWfdR2DeviceInfoLen);
+	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(
+				aidl_peer_wfd_r2_device_info.data(),
+				peer_wfd_r2_device_info, kWfdR2DeviceInfoLen);
+		}
+	}
+
+	if (peer_wfd_r2_device_info_len == kWfdR2DeviceInfoLen) {
+		const std::function<
+			ndk::ScopedAStatus(std::shared_ptr<ISupplicantP2pIfaceCallback>)>
+			func = std::bind(
+			&ISupplicantP2pIfaceCallback::onR2DeviceFound,
+			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);
+		callWithEachP2pIfaceCallback(misc_utils::charBufToString(wpa_s->ifname), func);
+	} else {
+		callWithEachP2pIfaceCallback(
+			misc_utils::charBufToString(wpa_s->ifname),
+			std::bind(
+			&ISupplicantP2pIfaceCallback::onDeviceFound,
+			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));
+	}
+}
+
+void AidlManager::notifyP2pDeviceLost(
+	struct wpa_supplicant *wpa_s, const u8 *p2p_device_addr)
+{
+	if (!wpa_s || !p2p_device_addr)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname), std::bind(
+				   &ISupplicantP2pIfaceCallback::onDeviceLost,
+				   std::placeholders::_1, macAddrToVec(p2p_device_addr)));
+}
+
+void AidlManager::notifyP2pFindStopped(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname), std::bind(
+				   &ISupplicantP2pIfaceCallback::onFindStopped,
+				   std::placeholders::_1));
+}
+
+void AidlManager::notifyP2pGoNegReq(
+	struct wpa_supplicant *wpa_s, const u8 *src_addr, u16 dev_passwd_id,
+	u8 /* go_intent */)
+{
+	if (!wpa_s || !src_addr)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onGoNegotiationRequest,
+		std::placeholders::_1, macAddrToVec(src_addr),
+		static_cast<WpsDevPasswordId>(
+			dev_passwd_id)));
+}
+
+void AidlManager::notifyP2pGoNegCompleted(
+	struct wpa_supplicant *wpa_s, const struct p2p_go_neg_results *res)
+{
+	if (!wpa_s || !res)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onGoNegotiationCompleted,
+		std::placeholders::_1,
+		static_cast<P2pStatusCode>(
+			res->status)));
+}
+
+void AidlManager::notifyP2pGroupFormationFailure(
+	struct wpa_supplicant *wpa_s, const char *reason)
+{
+	if (!wpa_s || !reason)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onGroupFormationFailure,
+		std::placeholders::_1, reason));
+}
+
+void AidlManager::notifyP2pGroupStarted(
+	struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
+	int persistent, int client)
+{
+	if (!wpa_group_s || !wpa_group_s->parent || !ssid)
+		return;
+
+	// For group notifications, need to use the parent iface for callbacks.
+	struct wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
+	if (!wpa_s)
+		return;
+
+	uint32_t aidl_freq = wpa_group_s->current_bss
+				 ? wpa_group_s->current_bss->freq
+				 : wpa_group_s->assoc_freq;
+	std::vector<uint8_t> aidl_psk(32);
+	if (ssid->psk_set) {
+		aidl_psk.assign(ssid->psk, ssid->psk + 32);
+	}
+	bool aidl_is_go = (client == 0 ? true : false);
+	bool aidl_is_persistent = (persistent == 1 ? true : false);
+
+	// notify the group device again to ensure the framework knowing this device.
+	struct p2p_data *p2p = wpa_s->global->p2p;
+	struct p2p_device *dev = p2p_get_device(p2p, wpa_group_s->go_dev_addr);
+	if (NULL != dev) {
+		wpa_printf(MSG_DEBUG, "P2P: Update GO device on group started.");
+		p2p->cfg->dev_found(p2p->cfg->cb_ctx, wpa_group_s->go_dev_addr,
+				&dev->info, !(dev->flags & P2P_DEV_REPORTED_ONCE));
+		dev->flags |= P2P_DEV_REPORTED | P2P_DEV_REPORTED_ONCE;
+	}
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onGroupStarted,
+		std::placeholders::_1, misc_utils::charBufToString(wpa_group_s->ifname),
+		aidl_is_go, byteArrToVec(ssid->ssid, ssid->ssid_len),
+		aidl_freq, aidl_psk, misc_utils::charBufToString(ssid->passphrase),
+		macAddrToVec(wpa_group_s->go_dev_addr), aidl_is_persistent));
+}
+
+void AidlManager::notifyP2pGroupRemoved(
+	struct wpa_supplicant *wpa_group_s, const struct wpa_ssid *ssid,
+	const char *role)
+{
+	if (!wpa_group_s || !wpa_group_s->parent || !ssid || !role)
+		return;
+
+	// For group notifications, need to use the parent iface for callbacks.
+	struct wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
+	if (!wpa_s)
+		return;
+
+	bool aidl_is_go = (std::string(role) == "GO");
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onGroupRemoved,
+		std::placeholders::_1, misc_utils::charBufToString(wpa_group_s->ifname), aidl_is_go));
+}
+
+void AidlManager::notifyP2pInvitationReceived(
+	struct wpa_supplicant *wpa_s, const u8 *sa, const u8 *go_dev_addr,
+	const u8 *bssid, int id, int op_freq)
+{
+	if (!wpa_s || !sa || !go_dev_addr || !bssid)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	int aidl_network_id;
+	if (id < 0) {
+		aidl_network_id = UINT32_MAX;
+	}
+	aidl_network_id = id;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onInvitationReceived,
+		std::placeholders::_1, macAddrToVec(sa), macAddrToVec(go_dev_addr),
+		macAddrToVec(bssid), aidl_network_id, op_freq));
+}
+
+void AidlManager::notifyP2pInvitationResult(
+	struct wpa_supplicant *wpa_s, int status, const u8 *bssid)
+{
+	if (!wpa_s)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onInvitationResult,
+		std::placeholders::_1, bssid ? macAddrToVec(bssid) : kZeroBssid,
+		static_cast<P2pStatusCode>(
+			status)));
+}
+
+void AidlManager::notifyP2pProvisionDiscovery(
+	struct wpa_supplicant *wpa_s, const u8 *dev_addr, int request,
+	enum p2p_prov_disc_status status, u16 config_methods,
+	unsigned int generated_pin)
+{
+	if (!wpa_s || !dev_addr)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	std::string aidl_generated_pin;
+	if (generated_pin > 0) {
+		aidl_generated_pin =
+			misc_utils::convertWpsPinToString(generated_pin);
+	}
+	bool aidl_is_request = (request == 1 ? true : false);
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onProvisionDiscoveryCompleted,
+		std::placeholders::_1, macAddrToVec(dev_addr), aidl_is_request,
+		static_cast<P2pProvDiscStatusCode>(status),
+		static_cast<WpsConfigMethods>(config_methods), aidl_generated_pin));
+}
+
+void AidlManager::notifyP2pSdResponse(
+	struct wpa_supplicant *wpa_s, const u8 *sa, u16 update_indic,
+	const u8 *tlvs, size_t tlvs_len)
+{
+	if (!wpa_s || !sa || !tlvs)
+		return;
+
+	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
+		p2p_iface_object_map_.end())
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onServiceDiscoveryResponse,
+		std::placeholders::_1, macAddrToVec(sa), update_indic,
+		byteArrToVec(tlvs, tlvs_len)));
+}
+
+void AidlManager::notifyApStaAuthorized(
+	struct wpa_supplicant *wpa_group_s, const u8 *sta, const u8 *p2p_dev_addr)
+{
+	if (!wpa_group_s || !wpa_group_s->parent || !sta)
+		return;
+	wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
+	if (!wpa_s)
+		return;
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onStaAuthorized,
+		std::placeholders::_1, macAddrToVec(sta),
+		p2p_dev_addr ? macAddrToVec(p2p_dev_addr) : kZeroBssid));
+}
+
+void AidlManager::notifyApStaDeauthorized(
+	struct wpa_supplicant *wpa_group_s, const u8 *sta, const u8 *p2p_dev_addr)
+{
+	if (!wpa_group_s || !wpa_group_s->parent || !sta)
+		return;
+	wpa_supplicant *wpa_s = getTargetP2pIfaceForGroup(wpa_group_s);
+	if (!wpa_s)
+		return;
+
+	callWithEachP2pIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantP2pIfaceCallback::onStaDeauthorized,
+		std::placeholders::_1, macAddrToVec(sta),
+		p2p_dev_addr ? macAddrToVec(p2p_dev_addr) : kZeroBssid));
+}
+
+void AidlManager::notifyExtRadioWorkStart(
+	struct wpa_supplicant *wpa_s, uint32_t id)
+{
+	if (!wpa_s)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onExtRadioWorkStart,
+		std::placeholders::_1, id));
+}
+
+void AidlManager::notifyExtRadioWorkTimeout(
+	struct wpa_supplicant *wpa_s, uint32_t id)
+{
+	if (!wpa_s)
+		return;
+
+	if (sta_iface_object_map_.find(wpa_s->ifname) ==
+		sta_iface_object_map_.end())
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onExtRadioWorkTimeout,
+		std::placeholders::_1, id));
+}
+
+void AidlManager::notifyEapError(struct wpa_supplicant *wpa_s, int error_code)
+{
+	if (!wpa_s)
+		return;
+
+	callWithEachStaIfaceCallback(
+		misc_utils::charBufToString(wpa_s->ifname),
+		std::bind(
+		&ISupplicantStaIfaceCallback::onEapFailure,
+		std::placeholders::_1, error_code));
+}
+
+/**
+ * Notify listener about a new DPP configuration received success event
+ *
+ * @param ifname Interface name
+ * @param config Configuration object
+ */
+void AidlManager::notifyDppConfigReceived(struct wpa_supplicant *wpa_s,
+		struct wpa_ssid *config)
+{
+	DppAkm securityAkm;
+	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 {
+		/* 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);
+
+	/* 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));
+}
+
+/**
+ * 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);
+}
+
+/**
+ * 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..b538e36
--- /dev/null
+++ b/wpa_supplicant/aidl/aidl_manager.h
@@ -0,0 +1,701 @@
+/*
+ * 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);
+
+	// 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..42b57e9
--- /dev/null
+++ b/wpa_supplicant/aidl/p2p_iface.cpp
@@ -0,0 +1,2028 @@
+/*
+ * 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;
+
+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);
+	}
+
+}
+
+}  // 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);
+}
+
+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",
+			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 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();
+}
+
+/**
+ * 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..d24645c
--- /dev/null
+++ b/wpa_supplicant/aidl/p2p_iface.h
@@ -0,0 +1,300 @@
+/*
+ * 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;
+
+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);
+
+	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..7238267
--- /dev/null
+++ b/wpa_supplicant/aidl/sta_iface.cpp
@@ -0,0 +1,1757 @@
+/*
+ * 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)
+{
+	return validateAndCall(
+		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		&StaIface::startDppConfiguratorInitiatorInternal,
+		in_peerBootstrapId,in_ownBootstrapId, in_ssid, in_password,
+		in_psk, in_netRole, in_securityAkm);
+}
+
+::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::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);
+}
+
+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);
+}
+
+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)
+{
+#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 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) {
+		wpa_printf(MSG_ERROR, "DPP: Error: invalid AKM specified: %d",
+				security_akm);
+		return 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 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 createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
+		}
+		if (password.empty() && psk.empty()) {
+			wpa_printf(MSG_ERROR, "DPP: Error: Password or PSK not specified");
+			return 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;
+
+	default:
+		wpa_printf(MSG_ERROR,
+			   "DPP: Invalid or unsupported security AKM specified: %d", security_akm);
+		return 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 ndk::ScopedAStatus::ok();
+	}
+#endif
+	return 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
+}
+
+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);
+
+	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()};
+}
+
+/**
+ * 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..98c3187
--- /dev/null
+++ b/wpa_supplicant/aidl/sta_iface.h
@@ -0,0 +1,263 @@
+/*
+ * 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/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) 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;
+
+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);
+	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);
+	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);
+
+	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..b6294da
--- /dev/null
+++ b/wpa_supplicant/aidl/sta_network.cpp
@@ -0,0 +1,2461 @@
+/*
+ * 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::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);
+}
+
+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::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;
+	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()};
+}
+
+/**
+ * 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..f1ef1ad
--- /dev/null
+++ b/wpa_supplicant/aidl/sta_network.h
@@ -0,0 +1,342 @@
+/*
+ * 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>
+
+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 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;
+
+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 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);
+
+	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 6b554f1..0000000
--- a/wpa_supplicant/hidl/1.4/p2p_iface.cpp
+++ /dev/null
@@ -1,2037 +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 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, allocate one extra
-	 * slot for the zero-terminator.
-	 */
-	params->freqs = (int *) os_calloc(2, sizeof(int));
-	if (params->freqs) {
-		params->freqs[0] = frequency;
-	} else {
-		return -ENOMEM;
-	}
-	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;
-		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);
-	}
-
-}
-
-}  // 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;
-	wpa_bss_flush(wpa_s);
-	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);
-
-	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",
-		    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..b3cb287 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);
@@ -640,7 +640,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 +658,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 +674,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 +686,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 +695,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 +704,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 +713,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 +734,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 +762,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 +778,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 +788,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 +807,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 +835,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 +855,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);
 }
@@ -935,7 +935,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 +982,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 +994,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 +1007,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 +1019,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 +1030,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 +1092,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 +1102,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 +1113,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 +1123,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 +1134,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 +1144,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 +1154,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 +1164,7 @@
 	if (!wpa_s)
 		return;
 
-	wpas_hidl_notify_dpp_timeout(wpa_s);
+	wpas_aidl_notify_dpp_timeout(wpa_s);
 #endif /* CONFIG_DPP */
 }
 
@@ -1174,7 +1174,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 +1184,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 +1207,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 +1224,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 +1237,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 +1245,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/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 3471b99..5cc6952 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -7581,7 +7581,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 +7711,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)
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;
