binder: Add binder skeletal code for Android
authorRoshan Pius <rpius@google.com>
Wed, 17 Feb 2016 00:39:28 +0000 (16:39 -0800)
committerJouni Malinen <j@w1.fi>
Sat, 2 Apr 2016 14:35:26 +0000 (17:35 +0300)
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>
16 files changed:
wpa_supplicant/Android.mk
wpa_supplicant/android.config
wpa_supplicant/binder/binder.cpp [new file with mode: 0644]
wpa_supplicant/binder/binder.h [new file with mode: 0644]
wpa_supplicant/binder/binder_i.h [new file with mode: 0644]
wpa_supplicant/binder/binder_manager.cpp [new file with mode: 0644]
wpa_supplicant/binder/binder_manager.h [new file with mode: 0644]
wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl [new file with mode: 0644]
wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl [new file with mode: 0644]
wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl [new file with mode: 0644]
wpa_supplicant/binder/iface.cpp [new file with mode: 0644]
wpa_supplicant/binder/iface.h [new file with mode: 0644]
wpa_supplicant/binder/supplicant.cpp [new file with mode: 0644]
wpa_supplicant/binder/supplicant.h [new file with mode: 0644]
wpa_supplicant/notify.c
wpa_supplicant/wpa_supplicant_i.h

index cd64e4a..f65076c 100644 (file)
@@ -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)
 
 ########################
index 190bc5a..0a8bf98 100644 (file)
@@ -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).
diff --git a/wpa_supplicant/binder/binder.cpp b/wpa_supplicant/binder/binder.cpp
new file mode 100644 (file)
index 0000000..59ee9a5
--- /dev/null
@@ -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();
+}
diff --git a/wpa_supplicant/binder/binder.h b/wpa_supplicant/binder/binder.h
new file mode 100644 (file)
index 0000000..6406f09
--- /dev/null
@@ -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 */
diff --git a/wpa_supplicant/binder/binder_i.h b/wpa_supplicant/binder/binder_i.h
new file mode 100644 (file)
index 0000000..e8087b6
--- /dev/null
@@ -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 */
diff --git a/wpa_supplicant/binder/binder_manager.cpp b/wpa_supplicant/binder/binder_manager.cpp
new file mode 100644 (file)
index 0000000..9c35b23
--- /dev/null
@@ -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 */
diff --git a/wpa_supplicant/binder/binder_manager.h b/wpa_supplicant/binder/binder_manager.h
new file mode 100644 (file)
index 0000000..011fa3e
--- /dev/null
@@ -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 */
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl
new file mode 100644 (file)
index 0000000..ea11d42
--- /dev/null
@@ -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 {
+}
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl
new file mode 100644 (file)
index 0000000..5be2391
--- /dev/null
@@ -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 {
+}
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl
new file mode 100644 (file)
index 0000000..d624d91
--- /dev/null
@@ -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 {
+}
diff --git a/wpa_supplicant/binder/iface.cpp b/wpa_supplicant/binder/iface.cpp
new file mode 100644 (file)
index 0000000..af2548d
--- /dev/null
@@ -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 */
diff --git a/wpa_supplicant/binder/iface.h b/wpa_supplicant/binder/iface.h
new file mode 100644 (file)
index 0000000..acc8e55
--- /dev/null
@@ -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 */
diff --git a/wpa_supplicant/binder/supplicant.cpp b/wpa_supplicant/binder/supplicant.cpp
new file mode 100644 (file)
index 0000000..053f329
--- /dev/null
@@ -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 */
diff --git a/wpa_supplicant/binder/supplicant.h b/wpa_supplicant/binder/supplicant.h
new file mode 100644 (file)
index 0000000..02b5918
--- /dev/null
@@ -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 */
index 325883d..e739363 100644 (file)
@@ -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 */
 }
 
 
index ef14616..255dcc3 100644 (file)
@@ -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;