xref: /freebsd-src/contrib/wpa/wpa_supplicant/binder/supplicant.cpp (revision 780fb4a2fa9a9aee5ac48a60b790f567c0dc13e9)
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 &params,
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