blob: 6b94aa171982d34b3cbec3a4759868ec3777e70d [file] [log] [blame]
Dmitry Shmidte4663042016-04-04 10:07:49 -07001/*
Roshan Pius57ffbcf2016-09-27 09:12:46 -07002 * hidl interface for wpa_supplicant daemon
Dmitry Shmidte4663042016-04-04 10:07:49 -07003 * 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
Roshan Pius57ffbcf2016-09-27 09:12:46 -070010#include "hidl_manager.h"
Roshan Pius7c0ebf22016-09-20 15:11:56 -070011#include "hidl_return_macros.h"
Dmitry Shmidte4663042016-04-04 10:07:49 -070012#include "iface.h"
13
Roshan Pius7c0ebf22016-09-20 15:11:56 -070014namespace android {
15namespace hardware {
16namespace wifi {
17namespace supplicant {
18namespace V1_0 {
19namespace implementation {
Roshan Pius8702ba92016-07-25 15:29:39 -070020
Roshan Pius54e763a2016-07-06 15:41:53 -070021Iface::Iface(struct wpa_global *wpa_global, const char ifname[])
22 : wpa_global_(wpa_global), ifname_(ifname)
23{
24}
Dmitry Shmidte4663042016-04-04 10:07:49 -070025
Roshan Pius7c0ebf22016-09-20 15:11:56 -070026Return<void> Iface::getName(getName_cb _hidl_cb)
Roshan Piusd6e37512016-07-07 13:20:46 -070027{
Roshan Piusd3854452016-07-07 16:46:41 -070028 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
Roshan Pius7c0ebf22016-09-20 15:11:56 -070029 if (!wpa_s) {
30 HIDL_RETURN(
31 SupplicantStatusCode::FAILURE_IFACE_INVALID, ifname_);
32 }
33
34 HIDL_RETURN(SupplicantStatusCode::SUCCESS, ifname_);
35}
36
37Return<void> Iface::addNetwork(addNetwork_cb _hidl_cb)
38{
39 android::sp<ISupplicantNetwork> network;
40 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
41 if (!wpa_s) {
42 HIDL_RETURN(
43 SupplicantStatusCode::FAILURE_IFACE_INVALID, network);
44 }
Roshan Piusd3854452016-07-07 16:46:41 -070045
Roshan Piusf745df82016-07-14 16:00:23 -070046 struct wpa_ssid *ssid = wpa_supplicant_add_network(wpa_s);
Roshan Piusd3854452016-07-07 16:46:41 -070047 if (!ssid) {
Roshan Pius7c0ebf22016-09-20 15:11:56 -070048 HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN, network);
Roshan Piusd3854452016-07-07 16:46:41 -070049 }
50
Roshan Pius57ffbcf2016-09-27 09:12:46 -070051 HidlManager *hidl_manager = HidlManager::getInstance();
52 if (!hidl_manager ||
53 hidl_manager->getNetworkHidlObjectByIfnameAndNetworkId(
Roshan Pius7c0ebf22016-09-20 15:11:56 -070054 wpa_s->ifname, ssid->id, &network)) {
55 HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN, network);
Roshan Piusd3854452016-07-07 16:46:41 -070056 }
Roshan Pius7c0ebf22016-09-20 15:11:56 -070057
58 HIDL_RETURN(SupplicantStatusCode::SUCCESS, network);
Roshan Piusd6e37512016-07-07 13:20:46 -070059}
60
Roshan Pius7c0ebf22016-09-20 15:11:56 -070061Return<void> Iface::removeNetwork(uint32_t id, removeNetwork_cb _hidl_cb)
Roshan Piusd6e37512016-07-07 13:20:46 -070062{
Roshan Piusd3854452016-07-07 16:46:41 -070063 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
Roshan Pius7c0ebf22016-09-20 15:11:56 -070064 if (!wpa_s) {
65 HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
66 }
Roshan Piusd3854452016-07-07 16:46:41 -070067
Roshan Pius7c0ebf22016-09-20 15:11:56 -070068 int result = wpa_supplicant_remove_network(wpa_s, id);
Roshan Piusf745df82016-07-14 16:00:23 -070069 if (result == -1) {
Roshan Pius7c0ebf22016-09-20 15:11:56 -070070 HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN);
Roshan Piusd3854452016-07-07 16:46:41 -070071 }
Roshan Piusf745df82016-07-14 16:00:23 -070072
Roshan Pius7c0ebf22016-09-20 15:11:56 -070073 if (result != 0) {
74 HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
Roshan Piusd3854452016-07-07 16:46:41 -070075 }
Roshan Pius7c0ebf22016-09-20 15:11:56 -070076
77 HIDL_RETURN(SupplicantStatusCode::SUCCESS);
Roshan Piusd3854452016-07-07 16:46:41 -070078}
79
Roshan Pius7c0ebf22016-09-20 15:11:56 -070080Return<void> Iface::getNetwork(uint32_t id, getNetwork_cb _hidl_cb)
Roshan Piusd3854452016-07-07 16:46:41 -070081{
Roshan Pius7c0ebf22016-09-20 15:11:56 -070082 android::sp<ISupplicantNetwork> network;
Roshan Piusd3854452016-07-07 16:46:41 -070083 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
Roshan Pius7c0ebf22016-09-20 15:11:56 -070084 if (!wpa_s) {
85 HIDL_RETURN(
86 SupplicantStatusCode::FAILURE_IFACE_INVALID, network);
87 }
Roshan Piusd3854452016-07-07 16:46:41 -070088
Roshan Pius7c0ebf22016-09-20 15:11:56 -070089 struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, id);
Roshan Piusd3854452016-07-07 16:46:41 -070090 if (!ssid) {
Roshan Pius7c0ebf22016-09-20 15:11:56 -070091 HIDL_RETURN(
92 SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, network);
Roshan Piusd3854452016-07-07 16:46:41 -070093 }
94
Roshan Pius57ffbcf2016-09-27 09:12:46 -070095 HidlManager *hidl_manager = HidlManager::getInstance();
96 if (!hidl_manager ||
97 hidl_manager->getNetworkHidlObjectByIfnameAndNetworkId(
Roshan Pius7c0ebf22016-09-20 15:11:56 -070098 wpa_s->ifname, ssid->id, &network)) {
99 HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN, network);
Roshan Piusd3854452016-07-07 16:46:41 -0700100 }
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700101
102 HIDL_RETURN(SupplicantStatusCode::SUCCESS, network);
Roshan Piusd6e37512016-07-07 13:20:46 -0700103}
104
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700105Return<void> Iface::listNetworks(listNetworks_cb _hidl_cb)
106{
107 std::vector<uint32_t> network_ids;
108
109 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
110 if (!wpa_s) {
111 HIDL_RETURN(
112 SupplicantStatusCode::FAILURE_IFACE_INVALID, network_ids);
113 }
114
115 for (struct wpa_ssid *wpa_ssid = wpa_s->conf->ssid; wpa_ssid;
116 wpa_ssid = wpa_ssid->next) {
117 network_ids.emplace_back(wpa_ssid->id);
118 }
119
120 HIDL_RETURN(SupplicantStatusCode::SUCCESS, network_ids);
121}
122
123Return<void> Iface::registerCallback(
124 const sp<ISupplicantIfaceCallback> &callback, registerCallback_cb _hidl_cb)
Roshan Pius0470cc82016-07-14 16:37:07 -0700125{
126 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700127 if (!wpa_s) {
128 HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
129 }
Roshan Pius8702ba92016-07-25 15:29:39 -0700130
Roshan Pius57ffbcf2016-09-27 09:12:46 -0700131 HidlManager *hidl_manager = HidlManager::getInstance();
132 if (!hidl_manager ||
133 hidl_manager->addIfaceCallbackHidlObject(ifname_, callback)) {
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700134 HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
Roshan Pius0470cc82016-07-14 16:37:07 -0700135 }
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700136
137 HIDL_RETURN(SupplicantStatusCode::SUCCESS);
Roshan Pius0470cc82016-07-14 16:37:07 -0700138}
139
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700140Return<void> Iface::reassociate(reassociate_cb _hidl_cb)
Roshan Piusf4e46cf2016-08-09 15:42:42 -0700141{
142 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700143 if (!wpa_s) {
144 HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
145 }
Roshan Piusf4e46cf2016-08-09 15:42:42 -0700146
147 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700148 HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
Roshan Piusf4e46cf2016-08-09 15:42:42 -0700149 }
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700150
151 HIDL_RETURN(SupplicantStatusCode::SUCCESS);
Roshan Piusf4e46cf2016-08-09 15:42:42 -0700152}
153
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700154Return<void> Iface::reconnect(reconnect_cb _hidl_cb)
Roshan Piusf4e46cf2016-08-09 15:42:42 -0700155{
156 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700157 if (!wpa_s) {
158 HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
159 }
Roshan Piusf4e46cf2016-08-09 15:42:42 -0700160
161 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700162 HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
Roshan Piusf4e46cf2016-08-09 15:42:42 -0700163 }
164 if (!wpa_s->disconnected) {
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700165 HIDL_RETURN(
166 SupplicantStatusCode::FAILURE_IFACE_NOT_DISCONNECTED);
Roshan Piusf4e46cf2016-08-09 15:42:42 -0700167 }
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700168
Roshan Piusf4e46cf2016-08-09 15:42:42 -0700169 wpas_request_connection(wpa_s);
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700170
171 HIDL_RETURN(SupplicantStatusCode::SUCCESS);
Roshan Piusf4e46cf2016-08-09 15:42:42 -0700172}
173
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700174Return<void> Iface::disconnect(disconnect_cb _hidl_cb)
Roshan Piusf4e46cf2016-08-09 15:42:42 -0700175{
176 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700177 if (!wpa_s) {
178 HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
179 }
Roshan Piusf4e46cf2016-08-09 15:42:42 -0700180
181 if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700182 HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
Roshan Piusf4e46cf2016-08-09 15:42:42 -0700183 }
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700184
Roshan Piusf4e46cf2016-08-09 15:42:42 -0700185 wpas_request_disconnection(wpa_s);
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700186
187 HIDL_RETURN(SupplicantStatusCode::SUCCESS);
Roshan Piusf4e46cf2016-08-09 15:42:42 -0700188}
189
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700190Return<void> Iface::setPowerSave(bool enable, setPowerSave_cb _hidl_cb)
Roshan Pius390ba282016-08-18 12:32:25 -0700191{
192 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700193 if (!wpa_s) {
194 HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
195 }
196
Roshan Pius390ba282016-08-18 12:32:25 -0700197 if (wpa_drv_set_p2p_powersave(wpa_s, enable, -1, -1)) {
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700198 HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
Roshan Pius390ba282016-08-18 12:32:25 -0700199 }
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700200
201 HIDL_RETURN(SupplicantStatusCode::SUCCESS);
Roshan Pius390ba282016-08-18 12:32:25 -0700202}
203
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700204Return<void> Iface::initiateTdlsDiscover(
205 const hidl_array<uint8_t, 6 /* 6 */> &mac_address,
206 initiateTdlsDiscover_cb _hidl_cb)
Roshan Pius390ba282016-08-18 12:32:25 -0700207{
208 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700209 if (!wpa_s) {
210 HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
Roshan Pius390ba282016-08-18 12:32:25 -0700211 }
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700212
213 if (!mac_address.data()) {
214 HIDL_RETURN(SupplicantStatusCode::FAILURE_ARGS_INVALID);
215 }
216
Roshan Pius390ba282016-08-18 12:32:25 -0700217 int ret;
218 const u8 *peer = mac_address.data();
219 if (wpa_tdls_is_external_setup(wpa_s->wpa)) {
220 ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer);
221 } else {
222 ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
223 }
224 if (ret) {
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700225 HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
Roshan Pius390ba282016-08-18 12:32:25 -0700226 }
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700227
228 HIDL_RETURN(SupplicantStatusCode::SUCCESS);
Roshan Pius390ba282016-08-18 12:32:25 -0700229}
230
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700231Return<void> Iface::initiateTdlsSetup(
232 const hidl_array<uint8_t, 6 /* 6 */> &mac_address,
233 initiateTdlsSetup_cb _hidl_cb)
Roshan Pius390ba282016-08-18 12:32:25 -0700234{
235 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700236 if (!wpa_s) {
237 HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
Roshan Pius390ba282016-08-18 12:32:25 -0700238 }
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700239
240 if (!mac_address.data()) {
241 HIDL_RETURN(SupplicantStatusCode::FAILURE_ARGS_INVALID);
242 }
243
Roshan Pius390ba282016-08-18 12:32:25 -0700244 int ret;
245 const u8 *peer = mac_address.data();
246 if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
247 !(wpa_s->conf->tdls_external_control)) {
248 wpa_tdls_remove(wpa_s->wpa, peer);
249 ret = wpa_tdls_start(wpa_s->wpa, peer);
250 } else {
251 ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
252 }
253 if (ret) {
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700254 HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
Roshan Pius390ba282016-08-18 12:32:25 -0700255 }
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700256
257 HIDL_RETURN(SupplicantStatusCode::SUCCESS);
Roshan Pius390ba282016-08-18 12:32:25 -0700258}
259
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700260Return<void> Iface::initiateTdlsTeardown(
261 const hidl_array<uint8_t, 6 /* 6 */> &mac_address,
262 initiateTdlsTeardown_cb _hidl_cb)
Roshan Pius390ba282016-08-18 12:32:25 -0700263{
264 struct wpa_supplicant *wpa_s = retrieveIfacePtr();
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700265 if (!wpa_s) {
266 HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
Roshan Pius390ba282016-08-18 12:32:25 -0700267 }
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700268
269 if (!mac_address.data()) {
270 HIDL_RETURN(SupplicantStatusCode::FAILURE_ARGS_INVALID);
271 }
272
Roshan Pius390ba282016-08-18 12:32:25 -0700273 int ret;
274 const u8 *peer = mac_address.data();
275 if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
276 !(wpa_s->conf->tdls_external_control)) {
277 ret = wpa_tdls_teardown_link(
278 wpa_s->wpa, peer, WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
279 } else {
280 ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
281 }
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700282
Roshan Pius390ba282016-08-18 12:32:25 -0700283 if (ret) {
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700284 HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
Roshan Pius390ba282016-08-18 12:32:25 -0700285 }
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700286
287 HIDL_RETURN(SupplicantStatusCode::SUCCESS);
Roshan Pius390ba282016-08-18 12:32:25 -0700288}
289
Roshan Pius54e763a2016-07-06 15:41:53 -0700290/**
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700291 * Retrieve the underlying |wpa_supplicant| struct
292 * pointer for this iface.
293 * If the underlying iface is removed, then all RPC method calls on this object
294 * will return failure.
Roshan Pius54e763a2016-07-06 15:41:53 -0700295 */
296wpa_supplicant *Iface::retrieveIfacePtr()
297{
298 return wpa_supplicant_get_iface(
299 (struct wpa_global *)wpa_global_, ifname_.c_str());
300}
Roshan Pius7c0ebf22016-09-20 15:11:56 -0700301
302} // namespace implementation
303} // namespace V1_0
304} // namespace wifi
305} // namespace supplicant
306} // namespace hardware
307} // namespace android