blob: 76569b1471fbb27872c75ec5638de93580db7de1 [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))
25 return android::binder::Status::fromServiceSpecificError(
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070026 ERROR_INVALID_ARGS,
27 android::String8("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,
41 android::String8("wpa_supplicant already controls this "
42 "interface."));
Dmitry Shmidte4663042016-04-04 10:07:49 -070043
44 android::binder::Status status;
45 struct wpa_supplicant *wpa_s = NULL;
46 struct wpa_interface iface;
47
48 os_memset(&iface, 0, sizeof(iface));
49 iface.driver = os_strdup(android::String8(driver).string());
50 iface.ifname = os_strdup(android::String8(ifname).string());
51 iface.confname = os_strdup(android::String8(confname).string());
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070052 iface.bridge_ifname =
53 os_strdup(android::String8(bridge_ifname).string());
Dmitry Shmidte4663042016-04-04 10:07:49 -070054 /* Otherwise, have wpa_supplicant attach to it. */
55 wpa_s = wpa_supplicant_add_iface(wpa_global_, &iface, NULL);
56 /* The supplicant core creates a corresponding binder object via
57 * BinderManager when |wpa_supplicant_add_iface| is called. */
58 if (!wpa_s || !wpa_s->binder_object_key) {
59 status = android::binder::Status::fromServiceSpecificError(
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070060 ERROR_UNKNOWN,
61 android::String8(
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 ||
67 binder_manager->getIfaceBinderObjectByKey(
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070068 wpa_s->binder_object_key, aidl_return))
69 status =
70 android::binder::Status::fromServiceSpecificError(
Dmitry Shmidte4663042016-04-04 10:07:49 -070071 ERROR_UNKNOWN,
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070072 android::String8("wpa_supplicant encountered a "
73 "binder error."));
Dmitry Shmidte4663042016-04-04 10:07:49 -070074 else
75 status = android::binder::Status::ok();
76 }
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());
89 if (!wpa_s || !wpa_s->binder_object_key)
90 return android::binder::Status::fromServiceSpecificError(
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070091 ERROR_IFACE_UNKNOWN,
92 android::String8("wpa_supplicant does not control this "
93 "interface."));
Dmitry Shmidte4663042016-04-04 10:07:49 -070094 if (wpa_supplicant_remove_iface(wpa_global_, wpa_s, 0))
95 return android::binder::Status::fromServiceSpecificError(
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -070096 ERROR_UNKNOWN,
97 android::String8(
98 "wpa_supplicant couldn't remove this interface."));
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());
109 if (!wpa_s || !wpa_s->binder_object_key)
110 return android::binder::Status::fromServiceSpecificError(
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -0700111 ERROR_IFACE_UNKNOWN,
112 android::String8(
113 "wpa_supplicant does not control this interface."));
Dmitry Shmidte4663042016-04-04 10:07:49 -0700114
115 BinderManager *binder_manager = BinderManager::getInstance();
116 if (!binder_manager ||
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -0700117 binder_manager->getIfaceBinderObjectByKey(
118 wpa_s->binder_object_key, aidl_return))
Dmitry Shmidte4663042016-04-04 10:07:49 -0700119 return android::binder::Status::fromServiceSpecificError(
Dmitry Shmidt7f2c7532016-08-15 09:48:12 -0700120 ERROR_UNKNOWN,
121 android::String8(
122 "wpa_supplicant encountered a binder error."));
Dmitry Shmidte4663042016-04-04 10:07:49 -0700123
124 return android::binder::Status::ok();
125}
126
127} /* namespace wpa_supplicant_binder */