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 <android-base/logging.h>
     18 
     19 #include "hidl_return_util.h"
     20 #include "hidl_struct_util.h"
     21 #include "wifi_sta_iface.h"
     22 #include "wifi_status_util.h"
     23 
     24 namespace android {
     25 namespace hardware {
     26 namespace wifi {
     27 namespace V1_3 {
     28 namespace implementation {
     29 using hidl_return_util::validateAndCall;
     30 
     31 WifiStaIface::WifiStaIface(
     32     const std::string& ifname,
     33     const std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal,
     34     const std::weak_ptr<iface_util::WifiIfaceUtil> iface_util)
     35     : ifname_(ifname),
     36       legacy_hal_(legacy_hal),
     37       iface_util_(iface_util),
     38       is_valid_(true) {
     39     // Turn on DFS channel usage for STA iface.
     40     legacy_hal::wifi_error legacy_status =
     41         legacy_hal_.lock()->setDfsFlag(ifname_, true);
     42     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
     43         LOG(ERROR)
     44             << "Failed to set DFS flag; DFS channels may be unavailable.";
     45     }
     46 }
     47 
     48 void WifiStaIface::invalidate() {
     49     legacy_hal_.reset();
     50     event_cb_handler_.invalidate();
     51     is_valid_ = false;
     52 }
     53 
     54 bool WifiStaIface::isValid() { return is_valid_; }
     55 
     56 std::string WifiStaIface::getName() { return ifname_; }
     57 
     58 std::set<sp<IWifiStaIfaceEventCallback>> WifiStaIface::getEventCallbacks() {
     59     return event_cb_handler_.getCallbacks();
     60 }
     61 
     62 Return<void> WifiStaIface::getName(getName_cb hidl_status_cb) {
     63     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
     64                            &WifiStaIface::getNameInternal, hidl_status_cb);
     65 }
     66 
     67 Return<void> WifiStaIface::getType(getType_cb hidl_status_cb) {
     68     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
     69                            &WifiStaIface::getTypeInternal, hidl_status_cb);
     70 }
     71 
     72 Return<void> WifiStaIface::registerEventCallback(
     73     const sp<IWifiStaIfaceEventCallback>& callback,
     74     registerEventCallback_cb hidl_status_cb) {
     75     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
     76                            &WifiStaIface::registerEventCallbackInternal,
     77                            hidl_status_cb, callback);
     78 }
     79 
     80 Return<void> WifiStaIface::getCapabilities(getCapabilities_cb hidl_status_cb) {
     81     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
     82                            &WifiStaIface::getCapabilitiesInternal,
     83                            hidl_status_cb);
     84 }
     85 
     86 Return<void> WifiStaIface::getApfPacketFilterCapabilities(
     87     getApfPacketFilterCapabilities_cb hidl_status_cb) {
     88     return validateAndCall(
     89         this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
     90         &WifiStaIface::getApfPacketFilterCapabilitiesInternal, hidl_status_cb);
     91 }
     92 
     93 Return<void> WifiStaIface::installApfPacketFilter(
     94     uint32_t cmd_id, const hidl_vec<uint8_t>& program,
     95     installApfPacketFilter_cb hidl_status_cb) {
     96     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
     97                            &WifiStaIface::installApfPacketFilterInternal,
     98                            hidl_status_cb, cmd_id, program);
     99 }
    100 
    101 Return<void> WifiStaIface::readApfPacketFilterData(
    102     readApfPacketFilterData_cb hidl_status_cb) {
    103     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    104                            &WifiStaIface::readApfPacketFilterDataInternal,
    105                            hidl_status_cb);
    106 }
    107 
    108 Return<void> WifiStaIface::getBackgroundScanCapabilities(
    109     getBackgroundScanCapabilities_cb hidl_status_cb) {
    110     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    111                            &WifiStaIface::getBackgroundScanCapabilitiesInternal,
    112                            hidl_status_cb);
    113 }
    114 
    115 Return<void> WifiStaIface::getValidFrequenciesForBand(
    116     WifiBand band, getValidFrequenciesForBand_cb hidl_status_cb) {
    117     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    118                            &WifiStaIface::getValidFrequenciesForBandInternal,
    119                            hidl_status_cb, band);
    120 }
    121 
    122 Return<void> WifiStaIface::startBackgroundScan(
    123     uint32_t cmd_id, const StaBackgroundScanParameters& params,
    124     startBackgroundScan_cb hidl_status_cb) {
    125     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    126                            &WifiStaIface::startBackgroundScanInternal,
    127                            hidl_status_cb, cmd_id, params);
    128 }
    129 
    130 Return<void> WifiStaIface::stopBackgroundScan(
    131     uint32_t cmd_id, stopBackgroundScan_cb hidl_status_cb) {
    132     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    133                            &WifiStaIface::stopBackgroundScanInternal,
    134                            hidl_status_cb, cmd_id);
    135 }
    136 
    137 Return<void> WifiStaIface::enableLinkLayerStatsCollection(
    138     bool debug, enableLinkLayerStatsCollection_cb hidl_status_cb) {
    139     return validateAndCall(
    140         this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    141         &WifiStaIface::enableLinkLayerStatsCollectionInternal, hidl_status_cb,
    142         debug);
    143 }
    144 
    145 Return<void> WifiStaIface::disableLinkLayerStatsCollection(
    146     disableLinkLayerStatsCollection_cb hidl_status_cb) {
    147     return validateAndCall(
    148         this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    149         &WifiStaIface::disableLinkLayerStatsCollectionInternal, hidl_status_cb);
    150 }
    151 
    152 Return<void> WifiStaIface::getLinkLayerStats(
    153     getLinkLayerStats_cb hidl_status_cb) {
    154     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    155                            &WifiStaIface::getLinkLayerStatsInternal,
    156                            hidl_status_cb);
    157 }
    158 
    159 Return<void> WifiStaIface::getLinkLayerStats_1_3(
    160     getLinkLayerStats_1_3_cb hidl_status_cb) {
    161     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    162                            &WifiStaIface::getLinkLayerStatsInternal_1_3,
    163                            hidl_status_cb);
    164 }
    165 
    166 Return<void> WifiStaIface::startRssiMonitoring(
    167     uint32_t cmd_id, int32_t max_rssi, int32_t min_rssi,
    168     startRssiMonitoring_cb hidl_status_cb) {
    169     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    170                            &WifiStaIface::startRssiMonitoringInternal,
    171                            hidl_status_cb, cmd_id, max_rssi, min_rssi);
    172 }
    173 
    174 Return<void> WifiStaIface::stopRssiMonitoring(
    175     uint32_t cmd_id, stopRssiMonitoring_cb hidl_status_cb) {
    176     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    177                            &WifiStaIface::stopRssiMonitoringInternal,
    178                            hidl_status_cb, cmd_id);
    179 }
    180 
    181 Return<void> WifiStaIface::getRoamingCapabilities(
    182     getRoamingCapabilities_cb hidl_status_cb) {
    183     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    184                            &WifiStaIface::getRoamingCapabilitiesInternal,
    185                            hidl_status_cb);
    186 }
    187 
    188 Return<void> WifiStaIface::configureRoaming(
    189     const StaRoamingConfig& config, configureRoaming_cb hidl_status_cb) {
    190     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    191                            &WifiStaIface::configureRoamingInternal,
    192                            hidl_status_cb, config);
    193 }
    194 
    195 Return<void> WifiStaIface::setRoamingState(StaRoamingState state,
    196                                            setRoamingState_cb hidl_status_cb) {
    197     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    198                            &WifiStaIface::setRoamingStateInternal,
    199                            hidl_status_cb, state);
    200 }
    201 
    202 Return<void> WifiStaIface::enableNdOffload(bool enable,
    203                                            enableNdOffload_cb hidl_status_cb) {
    204     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    205                            &WifiStaIface::enableNdOffloadInternal,
    206                            hidl_status_cb, enable);
    207 }
    208 
    209 Return<void> WifiStaIface::startSendingKeepAlivePackets(
    210     uint32_t cmd_id, const hidl_vec<uint8_t>& ip_packet_data,
    211     uint16_t ether_type, const hidl_array<uint8_t, 6>& src_address,
    212     const hidl_array<uint8_t, 6>& dst_address, uint32_t period_in_ms,
    213     startSendingKeepAlivePackets_cb hidl_status_cb) {
    214     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    215                            &WifiStaIface::startSendingKeepAlivePacketsInternal,
    216                            hidl_status_cb, cmd_id, ip_packet_data, ether_type,
    217                            src_address, dst_address, period_in_ms);
    218 }
    219 
    220 Return<void> WifiStaIface::stopSendingKeepAlivePackets(
    221     uint32_t cmd_id, stopSendingKeepAlivePackets_cb hidl_status_cb) {
    222     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    223                            &WifiStaIface::stopSendingKeepAlivePacketsInternal,
    224                            hidl_status_cb, cmd_id);
    225 }
    226 
    227 Return<void> WifiStaIface::setScanningMacOui(
    228     const hidl_array<uint8_t, 3>& oui, setScanningMacOui_cb hidl_status_cb) {
    229     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    230                            &WifiStaIface::setScanningMacOuiInternal,
    231                            hidl_status_cb, oui);
    232 }
    233 
    234 Return<void> WifiStaIface::startDebugPacketFateMonitoring(
    235     startDebugPacketFateMonitoring_cb hidl_status_cb) {
    236     return validateAndCall(
    237         this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    238         &WifiStaIface::startDebugPacketFateMonitoringInternal, hidl_status_cb);
    239 }
    240 
    241 Return<void> WifiStaIface::getDebugTxPacketFates(
    242     getDebugTxPacketFates_cb hidl_status_cb) {
    243     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    244                            &WifiStaIface::getDebugTxPacketFatesInternal,
    245                            hidl_status_cb);
    246 }
    247 
    248 Return<void> WifiStaIface::getDebugRxPacketFates(
    249     getDebugRxPacketFates_cb hidl_status_cb) {
    250     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    251                            &WifiStaIface::getDebugRxPacketFatesInternal,
    252                            hidl_status_cb);
    253 }
    254 
    255 Return<void> WifiStaIface::setMacAddress(const hidl_array<uint8_t, 6>& mac,
    256                                          setMacAddress_cb hidl_status_cb) {
    257     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    258                            &WifiStaIface::setMacAddressInternal, hidl_status_cb,
    259                            mac);
    260 }
    261 
    262 Return<void> WifiStaIface::getFactoryMacAddress(
    263     getFactoryMacAddress_cb hidl_status_cb) {
    264     return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
    265                            &WifiStaIface::getFactoryMacAddressInternal,
    266                            hidl_status_cb);
    267 }
    268 
    269 std::pair<WifiStatus, std::string> WifiStaIface::getNameInternal() {
    270     return {createWifiStatus(WifiStatusCode::SUCCESS), ifname_};
    271 }
    272 
    273 std::pair<WifiStatus, IfaceType> WifiStaIface::getTypeInternal() {
    274     return {createWifiStatus(WifiStatusCode::SUCCESS), IfaceType::STA};
    275 }
    276 
    277 WifiStatus WifiStaIface::registerEventCallbackInternal(
    278     const sp<IWifiStaIfaceEventCallback>& callback) {
    279     if (!event_cb_handler_.addCallback(callback)) {
    280         return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
    281     }
    282     return createWifiStatus(WifiStatusCode::SUCCESS);
    283 }
    284 
    285 std::pair<WifiStatus, uint32_t> WifiStaIface::getCapabilitiesInternal() {
    286     legacy_hal::wifi_error legacy_status;
    287     uint32_t legacy_feature_set;
    288     std::tie(legacy_status, legacy_feature_set) =
    289         legacy_hal_.lock()->getSupportedFeatureSet(ifname_);
    290     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
    291         return {createWifiStatusFromLegacyError(legacy_status), 0};
    292     }
    293     uint32_t legacy_logger_feature_set;
    294     std::tie(legacy_status, legacy_logger_feature_set) =
    295         legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname_);
    296     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
    297         // some devices don't support querying logger feature set
    298         legacy_logger_feature_set = 0;
    299     }
    300     uint32_t hidl_caps;
    301     if (!hidl_struct_util::convertLegacyFeaturesToHidlStaCapabilities(
    302             legacy_feature_set, legacy_logger_feature_set, &hidl_caps)) {
    303         return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), 0};
    304     }
    305     return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
    306 }
    307 
    308 std::pair<WifiStatus, StaApfPacketFilterCapabilities>
    309 WifiStaIface::getApfPacketFilterCapabilitiesInternal() {
    310     legacy_hal::wifi_error legacy_status;
    311     legacy_hal::PacketFilterCapabilities legacy_caps;
    312     std::tie(legacy_status, legacy_caps) =
    313         legacy_hal_.lock()->getPacketFilterCapabilities(ifname_);
    314     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
    315         return {createWifiStatusFromLegacyError(legacy_status), {}};
    316     }
    317     StaApfPacketFilterCapabilities hidl_caps;
    318     if (!hidl_struct_util::convertLegacyApfCapabilitiesToHidl(legacy_caps,
    319                                                               &hidl_caps)) {
    320         return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
    321     }
    322     return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
    323 }
    324 
    325 WifiStatus WifiStaIface::installApfPacketFilterInternal(
    326     uint32_t /* cmd_id */, const std::vector<uint8_t>& program) {
    327     legacy_hal::wifi_error legacy_status =
    328         legacy_hal_.lock()->setPacketFilter(ifname_, program);
    329     return createWifiStatusFromLegacyError(legacy_status);
    330 }
    331 
    332 std::pair<WifiStatus, std::vector<uint8_t>>
    333 WifiStaIface::readApfPacketFilterDataInternal() {
    334     const std::pair<legacy_hal::wifi_error, std::vector<uint8_t>>
    335         legacy_status_and_data =
    336             legacy_hal_.lock()->readApfPacketFilterData(ifname_);
    337     return {createWifiStatusFromLegacyError(legacy_status_and_data.first),
    338             std::move(legacy_status_and_data.second)};
    339 }
    340 
    341 std::pair<WifiStatus, StaBackgroundScanCapabilities>
    342 WifiStaIface::getBackgroundScanCapabilitiesInternal() {
    343     legacy_hal::wifi_error legacy_status;
    344     legacy_hal::wifi_gscan_capabilities legacy_caps;
    345     std::tie(legacy_status, legacy_caps) =
    346         legacy_hal_.lock()->getGscanCapabilities(ifname_);
    347     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
    348         return {createWifiStatusFromLegacyError(legacy_status), {}};
    349     }
    350     StaBackgroundScanCapabilities hidl_caps;
    351     if (!hidl_struct_util::convertLegacyGscanCapabilitiesToHidl(legacy_caps,
    352                                                                 &hidl_caps)) {
    353         return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
    354     }
    355     return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
    356 }
    357 
    358 std::pair<WifiStatus, std::vector<WifiChannelInMhz>>
    359 WifiStaIface::getValidFrequenciesForBandInternal(WifiBand band) {
    360     static_assert(sizeof(WifiChannelInMhz) == sizeof(uint32_t),
    361                   "Size mismatch");
    362     legacy_hal::wifi_error legacy_status;
    363     std::vector<uint32_t> valid_frequencies;
    364     std::tie(legacy_status, valid_frequencies) =
    365         legacy_hal_.lock()->getValidFrequenciesForBand(
    366             ifname_, hidl_struct_util::convertHidlWifiBandToLegacy(band));
    367     return {createWifiStatusFromLegacyError(legacy_status), valid_frequencies};
    368 }
    369 
    370 WifiStatus WifiStaIface::startBackgroundScanInternal(
    371     uint32_t cmd_id, const StaBackgroundScanParameters& params) {
    372     legacy_hal::wifi_scan_cmd_params legacy_params;
    373     if (!hidl_struct_util::convertHidlGscanParamsToLegacy(params,
    374                                                           &legacy_params)) {
    375         return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
    376     }
    377     android::wp<WifiStaIface> weak_ptr_this(this);
    378     const auto& on_failure_callback =
    379         [weak_ptr_this](legacy_hal::wifi_request_id id) {
    380             const auto shared_ptr_this = weak_ptr_this.promote();
    381             if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
    382                 LOG(ERROR) << "Callback invoked on an invalid object";
    383                 return;
    384             }
    385             for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
    386                 if (!callback->onBackgroundScanFailure(id).isOk()) {
    387                     LOG(ERROR)
    388                         << "Failed to invoke onBackgroundScanFailure callback";
    389                 }
    390             }
    391         };
    392     const auto& on_results_callback =
    393         [weak_ptr_this](
    394             legacy_hal::wifi_request_id id,
    395             const std::vector<legacy_hal::wifi_cached_scan_results>& results) {
    396             const auto shared_ptr_this = weak_ptr_this.promote();
    397             if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
    398                 LOG(ERROR) << "Callback invoked on an invalid object";
    399                 return;
    400             }
    401             std::vector<StaScanData> hidl_scan_datas;
    402             if (!hidl_struct_util::
    403                     convertLegacyVectorOfCachedGscanResultsToHidl(
    404                         results, &hidl_scan_datas)) {
    405                 LOG(ERROR) << "Failed to convert scan results to HIDL structs";
    406                 return;
    407             }
    408             for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
    409                 if (!callback->onBackgroundScanResults(id, hidl_scan_datas)
    410                          .isOk()) {
    411                     LOG(ERROR)
    412                         << "Failed to invoke onBackgroundScanResults callback";
    413                 }
    414             }
    415         };
    416     const auto& on_full_result_callback = [weak_ptr_this](
    417                                               legacy_hal::wifi_request_id id,
    418                                               const legacy_hal::
    419                                                   wifi_scan_result* result,
    420                                               uint32_t buckets_scanned) {
    421         const auto shared_ptr_this = weak_ptr_this.promote();
    422         if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
    423             LOG(ERROR) << "Callback invoked on an invalid object";
    424             return;
    425         }
    426         StaScanResult hidl_scan_result;
    427         if (!hidl_struct_util::convertLegacyGscanResultToHidl(
    428                 *result, true, &hidl_scan_result)) {
    429             LOG(ERROR) << "Failed to convert full scan results to HIDL structs";
    430             return;
    431         }
    432         for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
    433             if (!callback
    434                      ->onBackgroundFullScanResult(id, buckets_scanned,
    435                                                   hidl_scan_result)
    436                      .isOk()) {
    437                 LOG(ERROR)
    438                     << "Failed to invoke onBackgroundFullScanResult callback";
    439             }
    440         }
    441     };
    442     legacy_hal::wifi_error legacy_status = legacy_hal_.lock()->startGscan(
    443         ifname_, cmd_id, legacy_params, on_failure_callback,
    444         on_results_callback, on_full_result_callback);
    445     return createWifiStatusFromLegacyError(legacy_status);
    446 }
    447 
    448 WifiStatus WifiStaIface::stopBackgroundScanInternal(uint32_t cmd_id) {
    449     legacy_hal::wifi_error legacy_status =
    450         legacy_hal_.lock()->stopGscan(ifname_, cmd_id);
    451     return createWifiStatusFromLegacyError(legacy_status);
    452 }
    453 
    454 WifiStatus WifiStaIface::enableLinkLayerStatsCollectionInternal(bool debug) {
    455     legacy_hal::wifi_error legacy_status =
    456         legacy_hal_.lock()->enableLinkLayerStats(ifname_, debug);
    457     return createWifiStatusFromLegacyError(legacy_status);
    458 }
    459 
    460 WifiStatus WifiStaIface::disableLinkLayerStatsCollectionInternal() {
    461     legacy_hal::wifi_error legacy_status =
    462         legacy_hal_.lock()->disableLinkLayerStats(ifname_);
    463     return createWifiStatusFromLegacyError(legacy_status);
    464 }
    465 
    466 std::pair<WifiStatus, V1_0::StaLinkLayerStats>
    467 WifiStaIface::getLinkLayerStatsInternal() {
    468     return {createWifiStatus(WifiStatusCode::ERROR_NOT_SUPPORTED), {}};
    469 }
    470 
    471 std::pair<WifiStatus, V1_3::StaLinkLayerStats>
    472 WifiStaIface::getLinkLayerStatsInternal_1_3() {
    473     legacy_hal::wifi_error legacy_status;
    474     legacy_hal::LinkLayerStats legacy_stats;
    475     std::tie(legacy_status, legacy_stats) =
    476         legacy_hal_.lock()->getLinkLayerStats(ifname_);
    477     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
    478         return {createWifiStatusFromLegacyError(legacy_status), {}};
    479     }
    480     V1_3::StaLinkLayerStats hidl_stats;
    481     if (!hidl_struct_util::convertLegacyLinkLayerStatsToHidl(legacy_stats,
    482                                                              &hidl_stats)) {
    483         return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
    484     }
    485     return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_stats};
    486 }
    487 
    488 WifiStatus WifiStaIface::startRssiMonitoringInternal(uint32_t cmd_id,
    489                                                      int32_t max_rssi,
    490                                                      int32_t min_rssi) {
    491     android::wp<WifiStaIface> weak_ptr_this(this);
    492     const auto& on_threshold_breached_callback =
    493         [weak_ptr_this](legacy_hal::wifi_request_id id,
    494                         std::array<uint8_t, 6> bssid, int8_t rssi) {
    495             const auto shared_ptr_this = weak_ptr_this.promote();
    496             if (!shared_ptr_this.get() || !shared_ptr_this->isValid()) {
    497                 LOG(ERROR) << "Callback invoked on an invalid object";
    498                 return;
    499             }
    500             for (const auto& callback : shared_ptr_this->getEventCallbacks()) {
    501                 if (!callback->onRssiThresholdBreached(id, bssid, rssi)
    502                          .isOk()) {
    503                     LOG(ERROR)
    504                         << "Failed to invoke onRssiThresholdBreached callback";
    505                 }
    506             }
    507         };
    508     legacy_hal::wifi_error legacy_status =
    509         legacy_hal_.lock()->startRssiMonitoring(ifname_, cmd_id, max_rssi,
    510                                                 min_rssi,
    511                                                 on_threshold_breached_callback);
    512     return createWifiStatusFromLegacyError(legacy_status);
    513 }
    514 
    515 WifiStatus WifiStaIface::stopRssiMonitoringInternal(uint32_t cmd_id) {
    516     legacy_hal::wifi_error legacy_status =
    517         legacy_hal_.lock()->stopRssiMonitoring(ifname_, cmd_id);
    518     return createWifiStatusFromLegacyError(legacy_status);
    519 }
    520 
    521 std::pair<WifiStatus, StaRoamingCapabilities>
    522 WifiStaIface::getRoamingCapabilitiesInternal() {
    523     legacy_hal::wifi_error legacy_status;
    524     legacy_hal::wifi_roaming_capabilities legacy_caps;
    525     std::tie(legacy_status, legacy_caps) =
    526         legacy_hal_.lock()->getRoamingCapabilities(ifname_);
    527     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
    528         return {createWifiStatusFromLegacyError(legacy_status), {}};
    529     }
    530     StaRoamingCapabilities hidl_caps;
    531     if (!hidl_struct_util::convertLegacyRoamingCapabilitiesToHidl(legacy_caps,
    532                                                                   &hidl_caps)) {
    533         return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
    534     }
    535     return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_caps};
    536 }
    537 
    538 WifiStatus WifiStaIface::configureRoamingInternal(
    539     const StaRoamingConfig& config) {
    540     legacy_hal::wifi_roaming_config legacy_config;
    541     if (!hidl_struct_util::convertHidlRoamingConfigToLegacy(config,
    542                                                             &legacy_config)) {
    543         return createWifiStatus(WifiStatusCode::ERROR_INVALID_ARGS);
    544     }
    545     legacy_hal::wifi_error legacy_status =
    546         legacy_hal_.lock()->configureRoaming(ifname_, legacy_config);
    547     return createWifiStatusFromLegacyError(legacy_status);
    548 }
    549 
    550 WifiStatus WifiStaIface::setRoamingStateInternal(StaRoamingState state) {
    551     legacy_hal::wifi_error legacy_status =
    552         legacy_hal_.lock()->enableFirmwareRoaming(
    553             ifname_, hidl_struct_util::convertHidlRoamingStateToLegacy(state));
    554     return createWifiStatusFromLegacyError(legacy_status);
    555 }
    556 
    557 WifiStatus WifiStaIface::enableNdOffloadInternal(bool enable) {
    558     legacy_hal::wifi_error legacy_status =
    559         legacy_hal_.lock()->configureNdOffload(ifname_, enable);
    560     return createWifiStatusFromLegacyError(legacy_status);
    561 }
    562 
    563 WifiStatus WifiStaIface::startSendingKeepAlivePacketsInternal(
    564     uint32_t cmd_id, const std::vector<uint8_t>& ip_packet_data,
    565     uint16_t ether_type, const std::array<uint8_t, 6>& src_address,
    566     const std::array<uint8_t, 6>& dst_address, uint32_t period_in_ms) {
    567     legacy_hal::wifi_error legacy_status =
    568         legacy_hal_.lock()->startSendingOffloadedPacket(
    569             ifname_, cmd_id, ether_type, ip_packet_data, src_address,
    570             dst_address, period_in_ms);
    571     return createWifiStatusFromLegacyError(legacy_status);
    572 }
    573 
    574 WifiStatus WifiStaIface::stopSendingKeepAlivePacketsInternal(uint32_t cmd_id) {
    575     legacy_hal::wifi_error legacy_status =
    576         legacy_hal_.lock()->stopSendingOffloadedPacket(ifname_, cmd_id);
    577     return createWifiStatusFromLegacyError(legacy_status);
    578 }
    579 
    580 WifiStatus WifiStaIface::setScanningMacOuiInternal(
    581     const std::array<uint8_t, 3>& oui) {
    582     legacy_hal::wifi_error legacy_status =
    583         legacy_hal_.lock()->setScanningMacOui(ifname_, oui);
    584     return createWifiStatusFromLegacyError(legacy_status);
    585 }
    586 
    587 WifiStatus WifiStaIface::startDebugPacketFateMonitoringInternal() {
    588     legacy_hal::wifi_error legacy_status =
    589         legacy_hal_.lock()->startPktFateMonitoring(ifname_);
    590     return createWifiStatusFromLegacyError(legacy_status);
    591 }
    592 
    593 std::pair<WifiStatus, std::vector<WifiDebugTxPacketFateReport>>
    594 WifiStaIface::getDebugTxPacketFatesInternal() {
    595     legacy_hal::wifi_error legacy_status;
    596     std::vector<legacy_hal::wifi_tx_report> legacy_fates;
    597     std::tie(legacy_status, legacy_fates) =
    598         legacy_hal_.lock()->getTxPktFates(ifname_);
    599     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
    600         return {createWifiStatusFromLegacyError(legacy_status), {}};
    601     }
    602     std::vector<WifiDebugTxPacketFateReport> hidl_fates;
    603     if (!hidl_struct_util::convertLegacyVectorOfDebugTxPacketFateToHidl(
    604             legacy_fates, &hidl_fates)) {
    605         return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
    606     }
    607     return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_fates};
    608 }
    609 
    610 std::pair<WifiStatus, std::vector<WifiDebugRxPacketFateReport>>
    611 WifiStaIface::getDebugRxPacketFatesInternal() {
    612     legacy_hal::wifi_error legacy_status;
    613     std::vector<legacy_hal::wifi_rx_report> legacy_fates;
    614     std::tie(legacy_status, legacy_fates) =
    615         legacy_hal_.lock()->getRxPktFates(ifname_);
    616     if (legacy_status != legacy_hal::WIFI_SUCCESS) {
    617         return {createWifiStatusFromLegacyError(legacy_status), {}};
    618     }
    619     std::vector<WifiDebugRxPacketFateReport> hidl_fates;
    620     if (!hidl_struct_util::convertLegacyVectorOfDebugRxPacketFateToHidl(
    621             legacy_fates, &hidl_fates)) {
    622         return {createWifiStatus(WifiStatusCode::ERROR_UNKNOWN), {}};
    623     }
    624     return {createWifiStatus(WifiStatusCode::SUCCESS), hidl_fates};
    625 }
    626 
    627 WifiStatus WifiStaIface::setMacAddressInternal(
    628     const std::array<uint8_t, 6>& mac) {
    629     bool status = iface_util_.lock()->setMacAddress(ifname_, mac);
    630     if (!status) {
    631         return createWifiStatus(WifiStatusCode::ERROR_UNKNOWN);
    632     }
    633     return createWifiStatus(WifiStatusCode::SUCCESS);
    634 }
    635 
    636 std::pair<WifiStatus, std::array<uint8_t, 6>>
    637 WifiStaIface::getFactoryMacAddressInternal() {
    638     std::array<uint8_t, 6> mac =
    639         iface_util_.lock()->getFactoryMacAddress(ifname_);
    640     return {createWifiStatus(WifiStatusCode::SUCCESS), mac};
    641 }
    642 
    643 }  // namespace implementation
    644 }  // namespace V1_3
    645 }  // namespace wifi
    646 }  // namespace hardware
    647 }  // namespace android
    648