1  /*
2   * binder interface for wpa_supplicant daemon
3   * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
4   * Copyright (c) 2004-2016, Roshan Pius <rpius@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  
wpas_binder_sock_handler(int sock,void * eloop_ctx,void * sock_ctx)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  
wpas_binder_init(struct wpa_global * global)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  
wpas_binder_deinit(struct wpas_binder_priv * priv)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  
wpas_binder_register_interface(struct wpa_supplicant * wpa_s)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  
wpas_binder_unregister_interface(struct wpa_supplicant * wpa_s)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