blob: 3acc1ae0f0bf4ac6678b4209e8dea23e001ddb2a [file] [log] [blame]
Gabriel Birenf3262f92022-07-15 23:25:39 +00001/*
2 * Copyright (C) 2022 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 "wifi_legacy_hal.h"
18
19#include <android-base/logging.h>
20#include <cutils/properties.h>
21#include <net/if.h>
22
23#include <array>
24#include <chrono>
25
26#include "aidl_sync_util.h"
27#include "wifi_legacy_hal_stubs.h"
28
29namespace {
30// Constants ported over from the legacy HAL calling code
31// (com_android_server_wifi_WifiNative.cpp). This will all be thrown
32// away when this shim layer is replaced by the real vendor
33// implementation.
34static constexpr uint32_t kMaxVersionStringLength = 256;
35static constexpr uint32_t kMaxCachedGscanResults = 64;
36static constexpr uint32_t kMaxGscanFrequenciesForBand = 64;
37static constexpr uint32_t kLinkLayerStatsDataMpduSizeThreshold = 128;
38static constexpr uint32_t kMaxWakeReasonStatsArraySize = 32;
39static constexpr uint32_t kMaxRingBuffers = 10;
40static constexpr uint32_t kMaxWifiUsableChannels = 256;
41static constexpr uint32_t kMaxSupportedRadioCombinationsMatrixLength = 256;
42// Need a long timeout (1000ms) for chips that unload their driver.
43static constexpr uint32_t kMaxStopCompleteWaitMs = 1000;
44static constexpr char kDriverPropName[] = "wlan.driver.status";
45
46// Helper function to create a non-const char* for legacy Hal API's.
47std::vector<char> makeCharVec(const std::string& str) {
48 std::vector<char> vec(str.size() + 1);
49 vec.assign(str.begin(), str.end());
50 vec.push_back('\0');
51 return vec;
52}
53} // namespace
54
55namespace aidl {
56namespace android {
57namespace hardware {
58namespace wifi {
59namespace legacy_hal {
60
61// Legacy HAL functions accept "C" style function pointers, so use global
62// functions to pass to the legacy HAL function and store the corresponding
63// std::function methods to be invoked.
64//
65// Callback to be invoked once |stop| is complete
66std::function<void(wifi_handle handle)> on_stop_complete_internal_callback;
67void onAsyncStopComplete(wifi_handle handle) {
68 const auto lock = aidl_sync_util::acquireGlobalLock();
69 if (on_stop_complete_internal_callback) {
70 on_stop_complete_internal_callback(handle);
71 // Invalidate this callback since we don't want this firing again.
72 on_stop_complete_internal_callback = nullptr;
73 }
74}
75
76// Callback to be invoked for driver dump.
77std::function<void(char*, int)> on_driver_memory_dump_internal_callback;
78void onSyncDriverMemoryDump(char* buffer, int buffer_size) {
79 if (on_driver_memory_dump_internal_callback) {
80 on_driver_memory_dump_internal_callback(buffer, buffer_size);
81 }
82}
83
84// Callback to be invoked for firmware dump.
85std::function<void(char*, int)> on_firmware_memory_dump_internal_callback;
86void onSyncFirmwareMemoryDump(char* buffer, int buffer_size) {
87 if (on_firmware_memory_dump_internal_callback) {
88 on_firmware_memory_dump_internal_callback(buffer, buffer_size);
89 }
90}
91
92// Callback to be invoked for Gscan events.
93std::function<void(wifi_request_id, wifi_scan_event)> on_gscan_event_internal_callback;
94void onAsyncGscanEvent(wifi_request_id id, wifi_scan_event event) {
95 const auto lock = aidl_sync_util::acquireGlobalLock();
96 if (on_gscan_event_internal_callback) {
97 on_gscan_event_internal_callback(id, event);
98 }
99}
100
101// Callback to be invoked for Gscan full results.
102std::function<void(wifi_request_id, wifi_scan_result*, uint32_t)>
103 on_gscan_full_result_internal_callback;
104void onAsyncGscanFullResult(wifi_request_id id, wifi_scan_result* result,
105 uint32_t buckets_scanned) {
106 const auto lock = aidl_sync_util::acquireGlobalLock();
107 if (on_gscan_full_result_internal_callback) {
108 on_gscan_full_result_internal_callback(id, result, buckets_scanned);
109 }
110}
111
112// Callback to be invoked for link layer stats results.
113std::function<void((wifi_request_id, wifi_iface_stat*, int, wifi_radio_stat*))>
114 on_link_layer_stats_result_internal_callback;
115void onSyncLinkLayerStatsResult(wifi_request_id id, wifi_iface_stat* iface_stat, int num_radios,
116 wifi_radio_stat* radio_stat) {
117 if (on_link_layer_stats_result_internal_callback) {
118 on_link_layer_stats_result_internal_callback(id, iface_stat, num_radios, radio_stat);
119 }
120}
121
Mahesh KKV5f30d332022-10-26 14:07:44 -0700122// Callback to be invoked for Multi link layer stats results.
123std::function<void((wifi_request_id, wifi_iface_ml_stat*, int, wifi_radio_stat*))>
124 on_link_layer_ml_stats_result_internal_callback;
125void onSyncLinkLayerMlStatsResult(wifi_request_id id, wifi_iface_ml_stat* iface_ml_stat,
126 int num_radios, wifi_radio_stat* radio_stat) {
127 if (on_link_layer_ml_stats_result_internal_callback) {
128 on_link_layer_ml_stats_result_internal_callback(id, iface_ml_stat, num_radios, radio_stat);
129 }
130}
131
Gabriel Birenf3262f92022-07-15 23:25:39 +0000132// Callback to be invoked for rssi threshold breach.
133std::function<void((wifi_request_id, uint8_t*, int8_t))>
134 on_rssi_threshold_breached_internal_callback;
135void onAsyncRssiThresholdBreached(wifi_request_id id, uint8_t* bssid, int8_t rssi) {
136 const auto lock = aidl_sync_util::acquireGlobalLock();
137 if (on_rssi_threshold_breached_internal_callback) {
138 on_rssi_threshold_breached_internal_callback(id, bssid, rssi);
139 }
140}
141
142// Callback to be invoked for ring buffer data indication.
143std::function<void(char*, char*, int, wifi_ring_buffer_status*)>
144 on_ring_buffer_data_internal_callback;
145void onAsyncRingBufferData(char* ring_name, char* buffer, int buffer_size,
146 wifi_ring_buffer_status* status) {
147 const auto lock = aidl_sync_util::acquireGlobalLock();
148 if (on_ring_buffer_data_internal_callback) {
149 on_ring_buffer_data_internal_callback(ring_name, buffer, buffer_size, status);
150 }
151}
152
153// Callback to be invoked for error alert indication.
154std::function<void(wifi_request_id, char*, int, int)> on_error_alert_internal_callback;
155void onAsyncErrorAlert(wifi_request_id id, char* buffer, int buffer_size, int err_code) {
156 const auto lock = aidl_sync_util::acquireGlobalLock();
157 if (on_error_alert_internal_callback) {
158 on_error_alert_internal_callback(id, buffer, buffer_size, err_code);
159 }
160}
161
162// Callback to be invoked for radio mode change indication.
163std::function<void(wifi_request_id, uint32_t, wifi_mac_info*)>
164 on_radio_mode_change_internal_callback;
165void onAsyncRadioModeChange(wifi_request_id id, uint32_t num_macs, wifi_mac_info* mac_infos) {
166 const auto lock = aidl_sync_util::acquireGlobalLock();
167 if (on_radio_mode_change_internal_callback) {
168 on_radio_mode_change_internal_callback(id, num_macs, mac_infos);
169 }
170}
171
172// Callback to be invoked to report subsystem restart
173std::function<void(const char*)> on_subsystem_restart_internal_callback;
174void onAsyncSubsystemRestart(const char* error) {
175 const auto lock = aidl_sync_util::acquireGlobalLock();
176 if (on_subsystem_restart_internal_callback) {
177 on_subsystem_restart_internal_callback(error);
178 }
179}
180
181// Callback to be invoked for rtt results results.
182std::function<void(wifi_request_id, unsigned num_results, wifi_rtt_result* rtt_results[])>
183 on_rtt_results_internal_callback;
184void onAsyncRttResults(wifi_request_id id, unsigned num_results, wifi_rtt_result* rtt_results[]) {
185 const auto lock = aidl_sync_util::acquireGlobalLock();
186 if (on_rtt_results_internal_callback) {
187 on_rtt_results_internal_callback(id, num_results, rtt_results);
188 on_rtt_results_internal_callback = nullptr;
189 }
190}
191
192// Callbacks for the various NAN operations.
193// NOTE: These have very little conversions to perform before invoking the user
194// callbacks.
195// So, handle all of them here directly to avoid adding an unnecessary layer.
196std::function<void(transaction_id, const NanResponseMsg&)> on_nan_notify_response_user_callback;
197void onAsyncNanNotifyResponse(transaction_id id, NanResponseMsg* msg) {
198 const auto lock = aidl_sync_util::acquireGlobalLock();
199 if (on_nan_notify_response_user_callback && msg) {
200 on_nan_notify_response_user_callback(id, *msg);
201 }
202}
203
204std::function<void(const NanPublishRepliedInd&)> on_nan_event_publish_replied_user_callback;
205void onAsyncNanEventPublishReplied(NanPublishRepliedInd* /* event */) {
206 LOG(ERROR) << "onAsyncNanEventPublishReplied triggered";
207}
208
209std::function<void(const NanPublishTerminatedInd&)> on_nan_event_publish_terminated_user_callback;
210void onAsyncNanEventPublishTerminated(NanPublishTerminatedInd* event) {
211 const auto lock = aidl_sync_util::acquireGlobalLock();
212 if (on_nan_event_publish_terminated_user_callback && event) {
213 on_nan_event_publish_terminated_user_callback(*event);
214 }
215}
216
217std::function<void(const NanMatchInd&)> on_nan_event_match_user_callback;
218void onAsyncNanEventMatch(NanMatchInd* event) {
219 const auto lock = aidl_sync_util::acquireGlobalLock();
220 if (on_nan_event_match_user_callback && event) {
221 on_nan_event_match_user_callback(*event);
222 }
223}
224
225std::function<void(const NanMatchExpiredInd&)> on_nan_event_match_expired_user_callback;
226void onAsyncNanEventMatchExpired(NanMatchExpiredInd* event) {
227 const auto lock = aidl_sync_util::acquireGlobalLock();
228 if (on_nan_event_match_expired_user_callback && event) {
229 on_nan_event_match_expired_user_callback(*event);
230 }
231}
232
233std::function<void(const NanSubscribeTerminatedInd&)>
234 on_nan_event_subscribe_terminated_user_callback;
235void onAsyncNanEventSubscribeTerminated(NanSubscribeTerminatedInd* event) {
236 const auto lock = aidl_sync_util::acquireGlobalLock();
237 if (on_nan_event_subscribe_terminated_user_callback && event) {
238 on_nan_event_subscribe_terminated_user_callback(*event);
239 }
240}
241
242std::function<void(const NanFollowupInd&)> on_nan_event_followup_user_callback;
243void onAsyncNanEventFollowup(NanFollowupInd* event) {
244 const auto lock = aidl_sync_util::acquireGlobalLock();
245 if (on_nan_event_followup_user_callback && event) {
246 on_nan_event_followup_user_callback(*event);
247 }
248}
249
250std::function<void(const NanDiscEngEventInd&)> on_nan_event_disc_eng_event_user_callback;
251void onAsyncNanEventDiscEngEvent(NanDiscEngEventInd* event) {
252 const auto lock = aidl_sync_util::acquireGlobalLock();
253 if (on_nan_event_disc_eng_event_user_callback && event) {
254 on_nan_event_disc_eng_event_user_callback(*event);
255 }
256}
257
258std::function<void(const NanDisabledInd&)> on_nan_event_disabled_user_callback;
259void onAsyncNanEventDisabled(NanDisabledInd* event) {
260 const auto lock = aidl_sync_util::acquireGlobalLock();
261 if (on_nan_event_disabled_user_callback && event) {
262 on_nan_event_disabled_user_callback(*event);
263 }
264}
265
266std::function<void(const NanTCAInd&)> on_nan_event_tca_user_callback;
267void onAsyncNanEventTca(NanTCAInd* event) {
268 const auto lock = aidl_sync_util::acquireGlobalLock();
269 if (on_nan_event_tca_user_callback && event) {
270 on_nan_event_tca_user_callback(*event);
271 }
272}
273
274std::function<void(const NanBeaconSdfPayloadInd&)> on_nan_event_beacon_sdf_payload_user_callback;
275void onAsyncNanEventBeaconSdfPayload(NanBeaconSdfPayloadInd* event) {
276 const auto lock = aidl_sync_util::acquireGlobalLock();
277 if (on_nan_event_beacon_sdf_payload_user_callback && event) {
278 on_nan_event_beacon_sdf_payload_user_callback(*event);
279 }
280}
281
282std::function<void(const NanDataPathRequestInd&)> on_nan_event_data_path_request_user_callback;
283void onAsyncNanEventDataPathRequest(NanDataPathRequestInd* event) {
284 const auto lock = aidl_sync_util::acquireGlobalLock();
285 if (on_nan_event_data_path_request_user_callback && event) {
286 on_nan_event_data_path_request_user_callback(*event);
287 }
288}
289std::function<void(const NanDataPathConfirmInd&)> on_nan_event_data_path_confirm_user_callback;
290void onAsyncNanEventDataPathConfirm(NanDataPathConfirmInd* event) {
291 const auto lock = aidl_sync_util::acquireGlobalLock();
292 if (on_nan_event_data_path_confirm_user_callback && event) {
293 on_nan_event_data_path_confirm_user_callback(*event);
294 }
295}
296
297std::function<void(const NanDataPathEndInd&)> on_nan_event_data_path_end_user_callback;
298void onAsyncNanEventDataPathEnd(NanDataPathEndInd* event) {
299 const auto lock = aidl_sync_util::acquireGlobalLock();
300 if (on_nan_event_data_path_end_user_callback && event) {
301 on_nan_event_data_path_end_user_callback(*event);
302 }
303}
304
305std::function<void(const NanTransmitFollowupInd&)> on_nan_event_transmit_follow_up_user_callback;
306void onAsyncNanEventTransmitFollowUp(NanTransmitFollowupInd* event) {
307 const auto lock = aidl_sync_util::acquireGlobalLock();
308 if (on_nan_event_transmit_follow_up_user_callback && event) {
309 on_nan_event_transmit_follow_up_user_callback(*event);
310 }
311}
312
313std::function<void(const NanRangeRequestInd&)> on_nan_event_range_request_user_callback;
314void onAsyncNanEventRangeRequest(NanRangeRequestInd* event) {
315 const auto lock = aidl_sync_util::acquireGlobalLock();
316 if (on_nan_event_range_request_user_callback && event) {
317 on_nan_event_range_request_user_callback(*event);
318 }
319}
320
321std::function<void(const NanRangeReportInd&)> on_nan_event_range_report_user_callback;
322void onAsyncNanEventRangeReport(NanRangeReportInd* event) {
323 const auto lock = aidl_sync_util::acquireGlobalLock();
324 if (on_nan_event_range_report_user_callback && event) {
325 on_nan_event_range_report_user_callback(*event);
326 }
327}
328
329std::function<void(const NanDataPathScheduleUpdateInd&)> on_nan_event_schedule_update_user_callback;
330void onAsyncNanEventScheduleUpdate(NanDataPathScheduleUpdateInd* event) {
331 const auto lock = aidl_sync_util::acquireGlobalLock();
332 if (on_nan_event_schedule_update_user_callback && event) {
333 on_nan_event_schedule_update_user_callback(*event);
334 }
335}
336
Nate Jiang38e8db52022-12-02 17:30:27 -0800337std::function<void(const NanPairingRequestInd&)> on_nan_event_pairing_request_user_callback;
338void onAsyncNanEventPairingRequest(NanPairingRequestInd* event) {
339 const auto lock = aidl_sync_util::acquireGlobalLock();
340 if (on_nan_event_pairing_request_user_callback && event) {
341 on_nan_event_pairing_request_user_callback(*event);
342 }
343}
344
345std::function<void(const NanPairingConfirmInd&)> on_nan_event_pairing_confirm_user_callback;
346void onAsyncNanEventPairingConfirm(NanPairingConfirmInd* event) {
347 const auto lock = aidl_sync_util::acquireGlobalLock();
348 if (on_nan_event_pairing_confirm_user_callback && event) {
349 on_nan_event_pairing_confirm_user_callback(*event);
350 }
351}
352
353std::function<void(const NanBootstrappingRequestInd&)>
354 on_nan_event_bootstrapping_request_user_callback;
355void onAsyncNanEventBootstrappingRequest(NanBootstrappingRequestInd* event) {
356 const auto lock = aidl_sync_util::acquireGlobalLock();
357 if (on_nan_event_bootstrapping_request_user_callback && event) {
358 on_nan_event_bootstrapping_request_user_callback(*event);
359 }
360}
361
362std::function<void(const NanBootstrappingConfirmInd&)>
363 on_nan_event_bootstrapping_confirm_user_callback;
364void onAsyncNanEventBootstrappingConfirm(NanBootstrappingConfirmInd* event) {
365 const auto lock = aidl_sync_util::acquireGlobalLock();
366 if (on_nan_event_bootstrapping_confirm_user_callback && event) {
367 on_nan_event_bootstrapping_confirm_user_callback(*event);
368 }
369}
370
Gabriel Birenf3262f92022-07-15 23:25:39 +0000371// Callbacks for the various TWT operations.
372std::function<void(const TwtSetupResponse&)> on_twt_event_setup_response_callback;
373void onAsyncTwtEventSetupResponse(TwtSetupResponse* event) {
374 const auto lock = aidl_sync_util::acquireGlobalLock();
375 if (on_twt_event_setup_response_callback && event) {
376 on_twt_event_setup_response_callback(*event);
377 }
378}
379
380std::function<void(const TwtTeardownCompletion&)> on_twt_event_teardown_completion_callback;
381void onAsyncTwtEventTeardownCompletion(TwtTeardownCompletion* event) {
382 const auto lock = aidl_sync_util::acquireGlobalLock();
383 if (on_twt_event_teardown_completion_callback && event) {
384 on_twt_event_teardown_completion_callback(*event);
385 }
386}
387
388std::function<void(const TwtInfoFrameReceived&)> on_twt_event_info_frame_received_callback;
389void onAsyncTwtEventInfoFrameReceived(TwtInfoFrameReceived* event) {
390 const auto lock = aidl_sync_util::acquireGlobalLock();
391 if (on_twt_event_info_frame_received_callback && event) {
392 on_twt_event_info_frame_received_callback(*event);
393 }
394}
395
396std::function<void(const TwtDeviceNotify&)> on_twt_event_device_notify_callback;
397void onAsyncTwtEventDeviceNotify(TwtDeviceNotify* event) {
398 const auto lock = aidl_sync_util::acquireGlobalLock();
399 if (on_twt_event_device_notify_callback && event) {
400 on_twt_event_device_notify_callback(*event);
401 }
402}
403
404// Callback to report current CHRE NAN state
405std::function<void(chre_nan_rtt_state)> on_chre_nan_rtt_internal_callback;
406void onAsyncChreNanRttState(chre_nan_rtt_state state) {
407 const auto lock = aidl_sync_util::acquireGlobalLock();
408 if (on_chre_nan_rtt_internal_callback) {
409 on_chre_nan_rtt_internal_callback(state);
410 }
411}
412
413// Callback to report cached scan results
414std::function<void(wifi_cached_scan_report*)> on_cached_scan_results_internal_callback;
415void onSyncCachedScanResults(wifi_cached_scan_report* cache_report) {
416 if (on_cached_scan_results_internal_callback) {
417 on_cached_scan_results_internal_callback(cache_report);
418 }
419}
420
421// End of the free-standing "C" style callbacks.
422
423WifiLegacyHal::WifiLegacyHal(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
424 const wifi_hal_fn& fn, bool is_primary)
425 : global_func_table_(fn),
426 global_handle_(nullptr),
427 awaiting_event_loop_termination_(false),
428 is_started_(false),
429 iface_tool_(iface_tool),
430 is_primary_(is_primary) {}
431
432wifi_error WifiLegacyHal::initialize() {
433 LOG(DEBUG) << "Initialize legacy HAL";
434 // this now does nothing, since HAL function table is provided
435 // to the constructor
436 return WIFI_SUCCESS;
437}
438
439wifi_error WifiLegacyHal::start() {
440 // Ensure that we're starting in a good state.
441 CHECK(global_func_table_.wifi_initialize && !global_handle_ && iface_name_to_handle_.empty() &&
442 !awaiting_event_loop_termination_);
443 if (is_started_) {
444 LOG(DEBUG) << "Legacy HAL already started";
445 return WIFI_SUCCESS;
446 }
447 LOG(DEBUG) << "Waiting for the driver ready";
448 wifi_error status = global_func_table_.wifi_wait_for_driver_ready();
449 if (status == WIFI_ERROR_TIMED_OUT || status == WIFI_ERROR_UNKNOWN) {
450 LOG(ERROR) << "Failed or timed out awaiting driver ready";
451 return status;
452 }
453
454 if (is_primary_) {
455 property_set(kDriverPropName, "ok");
456
457 if (!iface_tool_.lock()->SetWifiUpState(true)) {
458 LOG(ERROR) << "Failed to set WiFi interface up";
459 return WIFI_ERROR_UNKNOWN;
460 }
461 }
462
463 LOG(DEBUG) << "Starting legacy HAL";
464 status = global_func_table_.wifi_initialize(&global_handle_);
465 if (status != WIFI_SUCCESS || !global_handle_) {
466 LOG(ERROR) << "Failed to retrieve global handle";
467 return status;
468 }
469 std::thread(&WifiLegacyHal::runEventLoop, this).detach();
470 status = retrieveIfaceHandles();
471 if (status != WIFI_SUCCESS || iface_name_to_handle_.empty()) {
472 LOG(ERROR) << "Failed to retrieve wlan interface handle";
473 return status;
474 }
475 LOG(DEBUG) << "Legacy HAL start complete";
476 is_started_ = true;
477 return WIFI_SUCCESS;
478}
479
480wifi_error WifiLegacyHal::stop(
481 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
482 const std::function<void()>& on_stop_complete_user_callback) {
483 if (!is_started_) {
484 LOG(DEBUG) << "Legacy HAL already stopped";
485 on_stop_complete_user_callback();
486 return WIFI_SUCCESS;
487 }
488 LOG(DEBUG) << "Stopping legacy HAL";
489 on_stop_complete_internal_callback = [on_stop_complete_user_callback,
490 this](wifi_handle handle) {
491 CHECK_EQ(global_handle_, handle) << "Handle mismatch";
492 LOG(INFO) << "Legacy HAL stop complete callback received";
493 // Invalidate all the internal pointers now that the HAL is
494 // stopped.
495 invalidate();
496 if (is_primary_) iface_tool_.lock()->SetWifiUpState(false);
497 on_stop_complete_user_callback();
498 is_started_ = false;
499 };
500 awaiting_event_loop_termination_ = true;
501 global_func_table_.wifi_cleanup(global_handle_, onAsyncStopComplete);
502 const auto status =
503 stop_wait_cv_.wait_for(*lock, std::chrono::milliseconds(kMaxStopCompleteWaitMs),
504 [this] { return !awaiting_event_loop_termination_; });
505 if (!status) {
506 LOG(ERROR) << "Legacy HAL stop failed or timed out";
507 return WIFI_ERROR_UNKNOWN;
508 }
509 LOG(DEBUG) << "Legacy HAL stop complete";
510 return WIFI_SUCCESS;
511}
512
513bool WifiLegacyHal::isStarted() {
514 return is_started_;
515}
516
517wifi_error WifiLegacyHal::waitForDriverReady() {
518 return global_func_table_.wifi_wait_for_driver_ready();
519}
520
521std::pair<wifi_error, std::string> WifiLegacyHal::getDriverVersion(const std::string& iface_name) {
522 std::array<char, kMaxVersionStringLength> buffer;
523 buffer.fill(0);
524 wifi_error status = global_func_table_.wifi_get_driver_version(getIfaceHandle(iface_name),
525 buffer.data(), buffer.size());
526 return {status, buffer.data()};
527}
528
529std::pair<wifi_error, std::string> WifiLegacyHal::getFirmwareVersion(
530 const std::string& iface_name) {
531 std::array<char, kMaxVersionStringLength> buffer;
532 buffer.fill(0);
533 wifi_error status = global_func_table_.wifi_get_firmware_version(getIfaceHandle(iface_name),
534 buffer.data(), buffer.size());
535 return {status, buffer.data()};
536}
537
538std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::requestDriverMemoryDump(
539 const std::string& iface_name) {
540 std::vector<uint8_t> driver_dump;
541 on_driver_memory_dump_internal_callback = [&driver_dump](char* buffer, int buffer_size) {
542 driver_dump.insert(driver_dump.end(), reinterpret_cast<uint8_t*>(buffer),
543 reinterpret_cast<uint8_t*>(buffer) + buffer_size);
544 };
545 wifi_error status = global_func_table_.wifi_get_driver_memory_dump(getIfaceHandle(iface_name),
546 {onSyncDriverMemoryDump});
547 on_driver_memory_dump_internal_callback = nullptr;
548 return {status, std::move(driver_dump)};
549}
550
551std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::requestFirmwareMemoryDump(
552 const std::string& iface_name) {
553 std::vector<uint8_t> firmware_dump;
554 on_firmware_memory_dump_internal_callback = [&firmware_dump](char* buffer, int buffer_size) {
555 firmware_dump.insert(firmware_dump.end(), reinterpret_cast<uint8_t*>(buffer),
556 reinterpret_cast<uint8_t*>(buffer) + buffer_size);
557 };
558 wifi_error status = global_func_table_.wifi_get_firmware_memory_dump(
559 getIfaceHandle(iface_name), {onSyncFirmwareMemoryDump});
560 on_firmware_memory_dump_internal_callback = nullptr;
561 return {status, std::move(firmware_dump)};
562}
563
564std::pair<wifi_error, uint64_t> WifiLegacyHal::getSupportedFeatureSet(
565 const std::string& iface_name) {
566 feature_set set = 0, chip_set = 0;
567 wifi_error status = WIFI_SUCCESS;
568
569 static_assert(sizeof(set) == sizeof(uint64_t),
570 "Some feature_flags can not be represented in output");
571 wifi_interface_handle iface_handle = getIfaceHandle(iface_name);
572
573 global_func_table_.wifi_get_chip_feature_set(
574 global_handle_, &chip_set); /* ignore error, chip_set will stay 0 */
575
576 if (iface_handle) {
577 status = global_func_table_.wifi_get_supported_feature_set(iface_handle, &set);
578 }
579 return {status, static_cast<uint64_t>(set | chip_set)};
580}
581
582std::pair<wifi_error, PacketFilterCapabilities> WifiLegacyHal::getPacketFilterCapabilities(
583 const std::string& iface_name) {
584 PacketFilterCapabilities caps;
585 wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities(
586 getIfaceHandle(iface_name), &caps.version, &caps.max_len);
587 return {status, caps};
588}
589
590wifi_error WifiLegacyHal::setPacketFilter(const std::string& iface_name,
591 const std::vector<uint8_t>& program) {
592 return global_func_table_.wifi_set_packet_filter(getIfaceHandle(iface_name), program.data(),
593 program.size());
594}
595
596std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::readApfPacketFilterData(
597 const std::string& iface_name) {
598 PacketFilterCapabilities caps;
599 wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities(
600 getIfaceHandle(iface_name), &caps.version, &caps.max_len);
601 if (status != WIFI_SUCCESS) {
602 return {status, {}};
603 }
604
605 // Size the buffer to read the entire program & work memory.
606 std::vector<uint8_t> buffer(caps.max_len);
607
608 status = global_func_table_.wifi_read_packet_filter(
609 getIfaceHandle(iface_name), /*src_offset=*/0, buffer.data(), buffer.size());
610 return {status, std::move(buffer)};
611}
612
613std::pair<wifi_error, wifi_gscan_capabilities> WifiLegacyHal::getGscanCapabilities(
614 const std::string& iface_name) {
615 wifi_gscan_capabilities caps;
616 wifi_error status =
617 global_func_table_.wifi_get_gscan_capabilities(getIfaceHandle(iface_name), &caps);
618 return {status, caps};
619}
620
621wifi_error WifiLegacyHal::startGscan(
622 const std::string& iface_name, wifi_request_id id, const wifi_scan_cmd_params& params,
623 const std::function<void(wifi_request_id)>& on_failure_user_callback,
624 const on_gscan_results_callback& on_results_user_callback,
625 const on_gscan_full_result_callback& on_full_result_user_callback) {
626 // If there is already an ongoing background scan, reject new scan requests.
627 if (on_gscan_event_internal_callback || on_gscan_full_result_internal_callback) {
628 return WIFI_ERROR_NOT_AVAILABLE;
629 }
630
631 // This callback will be used to either trigger |on_results_user_callback|
632 // or |on_failure_user_callback|.
633 on_gscan_event_internal_callback = [iface_name, on_failure_user_callback,
634 on_results_user_callback,
635 this](wifi_request_id id, wifi_scan_event event) {
636 switch (event) {
637 case WIFI_SCAN_RESULTS_AVAILABLE:
638 case WIFI_SCAN_THRESHOLD_NUM_SCANS:
639 case WIFI_SCAN_THRESHOLD_PERCENT: {
640 wifi_error status;
641 std::vector<wifi_cached_scan_results> cached_scan_results;
642 std::tie(status, cached_scan_results) = getGscanCachedResults(iface_name);
643 if (status == WIFI_SUCCESS) {
644 on_results_user_callback(id, cached_scan_results);
645 return;
646 }
647 FALLTHROUGH_INTENDED;
648 }
649 // Fall through if failed. Failure to retrieve cached scan
650 // results should trigger a background scan failure.
651 case WIFI_SCAN_FAILED:
652 on_failure_user_callback(id);
653 on_gscan_event_internal_callback = nullptr;
654 on_gscan_full_result_internal_callback = nullptr;
655 return;
656 }
657 LOG(FATAL) << "Unexpected gscan event received: " << event;
658 };
659
660 on_gscan_full_result_internal_callback = [on_full_result_user_callback](
661 wifi_request_id id, wifi_scan_result* result,
662 uint32_t buckets_scanned) {
663 if (result) {
664 on_full_result_user_callback(id, result, buckets_scanned);
665 }
666 };
667
668 wifi_scan_result_handler handler = {onAsyncGscanFullResult, onAsyncGscanEvent};
669 wifi_error status =
670 global_func_table_.wifi_start_gscan(id, getIfaceHandle(iface_name), params, handler);
671 if (status != WIFI_SUCCESS) {
672 on_gscan_event_internal_callback = nullptr;
673 on_gscan_full_result_internal_callback = nullptr;
674 }
675 return status;
676}
677
678wifi_error WifiLegacyHal::stopGscan(const std::string& iface_name, wifi_request_id id) {
679 // If there is no an ongoing background scan, reject stop requests.
680 // TODO(b/32337212): This needs to be handled by the HIDL object because we
681 // need to return the NOT_STARTED error code.
682 if (!on_gscan_event_internal_callback && !on_gscan_full_result_internal_callback) {
683 return WIFI_ERROR_NOT_AVAILABLE;
684 }
685 wifi_error status = global_func_table_.wifi_stop_gscan(id, getIfaceHandle(iface_name));
686 // If the request Id is wrong, don't stop the ongoing background scan. Any
687 // other error should be treated as the end of background scan.
688 if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
689 on_gscan_event_internal_callback = nullptr;
690 on_gscan_full_result_internal_callback = nullptr;
691 }
692 return status;
693}
694
695std::pair<wifi_error, std::vector<uint32_t>> WifiLegacyHal::getValidFrequenciesForBand(
696 const std::string& iface_name, wifi_band band) {
697 static_assert(sizeof(uint32_t) >= sizeof(wifi_channel),
698 "Wifi Channel cannot be represented in output");
699 std::vector<uint32_t> freqs;
700 freqs.resize(kMaxGscanFrequenciesForBand);
701 int32_t num_freqs = 0;
702 wifi_error status = global_func_table_.wifi_get_valid_channels(
703 getIfaceHandle(iface_name), band, freqs.size(),
704 reinterpret_cast<wifi_channel*>(freqs.data()), &num_freqs);
705 CHECK(num_freqs >= 0 && static_cast<uint32_t>(num_freqs) <= kMaxGscanFrequenciesForBand);
706 freqs.resize(num_freqs);
707 return {status, std::move(freqs)};
708}
709
710wifi_error WifiLegacyHal::setDfsFlag(const std::string& iface_name, bool dfs_on) {
711 return global_func_table_.wifi_set_nodfs_flag(getIfaceHandle(iface_name), dfs_on ? 0 : 1);
712}
713
714wifi_error WifiLegacyHal::enableLinkLayerStats(const std::string& iface_name, bool debug) {
715 wifi_link_layer_params params;
716 params.mpdu_size_threshold = kLinkLayerStatsDataMpduSizeThreshold;
717 params.aggressive_statistics_gathering = debug;
718 return global_func_table_.wifi_set_link_stats(getIfaceHandle(iface_name), params);
719}
720
721wifi_error WifiLegacyHal::disableLinkLayerStats(const std::string& iface_name) {
722 // TODO: Do we care about these responses?
723 uint32_t clear_mask_rsp;
724 uint8_t stop_rsp;
725 return global_func_table_.wifi_clear_link_stats(getIfaceHandle(iface_name), 0xFFFFFFFF,
726 &clear_mask_rsp, 1, &stop_rsp);
727}
728
Mahesh KKV5f30d332022-10-26 14:07:44 -0700729// Copies wifi_peer_info* to vector<WifiPeerInfo> and returns poiner to next element.
730wifi_peer_info* WifiLegacyHal::copyPeerInfo(wifi_peer_info* peer_ptr,
731 std::vector<WifiPeerInfo> peers) {
732 WifiPeerInfo peer;
733 peer.peer_info = *peer_ptr;
734 if (peer_ptr->num_rate > 0) {
735 // Copy the rate stats.
736 peer.rate_stats.assign(peer_ptr->rate_stats, peer_ptr->rate_stats + peer_ptr->num_rate);
737 }
738 peer.peer_info.num_rate = 0;
739 // Push peer info.
740 peers.push_back(peer);
741 // Return the address of next peer info.
742 return (wifi_peer_info*)((u8*)peer_ptr + sizeof(wifi_peer_info) +
743 (sizeof(wifi_rate_stat) * peer_ptr->num_rate));
744}
745// Copies wifi_link_stat* to vector<LinkStats> and returns poiner to next element.
746wifi_link_stat* WifiLegacyHal::copyLinkStat(wifi_link_stat* stat_ptr,
747 std::vector<LinkStats> stats) {
748 LinkStats linkStat;
749 linkStat.stat = *stat_ptr;
750 wifi_peer_info* l_peer_info_stats_ptr = stat_ptr->peer_info;
751 for (uint32_t i = 0; i < linkStat.stat.num_peers; i++) {
752 l_peer_info_stats_ptr = copyPeerInfo(l_peer_info_stats_ptr, linkStat.peers);
753 }
754 // Copied all peers to linkStat.peers.
755 linkStat.stat.num_peers = 0;
756 // Push link stat.
757 stats.push_back(linkStat);
758 // Read all peers, return the address of next wifi_link_stat.
759 return (wifi_link_stat*)l_peer_info_stats_ptr;
760}
761
762wifi_error WifiLegacyHal::getLinkLayerStats(const std::string& iface_name,
763 LinkLayerStats& link_stats,
764 LinkLayerMlStats& link_ml_stats) {
Gabriel Birenf3262f92022-07-15 23:25:39 +0000765 LinkLayerStats* link_stats_ptr = &link_stats;
Mahesh KKV5f30d332022-10-26 14:07:44 -0700766 link_stats_ptr->valid = false;
Gabriel Birenf3262f92022-07-15 23:25:39 +0000767
768 on_link_layer_stats_result_internal_callback = [&link_stats_ptr](
769 wifi_request_id /* id */,
770 wifi_iface_stat* iface_stats_ptr,
771 int num_radios,
772 wifi_radio_stat* radio_stats_ptr) {
773 wifi_radio_stat* l_radio_stats_ptr;
774 wifi_peer_info* l_peer_info_stats_ptr;
Mahesh KKV5f30d332022-10-26 14:07:44 -0700775 link_stats_ptr->valid = true;
Gabriel Birenf3262f92022-07-15 23:25:39 +0000776
777 if (iface_stats_ptr != nullptr) {
778 link_stats_ptr->iface = *iface_stats_ptr;
779 l_peer_info_stats_ptr = iface_stats_ptr->peer_info;
780 for (uint32_t i = 0; i < iface_stats_ptr->num_peers; i++) {
781 WifiPeerInfo peer;
782 peer.peer_info = *l_peer_info_stats_ptr;
783 if (l_peer_info_stats_ptr->num_rate > 0) {
784 /* Copy the rate stats */
785 peer.rate_stats.assign(
786 l_peer_info_stats_ptr->rate_stats,
787 l_peer_info_stats_ptr->rate_stats + l_peer_info_stats_ptr->num_rate);
788 }
789 peer.peer_info.num_rate = 0;
790 link_stats_ptr->peers.push_back(peer);
791 l_peer_info_stats_ptr =
792 (wifi_peer_info*)((u8*)l_peer_info_stats_ptr + sizeof(wifi_peer_info) +
793 (sizeof(wifi_rate_stat) *
794 l_peer_info_stats_ptr->num_rate));
795 }
796 link_stats_ptr->iface.num_peers = 0;
797 } else {
798 LOG(ERROR) << "Invalid iface stats in link layer stats";
799 }
800 if (num_radios <= 0 || radio_stats_ptr == nullptr) {
801 LOG(ERROR) << "Invalid radio stats in link layer stats";
802 return;
803 }
804 l_radio_stats_ptr = radio_stats_ptr;
805 for (int i = 0; i < num_radios; i++) {
806 LinkLayerRadioStats radio;
807
808 radio.stats = *l_radio_stats_ptr;
809 // Copy over the tx level array to the separate vector.
810 if (l_radio_stats_ptr->num_tx_levels > 0 &&
811 l_radio_stats_ptr->tx_time_per_levels != nullptr) {
812 radio.tx_time_per_levels.assign(
813 l_radio_stats_ptr->tx_time_per_levels,
814 l_radio_stats_ptr->tx_time_per_levels + l_radio_stats_ptr->num_tx_levels);
815 }
816 radio.stats.num_tx_levels = 0;
817 radio.stats.tx_time_per_levels = nullptr;
818 /* Copy over the channel stat to separate vector */
819 if (l_radio_stats_ptr->num_channels > 0) {
820 /* Copy the channel stats */
821 radio.channel_stats.assign(
822 l_radio_stats_ptr->channels,
823 l_radio_stats_ptr->channels + l_radio_stats_ptr->num_channels);
824 }
825 link_stats_ptr->radios.push_back(radio);
826 l_radio_stats_ptr =
827 (wifi_radio_stat*)((u8*)l_radio_stats_ptr + sizeof(wifi_radio_stat) +
828 (sizeof(wifi_channel_stat) *
829 l_radio_stats_ptr->num_channels));
830 }
831 };
832
Mahesh KKV5f30d332022-10-26 14:07:44 -0700833 LinkLayerMlStats* link_ml_stats_ptr = &link_ml_stats;
834 link_ml_stats_ptr->valid = false;
835
836 on_link_layer_ml_stats_result_internal_callback =
837 [this, &link_ml_stats_ptr](wifi_request_id /* id */,
838 wifi_iface_ml_stat* iface_ml_stats_ptr, int num_radios,
839 wifi_radio_stat* radio_stats_ptr) {
840 wifi_radio_stat* l_radio_stats_ptr;
841 wifi_link_stat* l_link_stat_ptr;
842 link_ml_stats_ptr->valid = true;
843
844 if (iface_ml_stats_ptr != nullptr && iface_ml_stats_ptr->num_links > 0) {
845 // Copy stats from wifi_iface_ml_stat to LinkLayerMlStats,
846 // - num_links * links[] to vector of links.
847 // - num_peers * peer_info[] to vector of links[i].peers.
848 link_ml_stats_ptr->iface = *iface_ml_stats_ptr;
849 l_link_stat_ptr = iface_ml_stats_ptr->links;
850 for (int l = 0; l < iface_ml_stats_ptr->num_links; ++l) {
851 l_link_stat_ptr = copyLinkStat(l_link_stat_ptr, link_ml_stats_ptr->links);
852 }
853 } else {
854 LOG(ERROR) << "Invalid iface stats in link layer stats";
855 }
856 if (num_radios <= 0 || radio_stats_ptr == nullptr) {
857 LOG(ERROR) << "Invalid radio stats in link layer stats";
858 return;
859 }
860 l_radio_stats_ptr = radio_stats_ptr;
861 for (int i = 0; i < num_radios; i++) {
862 LinkLayerRadioStats radio;
863
864 radio.stats = *l_radio_stats_ptr;
865 // Copy over the tx level array to the separate vector.
866 if (l_radio_stats_ptr->num_tx_levels > 0 &&
867 l_radio_stats_ptr->tx_time_per_levels != nullptr) {
868 radio.tx_time_per_levels.assign(l_radio_stats_ptr->tx_time_per_levels,
869 l_radio_stats_ptr->tx_time_per_levels +
870 l_radio_stats_ptr->num_tx_levels);
871 }
872 radio.stats.num_tx_levels = 0;
873 radio.stats.tx_time_per_levels = nullptr;
874 /* Copy over the channel stat to separate vector */
875 if (l_radio_stats_ptr->num_channels > 0) {
876 /* Copy the channel stats */
877 radio.channel_stats.assign(
878 l_radio_stats_ptr->channels,
879 l_radio_stats_ptr->channels + l_radio_stats_ptr->num_channels);
880 }
881 link_ml_stats_ptr->radios.push_back(radio);
882 l_radio_stats_ptr =
883 (wifi_radio_stat*)((u8*)l_radio_stats_ptr + sizeof(wifi_radio_stat) +
884 (sizeof(wifi_channel_stat) *
885 l_radio_stats_ptr->num_channels));
886 }
887 };
888
889 wifi_error status = global_func_table_.wifi_get_link_stats(
890 0, getIfaceHandle(iface_name),
891 {onSyncLinkLayerStatsResult, onSyncLinkLayerMlStatsResult});
Gabriel Birenf3262f92022-07-15 23:25:39 +0000892 on_link_layer_stats_result_internal_callback = nullptr;
Mahesh KKV5f30d332022-10-26 14:07:44 -0700893 on_link_layer_ml_stats_result_internal_callback = nullptr;
894
895 return status;
Gabriel Birenf3262f92022-07-15 23:25:39 +0000896}
897
898wifi_error WifiLegacyHal::startRssiMonitoring(
899 const std::string& iface_name, wifi_request_id id, int8_t max_rssi, int8_t min_rssi,
900 const on_rssi_threshold_breached_callback& on_threshold_breached_user_callback) {
901 if (on_rssi_threshold_breached_internal_callback) {
902 return WIFI_ERROR_NOT_AVAILABLE;
903 }
904 on_rssi_threshold_breached_internal_callback = [on_threshold_breached_user_callback](
905 wifi_request_id id, uint8_t* bssid_ptr,
906 int8_t rssi) {
907 if (!bssid_ptr) {
908 return;
909 }
910 std::array<uint8_t, ETH_ALEN> bssid_arr;
911 // |bssid_ptr| pointer is assumed to have 6 bytes for the mac
912 // address.
913 std::copy(bssid_ptr, bssid_ptr + 6, std::begin(bssid_arr));
914 on_threshold_breached_user_callback(id, bssid_arr, rssi);
915 };
916 wifi_error status = global_func_table_.wifi_start_rssi_monitoring(
917 id, getIfaceHandle(iface_name), max_rssi, min_rssi, {onAsyncRssiThresholdBreached});
918 if (status != WIFI_SUCCESS) {
919 on_rssi_threshold_breached_internal_callback = nullptr;
920 }
921 return status;
922}
923
924wifi_error WifiLegacyHal::stopRssiMonitoring(const std::string& iface_name, wifi_request_id id) {
925 if (!on_rssi_threshold_breached_internal_callback) {
926 return WIFI_ERROR_NOT_AVAILABLE;
927 }
928 wifi_error status =
929 global_func_table_.wifi_stop_rssi_monitoring(id, getIfaceHandle(iface_name));
930 // If the request Id is wrong, don't stop the ongoing rssi monitoring. Any
931 // other error should be treated as the end of background scan.
932 if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
933 on_rssi_threshold_breached_internal_callback = nullptr;
934 }
935 return status;
936}
937
938std::pair<wifi_error, wifi_roaming_capabilities> WifiLegacyHal::getRoamingCapabilities(
939 const std::string& iface_name) {
940 wifi_roaming_capabilities caps;
941 wifi_error status =
942 global_func_table_.wifi_get_roaming_capabilities(getIfaceHandle(iface_name), &caps);
943 return {status, caps};
944}
945
946wifi_error WifiLegacyHal::configureRoaming(const std::string& iface_name,
947 const wifi_roaming_config& config) {
948 wifi_roaming_config config_internal = config;
949 return global_func_table_.wifi_configure_roaming(getIfaceHandle(iface_name), &config_internal);
950}
951
952wifi_error WifiLegacyHal::enableFirmwareRoaming(const std::string& iface_name,
953 fw_roaming_state_t state) {
954 return global_func_table_.wifi_enable_firmware_roaming(getIfaceHandle(iface_name), state);
955}
956
957wifi_error WifiLegacyHal::configureNdOffload(const std::string& iface_name, bool enable) {
958 return global_func_table_.wifi_configure_nd_offload(getIfaceHandle(iface_name), enable);
959}
960
961wifi_error WifiLegacyHal::startSendingOffloadedPacket(const std::string& iface_name, int32_t cmd_id,
962 uint16_t ether_type,
963 const std::vector<uint8_t>& ip_packet_data,
964 const std::array<uint8_t, 6>& src_address,
965 const std::array<uint8_t, 6>& dst_address,
966 int32_t period_in_ms) {
967 std::vector<uint8_t> ip_packet_data_internal(ip_packet_data);
968 std::vector<uint8_t> src_address_internal(src_address.data(),
969 src_address.data() + src_address.size());
970 std::vector<uint8_t> dst_address_internal(dst_address.data(),
971 dst_address.data() + dst_address.size());
972 return global_func_table_.wifi_start_sending_offloaded_packet(
973 cmd_id, getIfaceHandle(iface_name), ether_type, ip_packet_data_internal.data(),
974 ip_packet_data_internal.size(), src_address_internal.data(),
975 dst_address_internal.data(), period_in_ms);
976}
977
978wifi_error WifiLegacyHal::stopSendingOffloadedPacket(const std::string& iface_name,
979 uint32_t cmd_id) {
980 return global_func_table_.wifi_stop_sending_offloaded_packet(cmd_id,
981 getIfaceHandle(iface_name));
982}
983
984wifi_error WifiLegacyHal::selectTxPowerScenario(const std::string& iface_name,
985 wifi_power_scenario scenario) {
986 return global_func_table_.wifi_select_tx_power_scenario(getIfaceHandle(iface_name), scenario);
987}
988
989wifi_error WifiLegacyHal::resetTxPowerScenario(const std::string& iface_name) {
990 return global_func_table_.wifi_reset_tx_power_scenario(getIfaceHandle(iface_name));
991}
992
993wifi_error WifiLegacyHal::setLatencyMode(const std::string& iface_name, wifi_latency_mode mode) {
994 return global_func_table_.wifi_set_latency_mode(getIfaceHandle(iface_name), mode);
995}
996
997wifi_error WifiLegacyHal::setThermalMitigationMode(wifi_thermal_mode mode,
998 uint32_t completion_window) {
999 return global_func_table_.wifi_set_thermal_mitigation_mode(global_handle_, mode,
1000 completion_window);
1001}
1002
1003wifi_error WifiLegacyHal::setDscpToAccessCategoryMapping(uint32_t start, uint32_t end,
1004 uint32_t access_category) {
1005 return global_func_table_.wifi_map_dscp_access_category(global_handle_, start, end,
1006 access_category);
1007}
1008
1009wifi_error WifiLegacyHal::resetDscpToAccessCategoryMapping() {
1010 return global_func_table_.wifi_reset_dscp_mapping(global_handle_);
1011}
1012
1013std::pair<wifi_error, uint32_t> WifiLegacyHal::getLoggerSupportedFeatureSet(
1014 const std::string& iface_name) {
1015 uint32_t supported_feature_flags = 0;
1016 wifi_error status = WIFI_SUCCESS;
1017
1018 wifi_interface_handle iface_handle = getIfaceHandle(iface_name);
1019
1020 if (iface_handle) {
1021 status = global_func_table_.wifi_get_logger_supported_feature_set(iface_handle,
1022 &supported_feature_flags);
1023 }
1024 return {status, supported_feature_flags};
1025}
1026
1027wifi_error WifiLegacyHal::startPktFateMonitoring(const std::string& iface_name) {
1028 return global_func_table_.wifi_start_pkt_fate_monitoring(getIfaceHandle(iface_name));
1029}
1030
1031std::pair<wifi_error, std::vector<wifi_tx_report>> WifiLegacyHal::getTxPktFates(
1032 const std::string& iface_name) {
1033 std::vector<wifi_tx_report> tx_pkt_fates;
1034 tx_pkt_fates.resize(MAX_FATE_LOG_LEN);
1035 size_t num_fates = 0;
1036 wifi_error status = global_func_table_.wifi_get_tx_pkt_fates(
1037 getIfaceHandle(iface_name), tx_pkt_fates.data(), tx_pkt_fates.size(), &num_fates);
1038 CHECK(num_fates <= MAX_FATE_LOG_LEN);
1039 tx_pkt_fates.resize(num_fates);
1040 return {status, std::move(tx_pkt_fates)};
1041}
1042
1043std::pair<wifi_error, std::vector<wifi_rx_report>> WifiLegacyHal::getRxPktFates(
1044 const std::string& iface_name) {
1045 std::vector<wifi_rx_report> rx_pkt_fates;
1046 rx_pkt_fates.resize(MAX_FATE_LOG_LEN);
1047 size_t num_fates = 0;
1048 wifi_error status = global_func_table_.wifi_get_rx_pkt_fates(
1049 getIfaceHandle(iface_name), rx_pkt_fates.data(), rx_pkt_fates.size(), &num_fates);
1050 CHECK(num_fates <= MAX_FATE_LOG_LEN);
1051 rx_pkt_fates.resize(num_fates);
1052 return {status, std::move(rx_pkt_fates)};
1053}
1054
1055std::pair<wifi_error, WakeReasonStats> WifiLegacyHal::getWakeReasonStats(
1056 const std::string& iface_name) {
1057 WakeReasonStats stats;
1058 stats.cmd_event_wake_cnt.resize(kMaxWakeReasonStatsArraySize);
1059 stats.driver_fw_local_wake_cnt.resize(kMaxWakeReasonStatsArraySize);
1060
1061 // This legacy struct needs separate memory to store the variable sized wake
1062 // reason types.
1063 stats.wake_reason_cnt.cmd_event_wake_cnt =
1064 reinterpret_cast<int32_t*>(stats.cmd_event_wake_cnt.data());
1065 stats.wake_reason_cnt.cmd_event_wake_cnt_sz = stats.cmd_event_wake_cnt.size();
1066 stats.wake_reason_cnt.cmd_event_wake_cnt_used = 0;
1067 stats.wake_reason_cnt.driver_fw_local_wake_cnt =
1068 reinterpret_cast<int32_t*>(stats.driver_fw_local_wake_cnt.data());
1069 stats.wake_reason_cnt.driver_fw_local_wake_cnt_sz = stats.driver_fw_local_wake_cnt.size();
1070 stats.wake_reason_cnt.driver_fw_local_wake_cnt_used = 0;
1071
1072 wifi_error status = global_func_table_.wifi_get_wake_reason_stats(getIfaceHandle(iface_name),
1073 &stats.wake_reason_cnt);
1074
1075 CHECK(stats.wake_reason_cnt.cmd_event_wake_cnt_used >= 0 &&
1076 static_cast<uint32_t>(stats.wake_reason_cnt.cmd_event_wake_cnt_used) <=
1077 kMaxWakeReasonStatsArraySize);
1078 stats.cmd_event_wake_cnt.resize(stats.wake_reason_cnt.cmd_event_wake_cnt_used);
1079 stats.wake_reason_cnt.cmd_event_wake_cnt = nullptr;
1080
1081 CHECK(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used >= 0 &&
1082 static_cast<uint32_t>(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used) <=
1083 kMaxWakeReasonStatsArraySize);
1084 stats.driver_fw_local_wake_cnt.resize(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used);
1085 stats.wake_reason_cnt.driver_fw_local_wake_cnt = nullptr;
1086
1087 return {status, stats};
1088}
1089
1090wifi_error WifiLegacyHal::registerRingBufferCallbackHandler(
1091 const std::string& iface_name, const on_ring_buffer_data_callback& on_user_data_callback) {
1092 if (on_ring_buffer_data_internal_callback) {
1093 return WIFI_ERROR_NOT_AVAILABLE;
1094 }
1095 on_ring_buffer_data_internal_callback = [on_user_data_callback](
1096 char* ring_name, char* buffer, int buffer_size,
1097 wifi_ring_buffer_status* status) {
1098 if (status && buffer) {
1099 std::vector<uint8_t> buffer_vector(reinterpret_cast<uint8_t*>(buffer),
1100 reinterpret_cast<uint8_t*>(buffer) + buffer_size);
1101 on_user_data_callback(ring_name, buffer_vector, *status);
1102 }
1103 };
1104 wifi_error status = global_func_table_.wifi_set_log_handler(0, getIfaceHandle(iface_name),
1105 {onAsyncRingBufferData});
1106 if (status != WIFI_SUCCESS) {
1107 on_ring_buffer_data_internal_callback = nullptr;
1108 }
1109 return status;
1110}
1111
1112wifi_error WifiLegacyHal::deregisterRingBufferCallbackHandler(const std::string& iface_name) {
1113 if (!on_ring_buffer_data_internal_callback) {
1114 return WIFI_ERROR_NOT_AVAILABLE;
1115 }
1116 on_ring_buffer_data_internal_callback = nullptr;
1117 return global_func_table_.wifi_reset_log_handler(0, getIfaceHandle(iface_name));
1118}
1119
1120std::pair<wifi_error, std::vector<wifi_ring_buffer_status>> WifiLegacyHal::getRingBuffersStatus(
1121 const std::string& iface_name) {
1122 std::vector<wifi_ring_buffer_status> ring_buffers_status;
1123 ring_buffers_status.resize(kMaxRingBuffers);
1124 uint32_t num_rings = kMaxRingBuffers;
1125 wifi_error status = global_func_table_.wifi_get_ring_buffers_status(
1126 getIfaceHandle(iface_name), &num_rings, ring_buffers_status.data());
1127 CHECK(num_rings <= kMaxRingBuffers);
1128 ring_buffers_status.resize(num_rings);
1129 return {status, std::move(ring_buffers_status)};
1130}
1131
1132wifi_error WifiLegacyHal::startRingBufferLogging(const std::string& iface_name,
1133 const std::string& ring_name,
1134 uint32_t verbose_level, uint32_t max_interval_sec,
1135 uint32_t min_data_size) {
1136 return global_func_table_.wifi_start_logging(getIfaceHandle(iface_name), verbose_level, 0,
1137 max_interval_sec, min_data_size,
1138 makeCharVec(ring_name).data());
1139}
1140
1141wifi_error WifiLegacyHal::getRingBufferData(const std::string& iface_name,
1142 const std::string& ring_name) {
1143 return global_func_table_.wifi_get_ring_data(getIfaceHandle(iface_name),
1144 makeCharVec(ring_name).data());
1145}
1146
1147wifi_error WifiLegacyHal::registerErrorAlertCallbackHandler(
1148 const std::string& iface_name, const on_error_alert_callback& on_user_alert_callback) {
1149 if (on_error_alert_internal_callback) {
1150 return WIFI_ERROR_NOT_AVAILABLE;
1151 }
1152 on_error_alert_internal_callback = [on_user_alert_callback](wifi_request_id id, char* buffer,
1153 int buffer_size, int err_code) {
1154 if (buffer) {
1155 CHECK(id == 0);
1156 on_user_alert_callback(
1157 err_code,
1158 std::vector<uint8_t>(reinterpret_cast<uint8_t*>(buffer),
1159 reinterpret_cast<uint8_t*>(buffer) + buffer_size));
1160 }
1161 };
1162 wifi_error status = global_func_table_.wifi_set_alert_handler(0, getIfaceHandle(iface_name),
1163 {onAsyncErrorAlert});
1164 if (status != WIFI_SUCCESS) {
1165 on_error_alert_internal_callback = nullptr;
1166 }
1167 return status;
1168}
1169
1170wifi_error WifiLegacyHal::deregisterErrorAlertCallbackHandler(const std::string& iface_name) {
1171 if (!on_error_alert_internal_callback) {
1172 return WIFI_ERROR_NOT_AVAILABLE;
1173 }
1174 on_error_alert_internal_callback = nullptr;
1175 return global_func_table_.wifi_reset_alert_handler(0, getIfaceHandle(iface_name));
1176}
1177
1178wifi_error WifiLegacyHal::registerRadioModeChangeCallbackHandler(
1179 const std::string& iface_name,
1180 const on_radio_mode_change_callback& on_user_change_callback) {
1181 if (on_radio_mode_change_internal_callback) {
1182 return WIFI_ERROR_NOT_AVAILABLE;
1183 }
1184 on_radio_mode_change_internal_callback = [on_user_change_callback](
1185 wifi_request_id /* id */, uint32_t num_macs,
1186 wifi_mac_info* mac_infos_arr) {
1187 if (num_macs > 0 && mac_infos_arr) {
1188 std::vector<WifiMacInfo> mac_infos_vec;
1189 for (uint32_t i = 0; i < num_macs; i++) {
1190 WifiMacInfo mac_info;
1191 mac_info.wlan_mac_id = mac_infos_arr[i].wlan_mac_id;
1192 mac_info.mac_band = mac_infos_arr[i].mac_band;
1193 for (int32_t j = 0; j < mac_infos_arr[i].num_iface; j++) {
1194 WifiIfaceInfo iface_info;
1195 iface_info.name = mac_infos_arr[i].iface_info[j].iface_name;
1196 iface_info.channel = mac_infos_arr[i].iface_info[j].channel;
1197 mac_info.iface_infos.push_back(iface_info);
1198 }
1199 mac_infos_vec.push_back(mac_info);
1200 }
1201 on_user_change_callback(mac_infos_vec);
1202 }
1203 };
1204 wifi_error status = global_func_table_.wifi_set_radio_mode_change_handler(
1205 0, getIfaceHandle(iface_name), {onAsyncRadioModeChange});
1206 if (status != WIFI_SUCCESS) {
1207 on_radio_mode_change_internal_callback = nullptr;
1208 }
1209 return status;
1210}
1211
1212wifi_error WifiLegacyHal::registerSubsystemRestartCallbackHandler(
1213 const on_subsystem_restart_callback& on_restart_callback) {
1214 if (on_subsystem_restart_internal_callback) {
1215 return WIFI_ERROR_NOT_AVAILABLE;
1216 }
1217 on_subsystem_restart_internal_callback = [on_restart_callback](const char* error) {
1218 on_restart_callback(error);
1219 };
1220 wifi_error status = global_func_table_.wifi_set_subsystem_restart_handler(
1221 global_handle_, {onAsyncSubsystemRestart});
1222 if (status != WIFI_SUCCESS) {
1223 on_subsystem_restart_internal_callback = nullptr;
1224 }
1225 return status;
1226}
1227
1228wifi_error WifiLegacyHal::startRttRangeRequest(
1229 const std::string& iface_name, wifi_request_id id,
1230 const std::vector<wifi_rtt_config>& rtt_configs,
1231 const on_rtt_results_callback& on_results_user_callback) {
1232 if (on_rtt_results_internal_callback) {
1233 return WIFI_ERROR_NOT_AVAILABLE;
1234 }
1235
1236 on_rtt_results_internal_callback = [on_results_user_callback](wifi_request_id id,
1237 unsigned num_results,
1238 wifi_rtt_result* rtt_results[]) {
1239 if (num_results > 0 && !rtt_results) {
1240 LOG(ERROR) << "Unexpected nullptr in RTT results";
1241 return;
1242 }
1243 std::vector<const wifi_rtt_result*> rtt_results_vec;
1244 std::copy_if(rtt_results, rtt_results + num_results, back_inserter(rtt_results_vec),
1245 [](wifi_rtt_result* rtt_result) { return rtt_result != nullptr; });
1246 on_results_user_callback(id, rtt_results_vec);
1247 };
1248
1249 std::vector<wifi_rtt_config> rtt_configs_internal(rtt_configs);
1250 wifi_error status = global_func_table_.wifi_rtt_range_request(
1251 id, getIfaceHandle(iface_name), rtt_configs.size(), rtt_configs_internal.data(),
1252 {onAsyncRttResults});
1253 if (status != WIFI_SUCCESS) {
1254 on_rtt_results_internal_callback = nullptr;
1255 }
1256 return status;
1257}
1258
1259wifi_error WifiLegacyHal::cancelRttRangeRequest(
1260 const std::string& iface_name, wifi_request_id id,
1261 const std::vector<std::array<uint8_t, ETH_ALEN>>& mac_addrs) {
1262 if (!on_rtt_results_internal_callback) {
1263 return WIFI_ERROR_NOT_AVAILABLE;
1264 }
1265 static_assert(sizeof(mac_addr) == sizeof(std::array<uint8_t, ETH_ALEN>),
1266 "MAC address size mismatch");
1267 // TODO: How do we handle partial cancels (i.e only a subset of enabled mac
1268 // addressed are cancelled).
1269 std::vector<std::array<uint8_t, ETH_ALEN>> mac_addrs_internal(mac_addrs);
1270 wifi_error status = global_func_table_.wifi_rtt_range_cancel(
1271 id, getIfaceHandle(iface_name), mac_addrs.size(),
1272 reinterpret_cast<mac_addr*>(mac_addrs_internal.data()));
1273 // If the request Id is wrong, don't stop the ongoing range request. Any
1274 // other error should be treated as the end of rtt ranging.
1275 if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
1276 on_rtt_results_internal_callback = nullptr;
1277 }
1278 return status;
1279}
1280
1281std::pair<wifi_error, wifi_rtt_capabilities> WifiLegacyHal::getRttCapabilities(
1282 const std::string& iface_name) {
1283 wifi_rtt_capabilities rtt_caps;
1284 wifi_error status =
1285 global_func_table_.wifi_get_rtt_capabilities(getIfaceHandle(iface_name), &rtt_caps);
1286 return {status, rtt_caps};
1287}
1288
1289std::pair<wifi_error, wifi_rtt_responder> WifiLegacyHal::getRttResponderInfo(
1290 const std::string& iface_name) {
1291 wifi_rtt_responder rtt_responder;
1292 wifi_error status = global_func_table_.wifi_rtt_get_responder_info(getIfaceHandle(iface_name),
1293 &rtt_responder);
1294 return {status, rtt_responder};
1295}
1296
1297wifi_error WifiLegacyHal::enableRttResponder(const std::string& iface_name, wifi_request_id id,
1298 const wifi_channel_info& channel_hint,
1299 uint32_t max_duration_secs,
1300 const wifi_rtt_responder& info) {
1301 wifi_rtt_responder info_internal(info);
1302 return global_func_table_.wifi_enable_responder(id, getIfaceHandle(iface_name), channel_hint,
1303 max_duration_secs, &info_internal);
1304}
1305
1306wifi_error WifiLegacyHal::disableRttResponder(const std::string& iface_name, wifi_request_id id) {
1307 return global_func_table_.wifi_disable_responder(id, getIfaceHandle(iface_name));
1308}
1309
1310wifi_error WifiLegacyHal::setRttLci(const std::string& iface_name, wifi_request_id id,
1311 const wifi_lci_information& info) {
1312 wifi_lci_information info_internal(info);
1313 return global_func_table_.wifi_set_lci(id, getIfaceHandle(iface_name), &info_internal);
1314}
1315
1316wifi_error WifiLegacyHal::setRttLcr(const std::string& iface_name, wifi_request_id id,
1317 const wifi_lcr_information& info) {
1318 wifi_lcr_information info_internal(info);
1319 return global_func_table_.wifi_set_lcr(id, getIfaceHandle(iface_name), &info_internal);
1320}
1321
1322wifi_error WifiLegacyHal::nanRegisterCallbackHandlers(const std::string& iface_name,
1323 const NanCallbackHandlers& user_callbacks) {
1324 on_nan_notify_response_user_callback = user_callbacks.on_notify_response;
1325 on_nan_event_publish_terminated_user_callback = user_callbacks.on_event_publish_terminated;
1326 on_nan_event_match_user_callback = user_callbacks.on_event_match;
1327 on_nan_event_match_expired_user_callback = user_callbacks.on_event_match_expired;
1328 on_nan_event_subscribe_terminated_user_callback = user_callbacks.on_event_subscribe_terminated;
1329 on_nan_event_followup_user_callback = user_callbacks.on_event_followup;
1330 on_nan_event_disc_eng_event_user_callback = user_callbacks.on_event_disc_eng_event;
1331 on_nan_event_disabled_user_callback = user_callbacks.on_event_disabled;
1332 on_nan_event_tca_user_callback = user_callbacks.on_event_tca;
1333 on_nan_event_beacon_sdf_payload_user_callback = user_callbacks.on_event_beacon_sdf_payload;
1334 on_nan_event_data_path_request_user_callback = user_callbacks.on_event_data_path_request;
Nate Jiang38e8db52022-12-02 17:30:27 -08001335 on_nan_event_pairing_request_user_callback = user_callbacks.on_event_pairing_request;
1336 on_nan_event_pairing_confirm_user_callback = user_callbacks.on_event_pairing_confirm;
1337 on_nan_event_bootstrapping_request_user_callback =
1338 user_callbacks.on_event_bootstrapping_request;
1339 on_nan_event_bootstrapping_confirm_user_callback =
1340 user_callbacks.on_event_bootstrapping_confirm;
Gabriel Birenf3262f92022-07-15 23:25:39 +00001341 on_nan_event_data_path_confirm_user_callback = user_callbacks.on_event_data_path_confirm;
1342 on_nan_event_data_path_end_user_callback = user_callbacks.on_event_data_path_end;
1343 on_nan_event_transmit_follow_up_user_callback = user_callbacks.on_event_transmit_follow_up;
1344 on_nan_event_range_request_user_callback = user_callbacks.on_event_range_request;
1345 on_nan_event_range_report_user_callback = user_callbacks.on_event_range_report;
1346 on_nan_event_schedule_update_user_callback = user_callbacks.on_event_schedule_update;
1347
Nate Jiang38e8db52022-12-02 17:30:27 -08001348 return global_func_table_.wifi_nan_register_handler(getIfaceHandle(iface_name),
1349 {onAsyncNanNotifyResponse,
1350 onAsyncNanEventPublishReplied,
1351 onAsyncNanEventPublishTerminated,
1352 onAsyncNanEventMatch,
1353 onAsyncNanEventMatchExpired,
1354 onAsyncNanEventSubscribeTerminated,
1355 onAsyncNanEventFollowup,
1356 onAsyncNanEventDiscEngEvent,
1357 onAsyncNanEventDisabled,
1358 onAsyncNanEventTca,
1359 onAsyncNanEventBeaconSdfPayload,
1360 onAsyncNanEventDataPathRequest,
1361 onAsyncNanEventDataPathConfirm,
1362 onAsyncNanEventDataPathEnd,
1363 onAsyncNanEventTransmitFollowUp,
1364 onAsyncNanEventRangeRequest,
1365 onAsyncNanEventRangeReport,
1366 onAsyncNanEventScheduleUpdate,
1367 onAsyncNanEventPairingRequest,
1368 onAsyncNanEventPairingConfirm,
1369 onAsyncNanEventBootstrappingRequest,
1370 onAsyncNanEventBootstrappingConfirm});
Gabriel Birenf3262f92022-07-15 23:25:39 +00001371}
1372
1373wifi_error WifiLegacyHal::nanEnableRequest(const std::string& iface_name, transaction_id id,
1374 const NanEnableRequest& msg) {
1375 NanEnableRequest msg_internal(msg);
1376 return global_func_table_.wifi_nan_enable_request(id, getIfaceHandle(iface_name),
1377 &msg_internal);
1378}
1379
1380wifi_error WifiLegacyHal::nanDisableRequest(const std::string& iface_name, transaction_id id) {
1381 return global_func_table_.wifi_nan_disable_request(id, getIfaceHandle(iface_name));
1382}
1383
1384wifi_error WifiLegacyHal::nanPublishRequest(const std::string& iface_name, transaction_id id,
1385 const NanPublishRequest& msg) {
1386 NanPublishRequest msg_internal(msg);
1387 return global_func_table_.wifi_nan_publish_request(id, getIfaceHandle(iface_name),
1388 &msg_internal);
1389}
1390
1391wifi_error WifiLegacyHal::nanPublishCancelRequest(const std::string& iface_name, transaction_id id,
1392 const NanPublishCancelRequest& msg) {
1393 NanPublishCancelRequest msg_internal(msg);
1394 return global_func_table_.wifi_nan_publish_cancel_request(id, getIfaceHandle(iface_name),
1395 &msg_internal);
1396}
1397
1398wifi_error WifiLegacyHal::nanSubscribeRequest(const std::string& iface_name, transaction_id id,
1399 const NanSubscribeRequest& msg) {
1400 NanSubscribeRequest msg_internal(msg);
1401 return global_func_table_.wifi_nan_subscribe_request(id, getIfaceHandle(iface_name),
1402 &msg_internal);
1403}
1404
1405wifi_error WifiLegacyHal::nanSubscribeCancelRequest(const std::string& iface_name,
1406 transaction_id id,
1407 const NanSubscribeCancelRequest& msg) {
1408 NanSubscribeCancelRequest msg_internal(msg);
1409 return global_func_table_.wifi_nan_subscribe_cancel_request(id, getIfaceHandle(iface_name),
1410 &msg_internal);
1411}
1412
1413wifi_error WifiLegacyHal::nanTransmitFollowupRequest(const std::string& iface_name,
1414 transaction_id id,
1415 const NanTransmitFollowupRequest& msg) {
1416 NanTransmitFollowupRequest msg_internal(msg);
1417 return global_func_table_.wifi_nan_transmit_followup_request(id, getIfaceHandle(iface_name),
1418 &msg_internal);
1419}
1420
1421wifi_error WifiLegacyHal::nanStatsRequest(const std::string& iface_name, transaction_id id,
1422 const NanStatsRequest& msg) {
1423 NanStatsRequest msg_internal(msg);
1424 return global_func_table_.wifi_nan_stats_request(id, getIfaceHandle(iface_name), &msg_internal);
1425}
1426
1427wifi_error WifiLegacyHal::nanConfigRequest(const std::string& iface_name, transaction_id id,
1428 const NanConfigRequest& msg) {
1429 NanConfigRequest msg_internal(msg);
1430 return global_func_table_.wifi_nan_config_request(id, getIfaceHandle(iface_name),
1431 &msg_internal);
1432}
1433
1434wifi_error WifiLegacyHal::nanTcaRequest(const std::string& iface_name, transaction_id id,
1435 const NanTCARequest& msg) {
1436 NanTCARequest msg_internal(msg);
1437 return global_func_table_.wifi_nan_tca_request(id, getIfaceHandle(iface_name), &msg_internal);
1438}
1439
1440wifi_error WifiLegacyHal::nanBeaconSdfPayloadRequest(const std::string& iface_name,
1441 transaction_id id,
1442 const NanBeaconSdfPayloadRequest& msg) {
1443 NanBeaconSdfPayloadRequest msg_internal(msg);
1444 return global_func_table_.wifi_nan_beacon_sdf_payload_request(id, getIfaceHandle(iface_name),
1445 &msg_internal);
1446}
1447
1448std::pair<wifi_error, NanVersion> WifiLegacyHal::nanGetVersion() {
1449 NanVersion version;
1450 wifi_error status = global_func_table_.wifi_nan_get_version(global_handle_, &version);
1451 return {status, version};
1452}
1453
1454wifi_error WifiLegacyHal::nanGetCapabilities(const std::string& iface_name, transaction_id id) {
1455 return global_func_table_.wifi_nan_get_capabilities(id, getIfaceHandle(iface_name));
1456}
1457
1458wifi_error WifiLegacyHal::nanDataInterfaceCreate(const std::string& iface_name, transaction_id id,
1459 const std::string& data_iface_name) {
1460 return global_func_table_.wifi_nan_data_interface_create(id, getIfaceHandle(iface_name),
1461 makeCharVec(data_iface_name).data());
1462}
1463
1464wifi_error WifiLegacyHal::nanDataInterfaceDelete(const std::string& iface_name, transaction_id id,
1465 const std::string& data_iface_name) {
1466 return global_func_table_.wifi_nan_data_interface_delete(id, getIfaceHandle(iface_name),
1467 makeCharVec(data_iface_name).data());
1468}
1469
1470wifi_error WifiLegacyHal::nanDataRequestInitiator(const std::string& iface_name, transaction_id id,
1471 const NanDataPathInitiatorRequest& msg) {
1472 NanDataPathInitiatorRequest msg_internal(msg);
1473 return global_func_table_.wifi_nan_data_request_initiator(id, getIfaceHandle(iface_name),
1474 &msg_internal);
1475}
1476
1477wifi_error WifiLegacyHal::nanDataIndicationResponse(const std::string& iface_name,
1478 transaction_id id,
1479 const NanDataPathIndicationResponse& msg) {
1480 NanDataPathIndicationResponse msg_internal(msg);
1481 return global_func_table_.wifi_nan_data_indication_response(id, getIfaceHandle(iface_name),
1482 &msg_internal);
1483}
1484
Nate Jiang38e8db52022-12-02 17:30:27 -08001485wifi_error WifiLegacyHal::nanPairingRequest(const std::string& iface_name, transaction_id id,
1486 const NanPairingRequest& msg) {
1487 NanPairingRequest msg_internal(msg);
1488 return global_func_table_.wifi_nan_pairing_request(id, getIfaceHandle(iface_name),
1489 &msg_internal);
1490}
1491
1492wifi_error WifiLegacyHal::nanPairingIndicationResponse(const std::string& iface_name,
1493 transaction_id id,
1494 const NanPairingIndicationResponse& msg) {
1495 NanPairingIndicationResponse msg_internal(msg);
1496 return global_func_table_.wifi_nan_pairing_indication_response(id, getIfaceHandle(iface_name),
1497 &msg_internal);
1498}
1499
1500wifi_error WifiLegacyHal::nanBootstrappingRequest(const std::string& iface_name, transaction_id id,
1501 const NanBootstrappingRequest& msg) {
1502 NanBootstrappingRequest msg_internal(msg);
1503 return global_func_table_.wifi_nan_bootstrapping_request(id, getIfaceHandle(iface_name),
1504 &msg_internal);
1505}
1506
1507wifi_error WifiLegacyHal::nanBootstrappingIndicationResponse(
1508 const std::string& iface_name, transaction_id id,
1509 const NanBootstrappingIndicationResponse& msg) {
1510 NanBootstrappingIndicationResponse msg_internal(msg);
1511 return global_func_table_.wifi_nan_bootstrapping_indication_response(
1512 id, getIfaceHandle(iface_name), &msg_internal);
1513}
1514
Gabriel Birenf3262f92022-07-15 23:25:39 +00001515typedef struct {
1516 u8 num_ndp_instances;
1517 NanDataPathId ndp_instance_id;
1518} NanDataPathEndSingleNdpIdRequest;
1519
1520wifi_error WifiLegacyHal::nanDataEnd(const std::string& iface_name, transaction_id id,
1521 uint32_t ndpInstanceId) {
1522 NanDataPathEndSingleNdpIdRequest msg;
1523 msg.num_ndp_instances = 1;
1524 msg.ndp_instance_id = ndpInstanceId;
1525 wifi_error status = global_func_table_.wifi_nan_data_end(id, getIfaceHandle(iface_name),
1526 (NanDataPathEndRequest*)&msg);
1527 return status;
1528}
1529
1530wifi_error WifiLegacyHal::setCountryCode(const std::string& iface_name,
1531 const std::array<uint8_t, 2> code) {
1532 std::string code_str(code.data(), code.data() + code.size());
1533 return global_func_table_.wifi_set_country_code(getIfaceHandle(iface_name), code_str.c_str());
1534}
1535
1536wifi_error WifiLegacyHal::retrieveIfaceHandles() {
1537 wifi_interface_handle* iface_handles = nullptr;
1538 int num_iface_handles = 0;
1539 wifi_error status =
1540 global_func_table_.wifi_get_ifaces(global_handle_, &num_iface_handles, &iface_handles);
1541 if (status != WIFI_SUCCESS) {
1542 LOG(ERROR) << "Failed to enumerate interface handles";
1543 return status;
1544 }
1545 iface_name_to_handle_.clear();
1546 for (int i = 0; i < num_iface_handles; ++i) {
1547 std::array<char, IFNAMSIZ> iface_name_arr = {};
1548 status = global_func_table_.wifi_get_iface_name(iface_handles[i], iface_name_arr.data(),
1549 iface_name_arr.size());
1550 if (status != WIFI_SUCCESS) {
1551 LOG(WARNING) << "Failed to get interface handle name";
1552 continue;
1553 }
1554 // Assuming the interface name is null terminated since the legacy HAL
1555 // API does not return a size.
1556 std::string iface_name(iface_name_arr.data());
1557 LOG(INFO) << "Adding interface handle for " << iface_name;
1558 iface_name_to_handle_[iface_name] = iface_handles[i];
1559 }
1560 return WIFI_SUCCESS;
1561}
1562
1563wifi_interface_handle WifiLegacyHal::getIfaceHandle(const std::string& iface_name) {
1564 const auto iface_handle_iter = iface_name_to_handle_.find(iface_name);
1565 if (iface_handle_iter == iface_name_to_handle_.end()) {
1566 LOG(ERROR) << "Unknown iface name: " << iface_name;
1567 return nullptr;
1568 }
1569 return iface_handle_iter->second;
1570}
1571
1572void WifiLegacyHal::runEventLoop() {
1573 LOG(DEBUG) << "Starting legacy HAL event loop";
1574 global_func_table_.wifi_event_loop(global_handle_);
1575 const auto lock = aidl_sync_util::acquireGlobalLock();
1576 if (!awaiting_event_loop_termination_) {
1577 LOG(FATAL) << "Legacy HAL event loop terminated, but HAL was not stopping";
1578 }
1579 LOG(DEBUG) << "Legacy HAL event loop terminated";
1580 awaiting_event_loop_termination_ = false;
1581 stop_wait_cv_.notify_one();
1582}
1583
1584std::pair<wifi_error, std::vector<wifi_cached_scan_results>> WifiLegacyHal::getGscanCachedResults(
1585 const std::string& iface_name) {
1586 std::vector<wifi_cached_scan_results> cached_scan_results;
1587 cached_scan_results.resize(kMaxCachedGscanResults);
1588 int32_t num_results = 0;
1589 wifi_error status = global_func_table_.wifi_get_cached_gscan_results(
1590 getIfaceHandle(iface_name), true /* always flush */, cached_scan_results.size(),
1591 cached_scan_results.data(), &num_results);
1592 CHECK(num_results >= 0 && static_cast<uint32_t>(num_results) <= kMaxCachedGscanResults);
1593 cached_scan_results.resize(num_results);
1594 // Check for invalid IE lengths in these cached scan results and correct it.
1595 for (auto& cached_scan_result : cached_scan_results) {
1596 int num_scan_results = cached_scan_result.num_results;
1597 for (int i = 0; i < num_scan_results; i++) {
1598 auto& scan_result = cached_scan_result.results[i];
1599 if (scan_result.ie_length > 0) {
1600 LOG(DEBUG) << "Cached scan result has non-zero IE length " << scan_result.ie_length;
1601 scan_result.ie_length = 0;
1602 }
1603 }
1604 }
1605 return {status, std::move(cached_scan_results)};
1606}
1607
1608wifi_error WifiLegacyHal::createVirtualInterface(const std::string& ifname,
1609 wifi_interface_type iftype) {
1610 // Create the interface if it doesn't exist. If interface already exist,
1611 // Vendor Hal should return WIFI_SUCCESS.
1612 wifi_error status = global_func_table_.wifi_virtual_interface_create(global_handle_,
1613 ifname.c_str(), iftype);
1614 return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status);
1615}
1616
1617wifi_error WifiLegacyHal::deleteVirtualInterface(const std::string& ifname) {
1618 // Delete the interface if it was created dynamically.
1619 wifi_error status =
1620 global_func_table_.wifi_virtual_interface_delete(global_handle_, ifname.c_str());
1621 return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status);
1622}
1623
1624wifi_error WifiLegacyHal::handleVirtualInterfaceCreateOrDeleteStatus(const std::string& ifname,
1625 wifi_error status) {
1626 if (status == WIFI_SUCCESS) {
1627 // refresh list of handlers now.
1628 status = retrieveIfaceHandles();
1629 } else if (status == WIFI_ERROR_NOT_SUPPORTED) {
1630 // Vendor hal does not implement this API. Such vendor implementations
1631 // are expected to create / delete interface by other means.
1632
1633 // check if interface exists.
1634 if (if_nametoindex(ifname.c_str())) {
1635 status = retrieveIfaceHandles();
1636 }
1637 }
1638 return status;
1639}
1640
1641wifi_error WifiLegacyHal::getSupportedIfaceName(uint32_t iface_type, std::string& ifname) {
1642 std::array<char, IFNAMSIZ> buffer;
1643
1644 wifi_error res = global_func_table_.wifi_get_supported_iface_name(
1645 global_handle_, (uint32_t)iface_type, buffer.data(), buffer.size());
1646 if (res == WIFI_SUCCESS) ifname = buffer.data();
1647
1648 return res;
1649}
1650
1651wifi_error WifiLegacyHal::multiStaSetPrimaryConnection(const std::string& ifname) {
1652 return global_func_table_.wifi_multi_sta_set_primary_connection(global_handle_,
1653 getIfaceHandle(ifname));
1654}
1655
1656wifi_error WifiLegacyHal::multiStaSetUseCase(wifi_multi_sta_use_case use_case) {
1657 return global_func_table_.wifi_multi_sta_set_use_case(global_handle_, use_case);
1658}
1659
1660wifi_error WifiLegacyHal::setCoexUnsafeChannels(
1661 std::vector<wifi_coex_unsafe_channel> unsafe_channels, uint32_t restrictions) {
1662 return global_func_table_.wifi_set_coex_unsafe_channels(global_handle_, unsafe_channels.size(),
1663 unsafe_channels.data(), restrictions);
1664}
1665
1666wifi_error WifiLegacyHal::setVoipMode(const std::string& iface_name, wifi_voip_mode mode) {
1667 return global_func_table_.wifi_set_voip_mode(getIfaceHandle(iface_name), mode);
1668}
1669
1670wifi_error WifiLegacyHal::twtRegisterHandler(const std::string& iface_name,
1671 const TwtCallbackHandlers& user_callbacks) {
1672 on_twt_event_setup_response_callback = user_callbacks.on_setup_response;
1673 on_twt_event_teardown_completion_callback = user_callbacks.on_teardown_completion;
1674 on_twt_event_info_frame_received_callback = user_callbacks.on_info_frame_received;
1675 on_twt_event_device_notify_callback = user_callbacks.on_device_notify;
1676
1677 return global_func_table_.wifi_twt_register_handler(
1678 getIfaceHandle(iface_name),
1679 {onAsyncTwtEventSetupResponse, onAsyncTwtEventTeardownCompletion,
1680 onAsyncTwtEventInfoFrameReceived, onAsyncTwtEventDeviceNotify});
1681}
1682
1683std::pair<wifi_error, TwtCapabilitySet> WifiLegacyHal::twtGetCapability(
1684 const std::string& iface_name) {
1685 TwtCapabilitySet capSet;
1686 wifi_error status =
1687 global_func_table_.wifi_twt_get_capability(getIfaceHandle(iface_name), &capSet);
1688 return {status, capSet};
1689}
1690
1691wifi_error WifiLegacyHal::twtSetupRequest(const std::string& iface_name,
1692 const TwtSetupRequest& msg) {
1693 TwtSetupRequest msgInternal(msg);
1694 return global_func_table_.wifi_twt_setup_request(getIfaceHandle(iface_name), &msgInternal);
1695}
1696
1697wifi_error WifiLegacyHal::twtTearDownRequest(const std::string& iface_name,
1698 const TwtTeardownRequest& msg) {
1699 TwtTeardownRequest msgInternal(msg);
1700 return global_func_table_.wifi_twt_teardown_request(getIfaceHandle(iface_name), &msgInternal);
1701}
1702
1703wifi_error WifiLegacyHal::twtInfoFrameRequest(const std::string& iface_name,
1704 const TwtInfoFrameRequest& msg) {
1705 TwtInfoFrameRequest msgInternal(msg);
1706 return global_func_table_.wifi_twt_info_frame_request(getIfaceHandle(iface_name), &msgInternal);
1707}
1708
1709std::pair<wifi_error, TwtStats> WifiLegacyHal::twtGetStats(const std::string& iface_name,
1710 uint8_t configId) {
1711 TwtStats stats;
1712 wifi_error status =
1713 global_func_table_.wifi_twt_get_stats(getIfaceHandle(iface_name), configId, &stats);
1714 return {status, stats};
1715}
1716
1717wifi_error WifiLegacyHal::twtClearStats(const std::string& iface_name, uint8_t configId) {
1718 return global_func_table_.wifi_twt_clear_stats(getIfaceHandle(iface_name), configId);
1719}
1720
1721wifi_error WifiLegacyHal::setDtimConfig(const std::string& iface_name, uint32_t multiplier) {
1722 return global_func_table_.wifi_set_dtim_config(getIfaceHandle(iface_name), multiplier);
1723}
1724
1725std::pair<wifi_error, std::vector<wifi_usable_channel>> WifiLegacyHal::getUsableChannels(
1726 uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask) {
1727 std::vector<wifi_usable_channel> channels;
1728 channels.resize(kMaxWifiUsableChannels);
1729 uint32_t size = 0;
1730 wifi_error status = global_func_table_.wifi_get_usable_channels(
1731 global_handle_, band_mask, iface_mode_mask, filter_mask, channels.size(), &size,
1732 reinterpret_cast<wifi_usable_channel*>(channels.data()));
1733 CHECK(size >= 0 && size <= kMaxWifiUsableChannels);
1734 channels.resize(size);
1735 return {status, std::move(channels)};
1736}
1737
1738wifi_error WifiLegacyHal::triggerSubsystemRestart() {
1739 return global_func_table_.wifi_trigger_subsystem_restart(global_handle_);
1740}
1741
1742wifi_error WifiLegacyHal::setIndoorState(bool isIndoor) {
1743 return global_func_table_.wifi_set_indoor_state(global_handle_, isIndoor);
1744}
1745
1746std::pair<wifi_error, wifi_radio_combination_matrix*>
1747WifiLegacyHal::getSupportedRadioCombinationsMatrix() {
1748 char* buffer = new char[kMaxSupportedRadioCombinationsMatrixLength];
1749 std::fill(buffer, buffer + kMaxSupportedRadioCombinationsMatrixLength, 0);
1750 uint32_t size = 0;
1751 wifi_radio_combination_matrix* radio_combination_matrix_ptr =
1752 reinterpret_cast<wifi_radio_combination_matrix*>(buffer);
1753 wifi_error status = global_func_table_.wifi_get_supported_radio_combinations_matrix(
1754 global_handle_, kMaxSupportedRadioCombinationsMatrixLength, &size,
1755 radio_combination_matrix_ptr);
1756 CHECK(size >= 0 && size <= kMaxSupportedRadioCombinationsMatrixLength);
1757 return {status, radio_combination_matrix_ptr};
1758}
1759
1760wifi_error WifiLegacyHal::chreNanRttRequest(const std::string& iface_name, bool enable) {
1761 if (enable)
1762 return global_func_table_.wifi_nan_rtt_chre_enable_request(0, getIfaceHandle(iface_name),
1763 NULL);
1764 else
1765 return global_func_table_.wifi_nan_rtt_chre_disable_request(0, getIfaceHandle(iface_name));
1766}
1767
1768wifi_error WifiLegacyHal::chreRegisterHandler(const std::string& iface_name,
1769 const ChreCallbackHandlers& handler) {
1770 if (on_chre_nan_rtt_internal_callback) {
1771 return WIFI_ERROR_NOT_AVAILABLE;
1772 }
1773
1774 on_chre_nan_rtt_internal_callback = handler.on_wifi_chre_nan_rtt_state;
1775
1776 wifi_error status = global_func_table_.wifi_chre_register_handler(getIfaceHandle(iface_name),
1777 {onAsyncChreNanRttState});
1778 if (status != WIFI_SUCCESS) {
1779 on_chre_nan_rtt_internal_callback = nullptr;
1780 }
1781 return status;
1782}
1783
1784wifi_error WifiLegacyHal::enableWifiTxPowerLimits(const std::string& iface_name, bool enable) {
1785 return global_func_table_.wifi_enable_tx_power_limits(getIfaceHandle(iface_name), enable);
1786}
1787
1788wifi_error WifiLegacyHal::getWifiCachedScanResults(
1789 const std::string& iface_name, const CachedScanResultsCallbackHandlers& handler) {
1790 on_cached_scan_results_internal_callback = handler.on_cached_scan_results;
1791
1792 wifi_error status = global_func_table_.wifi_get_cached_scan_results(getIfaceHandle(iface_name),
1793 {onSyncCachedScanResults});
1794
1795 on_cached_scan_results_internal_callback = nullptr;
1796 return status;
1797}
1798
Mahesh KKVc84d3772022-12-02 16:53:28 -08001799std::pair<wifi_error, wifi_chip_capabilities> WifiLegacyHal::getWifiChipCapabilities() {
1800 wifi_chip_capabilities chip_capabilities;
1801 wifi_error status =
1802 global_func_table_.wifi_get_chip_capabilities(global_handle_, &chip_capabilities);
1803 return {status, chip_capabilities};
1804}
1805
Gabriel Birenf3262f92022-07-15 23:25:39 +00001806void WifiLegacyHal::invalidate() {
1807 global_handle_ = nullptr;
1808 iface_name_to_handle_.clear();
1809 on_driver_memory_dump_internal_callback = nullptr;
1810 on_firmware_memory_dump_internal_callback = nullptr;
1811 on_gscan_event_internal_callback = nullptr;
1812 on_gscan_full_result_internal_callback = nullptr;
1813 on_link_layer_stats_result_internal_callback = nullptr;
Mahesh KKV5f30d332022-10-26 14:07:44 -07001814 on_link_layer_ml_stats_result_internal_callback = nullptr;
Gabriel Birenf3262f92022-07-15 23:25:39 +00001815 on_rssi_threshold_breached_internal_callback = nullptr;
1816 on_ring_buffer_data_internal_callback = nullptr;
1817 on_error_alert_internal_callback = nullptr;
1818 on_radio_mode_change_internal_callback = nullptr;
1819 on_subsystem_restart_internal_callback = nullptr;
1820 on_rtt_results_internal_callback = nullptr;
1821 on_nan_notify_response_user_callback = nullptr;
1822 on_nan_event_publish_terminated_user_callback = nullptr;
1823 on_nan_event_match_user_callback = nullptr;
1824 on_nan_event_match_expired_user_callback = nullptr;
1825 on_nan_event_subscribe_terminated_user_callback = nullptr;
1826 on_nan_event_followup_user_callback = nullptr;
1827 on_nan_event_disc_eng_event_user_callback = nullptr;
1828 on_nan_event_disabled_user_callback = nullptr;
1829 on_nan_event_tca_user_callback = nullptr;
1830 on_nan_event_beacon_sdf_payload_user_callback = nullptr;
1831 on_nan_event_data_path_request_user_callback = nullptr;
Nate Jiang38e8db52022-12-02 17:30:27 -08001832 on_nan_event_pairing_request_user_callback = nullptr;
1833 on_nan_event_pairing_confirm_user_callback = nullptr;
1834 on_nan_event_bootstrapping_request_user_callback = nullptr;
1835 on_nan_event_bootstrapping_confirm_user_callback = nullptr;
Gabriel Birenf3262f92022-07-15 23:25:39 +00001836 on_nan_event_data_path_confirm_user_callback = nullptr;
1837 on_nan_event_data_path_end_user_callback = nullptr;
1838 on_nan_event_transmit_follow_up_user_callback = nullptr;
1839 on_nan_event_range_request_user_callback = nullptr;
1840 on_nan_event_range_report_user_callback = nullptr;
1841 on_nan_event_schedule_update_user_callback = nullptr;
1842 on_twt_event_setup_response_callback = nullptr;
1843 on_twt_event_teardown_completion_callback = nullptr;
1844 on_twt_event_info_frame_received_callback = nullptr;
1845 on_twt_event_device_notify_callback = nullptr;
1846 on_chre_nan_rtt_internal_callback = nullptr;
1847}
1848
1849} // namespace legacy_hal
1850} // namespace wifi
1851} // namespace hardware
1852} // namespace android
1853} // namespace aidl