xref: /dragonfly/contrib/wpa_supplicant/wpa_supplicant/binder/binder.cpp (revision 3a84a4273475ed07d0ab1c2dfeffdfedef35d9cd)
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