1 /*
2  * Copyright (C) 2016 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 <android-base/logging.h>
18 
19 #include "hidl_return_util.h"
20 #include "hidl_struct_util.h"
21 #include "wifi_rtt_controller.h"
22 #include "wifi_status_util.h"
23 
24 namespace android {
25 namespace hardware {
26 namespace wifi {
27 namespace V1_0 {
28 namespace implementation {
29 using hidl_return_util::validateAndCall;
30 
WifiRttController(const sp<IWifiIface> & bound_iface,const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)31 WifiRttController::WifiRttController(
32     const sp<IWifiIface>& bound_iface,
33     const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
34     : bound_iface_(bound_iface), legacy_hal_(legacy_hal), is_valid_(true) {}
35 
invalidate()36 void WifiRttController::invalidate() {
37   legacy_hal_.reset();
38   event_callbacks_.clear();
39   is_valid_ = false;
40 }
41 
isValid()42 bool WifiRttController::isValid() {
43   return is_valid_;
44 }
45 
46 std::vector<sp<IWifiRttControllerEventCallback>>
getEventCallbacks()47 WifiRttController::getEventCallbacks() {
48   return event_callbacks_;
49 }
50 
getBoundIface(getBoundIface_cb hidl_status_cb)51 Return<void> WifiRttController::getBoundIface(getBoundIface_cb hidl_status_cb) {
52   return validateAndCall(this,
53                          WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
54                          &WifiRttController::getBoundIfaceInternal,
55                          hidl_status_cb);
56 }
57 
registerEventCallback(const sp<IWifiRttControllerEventCallback> & callback,registerEventCallback_cb hidl_status_cb)58 Return<void> WifiRttController::registerEventCallback(
59     const sp<IWifiRttControllerEventCallback>& callback,
60     registerEventCallback_cb hidl_status_cb) {
61   return validateAndCall(this,
62                          WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
63                          &WifiRttController::registerEventCallbackInternal,
64                          hidl_status_cb,
65                          callback);
66 }
67 
rangeRequest(uint32_t cmd_id,const hidl_vec<RttConfig> & rtt_configs,rangeRequest_cb hidl_status_cb)68 Return<void> WifiRttController::rangeRequest(
69     uint32_t cmd_id,
70     const hidl_vec<RttConfig>& rtt_configs,
71     rangeRequest_cb hidl_status_cb) {
72   return validateAndCall(this,
73                          WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
74                          &WifiRttController::rangeRequestInternal,
75                          hidl_status_cb,
76                          cmd_id,
77                          rtt_configs);
78 }
79 
rangeCancel(uint32_t cmd_id,const hidl_vec<hidl_array<uint8_t,6>> & addrs,rangeCancel_cb hidl_status_cb)80 Return<void> WifiRttController::rangeCancel(
81     uint32_t cmd_id,
82     const hidl_vec<hidl_array<uint8_t, 6>>& addrs,
83     rangeCancel_cb hidl_status_cb) {
84   return validateAndCall(this,
85                          WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
86                          &WifiRttController::rangeCancelInternal,
87                          hidl_status_cb,
88                          cmd_id,
89                          addrs);
90 }
91 
getCapabilities(getCapabilities_cb hidl_status_cb)92 Return<void> WifiRttController::getCapabilities(
93     getCapabilities_cb hidl_status_cb) {
94   return validateAndCall(this,
95                          WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
96                          &WifiRttController::getCapabilitiesInternal,
97                          hidl_status_cb);
98 }
99 
setLci(uint32_t cmd_id,const RttLciInformation & lci,setLci_cb hidl_status_cb)100 Return<void> WifiRttController::setLci(uint32_t cmd_id,
101                                        const RttLciInformation& lci,
102                                        setLci_cb hidl_status_cb) {
103   return validateAndCall(this,
104                          WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
105                          &WifiRttController::setLciInternal,
106                          hidl_status_cb,
107                          cmd_id,
108                          lci);
109 }
110 
setLcr(uint32_t cmd_id,const RttLcrInformation & lcr,setLcr_cb hidl_status_cb)111 Return<void> WifiRttController::setLcr(uint32_t cmd_id,
112                                        const RttLcrInformation& lcr,
113                                        setLcr_cb hidl_status_cb) {
114   return validateAndCall(this,
115                          WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
116                          &WifiRttController::setLcrInternal,
117                          hidl_status_cb,
118                          cmd_id,
119                          lcr);
120 }
121 
getResponderInfo(getResponderInfo_cb hidl_status_cb)122 Return<void> WifiRttController::getResponderInfo(
123     getResponderInfo_cb hidl_status_cb) {
124   return validateAndCall(this,
125                          WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
126                          &WifiRttController::getResponderInfoInternal,
127                          hidl_status_cb);
128 }
129 
enableResponder(uint32_t cmd_id,const WifiChannelInfo & channel_hint,uint32_t max_duration_seconds,const RttResponder & info,enableResponder_cb hidl_status_cb)130 Return<void> WifiRttController::enableResponder(
131     uint32_t cmd_id,
132     const WifiChannelInfo& channel_hint,
133     uint32_t max_duration_seconds,
134     const RttResponder& info,
135     enableResponder_cb hidl_status_cb) {
136   return validateAndCall(this,
137                          WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
138                          &WifiRttController::enableResponderInternal,
139                          hidl_status_cb,
140                          cmd_id,
141                          channel_hint,
142                          max_duration_seconds,
143                          info);
144 }
145 
disableResponder(uint32_t cmd_id,disableResponder_cb hidl_status_cb)146 Return<void> WifiRttController::disableResponder(
147     uint32_t cmd_id, disableResponder_cb hidl_status_cb) {
148   return validateAndCall(this,
149                          WifiStatusCode::ERROR_WIFI_RTT_CONTROLLER_INVALID,
150                          &WifiRttController::disableResponderInternal,
151                          hidl_status_cb,
152                          cmd_id);
153 }
154 
155 std::pair<WifiStatus, sp<IWifiIface>>
getBoundIfaceInternal()156 WifiRttController::getBoundIfaceInternal() {
157   return {createWifiStatus(WifiStatusCode::SUCCESS), bound_iface_};
158 }
159 
registerEventCallbackInternal(const sp<IWifiRttControllerEventCallback> & callback)160 WifiStatus WifiRttController::registerEventCallbackInternal(
161     const sp<IWifiRttControllerEventCallback>& callback) {
162   // TODO(b/31632518): remove the callback when the client is destroyed
163   event_callbacks_.emplace_back(callback);
164   return createWifiStatus(WifiStatusCode::SUCCESS);
165 }
166 
rangeRequestInternal(uint32_t cmd_id,const std::vector<RttConfig> & rtt_configs)167 WifiStatus WifiRttController::rangeRequestInternal(
168     uint32_t cmd_id, const std::vector<RttConfig>& rtt_configs) {
169   std::vector<legacy_hal::wifi_rtt_config> legacy_configs;
170   if (!hidl_struct_util::convertHidlVectorOfRttConfigToLegacy(
171           rtt_configs, &legacy_configs)) {
172     return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
173   }
174   android::wp<WifiRttController> weak_ptr_this(this);
175   const auto& on_results_callback = [weak_ptr_this](
176       legacy_hal::wifi_request_id id,
177       const std::vector<const legacy_hal::wifi_rtt_result*>& results) {
178     const auto shared_ptr_this = weak_ptr_this.promote();
179     if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
180       LOG(ERROR) << "Callback invoked on an invalid object";
181       return;
182     }
183     std::vector<RttResult> hidl_results;
184     if (!hidl_struct_util::convertLegacyVectorOfRttResultToHidl(
185             results, &hidl_results)) {
186       LOG(ERROR) << "Failed to convert rtt results to HIDL structs";
187       return;
188     }
189     for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
190       callback->onResults(id, hidl_results);
191     }
192   };
193   legacy_hal::wifi_error legacy_status =
194       legacy_hal_.lock()->startRttRangeRequest(
195           cmd_id, legacy_configs, on_results_callback);
196   return createWifiStatusFromLegacyError(legacy_status);
197 }
198 
rangeCancelInternal(uint32_t cmd_id,const std::vector<hidl_array<uint8_t,6>> & addrs)199 WifiStatus WifiRttController::rangeCancelInternal(
200     uint32_t cmd_id, const std::vector<hidl_array<uint8_t, 6>>& addrs) {
201   std::vector<std::array<uint8_t, 6>> legacy_addrs;
202   for (const auto& addr : addrs) {
203     legacy_addrs.push_back(addr);
204   }
205   legacy_hal::wifi_error legacy_status =
206       legacy_hal_.lock()->cancelRttRangeRequest(cmd_id, legacy_addrs);
207   return createWifiStatusFromLegacyError(legacy_status);
208 }
209 
210 std::pair<WifiStatus, RttCapabilities>
getCapabilitiesInternal()211 WifiRttController::getCapabilitiesInternal() {
212   legacy_hal::wifi_error legacy_status;
213   legacy_hal::wifi_rtt_capabilities legacy_caps;
214   std::tie(legacy_status, legacy_caps) =
215       legacy_hal_.lock()->getRttCapabilities();
216   if (legacy_status != legacy_hal::WIFI_SUCCESS) {
217     return {createWifiStatusFromLegacyError(legacy_status), {}};
218   }
219   RttCapabilities hidl_caps;
220   if (!hidl_struct_util::convertLegacyRttCapabilitiesToHidl(legacy_caps,
221                                                             &hidl_caps)) {
222     return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
223   }
224   return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
225 }
226 
setLciInternal(uint32_t cmd_id,const RttLciInformation & lci)227 WifiStatus WifiRttController::setLciInternal(uint32_t cmd_id,
228                                              const RttLciInformation& lci) {
229   legacy_hal::wifi_lci_information legacy_lci;
230   if (!hidl_struct_util::convertHidlRttLciInformationToLegacy(lci,
231                                                               &legacy_lci)) {
232     return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
233   }
234   legacy_hal::wifi_error legacy_status =
235       legacy_hal_.lock()->setRttLci(cmd_id, legacy_lci);
236   return createWifiStatusFromLegacyError(legacy_status);
237 }
238 
setLcrInternal(uint32_t cmd_id,const RttLcrInformation & lcr)239 WifiStatus WifiRttController::setLcrInternal(uint32_t cmd_id,
240                                              const RttLcrInformation& lcr) {
241   legacy_hal::wifi_lcr_information legacy_lcr;
242   if (!hidl_struct_util::convertHidlRttLcrInformationToLegacy(lcr,
243                                                               &legacy_lcr)) {
244     return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
245   }
246   legacy_hal::wifi_error legacy_status =
247       legacy_hal_.lock()->setRttLcr(cmd_id, legacy_lcr);
248   return createWifiStatusFromLegacyError(legacy_status);
249 }
250 
251 std::pair<WifiStatus, RttResponder>
getResponderInfoInternal()252 WifiRttController::getResponderInfoInternal() {
253   legacy_hal::wifi_error legacy_status;
254   legacy_hal::wifi_rtt_responder legacy_responder;
255   std::tie(legacy_status, legacy_responder) =
256       legacy_hal_.lock()->getRttResponderInfo();
257   if (legacy_status != legacy_hal::WIFI_SUCCESS) {
258     return {createWifiStatusFromLegacyError(legacy_status), {}};
259   }
260   RttResponder hidl_responder;
261   if (!hidl_struct_util::convertLegacyRttResponderToHidl(legacy_responder,
262                                                          &hidl_responder)) {
263     return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
264   }
265   return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_responder};
266 }
267 
enableResponderInternal(uint32_t cmd_id,const WifiChannelInfo & channel_hint,uint32_t max_duration_seconds,const RttResponder & info)268 WifiStatus WifiRttController::enableResponderInternal(
269     uint32_t cmd_id,
270     const WifiChannelInfo& channel_hint,
271     uint32_t max_duration_seconds,
272     const RttResponder& info) {
273   legacy_hal::wifi_channel_info legacy_channel_info;
274   if (!hidl_struct_util::convertHidlWifiChannelInfoToLegacy(
275           channel_hint, &legacy_channel_info)) {
276     return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
277   }
278   legacy_hal::wifi_rtt_responder legacy_responder;
279   if (!hidl_struct_util::convertHidlRttResponderToLegacy(info,
280                                                          &legacy_responder)) {
281     return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
282   }
283   legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->enableRttResponder(
284       cmd_id, legacy_channel_info, max_duration_seconds, legacy_responder);
285   return createWifiStatusFromLegacyError(legacy_status);
286 }
287 
disableResponderInternal(uint32_t cmd_id)288 WifiStatus WifiRttController::disableResponderInternal(uint32_t cmd_id) {
289   legacy_hal::wifi_error legacy_status =
290       legacy_hal_.lock()->disableRttResponder(cmd_id);
291   return createWifiStatusFromLegacyError(legacy_status);
292 }
293 }  // namespace implementation
294 }  // namespace V1_0
295 }  // namespace wifi
296 }  // namespace hardware
297 }  // namespace android
298