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