Home | History | Annotate | Download | only in default
      1 /*
      2  * Copyright (C) 2016 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #include <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