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