Merge changes Id19f1bcf,Iff20fb3c,I435f9154,I604f8add,I8bfb9c38, ...

* changes:
  wpa_supplicant: Turn off HIDL interface
  wpa_supplicant: HIDL implementation (2/2)
  wpa_supplicant: HIDL implementation (1/2)
  binder: Add/Implement More iface calls
  binder: Add network request/response interface
  Refactor |wpa_supplicant_ctrl_iface_ctrl_rsp_handle|
  binder: Change clang-format style to Google
  binder: Implement Set enterprise network params
  binder: INetwork enterprise Set params interface
  binder: Implement iface methods
  Move disconnect command handling to a common place
  binder: Reset internal states after network params update
  binder: Corrected couple of nits in private branch.
  binder: Implement |OnStateChanged| callback
  binder: Implement Set/Get network params (Part 3)
  binder: Implement Set/Get network params (Part 2)
  binder: Implement Set/Get network params (Part 1)
  binder: Implement enable/disable/select network
  binder: INetwork Set/Get params interface
  binder: Add network removal notification
  binder: Add iface/network addition/removal callbacks
  binder: Implement the callback addition/removal
  binder: Callback registration for interfaces
  binder: Turn on the compile flag for binder
  binder: Add parcelable for iface params
  binder: Set/Get debug params
  Move network add/remove operations to a common function
  binder: Implement network addition/removal
  binder: Use ifname as key in BinderManager |IIface| map
  binder: Add |INetwork| object interface
  binder: Move public headers to a separate folder
  binder: Notify iface add/remove to binder
  binder: Clang format the source code
  binder: Expose an aidl interface module
diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk
index 02987d1..e52ff14 100644
--- a/wpa_supplicant/Android.mk
+++ b/wpa_supplicant/Android.mk
@@ -49,7 +49,7 @@
 L_CFLAGS += -mabi=aapcs-linux
 endif
 
-# C++ flags for binder interface
+# C++ flags for hidl interface
 L_CPPFLAGS := -std=c++11 -Wall -Werror
 # TODO: Remove these allowed warnings later.
 L_CPPFLAGS += -Wno-unused-variable -Wno-unused-parameter
@@ -1355,9 +1355,9 @@
 OBJS += $(DBUS_OBJS)
 L_CFLAGS += $(DBUS_CFLAGS)
 
-ifdef CONFIG_CTRL_IFACE_BINDER
-WPA_SUPPLICANT_USE_BINDER=y
-L_CFLAGS += -DCONFIG_BINDER -DCONFIG_CTRL_IFACE_BINDER
+ifdef CONFIG_CTRL_IFACE_HIDL
+WPA_SUPPLICANT_USE_HIDL=y
+L_CFLAGS += -DCONFIG_HIDL -DCONFIG_CTRL_IFACE_HIDL
 endif
 
 ifdef CONFIG_READLINE
@@ -1597,9 +1597,10 @@
 ifeq ($(DBUS), y)
 LOCAL_SHARED_LIBRARIES += libdbus
 endif
-ifeq ($(WPA_SUPPLICANT_USE_BINDER), y)
-LOCAL_SHARED_LIBRARIES += libbinder libutils
-LOCAL_STATIC_LIBRARIES += libwpa_binder libwpa_binder_interface
+ifeq ($(WPA_SUPPLICANT_USE_HIDL), y)
+LOCAL_SHARED_LIBRARIES += android.hardware.wifi.supplicant@1.0
+LOCAL_SHARED_LIBRARIES += libhidl libhwbinder libutils
+LOCAL_STATIC_LIBRARIES += libwpa_hidl
 endif
 include $(BUILD_EXECUTABLE)
 
@@ -1641,41 +1642,24 @@
 LOCAL_EXPORT_C_INCLUDE_DIRS := $(LOCAL_PATH)/wpa_client_include
 include $(BUILD_SHARED_LIBRARY)
 
-ifeq ($(WPA_SUPPLICANT_USE_BINDER), y)
-### Binder interface library ###
+ifeq ($(WPA_SUPPLICANT_USE_HIDL), y)
+### Hidl service library ###
 ########################
-
 include $(CLEAR_VARS)
-LOCAL_MODULE := libwpa_binder_interface
-LOCAL_AIDL_INCLUDES := \
-    $(LOCAL_PATH)/binder \
-    frameworks/native/aidl/binder
-LOCAL_EXPORT_C_INCLUDE_DIRS := \
-    $(LOCAL_PATH)/binder
-LOCAL_CPPFLAGS := $(L_CPPFLAGS)
-LOCAL_SRC_FILES := \
-    binder/binder_constants.cpp \
-    binder/fi/w1/wpa_supplicant/ISupplicant.aidl \
-    binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl \
-    binder/fi/w1/wpa_supplicant/IIface.aidl
-LOCAL_SHARED_LIBRARIES := libbinder
-include $(BUILD_STATIC_LIBRARY)
-
-### Binder service library ###
-########################
-
-include $(CLEAR_VARS)
-LOCAL_MODULE := libwpa_binder
+LOCAL_MODULE := libwpa_hidl
 LOCAL_CPPFLAGS := $(L_CPPFLAGS)
 LOCAL_CFLAGS := $(L_CFLAGS)
 LOCAL_C_INCLUDES := $(INCLUDES)
 LOCAL_SRC_FILES := \
-    binder/binder.cpp binder/binder_manager.cpp \
-    binder/supplicant.cpp binder/iface.cpp
+    hidl/hidl.cpp \
+    hidl/hidl_manager.cpp \
+    hidl/iface.cpp \
+    hidl/network.cpp \
+    hidl/supplicant.cpp
 LOCAL_SHARED_LIBRARIES := \
-    libbinder \
+    android.hardware.wifi.supplicant@1.0 \
+    libhidl \
+    libhwbinder \
     libutils
-LOCAL_STATIC_LIBRARIES := libwpa_binder_interface
 include $(BUILD_STATIC_LIBRARY)
-
-endif # BINDER == y
+endif # WPA_SUPPLICANT_USE_HIDL == y
diff --git a/wpa_supplicant/android.config b/wpa_supplicant/android.config
index 02505bb..84044fc 100644
--- a/wpa_supplicant/android.config
+++ b/wpa_supplicant/android.config
@@ -324,9 +324,9 @@
 # Add introspection support for new DBus control interface
 #CONFIG_CTRL_IFACE_DBUS_INTRO=y
 
-# Add support for Binder control interface
+# Add support for Hidl control interface
 # Only applicable for Android platforms.
-#CONFIG_CTRL_IFACE_BINDER=y
+# CONFIG_CTRL_IFACE_HIDL=y
 
 # Add support for loading EAP methods dynamically as shared libraries.
 # When this option is enabled, each EAP method can be either included
diff --git a/wpa_supplicant/binder/binder.cpp b/wpa_supplicant/binder/binder.cpp
deleted file mode 100644
index 750e878..0000000
--- a/wpa_supplicant/binder/binder.cpp
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * binder 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 <binder/IPCThreadState.h>
-#include <binder/IServiceManager.h>
-#include <binder/ProcessState.h>
-
-#include "binder_manager.h"
-
-extern "C" {
-#include "binder.h"
-#include "binder_i.h"
-#include "utils/common.h"
-#include "utils/eloop.h"
-#include "utils/includes.h"
-}
-
-void wpas_binder_sock_handler(int sock, void *eloop_ctx, void *sock_ctx)
-{
-	struct wpa_global *global = (wpa_global *)eloop_ctx;
-	struct wpas_binder_priv *priv = (wpas_binder_priv *)sock_ctx;
-
-	wpa_printf(
-	    MSG_DEBUG, "Processing binder events on FD %d", priv->binder_fd);
-	android::IPCThreadState::self()->handlePolledCommands();
-}
-
-struct wpas_binder_priv *wpas_binder_init(struct wpa_global *global)
-{
-	struct wpas_binder_priv *priv;
-	wpa_supplicant_binder::BinderManager *binder_manager;
-
-	priv = (wpas_binder_priv *)os_zalloc(sizeof(*priv));
-	if (!priv)
-		return NULL;
-	priv->global = global;
-
-	android::ProcessState::self()->setThreadPoolMaxThreadCount(0);
-	android::IPCThreadState::self()->disableBackgroundScheduling(true);
-	android::IPCThreadState::self()->setupPolling(&priv->binder_fd);
-	wpa_printf(MSG_INFO, "Process binder events on FD %d", priv->binder_fd);
-	if (priv->binder_fd < 0)
-		goto err;
-	/* Look for read events from the binder socket in the eloop. */
-	if (eloop_register_read_sock(
-		priv->binder_fd, wpas_binder_sock_handler, global, priv) < 0)
-		goto err;
-
-	binder_manager = wpa_supplicant_binder::BinderManager::getInstance();
-	if (!binder_manager)
-		goto err;
-	binder_manager->registerBinderService(global);
-	/* We may not need to store this binder manager reference in the
-	 * global data strucure because we've made it a singleton class. */
-	priv->binder_manager = (void *)binder_manager;
-
-	return priv;
-
-err:
-	wpas_binder_deinit(priv);
-	return NULL;
-}
-
-void wpas_binder_deinit(struct wpas_binder_priv *priv)
-{
-	if (!priv)
-		return;
-
-	wpa_supplicant_binder::BinderManager::destroyInstance();
-	eloop_unregister_read_sock(priv->binder_fd);
-	android::IPCThreadState::shutdown();
-}
-
-int wpas_binder_register_interface(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s->global->binder)
-		return 1;
-
-	wpa_supplicant_binder::BinderManager *binder_manager =
-	    wpa_supplicant_binder::BinderManager::getInstance();
-	if (!binder_manager)
-		return 1;
-
-	return binder_manager->registerInterface(wpa_s);
-}
-
-int wpas_binder_unregister_interface(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s->global->binder)
-		return 1;
-
-	wpa_supplicant_binder::BinderManager *binder_manager =
-	    wpa_supplicant_binder::BinderManager::getInstance();
-	if (!binder_manager)
-		return 1;
-
-	return binder_manager->unregisterInterface(wpa_s);
-}
diff --git a/wpa_supplicant/binder/binder.h b/wpa_supplicant/binder/binder.h
deleted file mode 100644
index 019e327..0000000
--- a/wpa_supplicant/binder/binder.h
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * binder 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_BINDER_BINDER_H
-#define WPA_SUPPLICANT_BINDER_BINDER_H
-
-#ifdef _cplusplus
-extern "C" {
-#endif /* _cplusplus */
-
-/**
- * This is the binder RPC interface entry point to the wpa_supplicant core.
- * This initializes the binder driver & BinderManager instance and then forwards
- * all the notifcations from the supplicant core to the BinderManager.
- */
-struct wpas_binder_priv;
-struct wpa_global;
-
-struct wpas_binder_priv *wpas_binder_init(struct wpa_global *global);
-void wpas_binder_deinit(struct wpas_binder_priv *priv);
-
-#ifdef CONFIG_CTRL_IFACE_BINDER
-int wpas_binder_register_interface(struct wpa_supplicant *wpa_s);
-int wpas_binder_unregister_interface(struct wpa_supplicant *wpa_s);
-#else  /* CONFIG_CTRL_IFACE_BINDER */
-static inline int wpas_binder_register_interface(struct wpa_supplicant *wpa_s)
-{
-	return 0;
-}
-static inline int wpas_binder_unregister_interface(struct wpa_supplicant *wpa_s)
-{
-	return 0;
-}
-#endif /* CONFIG_CTRL_IFACE_BINDER */
-
-#ifdef _cplusplus
-}
-#endif /* _cplusplus */
-
-#endif /* WPA_SUPPLICANT_BINDER_BINDER_H */
diff --git a/wpa_supplicant/binder/binder_constants.cpp b/wpa_supplicant/binder/binder_constants.cpp
deleted file mode 100644
index 0d452b1..0000000
--- a/wpa_supplicant/binder/binder_constants.cpp
+++ /dev/null
@@ -1,18 +0,0 @@
-/*
- * binder 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 "binder_constants.h"
-
-namespace wpa_supplicant_binder {
-namespace binder_constants {
-
-const char kServiceName[] = "wpa_supplicant";
-
-} /* namespace binder_constants */
-} /* namespace wpa_supplicant_binder */
diff --git a/wpa_supplicant/binder/binder_constants.h b/wpa_supplicant/binder/binder_constants.h
deleted file mode 100644
index a4d9b55..0000000
--- a/wpa_supplicant/binder/binder_constants.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- * binder 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_BINDER_BINDER_CONSTANTS_H
-#define WPA_SUPPLICANT_BINDER_BINDER_CONSTANTS_H
-
-namespace wpa_supplicant_binder {
-namespace binder_constants {
-
-extern const char kServiceName[];
-
-} /* namespace binder_constants */
-} /* namespace wpa_supplicant_binder */
-
-#endif /* WPA_SUPPLICANT_BINDER_BINDER_CONSTANTS_H */
diff --git a/wpa_supplicant/binder/binder_i.h b/wpa_supplicant/binder/binder_i.h
deleted file mode 100644
index 5140d6d..0000000
--- a/wpa_supplicant/binder/binder_i.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * binder 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 BINDER_I_H
-#define BINDER_I_H
-
-#ifdef _cplusplus
-extern "C" {
-#endif // _cplusplus
-
-struct wpas_binder_priv
-{
-	int binder_fd;
-	struct wpa_global *global;
-	void *binder_manager;
-};
-
-#ifdef _cplusplus
-}
-#endif /* _cplusplus */
-
-#endif /* BINDER_I_H */
diff --git a/wpa_supplicant/binder/binder_manager.cpp b/wpa_supplicant/binder/binder_manager.cpp
deleted file mode 100644
index 27e8ded..0000000
--- a/wpa_supplicant/binder/binder_manager.cpp
+++ /dev/null
@@ -1,100 +0,0 @@
-/*
- * binder 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 <binder/IServiceManager.h>
-
-#include "binder_constants.h"
-#include "binder_manager.h"
-
-extern "C" {
-#include "utils/common.h"
-#include "utils/includes.h"
-}
-
-namespace wpa_supplicant_binder {
-
-BinderManager *BinderManager::instance_ = NULL;
-
-BinderManager *BinderManager::getInstance()
-{
-	if (!instance_)
-		instance_ = new BinderManager();
-	return instance_;
-}
-
-void BinderManager::destroyInstance()
-{
-	if (instance_)
-		delete instance_;
-	instance_ = NULL;
-}
-
-int BinderManager::registerBinderService(struct wpa_global *global)
-{
-	/* Create the main binder service object and register with
-	 * system service manager. */
-	supplicant_object_ = new Supplicant(global);
-	android::String16 service_name(binder_constants::kServiceName);
-	android::defaultServiceManager()->addService(
-	    service_name, android::IInterface::asBinder(supplicant_object_));
-	return 0;
-}
-
-int BinderManager::registerInterface(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s)
-		return 1;
-
-	/* Using the corresponding wpa_supplicant pointer as key to our
-	 * object map. */
-	const void *iface_key = wpa_s;
-
-	/* Return failure if we already have an object for that iface_key. */
-	if (iface_object_map_.find(iface_key) != iface_object_map_.end())
-		return 1;
-
-	iface_object_map_[iface_key] = new Iface(wpa_s);
-	if (!iface_object_map_[iface_key].get())
-		return 1;
-
-	wpa_s->binder_object_key = iface_key;
-
-	return 0;
-}
-
-int BinderManager::unregisterInterface(struct wpa_supplicant *wpa_s)
-{
-	if (!wpa_s || !wpa_s->binder_object_key)
-		return 1;
-
-	const void *iface_key = wpa_s;
-	if (iface_object_map_.find(iface_key) == iface_object_map_.end())
-		return 1;
-
-	/* Delete the corresponding iface object from our map. */
-	iface_object_map_.erase(iface_key);
-	wpa_s->binder_object_key = NULL;
-	return 0;
-}
-
-int BinderManager::getIfaceBinderObjectByKey(
-    const void *iface_object_key,
-    android::sp<fi::w1::wpa_supplicant::IIface> *iface_object)
-{
-	if (!iface_object_key || !iface_object)
-		return 1;
-
-	if (iface_object_map_.find(iface_object_key) == iface_object_map_.end())
-		return 1;
-
-	*iface_object = iface_object_map_[iface_object_key];
-	return 0;
-}
-
-} /* namespace wpa_supplicant_binder */
diff --git a/wpa_supplicant/binder/binder_manager.h b/wpa_supplicant/binder/binder_manager.h
deleted file mode 100644
index d8b7dd0..0000000
--- a/wpa_supplicant/binder/binder_manager.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * binder 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_BINDER_BINDER_MANAGER_H
-#define WPA_SUPPLICANT_BINDER_BINDER_MANAGER_H
-
-#include <map>
-#include <string>
-
-#include "iface.h"
-#include "supplicant.h"
-
-struct wpa_global;
-struct wpa_supplicant;
-
-namespace wpa_supplicant_binder {
-
-/**
- * BinderManager is responsible for managing the lifetime of all
- * binder 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 binder objects.
- */
-class BinderManager
-{
-public:
-	static BinderManager *getInstance();
-	static void destroyInstance();
-	int registerBinderService(struct wpa_global *global);
-	int registerInterface(struct wpa_supplicant *wpa_s);
-	int unregisterInterface(struct wpa_supplicant *wpa_s);
-	int getIfaceBinderObjectByKey(
-	    const void *iface_object_key,
-	    android::sp<fi::w1::wpa_supplicant::IIface> *iface_object);
-
-private:
-	BinderManager() = default;
-	~BinderManager() = default;
-
-	/* Singleton instance of this class. */
-	static BinderManager *instance_;
-	/* The main binder service object. */
-	android::sp<Supplicant> supplicant_object_;
-	/* Map of all the interface specific binder objects controlled by
-	 * wpa_supplicant. This map is keyed in by the corresponding
-	 * wpa_supplicant structure pointer. */
-	std::map<const void *, android::sp<Iface>> iface_object_map_;
-};
-
-} /* namespace wpa_supplicant_binder */
-
-#endif /* WPA_SUPPLICANT_BINDER_BINDER_MANAGER_H */
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl
deleted file mode 100644
index ea11d42..0000000
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * binder 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.
- */
-
-package fi.w1.wpa_supplicant;
-
-/**
- * Interface exposed by wpa_supplicant for each network interface it controls.
- */
-interface IIface {
-}
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl
deleted file mode 100644
index 1cbee20..0000000
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl
+++ /dev/null
@@ -1,59 +0,0 @@
-/*
- * WPA Supplicant - binder 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.
- */
-
-package fi.w1.wpa_supplicant;
-
-import android.os.PersistableBundle;
-import fi.w1.wpa_supplicant.IIface;
-
-/**
- * Interface exposed by the wpa_supplicant binder service registered
- * with the service manager with name: fi.w1.wpa_supplicant.
- */
-interface ISupplicant {
-	/* Error values returned by the service to RPC method calls. */
-	const int ERROR_INVALID_ARGS = 1;
-	const int ERROR_UNKNOWN = 2;
-	const int ERROR_IFACE_EXISTS = 3;
-	const int ERROR_IFACE_UNKNOWN = 4;
-
-	/**
-	 * Registers a wireless interface in wpa_supplicant.
-	 *
-	 * @param args A dictionary with arguments used to add the interface to
-	 *             wpa_supplicant.
-	 * The dictionary may contain the following entries:
-	 *   Ifname(String) Name of the network interface to control, e.g.,
-	 *   wlan0.
-	 *   BridgeIfname(String) Name of the bridge interface to control, e.g.,
-	 *   br0.
-	 *   Driver(String) Driver name which the interface uses, e.g., nl80211.
-	 *   ConfigFile(String) Configuration file path.
-	 *
-	 * @return Binder object representing the interface.
-	 */
-	IIface CreateInterface(in PersistableBundle args);
-
-	/**
-	 * Deregisters a wireless interface from wpa_supplicant.
-	 *
-	 * @param ifname Name of the network interface, e.g., wlan0
-	 */
-	void RemoveInterface(in @utf8InCpp String ifname);
-
-	/**
-	 * Gets a binder object for the interface corresponding to ifname
-	 * which wpa_supplicant already controls.
-	 *
-	 * @param ifname Name of the network interface, e.g., wlan0
-	 *
-	 * @return Binder object representing the interface.
-	 */
-	IIface GetInterface(in @utf8InCpp String ifname);
-}
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl
deleted file mode 100644
index d624d91..0000000
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl
+++ /dev/null
@@ -1,20 +0,0 @@
-/*
- * binder 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.
- */
-
-package fi.w1.wpa_supplicant;
-
-import android.os.PersistableBundle;
-
-/**
- * Callback Interface exposed by the wpa_supplicant service. Clients need
- * to host an instance of this binder object and pass a reference of the object
- * to wpa_supplicant via the registerCallbacksObject method.
- */
-interface ISupplicantCallbacks {
-}
diff --git a/wpa_supplicant/binder/iface.cpp b/wpa_supplicant/binder/iface.cpp
deleted file mode 100644
index c61b3b0..0000000
--- a/wpa_supplicant/binder/iface.cpp
+++ /dev/null
@@ -1,16 +0,0 @@
-/*
- * binder 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 "iface.h"
-
-namespace wpa_supplicant_binder {
-
-Iface::Iface(struct wpa_supplicant *wpa_s) : wpa_s_(wpa_s) {}
-
-} /* namespace wpa_supplicant_binder */
diff --git a/wpa_supplicant/binder/iface.h b/wpa_supplicant/binder/iface.h
deleted file mode 100644
index c0ee12c..0000000
--- a/wpa_supplicant/binder/iface.h
+++ /dev/null
@@ -1,42 +0,0 @@
-/*
- * binder 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_BINDER_IFACE_H
-#define WPA_SUPPLICANT_BINDER_IFACE_H
-
-#include "fi/w1/wpa_supplicant/BnIface.h"
-
-extern "C" {
-#include "utils/common.h"
-#include "utils/includes.h"
-#include "../wpa_supplicant_i.h"
-}
-
-namespace wpa_supplicant_binder {
-
-/**
- * Implementation of Iface binder object. Each unique binder
- * object is used for control operations on a specific interface
- * controlled by wpa_supplicant.
- */
-class Iface : public fi::w1::wpa_supplicant::BnIface
-{
-public:
-	Iface(struct wpa_supplicant *wpa_s);
-	virtual ~Iface() = default;
-
-private:
-	/* Raw pointer to the structure maintained by the core for this
-	 * interface. */
-	struct wpa_supplicant *wpa_s_;
-};
-
-} /* namespace wpa_supplicant_binder */
-
-#endif /* WPA_SUPPLICANT_BINDER_IFACE_H */
diff --git a/wpa_supplicant/binder/supplicant.cpp b/wpa_supplicant/binder/supplicant.cpp
deleted file mode 100644
index 76569b1..0000000
--- a/wpa_supplicant/binder/supplicant.cpp
+++ /dev/null
@@ -1,127 +0,0 @@
-/*
- * binder 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 "supplicant.h"
-#include "binder_manager.h"
-
-namespace wpa_supplicant_binder {
-
-Supplicant::Supplicant(struct wpa_global *global) : wpa_global_(global) {}
-
-android::binder::Status Supplicant::CreateInterface(
-    const android::os::PersistableBundle &params,
-    android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return)
-{
-	android::String16 driver, ifname, confname, bridge_ifname;
-
-	/* Check if required Ifname argument is missing */
-	if (!params.getString(android::String16("Ifname"), &ifname))
-		return android::binder::Status::fromServiceSpecificError(
-		    ERROR_INVALID_ARGS,
-		    android::String8("Ifname missing in params."));
-	/* Retrieve the remaining params from the dictionary */
-	params.getString(android::String16("Driver"), &driver);
-	params.getString(android::String16("ConfigFile"), &confname);
-	params.getString(android::String16("BridgeIfname"), &bridge_ifname);
-
-	/*
-	 * Try to get the wpa_supplicant record for this iface, return
-	 * an error if we already control it.
-	 */
-	if (wpa_supplicant_get_iface(
-		wpa_global_, android::String8(ifname).string()) != NULL)
-		return android::binder::Status::fromServiceSpecificError(
-		    ERROR_IFACE_EXISTS,
-		    android::String8("wpa_supplicant already controls this "
-				     "interface."));
-
-	android::binder::Status status;
-	struct wpa_supplicant *wpa_s = NULL;
-	struct wpa_interface iface;
-
-	os_memset(&iface, 0, sizeof(iface));
-	iface.driver = os_strdup(android::String8(driver).string());
-	iface.ifname = os_strdup(android::String8(ifname).string());
-	iface.confname = os_strdup(android::String8(confname).string());
-	iface.bridge_ifname =
-	    os_strdup(android::String8(bridge_ifname).string());
-	/* Otherwise, have wpa_supplicant attach to it. */
-	wpa_s = wpa_supplicant_add_iface(wpa_global_, &iface, NULL);
-	/* The supplicant core creates a corresponding binder object via
-	 * BinderManager when |wpa_supplicant_add_iface| is called. */
-	if (!wpa_s || !wpa_s->binder_object_key) {
-		status = android::binder::Status::fromServiceSpecificError(
-		    ERROR_UNKNOWN,
-		    android::String8(
-			"wpa_supplicant couldn't grab this interface."));
-	} else {
-		BinderManager *binder_manager = BinderManager::getInstance();
-
-		if (!binder_manager ||
-		    binder_manager->getIfaceBinderObjectByKey(
-			wpa_s->binder_object_key, aidl_return))
-			status =
-			    android::binder::Status::fromServiceSpecificError(
-				ERROR_UNKNOWN,
-				android::String8("wpa_supplicant encountered a "
-						 "binder error."));
-		else
-			status = android::binder::Status::ok();
-	}
-	os_free((void *)iface.driver);
-	os_free((void *)iface.ifname);
-	os_free((void *)iface.confname);
-	os_free((void *)iface.bridge_ifname);
-	return status;
-}
-
-android::binder::Status Supplicant::RemoveInterface(const std::string &ifname)
-{
-	struct wpa_supplicant *wpa_s;
-
-	wpa_s = wpa_supplicant_get_iface(wpa_global_, ifname.c_str());
-	if (!wpa_s || !wpa_s->binder_object_key)
-		return android::binder::Status::fromServiceSpecificError(
-		    ERROR_IFACE_UNKNOWN,
-		    android::String8("wpa_supplicant does not control this "
-				     "interface."));
-	if (wpa_supplicant_remove_iface(wpa_global_, wpa_s, 0))
-		return android::binder::Status::fromServiceSpecificError(
-		    ERROR_UNKNOWN,
-		    android::String8(
-			"wpa_supplicant couldn't remove this interface."));
-	return android::binder::Status::ok();
-}
-
-android::binder::Status Supplicant::GetInterface(
-    const std::string &ifname,
-    android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return)
-{
-	struct wpa_supplicant *wpa_s;
-
-	wpa_s = wpa_supplicant_get_iface(wpa_global_, ifname.c_str());
-	if (!wpa_s || !wpa_s->binder_object_key)
-		return android::binder::Status::fromServiceSpecificError(
-		    ERROR_IFACE_UNKNOWN,
-		    android::String8(
-			"wpa_supplicant does not control this interface."));
-
-	BinderManager *binder_manager = BinderManager::getInstance();
-	if (!binder_manager ||
-	    binder_manager->getIfaceBinderObjectByKey(
-		wpa_s->binder_object_key, aidl_return))
-		return android::binder::Status::fromServiceSpecificError(
-		    ERROR_UNKNOWN,
-		    android::String8(
-			"wpa_supplicant encountered a binder error."));
-
-	return android::binder::Status::ok();
-}
-
-} /* namespace wpa_supplicant_binder */
diff --git a/wpa_supplicant/binder/supplicant.h b/wpa_supplicant/binder/supplicant.h
deleted file mode 100644
index 136b99b..0000000
--- a/wpa_supplicant/binder/supplicant.h
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * binder 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_BINDER_SUPPLICANT_H
-#define WPA_SUPPLICANT_BINDER_SUPPLICANT_H
-
-#include "fi/w1/wpa_supplicant/BnSupplicant.h"
-#include "fi/w1/wpa_supplicant/IIface.h"
-#include "fi/w1/wpa_supplicant/ISupplicantCallbacks.h"
-
-extern "C" {
-#include "utils/common.h"
-#include "utils/includes.h"
-#include "../wpa_supplicant_i.h"
-}
-
-namespace wpa_supplicant_binder {
-
-/**
- * Implementation of the supplicant binder object. This binder
- * object is used core for global control operations on
- * wpa_supplicant.
- */
-class Supplicant : public fi::w1::wpa_supplicant::BnSupplicant
-{
-public:
-	Supplicant(struct wpa_global *global);
-	virtual ~Supplicant() = default;
-
-	android::binder::Status CreateInterface(
-	    const android::os::PersistableBundle &params,
-	    android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return) override;
-	android::binder::Status
-	RemoveInterface(const std::string &ifname) override;
-	android::binder::Status GetInterface(
-	    const std::string &ifname,
-	    android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return) override;
-
-private:
-	/* Raw pointer to the global structure maintained by the core. */
-	struct wpa_global *wpa_global_;
-	/* All the callback objects registered by the clients. */
-	std::vector<android::sp<fi::w1::wpa_supplicant::ISupplicantCallbacks>>
-	    callbacks_;
-};
-
-} /* namespace wpa_supplicant_binder */
-
-#endif /* WPA_SUPPLICANT_BINDER_SUPPLICANT_H */
diff --git a/wpa_supplicant/binder/.clang-format b/wpa_supplicant/hidl/.clang-format
similarity index 90%
rename from wpa_supplicant/binder/.clang-format
rename to wpa_supplicant/hidl/.clang-format
index dbfdabf..42fadb5 100644
--- a/wpa_supplicant/binder/.clang-format
+++ b/wpa_supplicant/hidl/.clang-format
@@ -1,4 +1,4 @@
-BasedOnStyle: LLVM
+BasedOnStyle: Google
 IndentWidth: 8
 UseTab: Always
 BreakBeforeBraces: Mozilla
diff --git a/wpa_supplicant/hidl/hidl.cpp b/wpa_supplicant/hidl/hidl.cpp
new file mode 100644
index 0000000..599938d
--- /dev/null
+++ b/wpa_supplicant/hidl/hidl.cpp
@@ -0,0 +1,183 @@
+/*
+ * 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 <hwbinder/ProcessState.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::ProcessState;
+using android::hardware::IPCThreadState;
+using android::hardware::wifi::supplicant::V1_0::implementation::HidlManager;
+
+void wpas_hidl_sock_handler(
+    int /* sock */, void * /* eloop_ctx */, void *sock_ctx)
+{
+	struct wpas_hidl_priv *priv = (wpas_hidl_priv *)sock_ctx;
+	wpa_printf(MSG_DEBUG, "Processing hidl events on FD %d", priv->hidl_fd);
+	IPCThreadState::self()->handlePolledCommands();
+}
+
+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");
+
+	ProcessState::self()->setThreadPoolMaxThreadCount(0);
+	IPCThreadState::self()->disableBackgroundScheduling(true);
+	IPCThreadState::self()->setupPolling(&priv->hidl_fd);
+	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);
+	IPCThreadState::shutdown();
+	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);
+}
diff --git a/wpa_supplicant/hidl/hidl.h b/wpa_supplicant/hidl/hidl.h
new file mode 100644
index 0000000..ee7cab1
--- /dev/null
+++ b/wpa_supplicant/hidl/hidl.h
@@ -0,0 +1,74 @@
+/*
+ * 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);
+#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;
+}
+#endif  // CONFIG_CTRL_IFACE_HIDL
+
+#ifdef _cplusplus
+}
+#endif  // _cplusplus
+
+#endif  // WPA_SUPPLICANT_HIDL_HIDL_H
diff --git a/wpa_supplicant/hidl/hidl_constants.h b/wpa_supplicant/hidl/hidl_constants.h
new file mode 100644
index 0000000..988a590
--- /dev/null
+++ b/wpa_supplicant/hidl/hidl_constants.h
@@ -0,0 +1,21 @@
+/*
+ * 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/hidl_i.h b/wpa_supplicant/hidl/hidl_i.h
new file mode 100644
index 0000000..c7a0142
--- /dev/null
+++ b/wpa_supplicant/hidl/hidl_i.h
@@ -0,0 +1,28 @@
+/*
+ * 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/hidl_manager.cpp b/wpa_supplicant/hidl/hidl_manager.cpp
new file mode 100644
index 0000000..372b221
--- /dev/null
+++ b/wpa_supplicant/hidl/hidl_manager.cpp
@@ -0,0 +1,631 @@
+/*
+ * 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 "hidl_manager.h"
+
+extern "C" {
+#include "utils/common.h"
+#include "utils/includes.h"
+}
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+namespace V1_0 {
+namespace implementation {
+
+const char HidlManager::kServiceName[] = "wpa_supplicant";
+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(kServiceName) !=
+	    android::NO_ERROR) {
+		return 1;
+	}
+	return 0;
+}
+
+/**
+ * Register an interface to hidl manager.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int HidlManager::registerInterface(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return 1;
+
+	// Using the corresponding ifname as key to our object map.
+	const std::string ifname(wpa_s->ifname);
+
+	// Return failure if we already have an object for that |ifname|.
+	if (iface_object_map_.find(ifname) != iface_object_map_.end())
+		return 1;
+
+	iface_object_map_[ifname] = new Iface(wpa_s->global, wpa_s->ifname);
+	if (!iface_object_map_[ifname].get())
+		return 1;
+
+	// Initialize the vector of callbacks for this object.
+	iface_callbacks_map_[ifname] =
+	    std::vector<android::sp<ISupplicantIfaceCallback>>();
+
+	// Invoke the |onInterfaceCreated| method on all registered callbacks.
+	callWithEachSupplicantCallback(std::bind(
+	    &ISupplicantCallback::onInterfaceCreated, std::placeholders::_1,
+	    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;
+
+	const std::string ifname(wpa_s->ifname);
+
+	if (iface_object_map_.find(ifname) == iface_object_map_.end())
+		return 1;
+
+	// Delete the corresponding iface object from our map.
+	iface_object_map_.erase(ifname);
+
+	// Delete all callbacks registered for this object.
+	auto iface_callback_map_iter = iface_callbacks_map_.find(ifname);
+	if (iface_callback_map_iter == iface_callbacks_map_.end())
+		return 1;
+	const auto &iface_callback_list = iface_callback_map_iter->second;
+#if 0   // TODO(b/31632518): HIDL object death notifications.
+	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.
+	iface_callbacks_map_.erase(iface_callback_map_iter);
+
+	// Invoke the |onInterfaceRemoved| method on all registered callbacks.
+	callWithEachSupplicantCallback(std::bind(
+	    &ISupplicantCallback::onInterfaceRemoved, std::placeholders::_1,
+	    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 (network_object_map_.find(network_key) != network_object_map_.end())
+		return 1;
+
+	network_object_map_[network_key] =
+	    new Network(wpa_s->global, wpa_s->ifname, ssid->id);
+	if (!network_object_map_[network_key].get())
+		return 1;
+
+	// Initialize the vector of callbacks for this object.
+	network_callbacks_map_[network_key] =
+	    std::vector<android::sp<ISupplicantNetworkCallback>>();
+
+	// Invoke the |onNetworkAdded| method on all registered callbacks.
+	callWithEachIfaceCallback(
+	    wpa_s->ifname, std::bind(
+			       &ISupplicantIfaceCallback::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 (network_object_map_.find(network_key) == network_object_map_.end())
+		return 1;
+
+	// Delete the corresponding network object from our map.
+	network_object_map_.erase(network_key);
+
+	// Delete all callbacks registered for this object.
+	auto network_callback_map_iter =
+	    network_callbacks_map_.find(network_key);
+	if (network_callback_map_iter == network_callbacks_map_.end())
+		return 1;
+	const auto &network_callback_list = network_callback_map_iter->second;
+#if 0   // TODO(b/31632518): HIDL object death notifications.
+	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.
+	network_callbacks_map_.erase(network_callback_map_iter);
+
+	// Invoke the |onNetworkRemoved| method on all registered callbacks.
+	callWithEachIfaceCallback(
+	    wpa_s->ifname, std::bind(
+			       &ISupplicantIfaceCallback::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;
+
+	const std::string ifname(wpa_s->ifname);
+	if (iface_object_map_.find(ifname) == iface_object_map_.end())
+		return 1;
+
+	// Invoke the |onStateChanged| method on all registered callbacks.
+	ISupplicantIfaceCallback::State hidl_state =
+	    static_cast<ISupplicantIfaceCallback::State>(wpa_s->wpa_state);
+	hidl_array<uint8_t, 6> hidl_bssid;
+	os_memcpy(hidl_bssid.data(), wpa_s->bssid, ETH_ALEN);
+	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);
+	}
+	callWithEachIfaceCallback(
+	    wpa_s->ifname, std::bind(
+			       &ISupplicantIfaceCallback::onStateChanged,
+			       std::placeholders::_1, hidl_state, hidl_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 (network_object_map_.find(network_key) == network_object_map_.end())
+		return 1;
+
+	// TODO(b/31646740): Parse the param string to find the appropriate
+	// callback.
+	return 0;
+}
+
+/**
+ * Retrieve the |ISupplicantIface| 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::getIfaceHidlObjectByIfname(
+    const std::string &ifname, android::sp<ISupplicantIface> *iface_object)
+{
+	if (ifname.empty() || !iface_object)
+		return 1;
+
+	auto iface_object_iter = iface_object_map_.find(ifname);
+	if (iface_object_iter == iface_object_map_.end())
+		return 1;
+
+	*iface_object = iface_object_iter->second;
+	return 0;
+}
+
+/**
+ * Retrieve the |ISupplicantNetwork| 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::getNetworkHidlObjectByIfnameAndNetworkId(
+    const std::string &ifname, int network_id,
+    android::sp<ISupplicantNetwork> *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 = network_object_map_.find(network_key);
+	if (network_object_iter == 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 |ISupplicantIfaceCallback| hidl object reference to our
+ * interface callback list.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param callback Hidl reference of the |ISupplicantIfaceCallback| object.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int HidlManager::addIfaceCallbackHidlObject(
+    const std::string &ifname,
+    const android::sp<ISupplicantIfaceCallback> &callback)
+{
+	if (ifname.empty())
+		return 1;
+
+	auto iface_callback_map_iter = iface_callbacks_map_.find(ifname);
+	if (iface_callback_map_iter == iface_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.
+	auto on_hidl_died_fctor = std::bind(
+	    &HidlManager::removeIfaceCallbackHidlObject, this, ifname,
+	    std::placeholders::_1);
+	return registerForDeathAndAddCallbackHidlObjectToList<
+	    ISupplicantIfaceCallback>(
+	    callback, on_hidl_died_fctor, iface_callback_list);
+}
+
+/**
+ * Add a new |ISupplicantNetworkCallback| 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 |ISupplicantNetworkCallback| object.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+int HidlManager::addNetworkCallbackHidlObject(
+    const std::string &ifname, int network_id,
+    const android::sp<ISupplicantNetworkCallback> &callback)
+{
+	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 =
+	    network_callbacks_map_.find(network_key);
+	if (network_callback_map_iter == network_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.
+	auto on_hidl_died_fctor = std::bind(
+	    &HidlManager::removeNetworkCallbackHidlObject, this, ifname,
+	    network_id, std::placeholders::_1);
+	return registerForDeathAndAddCallbackHidlObjectToList<
+	    ISupplicantNetworkCallback>(
+	    callback, on_hidl_died_fctor, network_callback_list);
+}
+
+/**
+ * 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 HidlManager::getNetworkObjectMapKey(
+    const std::string &ifname, int network_id)
+{
+	return ifname + "_" + std::to_string(network_id);
+}
+
+/**
+ * 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 |ISupplicantIfaceCallback| hidl object reference from
+ * our interface callback list.
+ *
+ * @param ifname Name of the corresponding interface.
+ * @param callback Hidl reference of the |ISupplicantIfaceCallback| object.
+ */
+void HidlManager::removeIfaceCallbackHidlObject(
+    const std::string &ifname,
+    const android::sp<ISupplicantIfaceCallback> &callback)
+{
+	if (ifname.empty())
+		return;
+
+	auto iface_callback_map_iter = iface_callbacks_map_.find(ifname);
+	if (iface_callback_map_iter == iface_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());
+}
+
+/**
+ * Removes the provided |ISupplicantNetworkCallback| 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 |ISupplicantNetworkCallback| object.
+ */
+void HidlManager::removeNetworkCallbackHidlObject(
+    const std::string &ifname, int network_id,
+    const android::sp<ISupplicantNetworkCallback> &callback)
+{
+	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 =
+	    network_callbacks_map_.find(network_key);
+	if (network_callback_map_iter == network_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());
+}
+
+/**
+ * Add callback to the corresponding list after linking to death on the
+ * corresponding hidl object reference.
+ *
+ * @param callback Hidl reference of the |ISupplicantNetworkCallback| object.
+ *
+ * @return 0 on success, 1 on failure.
+ */
+template <class CallbackType>
+int HidlManager::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)
+{
+	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!
+	callback_list.push_back(callback);
+#if 0   // TODO(b/31632518): HIDL object death notifications.
+	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.
+	return 0;
+}
+
+/**
+ * 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_) {
+		method(callback);
+	}
+}
+
+/**
+ * Helper fucntion to invoke the provided callback method on all the
+ * registered |ISupplicantIfaceCallback| 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::callWithEachIfaceCallback(
+    const std::string &ifname,
+    const std::function<Return<void>(android::sp<ISupplicantIfaceCallback>)>
+	&method)
+{
+	if (ifname.empty())
+		return;
+
+	auto iface_callback_map_iter = iface_callbacks_map_.find(ifname);
+	if (iface_callback_map_iter == iface_callbacks_map_.end())
+		return;
+	const auto &iface_callback_list = iface_callback_map_iter->second;
+	for (const auto &callback : iface_callback_list) {
+		method(callback);
+	}
+}
+
+/**
+ * Helper function to invoke the provided callback method on all the
+ * registered |ISupplicantNetworkCallback| 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
+ * |ISupplicantNetworkCallback|.
+ */
+void HidlManager::callWithEachNetworkCallback(
+    const std::string &ifname, int network_id,
+    const std::function<Return<void>(android::sp<ISupplicantNetworkCallback>)>
+	&method)
+{
+	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 =
+	    network_callbacks_map_.find(network_key);
+	if (network_callback_map_iter == network_callbacks_map_.end())
+		return;
+	const auto &network_callback_list = network_callback_map_iter->second;
+	for (const auto &callback : network_callback_list) {
+		method(callback);
+	}
+}
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace wifi
+}  // namespace supplicant
+}  // namespace hardware
+}  // namespace android
diff --git a/wpa_supplicant/hidl/hidl_manager.h b/wpa_supplicant/hidl/hidl_manager.h
new file mode 100644
index 0000000..f226d2d
--- /dev/null
+++ b/wpa_supplicant/hidl/hidl_manager.h
@@ -0,0 +1,311 @@
+/*
+ * 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/ISupplicantIfaceCallback.h>
+#include <android/hardware/wifi/supplicant/1.0/ISupplicantNetworkCallback.h>
+
+#include "iface.h"
+#include "network.h"
+#include "supplicant.h"
+
+struct wpa_global;
+struct wpa_supplicant;
+
+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);
+
+	// Methods called from hidl objects.
+	int getIfaceHidlObjectByIfname(
+	    const std::string &ifname,
+	    android::sp<
+		android::hardware::wifi::supplicant::V1_0::ISupplicantIface>
+		*iface_object);
+	int getNetworkHidlObjectByIfnameAndNetworkId(
+	    const std::string &ifname, int network_id,
+	    android::sp<
+		android::hardware::wifi::supplicant::V1_0::ISupplicantNetwork>
+		*network_object);
+	int addSupplicantCallbackHidlObject(
+	    const android::sp<
+		android::hardware::wifi::supplicant::V1_0::ISupplicantCallback>
+		&callback);
+	int addIfaceCallbackHidlObject(
+	    const std::string &ifname,
+	    const android::sp<android::hardware::wifi::supplicant::V1_0::
+				  ISupplicantIfaceCallback> &callback);
+	int addNetworkCallbackHidlObject(
+	    const std::string &ifname, int network_id,
+	    const android::sp<android::hardware::wifi::supplicant::V1_0::
+				  ISupplicantNetworkCallback> &callback);
+
+private:
+	HidlManager() = default;
+	~HidlManager() = default;
+	HidlManager(const HidlManager &) = default;
+	HidlManager &operator=(const HidlManager &) = default;
+
+	const std::string getNetworkObjectMapKey(
+	    const std::string &ifname, int network_id);
+
+	void removeSupplicantCallbackHidlObject(
+	    const android::sp<
+		android::hardware::wifi::supplicant::V1_0::ISupplicantCallback>
+		&callback);
+	void removeIfaceCallbackHidlObject(
+	    const std::string &ifname,
+	    const android::sp<android::hardware::wifi::supplicant::V1_0::
+				  ISupplicantIfaceCallback> &callback);
+	void removeNetworkCallbackHidlObject(
+	    const std::string &ifname, int network_id,
+	    const android::sp<android::hardware::wifi::supplicant::V1_0::
+				  ISupplicantNetworkCallback> &callback);
+	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);
+
+	void callWithEachSupplicantCallback(
+	    const std::function<android::hardware::Return<void>(
+		android::sp<android::hardware::wifi::supplicant::V1_0::
+				ISupplicantCallback>)> &method);
+	void callWithEachIfaceCallback(
+	    const std::string &ifname,
+	    const std::function<android::hardware::Return<void>(
+		android::sp<android::hardware::wifi::supplicant::V1_0::
+				ISupplicantIfaceCallback>)> &method);
+	void callWithEachNetworkCallback(
+	    const std::string &ifname, int network_id,
+	    const std::function<android::hardware::Return<void>(
+		android::sp<android::hardware::wifi::supplicant::V1_0::
+				ISupplicantNetworkCallback>)> &method);
+
+	// HIDL Service name.
+	static const char kServiceName[];
+	// Singleton instance of this class.
+	static HidlManager *instance_;
+	// The main hidl service object.
+	android::sp<Supplicant> supplicant_object_;
+	// Map of all the interface specific hidl objects controlled by
+	// wpa_supplicant. This map is keyed in by the corresponding
+	// |ifname|.
+	std::map<const std::string, android::sp<Iface>> iface_object_map_;
+	// Map of all the 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<Network>> network_object_map_;
+
+	// Callback registered for the main hidl service object.
+	std::vector<android::sp<
+	    android::hardware::wifi::supplicant::V1_0::ISupplicantCallback>>
+	    supplicant_callbacks_;
+	// Map of all the callbacks registered for 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<android::hardware::wifi::supplicant::V1_0::
+					ISupplicantIfaceCallback>>>
+	    iface_callbacks_map_;
+	// Map of all the callbacks registered for 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<android::hardware::wifi::supplicant::V1_0::
+					ISupplicantNetworkCallback>>>
+	    network_callbacks_map_;
+
+	/**
+	 * 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_;
+	};
+};
+
+// 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>(android::hardware::wifi::supplicant::V1_0::
+			      ISupplicant::DebugLevel::EXCESSIVE) ==
+	MSG_EXCESSIVE,
+    "Debug level value mismatch");
+static_assert(
+    static_cast<uint32_t>(android::hardware::wifi::supplicant::V1_0::
+			      ISupplicant::DebugLevel::ERROR) == MSG_ERROR,
+    "Debug level value mismatch");
+
+static_assert(
+    static_cast<uint32_t>(android::hardware::wifi::supplicant::V1_0::
+			      ISupplicantNetwork::KeyMgmtMask::NONE) ==
+	WPA_KEY_MGMT_NONE,
+    "KeyMgmt value mismatch");
+static_assert(
+    static_cast<uint32_t>(android::hardware::wifi::supplicant::V1_0::
+			      ISupplicantNetwork::KeyMgmtMask::WPA_PSK) ==
+	WPA_KEY_MGMT_PSK,
+    "KeyMgmt value mismatch");
+static_assert(
+    static_cast<uint32_t>(android::hardware::wifi::supplicant::V1_0::
+			      ISupplicantNetwork::KeyMgmtMask::WPA_EAP) ==
+	WPA_KEY_MGMT_IEEE8021X,
+    "KeyMgmt value mismatch");
+static_assert(
+    static_cast<uint32_t>(android::hardware::wifi::supplicant::V1_0::
+			      ISupplicantNetwork::KeyMgmtMask::IEEE8021X) ==
+	WPA_KEY_MGMT_IEEE8021X_NO_WPA,
+    "KeyMgmt value mismatch");
+static_assert(
+    static_cast<uint32_t>(android::hardware::wifi::supplicant::V1_0::
+			      ISupplicantNetwork::ProtoMask::WPA) ==
+	WPA_PROTO_WPA,
+    "Proto value mismatch");
+static_assert(
+    static_cast<uint32_t>(android::hardware::wifi::supplicant::V1_0::
+			      ISupplicantNetwork::ProtoMask::RSN) ==
+	WPA_PROTO_RSN,
+    "Proto value mismatch");
+static_assert(
+    static_cast<uint32_t>(android::hardware::wifi::supplicant::V1_0::
+			      ISupplicantNetwork::ProtoMask::OSEN) ==
+	WPA_PROTO_OSEN,
+    "Proto value mismatch");
+static_assert(
+    static_cast<uint32_t>(android::hardware::wifi::supplicant::V1_0::
+			      ISupplicantNetwork::AuthAlgMask::OPEN) ==
+	WPA_AUTH_ALG_OPEN,
+    "AuthAlg value mismatch");
+static_assert(
+    static_cast<uint32_t>(android::hardware::wifi::supplicant::V1_0::
+			      ISupplicantNetwork::AuthAlgMask::SHARED) ==
+	WPA_AUTH_ALG_SHARED,
+    "AuthAlg value mismatch");
+static_assert(
+    static_cast<uint32_t>(android::hardware::wifi::supplicant::V1_0::
+			      ISupplicantNetwork::AuthAlgMask::LEAP) ==
+	WPA_AUTH_ALG_LEAP,
+    "AuthAlg value mismatch");
+static_assert(
+    static_cast<uint32_t>(android::hardware::wifi::supplicant::V1_0::
+			      ISupplicantNetwork::GroupCipherMask::WEP40) ==
+	WPA_CIPHER_WEP40,
+    "GroupCipher value mismatch");
+static_assert(
+    static_cast<uint32_t>(android::hardware::wifi::supplicant::V1_0::
+			      ISupplicantNetwork::GroupCipherMask::WEP104) ==
+	WPA_CIPHER_WEP104,
+    "GroupCipher value mismatch");
+static_assert(
+    static_cast<uint32_t>(android::hardware::wifi::supplicant::V1_0::
+			      ISupplicantNetwork::GroupCipherMask::TKIP) ==
+	WPA_CIPHER_TKIP,
+    "GroupCipher value mismatch");
+static_assert(
+    static_cast<uint32_t>(android::hardware::wifi::supplicant::V1_0::
+			      ISupplicantNetwork::GroupCipherMask::CCMP) ==
+	WPA_CIPHER_CCMP,
+    "GroupCipher value mismatch");
+static_assert(
+    static_cast<uint32_t>(android::hardware::wifi::supplicant::V1_0::
+			      ISupplicantNetwork::PairwiseCipherMask::NONE) ==
+	WPA_CIPHER_NONE,
+    "PairwiseCipher value mismatch");
+static_assert(
+    static_cast<uint32_t>(android::hardware::wifi::supplicant::V1_0::
+			      ISupplicantNetwork::PairwiseCipherMask::TKIP) ==
+	WPA_CIPHER_TKIP,
+    "PairwiseCipher value mismatch");
+static_assert(
+    static_cast<uint32_t>(android::hardware::wifi::supplicant::V1_0::
+			      ISupplicantNetwork::PairwiseCipherMask::CCMP) ==
+	WPA_CIPHER_CCMP,
+    "PairwiseCipher value mismatch");
+
+static_assert(
+    static_cast<uint32_t>(android::hardware::wifi::supplicant::V1_0::
+			      ISupplicantIfaceCallback::State::DISCONNECTED) ==
+	WPA_DISCONNECTED,
+    "State value mismatch");
+static_assert(
+    static_cast<uint32_t>(android::hardware::wifi::supplicant::V1_0::
+			      ISupplicantIfaceCallback::State::COMPLETED) ==
+	WPA_COMPLETED,
+    "State 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/hidl_return_macros.h b/wpa_supplicant/hidl/hidl_return_macros.h
new file mode 100644
index 0000000..25e8f49
--- /dev/null
+++ b/wpa_supplicant/hidl/hidl_return_macros.h
@@ -0,0 +1,16 @@
+/*
+ * 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.
+ */
+
+// Macros to invoke the _hidl_cb to return status along with any return values.
+#define HIDL_RETURN(status_code, ...)                         \
+	do {                                                  \
+		SupplicantStatus status{.code = status_code}; \
+		_hidl_cb(status, ##__VA_ARGS__);              \
+		return Void();                                \
+	} while (false)
diff --git a/wpa_supplicant/hidl/iface.cpp b/wpa_supplicant/hidl/iface.cpp
new file mode 100644
index 0000000..6b94aa1
--- /dev/null
+++ b/wpa_supplicant/hidl/iface.cpp
@@ -0,0 +1,307 @@
+/*
+ * 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_macros.h"
+#include "iface.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+namespace V1_0 {
+namespace implementation {
+
+Iface::Iface(struct wpa_global *wpa_global, const char ifname[])
+    : wpa_global_(wpa_global), ifname_(ifname)
+{
+}
+
+Return<void> Iface::getName(getName_cb _hidl_cb)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (!wpa_s) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_IFACE_INVALID, ifname_);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, ifname_);
+}
+
+Return<void> Iface::addNetwork(addNetwork_cb _hidl_cb)
+{
+	android::sp<ISupplicantNetwork> network;
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (!wpa_s) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_IFACE_INVALID, network);
+	}
+
+	struct wpa_ssid *ssid = wpa_supplicant_add_network(wpa_s);
+	if (!ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN, network);
+	}
+
+	HidlManager *hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager ||
+	    hidl_manager->getNetworkHidlObjectByIfnameAndNetworkId(
+		wpa_s->ifname, ssid->id, &network)) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN, network);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, network);
+}
+
+Return<void> Iface::removeNetwork(uint32_t id, removeNetwork_cb _hidl_cb)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (!wpa_s) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
+	}
+
+	int result = wpa_supplicant_remove_network(wpa_s, id);
+	if (result == -1) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN);
+	}
+
+	if (result != 0) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Iface::getNetwork(uint32_t id, getNetwork_cb _hidl_cb)
+{
+	android::sp<ISupplicantNetwork> network;
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (!wpa_s) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_IFACE_INVALID, network);
+	}
+
+	struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, id);
+	if (!ssid) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, network);
+	}
+
+	HidlManager *hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager ||
+	    hidl_manager->getNetworkHidlObjectByIfnameAndNetworkId(
+		wpa_s->ifname, ssid->id, &network)) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN, network);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, network);
+}
+
+Return<void> Iface::listNetworks(listNetworks_cb _hidl_cb)
+{
+	std::vector<uint32_t> network_ids;
+
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (!wpa_s) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_IFACE_INVALID, network_ids);
+	}
+
+	for (struct wpa_ssid *wpa_ssid = wpa_s->conf->ssid; wpa_ssid;
+	     wpa_ssid = wpa_ssid->next) {
+		network_ids.emplace_back(wpa_ssid->id);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, network_ids);
+}
+
+Return<void> Iface::registerCallback(
+    const sp<ISupplicantIfaceCallback> &callback, registerCallback_cb _hidl_cb)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (!wpa_s) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
+	}
+
+	HidlManager *hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager ||
+	    hidl_manager->addIfaceCallbackHidlObject(ifname_, callback)) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Iface::reassociate(reassociate_cb _hidl_cb)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (!wpa_s) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
+	}
+
+	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Iface::reconnect(reconnect_cb _hidl_cb)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (!wpa_s) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
+	}
+
+	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+	if (!wpa_s->disconnected) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_IFACE_NOT_DISCONNECTED);
+	}
+
+	wpas_request_connection(wpa_s);
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Iface::disconnect(disconnect_cb _hidl_cb)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (!wpa_s) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
+	}
+
+	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
+	}
+
+	wpas_request_disconnection(wpa_s);
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Iface::setPowerSave(bool enable, setPowerSave_cb _hidl_cb)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (!wpa_s) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
+	}
+
+	if (wpa_drv_set_p2p_powersave(wpa_s, enable, -1, -1)) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Iface::initiateTdlsDiscover(
+    const hidl_array<uint8_t, 6 /* 6 */> &mac_address,
+    initiateTdlsDiscover_cb _hidl_cb)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (!wpa_s) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
+	}
+
+	if (!mac_address.data()) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+
+	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) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Iface::initiateTdlsSetup(
+    const hidl_array<uint8_t, 6 /* 6 */> &mac_address,
+    initiateTdlsSetup_cb _hidl_cb)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (!wpa_s) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
+	}
+
+	if (!mac_address.data()) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+
+	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) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Iface::initiateTdlsTeardown(
+    const hidl_array<uint8_t, 6 /* 6 */> &mac_address,
+    initiateTdlsTeardown_cb _hidl_cb)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (!wpa_s) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
+	}
+
+	if (!mac_address.data()) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+
+	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) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	HIDL_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 *Iface::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/iface.h b/wpa_supplicant/hidl/iface.h
new file mode 100644
index 0000000..3be2675
--- /dev/null
+++ b/wpa_supplicant/hidl/iface.h
@@ -0,0 +1,88 @@
+/*
+ * 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_IFACE_H
+#define WPA_SUPPLICANT_HIDL_IFACE_H
+
+#include <android-base/macros.h>
+
+#include <android/hardware/wifi/supplicant/1.0/ISupplicantIface.h>
+#include <android/hardware/wifi/supplicant/1.0/ISupplicantIfaceCallback.h>
+#include <android/hardware/wifi/supplicant/1.0/ISupplicantNetwork.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 {
+
+/**
+ * Implementation of Iface hidl object. Each unique hidl
+ * object is used for control operations on a specific interface
+ * controlled by wpa_supplicant.
+ */
+class Iface : public android::hardware::wifi::supplicant::V1_0::ISupplicantIface
+{
+public:
+	Iface(struct wpa_global* wpa_global, const char ifname[]);
+	~Iface() override = default;
+
+	// Hidl methods exposed.
+	Return<void> getName(getName_cb _hidl_cb) override;
+	Return<void> addNetwork(addNetwork_cb _hidl_cb) override;
+	Return<void> removeNetwork(
+	    uint32_t id, removeNetwork_cb _hidl_cb) override;
+	Return<void> getNetwork(uint32_t id, getNetwork_cb _hidl_cb) override;
+	Return<void> listNetworks(listNetworks_cb _hidl_cb) override;
+	Return<void> registerCallback(
+	    const sp<ISupplicantIfaceCallback>& 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 /* 6 */>& mac_address,
+	    initiateTdlsDiscover_cb _hidl_cb) override;
+	Return<void> initiateTdlsSetup(
+	    const hidl_array<uint8_t, 6 /* 6 */>& mac_address,
+	    initiateTdlsSetup_cb _hidl_cb) override;
+	Return<void> initiateTdlsTeardown(
+	    const hidl_array<uint8_t, 6 /* 6 */>& mac_address,
+	    initiateTdlsTeardown_cb _hidl_cb) override;
+
+private:
+	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 hidl object controls
+	const std::string ifname_;
+
+	DISALLOW_COPY_AND_ASSIGN(Iface);
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace wifi
+}  // namespace supplicant
+}  // namespace hardware
+}  // namespace android
+
+#endif  // WPA_SUPPLICANT_HIDL_IFACE_H
diff --git a/wpa_supplicant/hidl/network.cpp b/wpa_supplicant/hidl/network.cpp
new file mode 100644
index 0000000..a7824fe
--- /dev/null
+++ b/wpa_supplicant/hidl/network.cpp
@@ -0,0 +1,1193 @@
+/*
+ * 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_macros.h"
+#include "network.h"
+
+namespace {
+using android::hardware::wifi::supplicant::V1_0::ISupplicantNetwork;
+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>(ISupplicantNetwork::KeyMgmtMask::NONE) |
+     static_cast<uint32_t>(ISupplicantNetwork::KeyMgmtMask::WPA_PSK) |
+     static_cast<uint32_t>(ISupplicantNetwork::KeyMgmtMask::WPA_EAP) |
+     static_cast<uint32_t>(ISupplicantNetwork::KeyMgmtMask::IEEE8021X));
+constexpr uint32_t kAllowedproto_mask =
+    (static_cast<uint32_t>(ISupplicantNetwork::ProtoMask::WPA) |
+     static_cast<uint32_t>(ISupplicantNetwork::ProtoMask::RSN) |
+     static_cast<uint32_t>(ISupplicantNetwork::ProtoMask::OSEN));
+constexpr uint32_t kAllowedauth_alg_mask =
+    (static_cast<uint32_t>(ISupplicantNetwork::AuthAlgMask::OPEN) |
+     static_cast<uint32_t>(ISupplicantNetwork::AuthAlgMask::SHARED) |
+     static_cast<uint32_t>(ISupplicantNetwork::AuthAlgMask::LEAP));
+constexpr uint32_t kAllowedgroup_cipher_mask =
+    (static_cast<uint32_t>(ISupplicantNetwork::GroupCipherMask::WEP40) |
+     static_cast<uint32_t>(ISupplicantNetwork::GroupCipherMask::WEP104) |
+     static_cast<uint32_t>(ISupplicantNetwork::GroupCipherMask::TKIP) |
+     static_cast<uint32_t>(ISupplicantNetwork::GroupCipherMask::CCMP));
+constexpr uint32_t kAllowedpairwise_cipher_mask =
+    (static_cast<uint32_t>(ISupplicantNetwork::PairwiseCipherMask::NONE) |
+     static_cast<uint32_t>(ISupplicantNetwork::PairwiseCipherMask::TKIP) |
+     static_cast<uint32_t>(ISupplicantNetwork::PairwiseCipherMask::CCMP));
+
+constexpr uint32_t kEapMethodMax =
+    static_cast<uint32_t>(ISupplicantNetwork::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>(ISupplicantNetwork::EapPhase2Method::GTC) + 1;
+constexpr char const *kEapPhase2MethodStrings[kEapPhase2MethodMax] = {
+    "NULL", "PAP", "MSCHAP", "MSCHAPV2", "GTC"};
+}  // namespace
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+namespace V1_0 {
+namespace implementation {
+
+Network::Network(
+    struct wpa_global *wpa_global, const char ifname[], int network_id)
+    : wpa_global_(wpa_global), ifname_(ifname), network_id_(network_id)
+{
+}
+
+Return<void> Network::getId(getId_cb _hidl_cb)
+{
+	uint32_t id = UINT32_MAX;
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID, id);
+	}
+
+	id = network_id_;
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, id);
+}
+
+Return<void> Network::getInterfaceName(getInterfaceName_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_NETWORK_INVALID, ifname_);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, ifname_);
+}
+
+Return<void> Network::registerCallback(
+    const sp<ISupplicantNetworkCallback> &callback,
+    registerCallback_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	HidlManager *hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager ||
+	    hidl_manager->addNetworkCallbackHidlObject(
+		ifname_, network_id_, callback)) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setSsid(
+    const hidl_vec<uint8_t> &ssid, setSsid_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (ssid.size() == 0 ||
+	    ssid.size() >
+		static_cast<uint32_t>(ISupplicantNetwork::ParamSizeLimits::
+					  SSID_MAX_LEN_IN_BYTES)) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+
+	if (setByteArrayFieldAndResetState(
+		ssid.data(), ssid.size(), &(wpa_ssid->ssid),
+		&(wpa_ssid->ssid_len), "ssid")) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	if (wpa_ssid->passphrase) {
+		wpa_config_update_psk(wpa_ssid);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setBssid(
+    const hidl_array<uint8_t, 6 /* 6 */> &bssid, setBssid_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (!bssid.data()) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+
+	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);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setScanSsid(bool enable, setScanSsid_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	wpa_ssid->scan_ssid = enable ? 1 : 0;
+	resetInternalStateAfterParamsUpdate();
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setKeyMgmt(uint32_t key_mgmt_mask, setKeyMgmt_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (key_mgmt_mask & ~kAllowedKeyMgmtMask) {
+		HIDL_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();
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setProto(uint32_t proto_mask, setProto_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (proto_mask & ~kAllowedproto_mask) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	wpa_ssid->proto = proto_mask;
+	wpa_printf(MSG_MSGDUMP, "proto: 0x%x", wpa_ssid->proto);
+	resetInternalStateAfterParamsUpdate();
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setAuthAlg(
+    uint32_t auth_alg_mask,
+    std::function<void(const SupplicantStatus &status)> _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (auth_alg_mask & ~kAllowedauth_alg_mask) {
+		HIDL_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();
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setGroupCipher(
+    uint32_t group_cipher_mask, setGroupCipher_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (group_cipher_mask & ~kAllowedgroup_cipher_mask) {
+		HIDL_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();
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setPairwiseCipher(
+    uint32_t pairwise_cipher_mask, setPairwiseCipher_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (pairwise_cipher_mask & ~kAllowedpairwise_cipher_mask) {
+		HIDL_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();
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setPskPassphrase(
+    const hidl_string &psk, setPskPassphrase_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (isPskPassphraseValid(psk)) {
+		HIDL_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) {
+		HIDL_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")) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	if (wpa_ssid->ssid_len) {
+		wpa_config_update_psk(wpa_ssid);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setWepKey(
+    uint32_t key_idx, const hidl_vec<uint8_t> &wep_key, setWepKey_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (key_idx >=
+	    static_cast<uint32_t>(
+		ISupplicantNetwork::ParamSizeLimits::WEP_KEYS_MAX_NUM)) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	if (wep_key.size() !=
+		static_cast<uint32_t>(ISupplicantNetwork::ParamSizeLimits::
+					  WEP40_KEY_LEN_IN_BYTES) &&
+	    wep_key.size() !=
+		static_cast<uint32_t>(ISupplicantNetwork::ParamSizeLimits::
+					  WEP104_KEY_LEN_IN_BYTES)) {
+		HIDL_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();
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setWepTxKeyIdx(
+    uint32_t key_idx, setWepTxKeyIdx_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (key_idx >=
+	    static_cast<uint32_t>(
+		ISupplicantNetwork::ParamSizeLimits::WEP_KEYS_MAX_NUM)) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+	wpa_ssid->wep_tx_keyidx = key_idx;
+	resetInternalStateAfterParamsUpdate();
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setRequirePmf(bool enable, setRequirePmf_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	wpa_ssid->ieee80211w =
+	    enable ? MGMT_FRAME_PROTECTION_REQUIRED : NO_MGMT_FRAME_PROTECTION;
+	resetInternalStateAfterParamsUpdate();
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setEapMethod(
+    ISupplicantNetwork::EapMethod method, setEapMethod_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+	int retrieved_vendor, retrieved_method;
+
+	const char *method_str =
+	    kEapMethodStrings[static_cast<uint32_t>(method)];
+	// 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) {
+		HIDL_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) {
+		HIDL_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();
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setEapPhase2Method(
+    ISupplicantNetwork::EapPhase2Method method, setEapPhase2Method_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (setStringFieldAndResetState(
+		kEapPhase2MethodStrings[static_cast<uint32_t>(method)],
+		&(wpa_ssid->eap.phase2), "eap phase2")) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setEapIdentity(
+    const hidl_vec<uint8_t> &identity, setEapIdentity_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (setByteArrayFieldAndResetState(
+		identity.data(), identity.size(), &(wpa_ssid->eap.identity),
+		&(wpa_ssid->eap.identity_len), "eap identity")) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setEapAnonymousIdentity(
+    const hidl_vec<uint8_t> &identity, setEapAnonymousIdentity_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (setByteArrayFieldAndResetState(
+		identity.data(), identity.size(),
+		&(wpa_ssid->eap.anonymous_identity),
+		&(wpa_ssid->eap.anonymous_identity_len),
+		"eap anonymous_identity")) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setEapPassword(
+    const hidl_vec<uint8_t> &password, setEapPassword_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (setByteArrayKeyFieldAndResetState(
+		password.data(), password.size(), &(wpa_ssid->eap.password),
+		&(wpa_ssid->eap.password_len), "eap password")) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	wpa_ssid->eap.flags &= ~EAP_CONFIG_FLAGS_PASSWORD_NTHASH;
+	wpa_ssid->eap.flags &= ~EAP_CONFIG_FLAGS_EXT_PASSWORD;
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setEapCACert(
+    const hidl_string &path, setEapCACert_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (setStringFieldAndResetState(
+		path.c_str(), &(wpa_ssid->eap.ca_cert), "eap ca_cert")) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setEapCAPath(
+    const hidl_string &path, setEapCAPath_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (setStringFieldAndResetState(
+		path.c_str(), &(wpa_ssid->eap.ca_path), "eap ca_path")) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setEapClientCert(
+    const hidl_string &path, setEapClientCert_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (setStringFieldAndResetState(
+		path.c_str(), &(wpa_ssid->eap.client_cert),
+		"eap client_cert")) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setEapPrivateKey(
+    const hidl_string &path, setEapPrivateKey_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (setStringFieldAndResetState(
+		path.c_str(), &(wpa_ssid->eap.private_key),
+		"eap private_key")) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setEapSubjectMatch(
+    const hidl_string &match, setEapSubjectMatch_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (setStringFieldAndResetState(
+		match.c_str(), &(wpa_ssid->eap.subject_match),
+		"eap subject_match")) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setEapAltSubjectMatch(
+    const hidl_string &match, setEapAltSubjectMatch_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (setStringFieldAndResetState(
+		match.c_str(), &(wpa_ssid->eap.altsubject_match),
+		"eap altsubject_match")) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setEapEngine(bool enable, setEapEngine_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	wpa_ssid->eap.engine = enable ? 1 : 0;
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setEapEngineID(
+    const hidl_string &id, setEapEngineID_cb _hidl_cb)
+
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (setStringFieldAndResetState(
+		id.c_str(), &(wpa_ssid->eap.engine_id), "eap engine_id")) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::setEapDomainSuffixMatch(
+    const hidl_string &match, setEapDomainSuffixMatch_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (setStringFieldAndResetState(
+		match.c_str(), &(wpa_ssid->eap.domain_suffix_match),
+		"eap domain_suffix_match")) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::getSsid(getSsid_cb _hidl_cb)
+{
+	std::vector<uint8_t> ssid;
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_NETWORK_INVALID, ssid);
+	}
+
+	ssid.assign(wpa_ssid->ssid, wpa_ssid->ssid + wpa_ssid->ssid_len);
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, ssid);
+}
+
+Return<void> Network::getBssid(getBssid_cb _hidl_cb)
+{
+	hidl_array<uint8_t, 6> bssid;
+	os_memcpy(bssid.data(), kZeroBssid, ETH_ALEN);
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_NETWORK_INVALID, bssid);
+	}
+
+	if (wpa_ssid->bssid_set) {
+		os_memcpy(bssid.data(), wpa_ssid->bssid, ETH_ALEN);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, bssid);
+}
+
+Return<void> Network::getScanSsid(getScanSsid_cb _hidl_cb)
+{
+	bool enabled = false;
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_NETWORK_INVALID, enabled);
+	}
+
+	enabled = (wpa_ssid->scan_ssid == 1);
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, enabled);
+}
+
+Return<void> Network::getKeyMgmt(getKeyMgmt_cb _hidl_cb)
+{
+	uint32_t key_mgmt_mask = 0;
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		    key_mgmt_mask);
+	}
+
+	key_mgmt_mask = wpa_ssid->key_mgmt;
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, key_mgmt_mask);
+}
+
+Return<void> Network::getProto(getProto_cb _hidl_cb)
+{
+	uint32_t proto_mask = 0;
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_NETWORK_INVALID, proto_mask);
+	}
+
+	proto_mask = wpa_ssid->proto;
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, proto_mask);
+}
+
+Return<void> Network::getAuthAlg(getAuthAlg_cb _hidl_cb)
+{
+	uint32_t auth_alg_mask = 0;
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		    auth_alg_mask);
+	}
+
+	auth_alg_mask = wpa_ssid->auth_alg;
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, auth_alg_mask);
+}
+
+Return<void> Network::getGroupCipher(getGroupCipher_cb _hidl_cb)
+{
+	uint32_t group_cipher_mask = 0;
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		    group_cipher_mask);
+	}
+
+	group_cipher_mask = wpa_ssid->group_cipher;
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, group_cipher_mask);
+}
+
+Return<void> Network::getPairwiseCipher(getPairwiseCipher_cb _hidl_cb)
+{
+	uint32_t pairwise_cipher_mask = 0;
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		    pairwise_cipher_mask);
+	}
+
+	pairwise_cipher_mask = wpa_ssid->pairwise_cipher;
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, pairwise_cipher_mask);
+}
+
+Return<void> Network::getPskPassphrase(getPskPassphrase_cb _hidl_cb)
+{
+	hidl_string psk;
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID, psk);
+	}
+
+	if (wpa_ssid->passphrase) {
+		psk = wpa_ssid->passphrase;
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, psk);
+}
+
+Return<void> Network::getWepKey(uint32_t key_idx, getWepKey_cb _hidl_cb)
+{
+	std::vector<uint8_t> wep_key;
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_NETWORK_INVALID, wep_key);
+		return Void();
+	}
+
+	if (key_idx >=
+	    static_cast<uint32_t>(
+		ISupplicantNetwork::ParamSizeLimits::WEP_KEYS_MAX_NUM)) {
+		HIDL_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]);
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, wep_key);
+}
+
+Return<void> Network::getWepTxKeyIdx(getWepTxKeyIdx_cb _hidl_cb)
+{
+	uint32_t wep_tx_key_idx = UINT32_MAX;
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_NETWORK_INVALID,
+		    wep_tx_key_idx);
+	}
+
+	wep_tx_key_idx = wpa_ssid->wep_tx_keyidx;
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, wep_tx_key_idx);
+}
+
+Return<void> Network::getRequirePmf(getRequirePmf_cb _hidl_cb)
+{
+	bool enabled = false;
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_NETWORK_INVALID, enabled);
+	}
+
+	enabled = (wpa_ssid->ieee80211w == MGMT_FRAME_PROTECTION_REQUIRED);
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, enabled);
+}
+
+Return<void> Network::enable(bool no_connect, enable_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (wpa_ssid->disabled != 0) {
+		HIDL_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);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::disable(disable_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (wpa_ssid->disabled == 2) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	wpa_supplicant_disable_network(wpa_s, wpa_ssid);
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::select(select_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	if (wpa_ssid->disabled == 2) {
+		HIDL_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);
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::sendNetworkEapSimGsmAuthResponse(
+    const ISupplicantNetwork::NetworkResponseEapSimGsmAuthParams &params,
+    sendNetworkEapSimGsmAuthResponse_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	// Convert the incoming parameters to a string to pass to
+	// wpa_supplicant.
+	std::string ctrl_rsp_param;
+	uint32_t kc_hex_len = params.kc.size() * 2 + 1;
+	char *kc_hex = (char *)malloc(kc_hex_len);
+	uint32_t sres_hex_len = params.sres.size() * 2 + 1;
+	char *sres_hex = (char *)malloc(sres_hex_len);
+	if (!kc_hex || !sres_hex) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	wpa_snprintf_hex(
+	    kc_hex, kc_hex_len, params.kc.data(), params.kc.size());
+	wpa_snprintf_hex(
+	    sres_hex, sres_hex_len, params.sres.data(), params.sres.size());
+	ctrl_rsp_param += "kc:";
+	ctrl_rsp_param += kc_hex;
+	ctrl_rsp_param += " sres:";
+	ctrl_rsp_param += sres_hex;
+
+	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpa_supplicant_ctrl_rsp_handle(
+		wpa_s, wpa_ssid, rtype, ctrl_rsp_param.c_str())) {
+		HIDL_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());
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::sendNetworkEapSimUmtsAuthResponse(
+    const ISupplicantNetwork::NetworkResponseEapSimUmtsAuthParams &params,
+    sendNetworkEapSimUmtsAuthResponse_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	// Convert the incoming parameters to a string to pass to
+	// wpa_supplicant.
+	std::string ctrl_rsp_param;
+	uint32_t ik_hex_len = params.ik.size() * 2 + 1;
+	char *ik_hex = (char *)malloc(ik_hex_len);
+	uint32_t ck_hex_len = params.ck.size() * 2 + 1;
+	char *ck_hex = (char *)malloc(ck_hex_len);
+	uint32_t res_hex_len = params.res.size() * 2 + 1;
+	char *res_hex = (char *)malloc(res_hex_len);
+	if (!ik_hex || !ck_hex || !res_hex) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	wpa_snprintf_hex(
+	    ik_hex, ik_hex_len, params.ik.data(), params.ik.size());
+	wpa_snprintf_hex(
+	    ck_hex, ck_hex_len, params.ck.data(), params.ck.size());
+	wpa_snprintf_hex(
+	    res_hex, res_hex_len, params.res.data(), params.res.size());
+	ctrl_rsp_param += "ik:";
+	ctrl_rsp_param += ik_hex;
+	ctrl_rsp_param += "ck:";
+	ctrl_rsp_param += ck_hex;
+	ctrl_rsp_param += " res:";
+	ctrl_rsp_param += res_hex;
+
+	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_SIM;
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpa_supplicant_ctrl_rsp_handle(
+		wpa_s, wpa_ssid, rtype, ctrl_rsp_param.c_str())) {
+		HIDL_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());
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Network::sendNetworkEapIdentityResponse(
+    const hidl_vec<uint8_t> &identity,
+    sendNetworkEapIdentityResponse_cb _hidl_cb)
+{
+	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
+	if (!wpa_ssid) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_INVALID);
+	}
+
+	// Convert the incoming parameters to a string to pass to
+	// wpa_supplicant.
+	uint32_t identity_hex_len = identity.size() * 2 + 1;
+	char *identity_hex = (char *)malloc(identity_hex_len);
+	std::string ctrl_rsp_param;
+	if (!identity_hex) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+	wpa_snprintf_hex(
+	    identity_hex, identity_hex_len, identity.data(), identity.size());
+	ctrl_rsp_param = identity_hex;
+
+	enum wpa_ctrl_req_type rtype = WPA_CTRL_REQ_EAP_IDENTITY;
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (wpa_supplicant_ctrl_rsp_handle(
+		wpa_s, wpa_ssid, rtype, ctrl_rsp_param.c_str())) {
+		HIDL_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());
+
+	HIDL_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 *Network::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 *Network::retrieveIfacePtr()
+{
+	return wpa_supplicant_get_iface(
+	    (struct wpa_global *)wpa_global_, ifname_.c_str());
+}
+
+/**
+ * Check if the provided psk passhrase is valid or not.
+ *
+ * Returns 0 if valid, 1 otherwise.
+ */
+int Network::isPskPassphraseValid(const hidl_string &psk)
+{
+	if (psk.size() <
+		static_cast<uint32_t>(ISupplicantNetwork::ParamSizeLimits::
+					  PSK_PASSPHRASE_MIN_LEN_IN_BYTES) ||
+	    psk.size() >
+		static_cast<uint32_t>(ISupplicantNetwork::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 Network::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 Network::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 Network::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 Network::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 Network::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 Network::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/network.h b/wpa_supplicant/hidl/network.h
new file mode 100644
index 0000000..614513f
--- /dev/null
+++ b/wpa_supplicant/hidl/network.h
@@ -0,0 +1,184 @@
+/*
+ * 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_NETWORK_H
+#define WPA_SUPPLICANT_HIDL_NETWORK_H
+
+#include <android-base/macros.h>
+
+#include <android/hardware/wifi/supplicant/1.0/ISupplicantNetwork.h>
+#include <android/hardware/wifi/supplicant/1.0/ISupplicantNetworkCallback.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 Network hidl object. Each unique hidl
+ * object is used for control operations on a specific network
+ * controlled by wpa_supplicant.
+ */
+class Network : public ISupplicantNetwork
+{
+public:
+	Network(
+	    struct wpa_global* wpa_global, const char ifname[], int network_id);
+	~Network() override = default;
+
+	// Hidl methods exposed.
+	Return<void> getId(getId_cb _hidl_cb) override;
+	Return<void> getInterfaceName(getInterfaceName_cb _hidl_cb) override;
+	Return<void> registerCallback(
+	    const sp<ISupplicantNetworkCallback>& 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 /* 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> 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(
+	    ISupplicantNetwork::EapMethod method,
+	    setEapMethod_cb _hidl_cb) override;
+	Return<void> setEapPhase2Method(
+	    ISupplicantNetwork::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> setEapPrivateKey(
+	    const hidl_string& path, setEapPrivateKey_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> 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> 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> 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 ISupplicantNetwork::NetworkResponseEapSimGsmAuthParams&
+		params,
+	    sendNetworkEapSimGsmAuthResponse_cb _hidl_cb) override;
+	Return<void> sendNetworkEapSimUmtsAuthResponse(
+	    const ISupplicantNetwork::NetworkResponseEapSimUmtsAuthParams&
+		params,
+	    sendNetworkEapSimUmtsAuthResponse_cb _hidl_cb) override;
+	Return<void> sendNetworkEapIdentityResponse(
+	    const hidl_vec<uint8_t>& identity,
+	    sendNetworkEapIdentityResponse_cb _hidl_cb) override;
+
+private:
+	struct wpa_ssid* retrieveNetworkPtr();
+	struct wpa_supplicant* retrieveIfacePtr();
+	int isPskPassphraseValid(const android::hardware::hidl_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.
+	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_;
+
+	DISALLOW_COPY_AND_ASSIGN(Network);
+};
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace wifi
+}  // namespace supplicant
+}  // namespace hardware
+}  // namespace android
+
+#endif  // WPA_SUPPLICANT_HIDL_NETWORK_H
diff --git a/wpa_supplicant/hidl/supplicant.cpp b/wpa_supplicant/hidl/supplicant.cpp
new file mode 100644
index 0000000..b9f6ce2
--- /dev/null
+++ b/wpa_supplicant/hidl/supplicant.cpp
@@ -0,0 +1,155 @@
+/*
+ * 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_macros.h"
+#include "supplicant.h"
+
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+namespace V1_0 {
+namespace implementation {
+
+// 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) {}
+Return<void> Supplicant::createInterface(
+    const hidl_string& ifname, createInterface_cb _hidl_cb)
+{
+	android::sp<ISupplicantIface> iface;
+
+	// Check if required |ifname| argument is empty.
+	if (ifname.size() == 0) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_ARGS_INVALID, iface);
+	}
+	// Try to get the wpa_supplicant record for this iface, return
+	// an error if we already control it.
+	if (wpa_supplicant_get_iface(wpa_global_, ifname.c_str()) != NULL) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_EXISTS, iface);
+	}
+
+	// Otherwise, have wpa_supplicant attach to it.
+	struct wpa_supplicant* wpa_s = NULL;
+	struct wpa_interface iface_params;
+	os_memset(&iface_params, 0, sizeof(iface));
+	iface_params.ifname = ifname.c_str();
+	iface_params.confname = kConfigFilePath;
+	iface_params.driver = kDriverName;
+	wpa_s = wpa_supplicant_add_iface(wpa_global_, &iface_params, NULL);
+	if (!wpa_s) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN, iface);
+	}
+	// The supplicant core creates a corresponding hidl object via
+	// HidlManager when |wpa_supplicant_add_iface| is called.
+	HidlManager* hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager ||
+	    hidl_manager->getIfaceHidlObjectByIfname(wpa_s->ifname, &iface)) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN, iface);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, iface);
+}
+
+Return<void> Supplicant::removeInterface(
+    const hidl_string& ifname, removeInterface_cb _hidl_cb)
+{
+	struct wpa_supplicant* wpa_s;
+
+	wpa_s = wpa_supplicant_get_iface(wpa_global_, ifname.c_str());
+	if (!wpa_s) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN);
+	}
+	if (wpa_supplicant_remove_iface(wpa_global_, wpa_s, 0)) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Supplicant::getInterface(
+    const hidl_string& ifname, getInterface_cb _hidl_cb)
+{
+	android::sp<ISupplicantIface> iface;
+
+	struct wpa_supplicant* wpa_s =
+	    wpa_supplicant_get_iface(wpa_global_, ifname.c_str());
+	if (!wpa_s) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_UNKNOWN, iface);
+	}
+
+	HidlManager* hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager ||
+	    hidl_manager->getIfaceHidlObjectByIfname(wpa_s->ifname, &iface)) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN, iface);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, iface);
+}
+
+Return<void> Supplicant::listInterfaces(listInterfaces_cb _hidl_cb)
+{
+	std::vector<hidl_string> ifnames;
+	for (struct wpa_supplicant* wpa_s = wpa_global_->ifaces; wpa_s;
+	     wpa_s = wpa_s->next) {
+		ifnames.emplace_back(wpa_s->ifname);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, ifnames);
+}
+
+Return<void> Supplicant::registerCallback(
+    const sp<ISupplicantCallback>& callback, registerCallback_cb _hidl_cb)
+{
+	HidlManager* hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager ||
+	    hidl_manager->addSupplicantCallbackHidlObject(callback)) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<void> Supplicant::setDebugParams(
+    ISupplicant::DebugLevel level, bool show_timestamp, bool show_keys,
+    setDebugParams_cb _hidl_cb)
+{
+	if (wpa_supplicant_set_debug_params(
+		wpa_global_, static_cast<uint32_t>(level), show_timestamp,
+		show_keys)) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
+}
+
+Return<ISupplicant::DebugLevel> Supplicant::getDebugLevel()
+{
+	return (ISupplicant::DebugLevel)wpa_debug_level;
+}
+
+Return<bool> Supplicant::isDebugShowTimestampEnabled()
+{
+	return (wpa_debug_timestamp ? true : false);
+}
+
+Return<bool> Supplicant::isDebugShowKeysEnabled()
+{
+	return (wpa_debug_show_keys ? true : false);
+}
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace wifi
+}  // namespace supplicant
+}  // namespace hardware
+}  // namespace android
diff --git a/wpa_supplicant/hidl/supplicant.h b/wpa_supplicant/hidl/supplicant.h
new file mode 100644
index 0000000..cad4052
--- /dev/null
+++ b/wpa_supplicant/hidl/supplicant.h
@@ -0,0 +1,79 @@
+/*
+ * 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;
+
+	// Hidl methods exposed.
+	Return<void> createInterface(
+	    const hidl_string& ifname, createInterface_cb _hidl_cb) override;
+	Return<void> removeInterface(
+	    const hidl_string& ifname, removeInterface_cb _hidl_cb) override;
+	Return<void> getInterface(
+	    const hidl_string& ifname, 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;
+
+private:
+	// 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
diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c
index 67e36ae..c76b82d 100644
--- a/wpa_supplicant/notify.c
+++ b/wpa_supplicant/notify.c
@@ -13,7 +13,7 @@
 #include "config.h"
 #include "wpa_supplicant_i.h"
 #include "wps_supplicant.h"
-#include "binder/binder.h"
+#include "hidl/hidl.h"
 #include "dbus/dbus_common.h"
 #include "dbus/dbus_old.h"
 #include "dbus/dbus_new.h"
@@ -35,11 +35,11 @@
 	}
 #endif /* CONFIG_DBUS */
 
-#ifdef CONFIG_BINDER
-	global->binder = wpas_binder_init(global);
-	if (!global->binder)
+#ifdef CONFIG_HIDL
+	global->hidl = wpas_hidl_init(global);
+	if (!global->hidl)
 		return -1;
-#endif /* CONFIG_BINDER */
+#endif /* CONFIG_HIDL */
 
 	return 0;
 }
@@ -52,10 +52,10 @@
 		wpas_dbus_deinit(global->dbus);
 #endif /* CONFIG_DBUS */
 
-#ifdef CONFIG_BINDER
-	if (global->binder)
-		wpas_binder_deinit(global->binder);
-#endif /* CONFIG_BINDER */
+#ifdef CONFIG_HIDL
+	if (global->hidl)
+		wpas_hidl_deinit(global->hidl);
+#endif /* CONFIG_HIDL */
 }
 
 
@@ -70,6 +70,9 @@
 	if (wpas_dbus_register_interface(wpa_s))
 		return -1;
 
+	if (wpas_hidl_register_interface(wpa_s))
+		return -1;
+
 	return 0;
 }
 
@@ -84,6 +87,8 @@
 
 	/* unregister interface in new DBus ctrl iface */
 	wpas_dbus_unregister_interface(wpa_s);
+
+	wpas_hidl_unregister_interface(wpa_s);
 }
 
 
@@ -128,6 +133,8 @@
 		     wpa_ssid_txt(wpa_s->current_ssid->ssid,
 				  wpa_s->current_ssid->ssid_len) : "");
 #endif /* ANDROID */
+
+	wpas_hidl_notify_state_changed(wpa_s);
 }
 
 
@@ -214,6 +221,8 @@
 		return;
 
 	wpas_dbus_signal_network_request(wpa_s, ssid, rtype, default_txt);
+
+	wpas_hidl_notify_network_request(wpa_s, ssid, rtype, default_txt);
 }
 
 
@@ -323,8 +332,10 @@
 	 * applications since these network objects won't behave like
 	 * regular ones.
 	 */
-	if (!ssid->p2p_group && wpa_s->global->p2p_group_formation != wpa_s)
+	if (!ssid->p2p_group && wpa_s->global->p2p_group_formation != wpa_s) {
 		wpas_dbus_register_network(wpa_s, ssid);
+		wpas_hidl_register_network(wpa_s, ssid);
+	}
 }
 
 
@@ -354,8 +365,10 @@
 	if (wpa_s->wpa)
 		wpa_sm_pmksa_cache_flush(wpa_s->wpa, ssid);
 	if (!ssid->p2p_group && wpa_s->global->p2p_group_formation != wpa_s &&
-	    !wpa_s->p2p_mgmt)
+	    !wpa_s->p2p_mgmt) {
 		wpas_dbus_unregister_network(wpa_s, ssid->id);
+		wpas_hidl_unregister_network(wpa_s, ssid);
+	}
 	if (network_is_persistent_group(ssid))
 		wpas_notify_persistent_group_removed(wpa_s, ssid);
 
diff --git a/wpa_supplicant/wpa_supplicant.c b/wpa_supplicant/wpa_supplicant.c
index 7361ee9..282ef66 100644
--- a/wpa_supplicant/wpa_supplicant.c
+++ b/wpa_supplicant/wpa_supplicant.c
@@ -2767,9 +2767,8 @@
 		wpa_s->reassociate = 1;
 }
 
-
 /**
- * wpa_supplicant_add_network - Add a new network
+ * wpa_supplicant_add_network - Add a new network.
  * @wpa_s: wpa_supplicant structure for a network interface
  * Returns: The new network configuration or %NULL if operation failed
  *
@@ -2784,8 +2783,9 @@
 	struct wpa_ssid *ssid;
 
 	ssid = wpa_config_add_network(wpa_s->conf);
-	if (!ssid)
+	if (!ssid) {
 		return NULL;
+	}
 	wpas_notify_network_added(wpa_s, ssid);
 	ssid->disabled = 1;
 	wpa_config_set_network_defaults(ssid);
@@ -2793,7 +2793,6 @@
 	return ssid;
 }
 
-
 /**
  * wpa_supplicant_remove_network - Remove a configured network based on id
  * @wpa_s: wpa_supplicant structure for a network interface
@@ -2813,14 +2812,16 @@
 	int was_disabled;
 
 	ssid = wpa_config_get_network(wpa_s->conf, id);
-	if (!ssid)
+	if (ssid)
+		wpas_notify_network_removed(wpa_s, ssid);
+	if (ssid == NULL) {
 		return -1;
-	wpas_notify_network_removed(wpa_s, ssid);
+	}
 
 	if (wpa_s->last_ssid == ssid)
 		wpa_s->last_ssid = NULL;
 
-	if (ssid == wpa_s->current_ssid || !wpa_s->current_ssid) {
+	if (ssid == wpa_s->current_ssid || wpa_s->current_ssid == NULL) {
 #ifdef CONFIG_SME
 		wpa_s->sme.prev_bssid_set = 0;
 #endif /* CONFIG_SME */
@@ -2843,20 +2844,19 @@
 
 	was_disabled = ssid->disabled;
 
-	if (wpa_config_remove_network(wpa_s->conf, id) < 0)
+	if (wpa_config_remove_network(wpa_s->conf, id) < 0) {
 		return -2;
+	}
 
 	if (!was_disabled && wpa_s->sched_scanning) {
-		wpa_printf(MSG_DEBUG,
-			   "Stop ongoing sched_scan to remove network from filters");
+		wpa_printf(MSG_DEBUG, "Stop ongoing sched_scan to remove "
+			   "network from filters");
 		wpa_supplicant_cancel_sched_scan(wpa_s);
 		wpa_supplicant_req_scan(wpa_s, 0, 0);
 	}
-
 	return 0;
 }
 
-
 /**
  * wpa_supplicant_enable_network - Mark a configured network as enabled
  * @wpa_s: wpa_supplicant structure for a network interface
@@ -5813,20 +5813,36 @@
 }
 
 
-#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW)
+#if defined(CONFIG_CTRL_IFACE) || defined(CONFIG_CTRL_IFACE_DBUS_NEW) || defined (CONFIG_CTRL_IFACE_HIDL)
 int wpa_supplicant_ctrl_iface_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
 					      struct wpa_ssid *ssid,
 					      const char *field,
 					      const char *value)
 {
 #ifdef IEEE8021X_EAPOL
-	struct eap_peer_config *eap = &ssid->eap;
+	enum wpa_ctrl_req_type rtype;
 
 	wpa_printf(MSG_DEBUG, "CTRL_IFACE: response handle field=%s", field);
 	wpa_hexdump_ascii_key(MSG_DEBUG, "CTRL_IFACE: response value",
 			      (const u8 *) value, os_strlen(value));
 
-	switch (wpa_supplicant_ctrl_req_from_string(field)) {
+	rtype = wpa_supplicant_ctrl_req_from_string(field);
+	return wpa_supplicant_ctrl_rsp_handle(wpa_s, ssid, rtype, value);
+#else /* IEEE8021X_EAPOL */
+	wpa_printf(MSG_DEBUG, "CTRL_IFACE: IEEE 802.1X not included");
+	return -1;
+#endif /* IEEE8021X_EAPOL */
+}
+
+int wpa_supplicant_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
+				   struct wpa_ssid *ssid,
+				   enum wpa_ctrl_req_type rtype,
+				   const char *value)
+{
+#ifdef IEEE8021X_EAPOL
+	struct eap_peer_config *eap = &ssid->eap;
+
+	switch (rtype) {
 	case WPA_CTRL_REQ_EAP_IDENTITY:
 		os_free(eap->identity);
 		eap->identity = (u8 *) os_strdup(value);
@@ -5897,7 +5913,7 @@
 			return -1;
 		break;
 	default:
-		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown field '%s'", field);
+		wpa_printf(MSG_DEBUG, "CTRL_IFACE: Unknown type %d", rtype);
 		return -1;
 	}
 
@@ -5907,7 +5923,7 @@
 	return -1;
 #endif /* IEEE8021X_EAPOL */
 }
-#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW */
+#endif /* CONFIG_CTRL_IFACE || CONFIG_CTRL_IFACE_DBUS_NEW || CONFIG_CTRL_IFACE_HIDL */
 
 
 int wpas_network_disabled(struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
@@ -6135,7 +6151,6 @@
 		wpa_s->reattach = 0;
 }
 
-
 /**
  * wpas_request_disconnection - Request disconnection
  * @wpa_s: Pointer to the network interface
diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h
index 44f72a6..4f5d41b 100644
--- a/wpa_supplicant/wpa_supplicant_i.h
+++ b/wpa_supplicant/wpa_supplicant_i.h
@@ -44,7 +44,7 @@
 struct ctrl_iface_priv;
 struct ctrl_iface_global_priv;
 struct wpas_dbus_priv;
-struct wpas_binder_priv;
+struct wpas_hidl_priv;
 
 /**
  * struct wpa_interface - Parameters for wpa_supplicant_add_iface()
@@ -265,7 +265,7 @@
 	struct wpa_params params;
 	struct ctrl_iface_global_priv *ctrl_iface;
 	struct wpas_dbus_priv *dbus;
-	struct wpas_binder_priv *binder;
+	struct wpas_hidl_priv *hidl;
 	void **drv_priv;
 	size_t drv_count;
 	struct os_time suspend_time;
@@ -479,9 +479,9 @@
 	char *preq_notify_peer;
 #endif /* CONFIG_AP */
 #endif /* CONFIG_CTRL_IFACE_DBUS_NEW */
-#ifdef CONFIG_CTRL_IFACE_BINDER
-	const void *binder_object_key;
-#endif /* CONFIG_CTRL_IFACE_BINDER */
+#ifdef CONFIG_CTRL_IFACE_HIDL
+	const void *hidl_object_key;
+#endif /* CONFIG_CTRL_IFACE_HIDL */
 	char bridge_ifname[16];
 
 	char *confname;
@@ -1219,6 +1219,20 @@
 					      struct wpa_ssid *ssid,
 					      const char *field,
 					      const char *value);
+/**
+ * wpa_supplicant_ctrl_rsp_handle - Handle a control response
+ * @wpa_s: Pointer to wpa_supplicant data
+ * @ssid: Pointer to the network block the reply is for
+ * @field: field the response is a reply for
+ * @value: value (ie, password, etc) for @field
+ * Returns: 0 on success, non-zero on error
+ *
+ * Helper function to handle replies to control interface requests.
+ */
+int wpa_supplicant_ctrl_rsp_handle(struct wpa_supplicant *wpa_s,
+				   struct wpa_ssid *ssid,
+				   enum wpa_ctrl_req_type rtype,
+				   const char *value);
 
 void ibss_mesh_setup_freq(struct wpa_supplicant *wpa_s,
 			  const struct wpa_ssid *ssid,