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