blob: 55d6f593143417ef2be70f1b4b692c8541486962 [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;
Sunil Ravif8fc2372022-11-10 18:37:41 +0000184std::function<void(wifi_request_id, unsigned num_results, wifi_rtt_result_v2* rtt_results_v2[])>
185 on_rtt_results_internal_callback_v2;
maheshkkv7d422812023-11-16 17:32:50 -0800186std::function<void(wifi_request_id, unsigned num_results, wifi_rtt_result_v3* rtt_results_v3[])>
187 on_rtt_results_internal_callback_v3;
Sunil Ravif8fc2372022-11-10 18:37:41 +0000188
189void invalidateRttResultsCallbacks() {
190 on_rtt_results_internal_callback = nullptr;
191 on_rtt_results_internal_callback_v2 = nullptr;
maheshkkv7d422812023-11-16 17:32:50 -0800192 on_rtt_results_internal_callback_v3 = nullptr;
Sunil Ravif8fc2372022-11-10 18:37:41 +0000193};
194
Gabriel Birenf3262f92022-07-15 23:25:39 +0000195void onAsyncRttResults(wifi_request_id id, unsigned num_results, wifi_rtt_result* rtt_results[]) {
196 const auto lock = aidl_sync_util::acquireGlobalLock();
197 if (on_rtt_results_internal_callback) {
198 on_rtt_results_internal_callback(id, num_results, rtt_results);
Sunil Ravif8fc2372022-11-10 18:37:41 +0000199 invalidateRttResultsCallbacks();
200 }
201}
202
203void onAsyncRttResultsV2(wifi_request_id id, unsigned num_results,
204 wifi_rtt_result_v2* rtt_results_v2[]) {
205 const auto lock = aidl_sync_util::acquireGlobalLock();
206 if (on_rtt_results_internal_callback_v2) {
207 on_rtt_results_internal_callback_v2(id, num_results, rtt_results_v2);
208 invalidateRttResultsCallbacks();
Gabriel Birenf3262f92022-07-15 23:25:39 +0000209 }
210}
211
maheshkkv7d422812023-11-16 17:32:50 -0800212void onAsyncRttResultsV3(wifi_request_id id, unsigned num_results,
213 wifi_rtt_result_v3* rtt_results_v3[]) {
214 const auto lock = aidl_sync_util::acquireGlobalLock();
215 if (on_rtt_results_internal_callback_v3) {
216 on_rtt_results_internal_callback_v3(id, num_results, rtt_results_v3);
217 invalidateRttResultsCallbacks();
218 }
219}
220
Gabriel Birenf3262f92022-07-15 23:25:39 +0000221// Callbacks for the various NAN operations.
222// NOTE: These have very little conversions to perform before invoking the user
223// callbacks.
224// So, handle all of them here directly to avoid adding an unnecessary layer.
225std::function<void(transaction_id, const NanResponseMsg&)> on_nan_notify_response_user_callback;
226void onAsyncNanNotifyResponse(transaction_id id, NanResponseMsg* msg) {
227 const auto lock = aidl_sync_util::acquireGlobalLock();
228 if (on_nan_notify_response_user_callback && msg) {
229 on_nan_notify_response_user_callback(id, *msg);
230 }
231}
232
233std::function<void(const NanPublishRepliedInd&)> on_nan_event_publish_replied_user_callback;
234void onAsyncNanEventPublishReplied(NanPublishRepliedInd* /* event */) {
235 LOG(ERROR) << "onAsyncNanEventPublishReplied triggered";
236}
237
238std::function<void(const NanPublishTerminatedInd&)> on_nan_event_publish_terminated_user_callback;
239void onAsyncNanEventPublishTerminated(NanPublishTerminatedInd* event) {
240 const auto lock = aidl_sync_util::acquireGlobalLock();
241 if (on_nan_event_publish_terminated_user_callback && event) {
242 on_nan_event_publish_terminated_user_callback(*event);
243 }
244}
245
246std::function<void(const NanMatchInd&)> on_nan_event_match_user_callback;
247void onAsyncNanEventMatch(NanMatchInd* event) {
248 const auto lock = aidl_sync_util::acquireGlobalLock();
249 if (on_nan_event_match_user_callback && event) {
250 on_nan_event_match_user_callback(*event);
251 }
252}
253
254std::function<void(const NanMatchExpiredInd&)> on_nan_event_match_expired_user_callback;
255void onAsyncNanEventMatchExpired(NanMatchExpiredInd* event) {
256 const auto lock = aidl_sync_util::acquireGlobalLock();
257 if (on_nan_event_match_expired_user_callback && event) {
258 on_nan_event_match_expired_user_callback(*event);
259 }
260}
261
262std::function<void(const NanSubscribeTerminatedInd&)>
263 on_nan_event_subscribe_terminated_user_callback;
264void onAsyncNanEventSubscribeTerminated(NanSubscribeTerminatedInd* event) {
265 const auto lock = aidl_sync_util::acquireGlobalLock();
266 if (on_nan_event_subscribe_terminated_user_callback && event) {
267 on_nan_event_subscribe_terminated_user_callback(*event);
268 }
269}
270
271std::function<void(const NanFollowupInd&)> on_nan_event_followup_user_callback;
272void onAsyncNanEventFollowup(NanFollowupInd* event) {
273 const auto lock = aidl_sync_util::acquireGlobalLock();
274 if (on_nan_event_followup_user_callback && event) {
275 on_nan_event_followup_user_callback(*event);
276 }
277}
278
279std::function<void(const NanDiscEngEventInd&)> on_nan_event_disc_eng_event_user_callback;
280void onAsyncNanEventDiscEngEvent(NanDiscEngEventInd* event) {
281 const auto lock = aidl_sync_util::acquireGlobalLock();
282 if (on_nan_event_disc_eng_event_user_callback && event) {
283 on_nan_event_disc_eng_event_user_callback(*event);
284 }
285}
286
287std::function<void(const NanDisabledInd&)> on_nan_event_disabled_user_callback;
288void onAsyncNanEventDisabled(NanDisabledInd* event) {
289 const auto lock = aidl_sync_util::acquireGlobalLock();
290 if (on_nan_event_disabled_user_callback && event) {
291 on_nan_event_disabled_user_callback(*event);
292 }
293}
294
295std::function<void(const NanTCAInd&)> on_nan_event_tca_user_callback;
296void onAsyncNanEventTca(NanTCAInd* event) {
297 const auto lock = aidl_sync_util::acquireGlobalLock();
298 if (on_nan_event_tca_user_callback && event) {
299 on_nan_event_tca_user_callback(*event);
300 }
301}
302
303std::function<void(const NanBeaconSdfPayloadInd&)> on_nan_event_beacon_sdf_payload_user_callback;
304void onAsyncNanEventBeaconSdfPayload(NanBeaconSdfPayloadInd* event) {
305 const auto lock = aidl_sync_util::acquireGlobalLock();
306 if (on_nan_event_beacon_sdf_payload_user_callback && event) {
307 on_nan_event_beacon_sdf_payload_user_callback(*event);
308 }
309}
310
311std::function<void(const NanDataPathRequestInd&)> on_nan_event_data_path_request_user_callback;
312void onAsyncNanEventDataPathRequest(NanDataPathRequestInd* event) {
313 const auto lock = aidl_sync_util::acquireGlobalLock();
314 if (on_nan_event_data_path_request_user_callback && event) {
315 on_nan_event_data_path_request_user_callback(*event);
316 }
317}
318std::function<void(const NanDataPathConfirmInd&)> on_nan_event_data_path_confirm_user_callback;
319void onAsyncNanEventDataPathConfirm(NanDataPathConfirmInd* event) {
320 const auto lock = aidl_sync_util::acquireGlobalLock();
321 if (on_nan_event_data_path_confirm_user_callback && event) {
322 on_nan_event_data_path_confirm_user_callback(*event);
323 }
324}
325
326std::function<void(const NanDataPathEndInd&)> on_nan_event_data_path_end_user_callback;
327void onAsyncNanEventDataPathEnd(NanDataPathEndInd* event) {
328 const auto lock = aidl_sync_util::acquireGlobalLock();
329 if (on_nan_event_data_path_end_user_callback && event) {
330 on_nan_event_data_path_end_user_callback(*event);
331 }
332}
333
334std::function<void(const NanTransmitFollowupInd&)> on_nan_event_transmit_follow_up_user_callback;
335void onAsyncNanEventTransmitFollowUp(NanTransmitFollowupInd* event) {
336 const auto lock = aidl_sync_util::acquireGlobalLock();
337 if (on_nan_event_transmit_follow_up_user_callback && event) {
338 on_nan_event_transmit_follow_up_user_callback(*event);
339 }
340}
341
342std::function<void(const NanRangeRequestInd&)> on_nan_event_range_request_user_callback;
343void onAsyncNanEventRangeRequest(NanRangeRequestInd* event) {
344 const auto lock = aidl_sync_util::acquireGlobalLock();
345 if (on_nan_event_range_request_user_callback && event) {
346 on_nan_event_range_request_user_callback(*event);
347 }
348}
349
350std::function<void(const NanRangeReportInd&)> on_nan_event_range_report_user_callback;
351void onAsyncNanEventRangeReport(NanRangeReportInd* event) {
352 const auto lock = aidl_sync_util::acquireGlobalLock();
353 if (on_nan_event_range_report_user_callback && event) {
354 on_nan_event_range_report_user_callback(*event);
355 }
356}
357
358std::function<void(const NanDataPathScheduleUpdateInd&)> on_nan_event_schedule_update_user_callback;
359void onAsyncNanEventScheduleUpdate(NanDataPathScheduleUpdateInd* event) {
360 const auto lock = aidl_sync_util::acquireGlobalLock();
361 if (on_nan_event_schedule_update_user_callback && event) {
362 on_nan_event_schedule_update_user_callback(*event);
363 }
364}
365
Nate Jiangd6cc3312023-02-14 16:37:54 -0800366std::function<void(const NanSuspensionModeChangeInd&)>
367 on_nan_event_suspension_mode_change_user_callback;
368void onAsyncNanEventSuspensionModeChange(NanSuspensionModeChangeInd* event) {
369 const auto lock = aidl_sync_util::acquireGlobalLock();
370 if (on_nan_event_suspension_mode_change_user_callback && event) {
371 on_nan_event_suspension_mode_change_user_callback(*event);
372 }
373}
374
Nate Jiang38e8db52022-12-02 17:30:27 -0800375std::function<void(const NanPairingRequestInd&)> on_nan_event_pairing_request_user_callback;
376void onAsyncNanEventPairingRequest(NanPairingRequestInd* event) {
377 const auto lock = aidl_sync_util::acquireGlobalLock();
378 if (on_nan_event_pairing_request_user_callback && event) {
379 on_nan_event_pairing_request_user_callback(*event);
380 }
381}
382
383std::function<void(const NanPairingConfirmInd&)> on_nan_event_pairing_confirm_user_callback;
384void onAsyncNanEventPairingConfirm(NanPairingConfirmInd* event) {
385 const auto lock = aidl_sync_util::acquireGlobalLock();
386 if (on_nan_event_pairing_confirm_user_callback && event) {
387 on_nan_event_pairing_confirm_user_callback(*event);
388 }
389}
390
391std::function<void(const NanBootstrappingRequestInd&)>
392 on_nan_event_bootstrapping_request_user_callback;
393void onAsyncNanEventBootstrappingRequest(NanBootstrappingRequestInd* event) {
394 const auto lock = aidl_sync_util::acquireGlobalLock();
395 if (on_nan_event_bootstrapping_request_user_callback && event) {
396 on_nan_event_bootstrapping_request_user_callback(*event);
397 }
398}
399
400std::function<void(const NanBootstrappingConfirmInd&)>
401 on_nan_event_bootstrapping_confirm_user_callback;
402void onAsyncNanEventBootstrappingConfirm(NanBootstrappingConfirmInd* event) {
403 const auto lock = aidl_sync_util::acquireGlobalLock();
404 if (on_nan_event_bootstrapping_confirm_user_callback && event) {
405 on_nan_event_bootstrapping_confirm_user_callback(*event);
406 }
407}
408
Gabriel Birenf3262f92022-07-15 23:25:39 +0000409// Callbacks for the various TWT operations.
410std::function<void(const TwtSetupResponse&)> on_twt_event_setup_response_callback;
411void onAsyncTwtEventSetupResponse(TwtSetupResponse* event) {
412 const auto lock = aidl_sync_util::acquireGlobalLock();
413 if (on_twt_event_setup_response_callback && event) {
414 on_twt_event_setup_response_callback(*event);
415 }
416}
417
418std::function<void(const TwtTeardownCompletion&)> on_twt_event_teardown_completion_callback;
419void onAsyncTwtEventTeardownCompletion(TwtTeardownCompletion* event) {
420 const auto lock = aidl_sync_util::acquireGlobalLock();
421 if (on_twt_event_teardown_completion_callback && event) {
422 on_twt_event_teardown_completion_callback(*event);
423 }
424}
425
426std::function<void(const TwtInfoFrameReceived&)> on_twt_event_info_frame_received_callback;
427void onAsyncTwtEventInfoFrameReceived(TwtInfoFrameReceived* event) {
428 const auto lock = aidl_sync_util::acquireGlobalLock();
429 if (on_twt_event_info_frame_received_callback && event) {
430 on_twt_event_info_frame_received_callback(*event);
431 }
432}
433
434std::function<void(const TwtDeviceNotify&)> on_twt_event_device_notify_callback;
435void onAsyncTwtEventDeviceNotify(TwtDeviceNotify* event) {
436 const auto lock = aidl_sync_util::acquireGlobalLock();
437 if (on_twt_event_device_notify_callback && event) {
438 on_twt_event_device_notify_callback(*event);
439 }
440}
441
442// Callback to report current CHRE NAN state
443std::function<void(chre_nan_rtt_state)> on_chre_nan_rtt_internal_callback;
444void onAsyncChreNanRttState(chre_nan_rtt_state state) {
445 const auto lock = aidl_sync_util::acquireGlobalLock();
446 if (on_chre_nan_rtt_internal_callback) {
447 on_chre_nan_rtt_internal_callback(state);
448 }
449}
450
451// Callback to report cached scan results
452std::function<void(wifi_cached_scan_report*)> on_cached_scan_results_internal_callback;
453void onSyncCachedScanResults(wifi_cached_scan_report* cache_report) {
Kai Shi7d0e5e92023-11-20 19:23:36 -0800454 const auto lock = aidl_sync_util::acquireGlobalLock();
Gabriel Birenf3262f92022-07-15 23:25:39 +0000455 if (on_cached_scan_results_internal_callback) {
456 on_cached_scan_results_internal_callback(cache_report);
457 }
458}
459
maheshkkv39903822023-11-28 15:31:53 -0800460// Callback to be invoked for TWT failure
461std::function<void((wifi_request_id, wifi_twt_error_code error_code))>
462 on_twt_failure_internal_callback;
463void onAsyncTwtError(wifi_request_id id, wifi_twt_error_code error_code) {
464 const auto lock = aidl_sync_util::acquireGlobalLock();
465 if (on_twt_failure_internal_callback) {
466 on_twt_failure_internal_callback(id, error_code);
467 }
468}
469
470// Callback to be invoked for TWT session creation
471std::function<void((wifi_request_id, wifi_twt_session twt_session))>
472 on_twt_session_create_internal_callback;
473void onAsyncTwtSessionCreate(wifi_request_id id, wifi_twt_session twt_session) {
474 const auto lock = aidl_sync_util::acquireGlobalLock();
475 if (on_twt_session_create_internal_callback) {
476 on_twt_session_create_internal_callback(id, twt_session);
477 }
478}
479
480// Callback to be invoked for TWT session update
481std::function<void((wifi_request_id, wifi_twt_session twt_session))>
482 on_twt_session_update_internal_callback;
483void onAsyncTwtSessionUpdate(wifi_request_id id, wifi_twt_session twt_session) {
484 const auto lock = aidl_sync_util::acquireGlobalLock();
485 if (on_twt_session_update_internal_callback) {
486 on_twt_session_update_internal_callback(id, twt_session);
487 }
488}
489
490// Callback to be invoked for TWT session teardown
491std::function<void(
492 (wifi_request_id, int twt_session_id, wifi_twt_teardown_reason_code reason_code))>
493 on_twt_session_teardown_internal_callback;
494void onAsyncTwtSessionTeardown(wifi_request_id id, int twt_session_id,
495 wifi_twt_teardown_reason_code reason_code) {
496 const auto lock = aidl_sync_util::acquireGlobalLock();
497 if (on_twt_session_teardown_internal_callback) {
498 on_twt_session_teardown_internal_callback(id, twt_session_id, reason_code);
499 }
500}
501
502// Callback to be invoked for TWT session get stats
503std::function<void((wifi_request_id, int twt_session_id, wifi_twt_session_stats stats))>
504 on_twt_session_stats_internal_callback;
505void onAsyncTwtSessionStats(wifi_request_id id, int twt_session_id, wifi_twt_session_stats stats) {
506 const auto lock = aidl_sync_util::acquireGlobalLock();
507 if (on_twt_session_stats_internal_callback) {
508 on_twt_session_stats_internal_callback(id, twt_session_id, stats);
509 }
510}
511
512// Callback to be invoked for TWT session suspend
513std::function<void((wifi_request_id, int twt_session_id))> on_twt_session_suspend_internal_callback;
514void onAsyncTwtSessionSuspend(wifi_request_id id, int twt_session_id) {
515 const auto lock = aidl_sync_util::acquireGlobalLock();
516 if (on_twt_session_suspend_internal_callback) {
517 on_twt_session_suspend_internal_callback(id, twt_session_id);
518 }
519}
520
521// Callback to be invoked for TWT session resume
522std::function<void((wifi_request_id, int twt_session_id))> on_twt_session_resume_internal_callback;
523void onAsyncTwtSessionResume(wifi_request_id id, int twt_session_id) {
524 const auto lock = aidl_sync_util::acquireGlobalLock();
525 if (on_twt_session_resume_internal_callback) {
526 on_twt_session_resume_internal_callback(id, twt_session_id);
527 }
528}
529
Gabriel Birenf3262f92022-07-15 23:25:39 +0000530// End of the free-standing "C" style callbacks.
531
532WifiLegacyHal::WifiLegacyHal(const std::weak_ptr<::android::wifi_system::InterfaceTool> iface_tool,
533 const wifi_hal_fn& fn, bool is_primary)
534 : global_func_table_(fn),
535 global_handle_(nullptr),
536 awaiting_event_loop_termination_(false),
537 is_started_(false),
538 iface_tool_(iface_tool),
539 is_primary_(is_primary) {}
540
541wifi_error WifiLegacyHal::initialize() {
542 LOG(DEBUG) << "Initialize legacy HAL";
543 // this now does nothing, since HAL function table is provided
544 // to the constructor
545 return WIFI_SUCCESS;
546}
547
548wifi_error WifiLegacyHal::start() {
549 // Ensure that we're starting in a good state.
550 CHECK(global_func_table_.wifi_initialize && !global_handle_ && iface_name_to_handle_.empty() &&
551 !awaiting_event_loop_termination_);
552 if (is_started_) {
553 LOG(DEBUG) << "Legacy HAL already started";
554 return WIFI_SUCCESS;
555 }
556 LOG(DEBUG) << "Waiting for the driver ready";
557 wifi_error status = global_func_table_.wifi_wait_for_driver_ready();
558 if (status == WIFI_ERROR_TIMED_OUT || status == WIFI_ERROR_UNKNOWN) {
559 LOG(ERROR) << "Failed or timed out awaiting driver ready";
560 return status;
561 }
562
563 if (is_primary_) {
564 property_set(kDriverPropName, "ok");
565
566 if (!iface_tool_.lock()->SetWifiUpState(true)) {
567 LOG(ERROR) << "Failed to set WiFi interface up";
568 return WIFI_ERROR_UNKNOWN;
569 }
570 }
571
572 LOG(DEBUG) << "Starting legacy HAL";
573 status = global_func_table_.wifi_initialize(&global_handle_);
574 if (status != WIFI_SUCCESS || !global_handle_) {
575 LOG(ERROR) << "Failed to retrieve global handle";
576 return status;
577 }
578 std::thread(&WifiLegacyHal::runEventLoop, this).detach();
579 status = retrieveIfaceHandles();
580 if (status != WIFI_SUCCESS || iface_name_to_handle_.empty()) {
581 LOG(ERROR) << "Failed to retrieve wlan interface handle";
582 return status;
583 }
584 LOG(DEBUG) << "Legacy HAL start complete";
585 is_started_ = true;
586 return WIFI_SUCCESS;
587}
588
589wifi_error WifiLegacyHal::stop(
590 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock,
591 const std::function<void()>& on_stop_complete_user_callback) {
592 if (!is_started_) {
593 LOG(DEBUG) << "Legacy HAL already stopped";
594 on_stop_complete_user_callback();
595 return WIFI_SUCCESS;
596 }
597 LOG(DEBUG) << "Stopping legacy HAL";
598 on_stop_complete_internal_callback = [on_stop_complete_user_callback,
599 this](wifi_handle handle) {
600 CHECK_EQ(global_handle_, handle) << "Handle mismatch";
601 LOG(INFO) << "Legacy HAL stop complete callback received";
602 // Invalidate all the internal pointers now that the HAL is
603 // stopped.
604 invalidate();
605 if (is_primary_) iface_tool_.lock()->SetWifiUpState(false);
606 on_stop_complete_user_callback();
607 is_started_ = false;
608 };
609 awaiting_event_loop_termination_ = true;
610 global_func_table_.wifi_cleanup(global_handle_, onAsyncStopComplete);
611 const auto status =
612 stop_wait_cv_.wait_for(*lock, std::chrono::milliseconds(kMaxStopCompleteWaitMs),
613 [this] { return !awaiting_event_loop_termination_; });
614 if (!status) {
615 LOG(ERROR) << "Legacy HAL stop failed or timed out";
616 return WIFI_ERROR_UNKNOWN;
617 }
618 LOG(DEBUG) << "Legacy HAL stop complete";
619 return WIFI_SUCCESS;
620}
621
622bool WifiLegacyHal::isStarted() {
623 return is_started_;
624}
625
626wifi_error WifiLegacyHal::waitForDriverReady() {
627 return global_func_table_.wifi_wait_for_driver_ready();
628}
629
630std::pair<wifi_error, std::string> WifiLegacyHal::getDriverVersion(const std::string& iface_name) {
631 std::array<char, kMaxVersionStringLength> buffer;
632 buffer.fill(0);
633 wifi_error status = global_func_table_.wifi_get_driver_version(getIfaceHandle(iface_name),
634 buffer.data(), buffer.size());
635 return {status, buffer.data()};
636}
637
638std::pair<wifi_error, std::string> WifiLegacyHal::getFirmwareVersion(
639 const std::string& iface_name) {
640 std::array<char, kMaxVersionStringLength> buffer;
641 buffer.fill(0);
642 wifi_error status = global_func_table_.wifi_get_firmware_version(getIfaceHandle(iface_name),
643 buffer.data(), buffer.size());
644 return {status, buffer.data()};
645}
646
647std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::requestDriverMemoryDump(
648 const std::string& iface_name) {
649 std::vector<uint8_t> driver_dump;
650 on_driver_memory_dump_internal_callback = [&driver_dump](char* buffer, int buffer_size) {
651 driver_dump.insert(driver_dump.end(), reinterpret_cast<uint8_t*>(buffer),
652 reinterpret_cast<uint8_t*>(buffer) + buffer_size);
653 };
654 wifi_error status = global_func_table_.wifi_get_driver_memory_dump(getIfaceHandle(iface_name),
655 {onSyncDriverMemoryDump});
656 on_driver_memory_dump_internal_callback = nullptr;
657 return {status, std::move(driver_dump)};
658}
659
660std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::requestFirmwareMemoryDump(
661 const std::string& iface_name) {
662 std::vector<uint8_t> firmware_dump;
663 on_firmware_memory_dump_internal_callback = [&firmware_dump](char* buffer, int buffer_size) {
664 firmware_dump.insert(firmware_dump.end(), reinterpret_cast<uint8_t*>(buffer),
665 reinterpret_cast<uint8_t*>(buffer) + buffer_size);
666 };
667 wifi_error status = global_func_table_.wifi_get_firmware_memory_dump(
668 getIfaceHandle(iface_name), {onSyncFirmwareMemoryDump});
669 on_firmware_memory_dump_internal_callback = nullptr;
670 return {status, std::move(firmware_dump)};
671}
672
673std::pair<wifi_error, uint64_t> WifiLegacyHal::getSupportedFeatureSet(
674 const std::string& iface_name) {
675 feature_set set = 0, chip_set = 0;
676 wifi_error status = WIFI_SUCCESS;
677
678 static_assert(sizeof(set) == sizeof(uint64_t),
679 "Some feature_flags can not be represented in output");
680 wifi_interface_handle iface_handle = getIfaceHandle(iface_name);
681
682 global_func_table_.wifi_get_chip_feature_set(
683 global_handle_, &chip_set); /* ignore error, chip_set will stay 0 */
684
685 if (iface_handle) {
686 status = global_func_table_.wifi_get_supported_feature_set(iface_handle, &set);
687 }
688 return {status, static_cast<uint64_t>(set | chip_set)};
689}
690
691std::pair<wifi_error, PacketFilterCapabilities> WifiLegacyHal::getPacketFilterCapabilities(
692 const std::string& iface_name) {
693 PacketFilterCapabilities caps;
694 wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities(
695 getIfaceHandle(iface_name), &caps.version, &caps.max_len);
696 return {status, caps};
697}
698
699wifi_error WifiLegacyHal::setPacketFilter(const std::string& iface_name,
700 const std::vector<uint8_t>& program) {
701 return global_func_table_.wifi_set_packet_filter(getIfaceHandle(iface_name), program.data(),
702 program.size());
703}
704
705std::pair<wifi_error, std::vector<uint8_t>> WifiLegacyHal::readApfPacketFilterData(
706 const std::string& iface_name) {
707 PacketFilterCapabilities caps;
708 wifi_error status = global_func_table_.wifi_get_packet_filter_capabilities(
709 getIfaceHandle(iface_name), &caps.version, &caps.max_len);
710 if (status != WIFI_SUCCESS) {
711 return {status, {}};
712 }
713
714 // Size the buffer to read the entire program & work memory.
715 std::vector<uint8_t> buffer(caps.max_len);
716
717 status = global_func_table_.wifi_read_packet_filter(
718 getIfaceHandle(iface_name), /*src_offset=*/0, buffer.data(), buffer.size());
719 return {status, std::move(buffer)};
720}
721
722std::pair<wifi_error, wifi_gscan_capabilities> WifiLegacyHal::getGscanCapabilities(
723 const std::string& iface_name) {
724 wifi_gscan_capabilities caps;
725 wifi_error status =
726 global_func_table_.wifi_get_gscan_capabilities(getIfaceHandle(iface_name), &caps);
727 return {status, caps};
728}
729
730wifi_error WifiLegacyHal::startGscan(
731 const std::string& iface_name, wifi_request_id id, const wifi_scan_cmd_params& params,
732 const std::function<void(wifi_request_id)>& on_failure_user_callback,
733 const on_gscan_results_callback& on_results_user_callback,
734 const on_gscan_full_result_callback& on_full_result_user_callback) {
735 // If there is already an ongoing background scan, reject new scan requests.
736 if (on_gscan_event_internal_callback || on_gscan_full_result_internal_callback) {
737 return WIFI_ERROR_NOT_AVAILABLE;
738 }
739
740 // This callback will be used to either trigger |on_results_user_callback|
741 // or |on_failure_user_callback|.
742 on_gscan_event_internal_callback = [iface_name, on_failure_user_callback,
743 on_results_user_callback,
744 this](wifi_request_id id, wifi_scan_event event) {
745 switch (event) {
746 case WIFI_SCAN_RESULTS_AVAILABLE:
747 case WIFI_SCAN_THRESHOLD_NUM_SCANS:
748 case WIFI_SCAN_THRESHOLD_PERCENT: {
749 wifi_error status;
750 std::vector<wifi_cached_scan_results> cached_scan_results;
751 std::tie(status, cached_scan_results) = getGscanCachedResults(iface_name);
752 if (status == WIFI_SUCCESS) {
753 on_results_user_callback(id, cached_scan_results);
754 return;
755 }
756 FALLTHROUGH_INTENDED;
757 }
758 // Fall through if failed. Failure to retrieve cached scan
759 // results should trigger a background scan failure.
760 case WIFI_SCAN_FAILED:
761 on_failure_user_callback(id);
762 on_gscan_event_internal_callback = nullptr;
763 on_gscan_full_result_internal_callback = nullptr;
764 return;
765 }
766 LOG(FATAL) << "Unexpected gscan event received: " << event;
767 };
768
769 on_gscan_full_result_internal_callback = [on_full_result_user_callback](
770 wifi_request_id id, wifi_scan_result* result,
771 uint32_t buckets_scanned) {
772 if (result) {
773 on_full_result_user_callback(id, result, buckets_scanned);
774 }
775 };
776
777 wifi_scan_result_handler handler = {onAsyncGscanFullResult, onAsyncGscanEvent};
778 wifi_error status =
779 global_func_table_.wifi_start_gscan(id, getIfaceHandle(iface_name), params, handler);
780 if (status != WIFI_SUCCESS) {
781 on_gscan_event_internal_callback = nullptr;
782 on_gscan_full_result_internal_callback = nullptr;
783 }
784 return status;
785}
786
787wifi_error WifiLegacyHal::stopGscan(const std::string& iface_name, wifi_request_id id) {
788 // If there is no an ongoing background scan, reject stop requests.
789 // TODO(b/32337212): This needs to be handled by the HIDL object because we
790 // need to return the NOT_STARTED error code.
791 if (!on_gscan_event_internal_callback && !on_gscan_full_result_internal_callback) {
792 return WIFI_ERROR_NOT_AVAILABLE;
793 }
794 wifi_error status = global_func_table_.wifi_stop_gscan(id, getIfaceHandle(iface_name));
795 // If the request Id is wrong, don't stop the ongoing background scan. Any
796 // other error should be treated as the end of background scan.
797 if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
798 on_gscan_event_internal_callback = nullptr;
799 on_gscan_full_result_internal_callback = nullptr;
800 }
801 return status;
802}
803
804std::pair<wifi_error, std::vector<uint32_t>> WifiLegacyHal::getValidFrequenciesForBand(
805 const std::string& iface_name, wifi_band band) {
806 static_assert(sizeof(uint32_t) >= sizeof(wifi_channel),
807 "Wifi Channel cannot be represented in output");
808 std::vector<uint32_t> freqs;
809 freqs.resize(kMaxGscanFrequenciesForBand);
810 int32_t num_freqs = 0;
811 wifi_error status = global_func_table_.wifi_get_valid_channels(
812 getIfaceHandle(iface_name), band, freqs.size(),
813 reinterpret_cast<wifi_channel*>(freqs.data()), &num_freqs);
814 CHECK(num_freqs >= 0 && static_cast<uint32_t>(num_freqs) <= kMaxGscanFrequenciesForBand);
815 freqs.resize(num_freqs);
816 return {status, std::move(freqs)};
817}
818
819wifi_error WifiLegacyHal::setDfsFlag(const std::string& iface_name, bool dfs_on) {
820 return global_func_table_.wifi_set_nodfs_flag(getIfaceHandle(iface_name), dfs_on ? 0 : 1);
821}
822
823wifi_error WifiLegacyHal::enableLinkLayerStats(const std::string& iface_name, bool debug) {
824 wifi_link_layer_params params;
825 params.mpdu_size_threshold = kLinkLayerStatsDataMpduSizeThreshold;
826 params.aggressive_statistics_gathering = debug;
827 return global_func_table_.wifi_set_link_stats(getIfaceHandle(iface_name), params);
828}
829
830wifi_error WifiLegacyHal::disableLinkLayerStats(const std::string& iface_name) {
831 // TODO: Do we care about these responses?
832 uint32_t clear_mask_rsp;
833 uint8_t stop_rsp;
834 return global_func_table_.wifi_clear_link_stats(getIfaceHandle(iface_name), 0xFFFFFFFF,
835 &clear_mask_rsp, 1, &stop_rsp);
836}
837
Mahesh KKV5f30d332022-10-26 14:07:44 -0700838// Copies wifi_peer_info* to vector<WifiPeerInfo> and returns poiner to next element.
839wifi_peer_info* WifiLegacyHal::copyPeerInfo(wifi_peer_info* peer_ptr,
Ye Jiaodec38702023-02-10 11:37:58 +0800840 std::vector<WifiPeerInfo>& peers) {
Mahesh KKV5f30d332022-10-26 14:07:44 -0700841 WifiPeerInfo peer;
842 peer.peer_info = *peer_ptr;
843 if (peer_ptr->num_rate > 0) {
844 // Copy the rate stats.
845 peer.rate_stats.assign(peer_ptr->rate_stats, peer_ptr->rate_stats + peer_ptr->num_rate);
846 }
847 peer.peer_info.num_rate = 0;
848 // Push peer info.
849 peers.push_back(peer);
850 // Return the address of next peer info.
851 return (wifi_peer_info*)((u8*)peer_ptr + sizeof(wifi_peer_info) +
852 (sizeof(wifi_rate_stat) * peer_ptr->num_rate));
853}
854// Copies wifi_link_stat* to vector<LinkStats> and returns poiner to next element.
855wifi_link_stat* WifiLegacyHal::copyLinkStat(wifi_link_stat* stat_ptr,
Ye Jiaodec38702023-02-10 11:37:58 +0800856 std::vector<LinkStats>& stats) {
Mahesh KKV5f30d332022-10-26 14:07:44 -0700857 LinkStats linkStat;
858 linkStat.stat = *stat_ptr;
859 wifi_peer_info* l_peer_info_stats_ptr = stat_ptr->peer_info;
860 for (uint32_t i = 0; i < linkStat.stat.num_peers; i++) {
861 l_peer_info_stats_ptr = copyPeerInfo(l_peer_info_stats_ptr, linkStat.peers);
862 }
863 // Copied all peers to linkStat.peers.
864 linkStat.stat.num_peers = 0;
865 // Push link stat.
866 stats.push_back(linkStat);
867 // Read all peers, return the address of next wifi_link_stat.
868 return (wifi_link_stat*)l_peer_info_stats_ptr;
869}
870
871wifi_error WifiLegacyHal::getLinkLayerStats(const std::string& iface_name,
872 LinkLayerStats& link_stats,
873 LinkLayerMlStats& link_ml_stats) {
Gabriel Birenf3262f92022-07-15 23:25:39 +0000874 LinkLayerStats* link_stats_ptr = &link_stats;
Mahesh KKV5f30d332022-10-26 14:07:44 -0700875 link_stats_ptr->valid = false;
Gabriel Birenf3262f92022-07-15 23:25:39 +0000876
877 on_link_layer_stats_result_internal_callback = [&link_stats_ptr](
878 wifi_request_id /* id */,
879 wifi_iface_stat* iface_stats_ptr,
880 int num_radios,
881 wifi_radio_stat* radio_stats_ptr) {
882 wifi_radio_stat* l_radio_stats_ptr;
883 wifi_peer_info* l_peer_info_stats_ptr;
Mahesh KKV5f30d332022-10-26 14:07:44 -0700884 link_stats_ptr->valid = true;
Gabriel Birenf3262f92022-07-15 23:25:39 +0000885
886 if (iface_stats_ptr != nullptr) {
887 link_stats_ptr->iface = *iface_stats_ptr;
888 l_peer_info_stats_ptr = iface_stats_ptr->peer_info;
889 for (uint32_t i = 0; i < iface_stats_ptr->num_peers; i++) {
890 WifiPeerInfo peer;
891 peer.peer_info = *l_peer_info_stats_ptr;
892 if (l_peer_info_stats_ptr->num_rate > 0) {
893 /* Copy the rate stats */
894 peer.rate_stats.assign(
895 l_peer_info_stats_ptr->rate_stats,
896 l_peer_info_stats_ptr->rate_stats + l_peer_info_stats_ptr->num_rate);
897 }
898 peer.peer_info.num_rate = 0;
899 link_stats_ptr->peers.push_back(peer);
900 l_peer_info_stats_ptr =
901 (wifi_peer_info*)((u8*)l_peer_info_stats_ptr + sizeof(wifi_peer_info) +
902 (sizeof(wifi_rate_stat) *
903 l_peer_info_stats_ptr->num_rate));
904 }
905 link_stats_ptr->iface.num_peers = 0;
906 } else {
907 LOG(ERROR) << "Invalid iface stats in link layer stats";
908 }
909 if (num_radios <= 0 || radio_stats_ptr == nullptr) {
910 LOG(ERROR) << "Invalid radio stats in link layer stats";
911 return;
912 }
913 l_radio_stats_ptr = radio_stats_ptr;
914 for (int i = 0; i < num_radios; i++) {
915 LinkLayerRadioStats radio;
916
917 radio.stats = *l_radio_stats_ptr;
918 // Copy over the tx level array to the separate vector.
919 if (l_radio_stats_ptr->num_tx_levels > 0 &&
920 l_radio_stats_ptr->tx_time_per_levels != nullptr) {
921 radio.tx_time_per_levels.assign(
922 l_radio_stats_ptr->tx_time_per_levels,
923 l_radio_stats_ptr->tx_time_per_levels + l_radio_stats_ptr->num_tx_levels);
924 }
925 radio.stats.num_tx_levels = 0;
926 radio.stats.tx_time_per_levels = nullptr;
927 /* Copy over the channel stat to separate vector */
928 if (l_radio_stats_ptr->num_channels > 0) {
929 /* Copy the channel stats */
930 radio.channel_stats.assign(
931 l_radio_stats_ptr->channels,
932 l_radio_stats_ptr->channels + l_radio_stats_ptr->num_channels);
933 }
934 link_stats_ptr->radios.push_back(radio);
935 l_radio_stats_ptr =
936 (wifi_radio_stat*)((u8*)l_radio_stats_ptr + sizeof(wifi_radio_stat) +
937 (sizeof(wifi_channel_stat) *
938 l_radio_stats_ptr->num_channels));
939 }
940 };
941
Mahesh KKV5f30d332022-10-26 14:07:44 -0700942 LinkLayerMlStats* link_ml_stats_ptr = &link_ml_stats;
943 link_ml_stats_ptr->valid = false;
944
945 on_link_layer_ml_stats_result_internal_callback =
946 [this, &link_ml_stats_ptr](wifi_request_id /* id */,
947 wifi_iface_ml_stat* iface_ml_stats_ptr, int num_radios,
948 wifi_radio_stat* radio_stats_ptr) {
949 wifi_radio_stat* l_radio_stats_ptr;
950 wifi_link_stat* l_link_stat_ptr;
951 link_ml_stats_ptr->valid = true;
952
953 if (iface_ml_stats_ptr != nullptr && iface_ml_stats_ptr->num_links > 0) {
954 // Copy stats from wifi_iface_ml_stat to LinkLayerMlStats,
955 // - num_links * links[] to vector of links.
956 // - num_peers * peer_info[] to vector of links[i].peers.
957 link_ml_stats_ptr->iface = *iface_ml_stats_ptr;
958 l_link_stat_ptr = iface_ml_stats_ptr->links;
959 for (int l = 0; l < iface_ml_stats_ptr->num_links; ++l) {
960 l_link_stat_ptr = copyLinkStat(l_link_stat_ptr, link_ml_stats_ptr->links);
961 }
962 } else {
963 LOG(ERROR) << "Invalid iface stats in link layer stats";
964 }
965 if (num_radios <= 0 || radio_stats_ptr == nullptr) {
966 LOG(ERROR) << "Invalid radio stats in link layer stats";
967 return;
968 }
969 l_radio_stats_ptr = radio_stats_ptr;
970 for (int i = 0; i < num_radios; i++) {
971 LinkLayerRadioStats radio;
972
973 radio.stats = *l_radio_stats_ptr;
974 // Copy over the tx level array to the separate vector.
975 if (l_radio_stats_ptr->num_tx_levels > 0 &&
976 l_radio_stats_ptr->tx_time_per_levels != nullptr) {
977 radio.tx_time_per_levels.assign(l_radio_stats_ptr->tx_time_per_levels,
978 l_radio_stats_ptr->tx_time_per_levels +
979 l_radio_stats_ptr->num_tx_levels);
980 }
981 radio.stats.num_tx_levels = 0;
982 radio.stats.tx_time_per_levels = nullptr;
983 /* Copy over the channel stat to separate vector */
984 if (l_radio_stats_ptr->num_channels > 0) {
985 /* Copy the channel stats */
986 radio.channel_stats.assign(
987 l_radio_stats_ptr->channels,
988 l_radio_stats_ptr->channels + l_radio_stats_ptr->num_channels);
989 }
990 link_ml_stats_ptr->radios.push_back(radio);
991 l_radio_stats_ptr =
992 (wifi_radio_stat*)((u8*)l_radio_stats_ptr + sizeof(wifi_radio_stat) +
993 (sizeof(wifi_channel_stat) *
994 l_radio_stats_ptr->num_channels));
995 }
996 };
997
998 wifi_error status = global_func_table_.wifi_get_link_stats(
999 0, getIfaceHandle(iface_name),
1000 {onSyncLinkLayerStatsResult, onSyncLinkLayerMlStatsResult});
Gabriel Birenf3262f92022-07-15 23:25:39 +00001001 on_link_layer_stats_result_internal_callback = nullptr;
Mahesh KKV5f30d332022-10-26 14:07:44 -07001002 on_link_layer_ml_stats_result_internal_callback = nullptr;
1003
1004 return status;
Gabriel Birenf3262f92022-07-15 23:25:39 +00001005}
1006
1007wifi_error WifiLegacyHal::startRssiMonitoring(
1008 const std::string& iface_name, wifi_request_id id, int8_t max_rssi, int8_t min_rssi,
1009 const on_rssi_threshold_breached_callback& on_threshold_breached_user_callback) {
1010 if (on_rssi_threshold_breached_internal_callback) {
1011 return WIFI_ERROR_NOT_AVAILABLE;
1012 }
1013 on_rssi_threshold_breached_internal_callback = [on_threshold_breached_user_callback](
1014 wifi_request_id id, uint8_t* bssid_ptr,
1015 int8_t rssi) {
1016 if (!bssid_ptr) {
1017 return;
1018 }
1019 std::array<uint8_t, ETH_ALEN> bssid_arr;
1020 // |bssid_ptr| pointer is assumed to have 6 bytes for the mac
1021 // address.
1022 std::copy(bssid_ptr, bssid_ptr + 6, std::begin(bssid_arr));
1023 on_threshold_breached_user_callback(id, bssid_arr, rssi);
1024 };
1025 wifi_error status = global_func_table_.wifi_start_rssi_monitoring(
1026 id, getIfaceHandle(iface_name), max_rssi, min_rssi, {onAsyncRssiThresholdBreached});
1027 if (status != WIFI_SUCCESS) {
1028 on_rssi_threshold_breached_internal_callback = nullptr;
1029 }
1030 return status;
1031}
1032
1033wifi_error WifiLegacyHal::stopRssiMonitoring(const std::string& iface_name, wifi_request_id id) {
1034 if (!on_rssi_threshold_breached_internal_callback) {
1035 return WIFI_ERROR_NOT_AVAILABLE;
1036 }
1037 wifi_error status =
1038 global_func_table_.wifi_stop_rssi_monitoring(id, getIfaceHandle(iface_name));
1039 // If the request Id is wrong, don't stop the ongoing rssi monitoring. Any
1040 // other error should be treated as the end of background scan.
1041 if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
1042 on_rssi_threshold_breached_internal_callback = nullptr;
1043 }
1044 return status;
1045}
1046
1047std::pair<wifi_error, wifi_roaming_capabilities> WifiLegacyHal::getRoamingCapabilities(
1048 const std::string& iface_name) {
1049 wifi_roaming_capabilities caps;
1050 wifi_error status =
1051 global_func_table_.wifi_get_roaming_capabilities(getIfaceHandle(iface_name), &caps);
1052 return {status, caps};
1053}
1054
1055wifi_error WifiLegacyHal::configureRoaming(const std::string& iface_name,
1056 const wifi_roaming_config& config) {
1057 wifi_roaming_config config_internal = config;
1058 return global_func_table_.wifi_configure_roaming(getIfaceHandle(iface_name), &config_internal);
1059}
1060
1061wifi_error WifiLegacyHal::enableFirmwareRoaming(const std::string& iface_name,
1062 fw_roaming_state_t state) {
1063 return global_func_table_.wifi_enable_firmware_roaming(getIfaceHandle(iface_name), state);
1064}
1065
1066wifi_error WifiLegacyHal::configureNdOffload(const std::string& iface_name, bool enable) {
1067 return global_func_table_.wifi_configure_nd_offload(getIfaceHandle(iface_name), enable);
1068}
1069
1070wifi_error WifiLegacyHal::startSendingOffloadedPacket(const std::string& iface_name, int32_t cmd_id,
1071 uint16_t ether_type,
1072 const std::vector<uint8_t>& ip_packet_data,
1073 const std::array<uint8_t, 6>& src_address,
1074 const std::array<uint8_t, 6>& dst_address,
1075 int32_t period_in_ms) {
1076 std::vector<uint8_t> ip_packet_data_internal(ip_packet_data);
1077 std::vector<uint8_t> src_address_internal(src_address.data(),
1078 src_address.data() + src_address.size());
1079 std::vector<uint8_t> dst_address_internal(dst_address.data(),
1080 dst_address.data() + dst_address.size());
1081 return global_func_table_.wifi_start_sending_offloaded_packet(
1082 cmd_id, getIfaceHandle(iface_name), ether_type, ip_packet_data_internal.data(),
1083 ip_packet_data_internal.size(), src_address_internal.data(),
1084 dst_address_internal.data(), period_in_ms);
1085}
1086
1087wifi_error WifiLegacyHal::stopSendingOffloadedPacket(const std::string& iface_name,
1088 uint32_t cmd_id) {
1089 return global_func_table_.wifi_stop_sending_offloaded_packet(cmd_id,
1090 getIfaceHandle(iface_name));
1091}
1092
1093wifi_error WifiLegacyHal::selectTxPowerScenario(const std::string& iface_name,
1094 wifi_power_scenario scenario) {
1095 return global_func_table_.wifi_select_tx_power_scenario(getIfaceHandle(iface_name), scenario);
1096}
1097
1098wifi_error WifiLegacyHal::resetTxPowerScenario(const std::string& iface_name) {
1099 return global_func_table_.wifi_reset_tx_power_scenario(getIfaceHandle(iface_name));
1100}
1101
1102wifi_error WifiLegacyHal::setLatencyMode(const std::string& iface_name, wifi_latency_mode mode) {
1103 return global_func_table_.wifi_set_latency_mode(getIfaceHandle(iface_name), mode);
1104}
1105
1106wifi_error WifiLegacyHal::setThermalMitigationMode(wifi_thermal_mode mode,
1107 uint32_t completion_window) {
1108 return global_func_table_.wifi_set_thermal_mitigation_mode(global_handle_, mode,
1109 completion_window);
1110}
1111
1112wifi_error WifiLegacyHal::setDscpToAccessCategoryMapping(uint32_t start, uint32_t end,
1113 uint32_t access_category) {
1114 return global_func_table_.wifi_map_dscp_access_category(global_handle_, start, end,
1115 access_category);
1116}
1117
1118wifi_error WifiLegacyHal::resetDscpToAccessCategoryMapping() {
1119 return global_func_table_.wifi_reset_dscp_mapping(global_handle_);
1120}
1121
1122std::pair<wifi_error, uint32_t> WifiLegacyHal::getLoggerSupportedFeatureSet(
1123 const std::string& iface_name) {
1124 uint32_t supported_feature_flags = 0;
1125 wifi_error status = WIFI_SUCCESS;
1126
1127 wifi_interface_handle iface_handle = getIfaceHandle(iface_name);
1128
1129 if (iface_handle) {
1130 status = global_func_table_.wifi_get_logger_supported_feature_set(iface_handle,
1131 &supported_feature_flags);
1132 }
1133 return {status, supported_feature_flags};
1134}
1135
1136wifi_error WifiLegacyHal::startPktFateMonitoring(const std::string& iface_name) {
1137 return global_func_table_.wifi_start_pkt_fate_monitoring(getIfaceHandle(iface_name));
1138}
1139
1140std::pair<wifi_error, std::vector<wifi_tx_report>> WifiLegacyHal::getTxPktFates(
1141 const std::string& iface_name) {
1142 std::vector<wifi_tx_report> tx_pkt_fates;
1143 tx_pkt_fates.resize(MAX_FATE_LOG_LEN);
1144 size_t num_fates = 0;
1145 wifi_error status = global_func_table_.wifi_get_tx_pkt_fates(
1146 getIfaceHandle(iface_name), tx_pkt_fates.data(), tx_pkt_fates.size(), &num_fates);
1147 CHECK(num_fates <= MAX_FATE_LOG_LEN);
1148 tx_pkt_fates.resize(num_fates);
1149 return {status, std::move(tx_pkt_fates)};
1150}
1151
1152std::pair<wifi_error, std::vector<wifi_rx_report>> WifiLegacyHal::getRxPktFates(
1153 const std::string& iface_name) {
1154 std::vector<wifi_rx_report> rx_pkt_fates;
1155 rx_pkt_fates.resize(MAX_FATE_LOG_LEN);
1156 size_t num_fates = 0;
1157 wifi_error status = global_func_table_.wifi_get_rx_pkt_fates(
1158 getIfaceHandle(iface_name), rx_pkt_fates.data(), rx_pkt_fates.size(), &num_fates);
1159 CHECK(num_fates <= MAX_FATE_LOG_LEN);
1160 rx_pkt_fates.resize(num_fates);
1161 return {status, std::move(rx_pkt_fates)};
1162}
1163
1164std::pair<wifi_error, WakeReasonStats> WifiLegacyHal::getWakeReasonStats(
1165 const std::string& iface_name) {
1166 WakeReasonStats stats;
1167 stats.cmd_event_wake_cnt.resize(kMaxWakeReasonStatsArraySize);
1168 stats.driver_fw_local_wake_cnt.resize(kMaxWakeReasonStatsArraySize);
1169
1170 // This legacy struct needs separate memory to store the variable sized wake
1171 // reason types.
1172 stats.wake_reason_cnt.cmd_event_wake_cnt =
1173 reinterpret_cast<int32_t*>(stats.cmd_event_wake_cnt.data());
1174 stats.wake_reason_cnt.cmd_event_wake_cnt_sz = stats.cmd_event_wake_cnt.size();
1175 stats.wake_reason_cnt.cmd_event_wake_cnt_used = 0;
1176 stats.wake_reason_cnt.driver_fw_local_wake_cnt =
1177 reinterpret_cast<int32_t*>(stats.driver_fw_local_wake_cnt.data());
1178 stats.wake_reason_cnt.driver_fw_local_wake_cnt_sz = stats.driver_fw_local_wake_cnt.size();
1179 stats.wake_reason_cnt.driver_fw_local_wake_cnt_used = 0;
1180
1181 wifi_error status = global_func_table_.wifi_get_wake_reason_stats(getIfaceHandle(iface_name),
1182 &stats.wake_reason_cnt);
1183
1184 CHECK(stats.wake_reason_cnt.cmd_event_wake_cnt_used >= 0 &&
1185 static_cast<uint32_t>(stats.wake_reason_cnt.cmd_event_wake_cnt_used) <=
1186 kMaxWakeReasonStatsArraySize);
1187 stats.cmd_event_wake_cnt.resize(stats.wake_reason_cnt.cmd_event_wake_cnt_used);
1188 stats.wake_reason_cnt.cmd_event_wake_cnt = nullptr;
1189
1190 CHECK(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used >= 0 &&
1191 static_cast<uint32_t>(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used) <=
1192 kMaxWakeReasonStatsArraySize);
1193 stats.driver_fw_local_wake_cnt.resize(stats.wake_reason_cnt.driver_fw_local_wake_cnt_used);
1194 stats.wake_reason_cnt.driver_fw_local_wake_cnt = nullptr;
1195
1196 return {status, stats};
1197}
1198
1199wifi_error WifiLegacyHal::registerRingBufferCallbackHandler(
1200 const std::string& iface_name, const on_ring_buffer_data_callback& on_user_data_callback) {
1201 if (on_ring_buffer_data_internal_callback) {
1202 return WIFI_ERROR_NOT_AVAILABLE;
1203 }
1204 on_ring_buffer_data_internal_callback = [on_user_data_callback](
1205 char* ring_name, char* buffer, int buffer_size,
1206 wifi_ring_buffer_status* status) {
1207 if (status && buffer) {
1208 std::vector<uint8_t> buffer_vector(reinterpret_cast<uint8_t*>(buffer),
1209 reinterpret_cast<uint8_t*>(buffer) + buffer_size);
1210 on_user_data_callback(ring_name, buffer_vector, *status);
1211 }
1212 };
1213 wifi_error status = global_func_table_.wifi_set_log_handler(0, getIfaceHandle(iface_name),
1214 {onAsyncRingBufferData});
1215 if (status != WIFI_SUCCESS) {
1216 on_ring_buffer_data_internal_callback = nullptr;
1217 }
1218 return status;
1219}
1220
1221wifi_error WifiLegacyHal::deregisterRingBufferCallbackHandler(const std::string& iface_name) {
1222 if (!on_ring_buffer_data_internal_callback) {
1223 return WIFI_ERROR_NOT_AVAILABLE;
1224 }
1225 on_ring_buffer_data_internal_callback = nullptr;
1226 return global_func_table_.wifi_reset_log_handler(0, getIfaceHandle(iface_name));
1227}
1228
1229std::pair<wifi_error, std::vector<wifi_ring_buffer_status>> WifiLegacyHal::getRingBuffersStatus(
1230 const std::string& iface_name) {
1231 std::vector<wifi_ring_buffer_status> ring_buffers_status;
1232 ring_buffers_status.resize(kMaxRingBuffers);
1233 uint32_t num_rings = kMaxRingBuffers;
1234 wifi_error status = global_func_table_.wifi_get_ring_buffers_status(
1235 getIfaceHandle(iface_name), &num_rings, ring_buffers_status.data());
1236 CHECK(num_rings <= kMaxRingBuffers);
1237 ring_buffers_status.resize(num_rings);
1238 return {status, std::move(ring_buffers_status)};
1239}
1240
1241wifi_error WifiLegacyHal::startRingBufferLogging(const std::string& iface_name,
1242 const std::string& ring_name,
1243 uint32_t verbose_level, uint32_t max_interval_sec,
1244 uint32_t min_data_size) {
1245 return global_func_table_.wifi_start_logging(getIfaceHandle(iface_name), verbose_level, 0,
1246 max_interval_sec, min_data_size,
1247 makeCharVec(ring_name).data());
1248}
1249
1250wifi_error WifiLegacyHal::getRingBufferData(const std::string& iface_name,
1251 const std::string& ring_name) {
1252 return global_func_table_.wifi_get_ring_data(getIfaceHandle(iface_name),
1253 makeCharVec(ring_name).data());
1254}
1255
1256wifi_error WifiLegacyHal::registerErrorAlertCallbackHandler(
1257 const std::string& iface_name, const on_error_alert_callback& on_user_alert_callback) {
1258 if (on_error_alert_internal_callback) {
1259 return WIFI_ERROR_NOT_AVAILABLE;
1260 }
1261 on_error_alert_internal_callback = [on_user_alert_callback](wifi_request_id id, char* buffer,
1262 int buffer_size, int err_code) {
1263 if (buffer) {
1264 CHECK(id == 0);
1265 on_user_alert_callback(
1266 err_code,
1267 std::vector<uint8_t>(reinterpret_cast<uint8_t*>(buffer),
1268 reinterpret_cast<uint8_t*>(buffer) + buffer_size));
1269 }
1270 };
1271 wifi_error status = global_func_table_.wifi_set_alert_handler(0, getIfaceHandle(iface_name),
1272 {onAsyncErrorAlert});
1273 if (status != WIFI_SUCCESS) {
1274 on_error_alert_internal_callback = nullptr;
1275 }
1276 return status;
1277}
1278
1279wifi_error WifiLegacyHal::deregisterErrorAlertCallbackHandler(const std::string& iface_name) {
1280 if (!on_error_alert_internal_callback) {
1281 return WIFI_ERROR_NOT_AVAILABLE;
1282 }
1283 on_error_alert_internal_callback = nullptr;
1284 return global_func_table_.wifi_reset_alert_handler(0, getIfaceHandle(iface_name));
1285}
1286
1287wifi_error WifiLegacyHal::registerRadioModeChangeCallbackHandler(
1288 const std::string& iface_name,
1289 const on_radio_mode_change_callback& on_user_change_callback) {
1290 if (on_radio_mode_change_internal_callback) {
1291 return WIFI_ERROR_NOT_AVAILABLE;
1292 }
1293 on_radio_mode_change_internal_callback = [on_user_change_callback](
1294 wifi_request_id /* id */, uint32_t num_macs,
1295 wifi_mac_info* mac_infos_arr) {
1296 if (num_macs > 0 && mac_infos_arr) {
1297 std::vector<WifiMacInfo> mac_infos_vec;
1298 for (uint32_t i = 0; i < num_macs; i++) {
1299 WifiMacInfo mac_info;
1300 mac_info.wlan_mac_id = mac_infos_arr[i].wlan_mac_id;
1301 mac_info.mac_band = mac_infos_arr[i].mac_band;
1302 for (int32_t j = 0; j < mac_infos_arr[i].num_iface; j++) {
1303 WifiIfaceInfo iface_info;
1304 iface_info.name = mac_infos_arr[i].iface_info[j].iface_name;
1305 iface_info.channel = mac_infos_arr[i].iface_info[j].channel;
1306 mac_info.iface_infos.push_back(iface_info);
1307 }
1308 mac_infos_vec.push_back(mac_info);
1309 }
1310 on_user_change_callback(mac_infos_vec);
1311 }
1312 };
1313 wifi_error status = global_func_table_.wifi_set_radio_mode_change_handler(
1314 0, getIfaceHandle(iface_name), {onAsyncRadioModeChange});
1315 if (status != WIFI_SUCCESS) {
1316 on_radio_mode_change_internal_callback = nullptr;
1317 }
1318 return status;
1319}
1320
1321wifi_error WifiLegacyHal::registerSubsystemRestartCallbackHandler(
1322 const on_subsystem_restart_callback& on_restart_callback) {
1323 if (on_subsystem_restart_internal_callback) {
1324 return WIFI_ERROR_NOT_AVAILABLE;
1325 }
1326 on_subsystem_restart_internal_callback = [on_restart_callback](const char* error) {
1327 on_restart_callback(error);
1328 };
1329 wifi_error status = global_func_table_.wifi_set_subsystem_restart_handler(
1330 global_handle_, {onAsyncSubsystemRestart});
1331 if (status != WIFI_SUCCESS) {
1332 on_subsystem_restart_internal_callback = nullptr;
1333 }
1334 return status;
1335}
1336
maheshkkv7d422812023-11-16 17:32:50 -08001337wifi_error WifiLegacyHal::startRttRangeRequestV3(
1338 const std::string& iface_name, wifi_request_id id,
1339 const std::vector<wifi_rtt_config_v3>& rtt_configs,
1340 const on_rtt_results_callback_v3& on_results_user_callback_v3) {
1341 if (on_rtt_results_internal_callback_v3) {
1342 return WIFI_ERROR_NOT_AVAILABLE;
1343 }
1344
1345 on_rtt_results_internal_callback_v3 = [on_results_user_callback_v3](
1346 wifi_request_id id, unsigned num_results,
1347 wifi_rtt_result_v3* rtt_results_v3[]) {
1348 if (num_results > 0 && !rtt_results_v3) {
1349 LOG(ERROR) << "Unexpected nullptr in RTT v3 results";
1350 return;
1351 }
1352 std::vector<const wifi_rtt_result_v3*> rtt_results_vec_v3;
1353 std::copy_if(rtt_results_v3, rtt_results_v3 + num_results,
1354 back_inserter(rtt_results_vec_v3),
1355 [](wifi_rtt_result_v3* rtt_result_v3) { return rtt_result_v3 != nullptr; });
1356 on_results_user_callback_v3(id, rtt_results_vec_v3);
1357 };
1358
1359 std::vector<wifi_rtt_config_v3> rtt_configs_internal(rtt_configs);
1360 wifi_error status = global_func_table_.wifi_rtt_range_request_v3(
1361 id, getIfaceHandle(iface_name), rtt_configs.size(), rtt_configs_internal.data(),
1362 {onAsyncRttResultsV3});
1363 if (status != WIFI_SUCCESS) {
1364 invalidateRttResultsCallbacks();
1365 }
1366 return status;
1367}
1368
Gabriel Birenf3262f92022-07-15 23:25:39 +00001369wifi_error WifiLegacyHal::startRttRangeRequest(
1370 const std::string& iface_name, wifi_request_id id,
1371 const std::vector<wifi_rtt_config>& rtt_configs,
Sunil Ravif8fc2372022-11-10 18:37:41 +00001372 const on_rtt_results_callback& on_results_user_callback,
1373 const on_rtt_results_callback_v2& on_results_user_callback_v2) {
1374 if (on_rtt_results_internal_callback || on_rtt_results_internal_callback_v2) {
Gabriel Birenf3262f92022-07-15 23:25:39 +00001375 return WIFI_ERROR_NOT_AVAILABLE;
1376 }
1377
1378 on_rtt_results_internal_callback = [on_results_user_callback](wifi_request_id id,
1379 unsigned num_results,
1380 wifi_rtt_result* rtt_results[]) {
1381 if (num_results > 0 && !rtt_results) {
1382 LOG(ERROR) << "Unexpected nullptr in RTT results";
1383 return;
1384 }
1385 std::vector<const wifi_rtt_result*> rtt_results_vec;
1386 std::copy_if(rtt_results, rtt_results + num_results, back_inserter(rtt_results_vec),
1387 [](wifi_rtt_result* rtt_result) { return rtt_result != nullptr; });
1388 on_results_user_callback(id, rtt_results_vec);
1389 };
1390
Sunil Ravif8fc2372022-11-10 18:37:41 +00001391 on_rtt_results_internal_callback_v2 = [on_results_user_callback_v2](
1392 wifi_request_id id, unsigned num_results,
1393 wifi_rtt_result_v2* rtt_results_v2[]) {
1394 if (num_results > 0 && !rtt_results_v2) {
1395 LOG(ERROR) << "Unexpected nullptr in RTT results";
1396 return;
1397 }
1398 std::vector<const wifi_rtt_result_v2*> rtt_results_vec_v2;
1399 std::copy_if(rtt_results_v2, rtt_results_v2 + num_results,
1400 back_inserter(rtt_results_vec_v2),
1401 [](wifi_rtt_result_v2* rtt_result_v2) { return rtt_result_v2 != nullptr; });
1402 on_results_user_callback_v2(id, rtt_results_vec_v2);
1403 };
1404
Gabriel Birenf3262f92022-07-15 23:25:39 +00001405 std::vector<wifi_rtt_config> rtt_configs_internal(rtt_configs);
1406 wifi_error status = global_func_table_.wifi_rtt_range_request(
1407 id, getIfaceHandle(iface_name), rtt_configs.size(), rtt_configs_internal.data(),
Sunil Ravif8fc2372022-11-10 18:37:41 +00001408 {onAsyncRttResults, onAsyncRttResultsV2});
Gabriel Birenf3262f92022-07-15 23:25:39 +00001409 if (status != WIFI_SUCCESS) {
Sunil Ravif8fc2372022-11-10 18:37:41 +00001410 invalidateRttResultsCallbacks();
Gabriel Birenf3262f92022-07-15 23:25:39 +00001411 }
1412 return status;
1413}
1414
1415wifi_error WifiLegacyHal::cancelRttRangeRequest(
1416 const std::string& iface_name, wifi_request_id id,
1417 const std::vector<std::array<uint8_t, ETH_ALEN>>& mac_addrs) {
Sunil Ravif8fc2372022-11-10 18:37:41 +00001418 if (!on_rtt_results_internal_callback && !on_rtt_results_internal_callback_v2) {
Gabriel Birenf3262f92022-07-15 23:25:39 +00001419 return WIFI_ERROR_NOT_AVAILABLE;
1420 }
1421 static_assert(sizeof(mac_addr) == sizeof(std::array<uint8_t, ETH_ALEN>),
1422 "MAC address size mismatch");
1423 // TODO: How do we handle partial cancels (i.e only a subset of enabled mac
1424 // addressed are cancelled).
1425 std::vector<std::array<uint8_t, ETH_ALEN>> mac_addrs_internal(mac_addrs);
1426 wifi_error status = global_func_table_.wifi_rtt_range_cancel(
1427 id, getIfaceHandle(iface_name), mac_addrs.size(),
1428 reinterpret_cast<mac_addr*>(mac_addrs_internal.data()));
1429 // If the request Id is wrong, don't stop the ongoing range request. Any
1430 // other error should be treated as the end of rtt ranging.
1431 if (status != WIFI_ERROR_INVALID_REQUEST_ID) {
Sunil Ravif8fc2372022-11-10 18:37:41 +00001432 invalidateRttResultsCallbacks();
Gabriel Birenf3262f92022-07-15 23:25:39 +00001433 }
1434 return status;
1435}
1436
1437std::pair<wifi_error, wifi_rtt_capabilities> WifiLegacyHal::getRttCapabilities(
1438 const std::string& iface_name) {
1439 wifi_rtt_capabilities rtt_caps;
1440 wifi_error status =
1441 global_func_table_.wifi_get_rtt_capabilities(getIfaceHandle(iface_name), &rtt_caps);
1442 return {status, rtt_caps};
1443}
1444
maheshkkv7d422812023-11-16 17:32:50 -08001445std::pair<wifi_error, wifi_rtt_capabilities_v3> WifiLegacyHal::getRttCapabilitiesV3(
1446 const std::string& iface_name) {
1447 wifi_rtt_capabilities_v3 rtt_caps_v3;
1448 wifi_error status = global_func_table_.wifi_get_rtt_capabilities_v3(getIfaceHandle(iface_name),
1449 &rtt_caps_v3);
1450 return {status, rtt_caps_v3};
1451}
1452
Gabriel Birenf3262f92022-07-15 23:25:39 +00001453std::pair<wifi_error, wifi_rtt_responder> WifiLegacyHal::getRttResponderInfo(
1454 const std::string& iface_name) {
1455 wifi_rtt_responder rtt_responder;
1456 wifi_error status = global_func_table_.wifi_rtt_get_responder_info(getIfaceHandle(iface_name),
1457 &rtt_responder);
1458 return {status, rtt_responder};
1459}
1460
1461wifi_error WifiLegacyHal::enableRttResponder(const std::string& iface_name, wifi_request_id id,
1462 const wifi_channel_info& channel_hint,
1463 uint32_t max_duration_secs,
1464 const wifi_rtt_responder& info) {
1465 wifi_rtt_responder info_internal(info);
1466 return global_func_table_.wifi_enable_responder(id, getIfaceHandle(iface_name), channel_hint,
1467 max_duration_secs, &info_internal);
1468}
1469
1470wifi_error WifiLegacyHal::disableRttResponder(const std::string& iface_name, wifi_request_id id) {
1471 return global_func_table_.wifi_disable_responder(id, getIfaceHandle(iface_name));
1472}
1473
1474wifi_error WifiLegacyHal::setRttLci(const std::string& iface_name, wifi_request_id id,
1475 const wifi_lci_information& info) {
1476 wifi_lci_information info_internal(info);
1477 return global_func_table_.wifi_set_lci(id, getIfaceHandle(iface_name), &info_internal);
1478}
1479
1480wifi_error WifiLegacyHal::setRttLcr(const std::string& iface_name, wifi_request_id id,
1481 const wifi_lcr_information& info) {
1482 wifi_lcr_information info_internal(info);
1483 return global_func_table_.wifi_set_lcr(id, getIfaceHandle(iface_name), &info_internal);
1484}
1485
1486wifi_error WifiLegacyHal::nanRegisterCallbackHandlers(const std::string& iface_name,
1487 const NanCallbackHandlers& user_callbacks) {
1488 on_nan_notify_response_user_callback = user_callbacks.on_notify_response;
1489 on_nan_event_publish_terminated_user_callback = user_callbacks.on_event_publish_terminated;
1490 on_nan_event_match_user_callback = user_callbacks.on_event_match;
1491 on_nan_event_match_expired_user_callback = user_callbacks.on_event_match_expired;
1492 on_nan_event_subscribe_terminated_user_callback = user_callbacks.on_event_subscribe_terminated;
1493 on_nan_event_followup_user_callback = user_callbacks.on_event_followup;
1494 on_nan_event_disc_eng_event_user_callback = user_callbacks.on_event_disc_eng_event;
1495 on_nan_event_disabled_user_callback = user_callbacks.on_event_disabled;
1496 on_nan_event_tca_user_callback = user_callbacks.on_event_tca;
1497 on_nan_event_beacon_sdf_payload_user_callback = user_callbacks.on_event_beacon_sdf_payload;
1498 on_nan_event_data_path_request_user_callback = user_callbacks.on_event_data_path_request;
Nate Jiang38e8db52022-12-02 17:30:27 -08001499 on_nan_event_pairing_request_user_callback = user_callbacks.on_event_pairing_request;
1500 on_nan_event_pairing_confirm_user_callback = user_callbacks.on_event_pairing_confirm;
1501 on_nan_event_bootstrapping_request_user_callback =
1502 user_callbacks.on_event_bootstrapping_request;
1503 on_nan_event_bootstrapping_confirm_user_callback =
1504 user_callbacks.on_event_bootstrapping_confirm;
Gabriel Birenf3262f92022-07-15 23:25:39 +00001505 on_nan_event_data_path_confirm_user_callback = user_callbacks.on_event_data_path_confirm;
1506 on_nan_event_data_path_end_user_callback = user_callbacks.on_event_data_path_end;
1507 on_nan_event_transmit_follow_up_user_callback = user_callbacks.on_event_transmit_follow_up;
1508 on_nan_event_range_request_user_callback = user_callbacks.on_event_range_request;
1509 on_nan_event_range_report_user_callback = user_callbacks.on_event_range_report;
1510 on_nan_event_schedule_update_user_callback = user_callbacks.on_event_schedule_update;
Nate Jiangd6cc3312023-02-14 16:37:54 -08001511 on_nan_event_suspension_mode_change_user_callback =
1512 user_callbacks.on_event_suspension_mode_change;
Gabriel Birenf3262f92022-07-15 23:25:39 +00001513
Nate Jiang38e8db52022-12-02 17:30:27 -08001514 return global_func_table_.wifi_nan_register_handler(getIfaceHandle(iface_name),
1515 {onAsyncNanNotifyResponse,
1516 onAsyncNanEventPublishReplied,
1517 onAsyncNanEventPublishTerminated,
1518 onAsyncNanEventMatch,
1519 onAsyncNanEventMatchExpired,
1520 onAsyncNanEventSubscribeTerminated,
1521 onAsyncNanEventFollowup,
1522 onAsyncNanEventDiscEngEvent,
1523 onAsyncNanEventDisabled,
1524 onAsyncNanEventTca,
1525 onAsyncNanEventBeaconSdfPayload,
1526 onAsyncNanEventDataPathRequest,
1527 onAsyncNanEventDataPathConfirm,
1528 onAsyncNanEventDataPathEnd,
1529 onAsyncNanEventTransmitFollowUp,
1530 onAsyncNanEventRangeRequest,
1531 onAsyncNanEventRangeReport,
1532 onAsyncNanEventScheduleUpdate,
1533 onAsyncNanEventPairingRequest,
1534 onAsyncNanEventPairingConfirm,
1535 onAsyncNanEventBootstrappingRequest,
Nate Jiangd6cc3312023-02-14 16:37:54 -08001536 onAsyncNanEventBootstrappingConfirm,
1537 onAsyncNanEventSuspensionModeChange});
Gabriel Birenf3262f92022-07-15 23:25:39 +00001538}
1539
1540wifi_error WifiLegacyHal::nanEnableRequest(const std::string& iface_name, transaction_id id,
1541 const NanEnableRequest& msg) {
1542 NanEnableRequest msg_internal(msg);
1543 return global_func_table_.wifi_nan_enable_request(id, getIfaceHandle(iface_name),
1544 &msg_internal);
1545}
1546
1547wifi_error WifiLegacyHal::nanDisableRequest(const std::string& iface_name, transaction_id id) {
1548 return global_func_table_.wifi_nan_disable_request(id, getIfaceHandle(iface_name));
1549}
1550
1551wifi_error WifiLegacyHal::nanPublishRequest(const std::string& iface_name, transaction_id id,
1552 const NanPublishRequest& msg) {
1553 NanPublishRequest msg_internal(msg);
1554 return global_func_table_.wifi_nan_publish_request(id, getIfaceHandle(iface_name),
1555 &msg_internal);
1556}
1557
1558wifi_error WifiLegacyHal::nanPublishCancelRequest(const std::string& iface_name, transaction_id id,
1559 const NanPublishCancelRequest& msg) {
1560 NanPublishCancelRequest msg_internal(msg);
1561 return global_func_table_.wifi_nan_publish_cancel_request(id, getIfaceHandle(iface_name),
1562 &msg_internal);
1563}
1564
1565wifi_error WifiLegacyHal::nanSubscribeRequest(const std::string& iface_name, transaction_id id,
1566 const NanSubscribeRequest& msg) {
1567 NanSubscribeRequest msg_internal(msg);
1568 return global_func_table_.wifi_nan_subscribe_request(id, getIfaceHandle(iface_name),
1569 &msg_internal);
1570}
1571
1572wifi_error WifiLegacyHal::nanSubscribeCancelRequest(const std::string& iface_name,
1573 transaction_id id,
1574 const NanSubscribeCancelRequest& msg) {
1575 NanSubscribeCancelRequest msg_internal(msg);
1576 return global_func_table_.wifi_nan_subscribe_cancel_request(id, getIfaceHandle(iface_name),
1577 &msg_internal);
1578}
1579
1580wifi_error WifiLegacyHal::nanTransmitFollowupRequest(const std::string& iface_name,
1581 transaction_id id,
1582 const NanTransmitFollowupRequest& msg) {
1583 NanTransmitFollowupRequest msg_internal(msg);
1584 return global_func_table_.wifi_nan_transmit_followup_request(id, getIfaceHandle(iface_name),
1585 &msg_internal);
1586}
1587
1588wifi_error WifiLegacyHal::nanStatsRequest(const std::string& iface_name, transaction_id id,
1589 const NanStatsRequest& msg) {
1590 NanStatsRequest msg_internal(msg);
1591 return global_func_table_.wifi_nan_stats_request(id, getIfaceHandle(iface_name), &msg_internal);
1592}
1593
1594wifi_error WifiLegacyHal::nanConfigRequest(const std::string& iface_name, transaction_id id,
1595 const NanConfigRequest& msg) {
1596 NanConfigRequest msg_internal(msg);
1597 return global_func_table_.wifi_nan_config_request(id, getIfaceHandle(iface_name),
1598 &msg_internal);
1599}
1600
1601wifi_error WifiLegacyHal::nanTcaRequest(const std::string& iface_name, transaction_id id,
1602 const NanTCARequest& msg) {
1603 NanTCARequest msg_internal(msg);
1604 return global_func_table_.wifi_nan_tca_request(id, getIfaceHandle(iface_name), &msg_internal);
1605}
1606
1607wifi_error WifiLegacyHal::nanBeaconSdfPayloadRequest(const std::string& iface_name,
1608 transaction_id id,
1609 const NanBeaconSdfPayloadRequest& msg) {
1610 NanBeaconSdfPayloadRequest msg_internal(msg);
1611 return global_func_table_.wifi_nan_beacon_sdf_payload_request(id, getIfaceHandle(iface_name),
1612 &msg_internal);
1613}
1614
1615std::pair<wifi_error, NanVersion> WifiLegacyHal::nanGetVersion() {
1616 NanVersion version;
1617 wifi_error status = global_func_table_.wifi_nan_get_version(global_handle_, &version);
1618 return {status, version};
1619}
1620
1621wifi_error WifiLegacyHal::nanGetCapabilities(const std::string& iface_name, transaction_id id) {
1622 return global_func_table_.wifi_nan_get_capabilities(id, getIfaceHandle(iface_name));
1623}
1624
1625wifi_error WifiLegacyHal::nanDataInterfaceCreate(const std::string& iface_name, transaction_id id,
1626 const std::string& data_iface_name) {
1627 return global_func_table_.wifi_nan_data_interface_create(id, getIfaceHandle(iface_name),
1628 makeCharVec(data_iface_name).data());
1629}
1630
1631wifi_error WifiLegacyHal::nanDataInterfaceDelete(const std::string& iface_name, transaction_id id,
1632 const std::string& data_iface_name) {
1633 return global_func_table_.wifi_nan_data_interface_delete(id, getIfaceHandle(iface_name),
1634 makeCharVec(data_iface_name).data());
1635}
1636
1637wifi_error WifiLegacyHal::nanDataRequestInitiator(const std::string& iface_name, transaction_id id,
1638 const NanDataPathInitiatorRequest& msg) {
1639 NanDataPathInitiatorRequest msg_internal(msg);
1640 return global_func_table_.wifi_nan_data_request_initiator(id, getIfaceHandle(iface_name),
1641 &msg_internal);
1642}
1643
1644wifi_error WifiLegacyHal::nanDataIndicationResponse(const std::string& iface_name,
1645 transaction_id id,
1646 const NanDataPathIndicationResponse& msg) {
1647 NanDataPathIndicationResponse msg_internal(msg);
1648 return global_func_table_.wifi_nan_data_indication_response(id, getIfaceHandle(iface_name),
1649 &msg_internal);
1650}
1651
Nate Jiang38e8db52022-12-02 17:30:27 -08001652wifi_error WifiLegacyHal::nanPairingRequest(const std::string& iface_name, transaction_id id,
1653 const NanPairingRequest& msg) {
1654 NanPairingRequest msg_internal(msg);
1655 return global_func_table_.wifi_nan_pairing_request(id, getIfaceHandle(iface_name),
1656 &msg_internal);
1657}
1658
1659wifi_error WifiLegacyHal::nanPairingIndicationResponse(const std::string& iface_name,
1660 transaction_id id,
1661 const NanPairingIndicationResponse& msg) {
1662 NanPairingIndicationResponse msg_internal(msg);
1663 return global_func_table_.wifi_nan_pairing_indication_response(id, getIfaceHandle(iface_name),
1664 &msg_internal);
1665}
1666
1667wifi_error WifiLegacyHal::nanBootstrappingRequest(const std::string& iface_name, transaction_id id,
1668 const NanBootstrappingRequest& msg) {
1669 NanBootstrappingRequest msg_internal(msg);
1670 return global_func_table_.wifi_nan_bootstrapping_request(id, getIfaceHandle(iface_name),
1671 &msg_internal);
1672}
1673
1674wifi_error WifiLegacyHal::nanBootstrappingIndicationResponse(
1675 const std::string& iface_name, transaction_id id,
1676 const NanBootstrappingIndicationResponse& msg) {
1677 NanBootstrappingIndicationResponse msg_internal(msg);
1678 return global_func_table_.wifi_nan_bootstrapping_indication_response(
1679 id, getIfaceHandle(iface_name), &msg_internal);
1680}
1681
Gabriel Birenf3262f92022-07-15 23:25:39 +00001682typedef struct {
1683 u8 num_ndp_instances;
1684 NanDataPathId ndp_instance_id;
1685} NanDataPathEndSingleNdpIdRequest;
1686
1687wifi_error WifiLegacyHal::nanDataEnd(const std::string& iface_name, transaction_id id,
1688 uint32_t ndpInstanceId) {
1689 NanDataPathEndSingleNdpIdRequest msg;
1690 msg.num_ndp_instances = 1;
1691 msg.ndp_instance_id = ndpInstanceId;
1692 wifi_error status = global_func_table_.wifi_nan_data_end(id, getIfaceHandle(iface_name),
1693 (NanDataPathEndRequest*)&msg);
1694 return status;
1695}
1696
Nate Jiangbae6fdd2023-02-10 17:16:40 -08001697wifi_error WifiLegacyHal::nanPairingEnd(const std::string& iface_name, transaction_id id,
1698 uint32_t pairingId) {
1699 NanPairingEndRequest msg;
1700 msg.pairing_instance_id = pairingId;
1701 wifi_error status =
1702 global_func_table_.wifi_nan_pairing_end(id, getIfaceHandle(iface_name), &msg);
1703 return status;
1704}
1705
Phill Hayers02a97242022-12-15 16:05:14 +00001706wifi_error WifiLegacyHal::nanSuspendRequest(const std::string& iface_name, transaction_id id,
1707 const NanSuspendRequest& msg) {
1708 NanSuspendRequest msg_internal(msg);
1709 wifi_error status = global_func_table_.wifi_nan_suspend_request(id, getIfaceHandle(iface_name),
1710 &msg_internal);
1711 return status;
1712}
1713
1714wifi_error WifiLegacyHal::nanResumeRequest(const std::string& iface_name, transaction_id id,
1715 const NanResumeRequest& msg) {
1716 NanResumeRequest msg_internal(msg);
1717 wifi_error status = global_func_table_.wifi_nan_resume_request(id, getIfaceHandle(iface_name),
1718 &msg_internal);
1719 return status;
1720}
1721
Gabriel Birenf3262f92022-07-15 23:25:39 +00001722wifi_error WifiLegacyHal::setCountryCode(const std::string& iface_name,
1723 const std::array<uint8_t, 2> code) {
1724 std::string code_str(code.data(), code.data() + code.size());
1725 return global_func_table_.wifi_set_country_code(getIfaceHandle(iface_name), code_str.c_str());
1726}
1727
1728wifi_error WifiLegacyHal::retrieveIfaceHandles() {
1729 wifi_interface_handle* iface_handles = nullptr;
1730 int num_iface_handles = 0;
1731 wifi_error status =
1732 global_func_table_.wifi_get_ifaces(global_handle_, &num_iface_handles, &iface_handles);
1733 if (status != WIFI_SUCCESS) {
1734 LOG(ERROR) << "Failed to enumerate interface handles";
1735 return status;
1736 }
1737 iface_name_to_handle_.clear();
1738 for (int i = 0; i < num_iface_handles; ++i) {
1739 std::array<char, IFNAMSIZ> iface_name_arr = {};
1740 status = global_func_table_.wifi_get_iface_name(iface_handles[i], iface_name_arr.data(),
1741 iface_name_arr.size());
1742 if (status != WIFI_SUCCESS) {
1743 LOG(WARNING) << "Failed to get interface handle name";
1744 continue;
1745 }
1746 // Assuming the interface name is null terminated since the legacy HAL
1747 // API does not return a size.
1748 std::string iface_name(iface_name_arr.data());
1749 LOG(INFO) << "Adding interface handle for " << iface_name;
1750 iface_name_to_handle_[iface_name] = iface_handles[i];
1751 }
1752 return WIFI_SUCCESS;
1753}
1754
1755wifi_interface_handle WifiLegacyHal::getIfaceHandle(const std::string& iface_name) {
1756 const auto iface_handle_iter = iface_name_to_handle_.find(iface_name);
1757 if (iface_handle_iter == iface_name_to_handle_.end()) {
1758 LOG(ERROR) << "Unknown iface name: " << iface_name;
1759 return nullptr;
1760 }
1761 return iface_handle_iter->second;
1762}
1763
1764void WifiLegacyHal::runEventLoop() {
1765 LOG(DEBUG) << "Starting legacy HAL event loop";
1766 global_func_table_.wifi_event_loop(global_handle_);
1767 const auto lock = aidl_sync_util::acquireGlobalLock();
1768 if (!awaiting_event_loop_termination_) {
1769 LOG(FATAL) << "Legacy HAL event loop terminated, but HAL was not stopping";
1770 }
1771 LOG(DEBUG) << "Legacy HAL event loop terminated";
1772 awaiting_event_loop_termination_ = false;
1773 stop_wait_cv_.notify_one();
1774}
1775
1776std::pair<wifi_error, std::vector<wifi_cached_scan_results>> WifiLegacyHal::getGscanCachedResults(
1777 const std::string& iface_name) {
1778 std::vector<wifi_cached_scan_results> cached_scan_results;
1779 cached_scan_results.resize(kMaxCachedGscanResults);
1780 int32_t num_results = 0;
1781 wifi_error status = global_func_table_.wifi_get_cached_gscan_results(
1782 getIfaceHandle(iface_name), true /* always flush */, cached_scan_results.size(),
1783 cached_scan_results.data(), &num_results);
1784 CHECK(num_results >= 0 && static_cast<uint32_t>(num_results) <= kMaxCachedGscanResults);
1785 cached_scan_results.resize(num_results);
1786 // Check for invalid IE lengths in these cached scan results and correct it.
1787 for (auto& cached_scan_result : cached_scan_results) {
1788 int num_scan_results = cached_scan_result.num_results;
1789 for (int i = 0; i < num_scan_results; i++) {
1790 auto& scan_result = cached_scan_result.results[i];
1791 if (scan_result.ie_length > 0) {
1792 LOG(DEBUG) << "Cached scan result has non-zero IE length " << scan_result.ie_length;
1793 scan_result.ie_length = 0;
1794 }
1795 }
1796 }
1797 return {status, std::move(cached_scan_results)};
1798}
1799
1800wifi_error WifiLegacyHal::createVirtualInterface(const std::string& ifname,
1801 wifi_interface_type iftype) {
1802 // Create the interface if it doesn't exist. If interface already exist,
1803 // Vendor Hal should return WIFI_SUCCESS.
1804 wifi_error status = global_func_table_.wifi_virtual_interface_create(global_handle_,
1805 ifname.c_str(), iftype);
1806 return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status);
1807}
1808
1809wifi_error WifiLegacyHal::deleteVirtualInterface(const std::string& ifname) {
1810 // Delete the interface if it was created dynamically.
1811 wifi_error status =
1812 global_func_table_.wifi_virtual_interface_delete(global_handle_, ifname.c_str());
1813 return handleVirtualInterfaceCreateOrDeleteStatus(ifname, status);
1814}
1815
1816wifi_error WifiLegacyHal::handleVirtualInterfaceCreateOrDeleteStatus(const std::string& ifname,
1817 wifi_error status) {
1818 if (status == WIFI_SUCCESS) {
1819 // refresh list of handlers now.
1820 status = retrieveIfaceHandles();
1821 } else if (status == WIFI_ERROR_NOT_SUPPORTED) {
1822 // Vendor hal does not implement this API. Such vendor implementations
1823 // are expected to create / delete interface by other means.
1824
1825 // check if interface exists.
1826 if (if_nametoindex(ifname.c_str())) {
1827 status = retrieveIfaceHandles();
1828 }
1829 }
1830 return status;
1831}
1832
1833wifi_error WifiLegacyHal::getSupportedIfaceName(uint32_t iface_type, std::string& ifname) {
1834 std::array<char, IFNAMSIZ> buffer;
1835
1836 wifi_error res = global_func_table_.wifi_get_supported_iface_name(
1837 global_handle_, (uint32_t)iface_type, buffer.data(), buffer.size());
1838 if (res == WIFI_SUCCESS) ifname = buffer.data();
1839
1840 return res;
1841}
1842
1843wifi_error WifiLegacyHal::multiStaSetPrimaryConnection(const std::string& ifname) {
1844 return global_func_table_.wifi_multi_sta_set_primary_connection(global_handle_,
1845 getIfaceHandle(ifname));
1846}
1847
1848wifi_error WifiLegacyHal::multiStaSetUseCase(wifi_multi_sta_use_case use_case) {
1849 return global_func_table_.wifi_multi_sta_set_use_case(global_handle_, use_case);
1850}
1851
1852wifi_error WifiLegacyHal::setCoexUnsafeChannels(
1853 std::vector<wifi_coex_unsafe_channel> unsafe_channels, uint32_t restrictions) {
1854 return global_func_table_.wifi_set_coex_unsafe_channels(global_handle_, unsafe_channels.size(),
1855 unsafe_channels.data(), restrictions);
1856}
1857
1858wifi_error WifiLegacyHal::setVoipMode(const std::string& iface_name, wifi_voip_mode mode) {
1859 return global_func_table_.wifi_set_voip_mode(getIfaceHandle(iface_name), mode);
1860}
1861
maheshkkv39903822023-11-28 15:31:53 -08001862std::pair<wifi_twt_capabilities, wifi_error> WifiLegacyHal::twtGetCapabilities(
1863 const std::string& ifaceName) {
1864 wifi_twt_capabilities capabs = {};
1865 wifi_error status =
1866 global_func_table_.wifi_twt_get_capabilities(getIfaceHandle(ifaceName), &capabs);
1867 return {capabs, status};
1868}
1869
1870wifi_error WifiLegacyHal::twtSessionSetup(
1871 const std::string& ifaceName, uint32_t cmdId, const wifi_twt_request& request,
1872 const on_twt_failure& on_twt_failure_user_callback,
1873 const on_twt_session_create& on_twt_session_create_user_callback,
1874 const on_twt_session_update& on_twt_session_update_user_callback,
1875 const on_twt_session_teardown& on_twt_session_teardown_user_callback,
1876 const on_twt_session_stats& on_twt_session_stats_user_callback,
1877 const on_twt_session_suspend& on_twt_session_suspend_user_callback,
1878 const on_twt_session_resume& on_twt_session_resume_user_callback) {
1879 if (on_twt_failure_internal_callback || on_twt_session_create_internal_callback ||
1880 on_twt_session_update_internal_callback || on_twt_session_teardown_internal_callback ||
1881 on_twt_session_stats_internal_callback) {
1882 return WIFI_ERROR_NOT_AVAILABLE;
1883 }
1884
1885 on_twt_failure_internal_callback = [on_twt_failure_user_callback](
1886 wifi_request_id id, wifi_twt_error_code error_code) {
1887 on_twt_failure_user_callback(id, error_code);
1888 };
1889
1890 on_twt_session_create_internal_callback = [on_twt_session_create_user_callback](
1891 wifi_request_id id,
1892 wifi_twt_session twt_session) {
1893 on_twt_session_create_user_callback(id, twt_session);
1894 };
1895
1896 on_twt_session_update_internal_callback = [on_twt_session_update_user_callback](
1897 wifi_request_id id,
1898 wifi_twt_session twt_session) {
1899 on_twt_session_update_user_callback(id, twt_session);
1900 };
1901
1902 on_twt_session_teardown_internal_callback = [on_twt_session_teardown_user_callback](
1903 wifi_request_id id, int session_id,
1904 wifi_twt_teardown_reason_code reason_code) {
1905 on_twt_session_teardown_user_callback(id, session_id, reason_code);
1906 };
1907
1908 on_twt_session_stats_internal_callback = [on_twt_session_stats_user_callback](
1909 wifi_request_id id, int session_id,
1910 wifi_twt_session_stats stats) {
1911 on_twt_session_stats_user_callback(id, session_id, stats);
1912 };
1913
1914 on_twt_session_suspend_internal_callback = [on_twt_session_suspend_user_callback](
1915 wifi_request_id id, int session_id) {
1916 on_twt_session_suspend_user_callback(id, session_id);
1917 };
1918
1919 on_twt_session_resume_internal_callback = [on_twt_session_resume_user_callback](
1920 wifi_request_id id, int session_id) {
1921 on_twt_session_resume_user_callback(id, session_id);
1922 };
1923
1924 return global_func_table_.wifi_twt_session_setup(
1925 cmdId, getIfaceHandle(ifaceName), request,
1926 {onAsyncTwtError, onAsyncTwtSessionCreate, onAsyncTwtSessionUpdate,
1927 onAsyncTwtSessionTeardown, onAsyncTwtSessionStats, onAsyncTwtSessionSuspend,
1928 onAsyncTwtSessionResume});
1929}
1930
1931wifi_error WifiLegacyHal::twtSessionUpdate(const std::string& ifaceName, uint32_t cmdId,
1932 uint32_t sessionId, const wifi_twt_request& request) {
1933 return global_func_table_.wifi_twt_session_update(cmdId, getIfaceHandle(ifaceName), sessionId,
1934 request);
1935}
1936
1937wifi_error WifiLegacyHal::twtSessionSuspend(const std::string& ifaceName, uint32_t cmdId,
1938 uint32_t sessionId) {
1939 return global_func_table_.wifi_twt_session_suspend(cmdId, getIfaceHandle(ifaceName), sessionId);
1940}
1941
1942wifi_error WifiLegacyHal::twtSessionResume(const std::string& ifaceName, uint32_t cmdId,
1943 uint32_t sessionId) {
1944 return global_func_table_.wifi_twt_session_resume(cmdId, getIfaceHandle(ifaceName), sessionId);
1945}
1946
1947wifi_error WifiLegacyHal::twtSessionTeardown(const std::string& ifaceName, uint32_t cmdId,
1948 uint32_t sessionId) {
1949 return global_func_table_.wifi_twt_session_teardown(cmdId, getIfaceHandle(ifaceName),
1950 sessionId);
1951}
1952
1953wifi_error WifiLegacyHal::twtSessionGetStats(const std::string& ifaceName, uint32_t cmdId,
1954 uint32_t sessionId) {
1955 return global_func_table_.wifi_twt_session_get_stats(cmdId, getIfaceHandle(ifaceName),
1956 sessionId);
1957}
1958
Gabriel Birenf3262f92022-07-15 23:25:39 +00001959wifi_error WifiLegacyHal::twtRegisterHandler(const std::string& iface_name,
1960 const TwtCallbackHandlers& user_callbacks) {
1961 on_twt_event_setup_response_callback = user_callbacks.on_setup_response;
1962 on_twt_event_teardown_completion_callback = user_callbacks.on_teardown_completion;
1963 on_twt_event_info_frame_received_callback = user_callbacks.on_info_frame_received;
1964 on_twt_event_device_notify_callback = user_callbacks.on_device_notify;
1965
1966 return global_func_table_.wifi_twt_register_handler(
1967 getIfaceHandle(iface_name),
1968 {onAsyncTwtEventSetupResponse, onAsyncTwtEventTeardownCompletion,
1969 onAsyncTwtEventInfoFrameReceived, onAsyncTwtEventDeviceNotify});
1970}
1971
1972std::pair<wifi_error, TwtCapabilitySet> WifiLegacyHal::twtGetCapability(
1973 const std::string& iface_name) {
1974 TwtCapabilitySet capSet;
1975 wifi_error status =
1976 global_func_table_.wifi_twt_get_capability(getIfaceHandle(iface_name), &capSet);
1977 return {status, capSet};
1978}
1979
1980wifi_error WifiLegacyHal::twtSetupRequest(const std::string& iface_name,
1981 const TwtSetupRequest& msg) {
1982 TwtSetupRequest msgInternal(msg);
1983 return global_func_table_.wifi_twt_setup_request(getIfaceHandle(iface_name), &msgInternal);
1984}
1985
1986wifi_error WifiLegacyHal::twtTearDownRequest(const std::string& iface_name,
1987 const TwtTeardownRequest& msg) {
1988 TwtTeardownRequest msgInternal(msg);
1989 return global_func_table_.wifi_twt_teardown_request(getIfaceHandle(iface_name), &msgInternal);
1990}
1991
1992wifi_error WifiLegacyHal::twtInfoFrameRequest(const std::string& iface_name,
1993 const TwtInfoFrameRequest& msg) {
1994 TwtInfoFrameRequest msgInternal(msg);
1995 return global_func_table_.wifi_twt_info_frame_request(getIfaceHandle(iface_name), &msgInternal);
1996}
1997
1998std::pair<wifi_error, TwtStats> WifiLegacyHal::twtGetStats(const std::string& iface_name,
1999 uint8_t configId) {
2000 TwtStats stats;
2001 wifi_error status =
2002 global_func_table_.wifi_twt_get_stats(getIfaceHandle(iface_name), configId, &stats);
2003 return {status, stats};
2004}
2005
2006wifi_error WifiLegacyHal::twtClearStats(const std::string& iface_name, uint8_t configId) {
2007 return global_func_table_.wifi_twt_clear_stats(getIfaceHandle(iface_name), configId);
2008}
2009
Ye Jiao50274f72023-01-17 14:53:22 +08002010wifi_error WifiLegacyHal::setScanMode(const std::string& iface_name, bool enable) {
2011 return global_func_table_.wifi_set_scan_mode(iface_name.c_str(), enable);
2012}
2013
Gabriel Birenf3262f92022-07-15 23:25:39 +00002014wifi_error WifiLegacyHal::setDtimConfig(const std::string& iface_name, uint32_t multiplier) {
2015 return global_func_table_.wifi_set_dtim_config(getIfaceHandle(iface_name), multiplier);
2016}
2017
2018std::pair<wifi_error, std::vector<wifi_usable_channel>> WifiLegacyHal::getUsableChannels(
2019 uint32_t band_mask, uint32_t iface_mode_mask, uint32_t filter_mask) {
2020 std::vector<wifi_usable_channel> channels;
2021 channels.resize(kMaxWifiUsableChannels);
2022 uint32_t size = 0;
2023 wifi_error status = global_func_table_.wifi_get_usable_channels(
2024 global_handle_, band_mask, iface_mode_mask, filter_mask, channels.size(), &size,
2025 reinterpret_cast<wifi_usable_channel*>(channels.data()));
2026 CHECK(size >= 0 && size <= kMaxWifiUsableChannels);
2027 channels.resize(size);
2028 return {status, std::move(channels)};
2029}
2030
2031wifi_error WifiLegacyHal::triggerSubsystemRestart() {
2032 return global_func_table_.wifi_trigger_subsystem_restart(global_handle_);
2033}
2034
2035wifi_error WifiLegacyHal::setIndoorState(bool isIndoor) {
2036 return global_func_table_.wifi_set_indoor_state(global_handle_, isIndoor);
2037}
2038
2039std::pair<wifi_error, wifi_radio_combination_matrix*>
2040WifiLegacyHal::getSupportedRadioCombinationsMatrix() {
2041 char* buffer = new char[kMaxSupportedRadioCombinationsMatrixLength];
2042 std::fill(buffer, buffer + kMaxSupportedRadioCombinationsMatrixLength, 0);
2043 uint32_t size = 0;
2044 wifi_radio_combination_matrix* radio_combination_matrix_ptr =
2045 reinterpret_cast<wifi_radio_combination_matrix*>(buffer);
2046 wifi_error status = global_func_table_.wifi_get_supported_radio_combinations_matrix(
2047 global_handle_, kMaxSupportedRadioCombinationsMatrixLength, &size,
2048 radio_combination_matrix_ptr);
2049 CHECK(size >= 0 && size <= kMaxSupportedRadioCombinationsMatrixLength);
2050 return {status, radio_combination_matrix_ptr};
2051}
2052
2053wifi_error WifiLegacyHal::chreNanRttRequest(const std::string& iface_name, bool enable) {
2054 if (enable)
2055 return global_func_table_.wifi_nan_rtt_chre_enable_request(0, getIfaceHandle(iface_name),
2056 NULL);
2057 else
2058 return global_func_table_.wifi_nan_rtt_chre_disable_request(0, getIfaceHandle(iface_name));
2059}
2060
2061wifi_error WifiLegacyHal::chreRegisterHandler(const std::string& iface_name,
2062 const ChreCallbackHandlers& handler) {
2063 if (on_chre_nan_rtt_internal_callback) {
2064 return WIFI_ERROR_NOT_AVAILABLE;
2065 }
2066
2067 on_chre_nan_rtt_internal_callback = handler.on_wifi_chre_nan_rtt_state;
2068
2069 wifi_error status = global_func_table_.wifi_chre_register_handler(getIfaceHandle(iface_name),
2070 {onAsyncChreNanRttState});
2071 if (status != WIFI_SUCCESS) {
2072 on_chre_nan_rtt_internal_callback = nullptr;
2073 }
2074 return status;
2075}
2076
2077wifi_error WifiLegacyHal::enableWifiTxPowerLimits(const std::string& iface_name, bool enable) {
2078 return global_func_table_.wifi_enable_tx_power_limits(getIfaceHandle(iface_name), enable);
2079}
2080
Kai Shi7d0e5e92023-11-20 19:23:36 -08002081wifi_error WifiLegacyHal::getWifiCachedScanResults(const std::string& iface_name,
2082 WifiCachedScanReport& report) {
2083 on_cached_scan_results_internal_callback = [&report](wifi_cached_scan_report* report_ptr) {
2084 report.results.assign(report_ptr->results, report_ptr->results + report_ptr->result_cnt);
2085 report.scanned_freqs.assign(report_ptr->scanned_freq_list,
2086 report_ptr->scanned_freq_list + report_ptr->scanned_freq_num);
2087 report.ts = report_ptr->ts;
2088 };
Gabriel Birenf3262f92022-07-15 23:25:39 +00002089 wifi_error status = global_func_table_.wifi_get_cached_scan_results(getIfaceHandle(iface_name),
2090 {onSyncCachedScanResults});
Gabriel Birenf3262f92022-07-15 23:25:39 +00002091 on_cached_scan_results_internal_callback = nullptr;
2092 return status;
2093}
2094
Mahesh KKVc84d3772022-12-02 16:53:28 -08002095std::pair<wifi_error, wifi_chip_capabilities> WifiLegacyHal::getWifiChipCapabilities() {
2096 wifi_chip_capabilities chip_capabilities;
2097 wifi_error status =
2098 global_func_table_.wifi_get_chip_capabilities(global_handle_, &chip_capabilities);
2099 return {status, chip_capabilities};
2100}
2101
Shuibing Daie5fbcab2022-12-19 15:37:19 -08002102wifi_error WifiLegacyHal::enableStaChannelForPeerNetwork(uint32_t channelCategoryEnableFlag) {
2103 return global_func_table_.wifi_enable_sta_channel_for_peer_network(global_handle_,
2104 channelCategoryEnableFlag);
2105}
2106
maheshkkva8aba172023-02-13 12:33:26 -08002107wifi_error WifiLegacyHal::setMloMode(wifi_mlo_mode mode) {
2108 return global_func_table_.wifi_set_mlo_mode(global_handle_, mode);
2109}
2110
Sunil Ravif68b9a22023-02-15 20:56:56 +00002111std::pair<wifi_error, wifi_iface_concurrency_matrix>
2112WifiLegacyHal::getSupportedIfaceConcurrencyMatrix() {
2113 wifi_iface_concurrency_matrix iface_concurrency_matrix;
2114 wifi_error status = global_func_table_.wifi_get_supported_iface_concurrency_matrix(
2115 global_handle_, &iface_concurrency_matrix);
2116 return {status, iface_concurrency_matrix};
2117}
2118
Gabriel Birenf3262f92022-07-15 23:25:39 +00002119void WifiLegacyHal::invalidate() {
2120 global_handle_ = nullptr;
2121 iface_name_to_handle_.clear();
2122 on_driver_memory_dump_internal_callback = nullptr;
2123 on_firmware_memory_dump_internal_callback = nullptr;
2124 on_gscan_event_internal_callback = nullptr;
2125 on_gscan_full_result_internal_callback = nullptr;
2126 on_link_layer_stats_result_internal_callback = nullptr;
Mahesh KKV5f30d332022-10-26 14:07:44 -07002127 on_link_layer_ml_stats_result_internal_callback = nullptr;
Gabriel Birenf3262f92022-07-15 23:25:39 +00002128 on_rssi_threshold_breached_internal_callback = nullptr;
2129 on_ring_buffer_data_internal_callback = nullptr;
2130 on_error_alert_internal_callback = nullptr;
2131 on_radio_mode_change_internal_callback = nullptr;
2132 on_subsystem_restart_internal_callback = nullptr;
Sunil Ravif8fc2372022-11-10 18:37:41 +00002133 invalidateRttResultsCallbacks();
Gabriel Birenf3262f92022-07-15 23:25:39 +00002134 on_nan_notify_response_user_callback = nullptr;
2135 on_nan_event_publish_terminated_user_callback = nullptr;
2136 on_nan_event_match_user_callback = nullptr;
2137 on_nan_event_match_expired_user_callback = nullptr;
2138 on_nan_event_subscribe_terminated_user_callback = nullptr;
2139 on_nan_event_followup_user_callback = nullptr;
2140 on_nan_event_disc_eng_event_user_callback = nullptr;
2141 on_nan_event_disabled_user_callback = nullptr;
2142 on_nan_event_tca_user_callback = nullptr;
2143 on_nan_event_beacon_sdf_payload_user_callback = nullptr;
2144 on_nan_event_data_path_request_user_callback = nullptr;
Nate Jiang38e8db52022-12-02 17:30:27 -08002145 on_nan_event_pairing_request_user_callback = nullptr;
2146 on_nan_event_pairing_confirm_user_callback = nullptr;
2147 on_nan_event_bootstrapping_request_user_callback = nullptr;
2148 on_nan_event_bootstrapping_confirm_user_callback = nullptr;
Gabriel Birenf3262f92022-07-15 23:25:39 +00002149 on_nan_event_data_path_confirm_user_callback = nullptr;
2150 on_nan_event_data_path_end_user_callback = nullptr;
2151 on_nan_event_transmit_follow_up_user_callback = nullptr;
2152 on_nan_event_range_request_user_callback = nullptr;
2153 on_nan_event_range_report_user_callback = nullptr;
2154 on_nan_event_schedule_update_user_callback = nullptr;
2155 on_twt_event_setup_response_callback = nullptr;
2156 on_twt_event_teardown_completion_callback = nullptr;
2157 on_twt_event_info_frame_received_callback = nullptr;
2158 on_twt_event_device_notify_callback = nullptr;
2159 on_chre_nan_rtt_internal_callback = nullptr;
Kai Shi7d0e5e92023-11-20 19:23:36 -08002160 on_cached_scan_results_internal_callback = nullptr;
Gabriel Birenf3262f92022-07-15 23:25:39 +00002161}
2162
2163} // namespace legacy_hal
2164} // namespace wifi
2165} // namespace hardware
2166} // namespace android
2167} // namespace aidl