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