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