diff --git a/wpa_supplicant/hidl/1.0/hidl.cpp b/wpa_supplicant/hidl/1.0/hidl.cpp
deleted file mode 100644
index ce8a459..0000000
--- a/wpa_supplicant/hidl/1.0/hidl.cpp
+++ /dev/null
@@ -1,627 +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"
-}
-
-using android::hardware::configureRpcThreadpool;
-using android::hardware::setupTransportPolling;
-using android::hardware::handleTransportPoll;
-using android::hardware::wifi::supplicant::V1_0::implementation::HidlManager;
-
-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;
-	hidl_manager->registerHidlService(global);
-	// 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 || !url)
-		return;
-
-	wpa_printf(
-	    MSG_DEBUG,
-	    "Notifying HS20 deauth imminent notice rx to hidl control: %s",
-	    url);
-
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager)
-		return;
-
-	hidl_manager->notifyHs20RxDeauthImminentNotice(
-	    wpa_s, code, reauth_delay, 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)
-{
-	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);
-}
-
-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)
-{
-	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);
-}
-
-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);
-}
diff --git a/wpa_supplicant/hidl/1.0/hidl.h b/wpa_supplicant/hidl/1.0/hidl.h
deleted file mode 100644
index 96631f2..0000000
--- a/wpa_supplicant/hidl/1.0/hidl.h
+++ /dev/null
@@ -1,221 +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_disconnect_reason(struct wpa_supplicant *wpa_s);
-void wpas_hidl_notify_assoc_reject(struct wpa_supplicant *wpa_s);
-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);
-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);
-#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)
-{
-}
-static void wpas_hidl_notify_disconnect_reason(struct wpa_supplicant *wpa_s) {}
-static void wpas_hidl_notify_assoc_reject(struct wpa_supplicant *wpa_s) {}
-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)
-{
-}
-#endif  // CONFIG_CTRL_IFACE_HIDL
-
-#ifdef _cplusplus
-}
-#endif  // _cplusplus
-
-#endif  // WPA_SUPPLICANT_HIDL_HIDL_H
diff --git a/wpa_supplicant/hidl/1.0/hidl_constants.h b/wpa_supplicant/hidl/1.0/hidl_constants.h
deleted file mode 100644
index 988a590..0000000
--- a/wpa_supplicant/hidl/1.0/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.0/hidl_i.h b/wpa_supplicant/hidl/1.0/hidl_i.h
deleted file mode 100644
index c7a0142..0000000
--- a/wpa_supplicant/hidl/1.0/hidl_i.h
+++ /dev/null
@@ -1,28 +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.0/hidl_manager.cpp b/wpa_supplicant/hidl/1.0/hidl_manager.cpp
deleted file mode 100644
index 4655da2..0000000
--- a/wpa_supplicant/hidl/1.0/hidl_manager.cpp
+++ /dev/null
@@ -1,1777 +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 <regex>
-
-#include "hidl_manager.h"
-#include "misc_utils.h"
-
-extern "C" {
-#include "src/eap_common/eap_sim_common.h"
-}
-
-namespace {
-using android::hardware::hidl_array;
-
-constexpr uint8_t kWfdDeviceInfoLen = 6;
-// 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<CallbackType> &callback,
-    const std::function<void(const android::sp<CallbackType> &)>
-	&on_hidl_died_fctor,
-    std::vector<android::sp<CallbackType>> &callback_list)
-{
-#if 0   // TODO(b/31632518): HIDL object death notifications.
-	auto death_notifier = new CallbackObjectDeathNotifier<CallbackType>(
-	    callback, on_hidl_died_fctor);
-	// Use the |callback.get()| as cookie so that we don't need to
-	// store a reference to this |CallbackObjectDeathNotifier| instance
-	// to use in |unlinkToDeath| later.
-	// NOTE: This may cause an immediate callback if the object is already
-	// dead, so add it to the list before we register for callback!
-	if (android::hardware::IInterface::asBinder(callback)->linkToDeath(
-		death_notifier, callback.get()) != android::OK) {
-		wpa_printf(
-		    MSG_ERROR,
-		    "Error registering for death notification for "
-		    "supplicant callback object");
-		callback_list.erase(
-		    std::remove(
-			callback_list.begin(), callback_list.end(), callback),
-		    callback_list.end());
-		return 1;
-	}
-#endif  // TODO(b/31632518): HIDL object death notifications.
-	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 std::string &ifname, const android::sp<CallbackType> &callback,
-    const std::function<void(const android::sp<CallbackType> &)>
-	&on_hidl_died_fctor,
-    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>(
-	    callback, on_hidl_died_fctor, iface_callback_list);
-}
-
-template <class CallbackType>
-int addNetworkCallbackHidlObjectToMap(
-    const std::string &ifname, int network_id,
-    const android::sp<CallbackType> &callback,
-    const std::function<void(const android::sp<CallbackType> &)>
-	&on_hidl_died_fctor,
-    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>(
-	    callback, on_hidl_died_fctor, network_callback_list);
-}
-
-template <class CallbackType>
-int removeAllIfaceCallbackHidlObjectsFromMap(
-    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;
-#if 0   // TODO(b/31632518): HIDL object death notifications.
-	const auto &iface_callback_list = iface_callback_map_iter->second;
-	for (const auto &callback : iface_callback_list) {
-		if (android::hardware::IInterface::asBinder(callback)
-			->unlinkToDeath(nullptr, callback.get()) !=
-		    android::OK) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Error deregistering for death notification for "
-			    "iface callback object");
-		}
-	}
-#endif  // TODO(b/31632518): HIDL object death notifications.
-	callbacks_map.erase(iface_callback_map_iter);
-	return 0;
-}
-
-template <class CallbackType>
-int removeAllNetworkCallbackHidlObjectsFromMap(
-    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;
-#if 0   // TODO(b/31632518): HIDL object death notifications.
-	const auto &network_callback_list = network_callback_map_iter->second;
-	for (const auto &callback : network_callback_list) {
-		if (android::hardware::IInterface::asBinder(callback)
-			->unlinkToDeath(nullptr, callback.get()) !=
-		    android::OK) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Error deregistering for death "
-			    "notification for "
-			    "network callback object");
-		}
-	}
-#endif  // TODO(b/31632518): HIDL object death notifications.
-	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 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");
-		}
-	}
-}
-
-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_0 {
-namespace implementation {
-
-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);
-	if (supplicant_object_->registerAsService() != android::NO_ERROR) {
-		return 1;
-	}
-	if (!supplicant_object_->ensureConfigFileExists()) {
-		// If config file does not exist, we cannot start supplicant.
-		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>>();
-	}
-
-	// 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;
-
-	if (isP2pIface(wpa_s)) {
-		if (removeHidlObjectFromMap(
-			wpa_s->ifname, p2p_iface_object_map_)) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Failed to unregister P2P interface with HIDL "
-			    "control: %s",
-			    wpa_s->ifname);
-			return 1;
-		}
-		if (removeAllIfaceCallbackHidlObjectsFromMap(
-			wpa_s->ifname, p2p_iface_callbacks_map_)) {
-			return 1;
-		}
-	} else {
-		if (removeHidlObjectFromMap(
-			wpa_s->ifname, sta_iface_object_map_)) {
-			wpa_printf(
-			    MSG_ERROR,
-			    "Failed to unregister STA interface with HIDL "
-			    "control: %s",
-			    wpa_s->ifname);
-			return 1;
-		}
-		if (removeAllIfaceCallbackHidlObjectsFromMap(
-			wpa_s->ifname, sta_iface_callbacks_map_)) {
-			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(
-			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(
-			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;
-	}
-	callWithEachStaIfaceCallback(
-	    wpa_s->ifname, std::bind(
-			       &ISupplicantStaIfaceCallback::onStateChanged,
-			       std::placeholders::_1,
-			       static_cast<ISupplicantStaIfaceCallback::State>(
-				   wpa_s->wpa_state),
-			       bssid, hidl_network_id, hidl_ssid));
-	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;
-
-	ISupplicantStaIfaceCallback::AnqpData hidl_anqp_data;
-	ISupplicantStaIfaceCallback::Hs20AnqpData hidl_hs20_anqp_data;
-	if (std::string(result) == "SUCCESS") {
-		hidl_anqp_data.venueName =
-		    misc_utils::convertWpaBufToVector(anqp->venue_name);
-		hidl_anqp_data.roamingConsortium =
-		    misc_utils::convertWpaBufToVector(anqp->roaming_consortium);
-		hidl_anqp_data.ipAddrTypeAvailability =
-		    misc_utils::convertWpaBufToVector(
-			anqp->ip_addr_type_availability);
-		hidl_anqp_data.naiRealm =
-		    misc_utils::convertWpaBufToVector(anqp->nai_realm);
-		hidl_anqp_data.anqp3gppCellularNetwork =
-		    misc_utils::convertWpaBufToVector(anqp->anqp_3gpp);
-		hidl_anqp_data.domainName =
-		    misc_utils::convertWpaBufToVector(anqp->domain_name);
-
-		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(
-	    wpa_s->ifname, std::bind(
-			       &ISupplicantStaIfaceCallback::onAnqpQueryDone,
-			       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 immient 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.
- */
-void HidlManager::notifyHs20RxDeauthImminentNotice(
-    struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay, const char *url)
-{
-	if (!wpa_s || !url)
-		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 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.
- */
-void HidlManager::notifyAssocReject(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::onAssociationRejected,
-		std::placeholders::_1, bssid,
-		static_cast<ISupplicantStaIfaceCallback::StatusCode>(
-		    wpa_s->assoc_status_code),
-		wpa_s->assoc_timed_out == 1));
-}
-
-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)
-{
-	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);
-		}
-	}
-
-	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 = wpa_group_s->parent;
-	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
-	    p2p_iface_object_map_.end())
-		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);
-
-	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 = wpa_group_s->parent;
-	if (p2p_iface_object_map_.find(wpa_s->ifname) ==
-	    p2p_iface_object_map_.end())
-		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_s, const u8 *sta, const u8 *p2p_dev_addr)
-{
-	if (!wpa_s || !wpa_s->parent || !sta)
-		return;
-	if (p2p_iface_object_map_.find(wpa_s->parent->ifname) ==
-	    p2p_iface_object_map_.end())
-		return;
-	callWithEachP2pIfaceCallback(
-	    wpa_s->parent->ifname, std::bind(
-			       &ISupplicantP2pIfaceCallback::onStaAuthorized,
-			       std::placeholders::_1, sta, p2p_dev_addr ? p2p_dev_addr : kZeroBssid));
-}
-
-void HidlManager::notifyApStaDeauthorized(
-    struct wpa_supplicant *wpa_s, const u8 *sta, const u8 *p2p_dev_addr)
-{
-	if (!wpa_s || !wpa_s->parent || !sta)
-		return;
-	if (p2p_iface_object_map_.find(wpa_s->parent->ifname) ==
-	    p2p_iface_object_map_.end())
-		return;
-
-	callWithEachP2pIfaceCallback(
-	    wpa_s->parent->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));
-}
-
-/**
- * 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<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<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)
-{
-	// Register for death notification before we add it to our list.
-	auto on_hidl_died_fctor = std::bind(
-	    &HidlManager::removeSupplicantCallbackHidlObject, this,
-	    std::placeholders::_1);
-	return registerForDeathAndAddCallbackHidlObjectToList<
-	    ISupplicantCallback>(
-	    callback, on_hidl_died_fctor, 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)
-{
-	const std::function<void(
-	    const android::sp<ISupplicantP2pIfaceCallback> &)>
-	    on_hidl_died_fctor = std::bind(
-		&HidlManager::removeP2pIfaceCallbackHidlObject, this, ifname,
-		std::placeholders::_1);
-	return addIfaceCallbackHidlObjectToMap(
-	    ifname, callback, on_hidl_died_fctor, 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)
-{
-	const std::function<void(
-	    const android::sp<ISupplicantStaIfaceCallback> &)>
-	    on_hidl_died_fctor = std::bind(
-		&HidlManager::removeStaIfaceCallbackHidlObject, this, ifname,
-		std::placeholders::_1);
-	return addIfaceCallbackHidlObjectToMap(
-	    ifname, callback, on_hidl_died_fctor, 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)
-{
-	const std::function<void(
-	    const android::sp<ISupplicantP2pNetworkCallback> &)>
-	    on_hidl_died_fctor = std::bind(
-		&HidlManager::removeP2pNetworkCallbackHidlObject, this, ifname,
-		network_id, std::placeholders::_1);
-	return addNetworkCallbackHidlObjectToMap(
-	    ifname, network_id, callback, on_hidl_died_fctor,
-	    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)
-{
-	const std::function<void(
-	    const android::sp<ISupplicantStaNetworkCallback> &)>
-	    on_hidl_died_fctor = std::bind(
-		&HidlManager::removeStaNetworkCallbackHidlObject, this, ifname,
-		network_id, std::placeholders::_1);
-	return addNetworkCallbackHidlObjectToMap(
-	    ifname, network_id, callback, on_hidl_died_fctor,
-	    sta_network_callbacks_map_);
-}
-
-/**
- * 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 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::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_);
-}
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace wifi
-}  // namespace supplicant
-}  // namespace hardware
-}  // namespace android
diff --git a/wpa_supplicant/hidl/1.0/hidl_manager.h b/wpa_supplicant/hidl/1.0/hidl_manager.h
deleted file mode 100644
index 9d9527c..0000000
--- a/wpa_supplicant/hidl/1.0/hidl_manager.h
+++ /dev/null
@@ -1,678 +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.0/ISupplicantStaIfaceCallback.h>
-#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaNetworkCallback.h>
-
-#include "p2p_iface.h"
-#include "p2p_network.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 android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_0 {
-namespace implementation {
-
-/**
- * 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 notifyDisconnectReason(struct wpa_supplicant *wpa_s);
-	void notifyAssocReject(struct wpa_supplicant *wpa_s);
-	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);
-	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);
-
-	// 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<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<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;
-
-	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);
-	void callWithEachStaIfaceCallback(
-	    const std::string &ifname,
-	    const std::function<android::hardware::Return<void>(
-		android::sp<ISupplicantStaIfaceCallback>)> &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);
-
-	// Singleton instance of this class.
-	static HidlManager *instance_;
-	// 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_;
-
-#if 0  // TODO(b/31632518): HIDL object death notifications.
-	/**
-	 * Helper class used to deregister the callback object reference from
-	 * our callback list on the death of the hidl object.
-	 * This class stores a reference of the callback hidl object and a
-	 * function to be called to indicate the death of the hidl object.
-	 */
-	template <class CallbackType>
-	class CallbackObjectDeathNotifier
-	    : public android::hardware::IBinder::DeathRecipient
-	{
-	public:
-		CallbackObjectDeathNotifier(
-		    const android::sp<CallbackType> &callback,
-		    const std::function<void(const android::sp<CallbackType> &)>
-			&on_hidl_died)
-		    : callback_(callback), on_hidl_died_(on_hidl_died)
-		{
-		}
-		void binderDied(const android::wp<android::hardware::IBinder>
-				    & /* who */) override
-		{
-			on_hidl_died_(callback_);
-		}
-
-	private:
-		// The callback hidl object reference.
-		const android::sp<CallbackType> callback_;
-		// Callback function to be called when the hidl dies.
-		const std::function<void(const android::sp<CallbackType> &)>
-		    on_hidl_died_;
-	};
-#endif
-};
-
-// 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>(ISupplicantStaNetwork::KeyMgmtMask::NONE) ==
-	WPA_KEY_MGMT_NONE,
-    "KeyMgmt value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::WPA_PSK) ==
-	WPA_KEY_MGMT_PSK,
-    "KeyMgmt value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::WPA_EAP) ==
-	WPA_KEY_MGMT_IEEE8021X,
-    "KeyMgmt value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::IEEE8021X) ==
-	WPA_KEY_MGMT_IEEE8021X_NO_WPA,
-    "KeyMgmt value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::FT_EAP) ==
-	WPA_KEY_MGMT_FT_IEEE8021X,
-    "KeyMgmt value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::FT_PSK) ==
-	WPA_KEY_MGMT_FT_PSK,
-    "KeyMgmt value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaNetwork::KeyMgmtMask::OSEN) ==
-	WPA_KEY_MGMT_OSEN,
-    "KeyMgmt value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaNetwork::ProtoMask::WPA) ==
-	WPA_PROTO_WPA,
-    "Proto value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaNetwork::ProtoMask::RSN) ==
-	WPA_PROTO_RSN,
-    "Proto value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaNetwork::ProtoMask::OSEN) ==
-	WPA_PROTO_OSEN,
-    "Proto value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaNetwork::AuthAlgMask::OPEN) ==
-	WPA_AUTH_ALG_OPEN,
-    "AuthAlg value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaNetwork::AuthAlgMask::SHARED) ==
-	WPA_AUTH_ALG_SHARED,
-    "AuthAlg value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaNetwork::AuthAlgMask::LEAP) ==
-	WPA_AUTH_ALG_LEAP,
-    "AuthAlg value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaNetwork::GroupCipherMask::WEP40) ==
-	WPA_CIPHER_WEP40,
-    "GroupCipher value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaNetwork::GroupCipherMask::WEP104) ==
-	WPA_CIPHER_WEP104,
-    "GroupCipher value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaNetwork::GroupCipherMask::TKIP) ==
-	WPA_CIPHER_TKIP,
-    "GroupCipher value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaNetwork::GroupCipherMask::CCMP) ==
-	WPA_CIPHER_CCMP,
-    "GroupCipher value mismatch");
-static_assert(
-    static_cast<uint32_t>(
-	ISupplicantStaNetwork::GroupCipherMask::GTK_NOT_USED) ==
-	WPA_CIPHER_GTK_NOT_USED,
-    "GroupCipher value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaNetwork::PairwiseCipherMask::NONE) ==
-	WPA_CIPHER_NONE,
-    "PairwiseCipher value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaNetwork::PairwiseCipherMask::TKIP) ==
-	WPA_CIPHER_TKIP,
-    "PairwiseCipher value mismatch");
-static_assert(
-    static_cast<uint32_t>(ISupplicantStaNetwork::PairwiseCipherMask::CCMP) ==
-	WPA_CIPHER_CCMP,
-    "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_0
-}  // namespace wifi
-}  // namespace supplicant
-}  // namespace hardware
-}  // namespace android
-#endif  // WPA_SUPPLICANT_HIDL_HIDL_MANAGER_H
diff --git a/wpa_supplicant/hidl/1.0/hidl_return_util.h b/wpa_supplicant/hidl/1.0/hidl_return_util.h
deleted file mode 100644
index c077fc8..0000000
--- a/wpa_supplicant/hidl/1.0/hidl_return_util.h
+++ /dev/null
@@ -1,101 +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_0 {
-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 WorkFuncT, typename... Args>
-Return<void> validateAndCall(
-    ObjT* obj, SupplicantStatusCode status_code_if_invalid, WorkFuncT&& work,
-    const std::function<void(const SupplicantStatus&)>& 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 WorkFuncT, typename ReturnT, typename... Args>
-Return<void> validateAndCall(
-    ObjT* obj, SupplicantStatusCode status_code_if_invalid, WorkFuncT&& work,
-    const std::function<void(const SupplicantStatus&, ReturnT)>& hidl_cb,
-    Args&&... args)
-{
-	if (obj->isValid()) {
-		const auto& ret_pair =
-		    (obj->*work)(std::forward<Args>(args)...);
-		const SupplicantStatus& 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 WorkFuncT, typename ReturnT1, typename ReturnT2,
-    typename... Args>
-Return<void> validateAndCall(
-    ObjT* obj, SupplicantStatusCode status_code_if_invalid, WorkFuncT&& work,
-    const std::function<void(const SupplicantStatus&, ReturnT1, ReturnT2)>&
-	hidl_cb,
-    Args&&... args)
-{
-	if (obj->isValid()) {
-		const auto& ret_tuple =
-		    (obj->*work)(std::forward<Args>(args)...);
-		const SupplicantStatus& 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_util
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace supplicant
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-#endif  // HIDL_RETURN_UTIL_H_
diff --git a/wpa_supplicant/hidl/1.0/iface_config_utils.cpp b/wpa_supplicant/hidl/1.0/iface_config_utils.cpp
deleted file mode 100644
index 7dc5a6c..0000000
--- a/wpa_supplicant/hidl/1.0/iface_config_utils.cpp
+++ /dev/null
@@ -1,180 +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 {
-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_0 {
-namespace implementation {
-namespace iface_config_utils {
-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_0
-}  // namespace wifi
-}  // namespace supplicant
-}  // namespace hardware
-}  // namespace android
diff --git a/wpa_supplicant/hidl/1.0/iface_config_utils.h b/wpa_supplicant/hidl/1.0/iface_config_utils.h
deleted file mode 100644
index 789cc38..0000000
--- a/wpa_supplicant/hidl/1.0/iface_config_utils.h
+++ /dev/null
@@ -1,59 +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_0 {
-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_0
-}  // namespace wifi
-}  // namespace supplicant
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WPA_SUPPLICANT_HIDL_IFACE_CONFIG_UTILS_H
diff --git a/wpa_supplicant/hidl/1.0/misc_utils.h b/wpa_supplicant/hidl/1.0/misc_utils.h
deleted file mode 100644
index 354ec32..0000000
--- a/wpa_supplicant/hidl/1.0/misc_utils.h
+++ /dev/null
@@ -1,72 +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 MISC_UTILS_H_
-#define MISC_UTILS_H_
-
-extern "C" {
-#include "wpabuf.h"
-}
-
-namespace {
-constexpr size_t kWpsPinNumDigits = 8;
-// Custom deleter for wpabuf.
-void freeWpaBuf(wpabuf *ptr) { wpabuf_free(ptr); }
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_0 {
-namespace implementation {
-namespace misc_utils {
-using wpabuf_unique_ptr = std::unique_ptr<wpabuf, void (*)(wpabuf *)>;
-
-// Creates a unique_ptr for wpabuf ptr with a custom deleter.
-inline wpabuf_unique_ptr createWpaBufUniquePtr(struct wpabuf *raw_ptr)
-{
-	return {raw_ptr, freeWpaBuf};
-}
-
-// Creates a wpabuf ptr with a custom deleter copying the data from the provided
-// vector.
-inline wpabuf_unique_ptr convertVectorToWpaBuf(const std::vector<uint8_t> &data)
-{
-	return createWpaBufUniquePtr(
-	    wpabuf_alloc_copy(data.data(), data.size()));
-}
-
-// Copies the provided wpabuf contents to a std::vector.
-inline std::vector<uint8_t> convertWpaBufToVector(const struct wpabuf *buf)
-{
-	if (buf) {
-		return std::vector<uint8_t>(
-		    wpabuf_head_u8(buf), wpabuf_head_u8(buf) + wpabuf_len(buf));
-	} else {
-		return std::vector<uint8_t>();
-	}
-}
-
-// Returns a string holding the wps pin.
-inline std::string convertWpsPinToString(int pin)
-{
-	char pin_str[kWpsPinNumDigits + 1];
-	snprintf(pin_str, sizeof(pin_str), "%08d", pin);
-	return pin_str;
-}
-
-}  // namespace misc_utils
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace supplicant
-}  // namespace wifi
-}  // namespace hardware
-}  // namespace android
-#endif  // MISC_UTILS_H_
diff --git a/wpa_supplicant/hidl/1.0/p2p_iface.cpp b/wpa_supplicant/hidl/1.0/p2p_iface.cpp
deleted file mode 100644
index 7a94a31..0000000
--- a/wpa_supplicant/hidl/1.0/p2p_iface.cpp
+++ /dev/null
@@ -1,1284 +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"
-
-extern "C" {
-#include "ap.h"
-#include "wps_supplicant.h"
-#include "wifi_display.h"
-}
-
-namespace {
-const char kConfigMethodStrPbc[] = "pbc";
-const char kConfigMethodStrDisplay[] = "display";
-const char kConfigMethodStrKeypad[] = "keypad";
-constexpr char kSetMiracastMode[] = "MIRACAST ";
-constexpr uint8_t kWfdDeviceInfoSubelemId = 0;
-constexpr char kWfdDeviceInfoSubelemLenHexStr[] = "0006";
-
-using android::hardware::wifi::supplicant::V1_0::ISupplicantP2pIface;
-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);
-}
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_0 {
-namespace implementation {
-using hidl_return_util::validateAndCall;
-
-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);
-}
-
-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, ""};
-	}
-	wpas_p2p_stop_find(wpa_s);
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus P2pIface::flushInternal()
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	os_memset(wpa_s->p2p_auth_invite, 0, ETH_ALEN);
-	wpa_s->force_long_sd = 0;
-	wpas_p2p_stop_find(wpa_s);
-	wpa_s->parent->p2ps_method_config_any = 0;
-	if (wpa_s->global->p2p)
-		p2p_flush(wpa_s->global->p2p);
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-// This method only implements support for subset (needed by Android framework)
-// of parameters that can be specified for connect.
-std::pair<SupplicantStatus, std::string> P2pIface::connectInternal(
-    const std::array<uint8_t, 6>& peer_address,
-    ISupplicantP2pIface::WpsProvisionMethod provision_method,
-    const std::string& pre_selected_pin, bool join_existing_group,
-    bool persistent, uint32_t go_intent)
-{
-	struct wpa_supplicant* wpa_s = retrieveIfacePtr();
-	if (go_intent > 15) {
-		return {{SupplicantStatusCode::FAILURE_ARGS_INVALID, ""}, {}};
-	}
-	int go_intent_signed = join_existing_group ? -1 : go_intent;
-	p2p_wps_method wps_method = {};
-	switch (provision_method) {
-	case WpsProvisionMethod::PBC:
-		wps_method = WPS_PBC;
-		break;
-	case WpsProvisionMethod::DISPLAY:
-		wps_method = WPS_PIN_DISPLAY;
-		break;
-	case WpsProvisionMethod::KEYPAD:
-		wps_method = WPS_PIN_KEYPAD;
-		break;
-	}
-	int 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;
-	int new_pin = wpas_p2p_connect(
-	    wpa_s, peer_address.data(), pin, wps_method,
-	    persistent, false, join_existing_group, false, go_intent_signed, 0, 0, -1,
-	    false, ht40, vht, VHT_CHANWIDTH_USE_HT, 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 (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 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,
-			VHT_CHANWIDTH_USE_HT)) {
-			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,
-			VHT_CHANWIDTH_USE_HT, 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, ""};
-	}
-	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 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,
-		VHT_CHANWIDTH_USE_HT, 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)) {
-		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, ""};
-}
-
-/**
- * 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_0
-}  // namespace wifi
-}  // namespace supplicant
-}  // namespace hardware
-}  // namespace android
diff --git a/wpa_supplicant/hidl/1.0/p2p_iface.h b/wpa_supplicant/hidl/1.0/p2p_iface.h
deleted file mode 100644
index 4f4a79d..0000000
--- a/wpa_supplicant/hidl/1.0/p2p_iface.h
+++ /dev/null
@@ -1,314 +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.0/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"
-}
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_0 {
-namespace implementation {
-
-/**
- * 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 android::hardware::wifi::supplicant::V1_0::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;
-
-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();
-
-	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_0
-}  // namespace wifi
-}  // namespace supplicant
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WPA_SUPPLICANT_HIDL_P2P_IFACE_H
diff --git a/wpa_supplicant/hidl/1.0/p2p_network.cpp b/wpa_supplicant/hidl/1.0/p2p_network.cpp
deleted file mode 100644
index 7daa453..0000000
--- a/wpa_supplicant/hidl/1.0/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_0 {
-namespace implementation {
-using hidl_return_util::validateAndCall;
-
-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 == wpa_ssid::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_0
-}  // namespace wifi
-}  // namespace supplicant
-}  // namespace hardware
-}  // namespace android
diff --git a/wpa_supplicant/hidl/1.0/p2p_network.h b/wpa_supplicant/hidl/1.0/p2p_network.h
deleted file mode 100644
index 6164f43..0000000
--- a/wpa_supplicant/hidl/1.0/p2p_network.h
+++ /dev/null
@@ -1,102 +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_0 {
-namespace implementation {
-
-/**
- * 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_0
-}  // namespace wifi
-}  // namespace supplicant
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WPA_SUPPLICANT_HIDL_P2P_NETWORK_H
diff --git a/wpa_supplicant/hidl/1.0/sta_iface.cpp b/wpa_supplicant/hidl/1.0/sta_iface.cpp
deleted file mode 100644
index 8498e69..0000000
--- a/wpa_supplicant/hidl/1.0/sta_iface.cpp
+++ /dev/null
@@ -1,1020 +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"
-}
-
-namespace {
-using android::hardware::wifi::supplicant::V1_0::ISupplicantStaIface;
-using android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
-using android::hardware::wifi::supplicant::V1_0::SupplicantStatusCode;
-using android::hardware::wifi::supplicant::V1_0::implementation::HidlManager;
-
-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);
-}
-
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_0 {
-namespace implementation {
-using hidl_return_util::validateAndCall;
-
-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::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::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<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::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);
-}
-
-std::pair<SupplicantStatus, std::string> StaIface::getNameInternal()
-{
-	return {{SupplicantStatusCode::SUCCESS, ""}, ifname_};
-}
-
-std::pair<SupplicantStatus, IfaceType> StaIface::getTypeInternal()
-{
-	return {{SupplicantStatusCode::SUCCESS, ""}, IfaceType::STA};
-}
-
-std::pair<SupplicantStatus, sp<ISupplicantNetwork>>
-StaIface::addNetworkInternal()
-{
-	android::sp<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};
-}
-
-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<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)
-{
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager ||
-	    hidl_manager->addStaIfaceCallbackHidlObject(ifname_, callback)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {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(), info_elems_buf, num_info_elems,
-		sub_types_bitmask, false)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {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)) {
-		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, ""};
-}
-
-/**
- * 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_0
-}  // namespace wifi
-}  // namespace supplicant
-}  // namespace hardware
-}  // namespace android
diff --git a/wpa_supplicant/hidl/1.0/sta_iface.h b/wpa_supplicant/hidl/1.0/sta_iface.h
deleted file mode 100644
index 6e62260..0000000
--- a/wpa_supplicant/hidl/1.0/sta_iface.h
+++ /dev/null
@@ -1,249 +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.0/ISupplicantStaIface.h>
-#include <android/hardware/wifi/supplicant/1.0/ISupplicantStaIfaceCallback.h>
-#include <android/hardware/wifi/supplicant/1.0/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_0 {
-namespace implementation {
-
-/**
- * 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 android::hardware::wifi::supplicant::V1_0::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> getNetwork(
-	    SupplicantNetworkId id, getNetwork_cb _hidl_cb) override;
-	Return<void> listNetworks(listNetworks_cb _hidl_cb) override;
-	Return<void> registerCallback(
-	    const sp<ISupplicantStaIfaceCallback>& callback,
-	    registerCallback_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<ISupplicantStaIface::AnqpInfoId>& info_elements,
-	    const hidl_vec<ISupplicantStaIface::Hs20AnqpSubtypes>& sub_types,
-	    initiateAnqpQuery_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;
-
-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 removeNetworkInternal(SupplicantNetworkId id);
-	std::pair<SupplicantStatus, sp<ISupplicantNetwork>> getNetworkInternal(
-	    SupplicantNetworkId id);
-	std::pair<SupplicantStatus, std::vector<SupplicantNetworkId>>
-	listNetworksInternal();
-	SupplicantStatus registerCallbackInternal(
-	    const sp<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);
-	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);
-
-	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_0
-}  // namespace wifi
-}  // namespace supplicant
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WPA_SUPPLICANT_HIDL_STA_IFACE_H
diff --git a/wpa_supplicant/hidl/1.0/sta_network.cpp b/wpa_supplicant/hidl/1.0/sta_network.cpp
deleted file mode 100644
index f471941..0000000
--- a/wpa_supplicant/hidl/1.0/sta_network.cpp
+++ /dev/null
@@ -1,1825 +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::ISupplicantStaNetwork;
-using android::hardware::wifi::supplicant::V1_0::SupplicantStatus;
-
-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));
-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));
-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));
-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));
-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));
-
-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";
-}  // namespace
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_0 {
-namespace implementation {
-using hidl_return_util::validateAndCall;
-
-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::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::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::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::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::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);
-}
-
-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)
-{
-	HidlManager *hidl_manager = HidlManager::getInstance();
-	if (!hidl_manager ||
-	    hidl_manager->addStaNetworkCallbackHidlObject(
-		ifname_, network_id_, callback)) {
-		return {SupplicantStatusCode::FAILURE_UNKNOWN, ""};
-	}
-	return {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)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (key_mgmt_mask & ~kAllowedKeyMgmtMask) {
-		return {SupplicantStatusCode::FAILURE_ARGS_INVALID, ""};
-	}
-	wpa_ssid->key_mgmt = key_mgmt_mask;
-	wpa_printf(MSG_MSGDUMP, "key_mgmt: 0x%x", wpa_ssid->key_mgmt);
-	resetInternalStateAfterParamsUpdate();
-	return {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setProtoInternal(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, ""};
-}
-
-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, ""};
-}
-
-SupplicantStatus StaNetwork::setGroupCipherInternal(uint32_t group_cipher_mask)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (group_cipher_mask & ~kAllowedGroupCipherMask) {
-		return {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 {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setPairwiseCipherInternal(
-    uint32_t pairwise_cipher_mask)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (pairwise_cipher_mask & ~kAllowedPairwisewCipherMask) {
-		return {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 {SupplicantStatusCode::SUCCESS, ""};
-}
-
-SupplicantStatus StaNetwork::setPskPassphraseInternal(const std::string &psk)
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	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();
-	wpa_ssid->ieee80211w =
-	    enable ? MGMT_FRAME_PROTECTION_REQUIRED : NO_MGMT_FRAME_PROTECTION;
-	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, ""};
-	}
-	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.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.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.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.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.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.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.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.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.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, ""};
-}
-
-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()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		wpa_ssid->key_mgmt & kAllowedKeyMgmtMask};
-}
-
-std::pair<SupplicantStatus, uint32_t> StaNetwork::getProtoInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		wpa_ssid->proto & kAllowedProtoMask};
-}
-
-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()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		wpa_ssid->group_cipher & kAllowedGroupCipherMask};
-}
-
-std::pair<SupplicantStatus, uint32_t> StaNetwork::getPairwiseCipherInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		wpa_ssid->pairwise_cipher & kAllowedPairwisewCipherMask};
-}
-
-std::pair<SupplicantStatus, std::string> StaNetwork::getPskPassphraseInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	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::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<EapType>(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.ca_cert) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		reinterpret_cast<char *>(wpa_ssid->eap.ca_cert)};
-}
-
-std::pair<SupplicantStatus, std::string> StaNetwork::getEapCAPathInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->eap.ca_path) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		reinterpret_cast<char *>(wpa_ssid->eap.ca_path)};
-}
-
-std::pair<SupplicantStatus, std::string> StaNetwork::getEapClientCertInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->eap.client_cert) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		reinterpret_cast<char *>(wpa_ssid->eap.client_cert)};
-}
-
-std::pair<SupplicantStatus, std::string>
-StaNetwork::getEapPrivateKeyIdInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->eap.key_id) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, wpa_ssid->eap.key_id};
-}
-
-std::pair<SupplicantStatus, std::string>
-StaNetwork::getEapSubjectMatchInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->eap.subject_match) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		reinterpret_cast<char *>(wpa_ssid->eap.subject_match)};
-}
-
-std::pair<SupplicantStatus, std::string>
-StaNetwork::getEapAltSubjectMatchInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->eap.altsubject_match) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		reinterpret_cast<char *>(wpa_ssid->eap.altsubject_match)};
-}
-
-std::pair<SupplicantStatus, bool> StaNetwork::getEapEngineInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	return {{SupplicantStatusCode::SUCCESS, ""}, wpa_ssid->eap.engine == 1};
-}
-
-std::pair<SupplicantStatus, std::string> StaNetwork::getEapEngineIDInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->eap.engine_id) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""}, {wpa_ssid->eap.engine_id}};
-}
-
-std::pair<SupplicantStatus, std::string>
-StaNetwork::getEapDomainSuffixMatchInternal()
-{
-	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
-	if (!wpa_ssid->eap.domain_suffix_match) {
-		return {{SupplicantStatusCode::FAILURE_UNKNOWN, ""}, {}};
-	}
-	return {{SupplicantStatusCode::SUCCESS, ""},
-		{wpa_ssid->eap.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<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())};
-}
-
-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.data(),
-                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.data(),
-                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.data(),
-                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.data(),
-                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, ""};
-}
-
-/**
- * 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;
-}
-
-}  // namespace implementation
-}  // namespace V1_0
-}  // namespace wifi
-}  // namespace supplicant
-}  // namespace hardware
-}  // namespace android
diff --git a/wpa_supplicant/hidl/1.0/sta_network.h b/wpa_supplicant/hidl/1.0/sta_network.h
deleted file mode 100644
index 6e8d42b..0000000
--- a/wpa_supplicant/hidl/1.0/sta_network.h
+++ /dev/null
@@ -1,331 +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.0/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_0 {
-namespace implementation {
-
-/**
- * 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 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> 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> 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> 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> 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> 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;
-
-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);
-	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 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);
-	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::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();
-	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);
-
-	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);
-
-	// 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_0
-}  // namespace wifi
-}  // namespace supplicant
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WPA_SUPPLICANT_HIDL_STA_NETWORK_H
diff --git a/wpa_supplicant/hidl/1.0/supplicant.cpp b/wpa_supplicant/hidl/1.0/supplicant.cpp
deleted file mode 100644
index bf009b5..0000000
--- a/wpa_supplicant/hidl/1.0/supplicant.cpp
+++ /dev/null
@@ -1,309 +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 <android-base/file.h>
-#include <fcntl.h>
-#include <sys/stat.h>
-
-namespace {
-constexpr char kStaIfaceConfPath[] =
-    "/data/misc/wifi/wpa_supplicant.conf";
-constexpr char kP2pIfaceConfPath[] =
-    "/data/misc/wifi/p2p_supplicant.conf";
-// Migrate conf files for existing devices.
-constexpr char kTemplateConfPath[] =
-    "/vendor/etc/wifi/wpa_supplicant.conf";
-constexpr mode_t kConfigFileMode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP;
-
-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 exists,
- * 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);
-	if ((ret != 0) && (errno == ENOENT)) {
-		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 exists, copy over the contents of
- * |template_config_file_path|.
- */
-int copyTemplateConfigFileIfNotExists(
-    const std::string& config_file_path,
-    const std::string& template_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(template_config_file_path, config_file_path);
-	if (ret == 0) {
-		wpa_printf(
-		    MSG_INFO, "Copied template conf file from %s to %s",
-		    template_config_file_path.c_str(), 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_0 {
-namespace implementation {
-using hidl_return_util::validateAndCall;
-
-// These are hardcoded for android.
-const char Supplicant::kDriverName[] = "nl80211";
-const char Supplicant::kConfigFilePath[] =
-    "/data/misc/wifi/wpa_supplicant.conf";
-
-Supplicant::Supplicant(struct wpa_global* global) : wpa_global_(global) {}
-bool Supplicant::isValid()
-{
-	// This top level object cannot be invalidated.
-	return true;
-}
-
-bool Supplicant::ensureConfigFileExists()
-{
-	// To support Android P Wifi framework, make sure the config file exists.
-	if (copyTemplateConfigFileIfNotExists(
-		kStaIfaceConfPath, kTemplateConfPath) != 0) {
-		wpa_printf(MSG_ERROR, "Conf file does not exists: %s",
-		    kStaIfaceConfPath);
-		return false;
-	}
-	// P2P configuration file is not madatory but required for some devices.
-	if (copyTemplateConfigFileIfNotExists(
-		kP2pIfaceConfPath, kTemplateConfPath) != 0) {
-		wpa_printf(MSG_INFO, "Conf file does not exists: %s",
-		    kP2pIfaceConfPath);
-	}
-	return true;
-}
-
-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);
-}
-
-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<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_0
-}  // namespace wifi
-}  // namespace supplicant
-}  // namespace hardware
-}  // namespace android
diff --git a/wpa_supplicant/hidl/1.0/supplicant.h b/wpa_supplicant/hidl/1.0/supplicant.h
deleted file mode 100644
index 04d1ae1..0000000
--- a/wpa_supplicant/hidl/1.0/supplicant.h
+++ /dev/null
@@ -1,90 +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-base/macros.h>
-
-#include <android/hardware/wifi/supplicant/1.0/ISupplicant.h>
-#include <android/hardware/wifi/supplicant/1.0/ISupplicantCallback.h>
-#include <android/hardware/wifi/supplicant/1.0/ISupplicantIface.h>
-
-extern "C" {
-#include "utils/common.h"
-#include "utils/includes.h"
-#include "utils/wpa_debug.h"
-#include "wpa_supplicant_i.h"
-}
-
-namespace android {
-namespace hardware {
-namespace wifi {
-namespace supplicant {
-namespace V1_0 {
-namespace implementation {
-/**
- * Implementation of the supplicant hidl object. This hidl
- * object is used core for global control operations on
- * wpa_supplicant.
- */
-class Supplicant : public android::hardware::wifi::supplicant::V1_0::ISupplicant
-{
-public:
-	Supplicant(struct wpa_global* global);
-	~Supplicant() override = default;
-	bool isValid();
-	bool ensureConfigFileExists();
-
-	// Hidl methods exposed.
-	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;
-
-private:
-	// Corresponding worker functions for the HIDL methods.
-	std::pair<SupplicantStatus, sp<ISupplicantIface>> getInterfaceInternal(
-	    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);
-
-	// 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_0
-}  // namespace wifi
-}  // namespace supplicant
-}  // namespace hardware
-}  // namespace android
-
-#endif  // WPA_SUPPLICANT_HIDL_SUPPLICANT_H
