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 <fcntl.h> 18 19 #include <android-base/logging.h> 20 #include <android-base/unique_fd.h> 21 #include <cutils/properties.h> 22 #include <sys/stat.h> 23 #include <sys/sysmacros.h> 24 25 #include "hidl_return_util.h" 26 #include "hidl_struct_util.h" 27 #include "wifi_chip.h" 28 #include "wifi_status_util.h" 29 30 namespace { 31 using android::base::unique_fd; 32 using android::hardware::hidl_string; 33 using android::hardware::hidl_vec; 34 using android::hardware::wifi::V1_0::ChipModeId; 35 using android::hardware::wifi::V1_0::IfaceType; 36 using android::hardware::wifi::V1_0::IWifiChip; 37 using android::sp; 38 39 constexpr ChipModeId kInvalidModeId = UINT32_MAX; 40 // These mode ID's should be unique (even across combo versions). Refer to 41 // handleChipConfiguration() for it's usage. 42 // Mode ID's for V1 43 constexpr ChipModeId kV1StaChipModeId = 0; 44 constexpr ChipModeId kV1ApChipModeId = 1; 45 // Mode ID for V2 46 constexpr ChipModeId kV2ChipModeId = 2; 47 48 constexpr char kCpioMagic[] = "070701"; 49 constexpr size_t kMaxBufferSizeBytes = 1024 * 1024; 50 constexpr uint32_t kMaxRingBufferFileAgeSeconds = 60 * 60; 51 constexpr uint32_t kMaxRingBufferFileNum = 20; 52 constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/"; 53 54 template <typename Iface> 55 void invalidateAndClear(std::vector<sp<Iface>>& ifaces, sp<Iface> iface) { 56 iface->invalidate(); 57 ifaces.erase(std::remove(ifaces.begin(), ifaces.end(), iface), 58 ifaces.end()); 59 } 60 61 template <typename Iface> 62 void invalidateAndClearAll(std::vector<sp<Iface>>& ifaces) { 63 for (const auto& iface : ifaces) { 64 iface->invalidate(); 65 } 66 ifaces.clear(); 67 } 68 69 template <typename Iface> 70 std::vector<hidl_string> getNames(std::vector<sp<Iface>>& ifaces) { 71 std::vector<hidl_string> names; 72 for (const auto& iface : ifaces) { 73 names.emplace_back(iface->getName()); 74 } 75 return names; 76 } 77 78 template <typename Iface> 79 sp<Iface> findUsingName(std::vector<sp<Iface>>& ifaces, 80 const std::string& name) { 81 std::vector<hidl_string> names; 82 for (const auto& iface : ifaces) { 83 if (name == iface->getName()) { 84 return iface; 85 } 86 } 87 return nullptr; 88 } 89 90 std::string getWlan0IfaceName() { 91 std::array<char, PROPERTY_VALUE_MAX> buffer; 92 property_get("wifi.interface", buffer.data(), "wlan0"); 93 return buffer.data(); 94 } 95 96 std::string getWlan1IfaceName() { 97 std::array<char, PROPERTY_VALUE_MAX> buffer; 98 property_get("wifi.concurrent.interface", buffer.data(), "wlan1"); 99 return buffer.data(); 100 } 101 102 std::string getP2pIfaceName() { 103 std::array<char, PROPERTY_VALUE_MAX> buffer; 104 property_get("wifi.direct.interface", buffer.data(), "p2p0"); 105 return buffer.data(); 106 } 107 108 // delete files that meet either conditions: 109 // 1. older than a predefined time in the wifi tombstone dir. 110 // 2. Files in excess to a predefined amount, starting from the oldest ones 111 bool removeOldFilesInternal() { 112 time_t now = time(0); 113 const time_t delete_files_before = now - kMaxRingBufferFileAgeSeconds; 114 DIR* dir_dump = opendir(kTombstoneFolderPath); 115 if (!dir_dump) { 116 LOG(ERROR) << "Failed to open directory: " << strerror(errno); 117 return false; 118 } 119 unique_fd dir_auto_closer(dirfd(dir_dump)); 120 struct dirent* dp; 121 bool success = true; 122 std::list<std::pair<const time_t, std::string>> valid_files; 123 while ((dp = readdir(dir_dump))) { 124 if (dp->d_type != DT_REG) { 125 continue; 126 } 127 std::string cur_file_name(dp->d_name); 128 struct stat cur_file_stat; 129 std::string cur_file_path = kTombstoneFolderPath + cur_file_name; 130 if (stat(cur_file_path.c_str(), &cur_file_stat) == -1) { 131 LOG(ERROR) << "Failed to get file stat for " << cur_file_path 132 << ": " << strerror(errno); 133 success = false; 134 continue; 135 } 136 const time_t cur_file_time = cur_file_stat.st_mtime; 137 valid_files.push_back( 138 std::pair<const time_t, std::string>(cur_file_time, cur_file_path)); 139 } 140 valid_files.sort(); // sort the list of files by last modified time from 141 // small to big. 142 uint32_t cur_file_count = valid_files.size(); 143 for (auto cur_file : valid_files) { 144 if (cur_file_count > kMaxRingBufferFileNum || 145 cur_file.first < delete_files_before) { 146 if (unlink(cur_file.second.c_str()) != 0) { 147 LOG(ERROR) << "Error deleting file " << strerror(errno); 148 success = false; 149 } 150 cur_file_count--; 151 } else { 152 break; 153 } 154 } 155 return success; 156 } 157 158 // Helper function for |cpioArchiveFilesInDir| 159 bool cpioWriteHeader(int out_fd, struct stat& st, const char* file_name, 160 size_t file_name_len) { 161 std::array<char, 32 * 1024> read_buf; 162 ssize_t llen = 163 sprintf(read_buf.data(), 164 "%s%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X%08X", 165 kCpioMagic, static_cast<int>(st.st_ino), st.st_mode, st.st_uid, 166 st.st_gid, static_cast<int>(st.st_nlink), 167 static_cast<int>(st.st_mtime), static_cast<int>(st.st_size), 168 major(st.st_dev), minor(st.st_dev), major(st.st_rdev), 169 minor(st.st_rdev), static_cast<uint32_t>(file_name_len), 0); 170 if (write(out_fd, read_buf.data(), llen) == -1) { 171 LOG(ERROR) << "Error writing cpio header to file " << file_name << " " 172 << strerror(errno); 173 return false; 174 } 175 if (write(out_fd, file_name, file_name_len) == -1) { 176 LOG(ERROR) << "Error writing filename to file " << file_name << " " 177 << strerror(errno); 178 return false; 179 } 180 181 // NUL Pad header up to 4 multiple bytes. 182 llen = (llen + file_name_len) % 4; 183 if (llen != 0) { 184 const uint32_t zero = 0; 185 if (write(out_fd, &zero, 4 - llen) == -1) { 186 LOG(ERROR) << "Error padding 0s to file " << file_name << " " 187 << strerror(errno); 188 return false; 189 } 190 } 191 return true; 192 } 193 194 // Helper function for |cpioArchiveFilesInDir| 195 size_t cpioWriteFileContent(int fd_read, int out_fd, struct stat& st) { 196 // writing content of file 197 std::array<char, 32 * 1024> read_buf; 198 ssize_t llen = st.st_size; 199 size_t n_error = 0; 200 while (llen > 0) { 201 ssize_t bytes_read = read(fd_read, read_buf.data(), read_buf.size()); 202 if (bytes_read == -1) { 203 LOG(ERROR) << "Error reading file " << strerror(errno); 204 return ++n_error; 205 } 206 llen -= bytes_read; 207 if (write(out_fd, read_buf.data(), bytes_read) == -1) { 208 LOG(ERROR) << "Error writing data to file " << strerror(errno); 209 return ++n_error; 210 } 211 if (bytes_read == 0) { // this should never happen, but just in case 212 // to unstuck from while loop 213 LOG(ERROR) << "Unexpected read result for " << strerror(errno); 214 n_error++; 215 break; 216 } 217 } 218 llen = st.st_size % 4; 219 if (llen != 0) { 220 const uint32_t zero = 0; 221 if (write(out_fd, &zero, 4 - llen) == -1) { 222 LOG(ERROR) << "Error padding 0s to file " << strerror(errno); 223 return ++n_error; 224 } 225 } 226 return n_error; 227 } 228 229 // Helper function for |cpioArchiveFilesInDir| 230 bool cpioWriteFileTrailer(int out_fd) { 231 std::array<char, 4096> read_buf; 232 read_buf.fill(0); 233 if (write(out_fd, read_buf.data(), 234 sprintf(read_buf.data(), "070701%040X%056X%08XTRAILER!!!", 1, 235 0x0b, 0) + 236 4) == -1) { 237 LOG(ERROR) << "Error writing trailing bytes " << strerror(errno); 238 return false; 239 } 240 return true; 241 } 242 243 // Archives all files in |input_dir| and writes result into |out_fd| 244 // Logic obtained from //external/toybox/toys/posix/cpio.c "Output cpio archive" 245 // portion 246 size_t cpioArchiveFilesInDir(int out_fd, const char* input_dir) { 247 struct dirent* dp; 248 size_t n_error = 0; 249 DIR* dir_dump = opendir(input_dir); 250 if (!dir_dump) { 251 LOG(ERROR) << "Failed to open directory: " << strerror(errno); 252 return ++n_error; 253 } 254 unique_fd dir_auto_closer(dirfd(dir_dump)); 255 while ((dp = readdir(dir_dump))) { 256 if (dp->d_type != DT_REG) { 257 continue; 258 } 259 std::string cur_file_name(dp->d_name); 260 // string.size() does not include the null terminator. The cpio FreeBSD 261 // file header expects the null character to be included in the length. 262 const size_t file_name_len = cur_file_name.size() + 1; 263 struct stat st; 264 const std::string cur_file_path = kTombstoneFolderPath + cur_file_name; 265 if (stat(cur_file_path.c_str(), &st) == -1) { 266 LOG(ERROR) << "Failed to get file stat for " << cur_file_path 267 << ": " << strerror(errno); 268 n_error++; 269 continue; 270 } 271 const int fd_read = open(cur_file_path.c_str(), O_RDONLY); 272 if (fd_read == -1) { 273 LOG(ERROR) << "Failed to open file " << cur_file_path << " " 274 << strerror(errno); 275 n_error++; 276 continue; 277 } 278 unique_fd file_auto_closer(fd_read); 279 if (!cpioWriteHeader(out_fd, st, cur_file_name.c_str(), 280 file_name_len)) { 281 return ++n_error; 282 } 283 size_t write_error = cpioWriteFileContent(fd_read, out_fd, st); 284 if (write_error) { 285 return n_error + write_error; 286 } 287 } 288 if (!cpioWriteFileTrailer(out_fd)) { 289 return ++n_error; 290 } 291 return n_error; 292 } 293 294 // Helper function to create a non-const char*. 295 std::vector<char> makeCharVec(const std::string& str) { 296 std::vector<char> vec(str.size() + 1); 297 vec.assign(str.begin(), str.end()); 298 vec.push_back('\0'); 299 return vec; 300 } 301 302 } // namespace 303 304 namespace android { 305 namespace hardware { 306 namespace wifi { 307 namespace V1_2 { 308 namespace implementation { 309 using hidl_return_util::validateAndCall; 310 using hidl_return_util::validateAndCallWithLock; 311 312 WifiChip::WifiChip( 313 ChipId chip_id, const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal, 314 const std::weak_ptr<mode_controller::WifiModeController> mode_controller, 315 const std::weak_ptr<feature_flags::WifiFeatureFlags> feature_flags) 316 : chip_id_(chip_id), 317 legacy_hal_(legacy_hal), 318 mode_controller_(mode_controller), 319 feature_flags_(feature_flags), 320 is_valid_(true), 321 current_mode_id_(kInvalidModeId), 322 debug_ring_buffer_cb_registered_(false) { 323 populateModes(); 324 } 325 326 void WifiChip::invalidate() { 327 if (!writeRingbufferFilesInternal()) { 328 LOG(ERROR) << "Error writing files to flash"; 329 } 330 invalidateAndRemoveAllIfaces(); 331 legacy_hal_.reset(); 332 event_cb_handler_.invalidate(); 333 is_valid_ = false; 334 } 335 336 bool WifiChip::isValid() { return is_valid_; } 337 338 std::set<sp<IWifiChipEventCallback>> WifiChip::getEventCallbacks() { 339 return event_cb_handler_.getCallbacks(); 340 } 341 342 Return<void> WifiChip::getId(getId_cb hidl_status_cb) { 343 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 344 &WifiChip::getIdInternal, hidl_status_cb); 345 } 346 347 Return<void> WifiChip::registerEventCallback( 348 const sp<V1_0::IWifiChipEventCallback>& event_callback, 349 registerEventCallback_cb hidl_status_cb) { 350 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 351 &WifiChip::registerEventCallbackInternal, 352 hidl_status_cb, event_callback); 353 } 354 355 Return<void> WifiChip::getCapabilities(getCapabilities_cb hidl_status_cb) { 356 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 357 &WifiChip::getCapabilitiesInternal, hidl_status_cb); 358 } 359 360 Return<void> WifiChip::getAvailableModes(getAvailableModes_cb hidl_status_cb) { 361 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 362 &WifiChip::getAvailableModesInternal, 363 hidl_status_cb); 364 } 365 366 Return<void> WifiChip::configureChip(ChipModeId mode_id, 367 configureChip_cb hidl_status_cb) { 368 return validateAndCallWithLock( 369 this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 370 &WifiChip::configureChipInternal, hidl_status_cb, mode_id); 371 } 372 373 Return<void> WifiChip::getMode(getMode_cb hidl_status_cb) { 374 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 375 &WifiChip::getModeInternal, hidl_status_cb); 376 } 377 378 Return<void> WifiChip::requestChipDebugInfo( 379 requestChipDebugInfo_cb hidl_status_cb) { 380 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 381 &WifiChip::requestChipDebugInfoInternal, 382 hidl_status_cb); 383 } 384 385 Return<void> WifiChip::requestDriverDebugDump( 386 requestDriverDebugDump_cb hidl_status_cb) { 387 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 388 &WifiChip::requestDriverDebugDumpInternal, 389 hidl_status_cb); 390 } 391 392 Return<void> WifiChip::requestFirmwareDebugDump( 393 requestFirmwareDebugDump_cb hidl_status_cb) { 394 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 395 &WifiChip::requestFirmwareDebugDumpInternal, 396 hidl_status_cb); 397 } 398 399 Return<void> WifiChip::createApIface(createApIface_cb hidl_status_cb) { 400 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 401 &WifiChip::createApIfaceInternal, hidl_status_cb); 402 } 403 404 Return<void> WifiChip::getApIfaceNames(getApIfaceNames_cb hidl_status_cb) { 405 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 406 &WifiChip::getApIfaceNamesInternal, hidl_status_cb); 407 } 408 409 Return<void> WifiChip::getApIface(const hidl_string& ifname, 410 getApIface_cb hidl_status_cb) { 411 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 412 &WifiChip::getApIfaceInternal, hidl_status_cb, 413 ifname); 414 } 415 416 Return<void> WifiChip::removeApIface(const hidl_string& ifname, 417 removeApIface_cb hidl_status_cb) { 418 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 419 &WifiChip::removeApIfaceInternal, hidl_status_cb, 420 ifname); 421 } 422 423 Return<void> WifiChip::createNanIface(createNanIface_cb hidl_status_cb) { 424 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 425 &WifiChip::createNanIfaceInternal, hidl_status_cb); 426 } 427 428 Return<void> WifiChip::getNanIfaceNames(getNanIfaceNames_cb hidl_status_cb) { 429 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 430 &WifiChip::getNanIfaceNamesInternal, hidl_status_cb); 431 } 432 433 Return<void> WifiChip::getNanIface(const hidl_string& ifname, 434 getNanIface_cb hidl_status_cb) { 435 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 436 &WifiChip::getNanIfaceInternal, hidl_status_cb, 437 ifname); 438 } 439 440 Return<void> WifiChip::removeNanIface(const hidl_string& ifname, 441 removeNanIface_cb hidl_status_cb) { 442 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 443 &WifiChip::removeNanIfaceInternal, hidl_status_cb, 444 ifname); 445 } 446 447 Return<void> WifiChip::createP2pIface(createP2pIface_cb hidl_status_cb) { 448 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 449 &WifiChip::createP2pIfaceInternal, hidl_status_cb); 450 } 451 452 Return<void> WifiChip::getP2pIfaceNames(getP2pIfaceNames_cb hidl_status_cb) { 453 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 454 &WifiChip::getP2pIfaceNamesInternal, hidl_status_cb); 455 } 456 457 Return<void> WifiChip::getP2pIface(const hidl_string& ifname, 458 getP2pIface_cb hidl_status_cb) { 459 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 460 &WifiChip::getP2pIfaceInternal, hidl_status_cb, 461 ifname); 462 } 463 464 Return<void> WifiChip::removeP2pIface(const hidl_string& ifname, 465 removeP2pIface_cb hidl_status_cb) { 466 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 467 &WifiChip::removeP2pIfaceInternal, hidl_status_cb, 468 ifname); 469 } 470 471 Return<void> WifiChip::createStaIface(createStaIface_cb hidl_status_cb) { 472 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 473 &WifiChip::createStaIfaceInternal, hidl_status_cb); 474 } 475 476 Return<void> WifiChip::getStaIfaceNames(getStaIfaceNames_cb hidl_status_cb) { 477 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 478 &WifiChip::getStaIfaceNamesInternal, hidl_status_cb); 479 } 480 481 Return<void> WifiChip::getStaIface(const hidl_string& ifname, 482 getStaIface_cb hidl_status_cb) { 483 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 484 &WifiChip::getStaIfaceInternal, hidl_status_cb, 485 ifname); 486 } 487 488 Return<void> WifiChip::removeStaIface(const hidl_string& ifname, 489 removeStaIface_cb hidl_status_cb) { 490 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 491 &WifiChip::removeStaIfaceInternal, hidl_status_cb, 492 ifname); 493 } 494 495 Return<void> WifiChip::createRttController( 496 const sp<IWifiIface>& bound_iface, createRttController_cb hidl_status_cb) { 497 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 498 &WifiChip::createRttControllerInternal, 499 hidl_status_cb, bound_iface); 500 } 501 502 Return<void> WifiChip::getDebugRingBuffersStatus( 503 getDebugRingBuffersStatus_cb hidl_status_cb) { 504 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 505 &WifiChip::getDebugRingBuffersStatusInternal, 506 hidl_status_cb); 507 } 508 509 Return<void> WifiChip::startLoggingToDebugRingBuffer( 510 const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level, 511 uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes, 512 startLoggingToDebugRingBuffer_cb hidl_status_cb) { 513 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 514 &WifiChip::startLoggingToDebugRingBufferInternal, 515 hidl_status_cb, ring_name, verbose_level, 516 max_interval_in_sec, min_data_size_in_bytes); 517 } 518 519 Return<void> WifiChip::forceDumpToDebugRingBuffer( 520 const hidl_string& ring_name, 521 forceDumpToDebugRingBuffer_cb hidl_status_cb) { 522 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 523 &WifiChip::forceDumpToDebugRingBufferInternal, 524 hidl_status_cb, ring_name); 525 } 526 527 Return<void> WifiChip::stopLoggingToDebugRingBuffer( 528 stopLoggingToDebugRingBuffer_cb hidl_status_cb) { 529 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 530 &WifiChip::stopLoggingToDebugRingBufferInternal, 531 hidl_status_cb); 532 } 533 534 Return<void> WifiChip::getDebugHostWakeReasonStats( 535 getDebugHostWakeReasonStats_cb hidl_status_cb) { 536 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 537 &WifiChip::getDebugHostWakeReasonStatsInternal, 538 hidl_status_cb); 539 } 540 541 Return<void> WifiChip::enableDebugErrorAlerts( 542 bool enable, enableDebugErrorAlerts_cb hidl_status_cb) { 543 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 544 &WifiChip::enableDebugErrorAlertsInternal, 545 hidl_status_cb, enable); 546 } 547 548 Return<void> WifiChip::selectTxPowerScenario( 549 V1_1::IWifiChip::TxPowerScenario scenario, selectTxPowerScenario_cb hidl_status_cb) { 550 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 551 &WifiChip::selectTxPowerScenarioInternal, 552 hidl_status_cb, scenario); 553 } 554 555 Return<void> WifiChip::resetTxPowerScenario( 556 resetTxPowerScenario_cb hidl_status_cb) { 557 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 558 &WifiChip::resetTxPowerScenarioInternal, 559 hidl_status_cb); 560 } 561 562 Return<void> WifiChip::registerEventCallback_1_2( 563 const sp<IWifiChipEventCallback>& event_callback, 564 registerEventCallback_cb hidl_status_cb) { 565 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 566 &WifiChip::registerEventCallbackInternal_1_2, 567 hidl_status_cb, event_callback); 568 } 569 570 Return<void> WifiChip::selectTxPowerScenario_1_2( 571 TxPowerScenario scenario, selectTxPowerScenario_cb hidl_status_cb) { 572 return validateAndCall(this, WifiStatusCode::ERROR_WIFI_CHIP_INVALID, 573 &WifiChip::selectTxPowerScenarioInternal_1_2, hidl_status_cb, scenario); 574 } 575 576 Return<void> WifiChip::debug(const hidl_handle& handle, 577 const hidl_vec<hidl_string>&) { 578 if (handle != nullptr && handle->numFds >= 1) { 579 int fd = handle->data[0]; 580 if (!writeRingbufferFilesInternal()) { 581 LOG(ERROR) << "Error writing files to flash"; 582 } 583 uint32_t n_error = cpioArchiveFilesInDir(fd, kTombstoneFolderPath); 584 if (n_error != 0) { 585 LOG(ERROR) << n_error << " errors occured in cpio function"; 586 } 587 fsync(fd); 588 } else { 589 LOG(ERROR) << "File handle error"; 590 } 591 return Void(); 592 } 593 594 void WifiChip::invalidateAndRemoveAllIfaces() { 595 invalidateAndClearAll(ap_ifaces_); 596 invalidateAndClearAll(nan_ifaces_); 597 invalidateAndClearAll(p2p_ifaces_); 598 invalidateAndClearAll(sta_ifaces_); 599 // Since all the ifaces are invalid now, all RTT controller objects 600 // using those ifaces also need to be invalidated. 601 for (const auto& rtt : rtt_controllers_) { 602 rtt->invalidate(); 603 } 604 rtt_controllers_.clear(); 605 } 606 607 std::pair<WifiStatus, ChipId> WifiChip::getIdInternal() { 608 return {createWifiStatus(WifiStatusCode::SUCCESS), chip_id_}; 609 } 610 611 WifiStatus WifiChip::registerEventCallbackInternal( 612 const sp<V1_0::IWifiChipEventCallback>& /* event_callback */) { 613 // Deprecated support for this callback. 614 return createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED); 615 } 616 617 std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal() { 618 legacy_hal::wifi_error legacy_status; 619 uint32_t legacy_feature_set; 620 uint32_t legacy_logger_feature_set; 621 std::tie(legacy_status, legacy_feature_set) = 622 legacy_hal_.lock()->getSupportedFeatureSet(getWlan0IfaceName()); 623 if (legacy_status != legacy_hal::WIFI_SUCCESS) { 624 return {createWifiStatusFromLegacyError(legacy_status), 0}; 625 } 626 std::tie(legacy_status, legacy_logger_feature_set) = 627 legacy_hal_.lock()->getLoggerSupportedFeatureSet(getWlan0IfaceName()); 628 if (legacy_status != legacy_hal::WIFI_SUCCESS) { 629 // some devices don't support querying logger feature set 630 legacy_logger_feature_set = 0; 631 } 632 uint32_t hidl_caps; 633 if (!hidl_struct_util::convertLegacyFeaturesToHidlChipCapabilities( 634 legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) { 635 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0}; 636 } 637 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps}; 638 } 639 640 std::pair<WifiStatus, std::vector<IWifiChip::ChipMode>> 641 WifiChip::getAvailableModesInternal() { 642 return {createWifiStatus(WifiStatusCode::SUCCESS), modes_}; 643 } 644 645 WifiStatus WifiChip::configureChipInternal( 646 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, 647 ChipModeId mode_id) { 648 if (!isValidModeId(mode_id)) { 649 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); 650 } 651 if (mode_id == current_mode_id_) { 652 LOG(DEBUG) << "Already in the specified mode " << mode_id; 653 return createWifiStatus(WifiStatusCode::SUCCESS); 654 } 655 WifiStatus status = handleChipConfiguration(lock, mode_id); 656 if (status.code != WifiStatusCode::SUCCESS) { 657 for (const auto& callback : event_cb_handler_.getCallbacks()) { 658 if (!callback->onChipReconfigureFailure(status).isOk()) { 659 LOG(ERROR) 660 << "Failed to invoke onChipReconfigureFailure callback"; 661 } 662 } 663 return status; 664 } 665 for (const auto& callback : event_cb_handler_.getCallbacks()) { 666 if (!callback->onChipReconfigured(mode_id).isOk()) { 667 LOG(ERROR) << "Failed to invoke onChipReconfigured callback"; 668 } 669 } 670 current_mode_id_ = mode_id; 671 LOG(INFO) << "Configured chip in mode " << mode_id; 672 return status; 673 } 674 675 std::pair<WifiStatus, uint32_t> WifiChip::getModeInternal() { 676 if (!isValidModeId(current_mode_id_)) { 677 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), 678 current_mode_id_}; 679 } 680 return {createWifiStatus(WifiStatusCode::SUCCESS), current_mode_id_}; 681 } 682 683 std::pair<WifiStatus, IWifiChip::ChipDebugInfo> 684 WifiChip::requestChipDebugInfoInternal() { 685 IWifiChip::ChipDebugInfo result; 686 legacy_hal::wifi_error legacy_status; 687 std::string driver_desc; 688 std::tie(legacy_status, driver_desc) = 689 legacy_hal_.lock()->getDriverVersion(getWlan0IfaceName()); 690 if (legacy_status != legacy_hal::WIFI_SUCCESS) { 691 LOG(ERROR) << "Failed to get driver version: " 692 << legacyErrorToString(legacy_status); 693 WifiStatus status = createWifiStatusFromLegacyError( 694 legacy_status, "failed to get driver version"); 695 return {status, result}; 696 } 697 result.driverDescription = driver_desc.c_str(); 698 699 std::string firmware_desc; 700 std::tie(legacy_status, firmware_desc) = 701 legacy_hal_.lock()->getFirmwareVersion(getWlan0IfaceName()); 702 if (legacy_status != legacy_hal::WIFI_SUCCESS) { 703 LOG(ERROR) << "Failed to get firmware version: " 704 << legacyErrorToString(legacy_status); 705 WifiStatus status = createWifiStatusFromLegacyError( 706 legacy_status, "failed to get firmware version"); 707 return {status, result}; 708 } 709 result.firmwareDescription = firmware_desc.c_str(); 710 711 return {createWifiStatus(WifiStatusCode::SUCCESS), result}; 712 } 713 714 std::pair<WifiStatus, std::vector<uint8_t>> 715 WifiChip::requestDriverDebugDumpInternal() { 716 legacy_hal::wifi_error legacy_status; 717 std::vector<uint8_t> driver_dump; 718 std::tie(legacy_status, driver_dump) = 719 legacy_hal_.lock()->requestDriverMemoryDump(getWlan0IfaceName()); 720 if (legacy_status != legacy_hal::WIFI_SUCCESS) { 721 LOG(ERROR) << "Failed to get driver debug dump: " 722 << legacyErrorToString(legacy_status); 723 return {createWifiStatusFromLegacyError(legacy_status), 724 std::vector<uint8_t>()}; 725 } 726 return {createWifiStatus(WifiStatusCode::SUCCESS), driver_dump}; 727 } 728 729 std::pair<WifiStatus, std::vector<uint8_t>> 730 WifiChip::requestFirmwareDebugDumpInternal() { 731 legacy_hal::wifi_error legacy_status; 732 std::vector<uint8_t> firmware_dump; 733 std::tie(legacy_status, firmware_dump) = 734 legacy_hal_.lock()->requestFirmwareMemoryDump(getWlan0IfaceName()); 735 if (legacy_status != legacy_hal::WIFI_SUCCESS) { 736 LOG(ERROR) << "Failed to get firmware debug dump: " 737 << legacyErrorToString(legacy_status); 738 return {createWifiStatusFromLegacyError(legacy_status), {}}; 739 } 740 return {createWifiStatus(WifiStatusCode::SUCCESS), firmware_dump}; 741 } 742 743 std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::createApIfaceInternal() { 744 if (!canCurrentModeSupportIfaceOfType(IfaceType::AP)) { 745 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; 746 } 747 std::string ifname = allocateApOrStaIfaceName(); 748 sp<WifiApIface> iface = new WifiApIface(ifname, legacy_hal_); 749 ap_ifaces_.push_back(iface); 750 for (const auto& callback : event_cb_handler_.getCallbacks()) { 751 if (!callback->onIfaceAdded(IfaceType::AP, ifname).isOk()) { 752 LOG(ERROR) << "Failed to invoke onIfaceAdded callback"; 753 } 754 } 755 return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; 756 } 757 758 std::pair<WifiStatus, std::vector<hidl_string>> 759 WifiChip::getApIfaceNamesInternal() { 760 if (ap_ifaces_.empty()) { 761 return {createWifiStatus(WifiStatusCode::SUCCESS), {}}; 762 } 763 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(ap_ifaces_)}; 764 } 765 766 std::pair<WifiStatus, sp<IWifiApIface>> WifiChip::getApIfaceInternal( 767 const std::string& ifname) { 768 const auto iface = findUsingName(ap_ifaces_, ifname); 769 if (!iface.get()) { 770 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr}; 771 } 772 return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; 773 } 774 775 WifiStatus WifiChip::removeApIfaceInternal(const std::string& ifname) { 776 const auto iface = findUsingName(ap_ifaces_, ifname); 777 if (!iface.get()) { 778 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); 779 } 780 invalidateAndClear(ap_ifaces_, iface); 781 for (const auto& callback : event_cb_handler_.getCallbacks()) { 782 if (!callback->onIfaceRemoved(IfaceType::AP, ifname).isOk()) { 783 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback"; 784 } 785 } 786 return createWifiStatus(WifiStatusCode::SUCCESS); 787 } 788 789 std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::createNanIfaceInternal() { 790 if (!canCurrentModeSupportIfaceOfType(IfaceType::NAN)) { 791 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; 792 } 793 // These are still assumed to be based on wlan0. 794 std::string ifname = getWlan0IfaceName(); 795 sp<WifiNanIface> iface = new WifiNanIface(ifname, legacy_hal_); 796 nan_ifaces_.push_back(iface); 797 for (const auto& callback : event_cb_handler_.getCallbacks()) { 798 if (!callback->onIfaceAdded(IfaceType::NAN, ifname).isOk()) { 799 LOG(ERROR) << "Failed to invoke onIfaceAdded callback"; 800 } 801 } 802 return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; 803 } 804 805 std::pair<WifiStatus, std::vector<hidl_string>> 806 WifiChip::getNanIfaceNamesInternal() { 807 if (nan_ifaces_.empty()) { 808 return {createWifiStatus(WifiStatusCode::SUCCESS), {}}; 809 } 810 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(nan_ifaces_)}; 811 } 812 813 std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::getNanIfaceInternal( 814 const std::string& ifname) { 815 const auto iface = findUsingName(nan_ifaces_, ifname); 816 if (!iface.get()) { 817 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr}; 818 } 819 return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; 820 } 821 822 WifiStatus WifiChip::removeNanIfaceInternal(const std::string& ifname) { 823 const auto iface = findUsingName(nan_ifaces_, ifname); 824 if (!iface.get()) { 825 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); 826 } 827 invalidateAndClear(nan_ifaces_, iface); 828 for (const auto& callback : event_cb_handler_.getCallbacks()) { 829 if (!callback->onIfaceRemoved(IfaceType::NAN, ifname).isOk()) { 830 LOG(ERROR) << "Failed to invoke onIfaceAdded callback"; 831 } 832 } 833 return createWifiStatus(WifiStatusCode::SUCCESS); 834 } 835 836 std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::createP2pIfaceInternal() { 837 if (!canCurrentModeSupportIfaceOfType(IfaceType::P2P)) { 838 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; 839 } 840 std::string ifname = getP2pIfaceName(); 841 sp<WifiP2pIface> iface = new WifiP2pIface(ifname, legacy_hal_); 842 p2p_ifaces_.push_back(iface); 843 for (const auto& callback : event_cb_handler_.getCallbacks()) { 844 if (!callback->onIfaceAdded(IfaceType::P2P, ifname).isOk()) { 845 LOG(ERROR) << "Failed to invoke onIfaceAdded callback"; 846 } 847 } 848 return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; 849 } 850 851 std::pair<WifiStatus, std::vector<hidl_string>> 852 WifiChip::getP2pIfaceNamesInternal() { 853 if (p2p_ifaces_.empty()) { 854 return {createWifiStatus(WifiStatusCode::SUCCESS), {}}; 855 } 856 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(p2p_ifaces_)}; 857 } 858 859 std::pair<WifiStatus, sp<IWifiP2pIface>> WifiChip::getP2pIfaceInternal( 860 const std::string& ifname) { 861 const auto iface = findUsingName(p2p_ifaces_, ifname); 862 if (!iface.get()) { 863 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr}; 864 } 865 return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; 866 } 867 868 WifiStatus WifiChip::removeP2pIfaceInternal(const std::string& ifname) { 869 const auto iface = findUsingName(p2p_ifaces_, ifname); 870 if (!iface.get()) { 871 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); 872 } 873 invalidateAndClear(p2p_ifaces_, iface); 874 for (const auto& callback : event_cb_handler_.getCallbacks()) { 875 if (!callback->onIfaceRemoved(IfaceType::P2P, ifname).isOk()) { 876 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback"; 877 } 878 } 879 return createWifiStatus(WifiStatusCode::SUCCESS); 880 } 881 882 std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::createStaIfaceInternal() { 883 if (!canCurrentModeSupportIfaceOfType(IfaceType::STA)) { 884 return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}}; 885 } 886 std::string ifname = allocateApOrStaIfaceName(); 887 sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_); 888 sta_ifaces_.push_back(iface); 889 for (const auto& callback : event_cb_handler_.getCallbacks()) { 890 if (!callback->onIfaceAdded(IfaceType::STA, ifname).isOk()) { 891 LOG(ERROR) << "Failed to invoke onIfaceAdded callback"; 892 } 893 } 894 return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; 895 } 896 897 std::pair<WifiStatus, std::vector<hidl_string>> 898 WifiChip::getStaIfaceNamesInternal() { 899 if (sta_ifaces_.empty()) { 900 return {createWifiStatus(WifiStatusCode::SUCCESS), {}}; 901 } 902 return {createWifiStatus(WifiStatusCode::SUCCESS), getNames(sta_ifaces_)}; 903 } 904 905 std::pair<WifiStatus, sp<IWifiStaIface>> WifiChip::getStaIfaceInternal( 906 const std::string& ifname) { 907 const auto iface = findUsingName(sta_ifaces_, ifname); 908 if (!iface.get()) { 909 return {createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS), nullptr}; 910 } 911 return {createWifiStatus(WifiStatusCode::SUCCESS), iface}; 912 } 913 914 WifiStatus WifiChip::removeStaIfaceInternal(const std::string& ifname) { 915 const auto iface = findUsingName(sta_ifaces_, ifname); 916 if (!iface.get()) { 917 return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS); 918 } 919 invalidateAndClear(sta_ifaces_, iface); 920 for (const auto& callback : event_cb_handler_.getCallbacks()) { 921 if (!callback->onIfaceRemoved(IfaceType::STA, ifname).isOk()) { 922 LOG(ERROR) << "Failed to invoke onIfaceRemoved callback"; 923 } 924 } 925 return createWifiStatus(WifiStatusCode::SUCCESS); 926 } 927 928 std::pair<WifiStatus, sp<IWifiRttController>> 929 WifiChip::createRttControllerInternal(const sp<IWifiIface>& bound_iface) { 930 sp<WifiRttController> rtt = 931 new WifiRttController(getWlan0IfaceName(), bound_iface, legacy_hal_); 932 rtt_controllers_.emplace_back(rtt); 933 return {createWifiStatus(WifiStatusCode::SUCCESS), rtt}; 934 } 935 936 std::pair<WifiStatus, std::vector<WifiDebugRingBufferStatus>> 937 WifiChip::getDebugRingBuffersStatusInternal() { 938 legacy_hal::wifi_error legacy_status; 939 std::vector<legacy_hal::wifi_ring_buffer_status> 940 legacy_ring_buffer_status_vec; 941 std::tie(legacy_status, legacy_ring_buffer_status_vec) = 942 legacy_hal_.lock()->getRingBuffersStatus(getWlan0IfaceName()); 943 if (legacy_status != legacy_hal::WIFI_SUCCESS) { 944 return {createWifiStatusFromLegacyError(legacy_status), {}}; 945 } 946 std::vector<WifiDebugRingBufferStatus> hidl_ring_buffer_status_vec; 947 if (!hidl_struct_util::convertLegacyVectorOfDebugRingBufferStatusToHidl( 948 legacy_ring_buffer_status_vec, &hidl_ring_buffer_status_vec)) { 949 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; 950 } 951 return {createWifiStatus(WifiStatusCode::SUCCESS), 952 hidl_ring_buffer_status_vec}; 953 } 954 955 WifiStatus WifiChip::startLoggingToDebugRingBufferInternal( 956 const hidl_string& ring_name, WifiDebugRingBufferVerboseLevel verbose_level, 957 uint32_t max_interval_in_sec, uint32_t min_data_size_in_bytes) { 958 WifiStatus status = registerDebugRingBufferCallback(); 959 if (status.code != WifiStatusCode::SUCCESS) { 960 return status; 961 } 962 legacy_hal::wifi_error legacy_status = 963 legacy_hal_.lock()->startRingBufferLogging( 964 getWlan0IfaceName(), ring_name, 965 static_cast< 966 std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>( 967 verbose_level), 968 max_interval_in_sec, min_data_size_in_bytes); 969 ringbuffer_map_.insert(std::pair<std::string, Ringbuffer>( 970 ring_name, Ringbuffer(kMaxBufferSizeBytes))); 971 return createWifiStatusFromLegacyError(legacy_status); 972 } 973 974 WifiStatus WifiChip::forceDumpToDebugRingBufferInternal( 975 const hidl_string& ring_name) { 976 WifiStatus status = registerDebugRingBufferCallback(); 977 if (status.code != WifiStatusCode::SUCCESS) { 978 return status; 979 } 980 legacy_hal::wifi_error legacy_status = 981 legacy_hal_.lock()->getRingBufferData(getWlan0IfaceName(), ring_name); 982 983 return createWifiStatusFromLegacyError(legacy_status); 984 } 985 986 WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() { 987 legacy_hal::wifi_error legacy_status = 988 legacy_hal_.lock()->deregisterRingBufferCallbackHandler( 989 getWlan0IfaceName()); 990 return createWifiStatusFromLegacyError(legacy_status); 991 } 992 993 std::pair<WifiStatus, WifiDebugHostWakeReasonStats> 994 WifiChip::getDebugHostWakeReasonStatsInternal() { 995 legacy_hal::wifi_error legacy_status; 996 legacy_hal::WakeReasonStats legacy_stats; 997 std::tie(legacy_status, legacy_stats) = 998 legacy_hal_.lock()->getWakeReasonStats(getWlan0IfaceName()); 999 if (legacy_status != legacy_hal::WIFI_SUCCESS) { 1000 return {createWifiStatusFromLegacyError(legacy_status), {}}; 1001 } 1002 WifiDebugHostWakeReasonStats hidl_stats; 1003 if (!hidl_struct_util::convertLegacyWakeReasonStatsToHidl(legacy_stats, 1004 &hidl_stats)) { 1005 return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}}; 1006 } 1007 return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats}; 1008 } 1009 1010 WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) { 1011 legacy_hal::wifi_error legacy_status; 1012 if (enable) { 1013 android::wp<WifiChip> weak_ptr_this(this); 1014 const auto& on_alert_callback = [weak_ptr_this]( 1015 int32_t error_code, 1016 std::vector<uint8_t> debug_data) { 1017 const auto shared_ptr_this = weak_ptr_this.promote(); 1018 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { 1019 LOG(ERROR) << "Callback invoked on an invalid object"; 1020 return; 1021 } 1022 for (const auto& callback : shared_ptr_this->getEventCallbacks()) { 1023 if (!callback->onDebugErrorAlert(error_code, debug_data) 1024 .isOk()) { 1025 LOG(ERROR) << "Failed to invoke onDebugErrorAlert callback"; 1026 } 1027 } 1028 }; 1029 legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler( 1030 getWlan0IfaceName(), on_alert_callback); 1031 } else { 1032 legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler( 1033 getWlan0IfaceName()); 1034 } 1035 return createWifiStatusFromLegacyError(legacy_status); 1036 } 1037 1038 WifiStatus WifiChip::selectTxPowerScenarioInternal( 1039 V1_1::IWifiChip::TxPowerScenario scenario) { 1040 auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario( 1041 getWlan0IfaceName(), 1042 hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario)); 1043 return createWifiStatusFromLegacyError(legacy_status); 1044 } 1045 1046 WifiStatus WifiChip::resetTxPowerScenarioInternal() { 1047 auto legacy_status = 1048 legacy_hal_.lock()->resetTxPowerScenario(getWlan0IfaceName()); 1049 return createWifiStatusFromLegacyError(legacy_status); 1050 } 1051 1052 WifiStatus WifiChip::registerEventCallbackInternal_1_2( 1053 const sp<IWifiChipEventCallback>& event_callback) { 1054 if (!event_cb_handler_.addCallback(event_callback)) { 1055 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); 1056 } 1057 return createWifiStatus(WifiStatusCode::SUCCESS); 1058 } 1059 1060 WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2(TxPowerScenario scenario) { 1061 auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario( 1062 getWlan0IfaceName(), 1063 hidl_struct_util::convertHidlTxPowerScenarioToLegacy_1_2(scenario)); 1064 return createWifiStatusFromLegacyError(legacy_status); 1065 } 1066 1067 WifiStatus WifiChip::handleChipConfiguration( 1068 /* NONNULL */ std::unique_lock<std::recursive_mutex>* lock, 1069 ChipModeId mode_id) { 1070 // If the chip is already configured in a different mode, stop 1071 // the legacy HAL and then start it after firmware mode change. 1072 if (isValidModeId(current_mode_id_)) { 1073 LOG(INFO) << "Reconfiguring chip from mode " << current_mode_id_ 1074 << " to mode " << mode_id; 1075 invalidateAndRemoveAllIfaces(); 1076 legacy_hal::wifi_error legacy_status = 1077 legacy_hal_.lock()->stop(lock, []() {}); 1078 if (legacy_status != legacy_hal::WIFI_SUCCESS) { 1079 LOG(ERROR) << "Failed to stop legacy HAL: " 1080 << legacyErrorToString(legacy_status); 1081 return createWifiStatusFromLegacyError(legacy_status); 1082 } 1083 } 1084 // Firmware mode change not needed for V2 devices. 1085 bool success = true; 1086 if (mode_id == kV1StaChipModeId) { 1087 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::STA); 1088 } else if (mode_id == kV1ApChipModeId) { 1089 success = mode_controller_.lock()->changeFirmwareMode(IfaceType::AP); 1090 } 1091 if (!success) { 1092 return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN); 1093 } 1094 legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->start(); 1095 if (legacy_status != legacy_hal::WIFI_SUCCESS) { 1096 LOG(ERROR) << "Failed to start legacy HAL: " 1097 << legacyErrorToString(legacy_status); 1098 return createWifiStatusFromLegacyError(legacy_status); 1099 } 1100 // Every time the HAL is restarted, we need to register the 1101 // radio mode change callback. 1102 WifiStatus status = registerRadioModeChangeCallback(); 1103 if (status.code != WifiStatusCode::SUCCESS) { 1104 // This probably is not a critical failure? 1105 LOG(ERROR) << "Failed to register radio mode change callback"; 1106 } 1107 return createWifiStatus(WifiStatusCode::SUCCESS); 1108 } 1109 1110 WifiStatus WifiChip::registerDebugRingBufferCallback() { 1111 if (debug_ring_buffer_cb_registered_) { 1112 return createWifiStatus(WifiStatusCode::SUCCESS); 1113 } 1114 1115 android::wp<WifiChip> weak_ptr_this(this); 1116 const auto& on_ring_buffer_data_callback = 1117 [weak_ptr_this](const std::string& name, 1118 const std::vector<uint8_t>& data, 1119 const legacy_hal::wifi_ring_buffer_status& status) { 1120 const auto shared_ptr_this = weak_ptr_this.promote(); 1121 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { 1122 LOG(ERROR) << "Callback invoked on an invalid object"; 1123 return; 1124 } 1125 WifiDebugRingBufferStatus hidl_status; 1126 if (!hidl_struct_util::convertLegacyDebugRingBufferStatusToHidl( 1127 status, &hidl_status)) { 1128 LOG(ERROR) << "Error converting ring buffer status"; 1129 return; 1130 } 1131 const auto& target = shared_ptr_this->ringbuffer_map_.find(name); 1132 if (target != shared_ptr_this->ringbuffer_map_.end()) { 1133 Ringbuffer& cur_buffer = target->second; 1134 cur_buffer.append(data); 1135 } else { 1136 LOG(ERROR) << "Ringname " << name << " not found"; 1137 return; 1138 } 1139 }; 1140 legacy_hal::wifi_error legacy_status = 1141 legacy_hal_.lock()->registerRingBufferCallbackHandler( 1142 getWlan0IfaceName(), on_ring_buffer_data_callback); 1143 1144 if (legacy_status == legacy_hal::WIFI_SUCCESS) { 1145 debug_ring_buffer_cb_registered_ = true; 1146 } 1147 return createWifiStatusFromLegacyError(legacy_status); 1148 } 1149 1150 WifiStatus WifiChip::registerRadioModeChangeCallback() { 1151 android::wp<WifiChip> weak_ptr_this(this); 1152 const auto& on_radio_mode_change_callback = 1153 [weak_ptr_this](const std::vector<legacy_hal::WifiMacInfo>& mac_infos) { 1154 const auto shared_ptr_this = weak_ptr_this.promote(); 1155 if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) { 1156 LOG(ERROR) << "Callback invoked on an invalid object"; 1157 return; 1158 } 1159 std::vector<IWifiChipEventCallback::RadioModeInfo> 1160 hidl_radio_mode_infos; 1161 if (!hidl_struct_util::convertLegacyWifiMacInfosToHidl( 1162 mac_infos, &hidl_radio_mode_infos)) { 1163 LOG(ERROR) << "Error converting wifi mac info"; 1164 return; 1165 } 1166 for (const auto& callback : shared_ptr_this->getEventCallbacks()) { 1167 if (!callback->onRadioModeChange(hidl_radio_mode_infos) 1168 .isOk()) { 1169 LOG(ERROR) << "Failed to invoke onRadioModeChange" 1170 << " callback on: " << toString(callback); 1171 } 1172 } 1173 }; 1174 legacy_hal::wifi_error legacy_status = 1175 legacy_hal_.lock()->registerRadioModeChangeCallbackHandler( 1176 getWlan0IfaceName(), on_radio_mode_change_callback); 1177 return createWifiStatusFromLegacyError(legacy_status); 1178 } 1179 1180 void WifiChip::populateModes() { 1181 // The chip combination supported for current devices is fixed. 1182 // They can be one of the following based on device features: 1183 // a) 2 separate modes of operation with 1 interface combination each: 1184 // Mode 1 (STA mode): Will support 1 STA and 1 P2P or NAN(optional) 1185 // concurrent iface operations. 1186 // Mode 2 (AP mode): Will support 1 AP iface operation. 1187 // 1188 // b) 1 mode of operation with 2 interface combinations 1189 // (conditional on isDualInterfaceSupported()): 1190 // Interface Combination 1: Will support 1 STA and 1 P2P or NAN(optional) 1191 // concurrent iface operations. 1192 // Interface Combination 2: Will support 1 STA and 1 AP concurrent 1193 // iface operations. 1194 // If Aware is enabled (conditional on isAwareSupported()), the iface 1195 // combination will be modified to support either P2P or NAN in place of 1196 // just P2P. 1197 if (feature_flags_.lock()->isDualInterfaceSupported()) { 1198 // V2 Iface combinations for Mode Id = 2. 1199 const IWifiChip::ChipIfaceCombinationLimit 1200 chip_iface_combination_limit_1 = {{IfaceType::STA}, 1}; 1201 const IWifiChip::ChipIfaceCombinationLimit 1202 chip_iface_combination_limit_2 = {{IfaceType::AP}, 1}; 1203 IWifiChip::ChipIfaceCombinationLimit chip_iface_combination_limit_3; 1204 if (feature_flags_.lock()->isAwareSupported()) { 1205 chip_iface_combination_limit_3 = {{IfaceType::P2P, IfaceType::NAN}, 1206 1}; 1207 } else { 1208 chip_iface_combination_limit_3 = {{IfaceType::P2P}, 1}; 1209 } 1210 const IWifiChip::ChipIfaceCombination chip_iface_combination_1 = { 1211 {chip_iface_combination_limit_1, chip_iface_combination_limit_2}}; 1212 const IWifiChip::ChipIfaceCombination chip_iface_combination_2 = { 1213 {chip_iface_combination_limit_1, chip_iface_combination_limit_3}}; 1214 if (feature_flags_.lock()->isApDisabled()) { 1215 const IWifiChip::ChipMode chip_mode = { 1216 kV2ChipModeId, 1217 {chip_iface_combination_2}}; 1218 modes_ = {chip_mode}; 1219 } else { 1220 const IWifiChip::ChipMode chip_mode = { 1221 kV2ChipModeId, 1222 {chip_iface_combination_1, chip_iface_combination_2}}; 1223 modes_ = {chip_mode}; 1224 } 1225 } else { 1226 // V1 Iface combinations for Mode Id = 0. (STA Mode) 1227 const IWifiChip::ChipIfaceCombinationLimit 1228 sta_chip_iface_combination_limit_1 = {{IfaceType::STA}, 1}; 1229 IWifiChip::ChipIfaceCombinationLimit sta_chip_iface_combination_limit_2; 1230 if (feature_flags_.lock()->isAwareSupported()) { 1231 sta_chip_iface_combination_limit_2 = { 1232 {IfaceType::P2P, IfaceType::NAN}, 1}; 1233 } else { 1234 sta_chip_iface_combination_limit_2 = {{IfaceType::P2P}, 1}; 1235 } 1236 const IWifiChip::ChipIfaceCombination sta_chip_iface_combination = { 1237 {sta_chip_iface_combination_limit_1, 1238 sta_chip_iface_combination_limit_2}}; 1239 const IWifiChip::ChipMode sta_chip_mode = { 1240 kV1StaChipModeId, {sta_chip_iface_combination}}; 1241 // Iface combinations for Mode Id = 1. (AP Mode) 1242 const IWifiChip::ChipIfaceCombinationLimit 1243 ap_chip_iface_combination_limit = {{IfaceType::AP}, 1}; 1244 const IWifiChip::ChipIfaceCombination ap_chip_iface_combination = { 1245 {ap_chip_iface_combination_limit}}; 1246 const IWifiChip::ChipMode ap_chip_mode = {kV1ApChipModeId, 1247 {ap_chip_iface_combination}}; 1248 if (feature_flags_.lock()->isApDisabled()) { 1249 modes_ = {sta_chip_mode}; 1250 } else { 1251 modes_ = {sta_chip_mode, ap_chip_mode}; 1252 } 1253 } 1254 } 1255 1256 std::vector<IWifiChip::ChipIfaceCombination> 1257 WifiChip::getCurrentModeIfaceCombinations() { 1258 if (!isValidModeId(current_mode_id_)) { 1259 LOG(ERROR) << "Chip not configured in a mode yet"; 1260 return {}; 1261 } 1262 for (const auto& mode : modes_) { 1263 if (mode.id == current_mode_id_) { 1264 return mode.availableCombinations; 1265 } 1266 } 1267 CHECK(0) << "Expected to find iface combinations for current mode!"; 1268 return {}; 1269 } 1270 1271 // Returns a map indexed by IfaceType with the number of ifaces currently 1272 // created of the corresponding type. 1273 std::map<IfaceType, size_t> WifiChip::getCurrentIfaceCombination() { 1274 std::map<IfaceType, size_t> iface_counts; 1275 iface_counts[IfaceType::AP] = ap_ifaces_.size(); 1276 iface_counts[IfaceType::NAN] = nan_ifaces_.size(); 1277 iface_counts[IfaceType::P2P] = p2p_ifaces_.size(); 1278 iface_counts[IfaceType::STA] = sta_ifaces_.size(); 1279 return iface_counts; 1280 } 1281 1282 // This expands the provided iface combinations to a more parseable 1283 // form. Returns a vector of available combinations possible with the number 1284 // of ifaces of each type in the combination. 1285 // This method is a port of HalDeviceManager.expandIfaceCombos() from framework. 1286 std::vector<std::map<IfaceType, size_t>> WifiChip::expandIfaceCombinations( 1287 const IWifiChip::ChipIfaceCombination& combination) { 1288 uint32_t num_expanded_combos = 1; 1289 for (const auto& limit : combination.limits) { 1290 for (uint32_t i = 0; i < limit.maxIfaces; i++) { 1291 num_expanded_combos *= limit.types.size(); 1292 } 1293 } 1294 1295 // Allocate the vector of expanded combos and reset all iface counts to 0 1296 // in each combo. 1297 std::vector<std::map<IfaceType, size_t>> expanded_combos; 1298 expanded_combos.resize(num_expanded_combos); 1299 for (auto& expanded_combo : expanded_combos) { 1300 for (const auto type : 1301 {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) { 1302 expanded_combo[type] = 0; 1303 } 1304 } 1305 uint32_t span = num_expanded_combos; 1306 for (const auto& limit : combination.limits) { 1307 for (uint32_t i = 0; i < limit.maxIfaces; i++) { 1308 span /= limit.types.size(); 1309 for (uint32_t k = 0; k < num_expanded_combos; ++k) { 1310 const auto iface_type = 1311 limit.types[(k / span) % limit.types.size()]; 1312 expanded_combos[k][iface_type]++; 1313 } 1314 } 1315 } 1316 return expanded_combos; 1317 } 1318 1319 bool WifiChip::canExpandedIfaceCombinationSupportIfaceOfType( 1320 const std::map<IfaceType, size_t>& combo, IfaceType requested_type) { 1321 const auto current_combo = getCurrentIfaceCombination(); 1322 1323 // Check if we have space for 1 more iface of |type| in this combo 1324 for (const auto type : 1325 {IfaceType::AP, IfaceType::NAN, IfaceType::P2P, IfaceType::STA}) { 1326 size_t num_ifaces_needed = current_combo.at(type); 1327 if (type == requested_type) { 1328 num_ifaces_needed++; 1329 } 1330 size_t num_ifaces_allowed = combo.at(type); 1331 if (num_ifaces_needed > num_ifaces_allowed) { 1332 return false; 1333 } 1334 } 1335 return true; 1336 } 1337 1338 // This method does the following: 1339 // a) Enumerate all possible iface combos by expanding the current 1340 // ChipIfaceCombination. 1341 // b) Check if the requested iface type can be added to the current mode. 1342 bool WifiChip::canCurrentModeSupportIfaceOfType(IfaceType type) { 1343 if (!isValidModeId(current_mode_id_)) { 1344 LOG(ERROR) << "Chip not configured in a mode yet"; 1345 return false; 1346 } 1347 const auto combinations = getCurrentModeIfaceCombinations(); 1348 for (const auto& combination : combinations) { 1349 const auto expanded_combos = expandIfaceCombinations(combination); 1350 for (const auto& expanded_combo : expanded_combos) { 1351 if (canExpandedIfaceCombinationSupportIfaceOfType(expanded_combo, 1352 type)) { 1353 return true; 1354 } 1355 } 1356 } 1357 return false; 1358 } 1359 1360 bool WifiChip::isValidModeId(ChipModeId mode_id) { 1361 for (const auto& mode : modes_) { 1362 if (mode.id == mode_id) { 1363 return true; 1364 } 1365 } 1366 return false; 1367 } 1368 1369 // Return "wlan0", if "wlan0" is not already in use, else return "wlan1". 1370 // This is based on the assumption that we'll have a max of 2 concurrent 1371 // AP/STA ifaces. 1372 std::string WifiChip::allocateApOrStaIfaceName() { 1373 auto ap_iface = findUsingName(ap_ifaces_, getWlan0IfaceName()); 1374 auto sta_iface = findUsingName(sta_ifaces_, getWlan0IfaceName()); 1375 if (!ap_iface.get() && !sta_iface.get()) { 1376 return getWlan0IfaceName(); 1377 } 1378 ap_iface = findUsingName(ap_ifaces_, getWlan1IfaceName()); 1379 sta_iface = findUsingName(sta_ifaces_, getWlan1IfaceName()); 1380 if (!ap_iface.get() && !sta_iface.get()) { 1381 return getWlan1IfaceName(); 1382 } 1383 // This should never happen. We screwed up somewhere if it did. 1384 CHECK(0) << "wlan0 and wlan1 in use already!"; 1385 return {}; 1386 } 1387 1388 bool WifiChip::writeRingbufferFilesInternal() { 1389 if (!removeOldFilesInternal()) { 1390 LOG(ERROR) << "Error occurred while deleting old tombstone files"; 1391 return false; 1392 } 1393 // write ringbuffers to file 1394 for (const auto& item : ringbuffer_map_) { 1395 const Ringbuffer& cur_buffer = item.second; 1396 if (cur_buffer.getData().empty()) { 1397 continue; 1398 } 1399 const std::string file_path_raw = 1400 kTombstoneFolderPath + item.first + "XXXXXXXXXX"; 1401 const int dump_fd = mkstemp(makeCharVec(file_path_raw).data()); 1402 if (dump_fd == -1) { 1403 LOG(ERROR) << "create file failed: " << strerror(errno); 1404 return false; 1405 } 1406 unique_fd file_auto_closer(dump_fd); 1407 for (const auto& cur_block : cur_buffer.getData()) { 1408 if (write(dump_fd, cur_block.data(), 1409 sizeof(cur_block[0]) * cur_block.size()) == -1) { 1410 LOG(ERROR) << "Error writing to file " << strerror(errno); 1411 } 1412 } 1413 } 1414 return true; 1415 } 1416 1417 } // namespace implementation 1418 } // namespace V1_2 1419 } // namespace wifi 1420 } // namespace hardware 1421 } // namespace android 1422