wifi(implementation): Different names for concurrent ifaces

Allocate different iface names (wlan0, wlan1) for concurrent ifaces.

Bug: 65671875
Test: ./hardware/interfaces/wifi/1.2/default/tests/runtests.sh
Change-Id: Ie544404183dbb616a20f88f4fb3ce71795cf89af
diff --git a/wifi/1.2/default/tests/wifi_chip_unit_tests.cpp b/wifi/1.2/default/tests/wifi_chip_unit_tests.cpp
index e3c51fa..f73869b 100644
--- a/wifi/1.2/default/tests/wifi_chip_unit_tests.cpp
+++ b/wifi/1.2/default/tests/wifi_chip_unit_tests.cpp
@@ -520,6 +520,26 @@
     removeIface(IfaceType::NAN, nan_iface_name);
     ASSERT_FALSE(createIface(IfaceType::P2P).empty());
 }
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest,
+       CreateStaSta_EnsureDifferentIfaceNames) {
+    findModeAndConfigureForIfaceType(IfaceType::AP);
+    const auto sta1_iface_name = createIface(IfaceType::STA);
+    const auto sta2_iface_name = createIface(IfaceType::STA);
+    ASSERT_FALSE(sta1_iface_name.empty());
+    ASSERT_FALSE(sta2_iface_name.empty());
+    ASSERT_NE(sta1_iface_name, sta2_iface_name);
+}
+
+TEST_F(WifiChipV2_AwareIfaceCombinationTest,
+       CreateStaAp_EnsureDifferentIfaceNames) {
+    findModeAndConfigureForIfaceType(IfaceType::AP);
+    const auto sta_iface_name = createIface(IfaceType::STA);
+    const auto ap_iface_name = createIface(IfaceType::AP);
+    ASSERT_FALSE(sta_iface_name.empty());
+    ASSERT_FALSE(ap_iface_name.empty());
+    ASSERT_NE(sta_iface_name, ap_iface_name);
+}
 }  // namespace implementation
 }  // namespace V1_2
 }  // namespace wifi
diff --git a/wifi/1.2/default/wifi_chip.cpp b/wifi/1.2/default/wifi_chip.cpp
index d7be38f..adba054 100644
--- a/wifi/1.2/default/wifi_chip.cpp
+++ b/wifi/1.2/default/wifi_chip.cpp
@@ -81,13 +81,11 @@
     return buffer.data();
 }
 
-/** Not used yet.
 std::string getWlan1IfaceName() {
-  std::array<char, PROPERTY_VALUE_MAX> buffer;
-  property_get("wifi.concurrent.interface", buffer.data(), "wlan1");
-  return buffer.data();
+    std::array<char, PROPERTY_VALUE_MAX> buffer;
+    property_get("wifi.concurrent.interface", buffer.data(), "wlan1");
+    return buffer.data();
 }
-*/
 
 std::string getP2pIfaceName() {
     std::array<char, PROPERTY_VALUE_MAX> buffer;
@@ -506,7 +504,7 @@
     if (!canCurrentModeSupportIfaceOfType(IfaceType::AP)) {
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
-    std::string ifname = getWlan0IfaceName();
+    std::string ifname = allocateApOrStaIfaceName();
     sp<WifiApIface> iface = new WifiApIface(ifname, legacy_hal_);
     ap_ifaces_.push_back(iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
@@ -552,6 +550,7 @@
     if (!canCurrentModeSupportIfaceOfType(IfaceType::NAN)) {
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
+    // These are still assumed to be based on wlan0.
     std::string ifname = getWlan0IfaceName();
     sp<WifiNanIface> iface = new WifiNanIface(ifname, legacy_hal_);
     nan_ifaces_.push_back(iface);
@@ -644,7 +643,7 @@
     if (!canCurrentModeSupportIfaceOfType(IfaceType::STA)) {
         return {createWifiStatus(WifiStatusCode::ERROR_NOT_AVAILABLE), {}};
     }
-    std::string ifname = getWlan0IfaceName();
+    std::string ifname = allocateApOrStaIfaceName();
     sp<WifiStaIface> iface = new WifiStaIface(ifname, legacy_hal_);
     sta_ifaces_.push_back(iface);
     for (const auto& callback : event_cb_handler_.getCallbacks()) {
@@ -1061,6 +1060,25 @@
     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.
+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();
+    }
+    // This should never happen. We screwed up somewhere if it did.
+    CHECK(0) << "wlan0 and wlan1 in use already!";
+    return {};
+}
+
 }  // namespace implementation
 }  // namespace V1_2
 }  // namespace wifi
diff --git a/wifi/1.2/default/wifi_chip.h b/wifi/1.2/default/wifi_chip.h
index 472a694..97c434e 100644
--- a/wifi/1.2/default/wifi_chip.h
+++ b/wifi/1.2/default/wifi_chip.h
@@ -203,6 +203,7 @@
         const std::map<IfaceType, size_t>& combo, IfaceType type);
     bool canCurrentModeSupportIfaceOfType(IfaceType type);
     bool isValidModeId(ChipModeId mode_id);
+    std::string allocateApOrStaIfaceName();
 
     ChipId chip_id_;
     std::weak_ptr<legacy_hal::WifiLegacyHal> legacy_hal_;