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