Browse Source

binder: Add binder skeletal code for Android

Create the skeletal binder interface for wpa_supplicant. The interface
hierarchy is based off the existing dbus
interface(https://w1.fi/wpa_supplicant/devel/dbus.html).

Since we use libbinder, the binder interface codebase needs to be
written in C++ and can only be compiled on Android platform for now.

The aidl files define binder RPC interfaces. The Android build system
generates the corresponding C++ interface classes which needs to be
implemented by the server process.

The clients can obtain a reference to the binder service (root object)
using:
android::String16 service_name("fi.w1.wpa_supplicant");
android::sp<android::IBinder> binder =
  android::defaultServiceManager()->getService(service_name);

Once a reference to the root object is retrieved, the clients can
obtain references to other RPC objects using that root object methods.

Signed-off-by: Roshan Pius <rpius@google.com>
Roshan Pius 9 years ago
parent
commit
7b4bbb9f94

+ 14 - 0
wpa_supplicant/Android.mk

@@ -1346,6 +1346,16 @@ endif
 OBJS += $(DBUS_OBJS)
 L_CFLAGS += $(DBUS_CFLAGS)
 
+ifdef CONFIG_CTRL_IFACE_BINDER
+BINDER=y
+L_CFLAGS += -DCONFIG_BINDER -DCONFIG_CTRL_IFACE_BINDER
+OBJS += binder/binder.cpp binder/binder_manager.cpp
+OBJS += binder/supplicant.cpp binder/iface.cpp
+OBJS += binder/fi/w1/wpa_supplicant/ISupplicant.aidl
+OBJS += binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl
+OBJS += binder/fi/w1/wpa_supplicant/IIface.aidl
+endif
+
 ifdef CONFIG_READLINE
 OBJS_c += src/utils/edit_readline.c
 LIBS_c += -lncurses -lreadline
@@ -1583,6 +1593,10 @@ LOCAL_C_INCLUDES := $(INCLUDES)
 ifeq ($(DBUS), y)
 LOCAL_SHARED_LIBRARIES += libdbus
 endif
+ifeq ($(BINDER), y)
+LOCAL_AIDL_INCLUDES := $(LOCAL_PATH)/binder frameworks/native/aidl/binder
+LOCAL_SHARED_LIBRARIES += libutils libbinder
+endif
 include $(BUILD_EXECUTABLE)
 
 ########################

+ 4 - 0
wpa_supplicant/android.config

@@ -324,6 +324,10 @@ CONFIG_IEEE80211W=y
 # Add introspection support for new DBus control interface
 #CONFIG_CTRL_IFACE_DBUS_INTRO=y
 
+# Add support for Binder control interface
+# Only applicable for Android platforms.
+#CONFIG_CTRL_IFACE_BINDER=y
+
 # Add support for loading EAP methods dynamically as shared libraries.
 # When this option is enabled, each EAP method can be either included
 # statically (CONFIG_EAP_<method>=y) or dynamically (CONFIG_EAP_<method>=dyn).

+ 80 - 0
wpa_supplicant/binder/binder.cpp

@@ -0,0 +1,80 @@
+/*
+ * 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/ProcessState.h>
+#include <binder/IServiceManager.h>
+
+#include "binder_manager.h"
+
+extern "C" {
+#include "utils/includes.h"
+#include "utils/common.h"
+#include "utils/eloop.h"
+#include "binder.h"
+#include "binder_i.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();
+}

+ 32 - 0
wpa_supplicant/binder/binder.h

@@ -0,0 +1,32 @@
+/*
+ * 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_H
+#define 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 _cplusplus
+}
+#endif /* _cplusplus */
+
+#endif /* BINDER_H */

+ 27 - 0
wpa_supplicant/binder/binder_i.h

@@ -0,0 +1,27 @@
+/*
+ * 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 */

+ 53 - 0
wpa_supplicant/binder/binder_manager.cpp

@@ -0,0 +1,53 @@
+/*
+ * 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_manager.h"
+
+extern "C" {
+#include "utils/includes.h"
+#include "utils/common.h"
+}
+
+namespace wpa_supplicant_binder {
+
+const char BinderManager::kBinderServiceName[] = "fi.w1.wpa_supplicant";
+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(kBinderServiceName);
+	android::defaultServiceManager()->addService(
+		service_name,
+		android::IInterface::asBinder(supplicant_object_));
+	return 0;
+}
+
+} /* namespace wpa_supplicant_binder */

+ 54 - 0
wpa_supplicant/binder/binder_manager.h

@@ -0,0 +1,54 @@
+/*
+ * 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_MANAGER_H
+#define BINDER_MANAGER_H
+
+#include <map>
+#include <string>
+
+#include "supplicant.h"
+#include "iface.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 const char kBinderServiceName[];
+
+	static BinderManager * getInstance();
+	static void destroyInstance();
+	int registerBinderService(struct wpa_global *global);
+
+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 /* BINDER_MANAGER_H */

+ 16 - 0
wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl

@@ -0,0 +1,16 @@
+/*
+ * 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 {
+}

+ 19 - 0
wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl

@@ -0,0 +1,19 @@
+/*
+ * 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;
+
+/**
+ * Interface exposed by the wpa_supplicant binder service registered
+ * with the service manager with name: fi.w1.wpa_supplicant.
+ */
+interface ISupplicant {
+}

+ 20 - 0
wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl

@@ -0,0 +1,20 @@
+/*
+ * 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 {
+}

+ 19 - 0
wpa_supplicant/binder/iface.cpp

@@ -0,0 +1,19 @@
+/*
+ * 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 */

+ 42 - 0
wpa_supplicant/binder/iface.h

@@ -0,0 +1,42 @@
+/*
+ * 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 IFACE_H
+#define IFACE_H
+
+#include "fi/w1/wpa_supplicant/BnIface.h"
+
+extern "C" {
+#include "utils/includes.h"
+#include "utils/common.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 /* IFACE_H */

+ 19 - 0
wpa_supplicant/binder/supplicant.cpp

@@ -0,0 +1,19 @@
+/*
+ * 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"
+
+namespace wpa_supplicant_binder {
+
+Supplicant::Supplicant(struct wpa_global *global)
+	: wpa_global_(global)
+{
+}
+
+} /* namespace wpa_supplicant_binder */

+ 45 - 0
wpa_supplicant/binder/supplicant.h

@@ -0,0 +1,45 @@
+/*
+ * 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 SUPPLICANT_H
+#define SUPPLICANT_H
+
+#include "fi/w1/wpa_supplicant/BnSupplicant.h"
+#include "fi/w1/wpa_supplicant/ISupplicantCallbacks.h"
+
+extern "C" {
+#include "utils/includes.h"
+#include "utils/common.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;
+
+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 /* SUPPLICANT_H */

+ 12 - 0
wpa_supplicant/notify.c

@@ -13,6 +13,7 @@
 #include "config.h"
 #include "wpa_supplicant_i.h"
 #include "wps_supplicant.h"
+#include "binder/binder.h"
 #include "dbus/dbus_common.h"
 #include "dbus/dbus_old.h"
 #include "dbus/dbus_new.h"
@@ -34,6 +35,12 @@ int wpas_notify_supplicant_initialized(struct wpa_global *global)
 	}
 #endif /* CONFIG_DBUS */
 
+#ifdef CONFIG_BINDER
+	global->binder = wpas_binder_init(global);
+	if (!global->binder)
+		return -1;
+#endif /* CONFIG_BINDER */
+
 	return 0;
 }
 
@@ -44,6 +51,11 @@ void wpas_notify_supplicant_deinitialized(struct wpa_global *global)
 	if (global->dbus)
 		wpas_dbus_deinit(global->dbus);
 #endif /* CONFIG_DBUS */
+
+#ifdef CONFIG_BINDER
+	if (global->binder)
+		wpas_binder_deinit(global->binder);
+#endif /* CONFIG_BINDER */
 }
 
 

+ 2 - 0
wpa_supplicant/wpa_supplicant_i.h

@@ -44,6 +44,7 @@ struct wpa_driver_associate_params;
 struct ctrl_iface_priv;
 struct ctrl_iface_global_priv;
 struct wpas_dbus_priv;
+struct wpas_binder_priv;
 
 /**
  * struct wpa_interface - Parameters for wpa_supplicant_add_iface()
@@ -264,6 +265,7 @@ struct wpa_global {
 	struct wpa_params params;
 	struct ctrl_iface_global_priv *ctrl_iface;
 	struct wpas_dbus_priv *dbus;
+	struct wpas_binder_priv *binder;
 	void **drv_priv;
 	size_t drv_count;
 	struct os_time suspend_time;