1 /*
2 * Copyright (C) 2022 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "wifi_rtt_controller.h"
18
19 #include <android-base/logging.h>
20
21 #include "aidl_return_util.h"
22 #include "aidl_struct_util.h"
23 #include "wifi_status_util.h"
24
25 namespace aidl {
26 namespace android {
27 namespace hardware {
28 namespace wifi {
29 using aidl_return_util::validateAndCall;
30
WifiRttController(const std::string & iface_name,const std::shared_ptr<IWifiStaIface> & bound_iface,const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)31 WifiRttController::WifiRttController(const std::string& iface_name,
32 const std::shared_ptr<IWifiStaIface>& bound_iface,
33 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
34 : ifname_(iface_name), bound_iface_(bound_iface), legacy_hal_(legacy_hal), is_valid_(true) {}
35
create(const std::string & iface_name,const std::shared_ptr<IWifiStaIface> & bound_iface,const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)36 std::shared_ptr<WifiRttController> WifiRttController::create(
37 const std::string& iface_name, const std::shared_ptr<IWifiStaIface>& bound_iface,
38 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal) {
39 std::shared_ptr<WifiRttController> ptr =
40 ndk::SharedRefBase::make<WifiRttController>(iface_name, bound_iface, legacy_hal);
41 std::weak_ptr<WifiRttController> weak_ptr_this(ptr);
42 ptr->setWeakPtr(weak_ptr_this);
43 return ptr;
44 }
45
invalidate()46 void WifiRttController::invalidate() {
47 legacy_hal_.reset();
48 event_callbacks_.clear();
49 is_valid_ = false;
50 };
51
isValid()52 bool WifiRttController::isValid() {
53 return is_valid_;
54 }
55
setWeakPtr(std::weak_ptr<WifiRttController> ptr)56 void WifiRttController::setWeakPtr(std::weak_ptr<WifiRttController> ptr) {
57 weak_ptr_this_ = ptr;
58 }
59
60 std::vector<std::shared_ptr<IWifiRttControllerEventCallback>>
getEventCallbacks()61 WifiRttController::getEventCallbacks() {
62 return event_callbacks_;
63 }
64
getIfaceName()65 std::string WifiRttController::getIfaceName() {
66 return ifname_;
67 }
68
getBoundIface(std::shared_ptr<IWifiStaIface> * _aidl_return)69 ndk::ScopedAStatus WifiRttController::getBoundIface(std::shared_ptr<IWifiStaIface>* _aidl_return) {
70 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
71 &WifiRttController::getBoundIfaceInternal, _aidl_return);
72 }
73
registerEventCallback(const std::shared_ptr<IWifiRttControllerEventCallback> & callback)74 ndk::ScopedAStatus WifiRttController::registerEventCallback(
75 const std::shared_ptr<IWifiRttControllerEventCallback>& callback) {
76 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
77 &WifiRttController::registerEventCallbackInternal, callback);
78 }
79
rangeRequest(int32_t in_cmdId,const std::vector<RttConfig> & in_rttConfigs)80 ndk::ScopedAStatus WifiRttController::rangeRequest(int32_t in_cmdId,
81 const std::vector<RttConfig>& in_rttConfigs) {
82 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
83 &WifiRttController::rangeRequestInternal, in_cmdId, in_rttConfigs);
84 }
85
rangeCancel(int32_t in_cmdId,const std::vector<MacAddress> & in_addrs)86 ndk::ScopedAStatus WifiRttController::rangeCancel(int32_t in_cmdId,
87 const std::vector<MacAddress>& in_addrs) {
88 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
89 &WifiRttController::rangeCancelInternal, in_cmdId, in_addrs);
90 }
91
getCapabilities(RttCapabilities * _aidl_return)92 ndk::ScopedAStatus WifiRttController::getCapabilities(RttCapabilities* _aidl_return) {
93 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
94 &WifiRttController::getCapabilitiesInternal, _aidl_return);
95 }
96
setLci(int32_t in_cmdId,const RttLciInformation & in_lci)97 ndk::ScopedAStatus WifiRttController::setLci(int32_t in_cmdId, const RttLciInformation& in_lci) {
98 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
99 &WifiRttController::setLciInternal, in_cmdId, in_lci);
100 }
101
setLcr(int32_t in_cmdId,const RttLcrInformation & in_lcr)102 ndk::ScopedAStatus WifiRttController::setLcr(int32_t in_cmdId, const RttLcrInformation& in_lcr) {
103 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
104 &WifiRttController::setLcrInternal, in_cmdId, in_lcr);
105 }
106
getResponderInfo(RttResponder * _aidl_return)107 ndk::ScopedAStatus WifiRttController::getResponderInfo(RttResponder* _aidl_return) {
108 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
109 &WifiRttController::getResponderInfoInternal, _aidl_return);
110 }
111
enableResponder(int32_t in_cmdId,const WifiChannelInfo & in_channelHint,int32_t in_maxDurationInSeconds,const RttResponder & in_info)112 ndk::ScopedAStatus WifiRttController::enableResponder(int32_t in_cmdId,
113 const WifiChannelInfo& in_channelHint,
114 int32_t in_maxDurationInSeconds,
115 const RttResponder& in_info) {
116 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
117 &WifiRttController::enableResponderInternal, in_cmdId, in_channelHint,
118 in_maxDurationInSeconds, in_info);
119 }
120
disableResponder(int32_t in_cmdId)121 ndk::ScopedAStatus WifiRttController::disableResponder(int32_t in_cmdId) {
122 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
123 &WifiRttController::disableResponderInternal, in_cmdId);
124 }
125
126 std::pair<std::shared_ptr<IWifiStaIface>, ndk::ScopedAStatus>
getBoundIfaceInternal()127 WifiRttController::getBoundIfaceInternal() {
128 return {bound_iface_, ndk::ScopedAStatus::ok()};
129 }
130
registerEventCallbackInternal(const std::shared_ptr<IWifiRttControllerEventCallback> & callback)131 ndk::ScopedAStatus WifiRttController::registerEventCallbackInternal(
132 const std::shared_ptr<IWifiRttControllerEventCallback>& callback) {
133 event_callbacks_.emplace_back(callback);
134 return ndk::ScopedAStatus::ok();
135 }
136
rangeRequestInternal(int32_t cmd_id,const std::vector<RttConfig> & rtt_configs)137 ndk::ScopedAStatus WifiRttController::rangeRequestInternal(
138 int32_t cmd_id, const std::vector<RttConfig>& rtt_configs) {
139 // Try 11az secure, 11az non-secure & 11mc ranging (v4)
140 std::vector<legacy_hal::wifi_rtt_config_v4> legacy_configs_v4;
141 if (!aidl_struct_util::convertAidlVectorOfRttConfigToLegacyV4(rtt_configs,
142 &legacy_configs_v4)) {
143 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
144 }
145 std::weak_ptr<WifiRttController> weak_ptr_this = weak_ptr_this_;
146 const auto& on_results_callback_v4 =
147 [weak_ptr_this](legacy_hal::wifi_request_id id,
148 const std::vector<const legacy_hal::wifi_rtt_result_v4*>& results) {
149 const auto shared_ptr_this = weak_ptr_this.lock();
150 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
151 LOG(ERROR) << "v4 Callback invoked on an invalid object";
152 return;
153 }
154 std::vector<RttResult> aidl_results;
155 if (!aidl_struct_util::convertLegacyVectorOfRttResultV4ToAidl(results,
156 &aidl_results)) {
157 LOG(ERROR) << "Failed to convert rtt results v4 to AIDL structs";
158 return;
159 }
160 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
161 if (!callback->onResults(id, aidl_results).isOk()) {
162 LOG(ERROR) << "Failed to invoke the v4 callback";
163 }
164 }
165 };
166 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startRttRangeRequestV4(
167 ifname_, cmd_id, legacy_configs_v4, on_results_callback_v4);
168
169 if (legacy_status != legacy_hal::WIFI_ERROR_NOT_SUPPORTED) {
170 return createWifiStatusFromLegacyError(legacy_status);
171 }
172
173 // Fallback to 11az non-secure & 11mc ranging (v3)
174 std::vector<legacy_hal::wifi_rtt_config_v3> legacy_configs_v3;
175 if (!aidl_struct_util::convertAidlVectorOfRttConfigToLegacyV3(rtt_configs,
176 &legacy_configs_v3)) {
177 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
178 }
179 const auto& on_results_callback_v3 =
180 [weak_ptr_this](legacy_hal::wifi_request_id id,
181 const std::vector<const legacy_hal::wifi_rtt_result_v3*>& results) {
182 const auto shared_ptr_this = weak_ptr_this.lock();
183 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
184 LOG(ERROR) << "v3 Callback invoked on an invalid object";
185 return;
186 }
187 std::vector<RttResult> aidl_results;
188 if (!aidl_struct_util::convertLegacyVectorOfRttResultV3ToAidl(results,
189 &aidl_results)) {
190 LOG(ERROR) << "Failed to convert rtt results v3 to AIDL structs";
191 return;
192 }
193 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
194 if (!callback->onResults(id, aidl_results).isOk()) {
195 LOG(ERROR) << "Failed to invoke the v3 callback";
196 }
197 }
198 };
199 legacy_status = legacy_hal_.lock()->startRttRangeRequestV3(ifname_, cmd_id, legacy_configs_v3,
200 on_results_callback_v3);
201
202 if (legacy_status != legacy_hal::WIFI_ERROR_NOT_SUPPORTED) {
203 return createWifiStatusFromLegacyError(legacy_status);
204 }
205
206 // Fallback to 11mc ranging.
207 std::vector<legacy_hal::wifi_rtt_config> legacy_configs;
208 if (!aidl_struct_util::convertAidlVectorOfRttConfigToLegacy(rtt_configs, &legacy_configs)) {
209 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
210 }
211 const auto& on_results_callback =
212 [weak_ptr_this](legacy_hal::wifi_request_id id,
213 const std::vector<const legacy_hal::wifi_rtt_result*>& results) {
214 const auto shared_ptr_this = weak_ptr_this.lock();
215 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
216 LOG(ERROR) << "Callback invoked on an invalid object";
217 return;
218 }
219 std::vector<RttResult> aidl_results;
220 if (!aidl_struct_util::convertLegacyVectorOfRttResultToAidl(results,
221 &aidl_results)) {
222 LOG(ERROR) << "Failed to convert rtt results to AIDL structs";
223 return;
224 }
225 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
226 if (!callback->onResults(id, aidl_results).isOk()) {
227 LOG(ERROR) << "Failed to invoke the callback";
228 }
229 }
230 };
231 const auto& on_results_callback_v2 =
232 [weak_ptr_this](legacy_hal::wifi_request_id id,
233 const std::vector<const legacy_hal::wifi_rtt_result_v2*>& results) {
234 const auto shared_ptr_this = weak_ptr_this.lock();
235 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
236 LOG(ERROR) << "v2 Callback invoked on an invalid object";
237 return;
238 }
239 std::vector<RttResult> aidl_results;
240 if (!aidl_struct_util::convertLegacyVectorOfRttResultV2ToAidl(results,
241 &aidl_results)) {
242 LOG(ERROR) << "Failed to convert rtt results v2 to AIDL structs";
243 return;
244 }
245 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
246 if (!callback->onResults(id, aidl_results).isOk()) {
247 LOG(ERROR) << "Failed to invoke the v2 callback";
248 }
249 }
250 };
251 legacy_status = legacy_hal_.lock()->startRttRangeRequest(
252 ifname_, cmd_id, legacy_configs, on_results_callback, on_results_callback_v2);
253 return createWifiStatusFromLegacyError(legacy_status);
254 }
255
rangeCancelInternal(int32_t cmd_id,const std::vector<MacAddress> & addrs)256 ndk::ScopedAStatus WifiRttController::rangeCancelInternal(int32_t cmd_id,
257 const std::vector<MacAddress>& addrs) {
258 std::vector<std::array<uint8_t, ETH_ALEN>> legacy_addrs;
259 for (const auto& addr : addrs) {
260 std::array<uint8_t, ETH_ALEN> addr_array;
261 std::copy_n(addr.data.begin(), ETH_ALEN, addr_array.begin());
262 legacy_addrs.push_back(addr_array);
263 }
264 legacy_hal::wifi_error legacy_status =
265 legacy_hal_.lock()->cancelRttRangeRequest(ifname_, cmd_id, legacy_addrs);
266 return createWifiStatusFromLegacyError(legacy_status);
267 }
268
getCapabilitiesInternal()269 std::pair<RttCapabilities, ndk::ScopedAStatus> WifiRttController::getCapabilitiesInternal() {
270 legacy_hal::wifi_error legacy_status;
271 legacy_hal::wifi_rtt_capabilities_v3 legacy_caps_v3;
272 legacy_hal::wifi_rtt_capabilities_v4 legacy_caps_v4;
273
274 // Try v4 first
275 std::tie(legacy_status, legacy_caps_v4) = legacy_hal_.lock()->getRttCapabilitiesV4(ifname_);
276 if (legacy_status == legacy_hal::WIFI_SUCCESS) {
277 RttCapabilities aidl_caps;
278 if (!aidl_struct_util::convertLegacyRttCapabilitiesV4ToAidl(legacy_caps_v4, &aidl_caps)) {
279 return {RttCapabilities{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
280 }
281 return {aidl_caps, ndk::ScopedAStatus::ok()};
282 }
283
284 // If not supported, fallback to v3
285 if (legacy_status == legacy_hal::WIFI_ERROR_NOT_SUPPORTED) {
286 std::tie(legacy_status, legacy_caps_v3) = legacy_hal_.lock()->getRttCapabilitiesV3(ifname_);
287 if (legacy_status == legacy_hal::WIFI_SUCCESS) {
288 RttCapabilities aidl_caps;
289 if (!aidl_struct_util::convertLegacyRttCapabilitiesV3ToAidl(legacy_caps_v3,
290 &aidl_caps)) {
291 return {RttCapabilities{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
292 }
293 return {aidl_caps, ndk::ScopedAStatus::ok()};
294 }
295 }
296
297 // If not supported, fallback to default
298 if (legacy_status == legacy_hal::WIFI_ERROR_NOT_SUPPORTED) {
299 legacy_hal::wifi_rtt_capabilities legacy_caps;
300 std::tie(legacy_status, legacy_caps) = legacy_hal_.lock()->getRttCapabilities(ifname_);
301 if (legacy_status == legacy_hal::WIFI_SUCCESS) {
302 RttCapabilities aidl_caps;
303 if (!aidl_struct_util::convertLegacyRttCapabilitiesToAidl(legacy_caps, &aidl_caps)) {
304 return {RttCapabilities{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
305 }
306 return {aidl_caps, ndk::ScopedAStatus::ok()};
307 }
308 }
309
310 // Error, if all failed
311 return {RttCapabilities{}, createWifiStatusFromLegacyError(legacy_status)};
312 }
313
setLciInternal(int32_t cmd_id,const RttLciInformation & lci)314 ndk::ScopedAStatus WifiRttController::setLciInternal(int32_t cmd_id, const RttLciInformation& lci) {
315 legacy_hal::wifi_lci_information legacy_lci;
316 if (!aidl_struct_util::convertAidlRttLciInformationToLegacy(lci, &legacy_lci)) {
317 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
318 }
319 legacy_hal::wifi_error legacy_status =
320 legacy_hal_.lock()->setRttLci(ifname_, cmd_id, legacy_lci);
321 return createWifiStatusFromLegacyError(legacy_status);
322 }
323
setLcrInternal(int32_t cmd_id,const RttLcrInformation & lcr)324 ndk::ScopedAStatus WifiRttController::setLcrInternal(int32_t cmd_id, const RttLcrInformation& lcr) {
325 legacy_hal::wifi_lcr_information legacy_lcr;
326 if (!aidl_struct_util::convertAidlRttLcrInformationToLegacy(lcr, &legacy_lcr)) {
327 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
328 }
329 legacy_hal::wifi_error legacy_status =
330 legacy_hal_.lock()->setRttLcr(ifname_, cmd_id, legacy_lcr);
331 return createWifiStatusFromLegacyError(legacy_status);
332 }
333
getResponderInfoInternal()334 std::pair<RttResponder, ndk::ScopedAStatus> WifiRttController::getResponderInfoInternal() {
335 legacy_hal::wifi_error legacy_status;
336 legacy_hal::wifi_rtt_responder legacy_responder;
337 std::tie(legacy_status, legacy_responder) = legacy_hal_.lock()->getRttResponderInfo(ifname_);
338 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
339 return {RttResponder{}, createWifiStatusFromLegacyError(legacy_status)};
340 }
341 RttResponder aidl_responder;
342 if (!aidl_struct_util::convertLegacyRttResponderToAidl(legacy_responder, &aidl_responder)) {
343 return {RttResponder{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
344 }
345 return {aidl_responder, ndk::ScopedAStatus::ok()};
346 }
347
enableResponderInternal(int32_t cmd_id,const WifiChannelInfo & channel_hint,int32_t max_duration_seconds,const RttResponder & info)348 ndk::ScopedAStatus WifiRttController::enableResponderInternal(int32_t cmd_id,
349 const WifiChannelInfo& channel_hint,
350 int32_t max_duration_seconds,
351 const RttResponder& info) {
352 legacy_hal::wifi_channel_info legacy_channel_info;
353 if (!aidl_struct_util::convertAidlWifiChannelInfoToLegacy(channel_hint, &legacy_channel_info)) {
354 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
355 }
356 legacy_hal::wifi_rtt_responder legacy_responder;
357 if (!aidl_struct_util::convertAidlRttResponderToLegacy(info, &legacy_responder)) {
358 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
359 }
360 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableRttResponder(
361 ifname_, cmd_id, legacy_channel_info, max_duration_seconds, legacy_responder);
362 return createWifiStatusFromLegacyError(legacy_status);
363 }
364
disableResponderInternal(int32_t cmd_id)365 ndk::ScopedAStatus WifiRttController::disableResponderInternal(int32_t cmd_id) {
366 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->disableRttResponder(ifname_, cmd_id);
367 return createWifiStatusFromLegacyError(legacy_status);
368 }
369
370 } // namespace wifi
371 } // namespace hardware
372 } // namespace android
373 } // namespace aidl
374