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