Merge "WiFi: support more wlan interfaces than 2"

This commit is contained in:
TreeHugger Robot 2019-01-09 01:30:35 +00:00 committed by Android (Google) Code Review
commit 687cb73835
2 changed files with 115 additions and 42 deletions

View file

@ -16,6 +16,7 @@
#include <android-base/logging.h>
#include <android-base/macros.h>
#include <cutils/properties.h>
#include <gmock/gmock.h>
#undef NAN // This is weird, NAN is defined in bionic/libc/include/math.h:38
@ -117,6 +118,19 @@ class WifiChipTest : public Test {
.WillRepeatedly(testing::Return(modes));
}
void setup_MultiIfaceCombination() {
// clang-format off
const hidl_vec<V1_0::IWifiChip::ChipIfaceCombination> combinations = {
{{{{IfaceType::STA}, 3}}}
};
const std::vector<V1_0::IWifiChip::ChipMode> modes = {
{feature_flags::chip_mode_ids::kV3, combinations}
};
// clang-format on
EXPECT_CALL(*feature_flags_, getChipModes())
.WillRepeatedly(testing::Return(modes));
}
void assertNumberOfModes(uint32_t num_modes) {
chip_->getAvailableModes(
[num_modes](const WifiStatus& status,
@ -655,6 +669,58 @@ TEST_F(WifiChipV2_AwareDisabledApIfaceCombinationTest,
ASSERT_TRUE(createIface(IfaceType::AP).empty());
}
class WifiChip_MultiIfaceTest : public WifiChipTest {
public:
void SetUp() override {
setup_MultiIfaceCombination();
WifiChipTest::SetUp();
}
};
TEST_F(WifiChip_MultiIfaceTest, Create3Sta) {
findModeAndConfigureForIfaceType(IfaceType::STA);
ASSERT_FALSE(createIface(IfaceType::STA).empty());
ASSERT_FALSE(createIface(IfaceType::STA).empty());
ASSERT_FALSE(createIface(IfaceType::STA).empty());
ASSERT_TRUE(createIface(IfaceType::STA).empty());
}
TEST_F(WifiChip_MultiIfaceTest, CreateStaWithDefaultNames) {
property_set("wifi.interface.0", "");
property_set("wifi.interface.1", "");
property_set("wifi.interface.2", "");
property_set("wifi.interface", "");
property_set("wifi.concurrent.interface", "");
findModeAndConfigureForIfaceType(IfaceType::STA);
ASSERT_EQ(createIface(IfaceType::STA), "wlan0");
ASSERT_EQ(createIface(IfaceType::STA), "wlan1");
ASSERT_EQ(createIface(IfaceType::STA), "wlan2");
}
TEST_F(WifiChip_MultiIfaceTest, CreateStaWithCustomNames) {
property_set("wifi.interface.0", "test0");
property_set("wifi.interface.1", "test1");
property_set("wifi.interface.2", "test2");
property_set("wifi.interface", "bad0");
property_set("wifi.concurrent.interface", "bad1");
findModeAndConfigureForIfaceType(IfaceType::STA);
ASSERT_EQ(createIface(IfaceType::STA), "test0");
ASSERT_EQ(createIface(IfaceType::STA), "test1");
ASSERT_EQ(createIface(IfaceType::STA), "test2");
}
TEST_F(WifiChip_MultiIfaceTest, CreateStaWithCustomAltNames) {
property_set("wifi.interface.0", "");
property_set("wifi.interface.1", "");
property_set("wifi.interface.2", "");
property_set("wifi.interface", "testA0");
property_set("wifi.concurrent.interface", "testA1");
findModeAndConfigureForIfaceType(IfaceType::STA);
ASSERT_EQ(createIface(IfaceType::STA), "testA0");
ASSERT_EQ(createIface(IfaceType::STA), "testA1");
ASSERT_EQ(createIface(IfaceType::STA), "wlan2");
}
} // namespace implementation
} // namespace V1_3
} // namespace wifi

View file

@ -41,6 +41,7 @@ constexpr size_t kMaxBufferSizeBytes = 1024 * 1024 * 3;
constexpr uint32_t kMaxRingBufferFileAgeSeconds = 60 * 60 * 10;
constexpr uint32_t kMaxRingBufferFileNum = 20;
constexpr char kTombstoneFolderPath[] = "/data/vendor/tombstones/wifi/";
constexpr unsigned kMaxWlanIfaces = 100;
template <typename Iface>
void invalidateAndClear(std::vector<sp<Iface>>& ifaces, sp<Iface> iface) {
@ -78,16 +79,25 @@ sp<Iface> findUsingName(std::vector<sp<Iface>>& ifaces,
return nullptr;
}
std::string getWlan0IfaceName() {
std::array<char, PROPERTY_VALUE_MAX> buffer;
property_get("wifi.interface", buffer.data(), "wlan0");
return buffer.data();
}
std::string getWlanIfaceName(unsigned idx) {
if (idx >= kMaxWlanIfaces) {
CHECK(false) << "Requested interface beyond wlan" << kMaxWlanIfaces;
return {};
}
std::string getWlan1IfaceName() {
std::array<char, PROPERTY_VALUE_MAX> buffer;
property_get("wifi.concurrent.interface", buffer.data(), "wlan1");
return buffer.data();
std::string propName = "wifi.interface." + std::to_string(idx);
auto res = property_get(propName.c_str(), buffer.data(), nullptr);
if (res > 0) return buffer.data();
if (idx == 0 || idx == 1) {
const char* altPropName =
(idx == 0) ? "wifi.interface" : "wifi.concurrent.interface";
res = property_get(altPropName, buffer.data(), nullptr);
if (res > 0) return buffer.data();
}
return "wlan" + std::to_string(idx);
}
std::string getP2pIfaceName() {
@ -636,13 +646,14 @@ std::pair<WifiStatus, uint32_t> WifiChip::getCapabilitiesInternal_1_3() {
legacy_hal::wifi_error legacy_status;
uint32_t legacy_feature_set;
uint32_t legacy_logger_feature_set;
const auto ifname = getWlanIfaceName(0);
std::tie(legacy_status, legacy_feature_set) =
legacy_hal_.lock()->getSupportedFeatureSet(getWlan0IfaceName());
legacy_hal_.lock()->getSupportedFeatureSet(ifname);
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
return {createWifiStatusFromLegacyError(legacy_status), 0};
}
std::tie(legacy_status, legacy_logger_feature_set) =
legacy_hal_.lock()->getLoggerSupportedFeatureSet(getWlan0IfaceName());
legacy_hal_.lock()->getLoggerSupportedFeatureSet(ifname);
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
// some devices don't support querying logger feature set
legacy_logger_feature_set = 0;
@ -703,8 +714,9 @@ WifiChip::requestChipDebugInfoInternal() {
IWifiChip::ChipDebugInfo result;
legacy_hal::wifi_error legacy_status;
std::string driver_desc;
const auto ifname = getWlanIfaceName(0);
std::tie(legacy_status, driver_desc) =
legacy_hal_.lock()->getDriverVersion(getWlan0IfaceName());
legacy_hal_.lock()->getDriverVersion(ifname);
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
LOG(ERROR) << "Failed to get driver version: "
<< legacyErrorToString(legacy_status);
@ -716,7 +728,7 @@ WifiChip::requestChipDebugInfoInternal() {
std::string firmware_desc;
std::tie(legacy_status, firmware_desc) =
legacy_hal_.lock()->getFirmwareVersion(getWlan0IfaceName());
legacy_hal_.lock()->getFirmwareVersion(ifname);
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
LOG(ERROR) << "Failed to get firmware version: "
<< legacyErrorToString(legacy_status);
@ -734,7 +746,7 @@ WifiChip::requestDriverDebugDumpInternal() {
legacy_hal::wifi_error legacy_status;
std::vector<uint8_t> driver_dump;
std::tie(legacy_status, driver_dump) =
legacy_hal_.lock()->requestDriverMemoryDump(getWlan0IfaceName());
legacy_hal_.lock()->requestDriverMemoryDump(getWlanIfaceName(0));
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
LOG(ERROR) << "Failed to get driver debug dump: "
<< legacyErrorToString(legacy_status);
@ -749,7 +761,7 @@ WifiChip::requestFirmwareDebugDumpInternal() {
legacy_hal::wifi_error legacy_status;
std::vector<uint8_t> firmware_dump;
std::tie(legacy_status, firmware_dump) =
legacy_hal_.lock()->requestFirmwareMemoryDump(getWlan0IfaceName());
legacy_hal_.lock()->requestFirmwareMemoryDump(getWlanIfaceName(0));
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
LOG(ERROR) << "Failed to get firmware debug dump: "
<< legacyErrorToString(legacy_status);
@ -809,7 +821,7 @@ std::pair<WifiStatus, sp<IWifiNanIface>> WifiChip::createNanIfaceInternal() {
return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
}
// These are still assumed to be based on wlan0.
std::string ifname = getWlan0IfaceName();
std::string ifname = getWlanIfaceName(0);
sp<WifiNanIface> iface = new WifiNanIface(ifname, legacy_hal_);
nan_ifaces_.push_back(iface);
for (const auto& callback : event_cb_handler_.getCallbacks()) {
@ -952,7 +964,7 @@ WifiChip::createRttControllerInternal(const sp<IWifiIface>& bound_iface) {
return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
}
sp<WifiRttController> rtt =
new WifiRttController(getWlan0IfaceName(), bound_iface, legacy_hal_);
new WifiRttController(getWlanIfaceName(0), bound_iface, legacy_hal_);
rtt_controllers_.emplace_back(rtt);
return {createWifiStatus(WifiStatusCode::SUCCESS), rtt};
}
@ -963,7 +975,7 @@ WifiChip::getDebugRingBuffersStatusInternal() {
std::vector<legacy_hal::wifi_ring_buffer_status>
legacy_ring_buffer_status_vec;
std::tie(legacy_status, legacy_ring_buffer_status_vec) =
legacy_hal_.lock()->getRingBuffersStatus(getWlan0IfaceName());
legacy_hal_.lock()->getRingBuffersStatus(getWlanIfaceName(0));
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
return {createWifiStatusFromLegacyError(legacy_status), {}};
}
@ -985,7 +997,7 @@ WifiStatus WifiChip::startLoggingToDebugRingBufferInternal(
}
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->startRingBufferLogging(
getWlan0IfaceName(), ring_name,
getWlanIfaceName(0), ring_name,
static_cast<
std::underlying_type<WifiDebugRingBufferVerboseLevel>::type>(
verbose_level),
@ -1002,7 +1014,7 @@ WifiStatus WifiChip::forceDumpToDebugRingBufferInternal(
return status;
}
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->getRingBufferData(getWlan0IfaceName(), ring_name);
legacy_hal_.lock()->getRingBufferData(getWlanIfaceName(0), ring_name);
return createWifiStatusFromLegacyError(legacy_status);
}
@ -1018,7 +1030,7 @@ WifiStatus WifiChip::flushRingBufferToFileInternal() {
WifiStatus WifiChip::stopLoggingToDebugRingBufferInternal() {
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->deregisterRingBufferCallbackHandler(
getWlan0IfaceName());
getWlanIfaceName(0));
return createWifiStatusFromLegacyError(legacy_status);
}
@ -1027,7 +1039,7 @@ WifiChip::getDebugHostWakeReasonStatsInternal() {
legacy_hal::wifi_error legacy_status;
legacy_hal::WakeReasonStats legacy_stats;
std::tie(legacy_status, legacy_stats) =
legacy_hal_.lock()->getWakeReasonStats(getWlan0IfaceName());
legacy_hal_.lock()->getWakeReasonStats(getWlanIfaceName(0));
if (legacy_status != legacy_hal::WIFI_SUCCESS) {
return {createWifiStatusFromLegacyError(legacy_status), {}};
}
@ -1059,10 +1071,10 @@ WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
}
};
legacy_status = legacy_hal_.lock()->registerErrorAlertCallbackHandler(
getWlan0IfaceName(), on_alert_callback);
getWlanIfaceName(0), on_alert_callback);
} else {
legacy_status = legacy_hal_.lock()->deregisterErrorAlertCallbackHandler(
getWlan0IfaceName());
getWlanIfaceName(0));
}
return createWifiStatusFromLegacyError(legacy_status);
}
@ -1070,20 +1082,20 @@ WifiStatus WifiChip::enableDebugErrorAlertsInternal(bool enable) {
WifiStatus WifiChip::selectTxPowerScenarioInternal(
V1_1::IWifiChip::TxPowerScenario scenario) {
auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
getWlan0IfaceName(),
getWlanIfaceName(0),
hidl_struct_util::convertHidlTxPowerScenarioToLegacy(scenario));
return createWifiStatusFromLegacyError(legacy_status);
}
WifiStatus WifiChip::resetTxPowerScenarioInternal() {
auto legacy_status =
legacy_hal_.lock()->resetTxPowerScenario(getWlan0IfaceName());
legacy_hal_.lock()->resetTxPowerScenario(getWlanIfaceName(0));
return createWifiStatusFromLegacyError(legacy_status);
}
WifiStatus WifiChip::setLatencyModeInternal(LatencyMode mode) {
auto legacy_status = legacy_hal_.lock()->setLatencyMode(
getWlan0IfaceName(),
getWlanIfaceName(0),
hidl_struct_util::convertHidlLatencyModeToLegacy(mode));
return createWifiStatusFromLegacyError(legacy_status);
}
@ -1099,7 +1111,7 @@ WifiStatus WifiChip::registerEventCallbackInternal_1_2(
WifiStatus WifiChip::selectTxPowerScenarioInternal_1_2(
TxPowerScenario scenario) {
auto legacy_status = legacy_hal_.lock()->selectTxPowerScenario(
getWlan0IfaceName(),
getWlanIfaceName(0),
hidl_struct_util::convertHidlTxPowerScenarioToLegacy_1_2(scenario));
return createWifiStatusFromLegacyError(legacy_status);
}
@ -1179,7 +1191,7 @@ WifiStatus WifiChip::registerDebugRingBufferCallback() {
};
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->registerRingBufferCallbackHandler(
getWlan0IfaceName(), on_ring_buffer_data_callback);
getWlanIfaceName(0), on_ring_buffer_data_callback);
if (legacy_status == legacy_hal::WIFI_SUCCESS) {
debug_ring_buffer_cb_registered_ = true;
@ -1213,7 +1225,7 @@ WifiStatus WifiChip::registerRadioModeChangeCallback() {
};
legacy_hal::wifi_error legacy_status =
legacy_hal_.lock()->registerRadioModeChangeCallbackHandler(
getWlan0IfaceName(), on_radio_mode_change_callback);
getWlanIfaceName(0), on_radio_mode_change_callback);
return createWifiStatusFromLegacyError(legacy_status);
}
@ -1330,22 +1342,17 @@ bool WifiChip::isValidModeId(ChipModeId mode_id) {
return false;
}
// Return "wlan0", if "wlan0" is not already in use, else return "wlan1".
// This is based on the assumption that we'll have a max of 2 concurrent
// AP/STA ifaces.
// Return the first wlan (wlan0, wlan1 etc.) not already in use.
// This doesn't check the actual presence of these interfaces.
std::string WifiChip::allocateApOrStaIfaceName() {
auto ap_iface = findUsingName(ap_ifaces_, getWlan0IfaceName());
auto sta_iface = findUsingName(sta_ifaces_, getWlan0IfaceName());
if (!ap_iface.get() && !sta_iface.get()) {
return getWlan0IfaceName();
}
ap_iface = findUsingName(ap_ifaces_, getWlan1IfaceName());
sta_iface = findUsingName(sta_ifaces_, getWlan1IfaceName());
if (!ap_iface.get() && !sta_iface.get()) {
return getWlan1IfaceName();
for (unsigned i = 0; i < kMaxWlanIfaces; i++) {
const auto ifname = getWlanIfaceName(i);
if (findUsingName(ap_ifaces_, ifname)) continue;
if (findUsingName(sta_ifaces_, ifname)) continue;
return ifname;
}
// This should never happen. We screwed up somewhere if it did.
CHECK(0) << "wlan0 and wlan1 in use already!";
CHECK(false) << "All wlan interfaces in use already!";
return {};
}