Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit cc338202 authored by Roshan Pius's avatar Roshan Pius
Browse files

wifi(implementation): Add iface combo for 2018

Changes in the CL:
a) Added iface combo for 2018 using a new feature flag.
b) Added a generic algorithm to determine if an iface can be created or
not based on the iface combos supported. This is needed because we now
have to support 3 different combos (2016, 2017, 2018) in the HAL.
The current iface creation logic is hard to adapt to these 3 varying combos.

Bug: 65671875
Bug: 69863101
Test: ./hardware/interfaces/wifi/1.2/default/tests/runtests.sh
Change-Id: Iff8737843abee3d03567930e9faba775eaa82e07
parent 3312801a
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -24,6 +24,9 @@ LOCAL_CPPFLAGS := -Wall -Werror -Wextra
ifdef WIFI_HIDL_FEATURE_AWARE
LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_AWARE
endif
ifdef WIFI_HIDL_FEATURE_DUAL_INTERFACE
LOCAL_CPPFLAGS += -DWIFI_HIDL_FEATURE_DUAL_INTERFACE
endif
LOCAL_SRC_FILES := \
    hidl_struct_util.cpp \
    hidl_sync_util.cpp \
+1 −0
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ class MockWifiFeatureFlags : public WifiFeatureFlags {
    MockWifiFeatureFlags();

    MOCK_METHOD0(isAwareSupported, bool());
    MOCK_METHOD0(isDualInterfaceSupported, bool());
};

}  // namespace feature_flags
+203 −29
Original line number Diff line number Diff line
@@ -46,24 +46,31 @@ class WifiChipTest : public Test {
    void setupV1IfaceCombination() {
        EXPECT_CALL(*feature_flags_, isAwareSupported())
            .WillRepeatedly(testing::Return(false));
        chip_->getAvailableModes(
            [](const WifiStatus& status,
               const std::vector<WifiChip::ChipMode>& modes) {
                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
                // V1 has 2 modes of operation.
                ASSERT_EQ(2u, modes.size());
            });
        EXPECT_CALL(*feature_flags_, isDualInterfaceSupported())
            .WillRepeatedly(testing::Return(false));
    }

    void setupV1_AwareIfaceCombination() {
        EXPECT_CALL(*feature_flags_, isAwareSupported())
            .WillRepeatedly(testing::Return(true));
        EXPECT_CALL(*feature_flags_, isDualInterfaceSupported())
            .WillRepeatedly(testing::Return(false));
    }

    void setupV2IfaceCombination() {
    void setupV2_AwareIfaceCombination() {
        EXPECT_CALL(*feature_flags_, isAwareSupported())
            .WillRepeatedly(testing::Return(true));
        EXPECT_CALL(*feature_flags_, isDualInterfaceSupported())
            .WillRepeatedly(testing::Return(true));
    }

    void assertNumberOfModes(uint32_t num_modes) {
        chip_->getAvailableModes(
            [](const WifiStatus& status,
            [num_modes](const WifiStatus& status,
                        const std::vector<WifiChip::ChipMode>& modes) {
                ASSERT_EQ(WifiStatusCode::SUCCESS, status.code);
                // V2 has 2 modes of operation.
                ASSERT_EQ(2u, modes.size());
                // V2_Aware has 1 mode of operation.
                ASSERT_EQ(num_modes, modes.size());
            });
    }

@@ -199,8 +206,10 @@ class WifiChipTest : public Test {
class WifiChipV1IfaceCombinationTest : public WifiChipTest {
   public:
    void SetUp() override {
        WifiChipTest::SetUp();
        setupV1IfaceCombination();
        WifiChipTest::SetUp();
        // V1 has 2 modes of operation.
        assertNumberOfModes(2u);
    }
};

@@ -250,57 +259,62 @@ TEST_F(WifiChipV1IfaceCombinationTest, ApMode_CreateNan_ShouldFail) {
    ASSERT_TRUE(createIface(IfaceType::NAN).empty());
}

////////// V2 Iface Combinations ////////////
////////// V1 + Aware Iface Combinations ////////////
// Mode 1 - STA + P2P/NAN
// Mode 2 - AP
class WifiChipV2IfaceCombinationTest : public WifiChipTest {
class WifiChipV1_AwareIfaceCombinationTest : public WifiChipTest {
   public:
    void SetUp() override {
        setupV1_AwareIfaceCombination();
        WifiChipTest::SetUp();
        setupV2IfaceCombination();
        // V1_Aware has 2 modes of operation.
        assertNumberOfModes(2u);
    }
};

TEST_F(WifiChipV2IfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) {
TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateSta_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest, StaMode_CreateP2p_ShouldSucceed) {
TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateP2p_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest, StaMode_CreateNan_ShouldSucceed) {
TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateNan_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::NAN).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest, StaMode_CreateAp_ShouldFail) {
TEST_F(WifiChipV1_AwareIfaceCombinationTest, StaMode_CreateAp_ShouldFail) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_TRUE(createIface(IfaceType::AP).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest, StaMode_CreateStaP2p_ShouldSucceed) {
TEST_F(WifiChipV1_AwareIfaceCombinationTest,
       StaMode_CreateStaP2p_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest, StaMode_CreateStaNan_ShouldSucceed) {
TEST_F(WifiChipV1_AwareIfaceCombinationTest,
       StaMode_CreateStaNan_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
    ASSERT_FALSE(createIface(IfaceType::NAN).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest, StaMode_CreateStaP2PNan_ShouldFail) {
TEST_F(WifiChipV1_AwareIfaceCombinationTest,
       StaMode_CreateStaP2PNan_ShouldFail) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
    ASSERT_TRUE(createIface(IfaceType::NAN).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest,
TEST_F(WifiChipV1_AwareIfaceCombinationTest,
       StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
@@ -313,7 +327,7 @@ TEST_F(WifiChipV2IfaceCombinationTest,
    ASSERT_FALSE(createIface(IfaceType::NAN).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest,
TEST_F(WifiChipV1_AwareIfaceCombinationTest,
       StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
@@ -326,26 +340,186 @@ TEST_F(WifiChipV2IfaceCombinationTest,
    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest, ApMode_CreateAp_ShouldSucceed) {
TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateAp_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::AP);
    ASSERT_FALSE(createIface(IfaceType::AP).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest, ApMode_CreateSta_ShouldFail) {
TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateSta_ShouldFail) {
    findModeAndConfigureForIfaceType(IfaceType::AP);
    ASSERT_TRUE(createIface(IfaceType::STA).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest, ApMode_CreateP2p_ShouldFail) {
TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateP2p_ShouldFail) {
    findModeAndConfigureForIfaceType(IfaceType::AP);
    ASSERT_TRUE(createIface(IfaceType::STA).empty());
}

TEST_F(WifiChipV1_AwareIfaceCombinationTest, ApMode_CreateNan_ShouldFail) {
    findModeAndConfigureForIfaceType(IfaceType::AP);
    ASSERT_TRUE(createIface(IfaceType::NAN).empty());
}

////////// V2 + Aware Iface Combinations ////////////
// Mode 1 - STA + STA/AP
//        - STA + P2P/NAN
class WifiChipV2_AwareIfaceCombinationTest : public WifiChipTest {
   public:
    void SetUp() override {
        setupV2_AwareIfaceCombination();
        WifiChipTest::SetUp();
        // V2_Aware has 1 mode of operation.
        assertNumberOfModes(1u);
    }
};

TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateSta_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
}

TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateP2p_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
}

TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateNan_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::NAN).empty());
}

TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateAp_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::AP).empty());
}

TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaSta_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::AP);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
}

TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaAp_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::AP);
    ASSERT_FALSE(createIface(IfaceType::AP).empty());
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
}

TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaStaAp_ShouldFail) {
    findModeAndConfigureForIfaceType(IfaceType::AP);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
    ASSERT_TRUE(createIface(IfaceType::AP).empty());
}

TEST_F(WifiChipV2_AwareIfaceCombinationTest,
       CreateStaAp_AfterStaRemove_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
    const auto sta_iface_name = createIface(IfaceType::STA);
    ASSERT_FALSE(sta_iface_name.empty());
    ASSERT_TRUE(createIface(IfaceType::AP).empty());

    // After removing STA iface, AP iface creation should succeed.
    removeIface(IfaceType::STA, sta_iface_name);
    ASSERT_FALSE(createIface(IfaceType::AP).empty());
}

TEST_F(WifiChipV2_AwareIfaceCombinationTest,
       CreateStaSta_AfterApRemove_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
    const auto ap_iface_name = createIface(IfaceType::AP);
    ASSERT_FALSE(ap_iface_name.empty());
    ASSERT_TRUE(createIface(IfaceType::STA).empty());

    // After removing AP  iface, STA iface creation should succeed.
    removeIface(IfaceType::AP, ap_iface_name);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
}

TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2p_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
}

TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaNan_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
    ASSERT_FALSE(createIface(IfaceType::NAN).empty());
}

TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateStaP2PNan_ShouldFail) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
    ASSERT_TRUE(createIface(IfaceType::NAN).empty());
}

TEST_F(WifiChipV2_AwareIfaceCombinationTest,
       CreateStaNan_AfterP2pRemove_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
    const auto p2p_iface_name = createIface(IfaceType::P2P);
    ASSERT_FALSE(p2p_iface_name.empty());
    ASSERT_TRUE(createIface(IfaceType::NAN).empty());

    // After removing P2P iface, NAN iface creation should succeed.
    removeIface(IfaceType::P2P, p2p_iface_name);
    ASSERT_FALSE(createIface(IfaceType::NAN).empty());
}

TEST_F(WifiChipV2_AwareIfaceCombinationTest,
       CreateStaP2p_AfterNanRemove_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
    const auto nan_iface_name = createIface(IfaceType::NAN);
    ASSERT_FALSE(nan_iface_name.empty());
    ASSERT_TRUE(createIface(IfaceType::P2P).empty());

    // After removing NAN iface, P2P iface creation should succeed.
    removeIface(IfaceType::NAN, nan_iface_name);
    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
}

TEST_F(WifiChipV2IfaceCombinationTest, ApMode_CreateNan_ShouldFail) {
TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApNan_ShouldFail) {
    findModeAndConfigureForIfaceType(IfaceType::AP);
    ASSERT_FALSE(createIface(IfaceType::AP).empty());
    ASSERT_TRUE(createIface(IfaceType::NAN).empty());
}

TEST_F(WifiChipV2_AwareIfaceCombinationTest, CreateApP2p_ShouldFail) {
    findModeAndConfigureForIfaceType(IfaceType::AP);
    ASSERT_FALSE(createIface(IfaceType::AP).empty());
    ASSERT_TRUE(createIface(IfaceType::P2P).empty());
}

TEST_F(WifiChipV2_AwareIfaceCombinationTest,
       StaMode_CreateStaNan_AfterP2pRemove_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
    const auto p2p_iface_name = createIface(IfaceType::P2P);
    ASSERT_FALSE(p2p_iface_name.empty());
    ASSERT_TRUE(createIface(IfaceType::NAN).empty());

    // After removing P2P iface, NAN iface creation should succeed.
    removeIface(IfaceType::P2P, p2p_iface_name);
    ASSERT_FALSE(createIface(IfaceType::NAN).empty());
}

TEST_F(WifiChipV2_AwareIfaceCombinationTest,
       StaMode_CreateStaP2p_AfterNanRemove_ShouldSucceed) {
    findModeAndConfigureForIfaceType(IfaceType::STA);
    ASSERT_FALSE(createIface(IfaceType::STA).empty());
    const auto nan_iface_name = createIface(IfaceType::NAN);
    ASSERT_FALSE(nan_iface_name.empty());
    ASSERT_TRUE(createIface(IfaceType::P2P).empty());

    // After removing NAN iface, P2P iface creation should succeed.
    removeIface(IfaceType::NAN, nan_iface_name);
    ASSERT_FALSE(createIface(IfaceType::P2P).empty());
}
}  // namespace implementation
}  // namespace V1_2
}  // namespace wifi
+210 −61

File changed.

Preview size limit exceeded, changes collapsed.

+13 −0
Original line number Diff line number Diff line
@@ -193,6 +193,17 @@ class WifiChip : public V1_1::IWifiChip {
        std::unique_lock<std::recursive_mutex>* lock, ChipModeId mode_id);
    WifiStatus registerDebugRingBufferCallback();

    void populateModes();
    std::vector<IWifiChip::ChipIfaceCombination>
    getCurrentModeIfaceCombinations();
    std::map<IfaceType, size_t> getCurrentIfaceCombination();
    std::vector<std::map<IfaceType, size_t>> expandIfaceCombinations(
        const IWifiChip::ChipIfaceCombination& combination);
    bool canExpandedIfaceCombinationSupportIfaceOfType(
        const std::map<IfaceType, size_t>& combo, IfaceType type);
    bool canCurrentModeSupportIfaceOfType(IfaceType type);
    bool isValidModeId(ChipModeId mode_id);

    ChipId chip_id_;
    std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;
    std::weak_ptr<mode_controller::WifiModeController> mode_controller_;
@@ -203,7 +214,9 @@ class WifiChip : public V1_1::IWifiChip {
    std::vector<sp<WifiStaIface>> sta_ifaces_;
    std::vector<sp<WifiRttController>> rtt_controllers_;
    bool is_valid_;
    // Members pertaining to chip configuration.
    uint32_t current_mode_id_;
    std::vector<IWifiChip::ChipMode> modes_;
    // The legacy ring buffer callback API has only a global callback
    // registration mechanism. Use this to check if we have already
    // registered a callback.
Loading