blob: 5a0db75fcb990923fb9074ba388d2ef386059ff7 [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 */
Roshan Pius32c15e22016-07-07 13:46:39 -070024 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.");
Roshan Pius32c15e22016-07-07 13:46:39 -070028 }
Dmitry Shmidte4663042016-04-04 10:07:49 -070029 /* Retrieve the remaining params from the dictionary */
30 params.getString(android::String16("Driver"), &driver);
31 params.getString(android::String16("ConfigFile"), &confname);
32 params.getString(android::String16("BridgeIfname"), &bridge_ifname);
33
34 /*
35 * Try to get the wpa_supplicant record for this iface, return
36 * an error if we already control it.
37 */
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070038 if (wpa_supplicant_get_iface(
Roshan Pius32c15e22016-07-07 13:46:39 -070039 wpa_global_, android::String8(ifname).string()) != NULL) {
Dmitry Shmidte4663042016-04-04 10:07:49 -070040 return android::binder::Status::fromServiceSpecificError(
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070041 ERROR_IFACE_EXISTS,
Roshan Piusd6e37512016-07-07 13:20:46 -070042 "wpa_supplicant already controls this interface.");
Roshan Pius32c15e22016-07-07 13:46:39 -070043 }
Dmitry Shmidte4663042016-04-04 10:07:49 -070044
45 android::binder::Status status;
46 struct wpa_supplicant *wpa_s = NULL;
47 struct wpa_interface iface;
48
49 os_memset(&iface, 0, sizeof(iface));
50 iface.driver = os_strdup(android::String8(driver).string());
51 iface.ifname = os_strdup(android::String8(ifname).string());
52 iface.confname = os_strdup(android::String8(confname).string());
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070053 iface.bridge_ifname =
54 os_strdup(android::String8(bridge_ifname).string());
Dmitry Shmidte4663042016-04-04 10:07:49 -070055 /* Otherwise, have wpa_supplicant attach to it. */
56 wpa_s = wpa_supplicant_add_iface(wpa_global_, &iface, NULL);
57 /* The supplicant core creates a corresponding binder object via
58 * BinderManager when |wpa_supplicant_add_iface| is called. */
Roshan Pius32c15e22016-07-07 13:46:39 -070059 if (!wpa_s) {
Dmitry Shmidte4663042016-04-04 10:07:49 -070060 status = android::binder::Status::fromServiceSpecificError(
Roshan Piusd6e37512016-07-07 13:20:46 -070061 ERROR_GENERIC,
62 "wpa_supplicant couldn't grab this interface.");
Dmitry Shmidte4663042016-04-04 10:07:49 -070063 } else {
64 BinderManager *binder_manager = BinderManager::getInstance();
65
66 if (!binder_manager ||
Roshan Pius32c15e22016-07-07 13:46:39 -070067 binder_manager->getIfaceBinderObjectByIfname(
68 wpa_s->ifname, aidl_return)) {
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070069 status =
70 android::binder::Status::fromServiceSpecificError(
Roshan Piusd6e37512016-07-07 13:20:46 -070071 ERROR_GENERIC,
72 "wpa_supplicant encountered a binder error.");
Roshan Pius32c15e22016-07-07 13:46:39 -070073 } else {
Dmitry Shmidte4663042016-04-04 10:07:49 -070074 status = android::binder::Status::ok();
Roshan Pius32c15e22016-07-07 13:46:39 -070075 }
Dmitry Shmidte4663042016-04-04 10:07:49 -070076 }
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070077 os_free((void *)iface.driver);
78 os_free((void *)iface.ifname);
79 os_free((void *)iface.confname);
80 os_free((void *)iface.bridge_ifname);
Dmitry Shmidte4663042016-04-04 10:07:49 -070081 return status;
82}
83
Dmitry Shmidte4663042016-04-04 10:07:49 -070084android::binder::Status Supplicant::RemoveInterface(const std::string &ifname)
85{
86 struct wpa_supplicant *wpa_s;
87
88 wpa_s = wpa_supplicant_get_iface(wpa_global_, ifname.c_str());
Roshan Pius32c15e22016-07-07 13:46:39 -070089 if (!wpa_s) {
Dmitry Shmidte4663042016-04-04 10:07:49 -070090 return android::binder::Status::fromServiceSpecificError(
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070091 ERROR_IFACE_UNKNOWN,
Roshan Piusd6e37512016-07-07 13:20:46 -070092 "wpa_supplicant does not control this interface.");
Roshan Pius32c15e22016-07-07 13:46:39 -070093 }
94 if (wpa_supplicant_remove_iface(wpa_global_, wpa_s, 0)) {
Dmitry Shmidte4663042016-04-04 10:07:49 -070095 return android::binder::Status::fromServiceSpecificError(
Roshan Piusd6e37512016-07-07 13:20:46 -070096 ERROR_GENERIC,
97 "wpa_supplicant couldn't remove this interface.");
Roshan Pius32c15e22016-07-07 13:46:39 -070098 }
Dmitry Shmidte4663042016-04-04 10:07:49 -070099 return android::binder::Status::ok();
100}
101
Dmitry Shmidte4663042016-04-04 10:07:49 -0700102android::binder::Status Supplicant::GetInterface(
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -0700103 const std::string &ifname,
104 android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return)
Dmitry Shmidte4663042016-04-04 10:07:49 -0700105{
106 struct wpa_supplicant *wpa_s;
107
108 wpa_s = wpa_supplicant_get_iface(wpa_global_, ifname.c_str());
Roshan Pius32c15e22016-07-07 13:46:39 -0700109 if (!wpa_s) {
Dmitry Shmidte4663042016-04-04 10:07:49 -0700110 return android::binder::Status::fromServiceSpecificError(
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -0700111 ERROR_IFACE_UNKNOWN,
Roshan Piusd6e37512016-07-07 13:20:46 -0700112 "wpa_supplicant does not control this interface.");
Roshan Pius32c15e22016-07-07 13:46:39 -0700113 }
Dmitry Shmidte4663042016-04-04 10:07:49 -0700114
115 BinderManager *binder_manager = BinderManager::getInstance();
116 if (!binder_manager ||
Roshan Pius32c15e22016-07-07 13:46:39 -0700117 binder_manager->getIfaceBinderObjectByIfname(
118 wpa_s->ifname, aidl_return)) {
Dmitry Shmidte4663042016-04-04 10:07:49 -0700119 return android::binder::Status::fromServiceSpecificError(
Roshan Piusd6e37512016-07-07 13:20:46 -0700120 ERROR_GENERIC,
121 "wpa_supplicant encountered a binder error.");
Roshan Pius32c15e22016-07-07 13:46:39 -0700122 }
Dmitry Shmidte4663042016-04-04 10:07:49 -0700123
124 return android::binder::Status::ok();
125}
126
127} /* namespace wpa_supplicant_binder */