binder: Add/Implement More iface calls

Add/Implement few more |IIface| aidl object functions:
1. Power Save Mode
2. TDLS Discover
3. TDLS Setup
4. TDLS Teardown

BUG: 30759904
Change-Id: I604f8addc2fe009a2f4abb67d487d729b6558a12
TEST: None.
Signed-off-by: Roshan Pius <rpius@google.com>
diff --git a/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl b/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl
index f05d086..4769419 100644
--- a/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl
+++ b/wpa_supplicant/binder/fi/w1/wpa_supplicant/IIface.aidl
@@ -28,6 +28,9 @@
 	/* Network being removed/retrieved does not exist */
 	const int ERROR_NETWORK_UNKNOWN = 5;
 
+	/** Length of mac_address param in |InitiateTDLS|* functions. */
+	const int MAC_ADDRESS_LEN = 6;
+
 	/**
 	 * Retrieves the name of the network interface.
 	 *
@@ -91,4 +94,31 @@
 	 */
 	void Disconnect();
 
+	/**
+	 * Turn on/off power save mode for the interface.
+	 *
+	 * @param enable Indicate if power save is to be turned on/off.
+	 */
+	void SetPowerSave(boolean enable);
+
+	/**
+	 * Initiate TDLS discover with the provided peer mac address.
+	 *
+	 * @param mac_address MAC address of the peer.
+	 */
+	void InitiateTDLSDiscover(in byte[] mac_address);
+
+	/**
+	 * Initiate TDLS setup with the provided peer mac address.
+	 *
+	 * @param mac_address MAC address of the peer.
+	 */
+	void InitiateTDLSSetup(in byte[] mac_address);
+
+	/**
+	 * Initiate TDLS teardown with the provided peer mac address.
+	 *
+	 * @param mac_address MAC address of the peer.
+	 */
+	void InitiateTDLSTeardown(in byte[] mac_address);
 }
diff --git a/wpa_supplicant/binder/iface.cpp b/wpa_supplicant/binder/iface.cpp
index 0ff407a..624e467 100644
--- a/wpa_supplicant/binder/iface.cpp
+++ b/wpa_supplicant/binder/iface.cpp
@@ -164,6 +164,107 @@
 	return android::binder::Status::ok();
 }
 
+android::binder::Status Iface::SetPowerSave(bool enable)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	RETURN_IF_IFACE_INVALID(wpa_s);
+	if (wpa_drv_set_p2p_powersave(wpa_s, enable, -1, -1)) {
+		const std::string error_msg = "Failed setting power save mode" +
+					      std::to_string(enable) + ".";
+		return android::binder::Status::fromServiceSpecificError(
+		    ERROR_GENERIC, error_msg.c_str());
+	}
+	return android::binder::Status::ok();
+}
+
+android::binder::Status Iface::InitiateTDLSDiscover(
+    const std::vector<uint8_t> &mac_address)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	RETURN_IF_IFACE_INVALID(wpa_s);
+
+	if (mac_address.size() != MAC_ADDRESS_LEN) {
+		const std::string error_msg =
+		    "Invalid MAC address value length: " +
+		    std::to_string(mac_address.size()) + ".";
+		return android::binder::Status::fromExceptionCode(
+		    android::binder::Status::EX_ILLEGAL_ARGUMENT,
+		    error_msg.c_str());
+	}
+	int ret;
+	const u8 *peer = mac_address.data();
+	if (wpa_tdls_is_external_setup(wpa_s->wpa)) {
+		ret = wpa_tdls_send_discovery_request(wpa_s->wpa, peer);
+	} else {
+		ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
+	}
+	if (ret) {
+		return android::binder::Status::fromServiceSpecificError(
+		    ERROR_GENERIC, "Failed to initiate TDLS Discover.");
+	}
+	return android::binder::Status::ok();
+}
+
+android::binder::Status Iface::InitiateTDLSSetup(
+    const std::vector<uint8_t> &mac_address)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	RETURN_IF_IFACE_INVALID(wpa_s);
+
+	if (mac_address.size() != MAC_ADDRESS_LEN) {
+		const std::string error_msg =
+		    "Invalid MAC address value length: " +
+		    std::to_string(mac_address.size()) + ".";
+		return android::binder::Status::fromExceptionCode(
+		    android::binder::Status::EX_ILLEGAL_ARGUMENT,
+		    error_msg.c_str());
+	}
+	int ret;
+	const u8 *peer = mac_address.data();
+	if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
+	    !(wpa_s->conf->tdls_external_control)) {
+		wpa_tdls_remove(wpa_s->wpa, peer);
+		ret = wpa_tdls_start(wpa_s->wpa, peer);
+	} else {
+		ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
+	}
+	if (ret) {
+		return android::binder::Status::fromServiceSpecificError(
+		    ERROR_GENERIC, "Failed to initiate TDLS Setup.");
+	}
+	return android::binder::Status::ok();
+}
+
+android::binder::Status Iface::InitiateTDLSTeardown(
+    const std::vector<uint8_t> &mac_address)
+{
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	RETURN_IF_IFACE_INVALID(wpa_s);
+
+	if (mac_address.size() != MAC_ADDRESS_LEN) {
+		const std::string error_msg =
+		    "Invalid MAC address value length: " +
+		    std::to_string(mac_address.size()) + ".";
+		return android::binder::Status::fromExceptionCode(
+		    android::binder::Status::EX_ILLEGAL_ARGUMENT,
+		    error_msg.c_str());
+	}
+	int ret;
+	const u8 *peer = mac_address.data();
+	if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
+	    !(wpa_s->conf->tdls_external_control)) {
+		ret = wpa_tdls_teardown_link(
+		    wpa_s->wpa, peer, WLAN_REASON_TDLS_TEARDOWN_UNSPECIFIED);
+	} else {
+		ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
+	}
+	if (ret) {
+		return android::binder::Status::fromServiceSpecificError(
+		    ERROR_GENERIC, "Failed to initiate TDLS Teardown.");
+	}
+	return android::binder::Status::ok();
+}
+
 /**
  * Retrieve the underlying |wpa_supplicant| struct pointer for
  * this iface.
diff --git a/wpa_supplicant/binder/iface.h b/wpa_supplicant/binder/iface.h
index 4ebf59c..96d52ce 100644
--- a/wpa_supplicant/binder/iface.h
+++ b/wpa_supplicant/binder/iface.h
@@ -19,6 +19,7 @@
 #include "utils/common.h"
 #include "utils/includes.h"
 #include "wpa_supplicant_i.h"
+#include "driver_i.h"
 }
 
 namespace wpa_supplicant_binder {
@@ -50,6 +51,13 @@
 	android::binder::Status Reassociate() override;
 	android::binder::Status Reconnect() override;
 	android::binder::Status Disconnect() override;
+	android::binder::Status SetPowerSave(bool enable) override;
+	android::binder::Status InitiateTDLSDiscover(
+	    const std::vector<uint8_t> &mac_address) override;
+	android::binder::Status InitiateTDLSSetup(
+	    const std::vector<uint8_t> &mac_address) override;
+	android::binder::Status InitiateTDLSTeardown(
+	    const std::vector<uint8_t> &mac_address) override;
 
 private:
 	struct wpa_supplicant *retrieveIfacePtr();