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. TEST: `mmm -j32 external/wpa_supplicant_8/wpa_supplicant` with CONFIG_CTRL_IFACE_BINDER=y. Signed-off-by: Roshan Pius <rpius@xxxxxxxxxx> Change-Id: Icfe066f23c1637a521dce450c049ee23bab836b5 --- wpa_supplicant/Android.mk | 14 ++++ wpa_supplicant/android.config | 4 ++ wpa_supplicant/binder/binder.cpp | 79 ++++++++++++++++++++++ wpa_supplicant/binder/binder.h | 32 +++++++++ wpa_supplicant/binder/binder_i.h | 27 ++++++++ wpa_supplicant/binder/binder_manager.cpp | 49 ++++++++++++++ wpa_supplicant/binder/binder_manager.h | 52 ++++++++++++++ .../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 | 39 +++++++++++ wpa_supplicant/binder/supplicant.cpp | 19 ++++++ wpa_supplicant/binder/supplicant.h | 42 ++++++++++++ wpa_supplicant/notify.c | 12 ++++ wpa_supplicant/wpa_supplicant_i.h | 2 + 16 files changed, 445 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 95690bf..eb23fdb 100644 --- a/wpa_supplicant/Android.mk +++ b/wpa_supplicant/Android.mk @@ -1336,6 +1336,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 @@ -1573,6 +1583,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 e9c0a01..90048d0 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_<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 index 0000000..86a9d30 --- /dev/null +++ b/wpa_supplicant/binder/binder.cpp @@ -0,0 +1,79 @@ +/* + * WPA Supplicant - binder interface for wpa_supplicant daemon + * Copyright (c) 2004-2016, Jouni Malinen <j@xxxxx> + * Copyright (c) 2004-2016, Roshan Pius <rpius@xxxxxxxxxx> + * + * 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 "fi/w1/wpa_supplicant1/IWpaSupplicantMain.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 == NULL) + 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 == NULL) + 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 == NULL) + 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..d12a502 --- /dev/null +++ b/wpa_supplicant/binder/binder.h @@ -0,0 +1,32 @@ +/* + * WPA Supplicant - binder interface for wpa_supplicant daemon + * Copyright (c) 2004-2016, Jouni Malinen <j@xxxxx> + * Copyright (c) 2004-2016, Roshan Pius <rpius@xxxxxxxxxx> + * + * 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..6937e93 --- /dev/null +++ b/wpa_supplicant/binder/binder_i.h @@ -0,0 +1,27 @@ +/* + * WPA Supplicant - binder interface for wpa_supplicant daemon + * Copyright (c) 2004-2016, Jouni Malinen <j@xxxxx> + * Copyright (c) 2004-2016, Roshan Pius <rpius@xxxxxxxxxx> + * + * 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..8517fd9 --- /dev/null +++ b/wpa_supplicant/binder/binder_manager.cpp @@ -0,0 +1,49 @@ +/* + * WPA Supplicant - binder interface for wpa_supplicant daemon + * Copyright (c) 2004-2016, Jouni Malinen <j@xxxxx> + * Copyright (c) 2004-2016, Roshan Pius <rpius@xxxxxxxxxx> + * + * 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_ == NULL) + instance_ = new BinderManager(); + return instance_; +} + +void BinderManager::destroyInstance() +{ + if (instance_ != NULL) + 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..2530619 --- /dev/null +++ b/wpa_supplicant/binder/binder_manager.h @@ -0,0 +1,52 @@ +/* + * WPA Supplicant - binder interface for wpa_supplicant daemon + * Copyright (c) 2004-2016, Jouni Malinen <j@xxxxx> + * Copyright (c) 2004-2016, Roshan Pius <rpius@xxxxxxxxxx> + * + * 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 index 0000000..e096109 --- /dev/null +++ b/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl @@ -0,0 +1,16 @@ +/* + * WPA Supplicant - binder interface for wpa_supplicant daemon + * Copyright (c) 2004-2016, Jouni Malinen <j@xxxxx> + * Copyright (c) 2004-2016, Roshan Pius <rpius@xxxxxxxxxx> + * + * 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 <j@xxxxx> + * Copyright (c) 2004-2016, Roshan Pius <rpius@xxxxxxxxxx> + * + * 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..0b05a00 --- /dev/null +++ b/wpa_supplicant/binder/fi/w1/wpa_supplicant/ISupplicantCallbacks.aidl @@ -0,0 +1,20 @@ +/* + * WPA Supplicant - binder interface for wpa_supplicant daemon + * Copyright (c) 2004-2016, Jouni Malinen <j@xxxxx> + * Copyright (c) 2004-2016, Roshan Pius <rpius@xxxxxxxxxx> + * + * 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..7b64c72 --- /dev/null +++ b/wpa_supplicant/binder/iface.cpp @@ -0,0 +1,19 @@ +/* + * WPA Supplicant - binder interface for wpa_supplicant daemon + * Copyright (c) 2004-2016, Jouni Malinen <j@xxxxx> + * Copyright (c) 2004-2016, Roshan Pius <rpius@xxxxxxxxxx> + * + * 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..901d709 --- /dev/null +++ b/wpa_supplicant/binder/iface.h @@ -0,0 +1,39 @@ +/* + * WPA Supplicant - binder interface for wpa_supplicant daemon + * Copyright (c) 2004-2016, Jouni Malinen <j@xxxxx> + * Copyright (c) 2004-2016, Roshan Pius <rpius@xxxxxxxxxx> + * + * 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..c6a625a --- /dev/null +++ b/wpa_supplicant/binder/supplicant.cpp @@ -0,0 +1,19 @@ +/* + * WPA Supplicant - binder interface for wpa_supplicant daemon + * Copyright (c) 2004-2016, Jouni Malinen <j@xxxxx> + * Copyright (c) 2004-2016, Roshan Pius <rpius@xxxxxxxxxx> + * + * 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..4983570 --- /dev/null +++ b/wpa_supplicant/binder/supplicant.h @@ -0,0 +1,42 @@ +/* + * WPA Supplicant - binder interface for wpa_supplicant daemon + * Copyright (c) 2004-2016, Jouni Malinen <j@xxxxx> + * Copyright (c) 2004-2016, Roshan Pius <rpius@xxxxxxxxxx> + * + * 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 */ diff --git a/wpa_supplicant/notify.c b/wpa_supplicant/notify.c index 45d06bf..6935102 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 == NULL) + 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 7b74f38..d049e8a 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() @@ -253,6 +254,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.7.0.rc3.207.g0ac5344 _______________________________________________ Hostap mailing list Hostap@xxxxxxxxxxxxxxxxxxx http://lists.infradead.org/mailman/listinfo/hostap