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