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