Home | History | Annotate | Download | only in binder
      1 /*
      2  * binder interface for wpa_supplicant daemon
      3  * Copyright (c) 2004-2016, Jouni Malinen <j (at) w1.fi>
      4  * Copyright (c) 2004-2016, Roshan Pius <rpius (at) google.com>
      5  *
      6  * This software may be distributed under the terms of the BSD license.
      7  * See README for more details.
      8  */
      9 
     10 #include <binder/IPCThreadState.h>
     11 #include <binder/ProcessState.h>
     12 #include <binder/IServiceManager.h>
     13 
     14 #include "binder_manager.h"
     15 
     16 extern "C" {
     17 #include "utils/includes.h"
     18 #include "utils/common.h"
     19 #include "utils/eloop.h"
     20 #include "binder.h"
     21 #include "binder_i.h"
     22 }
     23 
     24 void wpas_binder_sock_handler(int sock, void *eloop_ctx, void *sock_ctx)
     25 {
     26 	struct wpa_global *global = (wpa_global *) eloop_ctx;
     27 	struct wpas_binder_priv *priv = (wpas_binder_priv *) sock_ctx;
     28 
     29 	wpa_printf(MSG_DEBUG, "Processing binder events on FD %d",
     30 		   priv->binder_fd);
     31 	android::IPCThreadState::self()->handlePolledCommands();
     32 }
     33 
     34 
     35 struct wpas_binder_priv * wpas_binder_init(struct wpa_global *global)
     36 {
     37 	struct wpas_binder_priv *priv;
     38 	wpa_supplicant_binder::BinderManager *binder_manager;
     39 
     40 	priv = (wpas_binder_priv *) os_zalloc(sizeof(*priv));
     41 	if (!priv)
     42 		return NULL;
     43 	priv->global = global;
     44 
     45 	android::ProcessState::self()->setThreadPoolMaxThreadCount(0);
     46 	android::IPCThreadState::self()->disableBackgroundScheduling(true);
     47 	android::IPCThreadState::self()->setupPolling(&priv->binder_fd);
     48 	wpa_printf(MSG_INFO, "Process binder events on FD %d", priv->binder_fd);
     49 	if (priv->binder_fd < 0)
     50 		goto err;
     51 	/* Look for read events from the binder socket in the eloop. */
     52 	if (eloop_register_read_sock(priv->binder_fd, wpas_binder_sock_handler,
     53 				     global, priv) < 0)
     54 		goto err;
     55 
     56 	binder_manager = wpa_supplicant_binder::BinderManager::getInstance();
     57 	if (!binder_manager)
     58 		goto err;
     59 	binder_manager->registerBinderService(global);
     60 	/* We may not need to store this binder manager reference in the
     61 	 * global data strucure because we've made it a singleton class. */
     62 	priv->binder_manager = (void *) binder_manager;
     63 
     64 	return priv;
     65 
     66 err:
     67 	wpas_binder_deinit(priv);
     68 	return NULL;
     69 }
     70 
     71 
     72 void wpas_binder_deinit(struct wpas_binder_priv *priv)
     73 {
     74 	if (!priv)
     75 		return;
     76 
     77 	wpa_supplicant_binder::BinderManager::destroyInstance();
     78 	eloop_unregister_read_sock(priv->binder_fd);
     79 	android::IPCThreadState::shutdown();
     80 }
     81 
     82 
     83 int wpas_binder_register_interface(struct wpa_supplicant *wpa_s)
     84 {
     85 	if (!wpa_s->global->binder)
     86 		return 1;
     87 
     88 	wpa_supplicant_binder::BinderManager *binder_manager =
     89 		wpa_supplicant_binder::BinderManager::getInstance();
     90 	if (!binder_manager)
     91 		return 1;
     92 
     93 	return binder_manager->registerInterface(wpa_s);
     94 }
     95 
     96 
     97 int wpas_binder_unregister_interface(struct wpa_supplicant *wpa_s)
     98 {
     99 	if (!wpa_s->global->binder)
    100 		return 1;
    101 
    102 	wpa_supplicant_binder::BinderManager *binder_manager =
    103 		wpa_supplicant_binder::BinderManager::getInstance();
    104 	if (!binder_manager)
    105 		return 1;
    106 
    107 	return binder_manager->unregisterInterface(wpa_s);
    108 }
    109