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>
This commit is contained in:
Roshan Pius 2016-02-16 16:39:28 -08:00 committed by Jouni Malinen
parent 5914ebf584
commit 7b4bbb9f94
16 changed files with 458 additions and 0 deletions

View 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)
########################

View 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).

View File

@ -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();
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 {
}

View File

@ -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 {
}

View File

@ -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 {
}

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View File

@ -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 */

View 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 */
}

View 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;