blob: d85f2cfa85ef48c2c93b8103039f678e5ddf8a6d [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
Dmitry Shmidte4663042016-04-04 10:07:49 -070010#include "supplicant.h"
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070011#include "binder_manager.h"
Dmitry Shmidte4663042016-04-04 10:07:49 -070012
13namespace wpa_supplicant_binder {
14
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070015Supplicant::Supplicant(struct wpa_global *global) : wpa_global_(global) {}
Dmitry Shmidte4663042016-04-04 10:07:49 -070016
17android::binder::Status Supplicant::CreateInterface(
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070018 const android::os::PersistableBundle &params,
19 android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return)
Dmitry Shmidte4663042016-04-04 10:07:49 -070020{
21 android::String16 driver, ifname, confname, bridge_ifname;
22
23 /* Check if required Ifname argument is missing */
24 if (!params.getString(android::String16("Ifname"), &ifname))
Roshan Piusd6e37512016-07-07 13:20:46 -070025 return android::binder::Status::fromExceptionCode(
26 android::binder::Status::EX_ILLEGAL_ARGUMENT,
27 "Ifname missing in params.");
Dmitry Shmidte4663042016-04-04 10:07:49 -070028 /* Retrieve the remaining params from the dictionary */
29 params.getString(android::String16("Driver"), &driver);
30 params.getString(android::String16("ConfigFile"), &confname);
31 params.getString(android::String16("BridgeIfname"), &bridge_ifname);
32
33 /*
34 * Try to get the wpa_supplicant record for this iface, return
35 * an error if we already control it.
36 */
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070037 if (wpa_supplicant_get_iface(
38 wpa_global_, android::String8(ifname).string()) != NULL)
Dmitry Shmidte4663042016-04-04 10:07:49 -070039 return android::binder::Status::fromServiceSpecificError(
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070040 ERROR_IFACE_EXISTS,
Roshan Piusd6e37512016-07-07 13:20:46 -070041 "wpa_supplicant already controls this interface.");
Dmitry Shmidte4663042016-04-04 10:07:49 -070042
43 android::binder::Status status;
44 struct wpa_supplicant *wpa_s = NULL;
45 struct wpa_interface iface;
46
47 os_memset(&iface, 0, sizeof(iface));
48 iface.driver = os_strdup(android::String8(driver).string());
49 iface.ifname = os_strdup(android::String8(ifname).string());
50 iface.confname = os_strdup(android::String8(confname).string());
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070051 iface.bridge_ifname =
52 os_strdup(android::String8(bridge_ifname).string());
Dmitry Shmidte4663042016-04-04 10:07:49 -070053 /* Otherwise, have wpa_supplicant attach to it. */
54 wpa_s = wpa_supplicant_add_iface(wpa_global_, &iface, NULL);
55 /* The supplicant core creates a corresponding binder object via
56 * BinderManager when |wpa_supplicant_add_iface| is called. */
57 if (!wpa_s || !wpa_s->binder_object_key) {
58 status = android::binder::Status::fromServiceSpecificError(
Roshan Piusd6e37512016-07-07 13:20:46 -070059 ERROR_GENERIC,
60 "wpa_supplicant couldn't grab this interface.");
Dmitry Shmidte4663042016-04-04 10:07:49 -070061 } else {
62 BinderManager *binder_manager = BinderManager::getInstance();
63
64 if (!binder_manager ||
65 binder_manager->getIfaceBinderObjectByKey(
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070066 wpa_s->binder_object_key, aidl_return))
67 status =
68 android::binder::Status::fromServiceSpecificError(
Roshan Piusd6e37512016-07-07 13:20:46 -070069 ERROR_GENERIC,
70 "wpa_supplicant encountered a binder error.");
Dmitry Shmidte4663042016-04-04 10:07:49 -070071 else
72 status = android::binder::Status::ok();
73 }
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070074 os_free((void *)iface.driver);
75 os_free((void *)iface.ifname);
76 os_free((void *)iface.confname);
77 os_free((void *)iface.bridge_ifname);
Dmitry Shmidte4663042016-04-04 10:07:49 -070078 return status;
79}
80
Dmitry Shmidte4663042016-04-04 10:07:49 -070081android::binder::Status Supplicant::RemoveInterface(const std::string &ifname)
82{
83 struct wpa_supplicant *wpa_s;
84
85 wpa_s = wpa_supplicant_get_iface(wpa_global_, ifname.c_str());
86 if (!wpa_s || !wpa_s->binder_object_key)
87 return android::binder::Status::fromServiceSpecificError(
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070088 ERROR_IFACE_UNKNOWN,
Roshan Piusd6e37512016-07-07 13:20:46 -070089 "wpa_supplicant does not control this interface.");
Dmitry Shmidte4663042016-04-04 10:07:49 -070090 if (wpa_supplicant_remove_iface(wpa_global_, wpa_s, 0))
91 return android::binder::Status::fromServiceSpecificError(
Roshan Piusd6e37512016-07-07 13:20:46 -070092 ERROR_GENERIC,
93 "wpa_supplicant couldn't remove this interface.");
Dmitry Shmidte4663042016-04-04 10:07:49 -070094 return android::binder::Status::ok();
95}
96
Dmitry Shmidte4663042016-04-04 10:07:49 -070097android::binder::Status Supplicant::GetInterface(
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070098 const std::string &ifname,
99 android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return)
Dmitry Shmidte4663042016-04-04 10:07:49 -0700100{
101 struct wpa_supplicant *wpa_s;
102
103 wpa_s = wpa_supplicant_get_iface(wpa_global_, ifname.c_str());
104 if (!wpa_s || !wpa_s->binder_object_key)
105 return android::binder::Status::fromServiceSpecificError(
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -0700106 ERROR_IFACE_UNKNOWN,
Roshan Piusd6e37512016-07-07 13:20:46 -0700107 "wpa_supplicant does not control this interface.");
Dmitry Shmidte4663042016-04-04 10:07:49 -0700108
109 BinderManager *binder_manager = BinderManager::getInstance();
110 if (!binder_manager ||
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -0700111 binder_manager->getIfaceBinderObjectByKey(
112 wpa_s->binder_object_key, aidl_return))
Dmitry Shmidte4663042016-04-04 10:07:49 -0700113 return android::binder::Status::fromServiceSpecificError(
Roshan Piusd6e37512016-07-07 13:20:46 -0700114 ERROR_GENERIC,
115 "wpa_supplicant encountered a binder error.");
Dmitry Shmidte4663042016-04-04 10:07:49 -0700116
117 return android::binder::Status::ok();
118}
119
120} /* namespace wpa_supplicant_binder */