From 7b4bbb9f946fb6861b2b4ded0f10949277514047 Mon Sep 17 00:00:00 2001 From: Roshan Pius Date: Tue, 16 Feb 2016 16:39:28 -0800 Subject: [PATCH] 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 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 --- wpa_supplicant/Android.mk | 14 ++++ wpa_supplicant/android.config | 4 ++ wpa_supplicant/binder/binder.cpp | 80 ++++++++++++++++++++++ wpa_supplicant/binder/binder.h | 32 +++++++++ wpa_supplicant/binder/binder_i.h | 27 ++++++++ wpa_supplicant/binder/binder_manager.cpp | 53 ++++++++++++++ wpa_supplicant/binder/binder_manager.h | 54 +++++++++++++++ .../binder/fi/w1/wpa_supplicant/IIface.aidl | 16 +++++ .../binder/fi/w1/wpa_supplicant/ISupplicant.aidl | 19 +++++ .../fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl | 20 ++++++ wpa_supplicant/binder/iface.cpp | 19 +++++ wpa_supplicant/binder/iface.h | 42 ++++++++++++ wpa_supplicant/binder/supplicant.cpp | 19 +++++ wpa_supplicant/binder/supplicant.h | 45 ++++++++++++ wpa_supplicant/notify.c | 12 ++++ wpa_supplicant/wpa_supplicant_i.h | 2 + 16 files changed, 458 insertions(+) create mode 100644 wpa_supplicant/binder/binder.cpp create mode 100644 wpa_supplicant/binder/binder.h create mode 100644 wpa_supplicant/binder/binder_i.h create mode 100644 wpa_supplicant/binder/binder_manager.cpp create mode 100644 wpa_supplicant/binder/binder_manager.h create mode 100644 wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl create mode 100644 wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicant.aidl create mode 100644 wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl create mode 100644 wpa_supplicant/binder/iface.cpp create mode 100644 wpa_supplicant/binder/iface.h create mode 100644 wpa_supplicant/binder/supplicant.cpp create mode 100644 wpa_supplicant/binder/supplicant.h diff --git a/wpa_supplicant/Android.mk b/wpa_supplicant/Android.mk index cd64e4a..f65076c 100644 --- a/wpa_supplicant/Android.mk +++ b/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) ######################## diff --git a/wpa_supplicant/android.config b/wpa_supplicant/android.config index 190bc5a..0a8bf98 100644 --- a/wpa_supplicant/android.config +++ b/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_=y) or dynamically (CONFIG_EAP_=dyn). diff --git a/wpa_supplicant/binder/binder.cpp b/wpa_supplicant/binder/binder.cpp new file mode 100644 index 0000000..59ee9a5 --- /dev/null +++ b/wpa_supplicant/binder/binder.cpp @@ -0,0 +1,80 @@ +/* + * binder interface for wpa_supplicant daemon + * Copyright (c) 2004-2016, Jouni Malinen + * Copyright (c) 2004-2016, Roshan Pius + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include +#include +#include + +#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 index 0000000..6406f09 --- /dev/null +++ b/wpa_supplicant/binder/binder.h @@ -0,0 +1,32 @@ +/* + * binder interface for wpa_supplicant daemon + * Copyright (c) 2004-2016, Jouni Malinen + * Copyright (c) 2004-2016, Roshan Pius + * + * 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 index 0000000..e8087b6 --- /dev/null +++ b/wpa_supplicant/binder/binder_i.h @@ -0,0 +1,27 @@ +/* + * binder interface for wpa_supplicant daemon + * Copyright (c) 2004-2016, Jouni Malinen + * Copyright (c) 2004-2016, Roshan Pius + * + * 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 index 0000000..9c35b23 --- /dev/null +++ b/wpa_supplicant/binder/binder_manager.cpp @@ -0,0 +1,53 @@ +/* + * binder interface for wpa_supplicant daemon + * Copyright (c) 2004-2016, Jouni Malinen + * Copyright (c) 2004-2016, Roshan Pius + * + * This software may be distributed under the terms of the BSD license. + * See README for more details. + */ + +#include + +#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 index 0000000..011fa3e --- /dev/null +++ b/wpa_supplicant/binder/binder_manager.h @@ -0,0 +1,54 @@ +/* + * binder interface for wpa_supplicant daemon + * Copyright (c) 2004-2016, Jouni Malinen + * Copyright (c) 2004-2016, Roshan Pius + * + * 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 +#include + +#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_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> 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 index 0000000..ea11d42 --- /dev/null +++ b/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 + * Copyright (c) 2004-2016, Roshan Pius + * + * 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 index 0000000..5be2391 --- /dev/null +++ b/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 + * Copyright (c) 2004-2016, Roshan Pius + * + * 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 index 0000000..d624d91 --- /dev/null +++ b/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 + * Copyright (c) 2004-2016, Roshan Pius + * + * 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 index 0000000..af2548d --- /dev/null +++ b/wpa_supplicant/binder/iface.cpp @@ -0,0 +1,19 @@ +/* + * binder interface for wpa_supplicant daemon + * Copyright (c) 2004-2016, Jouni Malinen + * Copyright (c) 2004-2016, Roshan Pius + * + * 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 index 0000000..acc8e55 --- /dev/null +++ b/wpa_supplicant/binder/iface.h @@ -0,0 +1,42 @@ +/* + * binder interface for wpa_supplicant daemon + * Copyright (c) 2004-2016, Jouni Malinen + * Copyright (c) 2004-2016, Roshan Pius + * + * 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 index 0000000..053f329 --- /dev/null +++ b/wpa_supplicant/binder/supplicant.cpp @@ -0,0 +1,19 @@ +/* + * binder interface for wpa_supplicant daemon + * Copyright (c) 2004-2016, Jouni Malinen + * Copyright (c) 2004-2016, Roshan Pius + * + * 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 index 0000000..02b5918 --- /dev/null +++ b/wpa_supplicant/binder/supplicant.h @@ -0,0 +1,45 @@ +/* + * binder interface for wpa_supplicant daemon + * Copyright (c) 2004-2016, Jouni Malinen + * Copyright (c) 2004-2016, Roshan Pius + * + * 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> + callbacks_; +}; + +} /* namespace wpa_supplicant_binder */ + +#endif /* SUPPLICANT_H */ diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c index 325883d..e739363 100644 --- a/wpa_supplicant/notify.c +++ b/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 */ } diff --git a/wpa_supplicant/wpa_supplicant_i.h b/wpa_supplicant/wpa_supplicant_i.h index ef14616..255dcc3 100644 --- a/wpa_supplicant/wpa_supplicant_i.h +++ b/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; -- 2.1.4