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