wifi: Supports forceClientDisconnect in bridged mode.

The interface will have two instances (e.q. 2.4 Ghz AP and 5 GHz AP) in dual AP mode.
The hostapd need to know the apIfaceInstance to get correct instance to
force the client disconnect.
Query it from bridge iface when it can't get from iface name.

AP+AP Part 5 includes:
1. Support forceClientDisconnect in dual AP mode.
2. Support dual SoftApInfo callback
   a. New callback onInfoListChanged
   b. Add instanceIdentifier in SoftApInfo but it is used only in
   framework.
   c. Add instanceIdentifier in WifiClient but it is used only in
   framework.

Bug: 162686273
Test: atest -c VtsHalWifiHostapdV1_0TargetTest
Test: atest -c VtsHalWifiHostapdV1_1TargetTest
Test: atest -c VtsHalWifiHostapdV1_2TargetTest
Test: atest -c VtsHalWifiHostapdV1_3TargetTest
Change-Id: Ifc1fda3dbe52adeaf3d7e68fef8f81b2117d8258
diff --git a/hostapd/hidl/1.3/hostapd.cpp b/hostapd/hidl/1.3/hostapd.cpp
index ce20cea..5d64049 100644
--- a/hostapd/hidl/1.3/hostapd.cpp
+++ b/hostapd/hidl/1.3/hostapd.cpp
@@ -545,6 +545,23 @@
 	}
 }
 
+bool forceStaDisconnection(struct hostapd_data* hapd,
+			   const std::array<uint8_t, 6>& client_address,
+			   const uint16_t reason_code) {
+	struct sta_info *sta;
+	for (sta = hapd->sta_list; sta; sta = sta->next) {
+		int res;
+		res = memcmp(sta->addr, client_address.data(), ETH_ALEN);
+		if (res == 0) {
+			wpa_printf(MSG_INFO, "Force client:" MACSTR " disconnect with reason: %d",
+			    MAC2STR(client_address.data()), reason_code);
+			ap_sta_disconnect(hapd, sta, sta->addr, reason_code);
+			return true;
+		}
+	}
+	return false;
+}
+
 // hostapd core functions accept "C" style function pointers, so use global
 // functions to pass to the hostapd core function and store the corresponding
 // std::function methods to be invoked.
@@ -911,20 +928,29 @@
     const std::array<uint8_t, 6>& client_address, V1_2::Ieee80211ReasonCode reason_code)
 {
 	struct hostapd_data *hapd = hostapd_get_iface(interfaces_, iface_name.c_str());
-	struct sta_info *sta;
+	bool result;
+	if (!hapd) {
+	    for (auto const& iface : br_interfaces_) {
+		if (iface.first == iface_name) {
+		    for (auto const& instance : iface.second) {
+			hapd = hostapd_get_iface(interfaces_, instance.c_str());
+			if (hapd) {
+				result = forceStaDisconnection(hapd, client_address,
+							       (uint16_t) reason_code);
+				if (result) break;
+			}
+		    }
+		}
+	    }
+	} else {
+		result = forceStaDisconnection(hapd, client_address, (uint16_t) reason_code);
+	}
 	if (!hapd) {
 		wpa_printf(MSG_ERROR, "Interface %s doesn't exist", iface_name.c_str());
 		return {V1_2::HostapdStatusCode::FAILURE_IFACE_UNKNOWN, ""};
 	}
-	for (sta = hapd->sta_list; sta; sta = sta->next) {
-		int res;
-		res = memcmp(sta->addr, client_address.data(), ETH_ALEN);
-		if (res == 0) {
-			wpa_printf(MSG_INFO, "Force client:" MACSTR " disconnect with reason: %d",
-			    MAC2STR(client_address.data()), (uint16_t) reason_code);
-			ap_sta_disconnect(hapd, sta, sta->addr, (uint16_t) reason_code);
-			return {V1_2::HostapdStatusCode::SUCCESS, ""};
-		}
+	if (result) {
+		return {V1_2::HostapdStatusCode::SUCCESS, ""};
 	}
 	return {V1_2::HostapdStatusCode::FAILURE_CLIENT_UNKNOWN, ""};
 }