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