blob: cc8edd104174ac9cfeb4a296124f5ca856ecc14a [file] [log] [blame]
Roshan Pius3e2d6712016-10-06 13:16:23 -07001/*
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
Roshan Pius3e2d6712016-10-06 13:16:23 -070017#include <android-base/logging.h>
18
Roshan Pius907d4a22016-10-27 12:48:12 -070019#include "hidl_return_util.h"
Roshan Pius970f0312016-12-05 15:25:51 -080020#include "hidl_struct_util.h"
Roshan Pius907d4a22016-10-27 12:48:12 -070021#include "wifi_sta_iface.h"
Roshan Pius734fea02016-10-11 08:30:28 -070022#include "wifi_status_util.h"
Roshan Pius3e2d6712016-10-06 13:16:23 -070023
24namespace android {
25namespace hardware {
26namespace wifi {
27namespace V1_0 {
28namespace implementation {
Roshan Pius907d4a22016-10-27 12:48:12 -070029using hidl_return_util::validateAndCall;
Roshan Pius3e2d6712016-10-06 13:16:23 -070030
Roshan Pius6cedc972016-10-28 10:11:17 -070031WifiStaIface::WifiStaIface(
32 const std::string& ifname,
33 const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal)
Roshan Pius3e2d6712016-10-06 13:16:23 -070034 : ifname_(ifname), legacy_hal_(legacy_hal), is_valid_(true) {}
35
36void WifiStaIface::invalidate() {
37 legacy_hal_.reset();
Roshan Piusa04ba3f2016-10-27 14:36:26 -070038 event_callbacks_.clear();
Roshan Pius3e2d6712016-10-06 13:16:23 -070039 is_valid_ = false;
40}
41
Roshan Pius907d4a22016-10-27 12:48:12 -070042bool WifiStaIface::isValid() {
43 return is_valid_;
44}
45
Roshan Pius970f0312016-12-05 15:25:51 -080046std::vector<sp<IWifiStaIfaceEventCallback>> WifiStaIface::getEventCallbacks() {
47 return event_callbacks_;
48}
49
Roshan Pius734fea02016-10-11 08:30:28 -070050Return<void> WifiStaIface::getName(getName_cb hidl_status_cb) {
Roshan Pius907d4a22016-10-27 12:48:12 -070051 return validateAndCall(this,
52 WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
53 &WifiStaIface::getNameInternal,
54 hidl_status_cb);
Roshan Pius3e2d6712016-10-06 13:16:23 -070055}
56
Roshan Pius734fea02016-10-11 08:30:28 -070057Return<void> WifiStaIface::getType(getType_cb hidl_status_cb) {
Roshan Pius907d4a22016-10-27 12:48:12 -070058 return validateAndCall(this,
59 WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
60 &WifiStaIface::getTypeInternal,
61 hidl_status_cb);
62}
63
Roshan Piusa04ba3f2016-10-27 14:36:26 -070064Return<void> WifiStaIface::registerEventCallback(
65 const sp<IWifiStaIfaceEventCallback>& callback,
66 registerEventCallback_cb hidl_status_cb) {
67 return validateAndCall(this,
68 WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
69 &WifiStaIface::registerEventCallbackInternal,
70 hidl_status_cb,
71 callback);
72}
73
74Return<void> WifiStaIface::getCapabilities(getCapabilities_cb hidl_status_cb) {
75 return validateAndCall(this,
76 WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
77 &WifiStaIface::getCapabilitiesInternal,
78 hidl_status_cb);
79}
80
81Return<void> WifiStaIface::getApfPacketFilterCapabilities(
82 getApfPacketFilterCapabilities_cb hidl_status_cb) {
83 return validateAndCall(this,
84 WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
85 &WifiStaIface::getApfPacketFilterCapabilitiesInternal,
86 hidl_status_cb);
87}
88
89Return<void> WifiStaIface::installApfPacketFilter(
90 uint32_t cmd_id,
91 const hidl_vec<uint8_t>& program,
92 installApfPacketFilter_cb hidl_status_cb) {
93 return validateAndCall(this,
94 WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
95 &WifiStaIface::installApfPacketFilterInternal,
96 hidl_status_cb,
97 cmd_id,
98 program);
99}
100
101Return<void> WifiStaIface::getBackgroundScanCapabilities(
102 getBackgroundScanCapabilities_cb hidl_status_cb) {
103 return validateAndCall(this,
104 WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
105 &WifiStaIface::getBackgroundScanCapabilitiesInternal,
106 hidl_status_cb);
107}
108
109Return<void> WifiStaIface::getValidFrequenciesForBackgroundScan(
110 StaBackgroundScanBand band,
111 getValidFrequenciesForBackgroundScan_cb hidl_status_cb) {
112 return validateAndCall(
113 this,
114 WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
115 &WifiStaIface::getValidFrequenciesForBackgroundScanInternal,
116 hidl_status_cb,
117 band);
118}
119
120Return<void> WifiStaIface::startBackgroundScan(
121 uint32_t cmd_id,
122 const StaBackgroundScanParameters& params,
123 startBackgroundScan_cb hidl_status_cb) {
124 return validateAndCall(this,
125 WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
126 &WifiStaIface::startBackgroundScanInternal,
127 hidl_status_cb,
128 cmd_id,
129 params);
130}
131
132Return<void> WifiStaIface::stopBackgroundScan(
133 uint32_t cmd_id, stopBackgroundScan_cb hidl_status_cb) {
134 return validateAndCall(this,
135 WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
136 &WifiStaIface::stopBackgroundScanInternal,
137 hidl_status_cb,
138 cmd_id);
139}
140
141Return<void> WifiStaIface::enableLinkLayerStatsCollection(
142 bool debug, enableLinkLayerStatsCollection_cb hidl_status_cb) {
143 return validateAndCall(this,
144 WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
145 &WifiStaIface::enableLinkLayerStatsCollectionInternal,
146 hidl_status_cb,
147 debug);
148}
149
150Return<void> WifiStaIface::disableLinkLayerStatsCollection(
151 disableLinkLayerStatsCollection_cb hidl_status_cb) {
152 return validateAndCall(this,
153 WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
154 &WifiStaIface::disableLinkLayerStatsCollectionInternal,
155 hidl_status_cb);
156}
157
158Return<void> WifiStaIface::getLinkLayerStats(
159 getLinkLayerStats_cb hidl_status_cb) {
160 return validateAndCall(this,
161 WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
162 &WifiStaIface::getLinkLayerStatsInternal,
163 hidl_status_cb);
164}
165
166Return<void> WifiStaIface::startDebugPacketFateMonitoring(
167 startDebugPacketFateMonitoring_cb hidl_status_cb) {
168 return validateAndCall(this,
169 WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
170 &WifiStaIface::startDebugPacketFateMonitoringInternal,
171 hidl_status_cb);
172}
173
174Return<void> WifiStaIface::stopDebugPacketFateMonitoring(
175 stopDebugPacketFateMonitoring_cb hidl_status_cb) {
176 return validateAndCall(this,
177 WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
178 &WifiStaIface::stopDebugPacketFateMonitoringInternal,
179 hidl_status_cb);
180}
181
182Return<void> WifiStaIface::getDebugTxPacketFates(
183 getDebugTxPacketFates_cb hidl_status_cb) {
184 return validateAndCall(this,
185 WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
186 &WifiStaIface::getDebugTxPacketFatesInternal,
187 hidl_status_cb);
188}
189
190Return<void> WifiStaIface::getDebugRxPacketFates(
191 getDebugRxPacketFates_cb hidl_status_cb) {
192 return validateAndCall(this,
193 WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
194 &WifiStaIface::getDebugRxPacketFatesInternal,
195 hidl_status_cb);
196}
197
Roshan Pius907d4a22016-10-27 12:48:12 -0700198std::pair<WifiStatus, std::string> WifiStaIface::getNameInternal() {
199 return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
200}
201
202std::pair<WifiStatus, IfaceType> WifiStaIface::getTypeInternal() {
203 return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::STA};
Roshan Pius3e2d6712016-10-06 13:16:23 -0700204}
205
Roshan Piusa04ba3f2016-10-27 14:36:26 -0700206WifiStatus WifiStaIface::registerEventCallbackInternal(
207 const sp<IWifiStaIfaceEventCallback>& callback) {
208 // TODO(b/31632518): remove the callback when the client is destroyed
209 event_callbacks_.emplace_back(callback);
210 return createWifiStatus(WifiStatusCode::SUCCESS);
211}
212
213std::pair<WifiStatus, uint32_t> WifiStaIface::getCapabilitiesInternal() {
Roshan Pius970f0312016-12-05 15:25:51 -0800214 legacy_hal::wifi_error legacy_status;
215 uint32_t legacy_feature_set;
216 std::tie(legacy_status, legacy_feature_set) =
217 legacy_hal_.lock()->getSupportedFeatureSet();
218 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
219 return {createWifiStatusFromLegacyError(legacy_status), 0};
220 }
221 uint32_t legacy_logger_feature_set;
222 std::tie(legacy_status, legacy_logger_feature_set) =
223 legacy_hal_.lock()->getLoggerSupportedFeatureSet();
224 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
225 return {createWifiStatusFromLegacyError(legacy_status), 0};
226 }
227 uint32_t hidl_caps;
228 if (!hidl_struct_util::convertLegacyFeaturesToHidlStaCapabilities(
229 legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
230 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
231 }
232 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
Roshan Piusa04ba3f2016-10-27 14:36:26 -0700233}
234
235std::pair<WifiStatus, StaApfPacketFilterCapabilities>
236WifiStaIface::getApfPacketFilterCapabilitiesInternal() {
Roshan Pius970f0312016-12-05 15:25:51 -0800237 legacy_hal::wifi_error legacy_status;
238 legacy_hal::PacketFilterCapabilities legacy_caps;
239 std::tie(legacy_status, legacy_caps) =
240 legacy_hal_.lock()->getPacketFilterCapabilities();
241 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
242 return {createWifiStatusFromLegacyError(legacy_status), {}};
243 }
244 StaApfPacketFilterCapabilities hidl_caps;
245 if (!hidl_struct_util::convertLegacyApfCapabilitiesToHidl(legacy_caps,
246 &hidl_caps)) {
247 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
248 }
249 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
Roshan Piusa04ba3f2016-10-27 14:36:26 -0700250}
251
252WifiStatus WifiStaIface::installApfPacketFilterInternal(
Roshan Pius970f0312016-12-05 15:25:51 -0800253 uint32_t /* cmd_id */, const std::vector<uint8_t>& program) {
254 legacy_hal::wifi_error legacy_status =
255 legacy_hal_.lock()->setPacketFilter(program);
256 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusa04ba3f2016-10-27 14:36:26 -0700257}
258
259std::pair<WifiStatus, StaBackgroundScanCapabilities>
260WifiStaIface::getBackgroundScanCapabilitiesInternal() {
Roshan Pius970f0312016-12-05 15:25:51 -0800261 legacy_hal::wifi_error legacy_status;
262 legacy_hal::wifi_gscan_capabilities legacy_caps;
263 std::tie(legacy_status, legacy_caps) =
264 legacy_hal_.lock()->getGscanCapabilities();
265 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
266 return {createWifiStatusFromLegacyError(legacy_status), {}};
267 }
268 StaBackgroundScanCapabilities hidl_caps;
269 if (!hidl_struct_util::convertLegacyGscanCapabilitiesToHidl(legacy_caps,
270 &hidl_caps)) {
271 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
272 }
273 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
Roshan Piusa04ba3f2016-10-27 14:36:26 -0700274}
275
276std::pair<WifiStatus, std::vector<WifiChannelInMhz>>
277WifiStaIface::getValidFrequenciesForBackgroundScanInternal(
Roshan Pius970f0312016-12-05 15:25:51 -0800278 StaBackgroundScanBand band) {
279 static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t), "Size mismatch");
280 legacy_hal::wifi_error legacy_status;
281 std::vector<uint32_t> valid_frequencies;
282 std::tie(legacy_status, valid_frequencies) =
283 legacy_hal_.lock()->getValidFrequenciesForGscan(
284 hidl_struct_util::convertHidlGscanBandToLegacy(band));
285 return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies};
Roshan Piusa04ba3f2016-10-27 14:36:26 -0700286}
287
288WifiStatus WifiStaIface::startBackgroundScanInternal(
Roshan Pius970f0312016-12-05 15:25:51 -0800289 uint32_t cmd_id, const StaBackgroundScanParameters& params) {
290 legacy_hal::wifi_scan_cmd_params legacy_params;
291 if (!hidl_struct_util::convertHidlGscanParamsToLegacy(params,
292 &legacy_params)) {
293 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
294 }
295 android::wp<WifiStaIface> weak_ptr_this(this);
296 const auto& on_failure_callback =
297 [weak_ptr_this](legacy_hal::wifi_request_id id) {
298 const auto shared_ptr_this = weak_ptr_this.promote();
299 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
300 LOG(ERROR) << "Callback invoked on an invalid object";
301 return;
302 }
303 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
304 callback->onBackgroundScanFailure(id);
305 }
306 };
307 const auto& on_results_callback = [weak_ptr_this](
308 legacy_hal::wifi_request_id id,
309 const std::vector<legacy_hal::wifi_cached_scan_results>& results) {
310 const auto shared_ptr_this = weak_ptr_this.promote();
311 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
312 LOG(ERROR) << "Callback invoked on an invalid object";
313 return;
314 }
315 std::vector<StaScanData> hidl_scan_datas;
316 if (!hidl_struct_util::convertLegacyVectorOfCachedGscanResultsToHidl(
317 results, &hidl_scan_datas)) {
318 LOG(ERROR) << "Failed to convert scan results to HIDL structs";
319 return;
320 }
321 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
322 callback->onBackgroundScanResults(id, hidl_scan_datas);
323 }
324 };
325 const auto& on_full_result_callback = [weak_ptr_this](
326 legacy_hal::wifi_request_id id,
327 const legacy_hal::wifi_scan_result* result,
328 uint32_t /* buckets_scanned */) {
329 const auto shared_ptr_this = weak_ptr_this.promote();
330 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
331 LOG(ERROR) << "Callback invoked on an invalid object";
332 return;
333 }
334 StaScanResult hidl_scan_result;
335 if (!hidl_struct_util::convertLegacyGscanResultToHidl(
336 *result, true, &hidl_scan_result)) {
337 LOG(ERROR) << "Failed to convert full scan results to HIDL structs";
338 return;
339 }
340 for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
341 callback->onBackgroundFullScanResult(id, hidl_scan_result);
342 }
343 };
344 legacy_hal::wifi_error legacy_status =
345 legacy_hal_.lock()->startGscan(cmd_id,
346 legacy_params,
347 on_failure_callback,
348 on_results_callback,
349 on_full_result_callback);
350 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusa04ba3f2016-10-27 14:36:26 -0700351}
352
Roshan Pius970f0312016-12-05 15:25:51 -0800353WifiStatus WifiStaIface::stopBackgroundScanInternal(uint32_t cmd_id) {
354 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->stopGscan(cmd_id);
355 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusa04ba3f2016-10-27 14:36:26 -0700356}
357
Roshan Pius970f0312016-12-05 15:25:51 -0800358WifiStatus WifiStaIface::enableLinkLayerStatsCollectionInternal(bool debug) {
359 legacy_hal::wifi_error legacy_status =
360 legacy_hal_.lock()->enableLinkLayerStats(debug);
361 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusa04ba3f2016-10-27 14:36:26 -0700362}
363
364WifiStatus WifiStaIface::disableLinkLayerStatsCollectionInternal() {
Roshan Pius970f0312016-12-05 15:25:51 -0800365 legacy_hal::wifi_error legacy_status =
366 legacy_hal_.lock()->disableLinkLayerStats();
367 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusa04ba3f2016-10-27 14:36:26 -0700368}
369
370std::pair<WifiStatus, StaLinkLayerStats>
371WifiStaIface::getLinkLayerStatsInternal() {
Roshan Pius970f0312016-12-05 15:25:51 -0800372 legacy_hal::wifi_error legacy_status;
373 legacy_hal::LinkLayerStats legacy_stats;
374 std::tie(legacy_status, legacy_stats) =
375 legacy_hal_.lock()->getLinkLayerStats();
376 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
377 return {createWifiStatusFromLegacyError(legacy_status), {}};
378 }
379 StaLinkLayerStats hidl_stats;
380 if (!hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats,
381 &hidl_stats)) {
382 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
383 }
384 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
Roshan Piusa04ba3f2016-10-27 14:36:26 -0700385}
386
387WifiStatus WifiStaIface::startDebugPacketFateMonitoringInternal() {
Roshan Pius970f0312016-12-05 15:25:51 -0800388 legacy_hal::wifi_error legacy_status =
389 legacy_hal_.lock()->startPktFateMonitoring();
390 return createWifiStatusFromLegacyError(legacy_status);
Roshan Piusa04ba3f2016-10-27 14:36:26 -0700391}
392
393WifiStatus WifiStaIface::stopDebugPacketFateMonitoringInternal() {
Roshan Pius970f0312016-12-05 15:25:51 -0800394 // There is no stop in legacy HAL implementation.
395 return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED);
Roshan Piusa04ba3f2016-10-27 14:36:26 -0700396}
397
398std::pair<WifiStatus, std::vector<WifiDebugTxPacketFateReport>>
399WifiStaIface::getDebugTxPacketFatesInternal() {
Roshan Pius970f0312016-12-05 15:25:51 -0800400 legacy_hal::wifi_error legacy_status;
401 std::vector<legacy_hal::wifi_tx_report> legacy_fates;
402 std::tie(legacy_status, legacy_fates) = legacy_hal_.lock()->getTxPktFates();
403 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
404 return {createWifiStatusFromLegacyError(legacy_status), {}};
405 }
406 std::vector<WifiDebugTxPacketFateReport> hidl_fates;
407 if (!hidl_struct_util::convertLegacyVectorOfDebugTxPacketFateToHidl(
408 legacy_fates, &hidl_fates)) {
409 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
410 }
411 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_fates};
Roshan Piusa04ba3f2016-10-27 14:36:26 -0700412}
413
414std::pair<WifiStatus, std::vector<WifiDebugRxPacketFateReport>>
415WifiStaIface::getDebugRxPacketFatesInternal() {
Roshan Pius970f0312016-12-05 15:25:51 -0800416 legacy_hal::wifi_error legacy_status;
417 std::vector<legacy_hal::wifi_rx_report> legacy_fates;
418 std::tie(legacy_status, legacy_fates) = legacy_hal_.lock()->getRxPktFates();
419 if (legacy_status != legacy_hal::WIFI_SUCCESS) {
420 return {createWifiStatusFromLegacyError(legacy_status), {}};
421 }
422 std::vector<WifiDebugRxPacketFateReport> hidl_fates;
423 if (!hidl_struct_util::convertLegacyVectorOfDebugRxPacketFateToHidl(
424 legacy_fates, &hidl_fates)) {
425 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
426 }
427 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_fates};
Roshan Piusa04ba3f2016-10-27 14:36:26 -0700428}
429
Roshan Pius3e2d6712016-10-06 13:16:23 -0700430} // namespace implementation
431} // namespace V1_0
432} // namespace wifi
433} // namespace hardware
434} // namespace android