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 <array>
18 #include <chrono>
19
20 #include <android-base/logging.h>
21 #include <cutils/properties.h>
22
23 #include "hidl_sync_util.h"
24 #include "wifi_legacy_hal.h"
25 #include "wifi_legacy_hal_stubs.h"
26
27 namespace {
28 // Constants ported over from the legacy HAL calling code
29 // (com_android_server_wifi_WifiNative.cpp). This will all be thrown
30 // away when this shim layer is replaced by the real vendor
31 // implementation.
32 static constexpr uint32_t kMaxVersionStringLength = 256;
33 static constexpr uint32_t kMaxCachedGscanResults = 64;
34 static constexpr uint32_t kMaxGscanFrequenciesForBand = 64;
35 static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128;
36 static constexpr uint32_t kMaxWakeReasonStatsArraySize = 32;
37 static constexpr uint32_t kMaxRingBuffers = 10;
38 static constexpr uint32_t kMaxStopCompleteWaitMs = 100;
39
40 // Helper function to create a non-const char* for legacy Hal API's.
makeCharVec(const std::string & str)41 std::vector<char> makeCharVec(const std::string& str) {
42 std::vector<char> vec(str.size() + 1);
43 vec.assign(str.begin(), str.end());
44 vec.push_back('\0');
45 return vec;
46 }
47 } // namespace
48
49 namespace android {
50 namespace hardware {
51 namespace wifi {
52 namespace V1_1 {
53 namespace implementation {
54 namespace legacy_hal {
55 // Legacy HAL functions accept "C" style function pointers, so use global
56 // functions to pass to the legacy HAL function and store the corresponding
57 // std::function methods to be invoked.
58 //
59 // Callback to be invoked once |stop| is complete
60 std::function<void(wifi_handle handle)> on_stop_complete_internal_callback;
onAsyncStopComplete(wifi_handle handle)61 void onAsyncStopComplete(wifi_handle handle) {
62 const auto lock = hidl_sync_util::acquireGlobalLock();
63 if (on_stop_complete_internal_callback) {
64 on_stop_complete_internal_callback(handle);
65 // Invalidate this callback since we don't want this firing again.
66 on_stop_complete_internal_callback = nullptr;
67 }
68 }
69
70 // Callback to be invoked for driver dump.
71 std::function<void(char*, int)> on_driver_memory_dump_internal_callback;
onSyncDriverMemoryDump(char * buffer,int buffer_size)72 void onSyncDriverMemoryDump(char* buffer, int buffer_size) {
73 if (on_driver_memory_dump_internal_callback) {
74 on_driver_memory_dump_internal_callback(buffer, buffer_size);
75 }
76 }
77
78 // Callback to be invoked for firmware dump.
79 std::function<void(char*, int)> on_firmware_memory_dump_internal_callback;
onSyncFirmwareMemoryDump(char * buffer,int buffer_size)80 void onSyncFirmwareMemoryDump(char* buffer, int buffer_size) {
81 if (on_firmware_memory_dump_internal_callback) {
82 on_firmware_memory_dump_internal_callback(buffer, buffer_size);
83 }
84 }
85
86 // Callback to be invoked for Gscan events.
87 std::function<void(wifi_request_id, wifi_scan_event)>
88 on_gscan_event_internal_callback;
onAsyncGscanEvent(wifi_request_id id,wifi_scan_event event)89 void onAsyncGscanEvent(wifi_request_id id, wifi_scan_event event) {
90 const auto lock = hidl_sync_util::acquireGlobalLock();
91 if (on_gscan_event_internal_callback) {
92 on_gscan_event_internal_callback(id, event);
93 }
94 }
95
96 // Callback to be invoked for Gscan full results.
97 std::function<void(wifi_request_id, wifi_scan_result*, uint32_t)>
98 on_gscan_full_result_internal_callback;
onAsyncGscanFullResult(wifi_request_id id,wifi_scan_result * result,uint32_t buckets_scanned)99 void onAsyncGscanFullResult(wifi_request_id id,
100 wifi_scan_result* result,
101 uint32_t buckets_scanned) {
102 const auto lock = hidl_sync_util::acquireGlobalLock();
103 if (on_gscan_full_result_internal_callback) {
104 on_gscan_full_result_internal_callback(id, result, buckets_scanned);
105 }
106 }
107
108 // Callback to be invoked for link layer stats results.
109 std::function<void((wifi_request_id, wifi_iface_stat*, int, wifi_radio_stat*))>
110 on_link_layer_stats_result_internal_callback;
onSyncLinkLayerStatsResult(wifi_request_id id,wifi_iface_stat * iface_stat,int num_radios,wifi_radio_stat * radio_stat)111 void onSyncLinkLayerStatsResult(wifi_request_id id,
112 wifi_iface_stat* iface_stat,
113 int num_radios,
114 wifi_radio_stat* radio_stat) {
115 if (on_link_layer_stats_result_internal_callback) {
116 on_link_layer_stats_result_internal_callback(
117 id, iface_stat, num_radios, radio_stat);
118 }
119 }
120
121 // Callback to be invoked for rssi threshold breach.
122 std::function<void((wifi_request_id, uint8_t*, int8_t))>
123 on_rssi_threshold_breached_internal_callback;
onAsyncRssiThresholdBreached(wifi_request_id id,uint8_t * bssid,int8_t rssi)124 void onAsyncRssiThresholdBreached(wifi_request_id id,
125 uint8_t* bssid,
126 int8_t rssi) {
127 const auto lock = hidl_sync_util::acquireGlobalLock();
128 if (on_rssi_threshold_breached_internal_callback) {
129 on_rssi_threshold_breached_internal_callback(id, bssid, rssi);
130 }
131 }
132
133 // Callback to be invoked for ring buffer data indication.
134 std::function<void(char*, char*, int, wifi_ring_buffer_status*)>
135 on_ring_buffer_data_internal_callback;
onAsyncRingBufferData(char * ring_name,char * buffer,int buffer_size,wifi_ring_buffer_status * status)136 void onAsyncRingBufferData(char* ring_name,
137 char* buffer,
138 int buffer_size,
139 wifi_ring_buffer_status* status) {
140 const auto lock = hidl_sync_util::acquireGlobalLock();
141 if (on_ring_buffer_data_internal_callback) {
142 on_ring_buffer_data_internal_callback(
143 ring_name, buffer, buffer_size, status);
144 }
145 }
146
147 // Callback to be invoked for error alert indication.
148 std::function<void(wifi_request_id, char*, int, int)>
149 on_error_alert_internal_callback;
onAsyncErrorAlert(wifi_request_id id,char * buffer,int buffer_size,int err_code)150 void onAsyncErrorAlert(wifi_request_id id,
151 char* buffer,
152 int buffer_size,
153 int err_code) {
154 const auto lock = hidl_sync_util::acquireGlobalLock();
155 if (on_error_alert_internal_callback) {
156 on_error_alert_internal_callback(id, buffer, buffer_size, err_code);
157 }
158 }
159
160 // Callback to be invoked for rtt results results.
161 std::function<void(
162 wifi_request_id, unsigned num_results, wifi_rtt_result* rtt_results[])>
163 on_rtt_results_internal_callback;
onAsyncRttResults(wifi_request_id id,unsigned num_results,wifi_rtt_result * rtt_results[])164 void onAsyncRttResults(wifi_request_id id,
165 unsigned num_results,
166 wifi_rtt_result* rtt_results[]) {
167 const auto lock = hidl_sync_util::acquireGlobalLock();
168 if (on_rtt_results_internal_callback) {
169 on_rtt_results_internal_callback(id, num_results, rtt_results);
170 on_rtt_results_internal_callback = nullptr;
171 }
172 }
173
174 // Callbacks for the various NAN operations.
175 // NOTE: These have very little conversions to perform before invoking the user
176 // callbacks.
177 // So, handle all of them here directly to avoid adding an unnecessary layer.
178 std::function<void(transaction_id, const NanResponseMsg&)>
179 on_nan_notify_response_user_callback;
onAysncNanNotifyResponse(transaction_id id,NanResponseMsg * msg)180 void onAysncNanNotifyResponse(transaction_id id, NanResponseMsg* msg) {
181 const auto lock = hidl_sync_util::acquireGlobalLock();
182 if (on_nan_notify_response_user_callback && msg) {
183 on_nan_notify_response_user_callback(id, *msg);
184 }
185 }
186
187 std::function<void(const NanPublishRepliedInd&)>
188 on_nan_event_publish_replied_user_callback;
onAysncNanEventPublishReplied(NanPublishRepliedInd *)189 void onAysncNanEventPublishReplied(NanPublishRepliedInd* /* event */) {
190 LOG(ERROR) << "onAysncNanEventPublishReplied triggered";
191 }
192
193 std::function<void(const NanPublishTerminatedInd&)>
194 on_nan_event_publish_terminated_user_callback;
onAysncNanEventPublishTerminated(NanPublishTerminatedInd * event)195 void onAysncNanEventPublishTerminated(NanPublishTerminatedInd* event) {
196 const auto lock = hidl_sync_util::acquireGlobalLock();
197 if (on_nan_event_publish_terminated_user_callback && event) {
198 on_nan_event_publish_terminated_user_callback(*event);
199 }
200 }
201
202 std::function<void(const NanMatchInd&)> on_nan_event_match_user_callback;
onAysncNanEventMatch(NanMatchInd * event)203 void onAysncNanEventMatch(NanMatchInd* event) {
204 const auto lock = hidl_sync_util::acquireGlobalLock();
205 if (on_nan_event_match_user_callback && event) {
206 on_nan_event_match_user_callback(*event);
207 }
208 }
209
210 std::function<void(const NanMatchExpiredInd&)>
211 on_nan_event_match_expired_user_callback;
onAysncNanEventMatchExpired(NanMatchExpiredInd * event)212 void onAysncNanEventMatchExpired(NanMatchExpiredInd* event) {
213 const auto lock = hidl_sync_util::acquireGlobalLock();
214 if (on_nan_event_match_expired_user_callback && event) {
215 on_nan_event_match_expired_user_callback(*event);
216 }
217 }
218
219 std::function<void(const NanSubscribeTerminatedInd&)>
220 on_nan_event_subscribe_terminated_user_callback;
onAysncNanEventSubscribeTerminated(NanSubscribeTerminatedInd * event)221 void onAysncNanEventSubscribeTerminated(NanSubscribeTerminatedInd* event) {
222 const auto lock = hidl_sync_util::acquireGlobalLock();
223 if (on_nan_event_subscribe_terminated_user_callback && event) {
224 on_nan_event_subscribe_terminated_user_callback(*event);
225 }
226 }
227
228 std::function<void(const NanFollowupInd&)> on_nan_event_followup_user_callback;
onAysncNanEventFollowup(NanFollowupInd * event)229 void onAysncNanEventFollowup(NanFollowupInd* event) {
230 const auto lock = hidl_sync_util::acquireGlobalLock();
231 if (on_nan_event_followup_user_callback && event) {
232 on_nan_event_followup_user_callback(*event);
233 }
234 }
235
236 std::function<void(const NanDiscEngEventInd&)>
237 on_nan_event_disc_eng_event_user_callback;
onAysncNanEventDiscEngEvent(NanDiscEngEventInd * event)238 void onAysncNanEventDiscEngEvent(NanDiscEngEventInd* event) {
239 const auto lock = hidl_sync_util::acquireGlobalLock();
240 if (on_nan_event_disc_eng_event_user_callback && event) {
241 on_nan_event_disc_eng_event_user_callback(*event);
242 }
243 }
244
245 std::function<void(const NanDisabledInd&)> on_nan_event_disabled_user_callback;
onAysncNanEventDisabled(NanDisabledInd * event)246 void onAysncNanEventDisabled(NanDisabledInd* event) {
247 const auto lock = hidl_sync_util::acquireGlobalLock();
248 if (on_nan_event_disabled_user_callback && event) {
249 on_nan_event_disabled_user_callback(*event);
250 }
251 }
252
253 std::function<void(const NanTCAInd&)> on_nan_event_tca_user_callback;
onAysncNanEventTca(NanTCAInd * event)254 void onAysncNanEventTca(NanTCAInd* event) {
255 const auto lock = hidl_sync_util::acquireGlobalLock();
256 if (on_nan_event_tca_user_callback && event) {
257 on_nan_event_tca_user_callback(*event);
258 }
259 }
260
261 std::function<void(const NanBeaconSdfPayloadInd&)>
262 on_nan_event_beacon_sdf_payload_user_callback;
onAysncNanEventBeaconSdfPayload(NanBeaconSdfPayloadInd * event)263 void onAysncNanEventBeaconSdfPayload(NanBeaconSdfPayloadInd* event) {
264 const auto lock = hidl_sync_util::acquireGlobalLock();
265 if (on_nan_event_beacon_sdf_payload_user_callback && event) {
266 on_nan_event_beacon_sdf_payload_user_callback(*event);
267 }
268 }
269
270 std::function<void(const NanDataPathRequestInd&)>
271 on_nan_event_data_path_request_user_callback;
onAysncNanEventDataPathRequest(NanDataPathRequestInd * event)272 void onAysncNanEventDataPathRequest(NanDataPathRequestInd* event) {
273 const auto lock = hidl_sync_util::acquireGlobalLock();
274 if (on_nan_event_data_path_request_user_callback && event) {
275 on_nan_event_data_path_request_user_callback(*event);
276 }
277 }
278 std::function<void(const NanDataPathConfirmInd&)>
279 on_nan_event_data_path_confirm_user_callback;
onAysncNanEventDataPathConfirm(NanDataPathConfirmInd * event)280 void onAysncNanEventDataPathConfirm(NanDataPathConfirmInd* event) {
281 const auto lock = hidl_sync_util::acquireGlobalLock();
282 if (on_nan_event_data_path_confirm_user_callback && event) {
283 on_nan_event_data_path_confirm_user_callback(*event);
284 }
285 }
286
287 std::function<void(const NanDataPathEndInd&)>
288 on_nan_event_data_path_end_user_callback;
onAysncNanEventDataPathEnd(NanDataPathEndInd * event)289 void onAysncNanEventDataPathEnd(NanDataPathEndInd* event) {
290 const auto lock = hidl_sync_util::acquireGlobalLock();
291 if (on_nan_event_data_path_end_user_callback && event) {
292 on_nan_event_data_path_end_user_callback(*event);
293 }
294 }
295
296 std::function<void(const NanTransmitFollowupInd&)>
297 on_nan_event_transmit_follow_up_user_callback;
onAysncNanEventTransmitFollowUp(NanTransmitFollowupInd * event)298 void onAysncNanEventTransmitFollowUp(NanTransmitFollowupInd* event) {
299 const auto lock = hidl_sync_util::acquireGlobalLock();
300 if (on_nan_event_transmit_follow_up_user_callback && event) {
301 on_nan_event_transmit_follow_up_user_callback(*event);
302 }
303 }
304
305 std::function<void(const NanRangeRequestInd&)>
306 on_nan_event_range_request_user_callback;
onAysncNanEventRangeRequest(NanRangeRequestInd * event)307 void onAysncNanEventRangeRequest(NanRangeRequestInd* event) {
308 const auto lock = hidl_sync_util::acquireGlobalLock();
309 if (on_nan_event_range_request_user_callback && event) {
310 on_nan_event_range_request_user_callback(*event);
311 }
312 }
313
314 std::function<void(const NanRangeReportInd&)>
315 on_nan_event_range_report_user_callback;
onAysncNanEventRangeReport(NanRangeReportInd * event)316 void onAysncNanEventRangeReport(NanRangeReportInd* event) {
317 const auto lock = hidl_sync_util::acquireGlobalLock();
318 if (on_nan_event_range_report_user_callback && event) {
319 on_nan_event_range_report_user_callback(*event);
320 }
321 }
322 // End of the free-standing "C" style callbacks.
323
WifiLegacyHal()324 WifiLegacyHal::WifiLegacyHal()
325 : global_handle_(nullptr),
326 wlan_interface_handle_(nullptr),
327 awaiting_event_loop_termination_(false),
328 is_started_(false) {}
329
initialize()330 wifi_error WifiLegacyHal::initialize() {
331 LOG(DEBUG) << "Initialize legacy HAL";
332 // TODO: Add back the HAL Tool if we need to. All we need from the HAL tool
333 // for now is this function call which we can directly call.
334 if (!initHalFuncTableWithStubs(&global_func_table_)) {
335 LOG(ERROR) << "Failed to initialize legacy hal function table with stubs";
336 return WIFI_ERROR_UNKNOWN;
337 }
338 wifi_error status = init_wifi_vendor_hal_func_table(&global_func_table_);
339 if (status != WIFI_SUCCESS) {
340 LOG(ERROR) << "Failed to initialize legacy hal function table";
341 }
342 return status;
343 }
344
start()345 wifi_error WifiLegacyHal::start() {
346 // Ensure that we're starting in a good state.
347 CHECK(global_func_table_.wifi_initialize && !global_handle_ &&
348 !wlan_interface_handle_ && !awaiting_event_loop_termination_);
349 if (is_started_) {
350 LOG(DEBUG) << "Legacy HAL already started";
351 return WIFI_SUCCESS;
352 }
353 LOG(DEBUG) << "Starting legacy HAL";
354 if (!iface_tool_.SetWifiUpState(true)) {
355 LOG(ERROR) << "Failed to set WiFi interface up";
356 return WIFI_ERROR_UNKNOWN;
357 }
358 wifi_error status = global_func_table_.wifi_initialize(&global_handle_);
359 if (status != WIFI_SUCCESS || !global_handle_) {
360 LOG(ERROR) << "Failed to retrieve global handle";
361 return status;
362 }
363 std::thread(&WifiLegacyHal::runEventLoop, this).detach();
364 status = retrieveWlanInterfaceHandle();
365 if (status != WIFI_SUCCESS || !wlan_interface_handle_) {
366 LOG(ERROR) << "Failed to retrieve wlan interface handle";
367 return status;
368 }
369 LOG(DEBUG) << "Legacy HAL start complete";
370 is_started_ = true;
371 return WIFI_SUCCESS;
372 }
373
stop(std::unique_lock<std::recursive_mutex> * lock,const std::function<void ()> & on_stop_complete_user_callback)374 wifi_error WifiLegacyHal::stop(
375 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
376 const std::function<void()>& on_stop_complete_user_callback) {
377 if (!is_started_) {
378 LOG(DEBUG) << "Legacy HAL already stopped";
379 on_stop_complete_user_callback();
380 return WIFI_SUCCESS;
381 }
382 LOG(DEBUG) << "Stopping legacy HAL";
383 on_stop_complete_internal_callback =
384 [on_stop_complete_user_callback, this](wifi_handle handle) {
385 CHECK_EQ(global_handle_, handle) << "Handle mismatch";
386 LOG(INFO) << "Legacy HAL stop complete callback received";
387 // Invalidate all the internal pointers now that the HAL is
388 // stopped.
389 invalidate();
390 iface_tool_.SetWifiUpState(false);
391 on_stop_complete_user_callback();
392 is_started_ = false;
393 };
394 awaiting_event_loop_termination_ = true;
395 global_func_table_.wifi_cleanup(global_handle_, onAsyncStopComplete);
396 const auto status = stop_wait_cv_.wait_for(
397 *lock, std::chrono::milliseconds(kMaxStopCompleteWaitMs),
398 [this] { return !awaiting_event_loop_termination_; });
399 if (!status) {
400 LOG(ERROR) << "Legacy HAL stop failed or timed out";
401 return WIFI_ERROR_UNKNOWN;
402 }
403 LOG(DEBUG) << "Legacy HAL stop complete";
404 return WIFI_SUCCESS;
405 }
406
getApIfaceName()407 std::string WifiLegacyHal::getApIfaceName() {
408 // Fake name. This interface does not exist in legacy HAL
409 // API's.
410 return "ap0";
411 }
412
getNanIfaceName()413 std::string WifiLegacyHal::getNanIfaceName() {
414 // Fake name. This interface does not exist in legacy HAL
415 // API's.
416 return "nan0";
417 }
418
getP2pIfaceName()419 std::string WifiLegacyHal::getP2pIfaceName() {
420 std::array<char, PROPERTY_VALUE_MAX> buffer;
421 property_get("wifi.direct.interface", buffer.data(), "p2p0");
422 return buffer.data();
423 }
424
getStaIfaceName()425 std::string WifiLegacyHal::getStaIfaceName() {
426 std::array<char, PROPERTY_VALUE_MAX> buffer;
427 property_get("wifi.interface", buffer.data(), "wlan0");
428 return buffer.data();
429 }
430
getDriverVersion()431 std::pair<wifi_error, std::string> WifiLegacyHal::getDriverVersion() {
432 std::array<char, kMaxVersionStringLength> buffer;
433 buffer.fill(0);
434 wifi_error status = global_func_table_.wifi_get_driver_version(
435 wlan_interface_handle_, buffer.data(), buffer.size());
436 return {status, buffer.data()};
437 }
438
getFirmwareVersion()439 std::pair<wifi_error, std::string> WifiLegacyHal::getFirmwareVersion() {
440 std::array<char, kMaxVersionStringLength> buffer;
441 buffer.fill(0);
442 wifi_error status = global_func_table_.wifi_get_firmware_version(
443 wlan_interface_handle_, buffer.data(), buffer.size());
444 return {status, buffer.data()};
445 }
446
447 std::pair<wifi_error, std::vector<uint8_t>>
requestDriverMemoryDump()448 WifiLegacyHal::requestDriverMemoryDump() {
449 std::vector<uint8_t> driver_dump;
450 on_driver_memory_dump_internal_callback = [&driver_dump](char* buffer,
451 int buffer_size) {
452 driver_dump.insert(driver_dump.end(),
453 reinterpret_cast<uint8_t*>(buffer),
454 reinterpret_cast<uint8_t*>(buffer) + buffer_size);
455 };
456 wifi_error status = global_func_table_.wifi_get_driver_memory_dump(
457 wlan_interface_handle_, {onSyncDriverMemoryDump});
458 on_driver_memory_dump_internal_callback = nullptr;
459 return {status, std::move(driver_dump)};
460 }
461
462 std::pair<wifi_error, std::vector<uint8_t>>
requestFirmwareMemoryDump()463 WifiLegacyHal::requestFirmwareMemoryDump() {
464 std::vector<uint8_t> firmware_dump;
465 on_firmware_memory_dump_internal_callback = [&firmware_dump](
466 char* buffer, int buffer_size) {
467 firmware_dump.insert(firmware_dump.end(),
468 reinterpret_cast<uint8_t*>(buffer),
469 reinterpret_cast<uint8_t*>(buffer) + buffer_size);
470 };
471 wifi_error status = global_func_table_.wifi_get_firmware_memory_dump(
472 wlan_interface_handle_, {onSyncFirmwareMemoryDump});
473 on_firmware_memory_dump_internal_callback = nullptr;
474 return {status, std::move(firmware_dump)};
475 }
476
getSupportedFeatureSet()477 std::pair<wifi_error, uint32_t> WifiLegacyHal::getSupportedFeatureSet() {
478 feature_set set;
479 static_assert(sizeof(set) == sizeof(uint32_t),
480 "Some features can not be represented in output");
481 wifi_error status = global_func_table_.wifi_get_supported_feature_set(
482 wlan_interface_handle_, &set);
483 return {status, static_cast<uint32_t>(set)};
484 }
485
486 std::pair<wifi_error, PacketFilterCapabilities>
getPacketFilterCapabilities()487 WifiLegacyHal::getPacketFilterCapabilities() {
488 PacketFilterCapabilities caps;
489 wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities(
490 wlan_interface_handle_, &caps.version, &caps.max_len);
491 return {status, caps};
492 }
493
setPacketFilter(const std::vector<uint8_t> & program)494 wifi_error WifiLegacyHal::setPacketFilter(const std::vector<uint8_t>& program) {
495 return global_func_table_.wifi_set_packet_filter(
496 wlan_interface_handle_, program.data(), program.size());
497 }
498
499 std::pair<wifi_error, wifi_gscan_capabilities>
getGscanCapabilities()500 WifiLegacyHal::getGscanCapabilities() {
501 wifi_gscan_capabilities caps;
502 wifi_error status = global_func_table_.wifi_get_gscan_capabilities(
503 wlan_interface_handle_, &caps);
504 return {status, caps};
505 }
506
startGscan(wifi_request_id id,const wifi_scan_cmd_params & params,const std::function<void (wifi_request_id)> & on_failure_user_callback,const on_gscan_results_callback & on_results_user_callback,const on_gscan_full_result_callback & on_full_result_user_callback)507 wifi_error WifiLegacyHal::startGscan(
508 wifi_request_id id,
509 const wifi_scan_cmd_params& params,
510 const std::function<void(wifi_request_id)>& on_failure_user_callback,
511 const on_gscan_results_callback& on_results_user_callback,
512 const on_gscan_full_result_callback& on_full_result_user_callback) {
513 // If there is already an ongoing background scan, reject new scan requests.
514 if (on_gscan_event_internal_callback ||
515 on_gscan_full_result_internal_callback) {
516 return WIFI_ERROR_NOT_AVAILABLE;
517 }
518
519 // This callback will be used to either trigger |on_results_user_callback| or
520 // |on_failure_user_callback|.
521 on_gscan_event_internal_callback =
522 [on_failure_user_callback, on_results_user_callback, this](
523 wifi_request_id id, wifi_scan_event event) {
524 switch (event) {
525 case WIFI_SCAN_RESULTS_AVAILABLE:
526 case WIFI_SCAN_THRESHOLD_NUM_SCANS:
527 case WIFI_SCAN_THRESHOLD_PERCENT: {
528 wifi_error status;
529 std::vector<wifi_cached_scan_results> cached_scan_results;
530 std::tie(status, cached_scan_results) = getGscanCachedResults();
531 if (status == WIFI_SUCCESS) {
532 on_results_user_callback(id, cached_scan_results);
533 return;
534 }
535 }
536 // Fall through if failed. Failure to retrieve cached scan results
537 // should trigger a background scan failure.
538 case WIFI_SCAN_FAILED:
539 on_failure_user_callback(id);
540 on_gscan_event_internal_callback = nullptr;
541 on_gscan_full_result_internal_callback = nullptr;
542 return;
543 }
544 LOG(FATAL) << "Unexpected gscan event received: " << event;
545 };
546
547 on_gscan_full_result_internal_callback = [on_full_result_user_callback](
548 wifi_request_id id, wifi_scan_result* result, uint32_t buckets_scanned) {
549 if (result) {
550 on_full_result_user_callback(id, result, buckets_scanned);
551 }
552 };
553
554 wifi_scan_result_handler handler = {onAsyncGscanFullResult,
555 onAsyncGscanEvent};
556 wifi_error status = global_func_table_.wifi_start_gscan(
557 id, wlan_interface_handle_, params, handler);
558 if (status != WIFI_SUCCESS) {
559 on_gscan_event_internal_callback = nullptr;
560 on_gscan_full_result_internal_callback = nullptr;
561 }
562 return status;
563 }
564
stopGscan(wifi_request_id id)565 wifi_error WifiLegacyHal::stopGscan(wifi_request_id id) {
566 // If there is no an ongoing background scan, reject stop requests.
567 // TODO(b/32337212): This needs to be handled by the HIDL object because we
568 // need to return the NOT_STARTED error code.
569 if (!on_gscan_event_internal_callback &&
570 !on_gscan_full_result_internal_callback) {
571 return WIFI_ERROR_NOT_AVAILABLE;
572 }
573 wifi_error status =
574 global_func_table_.wifi_stop_gscan(id, wlan_interface_handle_);
575 // If the request Id is wrong, don't stop the ongoing background scan. Any
576 // other error should be treated as the end of background scan.
577 if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
578 on_gscan_event_internal_callback = nullptr;
579 on_gscan_full_result_internal_callback = nullptr;
580 }
581 return status;
582 }
583
584 std::pair<wifi_error, std::vector<uint32_t>>
getValidFrequenciesForBand(wifi_band band)585 WifiLegacyHal::getValidFrequenciesForBand(wifi_band band) {
586 static_assert(sizeof(uint32_t) >= sizeof(wifi_channel),
587 "Wifi Channel cannot be represented in output");
588 std::vector<uint32_t> freqs;
589 freqs.resize(kMaxGscanFrequenciesForBand);
590 int32_t num_freqs = 0;
591 wifi_error status = global_func_table_.wifi_get_valid_channels(
592 wlan_interface_handle_,
593 band,
594 freqs.size(),
595 reinterpret_cast<wifi_channel*>(freqs.data()),
596 &num_freqs);
597 CHECK(num_freqs >= 0 &&
598 static_cast<uint32_t>(num_freqs) <= kMaxGscanFrequenciesForBand);
599 freqs.resize(num_freqs);
600 return {status, std::move(freqs)};
601 }
602
setDfsFlag(bool dfs_on)603 wifi_error WifiLegacyHal::setDfsFlag(bool dfs_on) {
604 return global_func_table_.wifi_set_nodfs_flag(
605 wlan_interface_handle_, dfs_on ? 0 : 1);
606 }
607
enableLinkLayerStats(bool debug)608 wifi_error WifiLegacyHal::enableLinkLayerStats(bool debug) {
609 wifi_link_layer_params params;
610 params.mpdu_size_threshold = kLinkLayerStatsDataMpduSizeThreshold;
611 params.aggressive_statistics_gathering = debug;
612 return global_func_table_.wifi_set_link_stats(wlan_interface_handle_, params);
613 }
614
disableLinkLayerStats()615 wifi_error WifiLegacyHal::disableLinkLayerStats() {
616 // TODO: Do we care about these responses?
617 uint32_t clear_mask_rsp;
618 uint8_t stop_rsp;
619 return global_func_table_.wifi_clear_link_stats(
620 wlan_interface_handle_, 0xFFFFFFFF, &clear_mask_rsp, 1, &stop_rsp);
621 }
622
getLinkLayerStats()623 std::pair<wifi_error, LinkLayerStats> WifiLegacyHal::getLinkLayerStats() {
624 LinkLayerStats link_stats{};
625 LinkLayerStats* link_stats_ptr = &link_stats;
626
627 on_link_layer_stats_result_internal_callback =
628 [&link_stats_ptr](wifi_request_id /* id */,
629 wifi_iface_stat* iface_stats_ptr,
630 int num_radios,
631 wifi_radio_stat* radio_stats_ptr) {
632 if (iface_stats_ptr != nullptr) {
633 link_stats_ptr->iface = *iface_stats_ptr;
634 link_stats_ptr->iface.num_peers = 0;
635 } else {
636 LOG(ERROR) << "Invalid iface stats in link layer stats";
637 }
638 if (num_radios <= 0 || radio_stats_ptr == nullptr) {
639 LOG(ERROR) << "Invalid radio stats in link layer stats";
640 return;
641 }
642 for (int i = 0; i < num_radios; i++) {
643 LinkLayerRadioStats radio;
644 radio.stats = radio_stats_ptr[i];
645 // Copy over the tx level array to the separate vector.
646 if (radio_stats_ptr[i].num_tx_levels > 0 &&
647 radio_stats_ptr[i].tx_time_per_levels != nullptr) {
648 radio.tx_time_per_levels.assign(
649 radio_stats_ptr[i].tx_time_per_levels,
650 radio_stats_ptr[i].tx_time_per_levels +
651 radio_stats_ptr[i].num_tx_levels);
652 }
653 radio.stats.num_tx_levels = 0;
654 radio.stats.tx_time_per_levels = nullptr;
655 link_stats_ptr->radios.push_back(radio);
656 }
657 };
658
659 wifi_error status = global_func_table_.wifi_get_link_stats(
660 0, wlan_interface_handle_, {onSyncLinkLayerStatsResult});
661 on_link_layer_stats_result_internal_callback = nullptr;
662 return {status, link_stats};
663 }
664
startRssiMonitoring(wifi_request_id id,int8_t max_rssi,int8_t min_rssi,const on_rssi_threshold_breached_callback & on_threshold_breached_user_callback)665 wifi_error WifiLegacyHal::startRssiMonitoring(
666 wifi_request_id id,
667 int8_t max_rssi,
668 int8_t min_rssi,
669 const on_rssi_threshold_breached_callback&
670 on_threshold_breached_user_callback) {
671 if (on_rssi_threshold_breached_internal_callback) {
672 return WIFI_ERROR_NOT_AVAILABLE;
673 }
674 on_rssi_threshold_breached_internal_callback =
675 [on_threshold_breached_user_callback](
676 wifi_request_id id, uint8_t* bssid_ptr, int8_t rssi) {
677 if (!bssid_ptr) {
678 return;
679 }
680 std::array<uint8_t, 6> bssid_arr;
681 // |bssid_ptr| pointer is assumed to have 6 bytes for the mac address.
682 std::copy(bssid_ptr, bssid_ptr + 6, std::begin(bssid_arr));
683 on_threshold_breached_user_callback(id, bssid_arr, rssi);
684 };
685 wifi_error status = global_func_table_.wifi_start_rssi_monitoring(
686 id,
687 wlan_interface_handle_,
688 max_rssi,
689 min_rssi,
690 {onAsyncRssiThresholdBreached});
691 if (status != WIFI_SUCCESS) {
692 on_rssi_threshold_breached_internal_callback = nullptr;
693 }
694 return status;
695 }
696
stopRssiMonitoring(wifi_request_id id)697 wifi_error WifiLegacyHal::stopRssiMonitoring(wifi_request_id id) {
698 if (!on_rssi_threshold_breached_internal_callback) {
699 return WIFI_ERROR_NOT_AVAILABLE;
700 }
701 wifi_error status =
702 global_func_table_.wifi_stop_rssi_monitoring(id, wlan_interface_handle_);
703 // If the request Id is wrong, don't stop the ongoing rssi monitoring. Any
704 // other error should be treated as the end of background scan.
705 if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
706 on_rssi_threshold_breached_internal_callback = nullptr;
707 }
708 return status;
709 }
710
711 std::pair<wifi_error, wifi_roaming_capabilities>
getRoamingCapabilities()712 WifiLegacyHal::getRoamingCapabilities() {
713 wifi_roaming_capabilities caps;
714 wifi_error status = global_func_table_.wifi_get_roaming_capabilities(
715 wlan_interface_handle_, &caps);
716 return {status, caps};
717 }
718
configureRoaming(const wifi_roaming_config & config)719 wifi_error WifiLegacyHal::configureRoaming(const wifi_roaming_config& config) {
720 wifi_roaming_config config_internal = config;
721 return global_func_table_.wifi_configure_roaming(wlan_interface_handle_,
722 &config_internal);
723 }
724
enableFirmwareRoaming(fw_roaming_state_t state)725 wifi_error WifiLegacyHal::enableFirmwareRoaming(fw_roaming_state_t state) {
726 return global_func_table_.wifi_enable_firmware_roaming(wlan_interface_handle_,
727 state);
728 }
729
configureNdOffload(bool enable)730 wifi_error WifiLegacyHal::configureNdOffload(bool enable) {
731 return global_func_table_.wifi_configure_nd_offload(wlan_interface_handle_,
732 enable);
733 }
734
startSendingOffloadedPacket(uint32_t cmd_id,const std::vector<uint8_t> & ip_packet_data,const std::array<uint8_t,6> & src_address,const std::array<uint8_t,6> & dst_address,uint32_t period_in_ms)735 wifi_error WifiLegacyHal::startSendingOffloadedPacket(
736 uint32_t cmd_id,
737 const std::vector<uint8_t>& ip_packet_data,
738 const std::array<uint8_t, 6>& src_address,
739 const std::array<uint8_t, 6>& dst_address,
740 uint32_t period_in_ms) {
741 std::vector<uint8_t> ip_packet_data_internal(ip_packet_data);
742 std::vector<uint8_t> src_address_internal(
743 src_address.data(), src_address.data() + src_address.size());
744 std::vector<uint8_t> dst_address_internal(
745 dst_address.data(), dst_address.data() + dst_address.size());
746 return global_func_table_.wifi_start_sending_offloaded_packet(
747 cmd_id,
748 wlan_interface_handle_,
749 ip_packet_data_internal.data(),
750 ip_packet_data_internal.size(),
751 src_address_internal.data(),
752 dst_address_internal.data(),
753 period_in_ms);
754 }
755
stopSendingOffloadedPacket(uint32_t cmd_id)756 wifi_error WifiLegacyHal::stopSendingOffloadedPacket(uint32_t cmd_id) {
757 return global_func_table_.wifi_stop_sending_offloaded_packet(
758 cmd_id, wlan_interface_handle_);
759 }
760
setScanningMacOui(const std::array<uint8_t,3> & oui)761 wifi_error WifiLegacyHal::setScanningMacOui(const std::array<uint8_t, 3>& oui) {
762 std::vector<uint8_t> oui_internal(oui.data(), oui.data() + oui.size());
763 return global_func_table_.wifi_set_scanning_mac_oui(wlan_interface_handle_,
764 oui_internal.data());
765 }
766
selectTxPowerScenario(wifi_power_scenario scenario)767 wifi_error WifiLegacyHal::selectTxPowerScenario(wifi_power_scenario scenario) {
768 return global_func_table_.wifi_select_tx_power_scenario(
769 wlan_interface_handle_, scenario);
770 }
771
resetTxPowerScenario()772 wifi_error WifiLegacyHal::resetTxPowerScenario() {
773 return global_func_table_.wifi_reset_tx_power_scenario(wlan_interface_handle_);
774 }
775
getLoggerSupportedFeatureSet()776 std::pair<wifi_error, uint32_t> WifiLegacyHal::getLoggerSupportedFeatureSet() {
777 uint32_t supported_features;
778 wifi_error status = global_func_table_.wifi_get_logger_supported_feature_set(
779 wlan_interface_handle_, &supported_features);
780 return {status, supported_features};
781 }
782
startPktFateMonitoring()783 wifi_error WifiLegacyHal::startPktFateMonitoring() {
784 return global_func_table_.wifi_start_pkt_fate_monitoring(
785 wlan_interface_handle_);
786 }
787
788 std::pair<wifi_error, std::vector<wifi_tx_report>>
getTxPktFates()789 WifiLegacyHal::getTxPktFates() {
790 std::vector<wifi_tx_report> tx_pkt_fates;
791 tx_pkt_fates.resize(MAX_FATE_LOG_LEN);
792 size_t num_fates = 0;
793 wifi_error status =
794 global_func_table_.wifi_get_tx_pkt_fates(wlan_interface_handle_,
795 tx_pkt_fates.data(),
796 tx_pkt_fates.size(),
797 &num_fates);
798 CHECK(num_fates <= MAX_FATE_LOG_LEN);
799 tx_pkt_fates.resize(num_fates);
800 return {status, std::move(tx_pkt_fates)};
801 }
802
803 std::pair<wifi_error, std::vector<wifi_rx_report>>
getRxPktFates()804 WifiLegacyHal::getRxPktFates() {
805 std::vector<wifi_rx_report> rx_pkt_fates;
806 rx_pkt_fates.resize(MAX_FATE_LOG_LEN);
807 size_t num_fates = 0;
808 wifi_error status =
809 global_func_table_.wifi_get_rx_pkt_fates(wlan_interface_handle_,
810 rx_pkt_fates.data(),
811 rx_pkt_fates.size(),
812 &num_fates);
813 CHECK(num_fates <= MAX_FATE_LOG_LEN);
814 rx_pkt_fates.resize(num_fates);
815 return {status, std::move(rx_pkt_fates)};
816 }
817
getWakeReasonStats()818 std::pair<wifi_error, WakeReasonStats> WifiLegacyHal::getWakeReasonStats() {
819 WakeReasonStats stats;
820 stats.cmd_event_wake_cnt.resize(kMaxWakeReasonStatsArraySize);
821 stats.driver_fw_local_wake_cnt.resize(kMaxWakeReasonStatsArraySize);
822
823 // This legacy struct needs separate memory to store the variable sized wake
824 // reason types.
825 stats.wake_reason_cnt.cmd_event_wake_cnt =
826 reinterpret_cast<int32_t*>(stats.cmd_event_wake_cnt.data());
827 stats.wake_reason_cnt.cmd_event_wake_cnt_sz = stats.cmd_event_wake_cnt.size();
828 stats.wake_reason_cnt.cmd_event_wake_cnt_used = 0;
829 stats.wake_reason_cnt.driver_fw_local_wake_cnt =
830 reinterpret_cast<int32_t*>(stats.driver_fw_local_wake_cnt.data());
831 stats.wake_reason_cnt.driver_fw_local_wake_cnt_sz =
832 stats.driver_fw_local_wake_cnt.size();
833 stats.wake_reason_cnt.driver_fw_local_wake_cnt_used = 0;
834
835 wifi_error status = global_func_table_.wifi_get_wake_reason_stats(
836 wlan_interface_handle_, &stats.wake_reason_cnt);
837
838 CHECK(stats.wake_reason_cnt.cmd_event_wake_cnt_used >= 0 &&
839 static_cast<uint32_t>(stats.wake_reason_cnt.cmd_event_wake_cnt_used) <=
840 kMaxWakeReasonStatsArraySize);
841 stats.cmd_event_wake_cnt.resize(
842 stats.wake_reason_cnt.cmd_event_wake_cnt_used);
843 stats.wake_reason_cnt.cmd_event_wake_cnt = nullptr;
844
845 CHECK(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used >= 0 &&
846 static_cast<uint32_t>(
847 stats.wake_reason_cnt.driver_fw_local_wake_cnt_used) <=
848 kMaxWakeReasonStatsArraySize);
849 stats.driver_fw_local_wake_cnt.resize(
850 stats.wake_reason_cnt.driver_fw_local_wake_cnt_used);
851 stats.wake_reason_cnt.driver_fw_local_wake_cnt = nullptr;
852
853 return {status, stats};
854 }
855
registerRingBufferCallbackHandler(const on_ring_buffer_data_callback & on_user_data_callback)856 wifi_error WifiLegacyHal::registerRingBufferCallbackHandler(
857 const on_ring_buffer_data_callback& on_user_data_callback) {
858 if (on_ring_buffer_data_internal_callback) {
859 return WIFI_ERROR_NOT_AVAILABLE;
860 }
861 on_ring_buffer_data_internal_callback = [on_user_data_callback](
862 char* ring_name,
863 char* buffer,
864 int buffer_size,
865 wifi_ring_buffer_status* status) {
866 if (status && buffer) {
867 std::vector<uint8_t> buffer_vector(
868 reinterpret_cast<uint8_t*>(buffer),
869 reinterpret_cast<uint8_t*>(buffer) + buffer_size);
870 on_user_data_callback(ring_name, buffer_vector, *status);
871 }
872 };
873 wifi_error status = global_func_table_.wifi_set_log_handler(
874 0, wlan_interface_handle_, {onAsyncRingBufferData});
875 if (status != WIFI_SUCCESS) {
876 on_ring_buffer_data_internal_callback = nullptr;
877 }
878 return status;
879 }
880
deregisterRingBufferCallbackHandler()881 wifi_error WifiLegacyHal::deregisterRingBufferCallbackHandler() {
882 if (!on_ring_buffer_data_internal_callback) {
883 return WIFI_ERROR_NOT_AVAILABLE;
884 }
885 on_ring_buffer_data_internal_callback = nullptr;
886 return global_func_table_.wifi_reset_log_handler(0, wlan_interface_handle_);
887 }
888
889 std::pair<wifi_error, std::vector<wifi_ring_buffer_status>>
getRingBuffersStatus()890 WifiLegacyHal::getRingBuffersStatus() {
891 std::vector<wifi_ring_buffer_status> ring_buffers_status;
892 ring_buffers_status.resize(kMaxRingBuffers);
893 uint32_t num_rings = kMaxRingBuffers;
894 wifi_error status = global_func_table_.wifi_get_ring_buffers_status(
895 wlan_interface_handle_, &num_rings, ring_buffers_status.data());
896 CHECK(num_rings <= kMaxRingBuffers);
897 ring_buffers_status.resize(num_rings);
898 return {status, std::move(ring_buffers_status)};
899 }
900
startRingBufferLogging(const std::string & ring_name,uint32_t verbose_level,uint32_t max_interval_sec,uint32_t min_data_size)901 wifi_error WifiLegacyHal::startRingBufferLogging(const std::string& ring_name,
902 uint32_t verbose_level,
903 uint32_t max_interval_sec,
904 uint32_t min_data_size) {
905 return global_func_table_.wifi_start_logging(wlan_interface_handle_,
906 verbose_level,
907 0,
908 max_interval_sec,
909 min_data_size,
910 makeCharVec(ring_name).data());
911 }
912
getRingBufferData(const std::string & ring_name)913 wifi_error WifiLegacyHal::getRingBufferData(const std::string& ring_name) {
914 return global_func_table_.wifi_get_ring_data(wlan_interface_handle_,
915 makeCharVec(ring_name).data());
916 }
917
registerErrorAlertCallbackHandler(const on_error_alert_callback & on_user_alert_callback)918 wifi_error WifiLegacyHal::registerErrorAlertCallbackHandler(
919 const on_error_alert_callback& on_user_alert_callback) {
920 if (on_error_alert_internal_callback) {
921 return WIFI_ERROR_NOT_AVAILABLE;
922 }
923 on_error_alert_internal_callback = [on_user_alert_callback](
924 wifi_request_id id, char* buffer, int buffer_size, int err_code) {
925 if (buffer) {
926 CHECK(id == 0);
927 on_user_alert_callback(
928 err_code,
929 std::vector<uint8_t>(
930 reinterpret_cast<uint8_t*>(buffer),
931 reinterpret_cast<uint8_t*>(buffer) + buffer_size));
932 }
933 };
934 wifi_error status = global_func_table_.wifi_set_alert_handler(
935 0, wlan_interface_handle_, {onAsyncErrorAlert});
936 if (status != WIFI_SUCCESS) {
937 on_error_alert_internal_callback = nullptr;
938 }
939 return status;
940 }
941
deregisterErrorAlertCallbackHandler()942 wifi_error WifiLegacyHal::deregisterErrorAlertCallbackHandler() {
943 if (!on_error_alert_internal_callback) {
944 return WIFI_ERROR_NOT_AVAILABLE;
945 }
946 on_error_alert_internal_callback = nullptr;
947 return global_func_table_.wifi_reset_alert_handler(0, wlan_interface_handle_);
948 }
949
startRttRangeRequest(wifi_request_id id,const std::vector<wifi_rtt_config> & rtt_configs,const on_rtt_results_callback & on_results_user_callback)950 wifi_error WifiLegacyHal::startRttRangeRequest(
951 wifi_request_id id,
952 const std::vector<wifi_rtt_config>& rtt_configs,
953 const on_rtt_results_callback& on_results_user_callback) {
954 if (on_rtt_results_internal_callback) {
955 return WIFI_ERROR_NOT_AVAILABLE;
956 }
957
958 on_rtt_results_internal_callback = [on_results_user_callback](
959 wifi_request_id id,
960 unsigned num_results,
961 wifi_rtt_result* rtt_results[]) {
962 if (num_results > 0 && !rtt_results) {
963 LOG(ERROR) << "Unexpected nullptr in RTT results";
964 return;
965 }
966 std::vector<const wifi_rtt_result*> rtt_results_vec;
967 std::copy_if(
968 rtt_results,
969 rtt_results + num_results,
970 back_inserter(rtt_results_vec),
971 [](wifi_rtt_result* rtt_result) { return rtt_result != nullptr; });
972 on_results_user_callback(id, rtt_results_vec);
973 };
974
975 std::vector<wifi_rtt_config> rtt_configs_internal(rtt_configs);
976 wifi_error status =
977 global_func_table_.wifi_rtt_range_request(id,
978 wlan_interface_handle_,
979 rtt_configs.size(),
980 rtt_configs_internal.data(),
981 {onAsyncRttResults});
982 if (status != WIFI_SUCCESS) {
983 on_rtt_results_internal_callback = nullptr;
984 }
985 return status;
986 }
987
cancelRttRangeRequest(wifi_request_id id,const std::vector<std::array<uint8_t,6>> & mac_addrs)988 wifi_error WifiLegacyHal::cancelRttRangeRequest(
989 wifi_request_id id, const std::vector<std::array<uint8_t, 6>>& mac_addrs) {
990 if (!on_rtt_results_internal_callback) {
991 return WIFI_ERROR_NOT_AVAILABLE;
992 }
993 static_assert(sizeof(mac_addr) == sizeof(std::array<uint8_t, 6>),
994 "MAC address size mismatch");
995 // TODO: How do we handle partial cancels (i.e only a subset of enabled mac
996 // addressed are cancelled).
997 std::vector<std::array<uint8_t, 6>> mac_addrs_internal(mac_addrs);
998 wifi_error status = global_func_table_.wifi_rtt_range_cancel(
999 id,
1000 wlan_interface_handle_,
1001 mac_addrs.size(),
1002 reinterpret_cast<mac_addr*>(mac_addrs_internal.data()));
1003 // If the request Id is wrong, don't stop the ongoing range request. Any
1004 // other error should be treated as the end of rtt ranging.
1005 if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
1006 on_rtt_results_internal_callback = nullptr;
1007 }
1008 return status;
1009 }
1010
1011 std::pair<wifi_error, wifi_rtt_capabilities>
getRttCapabilities()1012 WifiLegacyHal::getRttCapabilities() {
1013 wifi_rtt_capabilities rtt_caps;
1014 wifi_error status = global_func_table_.wifi_get_rtt_capabilities(
1015 wlan_interface_handle_, &rtt_caps);
1016 return {status, rtt_caps};
1017 }
1018
getRttResponderInfo()1019 std::pair<wifi_error, wifi_rtt_responder> WifiLegacyHal::getRttResponderInfo() {
1020 wifi_rtt_responder rtt_responder;
1021 wifi_error status = global_func_table_.wifi_rtt_get_responder_info(
1022 wlan_interface_handle_, &rtt_responder);
1023 return {status, rtt_responder};
1024 }
1025
enableRttResponder(wifi_request_id id,const wifi_channel_info & channel_hint,uint32_t max_duration_secs,const wifi_rtt_responder & info)1026 wifi_error WifiLegacyHal::enableRttResponder(
1027 wifi_request_id id,
1028 const wifi_channel_info& channel_hint,
1029 uint32_t max_duration_secs,
1030 const wifi_rtt_responder& info) {
1031 wifi_rtt_responder info_internal(info);
1032 return global_func_table_.wifi_enable_responder(id,
1033 wlan_interface_handle_,
1034 channel_hint,
1035 max_duration_secs,
1036 &info_internal);
1037 }
1038
disableRttResponder(wifi_request_id id)1039 wifi_error WifiLegacyHal::disableRttResponder(wifi_request_id id) {
1040 return global_func_table_.wifi_disable_responder(id, wlan_interface_handle_);
1041 }
1042
setRttLci(wifi_request_id id,const wifi_lci_information & info)1043 wifi_error WifiLegacyHal::setRttLci(wifi_request_id id,
1044 const wifi_lci_information& info) {
1045 wifi_lci_information info_internal(info);
1046 return global_func_table_.wifi_set_lci(
1047 id, wlan_interface_handle_, &info_internal);
1048 }
1049
setRttLcr(wifi_request_id id,const wifi_lcr_information & info)1050 wifi_error WifiLegacyHal::setRttLcr(wifi_request_id id,
1051 const wifi_lcr_information& info) {
1052 wifi_lcr_information info_internal(info);
1053 return global_func_table_.wifi_set_lcr(
1054 id, wlan_interface_handle_, &info_internal);
1055 }
1056
nanRegisterCallbackHandlers(const NanCallbackHandlers & user_callbacks)1057 wifi_error WifiLegacyHal::nanRegisterCallbackHandlers(
1058 const NanCallbackHandlers& user_callbacks) {
1059 on_nan_notify_response_user_callback = user_callbacks.on_notify_response;
1060 on_nan_event_publish_terminated_user_callback =
1061 user_callbacks.on_event_publish_terminated;
1062 on_nan_event_match_user_callback = user_callbacks.on_event_match;
1063 on_nan_event_match_expired_user_callback =
1064 user_callbacks.on_event_match_expired;
1065 on_nan_event_subscribe_terminated_user_callback =
1066 user_callbacks.on_event_subscribe_terminated;
1067 on_nan_event_followup_user_callback = user_callbacks.on_event_followup;
1068 on_nan_event_disc_eng_event_user_callback =
1069 user_callbacks.on_event_disc_eng_event;
1070 on_nan_event_disabled_user_callback = user_callbacks.on_event_disabled;
1071 on_nan_event_tca_user_callback = user_callbacks.on_event_tca;
1072 on_nan_event_beacon_sdf_payload_user_callback =
1073 user_callbacks.on_event_beacon_sdf_payload;
1074 on_nan_event_data_path_request_user_callback =
1075 user_callbacks.on_event_data_path_request;
1076 on_nan_event_data_path_confirm_user_callback =
1077 user_callbacks.on_event_data_path_confirm;
1078 on_nan_event_data_path_end_user_callback =
1079 user_callbacks.on_event_data_path_end;
1080 on_nan_event_transmit_follow_up_user_callback =
1081 user_callbacks.on_event_transmit_follow_up;
1082 on_nan_event_range_request_user_callback =
1083 user_callbacks.on_event_range_request;
1084 on_nan_event_range_report_user_callback =
1085 user_callbacks.on_event_range_report;
1086
1087 return global_func_table_.wifi_nan_register_handler(
1088 wlan_interface_handle_,
1089 {onAysncNanNotifyResponse,
1090 onAysncNanEventPublishReplied,
1091 onAysncNanEventPublishTerminated,
1092 onAysncNanEventMatch,
1093 onAysncNanEventMatchExpired,
1094 onAysncNanEventSubscribeTerminated,
1095 onAysncNanEventFollowup,
1096 onAysncNanEventDiscEngEvent,
1097 onAysncNanEventDisabled,
1098 onAysncNanEventTca,
1099 onAysncNanEventBeaconSdfPayload,
1100 onAysncNanEventDataPathRequest,
1101 onAysncNanEventDataPathConfirm,
1102 onAysncNanEventDataPathEnd,
1103 onAysncNanEventTransmitFollowUp,
1104 onAysncNanEventRangeRequest,
1105 onAysncNanEventRangeReport});
1106 }
1107
nanEnableRequest(transaction_id id,const NanEnableRequest & msg)1108 wifi_error WifiLegacyHal::nanEnableRequest(transaction_id id,
1109 const NanEnableRequest& msg) {
1110 NanEnableRequest msg_internal(msg);
1111 return global_func_table_.wifi_nan_enable_request(
1112 id, wlan_interface_handle_, &msg_internal);
1113 }
1114
nanDisableRequest(transaction_id id)1115 wifi_error WifiLegacyHal::nanDisableRequest(transaction_id id) {
1116 return global_func_table_.wifi_nan_disable_request(id,
1117 wlan_interface_handle_);
1118 }
1119
nanPublishRequest(transaction_id id,const NanPublishRequest & msg)1120 wifi_error WifiLegacyHal::nanPublishRequest(transaction_id id,
1121 const NanPublishRequest& msg) {
1122 NanPublishRequest msg_internal(msg);
1123 return global_func_table_.wifi_nan_publish_request(
1124 id, wlan_interface_handle_, &msg_internal);
1125 }
1126
nanPublishCancelRequest(transaction_id id,const NanPublishCancelRequest & msg)1127 wifi_error WifiLegacyHal::nanPublishCancelRequest(
1128 transaction_id id, const NanPublishCancelRequest& msg) {
1129 NanPublishCancelRequest msg_internal(msg);
1130 return global_func_table_.wifi_nan_publish_cancel_request(
1131 id, wlan_interface_handle_, &msg_internal);
1132 }
1133
nanSubscribeRequest(transaction_id id,const NanSubscribeRequest & msg)1134 wifi_error WifiLegacyHal::nanSubscribeRequest(transaction_id id,
1135 const NanSubscribeRequest& msg) {
1136 NanSubscribeRequest msg_internal(msg);
1137 return global_func_table_.wifi_nan_subscribe_request(
1138 id, wlan_interface_handle_, &msg_internal);
1139 }
1140
nanSubscribeCancelRequest(transaction_id id,const NanSubscribeCancelRequest & msg)1141 wifi_error WifiLegacyHal::nanSubscribeCancelRequest(
1142 transaction_id id, const NanSubscribeCancelRequest& msg) {
1143 NanSubscribeCancelRequest msg_internal(msg);
1144 return global_func_table_.wifi_nan_subscribe_cancel_request(
1145 id, wlan_interface_handle_, &msg_internal);
1146 }
1147
nanTransmitFollowupRequest(transaction_id id,const NanTransmitFollowupRequest & msg)1148 wifi_error WifiLegacyHal::nanTransmitFollowupRequest(
1149 transaction_id id, const NanTransmitFollowupRequest& msg) {
1150 NanTransmitFollowupRequest msg_internal(msg);
1151 return global_func_table_.wifi_nan_transmit_followup_request(
1152 id, wlan_interface_handle_, &msg_internal);
1153 }
1154
nanStatsRequest(transaction_id id,const NanStatsRequest & msg)1155 wifi_error WifiLegacyHal::nanStatsRequest(transaction_id id,
1156 const NanStatsRequest& msg) {
1157 NanStatsRequest msg_internal(msg);
1158 return global_func_table_.wifi_nan_stats_request(
1159 id, wlan_interface_handle_, &msg_internal);
1160 }
1161
nanConfigRequest(transaction_id id,const NanConfigRequest & msg)1162 wifi_error WifiLegacyHal::nanConfigRequest(transaction_id id,
1163 const NanConfigRequest& msg) {
1164 NanConfigRequest msg_internal(msg);
1165 return global_func_table_.wifi_nan_config_request(
1166 id, wlan_interface_handle_, &msg_internal);
1167 }
1168
nanTcaRequest(transaction_id id,const NanTCARequest & msg)1169 wifi_error WifiLegacyHal::nanTcaRequest(transaction_id id,
1170 const NanTCARequest& msg) {
1171 NanTCARequest msg_internal(msg);
1172 return global_func_table_.wifi_nan_tca_request(
1173 id, wlan_interface_handle_, &msg_internal);
1174 }
1175
nanBeaconSdfPayloadRequest(transaction_id id,const NanBeaconSdfPayloadRequest & msg)1176 wifi_error WifiLegacyHal::nanBeaconSdfPayloadRequest(
1177 transaction_id id, const NanBeaconSdfPayloadRequest& msg) {
1178 NanBeaconSdfPayloadRequest msg_internal(msg);
1179 return global_func_table_.wifi_nan_beacon_sdf_payload_request(
1180 id, wlan_interface_handle_, &msg_internal);
1181 }
1182
nanGetVersion()1183 std::pair<wifi_error, NanVersion> WifiLegacyHal::nanGetVersion() {
1184 NanVersion version;
1185 wifi_error status =
1186 global_func_table_.wifi_nan_get_version(global_handle_, &version);
1187 return {status, version};
1188 }
1189
nanGetCapabilities(transaction_id id)1190 wifi_error WifiLegacyHal::nanGetCapabilities(transaction_id id) {
1191 return global_func_table_.wifi_nan_get_capabilities(id,
1192 wlan_interface_handle_);
1193 }
1194
nanDataInterfaceCreate(transaction_id id,const std::string & iface_name)1195 wifi_error WifiLegacyHal::nanDataInterfaceCreate(
1196 transaction_id id, const std::string& iface_name) {
1197 return global_func_table_.wifi_nan_data_interface_create(
1198 id, wlan_interface_handle_, makeCharVec(iface_name).data());
1199 }
1200
nanDataInterfaceDelete(transaction_id id,const std::string & iface_name)1201 wifi_error WifiLegacyHal::nanDataInterfaceDelete(
1202 transaction_id id, const std::string& iface_name) {
1203 return global_func_table_.wifi_nan_data_interface_delete(
1204 id, wlan_interface_handle_, makeCharVec(iface_name).data());
1205 }
1206
nanDataRequestInitiator(transaction_id id,const NanDataPathInitiatorRequest & msg)1207 wifi_error WifiLegacyHal::nanDataRequestInitiator(
1208 transaction_id id, const NanDataPathInitiatorRequest& msg) {
1209 NanDataPathInitiatorRequest msg_internal(msg);
1210 return global_func_table_.wifi_nan_data_request_initiator(
1211 id, wlan_interface_handle_, &msg_internal);
1212 }
1213
nanDataIndicationResponse(transaction_id id,const NanDataPathIndicationResponse & msg)1214 wifi_error WifiLegacyHal::nanDataIndicationResponse(
1215 transaction_id id, const NanDataPathIndicationResponse& msg) {
1216 NanDataPathIndicationResponse msg_internal(msg);
1217 return global_func_table_.wifi_nan_data_indication_response(
1218 id, wlan_interface_handle_, &msg_internal);
1219 }
1220
1221 typedef struct {
1222 u8 num_ndp_instances;
1223 NanDataPathId ndp_instance_id;
1224 } NanDataPathEndSingleNdpIdRequest;
1225
nanDataEnd(transaction_id id,uint32_t ndpInstanceId)1226 wifi_error WifiLegacyHal::nanDataEnd(transaction_id id,
1227 uint32_t ndpInstanceId) {
1228 NanDataPathEndSingleNdpIdRequest msg;
1229 msg.num_ndp_instances = 1;
1230 msg.ndp_instance_id = ndpInstanceId;
1231 wifi_error status = global_func_table_.wifi_nan_data_end(
1232 id, wlan_interface_handle_, (NanDataPathEndRequest*)&msg);
1233 return status;
1234 }
1235
setCountryCode(std::array<int8_t,2> code)1236 wifi_error WifiLegacyHal::setCountryCode(std::array<int8_t, 2> code) {
1237 std::string code_str(code.data(), code.data() + code.size());
1238 return global_func_table_.wifi_set_country_code(wlan_interface_handle_,
1239 code_str.c_str());
1240 }
1241
retrieveWlanInterfaceHandle()1242 wifi_error WifiLegacyHal::retrieveWlanInterfaceHandle() {
1243 const std::string& ifname_to_find = getStaIfaceName();
1244 wifi_interface_handle* iface_handles = nullptr;
1245 int num_iface_handles = 0;
1246 wifi_error status = global_func_table_.wifi_get_ifaces(
1247 global_handle_, &num_iface_handles, &iface_handles);
1248 if (status != WIFI_SUCCESS) {
1249 LOG(ERROR) << "Failed to enumerate interface handles";
1250 return status;
1251 }
1252 for (int i = 0; i < num_iface_handles; ++i) {
1253 std::array<char, IFNAMSIZ> current_ifname;
1254 current_ifname.fill(0);
1255 status = global_func_table_.wifi_get_iface_name(
1256 iface_handles[i], current_ifname.data(), current_ifname.size());
1257 if (status != WIFI_SUCCESS) {
1258 LOG(WARNING) << "Failed to get interface handle name";
1259 continue;
1260 }
1261 if (ifname_to_find == current_ifname.data()) {
1262 wlan_interface_handle_ = iface_handles[i];
1263 return WIFI_SUCCESS;
1264 }
1265 }
1266 return WIFI_ERROR_UNKNOWN;
1267 }
1268
runEventLoop()1269 void WifiLegacyHal::runEventLoop() {
1270 LOG(DEBUG) << "Starting legacy HAL event loop";
1271 global_func_table_.wifi_event_loop(global_handle_);
1272 const auto lock = hidl_sync_util::acquireGlobalLock();
1273 if (!awaiting_event_loop_termination_) {
1274 LOG(FATAL) << "Legacy HAL event loop terminated, but HAL was not stopping";
1275 }
1276 LOG(DEBUG) << "Legacy HAL event loop terminated";
1277 awaiting_event_loop_termination_ = false;
1278 stop_wait_cv_.notify_one();
1279 }
1280
1281 std::pair<wifi_error, std::vector<wifi_cached_scan_results>>
getGscanCachedResults()1282 WifiLegacyHal::getGscanCachedResults() {
1283 std::vector<wifi_cached_scan_results> cached_scan_results;
1284 cached_scan_results.resize(kMaxCachedGscanResults);
1285 int32_t num_results = 0;
1286 wifi_error status = global_func_table_.wifi_get_cached_gscan_results(
1287 wlan_interface_handle_,
1288 true /* always flush */,
1289 cached_scan_results.size(),
1290 cached_scan_results.data(),
1291 &num_results);
1292 CHECK(num_results >= 0 &&
1293 static_cast<uint32_t>(num_results) <= kMaxCachedGscanResults);
1294 cached_scan_results.resize(num_results);
1295 // Check for invalid IE lengths in these cached scan results and correct it.
1296 for (auto& cached_scan_result : cached_scan_results) {
1297 int num_scan_results = cached_scan_result.num_results;
1298 for (int i = 0; i < num_scan_results; i++) {
1299 auto& scan_result = cached_scan_result.results[i];
1300 if (scan_result.ie_length > 0) {
1301 LOG(DEBUG) << "Cached scan result has non-zero IE length "
1302 << scan_result.ie_length;
1303 scan_result.ie_length = 0;
1304 }
1305 }
1306 }
1307 return {status, std::move(cached_scan_results)};
1308 }
1309
invalidate()1310 void WifiLegacyHal::invalidate() {
1311 global_handle_ = nullptr;
1312 wlan_interface_handle_ = nullptr;
1313 on_driver_memory_dump_internal_callback = nullptr;
1314 on_firmware_memory_dump_internal_callback = nullptr;
1315 on_gscan_event_internal_callback = nullptr;
1316 on_gscan_full_result_internal_callback = nullptr;
1317 on_link_layer_stats_result_internal_callback = nullptr;
1318 on_rssi_threshold_breached_internal_callback = nullptr;
1319 on_ring_buffer_data_internal_callback = nullptr;
1320 on_error_alert_internal_callback = nullptr;
1321 on_rtt_results_internal_callback = nullptr;
1322 on_nan_notify_response_user_callback = nullptr;
1323 on_nan_event_publish_terminated_user_callback = nullptr;
1324 on_nan_event_match_user_callback = nullptr;
1325 on_nan_event_match_expired_user_callback = nullptr;
1326 on_nan_event_subscribe_terminated_user_callback = nullptr;
1327 on_nan_event_followup_user_callback = nullptr;
1328 on_nan_event_disc_eng_event_user_callback = nullptr;
1329 on_nan_event_disabled_user_callback = nullptr;
1330 on_nan_event_tca_user_callback = nullptr;
1331 on_nan_event_beacon_sdf_payload_user_callback = nullptr;
1332 on_nan_event_data_path_request_user_callback = nullptr;
1333 on_nan_event_data_path_confirm_user_callback = nullptr;
1334 on_nan_event_data_path_end_user_callback = nullptr;
1335 on_nan_event_transmit_follow_up_user_callback = nullptr;
1336 on_nan_event_range_request_user_callback = nullptr;
1337 on_nan_event_range_report_user_callback = nullptr;
1338 }
1339
1340 } // namespace legacy_hal
1341 } // namespace implementation
1342 } // namespace V1_1
1343 } // namespace wifi
1344 } // namespace hardware
1345 } // namespace android
1346