Merge "Add the HAL support for getCachedScanResult." into main

This commit is contained in:
Kai Shi 2023-12-07 22:02:48 +00:00 committed by Android (Google) Code Review
commit a0fc82730d
13 changed files with 349 additions and 8 deletions

View file

@ -0,0 +1,39 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.wifi;
@VintfStability
parcelable CachedScanData {
int[] scannedFrequenciesMhz;
android.hardware.wifi.CachedScanResult[] cachedScanResults;
}

View file

@ -0,0 +1,44 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
///////////////////////////////////////////////////////////////////////////////
// THIS FILE IS IMMUTABLE. DO NOT EDIT IN ANY CASE. //
///////////////////////////////////////////////////////////////////////////////
// This file is a snapshot of an AIDL file. Do not edit it manually. There are
// two cases:
// 1). this is a frozen version file - do not edit this in any case.
// 2). this is a 'current' file. If you make a backwards compatible change to
// the interface (from the latest frozen version), the build system will
// prompt you to update this file with `m <name>-update-api`.
//
// You must not make a backward incompatible change to any AIDL file built
// with the aidl_interface module type with versions property set. The module
// type is used to build AIDL files in a way that they can be used across
// independently updatable components of the system. If a device is shipped
// with such a backward incompatible change, it has a high risk of breaking
// later when a module using the interface is updated, e.g., Mainline modules.
package android.hardware.wifi;
@VintfStability
parcelable CachedScanResult {
long timeStampInUs;
byte[] ssid;
byte[6] bssid;
int rssiDbm;
int frequencyMhz;
android.hardware.wifi.WifiChannelWidthInMhz channelWidthMhz;
android.hardware.wifi.WifiRatePreamble preambleType;
}

View file

@ -61,6 +61,7 @@ interface IWifiStaIface {
void stopRssiMonitoring(in int cmdId);
void stopSendingKeepAlivePackets(in int cmdId);
void setDtimMultiplier(in int multiplier);
android.hardware.wifi.CachedScanData getCachedScanData();
@Backing(type="int") @VintfStability
enum FeatureSetMask {
APF = (1 << 0) /* 1 */,

View file

@ -0,0 +1,35 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.wifi;
import android.hardware.wifi.CachedScanResult;
/**
* Scan data cached in Wifi firmware
*/
@VintfStability
parcelable CachedScanData {
/**
* List of scanned frequencies in MHz.
*/
int[] scannedFrequenciesMhz;
/**
* List of scan results.
*/
CachedScanResult[] cachedScanResults;
}

View file

@ -0,0 +1,55 @@
/*
* Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package android.hardware.wifi;
import android.hardware.wifi.WifiChannelWidthInMhz;
import android.hardware.wifi.WifiRatePreamble;
/**
* Scan result cached in Wifi firmware
*/
@VintfStability
parcelable CachedScanResult {
/**
* Time in micro seconds since boot when the scan was done
*/
long timeStampInUs;
/**
* SSID of beacon excluding null.
*/
byte[] ssid;
/**
* BSSID of beacon
*/
byte[6] bssid;
/**
* Beacon received signal stength indicatior (RSSI), in dbm
*/
int rssiDbm;
/**
* Frequency of beacon, in MHz
*/
int frequencyMhz;
/**
* Channel bandwidth of found network
*/
WifiChannelWidthInMhz channelWidthMhz;
/**
* Supported rate and preamble type
*/
WifiRatePreamble preambleType;
}

View file

@ -16,6 +16,7 @@
package android.hardware.wifi;
import android.hardware.wifi.CachedScanData;
import android.hardware.wifi.IWifiStaIfaceEventCallback;
import android.hardware.wifi.StaApfPacketFilterCapabilities;
import android.hardware.wifi.StaBackgroundScanCapabilities;
@ -556,4 +557,16 @@ interface IWifiStaIface {
* |WifiStatusCode.ERROR_UNKNOWN|
*/
void setDtimMultiplier(in int multiplier);
/**
* Get the cached scan data.
*
* @return Instance of |CachedScanData|.
* @throws ServiceSpecificException with one of the following values:
* |WifiStatusCode.ERROR_WIFI_IFACE_INVALID|,
* |WifiStatusCode.ERROR_NOT_SUPPORTED|,
* |WifiStatusCode.ERROR_NOT_AVAILABLE|,
* |WifiStatusCode.ERROR_UNKNOWN|
*/
CachedScanData getCachedScanData();
}

View file

@ -3389,6 +3389,69 @@ bool convertLegacyIfaceCombinationsMatrixToChipMode(
return true;
}
bool convertCachedScanReportToAidl(const legacy_hal::WifiCachedScanReport& report,
CachedScanData* aidl_scan_data) {
if (!aidl_scan_data) {
return false;
}
*aidl_scan_data = {};
std::vector<CachedScanResult> aidl_scan_results;
for (const auto& result : report.results) {
CachedScanResult aidl_scan_result;
if (!convertCachedScanResultToAidl(result, report.ts, &aidl_scan_result)) {
return false;
}
aidl_scan_results.push_back(aidl_scan_result);
}
aidl_scan_data->cachedScanResults = aidl_scan_results;
aidl_scan_data->scannedFrequenciesMhz = report.scanned_freqs;
return true;
}
bool convertCachedScanResultToAidl(const legacy_hal::wifi_cached_scan_result& legacy_scan_result,
uint64_t ts_us, CachedScanResult* aidl_scan_result) {
if (!aidl_scan_result) {
return false;
}
*aidl_scan_result = {};
aidl_scan_result->timeStampInUs = ts_us - legacy_scan_result.age_ms * 1000;
if (aidl_scan_result->timeStampInUs < 0) {
aidl_scan_result->timeStampInUs = 0;
return false;
}
size_t max_len_excluding_null = sizeof(legacy_scan_result.ssid) - 1;
size_t ssid_len = strnlen((const char*)legacy_scan_result.ssid, max_len_excluding_null);
aidl_scan_result->ssid =
std::vector<uint8_t>(legacy_scan_result.ssid, legacy_scan_result.ssid + ssid_len);
aidl_scan_result->bssid = std::array<uint8_t, 6>();
std::copy(legacy_scan_result.bssid, legacy_scan_result.bssid + 6,
std::begin(aidl_scan_result->bssid));
aidl_scan_result->frequencyMhz = legacy_scan_result.chanspec.primary_frequency;
aidl_scan_result->channelWidthMhz =
convertLegacyWifiChannelWidthToAidl(legacy_scan_result.chanspec.width);
aidl_scan_result->rssiDbm = legacy_scan_result.rssi;
aidl_scan_result->preambleType = convertScanResultFlagsToPreambleType(legacy_scan_result.flags);
return true;
}
WifiRatePreamble convertScanResultFlagsToPreambleType(int flags) {
if ((flags & WIFI_CACHED_SCAN_RESULT_FLAGS_EHT_OPS_PRESENT) > 0) {
return WifiRatePreamble::EHT;
}
if ((flags & WIFI_CACHED_SCAN_RESULT_FLAGS_HE_OPS_PRESENT) > 0) {
return WifiRatePreamble::HE;
}
if ((flags & WIFI_CACHED_SCAN_RESULT_FLAGS_VHT_OPS_PRESENT) > 0) {
return WifiRatePreamble::VHT;
}
if ((flags & WIFI_CACHED_SCAN_RESULT_FLAGS_HT_OPS_PRESENT) > 0) {
return WifiRatePreamble::HT;
}
return WifiRatePreamble::OFDM;
}
} // namespace aidl_struct_util
} // namespace wifi
} // namespace hardware

View file

@ -202,6 +202,11 @@ bool convertLegacyNanBootstrappingConfirmIndToAidl(
const legacy_hal::NanBootstrappingConfirmInd& legacy_ind,
NanBootstrappingConfirmInd* aidl_ind);
uint32_t convertAidlChannelCategoryToLegacy(uint32_t aidl_channel_category_mask);
bool convertCachedScanReportToAidl(const legacy_hal::WifiCachedScanReport& report,
CachedScanData* aidl_scan_data);
bool convertCachedScanResultToAidl(const legacy_hal::wifi_cached_scan_result& legacy_scan_result,
uint64_t ts_us, CachedScanResult* aidl_scan_result);
WifiRatePreamble convertScanResultFlagsToPreambleType(int flags);
} // namespace aidl_struct_util
} // namespace wifi
} // namespace hardware

View file

@ -35,6 +35,12 @@ byte LCI[] = {0x27, 0x1A, 0x1, 0x00, 0x8, 0x01, 0x00, 0x08, 0x00, 0x10, 0x52,
0x2c, 0x00, 0x00, 0x41, 0x06, 0x03, 0x06, 0x00, 0x80};
byte LCR[] = {0x27, 0xE, 0x1, 0x00, 0xB, 0x01, 0x00, 0x0b, 0x00, 0x09,
0x55, 0x53, 0x18, 0x05, 0x39, 0x34, 0x30, 0x34, 0x33};
constexpr int kNumScanResult = 2;
constexpr int kRssi[] = {-60, -70};
constexpr uint8_t kBssid[] = {0x12, 0x34, 0x56, 0x78, 0x9a, 0};
constexpr uint8_t kSsidLen = 6;
constexpr char kSsid[] = {'a', 'b', 'c', 'd', 'e', '\0'};
} // namespace
namespace aidl {
@ -883,6 +889,51 @@ TEST_F(AidlStructUtilTest, convertLegacyVectorOfRttResultV2ToAidl) {
}
}
TEST_F(AidlStructUtilTest, convertCachedScanReportToAidl) {
legacy_hal::WifiCachedScanReport hw_report;
hw_report.ts = 10000000;
std::vector<int> scanned_freqs{5260, 2437, 5200};
std::vector<wifi_cached_scan_result> results;
hw_report.scanned_freqs = scanned_freqs;
for (int i = 0; i < kNumScanResult; i++) {
wifi_cached_scan_result result;
result.age_ms = i * 1000;
result.capability = i;
memcpy(result.ssid, kSsid, kSsidLen);
result.ssid_len = kSsidLen;
memcpy(result.bssid, kBssid, 6);
result.flags = WIFI_CACHED_SCAN_RESULT_FLAGS_HE_OPS_PRESENT;
result.rssi = kRssi[i];
result.chanspec = {legacy_hal::WIFI_CHAN_WIDTH_40, 0, 0, i};
results.push_back(result);
}
hw_report.results = results;
CachedScanData aidl_data;
aidl_struct_util::convertCachedScanReportToAidl(hw_report, &aidl_data);
EXPECT_EQ(scanned_freqs.size(), aidl_data.scannedFrequenciesMhz.size());
EXPECT_EQ(scanned_freqs[2], aidl_data.scannedFrequenciesMhz[2]);
EXPECT_EQ(5260, aidl_data.scannedFrequenciesMhz[0]);
EXPECT_EQ(kNumScanResult, (int)aidl_data.cachedScanResults.size());
for (int i = 0; i < kNumScanResult; i++) {
EXPECT_EQ(hw_report.results[i].rssi, aidl_data.cachedScanResults[i].rssiDbm);
EXPECT_EQ(i, aidl_data.cachedScanResults[i].frequencyMhz);
int64_t expected_ts = 10000000 - i * 1000 * 1000;
EXPECT_EQ(expected_ts, aidl_data.cachedScanResults[i].timeStampInUs);
EXPECT_EQ(WifiRatePreamble::HE, aidl_data.cachedScanResults[i].preambleType);
EXPECT_EQ(WifiChannelWidthInMhz::WIDTH_40, aidl_data.cachedScanResults[i].channelWidthMhz);
for (int k = 0; k < 6; k++) {
EXPECT_EQ(kBssid[k], aidl_data.cachedScanResults[i].bssid[k]);
}
for (int k = 0; k < kSsidLen; k++) {
EXPECT_EQ(kSsid[k], aidl_data.cachedScanResults[i].ssid[k]);
}
}
}
} // namespace wifi
} // namespace hardware
} // namespace android

View file

@ -439,6 +439,7 @@ void onAsyncChreNanRttState(chre_nan_rtt_state state) {
// Callback to report cached scan results
std::function<void(wifi_cached_scan_report*)> on_cached_scan_results_internal_callback;
void onSyncCachedScanResults(wifi_cached_scan_report* cache_report) {
const auto lock = aidl_sync_util::acquireGlobalLock();
if (on_cached_scan_results_internal_callback) {
on_cached_scan_results_internal_callback(cache_report);
}
@ -1858,13 +1859,16 @@ wifi_error WifiLegacyHal::enableWifiTxPowerLimits(const std::string& iface_name,
return global_func_table_.wifi_enable_tx_power_limits(getIfaceHandle(iface_name), enable);
}
wifi_error WifiLegacyHal::getWifiCachedScanResults(
const std::string& iface_name, const CachedScanResultsCallbackHandlers& handler) {
on_cached_scan_results_internal_callback = handler.on_cached_scan_results;
wifi_error WifiLegacyHal::getWifiCachedScanResults(const std::string& iface_name,
WifiCachedScanReport& report) {
on_cached_scan_results_internal_callback = [&report](wifi_cached_scan_report* report_ptr) {
report.results.assign(report_ptr->results, report_ptr->results + report_ptr->result_cnt);
report.scanned_freqs.assign(report_ptr->scanned_freq_list,
report_ptr->scanned_freq_list + report_ptr->scanned_freq_num);
report.ts = report_ptr->ts;
};
wifi_error status = global_func_table_.wifi_get_cached_scan_results(getIfaceHandle(iface_name),
{onSyncCachedScanResults});
on_cached_scan_results_internal_callback = nullptr;
return status;
}
@ -1934,6 +1938,7 @@ void WifiLegacyHal::invalidate() {
on_twt_event_info_frame_received_callback = nullptr;
on_twt_event_device_notify_callback = nullptr;
on_chre_nan_rtt_internal_callback = nullptr;
on_cached_scan_results_internal_callback = nullptr;
}
} // namespace legacy_hal

View file

@ -257,6 +257,7 @@ using ::WIFI_BAND_ABG_WITH_DFS;
using ::WIFI_BAND_BG;
using ::WIFI_BAND_UNSPECIFIED;
using ::wifi_cached_scan_report;
using ::wifi_cached_scan_result;
using ::wifi_cached_scan_results;
using ::WIFI_CHAN_WIDTH_10;
using ::WIFI_CHAN_WIDTH_160;
@ -423,6 +424,12 @@ struct LinkLayerMlStats {
bool valid;
};
struct WifiCachedScanReport {
uint64_t ts;
std::vector<int> scanned_freqs;
std::vector<wifi_cached_scan_result> results;
};
#pragma GCC diagnostic pop
// The |WLAN_DRIVER_WAKE_REASON_CNT.cmd_event_wake_cnt| and
@ -533,8 +540,9 @@ struct ChreCallbackHandlers {
std::function<void(chre_nan_rtt_state)> on_wifi_chre_nan_rtt_state;
};
// Cached Scan Results response and event callbacks struct.
struct CachedScanResultsCallbackHandlers {
using on_cached_scan_results_callback = std::function<void(wifi_cached_scan_report*)>;
struct CachedScanResultsCallbfackHandlers {
// Callback for Cached Scan Results
std::function<void(wifi_cached_scan_report*)> on_cached_scan_results;
};
@ -777,7 +785,7 @@ class WifiLegacyHal {
wifi_error enableWifiTxPowerLimits(const std::string& iface_name, bool enable);
wifi_error getWifiCachedScanResults(const std::string& iface_name,
const CachedScanResultsCallbackHandlers& handler);
WifiCachedScanReport& report);
std::pair<wifi_error, wifi_chip_capabilities> getWifiChipCapabilities();
wifi_error enableStaChannelForPeerNetwork(uint32_t channelCategoryEnableFlag);
wifi_error setMloMode(wifi_mlo_mode mode);

View file

@ -219,6 +219,11 @@ ndk::ScopedAStatus WifiStaIface::setDtimMultiplier(int32_t in_multiplier) {
&WifiStaIface::setDtimMultiplierInternal, in_multiplier);
}
ndk::ScopedAStatus WifiStaIface::getCachedScanData(CachedScanData* _aidl_return) {
return validateAndCall(this, WifiStatusCode::ERROR_WIFI_IFACE_INVALID,
&WifiStaIface::getCachedScanDataInternal, _aidl_return);
}
std::pair<std::string, ndk::ScopedAStatus> WifiStaIface::getNameInternal() {
return {ifname_, ndk::ScopedAStatus::ok()};
}
@ -540,6 +545,21 @@ ndk::ScopedAStatus WifiStaIface::setDtimMultiplierInternal(const int multiplier)
return createWifiStatusFromLegacyError(legacy_status);
}
std::pair<CachedScanData, ndk::ScopedAStatus> WifiStaIface::getCachedScanDataInternal() {
legacy_hal::WifiCachedScanReport cached_scan_report;
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->getWifiCachedScanResults(ifname_, cached_scan_report);
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
return {CachedScanData{}, createWifiStatusFromLegacyError(legacy_status)};
}
CachedScanData aidl_scan_data;
if (!aidl_struct_util::convertCachedScanReportToAidl(cached_scan_report, &aidl_scan_data)) {
return {CachedScanData{}, createWifiStatus(WifiStatusCode::ERROR_UNKNOWN)};
}
return {aidl_scan_data, ndk::ScopedAStatus::ok()};
}
} // namespace wifi
} // namespace hardware
} // namespace android

View file

@ -90,6 +90,7 @@ class WifiStaIface : public BnWifiStaIface {
ndk::ScopedAStatus getFactoryMacAddress(std::array<uint8_t, 6>* _aidl_return) override;
ndk::ScopedAStatus setScanMode(bool in_enable) override;
ndk::ScopedAStatus setDtimMultiplier(int32_t in_multiplier) override;
ndk::ScopedAStatus getCachedScanData(CachedScanData* _aidl_return) override;
private:
// Corresponding worker functions for the AIDL methods.
@ -130,6 +131,7 @@ class WifiStaIface : public BnWifiStaIface {
std::pair<std::array<uint8_t, 6>, ndk::ScopedAStatus> getFactoryMacAddressInternal();
ndk::ScopedAStatus setScanModeInternal(bool enable);
ndk::ScopedAStatus setDtimMultiplierInternal(const int multiplier);
std::pair<CachedScanData, ndk::ScopedAStatus> getCachedScanDataInternal();
void setWeakPtr(std::weak_ptr<WifiStaIface> ptr);