blob: 258fa2bd76d6fae426a9e0b0e03e021fcb5dec84 [file] [log] [blame]
Roshan Pius57ffbcf2016-09-27 09:12:46 -07001/*
2 * hidl 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 <hidl/IPCThreadState.h>
11#include <hidl/IServiceManager.h>
12#include <hidl/ProcessState.h>
13
14#include "hidl_manager.h"
15
16extern "C" {
17#include "hidl.h"
18#include "hidl_i.h"
19#include "utils/common.h"
20#include "utils/eloop.h"
21#include "utils/includes.h"
22}
23
24void wpas_hidl_sock_handler(
25 int /* sock */, void * /* eloop_ctx */, void *sock_ctx)
26{
27 struct wpas_hidl_priv *priv = (wpas_hidl_priv *)sock_ctx;
28 wpa_printf(
29 MSG_DEBUG, "Processing hidl events on FD %d", priv->hidl_fd);
30 android::IPCThreadState::self()->handlePolledCommands();
31}
32
33struct wpas_hidl_priv *wpas_hidl_init(struct wpa_global *global)
34{
35 struct wpas_hidl_priv *priv;
36 wpa_supplicant_hidl::HidlManager *hidl_manager;
37
38 priv = (wpas_hidl_priv *)os_zalloc(sizeof(*priv));
39 if (!priv)
40 return NULL;
41 priv->global = global;
42
43 wpa_printf(MSG_DEBUG, "Initing hidl control");
44
45 android::ProcessState::self()->setThreadPoolMaxThreadCount(0);
46 android::IPCThreadState::self()->disableBackgroundScheduling(true);
47 android::IPCThreadState::self()->setupPolling(&priv->hidl_fd);
48 if (priv->hidl_fd < 0)
49 goto err;
50
51 wpa_printf(
52 MSG_INFO, "Processing hidl events on FD %d", priv->hidl_fd);
53 /* Look for read events from the hidl socket in the eloop. */
54 if (eloop_register_read_sock(
55 priv->hidl_fd, wpas_hidl_sock_handler, global, priv) < 0)
56 goto err;
57
58 hidl_manager = wpa_supplicant_hidl::HidlManager::getInstance();
59 if (!hidl_manager)
60 goto err;
61 hidl_manager->registerHidlService(global);
62 /* We may not need to store this hidl manager reference in the
63 * global data strucure because we've made it a singleton class. */
64 priv->hidl_manager = (void *)hidl_manager;
65
66 return priv;
67err:
68 wpas_hidl_deinit(priv);
69 return NULL;
70}
71
72void wpas_hidl_deinit(struct wpas_hidl_priv *priv)
73{
74 if (!priv)
75 return;
76
77 wpa_printf(MSG_DEBUG, "Deiniting hidl control");
78
79 wpa_supplicant_hidl::HidlManager::destroyInstance();
80 eloop_unregister_read_sock(priv->hidl_fd);
81 android::IPCThreadState::shutdown();
82 os_free(priv);
83}
84
85int wpas_hidl_register_interface(struct wpa_supplicant *wpa_s)
86{
87 if (!wpa_s || !wpa_s->global->hidl)
88 return 1;
89
90 wpa_printf(
91 MSG_DEBUG, "Registering interface to hidl control: %s",
92 wpa_s->ifname);
93
94 wpa_supplicant_hidl::HidlManager *hidl_manager =
95 wpa_supplicant_hidl::HidlManager::getInstance();
96 if (!hidl_manager)
97 return 1;
98
99 return hidl_manager->registerInterface(wpa_s);
100}
101
102int wpas_hidl_unregister_interface(struct wpa_supplicant *wpa_s)
103{
104 if (!wpa_s || !wpa_s->global->hidl)
105 return 1;
106
107 wpa_printf(
108 MSG_DEBUG, "Deregistering interface from hidl control: %s",
109 wpa_s->ifname);
110
111 wpa_supplicant_hidl::HidlManager *hidl_manager =
112 wpa_supplicant_hidl::HidlManager::getInstance();
113 if (!hidl_manager)
114 return 1;
115
116 return hidl_manager->unregisterInterface(wpa_s);
117}
118
119int wpas_hidl_register_network(
120 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
121{
122 if (!wpa_s || !wpa_s->global->hidl || !ssid)
123 return 1;
124
125 wpa_printf(
126 MSG_DEBUG, "Registering network to hidl control: %d", ssid->id);
127
128 wpa_supplicant_hidl::HidlManager *hidl_manager =
129 wpa_supplicant_hidl::HidlManager::getInstance();
130 if (!hidl_manager)
131 return 1;
132
133 return hidl_manager->registerNetwork(wpa_s, ssid);
134}
135
136int wpas_hidl_unregister_network(
137 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid)
138{
139 if (!wpa_s || !wpa_s->global->hidl || !ssid)
140 return 1;
141
142 wpa_printf(
143 MSG_DEBUG, "Deregistering network from hidl control: %d",
144 ssid->id);
145
146 wpa_supplicant_hidl::HidlManager *hidl_manager =
147 wpa_supplicant_hidl::HidlManager::getInstance();
148 if (!hidl_manager)
149 return 1;
150
151 return hidl_manager->unregisterNetwork(wpa_s, ssid);
152}
153
154int wpas_hidl_notify_state_changed(struct wpa_supplicant *wpa_s)
155{
156 if (!wpa_s || !wpa_s->global->hidl)
157 return 1;
158
159 wpa_printf(
160 MSG_DEBUG, "Notifying state change event to hidl control: %d",
161 wpa_s->wpa_state);
162
163 wpa_supplicant_hidl::HidlManager *hidl_manager =
164 wpa_supplicant_hidl::HidlManager::getInstance();
165 if (!hidl_manager)
166 return 1;
167
168 return hidl_manager->notifyStateChange(wpa_s);
169}
170
171int wpas_hidl_notify_network_request(
172 struct wpa_supplicant *wpa_s, struct wpa_ssid *ssid,
173 enum wpa_ctrl_req_type rtype, const char *default_txt)
174{
175 if (!wpa_s || !wpa_s->global->hidl || !ssid)
176 return 1;
177
178 wpa_printf(
179 MSG_DEBUG, "Notifying network request to hidl control: %d",
180 ssid->id);
181
182 wpa_supplicant_hidl::HidlManager *hidl_manager =
183 wpa_supplicant_hidl::HidlManager::getInstance();
184 if (!hidl_manager)
185 return 1;
186
187 return hidl_manager->notifyNetworkRequest(
188 wpa_s, ssid, rtype, default_txt);
189}