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