hostapd: Upgrade hostapd hidl to 1.2

Add new API support: Hostapd::forceClientDisconnect

Bug:142752869
Test: Manual Test
Test: VtsHalWifiHostapdV1_0Target
Test: VtsHalWifiHostapdV1_1Target
Change-Id: I7b11fec6b3df01838006f3cc6616d1a828ac96c6
diff --git a/hostapd/Android.mk b/hostapd/Android.mk
index 24f1403..e9035e5 100644
--- a/hostapd/Android.mk
+++ b/hostapd/Android.mk
@@ -1132,6 +1132,7 @@
 ifeq ($(HOSTAPD_USE_HIDL), y)
 LOCAL_SHARED_LIBRARIES += android.hardware.wifi.hostapd@1.0
 LOCAL_SHARED_LIBRARIES += android.hardware.wifi.hostapd@1.1
+LOCAL_SHARED_LIBRARIES += android.hardware.wifi.hostapd@1.2
 LOCAL_SHARED_LIBRARIES += libbase libhidlbase libutils
 LOCAL_STATIC_LIBRARIES += libhostapd_hidl
 endif
@@ -1174,13 +1175,14 @@
 LOCAL_CPPFLAGS := $(L_CPPFLAGS)
 LOCAL_CFLAGS := $(L_CFLAGS)
 LOCAL_C_INCLUDES := $(INCLUDES)
-HIDL_INTERFACE_VERSION = 1.1
+HIDL_INTERFACE_VERSION = 1.2
 LOCAL_SRC_FILES := \
     hidl/$(HIDL_INTERFACE_VERSION)/hidl.cpp \
     hidl/$(HIDL_INTERFACE_VERSION)/hostapd.cpp
 LOCAL_SHARED_LIBRARIES := \
     android.hardware.wifi.hostapd@1.0 \
     android.hardware.wifi.hostapd@1.1 \
+    android.hardware.wifi.hostapd@1.2 \
     libbase \
     libhidlbase \
     libutils \
diff --git a/hostapd/hidl/1.1/hidl.cpp b/hostapd/hidl/1.2/hidl.cpp
similarity index 93%
rename from hostapd/hidl/1.1/hidl.cpp
rename to hostapd/hidl/1.2/hidl.cpp
index 2051e7b..4bde312 100644
--- a/hostapd/hidl/1.1/hidl.cpp
+++ b/hostapd/hidl/1.2/hidl.cpp
@@ -22,8 +22,8 @@
 
 using android::hardware::configureRpcThreadpool;
 using android::hardware::IPCThreadState;
-using android::hardware::wifi::hostapd::V1_1::IHostapd;
-using android::hardware::wifi::hostapd::V1_1::implementation::Hostapd;
+using android::hardware::wifi::hostapd::V1_2::IHostapd;
+using android::hardware::wifi::hostapd::V1_2::implementation::Hostapd;
 
 // This file is a bridge between the hostapd code written in 'C' and the HIDL
 // interface in C++. So, using "C" style static globals here!
diff --git a/hostapd/hidl/1.1/hidl.h b/hostapd/hidl/1.2/hidl.h
similarity index 100%
rename from hostapd/hidl/1.1/hidl.h
rename to hostapd/hidl/1.2/hidl.h
diff --git a/hostapd/hidl/1.1/hidl_return_util.h b/hostapd/hidl/1.2/hidl_return_util.h
similarity index 83%
rename from hostapd/hidl/1.1/hidl_return_util.h
rename to hostapd/hidl/1.2/hidl_return_util.h
index d914ee2..81742f8 100644
--- a/hostapd/hidl/1.1/hidl_return_util.h
+++ b/hostapd/hidl/1.2/hidl_return_util.h
@@ -16,7 +16,7 @@
 namespace hardware {
 namespace wifi {
 namespace hostapd {
-namespace V1_1 {
+namespace V1_2 {
 namespace implementation {
 namespace hidl_return_util {
 
@@ -25,18 +25,17 @@
  * HIDL interface object.
  */
 // Use for HIDL methods which return only an instance of HostapdStatus.
-template <typename ObjT, typename WorkFuncT, typename... Args>
+template <typename ObjT, typename WorkFuncT, typename StatusT, typename... Args>
 Return<void> call(
     ObjT* obj, WorkFuncT&& work,
-    const std::function<void(const HostapdStatus&)>& hidl_cb, Args&&... args)
+    const std::function<void(const StatusT&)>& hidl_cb, Args&&... args)
 {
 	hidl_cb((obj->*work)(std::forward<Args>(args)...));
 	return Void();
 }
-
 }  // namespace hidl_return_util
 }  // namespace implementation
-}  // namespace V1_1
+}  // namespace V1_2
 }  // namespace hostapd
 }  // namespace wifi
 }  // namespace hardware
diff --git a/hostapd/hidl/1.1/hostapd.cpp b/hostapd/hidl/1.2/hostapd.cpp
similarity index 81%
rename from hostapd/hidl/1.1/hostapd.cpp
rename to hostapd/hidl/1.2/hostapd.cpp
index 0298537..50e0a82 100644
--- a/hostapd/hidl/1.1/hostapd.cpp
+++ b/hostapd/hidl/1.2/hostapd.cpp
@@ -33,7 +33,7 @@
 using android::base::RemoveFileIfExists;
 using android::base::StringPrintf;
 using android::base::WriteStringToFile;
-using android::hardware::wifi::hostapd::V1_1::IHostapd;
+using android::hardware::wifi::hostapd::V1_2::IHostapd;
 
 std::string WriteHostapdConfig(
     const std::string& interface_name, const std::string& config)
@@ -224,7 +224,7 @@
 namespace hardware {
 namespace wifi {
 namespace hostapd {
-namespace V1_1 {
+namespace V1_2 {
 namespace implementation {
 using hidl_return_util::call;
 using namespace android::hardware::wifi::hostapd::V1_0;
@@ -265,38 +265,48 @@
 }
 
 Return<void> Hostapd::registerCallback(
-    const sp<IHostapdCallback>& callback, registerCallback_cb _hidl_cb)
+    const sp<V1_1::IHostapdCallback>& callback, registerCallback_cb _hidl_cb)
 {
 	return call(
 	    this, &Hostapd::registerCallbackInternal, _hidl_cb, callback);
 }
 
-HostapdStatus Hostapd::addAccessPointInternal(
+Return<void> Hostapd::forceClientDisconnect(
+    const hidl_string& iface_name, const hidl_array<uint8_t, 6>& client_address,
+    V1_2::Ieee80211ReasonCode reason_code, forceClientDisconnect_cb _hidl_cb)
+{
+	return call(
+	    this, &Hostapd::forceClientDisconnectInternal, _hidl_cb, iface_name,
+	    client_address, reason_code);
+}
+
+
+V1_0::HostapdStatus Hostapd::addAccessPointInternal(
     const V1_0::IHostapd::IfaceParams& iface_params,
     const NetworkParams& nw_params)
 {
-	return {HostapdStatusCode::FAILURE_UNKNOWN, ""};
+	return {V1_0::HostapdStatusCode::FAILURE_UNKNOWN, ""};
 }
 
-HostapdStatus Hostapd::addAccessPointInternal_1_1(
+V1_0::HostapdStatus Hostapd::addAccessPointInternal_1_1(
     const IfaceParams& iface_params, const NetworkParams& nw_params)
 {
 	if (hostapd_get_iface(interfaces_, iface_params.V1_0.ifaceName.c_str())) {
 		wpa_printf(
 		    MSG_ERROR, "Interface %s already present",
 		    iface_params.V1_0.ifaceName.c_str());
-		return {HostapdStatusCode::FAILURE_IFACE_EXISTS, ""};
+		return {V1_0::HostapdStatusCode::FAILURE_IFACE_EXISTS, ""};
 	}
 	const auto conf_params = CreateHostapdConfig(iface_params, nw_params);
 	if (conf_params.empty()) {
 		wpa_printf(MSG_ERROR, "Failed to create config params");
-		return {HostapdStatusCode::FAILURE_ARGS_INVALID, ""};
+		return {V1_0::HostapdStatusCode::FAILURE_ARGS_INVALID, ""};
 	}
 	const auto conf_file_path =
 	    WriteHostapdConfig(iface_params.V1_0.ifaceName, conf_params);
 	if (conf_file_path.empty()) {
 		wpa_printf(MSG_ERROR, "Failed to write config file");
-		return {HostapdStatusCode::FAILURE_UNKNOWN, ""};
+		return {V1_0::HostapdStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	std::string add_iface_param_str = StringPrintf(
 	    "%s config=%s", iface_params.V1_0.ifaceName.c_str(),
@@ -307,7 +317,7 @@
 		wpa_printf(
 		    MSG_ERROR, "Adding interface %s failed",
 		    add_iface_param_str.c_str());
-		return {HostapdStatusCode::FAILURE_UNKNOWN, ""};
+		return {V1_0::HostapdStatusCode::FAILURE_UNKNOWN, ""};
 	}
 	struct hostapd_data* iface_hapd =
 	    hostapd_get_iface(interfaces_, iface_params.V1_0.ifaceName.c_str());
@@ -333,12 +343,12 @@
 		wpa_printf(
 		    MSG_ERROR, "Enabling interface %s failed",
 		    iface_params.V1_0.ifaceName.c_str());
-		return {HostapdStatusCode::FAILURE_UNKNOWN, ""};
+		return {V1_0::HostapdStatusCode::FAILURE_UNKNOWN, ""};
 	}
-	return {HostapdStatusCode::SUCCESS, ""};
+	return {V1_0::HostapdStatusCode::SUCCESS, ""};
 }
 
-HostapdStatus Hostapd::removeAccessPointInternal(const std::string& iface_name)
+V1_0::HostapdStatus Hostapd::removeAccessPointInternal(const std::string& iface_name)
 {
 	std::vector<char> remove_iface_param_vec(
 	    iface_name.begin(), iface_name.end() + 1);
@@ -347,20 +357,42 @@
 		wpa_printf(
 		    MSG_ERROR, "Removing interface %s failed",
 		    iface_name.c_str());
-		return {HostapdStatusCode::FAILURE_UNKNOWN, ""};
+		return {V1_0::HostapdStatusCode::FAILURE_UNKNOWN, ""};
 	}
-	return {HostapdStatusCode::SUCCESS, ""};
+	return {V1_0::HostapdStatusCode::SUCCESS, ""};
 }
 
-HostapdStatus Hostapd::registerCallbackInternal(
-    const sp<IHostapdCallback>& callback)
+V1_0::HostapdStatus Hostapd::registerCallbackInternal(
+    const sp<V1_1::IHostapdCallback>& callback)
 {
 	callbacks_.push_back(callback);
-	return {HostapdStatusCode::SUCCESS, ""};
+	return {V1_0::HostapdStatusCode::SUCCESS, ""};
+}
+
+V1_2::HostapdStatus Hostapd::forceClientDisconnectInternal(const std::string& iface_name,
+    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;
+	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, ""};
+		}
+	}
+	return {V1_2::HostapdStatusCode::FAILURE_CLIENT_UNKNOWN, ""};
 }
 
 }  // namespace implementation
-}  // namespace V1_1
+}  // namespace V1_2
 }  // namespace hostapd
 }  // namespace wifi
 }  // namespace hardware
diff --git a/hostapd/hidl/1.1/hostapd.h b/hostapd/hidl/1.2/hostapd.h
similarity index 69%
rename from hostapd/hidl/1.1/hostapd.h
rename to hostapd/hidl/1.2/hostapd.h
index e2b4ba8..80db4e9 100644
--- a/hostapd/hidl/1.1/hostapd.h
+++ b/hostapd/hidl/1.2/hostapd.h
@@ -14,7 +14,7 @@
 
 #include <android-base/macros.h>
 
-#include <android/hardware/wifi/hostapd/1.1/IHostapd.h>
+#include <android/hardware/wifi/hostapd/1.2/IHostapd.h>
 #include <android/hardware/wifi/hostapd/1.1/IHostapdCallback.h>
 
 extern "C"
@@ -23,13 +23,14 @@
 #include "utils/includes.h"
 #include "utils/wpa_debug.h"
 #include "ap/hostapd.h"
+#include "ap/sta_info.h"
 }
 
 namespace android {
 namespace hardware {
 namespace wifi {
 namespace hostapd {
-namespace V1_1 {
+namespace V1_2 {
 namespace implementation {
 using namespace android::hardware::wifi::hostapd::V1_0;
 
@@ -38,7 +39,7 @@
  * object is used core for global control operations on
  * hostapd.
  */
-class Hostapd : public V1_1::IHostapd
+class Hostapd : public V1_2::IHostapd
 {
 public:
 	Hostapd(hapd_interfaces* interfaces);
@@ -56,29 +57,34 @@
 	    removeAccessPoint_cb _hidl_cb) override;
 	Return<void> terminate() override;
 	Return<void> registerCallback(
-	    const sp<IHostapdCallback>& callback,
+	    const sp<V1_1::IHostapdCallback>& callback,
 	    registerCallback_cb _hidl_cb) override;
-
+	Return<void>forceClientDisconnect(
+	    const hidl_string& iface_name,
+	    const hidl_array<uint8_t, 6>& client_address,
+	    V1_2::Ieee80211ReasonCode reason_code, forceClientDisconnect_cb _hidl_cb) override;
 private:
 	// Corresponding worker functions for the HIDL methods.
-	HostapdStatus addAccessPointInternal(
+	V1_0::HostapdStatus addAccessPointInternal(
 	    const V1_0::IHostapd::IfaceParams& iface_params,
 	    const NetworkParams& nw_params);
-	HostapdStatus addAccessPointInternal_1_1(
+	V1_0::HostapdStatus addAccessPointInternal_1_1(
 	    const IfaceParams& IfaceParams, const NetworkParams& nw_params);
-	HostapdStatus removeAccessPointInternal(const std::string& iface_name);
-	HostapdStatus registerCallbackInternal(
-	    const sp<IHostapdCallback>& callback);
-
+	V1_0::HostapdStatus removeAccessPointInternal(const std::string& iface_name);
+	V1_0::HostapdStatus registerCallbackInternal(
+	    const sp<V1_1::IHostapdCallback>& callback);
+	V1_2::HostapdStatus forceClientDisconnectInternal(
+	    const std::string& iface_name,
+	    const std::array<uint8_t, 6>& client_address,
+	    V1_2::Ieee80211ReasonCode reason_code);
 	// Raw pointer to the global structure maintained by the core.
 	struct hapd_interfaces* interfaces_;
 	// Callbacks registered.
-	std::vector<sp<IHostapdCallback>> callbacks_;
-
+	std::vector<sp<V1_1::IHostapdCallback>> callbacks_;
 	DISALLOW_COPY_AND_ASSIGN(Hostapd);
 };
 }  // namespace implementation
-}  // namespace V1_1
+}  // namespace V1_2
 }  // namespace hostapd
 }  // namespace wifi
 }  // namespace hardware
diff --git a/hostapd/hostapd.android.rc b/hostapd/hostapd.android.rc
index c8792d6..512ca0d 100644
--- a/hostapd/hostapd.android.rc
+++ b/hostapd/hostapd.android.rc
@@ -14,6 +14,7 @@
 service hostapd /vendor/bin/hw/hostapd
     interface android.hardware.wifi.hostapd@1.0::IHostapd default
     interface android.hardware.wifi.hostapd@1.1::IHostapd default
+    interface android.hardware.wifi.hostapd@1.2::IHostapd default
     class main
     capabilities NET_ADMIN NET_RAW
     user wifi