1*780fb4a2SCy Schubert /*
2*780fb4a2SCy Schubert * binder interface for wpa_supplicant daemon
3*780fb4a2SCy Schubert * Copyright (c) 2004-2016, Jouni Malinen <j@w1.fi>
4*780fb4a2SCy Schubert * Copyright (c) 2004-2016, Roshan Pius <rpius@google.com>
5*780fb4a2SCy Schubert *
6*780fb4a2SCy Schubert * This software may be distributed under the terms of the BSD license.
7*780fb4a2SCy Schubert * See README for more details.
8*780fb4a2SCy Schubert */
9*780fb4a2SCy Schubert
10*780fb4a2SCy Schubert #include "supplicant.h"
11*780fb4a2SCy Schubert #include "binder_manager.h"
12*780fb4a2SCy Schubert
13*780fb4a2SCy Schubert namespace wpa_supplicant_binder {
14*780fb4a2SCy Schubert
Supplicant(struct wpa_global * global)15*780fb4a2SCy Schubert Supplicant::Supplicant(struct wpa_global *global) : wpa_global_(global) {}
16*780fb4a2SCy Schubert
CreateInterface(const android::os::PersistableBundle & params,android::sp<fi::w1::wpa_supplicant::IIface> * aidl_return)17*780fb4a2SCy Schubert android::binder::Status Supplicant::CreateInterface(
18*780fb4a2SCy Schubert const android::os::PersistableBundle ¶ms,
19*780fb4a2SCy Schubert android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return)
20*780fb4a2SCy Schubert {
21*780fb4a2SCy Schubert android::String16 driver, ifname, confname, bridge_ifname;
22*780fb4a2SCy Schubert
23*780fb4a2SCy Schubert /* Check if required Ifname argument is missing */
24*780fb4a2SCy Schubert if (!params.getString(android::String16("Ifname"), &ifname))
25*780fb4a2SCy Schubert return android::binder::Status::fromServiceSpecificError(
26*780fb4a2SCy Schubert ERROR_INVALID_ARGS,
27*780fb4a2SCy Schubert android::String8("Ifname missing in params."));
28*780fb4a2SCy Schubert /* Retrieve the remaining params from the dictionary */
29*780fb4a2SCy Schubert params.getString(android::String16("Driver"), &driver);
30*780fb4a2SCy Schubert params.getString(android::String16("ConfigFile"), &confname);
31*780fb4a2SCy Schubert params.getString(android::String16("BridgeIfname"), &bridge_ifname);
32*780fb4a2SCy Schubert
33*780fb4a2SCy Schubert /*
34*780fb4a2SCy Schubert * Try to get the wpa_supplicant record for this iface, return
35*780fb4a2SCy Schubert * an error if we already control it.
36*780fb4a2SCy Schubert */
37*780fb4a2SCy Schubert if (wpa_supplicant_get_iface(
38*780fb4a2SCy Schubert wpa_global_, android::String8(ifname).string()) != NULL)
39*780fb4a2SCy Schubert return android::binder::Status::fromServiceSpecificError(
40*780fb4a2SCy Schubert ERROR_IFACE_EXISTS,
41*780fb4a2SCy Schubert android::String8("wpa_supplicant already controls this "
42*780fb4a2SCy Schubert "interface."));
43*780fb4a2SCy Schubert
44*780fb4a2SCy Schubert android::binder::Status status;
45*780fb4a2SCy Schubert struct wpa_supplicant *wpa_s = NULL;
46*780fb4a2SCy Schubert struct wpa_interface iface;
47*780fb4a2SCy Schubert
48*780fb4a2SCy Schubert os_memset(&iface, 0, sizeof(iface));
49*780fb4a2SCy Schubert iface.driver = os_strdup(android::String8(driver).string());
50*780fb4a2SCy Schubert iface.ifname = os_strdup(android::String8(ifname).string());
51*780fb4a2SCy Schubert iface.confname = os_strdup(android::String8(confname).string());
52*780fb4a2SCy Schubert iface.bridge_ifname =
53*780fb4a2SCy Schubert os_strdup(android::String8(bridge_ifname).string());
54*780fb4a2SCy Schubert /* Otherwise, have wpa_supplicant attach to it. */
55*780fb4a2SCy Schubert wpa_s = wpa_supplicant_add_iface(wpa_global_, &iface, NULL);
56*780fb4a2SCy Schubert /* The supplicant core creates a corresponding binder object via
57*780fb4a2SCy Schubert * BinderManager when |wpa_supplicant_add_iface| is called. */
58*780fb4a2SCy Schubert if (!wpa_s || !wpa_s->binder_object_key) {
59*780fb4a2SCy Schubert status = android::binder::Status::fromServiceSpecificError(
60*780fb4a2SCy Schubert ERROR_UNKNOWN,
61*780fb4a2SCy Schubert android::String8(
62*780fb4a2SCy Schubert "wpa_supplicant couldn't grab this interface."));
63*780fb4a2SCy Schubert } else {
64*780fb4a2SCy Schubert BinderManager *binder_manager = BinderManager::getInstance();
65*780fb4a2SCy Schubert
66*780fb4a2SCy Schubert if (!binder_manager ||
67*780fb4a2SCy Schubert binder_manager->getIfaceBinderObjectByKey(
68*780fb4a2SCy Schubert wpa_s->binder_object_key, aidl_return))
69*780fb4a2SCy Schubert status =
70*780fb4a2SCy Schubert android::binder::Status::fromServiceSpecificError(
71*780fb4a2SCy Schubert ERROR_UNKNOWN,
72*780fb4a2SCy Schubert android::String8("wpa_supplicant encountered a "
73*780fb4a2SCy Schubert "binder error."));
74*780fb4a2SCy Schubert else
75*780fb4a2SCy Schubert status = android::binder::Status::ok();
76*780fb4a2SCy Schubert }
77*780fb4a2SCy Schubert os_free((void *)iface.driver);
78*780fb4a2SCy Schubert os_free((void *)iface.ifname);
79*780fb4a2SCy Schubert os_free((void *)iface.confname);
80*780fb4a2SCy Schubert os_free((void *)iface.bridge_ifname);
81*780fb4a2SCy Schubert return status;
82*780fb4a2SCy Schubert }
83*780fb4a2SCy Schubert
RemoveInterface(const std::string & ifname)84*780fb4a2SCy Schubert android::binder::Status Supplicant::RemoveInterface(const std::string &ifname)
85*780fb4a2SCy Schubert {
86*780fb4a2SCy Schubert struct wpa_supplicant *wpa_s;
87*780fb4a2SCy Schubert
88*780fb4a2SCy Schubert wpa_s = wpa_supplicant_get_iface(wpa_global_, ifname.c_str());
89*780fb4a2SCy Schubert if (!wpa_s || !wpa_s->binder_object_key)
90*780fb4a2SCy Schubert return android::binder::Status::fromServiceSpecificError(
91*780fb4a2SCy Schubert ERROR_IFACE_UNKNOWN,
92*780fb4a2SCy Schubert android::String8("wpa_supplicant does not control this "
93*780fb4a2SCy Schubert "interface."));
94*780fb4a2SCy Schubert if (wpa_supplicant_remove_iface(wpa_global_, wpa_s, 0))
95*780fb4a2SCy Schubert return android::binder::Status::fromServiceSpecificError(
96*780fb4a2SCy Schubert ERROR_UNKNOWN,
97*780fb4a2SCy Schubert android::String8(
98*780fb4a2SCy Schubert "wpa_supplicant couldn't remove this interface."));
99*780fb4a2SCy Schubert return android::binder::Status::ok();
100*780fb4a2SCy Schubert }
101*780fb4a2SCy Schubert
GetInterface(const std::string & ifname,android::sp<fi::w1::wpa_supplicant::IIface> * aidl_return)102*780fb4a2SCy Schubert android::binder::Status Supplicant::GetInterface(
103*780fb4a2SCy Schubert const std::string &ifname,
104*780fb4a2SCy Schubert android::sp<fi::w1::wpa_supplicant::IIface> *aidl_return)
105*780fb4a2SCy Schubert {
106*780fb4a2SCy Schubert struct wpa_supplicant *wpa_s;
107*780fb4a2SCy Schubert
108*780fb4a2SCy Schubert wpa_s = wpa_supplicant_get_iface(wpa_global_, ifname.c_str());
109*780fb4a2SCy Schubert if (!wpa_s || !wpa_s->binder_object_key)
110*780fb4a2SCy Schubert return android::binder::Status::fromServiceSpecificError(
111*780fb4a2SCy Schubert ERROR_IFACE_UNKNOWN,
112*780fb4a2SCy Schubert android::String8(
113*780fb4a2SCy Schubert "wpa_supplicant does not control this interface."));
114*780fb4a2SCy Schubert
115*780fb4a2SCy Schubert BinderManager *binder_manager = BinderManager::getInstance();
116*780fb4a2SCy Schubert if (!binder_manager ||
117*780fb4a2SCy Schubert binder_manager->getIfaceBinderObjectByKey(
118*780fb4a2SCy Schubert wpa_s->binder_object_key, aidl_return))
119*780fb4a2SCy Schubert return android::binder::Status::fromServiceSpecificError(
120*780fb4a2SCy Schubert ERROR_UNKNOWN,
121*780fb4a2SCy Schubert android::String8(
122*780fb4a2SCy Schubert "wpa_supplicant encountered a binder error."));
123*780fb4a2SCy Schubert
124*780fb4a2SCy Schubert return android::binder::Status::ok();
125*780fb4a2SCy Schubert }
126*780fb4a2SCy Schubert
127*780fb4a2SCy Schubert } /* namespace wpa_supplicant_binder */
128