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/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 
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(MSG_DEBUG, "Processing binder events on FD %d",
30 		   priv->binder_fd);
31 	android::IPCThreadState::self()->handlePolledCommands();
32 }
33 
34 
wpas_binder_init(struct wpa_global * global)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 
wpas_binder_deinit(struct wpas_binder_priv * priv)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 
wpas_binder_register_interface(struct wpa_supplicant * wpa_s)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 
wpas_binder_unregister_interface(struct wpa_supplicant * wpa_s)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