Home | History | Annotate | Line # | 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/IServiceManager.h>
     12 #include <binder/ProcessState.h>
     13 
     14 #include "binder_manager.h"
     15 
     16 extern "C" {
     17 #include "binder.h"
     18 #include "binder_i.h"
     19 #include "utils/common.h"
     20 #include "utils/eloop.h"
     21 #include "utils/includes.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(
     30 	    MSG_DEBUG, "Processing binder events on FD %d", priv->binder_fd);
     31 	android::IPCThreadState::self()->handlePolledCommands();
     32 }
     33 
     34 struct wpas_binder_priv *wpas_binder_init(struct wpa_global *global)
     35 {
     36 	struct wpas_binder_priv *priv;
     37 	wpa_supplicant_binder::BinderManager *binder_manager;
     38 
     39 	priv = (wpas_binder_priv *)os_zalloc(sizeof(*priv));
     40 	if (!priv)
     41 		return NULL;
     42 	priv->global = global;
     43 
     44 	android::ProcessState::self()->setThreadPoolMaxThreadCount(0);
     45 	android::IPCThreadState::self()->disableBackgroundScheduling(true);
     46 	android::IPCThreadState::self()->setupPolling(&priv->binder_fd);
     47 	wpa_printf(MSG_INFO, "Process binder events on FD %d", priv->binder_fd);
     48 	if (priv->binder_fd < 0)
     49 		goto err;
     50 	/* Look for read events from the binder socket in the eloop. */
     51 	if (eloop_register_read_sock(
     52 		priv->binder_fd, wpas_binder_sock_handler, global, priv) < 0)
     53 		goto err;
     54 
     55 	binder_manager = wpa_supplicant_binder::BinderManager::getInstance();
     56 	if (!binder_manager)
     57 		goto err;
     58 	binder_manager->registerBinderService(global);
     59 	/* We may not need to store this binder manager reference in the
     60 	 * global data strucure because we've made it a singleton class. */
     61 	priv->binder_manager = (void *)binder_manager;
     62 
     63 	return priv;
     64 
     65 err:
     66 	wpas_binder_deinit(priv);
     67 	return NULL;
     68 }
     69 
     70 void wpas_binder_deinit(struct wpas_binder_priv *priv)
     71 {
     72 	if (!priv)
     73 		return;
     74 
     75 	wpa_supplicant_binder::BinderManager::destroyInstance();
     76 	eloop_unregister_read_sock(priv->binder_fd);
     77 	android::IPCThreadState::shutdown();
     78 }
     79 
     80 int wpas_binder_register_interface(struct wpa_supplicant *wpa_s)
     81 {
     82 	if (!wpa_s->global->binder)
     83 		return 1;
     84 
     85 	wpa_supplicant_binder::BinderManager *binder_manager =
     86 	    wpa_supplicant_binder::BinderManager::getInstance();
     87 	if (!binder_manager)
     88 		return 1;
     89 
     90 	return binder_manager->registerInterface(wpa_s);
     91 }
     92 
     93 int wpas_binder_unregister_interface(struct wpa_supplicant *wpa_s)
     94 {
     95 	if (!wpa_s->global->binder)
     96 		return 1;
     97 
     98 	wpa_supplicant_binder::BinderManager *binder_manager =
     99 	    wpa_supplicant_binder::BinderManager::getInstance();
    100 	if (!binder_manager)
    101 		return 1;
    102 
    103 	return binder_manager->unregisterInterface(wpa_s);
    104 }
    105