xref: /aosp_15_r20/external/wpa_supplicant_8/wpa_supplicant/aidl/vendor/p2p_network.cpp (revision 03f9172ca588f91df233974f4258bab95191f931)
1 /*
2  * WPA Supplicant - P2P network Aidl interface
3  * Copyright (c) 2021, Google Inc. All rights reserved.
4  *
5  * This software may be distributed under the terms of the BSD license.
6  * See README for more details.
7  */
8 
9 #include "aidl_manager.h"
10 #include "aidl_return_util.h"
11 #include "misc_utils.h"
12 #include "p2p_network.h"
13 
14 extern "C"
15 {
16 #include "config_ssid.h"
17 }
18 
19 namespace aidl {
20 namespace android {
21 namespace hardware {
22 namespace wifi {
23 namespace supplicant {
24 using aidl_return_util::validateAndCall;
25 using misc_utils::createStatus;
26 
P2pNetwork(struct wpa_global * wpa_global,const char ifname[],int network_id)27 P2pNetwork::P2pNetwork(
28 	struct wpa_global *wpa_global, const char ifname[], int network_id)
29 	: wpa_global_(wpa_global),
30 	  ifname_(ifname),
31 	  network_id_(network_id),
32 	  is_valid_(true)
33 {}
34 
invalidate()35 void P2pNetwork::invalidate() { is_valid_ = false; }
isValid()36 bool P2pNetwork::isValid()
37 {
38 	return (is_valid_ && (retrieveNetworkPtr() != nullptr));
39 }
40 
getId(int32_t * _aidl_return)41 ::ndk::ScopedAStatus P2pNetwork::getId(
42 	int32_t* _aidl_return)
43 {
44 	return validateAndCall(
45 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
46 		&P2pNetwork::getIdInternal, _aidl_return);
47 }
48 
getInterfaceName(std::string * _aidl_return)49 ::ndk::ScopedAStatus P2pNetwork::getInterfaceName(
50 	std::string* _aidl_return)
51 {
52 	return validateAndCall(
53 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
54 		&P2pNetwork::getInterfaceNameInternal, _aidl_return);
55 }
56 
getType(IfaceType * _aidl_return)57 ::ndk::ScopedAStatus P2pNetwork::getType(
58 	IfaceType* _aidl_return)
59 {
60 	return validateAndCall(
61 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
62 		&P2pNetwork::getTypeInternal, _aidl_return);
63 }
64 
getSsid(std::vector<uint8_t> * _aidl_return)65 ::ndk::ScopedAStatus P2pNetwork::getSsid(
66 	std::vector<uint8_t>* _aidl_return)
67 {
68 	return validateAndCall(
69 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
70 		&P2pNetwork::getSsidInternal, _aidl_return);
71 }
72 
getBssid(std::vector<uint8_t> * _aidl_return)73 ::ndk::ScopedAStatus P2pNetwork::getBssid(
74 	std::vector<uint8_t>* _aidl_return)
75 {
76 	return validateAndCall(
77 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
78 		&P2pNetwork::getBssidInternal, _aidl_return);
79 }
80 
isCurrent(bool * _aidl_return)81 ::ndk::ScopedAStatus P2pNetwork::isCurrent(
82 	bool* _aidl_return)
83 {
84 	return validateAndCall(
85 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
86 		&P2pNetwork::isCurrentInternal, _aidl_return);
87 }
88 
isPersistent(bool * _aidl_return)89 ::ndk::ScopedAStatus P2pNetwork::isPersistent(
90 	bool* _aidl_return)
91 {
92 	return validateAndCall(
93 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
94 		&P2pNetwork::isPersistentInternal, _aidl_return);
95 }
96 
isGroupOwner(bool * _aidl_return)97 ::ndk::ScopedAStatus P2pNetwork::isGroupOwner(
98 	bool* _aidl_return)
99 {
100 	return validateAndCall(
101 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
102 		&P2pNetwork::isGroupOwnerInternal, _aidl_return);
103 }
104 
setClientList(const std::vector<MacAddress> & in_clients)105 ::ndk::ScopedAStatus P2pNetwork::setClientList(
106 	const std::vector<MacAddress>& in_clients)
107 {
108 	return validateAndCall(
109 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
110 		&P2pNetwork::setClientListInternal, in_clients);
111 }
112 
getClientList(std::vector<MacAddress> * _aidl_return)113 ::ndk::ScopedAStatus P2pNetwork::getClientList(
114 	std::vector<MacAddress>* _aidl_return)
115 {
116 	return validateAndCall(
117 		this, SupplicantStatusCode::FAILURE_NETWORK_INVALID,
118 		&P2pNetwork::getClientListInternal, _aidl_return);
119 }
120 
getIdInternal()121 std::pair<uint32_t, ndk::ScopedAStatus> P2pNetwork::getIdInternal()
122 {
123 	return {network_id_, ndk::ScopedAStatus::ok()};
124 }
125 
getInterfaceNameInternal()126 std::pair<std::string, ndk::ScopedAStatus> P2pNetwork::getInterfaceNameInternal()
127 {
128 	return {ifname_, ndk::ScopedAStatus::ok()};
129 }
130 
getTypeInternal()131 std::pair<IfaceType, ndk::ScopedAStatus> P2pNetwork::getTypeInternal()
132 {
133 	return {IfaceType::P2P, ndk::ScopedAStatus::ok()};
134 }
135 
getSsidInternal()136 std::pair<std::vector<uint8_t>, ndk::ScopedAStatus> P2pNetwork::getSsidInternal()
137 {
138 	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
139 	std::vector<uint8_t> ssid(
140 		wpa_ssid->ssid, wpa_ssid->ssid + wpa_ssid->ssid_len);
141 	return {ssid, ndk::ScopedAStatus::ok()};
142 }
143 
144 std::pair<std::vector<uint8_t>, ndk::ScopedAStatus>
getBssidInternal()145 P2pNetwork::getBssidInternal()
146 {
147 	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
148 	std::vector<uint8_t> bssid;
149 	if (wpa_ssid->bssid_set) {
150 		bssid.assign(wpa_ssid->bssid, wpa_ssid->bssid + ETH_ALEN);
151 	}
152 	return {bssid, ndk::ScopedAStatus::ok()};
153 }
154 
isCurrentInternal()155 std::pair<bool, ndk::ScopedAStatus> P2pNetwork::isCurrentInternal()
156 {
157 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
158 	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
159 	return {(wpa_s->current_ssid == wpa_ssid),
160 		ndk::ScopedAStatus::ok()};
161 }
162 
isPersistentInternal()163 std::pair<bool, ndk::ScopedAStatus> P2pNetwork::isPersistentInternal()
164 {
165 	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
166 	return {(wpa_ssid->disabled == 2), ndk::ScopedAStatus::ok()};
167 }
168 
isGroupOwnerInternal()169 std::pair<bool, ndk::ScopedAStatus> P2pNetwork::isGroupOwnerInternal()
170 {
171 	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
172 	return {(wpa_ssid->mode == wpas_mode::WPAS_MODE_P2P_GO),
173 		ndk::ScopedAStatus::ok()};
174 }
175 
setClientListInternal(const std::vector<MacAddress> & clients)176 ndk::ScopedAStatus P2pNetwork::setClientListInternal(
177 	const std::vector<MacAddress> &clients)
178 {
179 	for (const auto &client : clients) {
180 		if (client.data.size() != ETH_ALEN) {
181 			return createStatus(SupplicantStatusCode::FAILURE_ARGS_INVALID);
182 		}
183 	}
184 	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
185 	os_free(wpa_ssid->p2p_client_list);
186 	// Internal representation uses a generic MAC addr/mask storage format
187 	// (even though the mask is always 0xFF'ed for p2p_client_list). So, the
188 	// first 6 bytes holds the client MAC address and the next 6 bytes are
189 	// OxFF'ed.
190 	wpa_ssid->p2p_client_list =
191 		(u8 *)os_malloc(ETH_ALEN * 2 * clients.size());
192 	if (!wpa_ssid->p2p_client_list) {
193 		return createStatus(SupplicantStatusCode::FAILURE_UNKNOWN);
194 	}
195 	u8 *list = wpa_ssid->p2p_client_list;
196 	for (const auto &client : clients) {
197 		os_memcpy(list, client.data.data(), ETH_ALEN);
198 		list += ETH_ALEN;
199 		os_memset(list, 0xFF, ETH_ALEN);
200 		list += ETH_ALEN;
201 	}
202 	wpa_ssid->num_p2p_clients = clients.size();
203 	return ndk::ScopedAStatus::ok();
204 }
205 
206 std::pair<std::vector<MacAddress>, ndk::ScopedAStatus>
getClientListInternal()207 P2pNetwork::getClientListInternal()
208 {
209 	std::vector<MacAddress> clients;
210 	struct wpa_ssid *wpa_ssid = retrieveNetworkPtr();
211 	if (!wpa_ssid->p2p_client_list) {
212 		return {clients, createStatus(SupplicantStatusCode::FAILURE_UNKNOWN)};
213 	}
214 	u8 *list = wpa_ssid->p2p_client_list;
215 	for (size_t i = 0; i < wpa_ssid->num_p2p_clients; i++) {
216 		MacAddress client = MacAddress{};
217 		client.data = std::vector<uint8_t>(list, list + ETH_ALEN);
218 		clients.emplace_back(client);
219 		list += 2 * ETH_ALEN;
220 	}
221 	return {clients, ndk::ScopedAStatus::ok()};
222 }
223 
224 /**
225  * Retrieve the underlying |wpa_ssid| struct pointer for
226  * this network.
227  * If the underlying network is removed or the interface
228  * this network belong to is removed, all RPC method calls
229  * on this object will return failure.
230  */
retrieveNetworkPtr()231 struct wpa_ssid *P2pNetwork::retrieveNetworkPtr()
232 {
233 	wpa_supplicant *wpa_s = retrieveIfacePtr();
234 	if (!wpa_s)
235 		return nullptr;
236 	return wpa_config_get_network(wpa_s->conf, network_id_);
237 }
238 
239 /**
240  * Retrieve the underlying |wpa_supplicant| struct
241  * pointer for this network.
242  */
retrieveIfacePtr()243 struct wpa_supplicant *P2pNetwork::retrieveIfacePtr()
244 {
245 	return wpa_supplicant_get_iface(
246 		(struct wpa_global *)wpa_global_, ifname_.c_str());
247 }
248 }  // namespace supplicant
249 }  // namespace wifi
250 }  // namespace hardware
251 }  // namespace android
252 }  // namespace aidl
253