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
24namespace android {
25namespace hardware {
26namespace wifi {
27namespace V1_0 {
28namespace implementation {
29using hidl_return_util::validateAndCall;
30
31WifiRttController::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
36void WifiRttController::invalidate() {
37  legacy_hal_.reset();
38  event_callbacks_.clear();
39  is_valid_ = false;
40}
41
42bool WifiRttController::isValid() {
43  return is_valid_;
44}
45
46std::vector<sp<IWifiRttControllerEventCallback>>
47WifiRttController::getEventCallbacks() {
48  return event_callbacks_;
49}
50
51Return<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
58Return<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
68Return<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
80Return<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
92Return<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
100Return<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
111Return<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
122Return<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
130Return<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
146Return<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
155std::pair<WifiStatus, sp<IWifiIface>>
156WifiRttController::getBoundIfaceInternal() {
157  return {createWifiStatus(WifiStatusCode::SUCCESS), bound_iface_};
158}
159
160WifiStatus 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
167WifiStatus 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
199WifiStatus 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
210std::pair<WifiStatus, RttCapabilities>
211WifiRttController::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
227WifiStatus 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
239WifiStatus 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
251std::pair<WifiStatus, RttResponder>
252WifiRttController::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
268WifiStatus 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
288WifiStatus 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