blob: eb6006c56904630a18d08d489f322d111dc2e478 [file] [log] [blame]
Dmitry Shmidte4663042016-04-04 10:07:49 -07001/*
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>
Dmitry Shmidte4663042016-04-04 10:07:49 -070011#include <binder/IServiceManager.h>
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070012#include <binder/ProcessState.h>
Dmitry Shmidte4663042016-04-04 10:07:49 -070013
14#include "binder_manager.h"
15
16extern "C" {
Dmitry Shmidte4663042016-04-04 10:07:49 -070017#include "binder.h"
18#include "binder_i.h"
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070019#include "utils/common.h"
20#include "utils/eloop.h"
21#include "utils/includes.h"
Dmitry Shmidte4663042016-04-04 10:07:49 -070022}
23
24void wpas_binder_sock_handler(int sock, void *eloop_ctx, void *sock_ctx)
25{
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070026 struct wpa_global *global = (wpa_global *)eloop_ctx;
27 struct wpas_binder_priv *priv = (wpas_binder_priv *)sock_ctx;
Dmitry Shmidte4663042016-04-04 10:07:49 -070028
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070029 wpa_printf(
30 MSG_DEBUG, "Processing binder events on FD %d", priv->binder_fd);
Dmitry Shmidte4663042016-04-04 10:07:49 -070031 android::IPCThreadState::self()->handlePolledCommands();
32}
33
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070034struct wpas_binder_priv *wpas_binder_init(struct wpa_global *global)
Dmitry Shmidte4663042016-04-04 10:07:49 -070035{
36 struct wpas_binder_priv *priv;
37 wpa_supplicant_binder::BinderManager *binder_manager;
38
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070039 priv = (wpas_binder_priv *)os_zalloc(sizeof(*priv));
Dmitry Shmidte4663042016-04-04 10:07:49 -070040 if (!priv)
41 return NULL;
42 priv->global = global;
43
Roshan Pius54e763a2016-07-06 15:41:53 -070044 wpa_printf(MSG_DEBUG, "Initing binder control");
45
Dmitry Shmidte4663042016-04-04 10:07:49 -070046 android::ProcessState::self()->setThreadPoolMaxThreadCount(0);
47 android::IPCThreadState::self()->disableBackgroundScheduling(true);
48 android::IPCThreadState::self()->setupPolling(&priv->binder_fd);
Dmitry Shmidte4663042016-04-04 10:07:49 -070049 if (priv->binder_fd < 0)
50 goto err;
Roshan Pius54e763a2016-07-06 15:41:53 -070051
52 wpa_printf(
53 MSG_INFO, "Processing binder events on FD %d", priv->binder_fd);
Dmitry Shmidte4663042016-04-04 10:07:49 -070054 /* Look for read events from the binder socket in the eloop. */
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070055 if (eloop_register_read_sock(
56 priv->binder_fd, wpas_binder_sock_handler, global, priv) < 0)
Dmitry Shmidte4663042016-04-04 10:07:49 -070057 goto err;
58
59 binder_manager = wpa_supplicant_binder::BinderManager::getInstance();
60 if (!binder_manager)
61 goto err;
62 binder_manager->registerBinderService(global);
63 /* We may not need to store this binder manager reference in the
64 * global data strucure because we've made it a singleton class. */
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070065 priv->binder_manager = (void *)binder_manager;
Dmitry Shmidte4663042016-04-04 10:07:49 -070066
67 return priv;
68
69err:
70 wpas_binder_deinit(priv);
71 return NULL;
72}
73
Dmitry Shmidte4663042016-04-04 10:07:49 -070074void wpas_binder_deinit(struct wpas_binder_priv *priv)
75{
76 if (!priv)
77 return;
78
Roshan Pius54e763a2016-07-06 15:41:53 -070079 wpa_printf(MSG_DEBUG, "Deiniting binder control");
80
Dmitry Shmidte4663042016-04-04 10:07:49 -070081 wpa_supplicant_binder::BinderManager::destroyInstance();
82 eloop_unregister_read_sock(priv->binder_fd);
83 android::IPCThreadState::shutdown();
84}
85
Dmitry Shmidte4663042016-04-04 10:07:49 -070086int wpas_binder_register_interface(struct wpa_supplicant *wpa_s)
87{
88 if (!wpa_s->global->binder)
89 return 1;
90
Roshan Pius54e763a2016-07-06 15:41:53 -070091 wpa_printf(
92 MSG_DEBUG, "Registering interface to binder control: %s",
93 wpa_s->ifname);
94
Dmitry Shmidte4663042016-04-04 10:07:49 -070095 wpa_supplicant_binder::BinderManager *binder_manager =
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070096 wpa_supplicant_binder::BinderManager::getInstance();
Dmitry Shmidte4663042016-04-04 10:07:49 -070097 if (!binder_manager)
98 return 1;
99
100 return binder_manager->registerInterface(wpa_s);
101}
102
Dmitry Shmidte4663042016-04-04 10:07:49 -0700103int wpas_binder_unregister_interface(struct wpa_supplicant *wpa_s)
104{
105 if (!wpa_s->global->binder)
106 return 1;
107
Roshan Pius54e763a2016-07-06 15:41:53 -0700108 wpa_printf(
109 MSG_DEBUG, "Deregistering interface from binder control: %s",
110 wpa_s->ifname);
111
Dmitry Shmidte4663042016-04-04 10:07:49 -0700112 wpa_supplicant_binder::BinderManager *binder_manager =
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -0700113 wpa_supplicant_binder::BinderManager::getInstance();
Dmitry Shmidte4663042016-04-04 10:07:49 -0700114 if (!binder_manager)
115 return 1;
116
117 return binder_manager->unregisterInterface(wpa_s);
118}