wpa_supplicant: HIDL implementation (2/2)

Migrated the AIDL interface to HIDL.

Summary of the changes:
1. Changed method signatures to always invoke a callback with the
status of the operation and possibly a return value.
2. Use hidl_vec, hidl_string, hidl_array in place of
std::vector, std::string, normal array,  for all HIDL method params.
3. Removed all parcelables and instead use the structs declared in the
HIDL interface.
4. Moved all constants to enums and use static_cast to retrieve their
underlying values.
5. Changed the input params for |ISupplicant.createInterface|. Only the
interface name is passed by the caller, the rest of the params are
hardcoded in the implementation of the HIDL interface.
6. Changed any remaining comments from "C" style to "C++" style.
7. Move the implementation to
android::hardware::wifi:supplicant::V1_0::implementation namespace.

TODO's:
1. Need to handle the |notifyNetworkRequest|. This needs some
additional string parsing logic which will be handled in a future CL.
2. Death notifications are not yet added in the HIDL interface. So, that
part of the code is under "#if 0".
3. The |hidl_vec| implementation does not support an |assign| method
yet, so marked places where we need this for cleanup later.

Bug: 31365276
Test: mmm -j32 external/wpa_supplicant_8
Test: Will test on device using go/aog/279621 once the HIDL changes are
in AOSP.

Change-Id: Iff20fb3c6fc23b0122c0c07529171e3a473b1d63
diff --git a/wpa_supplicant/hidl/iface.cpp b/wpa_supplicant/hidl/iface.cpp
index 1ba93b7..6b94aa1 100644
--- a/wpa_supplicant/hidl/iface.cpp
+++ b/wpa_supplicant/hidl/iface.cpp
@@ -8,189 +8,212 @@
  */
 
 #include "hidl_manager.h"
+#include "hidl_return_macros.h"
 #include "iface.h"
 
-namespace wpa_supplicant_hidl {
-
-#define RETURN_IF_IFACE_INVALID(wpa_s)                                  \
-	{                                                               \
-		if (!wpa_s) {                                           \
-			return android::hidl::Status::                \
-			    fromServiceSpecificError(                   \
-				ERROR_IFACE_INVALID,                    \
-				"wpa_supplicant does not control this " \
-				"interface.");                          \
-		}                                                       \
-	}  // #define RETURN_IF_IFACE_INVALID(wpa_s)
+namespace android {
+namespace hardware {
+namespace wifi {
+namespace supplicant {
+namespace V1_0 {
+namespace implementation {
 
 Iface::Iface(struct wpa_global *wpa_global, const char ifname[])
     : wpa_global_(wpa_global), ifname_(ifname)
 {
 }
 
-android::hidl::Status Iface::GetName(std::string *iface_name_out)
-{
-	// We could directly return the name we hold, but let's verify
-	// if the underlying iface still exists.
-	RETURN_IF_IFACE_INVALID(retrieveIfacePtr());
-	*iface_name_out = ifname_;
-	return android::hidl::Status::ok();
-}
-
-android::hidl::Status Iface::AddNetwork(
-    android::sp<fi::w1::wpa_supplicant::INetwork> *network_object_out)
+Return<void> Iface::getName(getName_cb _hidl_cb)
 {
 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	RETURN_IF_IFACE_INVALID(wpa_s);
+	if (!wpa_s) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_IFACE_INVALID, ifname_);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, ifname_);
+}
+
+Return<void> Iface::addNetwork(addNetwork_cb _hidl_cb)
+{
+	android::sp<ISupplicantNetwork> network;
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (!wpa_s) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_IFACE_INVALID, network);
+	}
 
 	struct wpa_ssid *ssid = wpa_supplicant_add_network(wpa_s);
 	if (!ssid) {
-		return android::hidl::Status::fromServiceSpecificError(
-		    ERROR_GENERIC, "wpa_supplicant couldn't add this network.");
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN, network);
 	}
 
 	HidlManager *hidl_manager = HidlManager::getInstance();
 	if (!hidl_manager ||
 	    hidl_manager->getNetworkHidlObjectByIfnameAndNetworkId(
-		wpa_s->ifname, ssid->id, network_object_out)) {
-		return android::hidl::Status::fromServiceSpecificError(
-		    ERROR_GENERIC,
-		    "wpa_supplicant encountered a hidl error.");
+		wpa_s->ifname, ssid->id, &network)) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN, network);
 	}
-	return android::hidl::Status::ok();
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, network);
 }
 
-android::hidl::Status Iface::RemoveNetwork(int network_id)
+Return<void> Iface::removeNetwork(uint32_t id, removeNetwork_cb _hidl_cb)
 {
 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	RETURN_IF_IFACE_INVALID(wpa_s);
+	if (!wpa_s) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
+	}
 
-	int result = wpa_supplicant_remove_network(wpa_s, network_id);
+	int result = wpa_supplicant_remove_network(wpa_s, id);
 	if (result == -1) {
-		return android::hidl::Status::fromServiceSpecificError(
-		    ERROR_NETWORK_UNKNOWN,
-		    "wpa_supplicant does not control this network.");
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN);
 	}
 
-	if (result == -2) {
-		return android::hidl::Status::fromServiceSpecificError(
-		    ERROR_GENERIC,
-		    "wpa_supplicant couldn't remove this network.");
+	if (result != 0) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
 	}
-	return android::hidl::Status::ok();
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
 }
 
-android::hidl::Status Iface::GetNetwork(
-    int network_id,
-    android::sp<fi::w1::wpa_supplicant::INetwork> *network_object_out)
+Return<void> Iface::getNetwork(uint32_t id, getNetwork_cb _hidl_cb)
 {
+	android::sp<ISupplicantNetwork> network;
 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	RETURN_IF_IFACE_INVALID(wpa_s);
+	if (!wpa_s) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_IFACE_INVALID, network);
+	}
 
-	struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, network_id);
+	struct wpa_ssid *ssid = wpa_config_get_network(wpa_s->conf, id);
 	if (!ssid) {
-		return android::hidl::Status::fromServiceSpecificError(
-		    ERROR_NETWORK_UNKNOWN,
-		    "wpa_supplicant does not control this network.");
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_NETWORK_UNKNOWN, network);
 	}
 
 	HidlManager *hidl_manager = HidlManager::getInstance();
 	if (!hidl_manager ||
 	    hidl_manager->getNetworkHidlObjectByIfnameAndNetworkId(
-		wpa_s->ifname, ssid->id, network_object_out)) {
-		return android::hidl::Status::fromServiceSpecificError(
-		    ERROR_GENERIC,
-		    "wpa_supplicant encountered a hidl error.");
+		wpa_s->ifname, ssid->id, &network)) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN, network);
 	}
-	return android::hidl::Status::ok();
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, network);
 }
 
-android::hidl::Status Iface::RegisterCallback(
-    const android::sp<fi::w1::wpa_supplicant::IIfaceCallback> &callback)
+Return<void> Iface::listNetworks(listNetworks_cb _hidl_cb)
+{
+	std::vector<uint32_t> network_ids;
+
+	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
+	if (!wpa_s) {
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_IFACE_INVALID, network_ids);
+	}
+
+	for (struct wpa_ssid *wpa_ssid = wpa_s->conf->ssid; wpa_ssid;
+	     wpa_ssid = wpa_ssid->next) {
+		network_ids.emplace_back(wpa_ssid->id);
+	}
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS, network_ids);
+}
+
+Return<void> Iface::registerCallback(
+    const sp<ISupplicantIfaceCallback> &callback, registerCallback_cb _hidl_cb)
 {
 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	RETURN_IF_IFACE_INVALID(wpa_s);
+	if (!wpa_s) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
+	}
 
 	HidlManager *hidl_manager = HidlManager::getInstance();
 	if (!hidl_manager ||
 	    hidl_manager->addIfaceCallbackHidlObject(ifname_, callback)) {
-		return android::hidl::Status::fromServiceSpecificError(
-		    ERROR_GENERIC,
-		    "wpa_supplicant encountered a hidl error.");
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
 	}
-	return android::hidl::Status::ok();
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
 }
 
-android::hidl::Status Iface::Reassociate()
+Return<void> Iface::reassociate(reassociate_cb _hidl_cb)
 {
 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	RETURN_IF_IFACE_INVALID(wpa_s);
+	if (!wpa_s) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
+	}
 
 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
-		return android::hidl::Status::fromServiceSpecificError(
-		    ERROR_IFACE_DISABLED);
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
 	}
-	wpas_request_connection(wpa_s);
-	return android::hidl::Status::ok();
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
 }
 
-android::hidl::Status Iface::Reconnect()
+Return<void> Iface::reconnect(reconnect_cb _hidl_cb)
 {
 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	RETURN_IF_IFACE_INVALID(wpa_s);
+	if (!wpa_s) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
+	}
 
 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
-		return android::hidl::Status::fromServiceSpecificError(
-		    ERROR_IFACE_DISABLED);
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
 	}
 	if (!wpa_s->disconnected) {
-		return android::hidl::Status::fromServiceSpecificError(
-		    ERROR_IFACE_NOT_DISCONNECTED);
+		HIDL_RETURN(
+		    SupplicantStatusCode::FAILURE_IFACE_NOT_DISCONNECTED);
 	}
+
 	wpas_request_connection(wpa_s);
-	return android::hidl::Status::ok();
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
 }
 
-android::hidl::Status Iface::Disconnect()
+Return<void> Iface::disconnect(disconnect_cb _hidl_cb)
 {
 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	RETURN_IF_IFACE_INVALID(wpa_s);
+	if (!wpa_s) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
+	}
 
 	if (wpa_s->wpa_state == WPA_INTERFACE_DISABLED) {
-		return android::hidl::Status::fromServiceSpecificError(
-		    ERROR_IFACE_DISABLED);
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_DISABLED);
 	}
+
 	wpas_request_disconnection(wpa_s);
-	return android::hidl::Status::ok();
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
 }
 
-android::hidl::Status Iface::SetPowerSave(bool enable)
+Return<void> Iface::setPowerSave(bool enable, setPowerSave_cb _hidl_cb)
 {
 	struct wpa_supplicant *wpa_s = retrieveIfacePtr();
-	RETURN_IF_IFACE_INVALID(wpa_s);
+	if (!wpa_s) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
+	}
+
 	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::hidl::Status::fromServiceSpecificError(
-		    ERROR_GENERIC, error_msg.c_str());
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
 	}
-	return android::hidl::Status::ok();
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
 }
 
-android::hidl::Status Iface::InitiateTDLSDiscover(
-    const std::vector<uint8_t> &mac_address)
+Return<void> Iface::initiateTdlsDiscover(
+    const hidl_array<uint8_t, 6 /* 6 */> &mac_address,
+    initiateTdlsDiscover_cb _hidl_cb)
 {
 	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::hidl::Status::fromExceptionCode(
-		    android::hidl::Status::EX_ILLEGAL_ARGUMENT,
-		    error_msg.c_str());
+	if (!wpa_s) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
 	}
+
+	if (!mac_address.data()) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+
 	int ret;
 	const u8 *peer = mac_address.data();
 	if (wpa_tdls_is_external_setup(wpa_s->wpa)) {
@@ -199,26 +222,25 @@
 		ret = wpa_drv_tdls_oper(wpa_s, TDLS_DISCOVERY_REQ, peer);
 	}
 	if (ret) {
-		return android::hidl::Status::fromServiceSpecificError(
-		    ERROR_GENERIC, "Failed to initiate TDLS Discover.");
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
 	}
-	return android::hidl::Status::ok();
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
 }
 
-android::hidl::Status Iface::InitiateTDLSSetup(
-    const std::vector<uint8_t> &mac_address)
+Return<void> Iface::initiateTdlsSetup(
+    const hidl_array<uint8_t, 6 /* 6 */> &mac_address,
+    initiateTdlsSetup_cb _hidl_cb)
 {
 	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::hidl::Status::fromExceptionCode(
-		    android::hidl::Status::EX_ILLEGAL_ARGUMENT,
-		    error_msg.c_str());
+	if (!wpa_s) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
 	}
+
+	if (!mac_address.data()) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+
 	int ret;
 	const u8 *peer = mac_address.data();
 	if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
@@ -229,26 +251,25 @@
 		ret = wpa_drv_tdls_oper(wpa_s, TDLS_SETUP, peer);
 	}
 	if (ret) {
-		return android::hidl::Status::fromServiceSpecificError(
-		    ERROR_GENERIC, "Failed to initiate TDLS Setup.");
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
 	}
-	return android::hidl::Status::ok();
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
 }
 
-android::hidl::Status Iface::InitiateTDLSTeardown(
-    const std::vector<uint8_t> &mac_address)
+Return<void> Iface::initiateTdlsTeardown(
+    const hidl_array<uint8_t, 6 /* 6 */> &mac_address,
+    initiateTdlsTeardown_cb _hidl_cb)
 {
 	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::hidl::Status::fromExceptionCode(
-		    android::hidl::Status::EX_ILLEGAL_ARGUMENT,
-		    error_msg.c_str());
+	if (!wpa_s) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_IFACE_INVALID);
 	}
+
+	if (!mac_address.data()) {
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_ARGS_INVALID);
+	}
+
 	int ret;
 	const u8 *peer = mac_address.data();
 	if (wpa_tdls_is_external_setup(wpa_s->wpa) &&
@@ -258,22 +279,29 @@
 	} else {
 		ret = wpa_drv_tdls_oper(wpa_s, TDLS_TEARDOWN, peer);
 	}
+
 	if (ret) {
-		return android::hidl::Status::fromServiceSpecificError(
-		    ERROR_GENERIC, "Failed to initiate TDLS Teardown.");
+		HIDL_RETURN(SupplicantStatusCode::FAILURE_UNKNOWN);
 	}
-	return android::hidl::Status::ok();
+
+	HIDL_RETURN(SupplicantStatusCode::SUCCESS);
 }
 
 /**
- * Retrieve the underlying |wpa_supplicant| struct pointer for
- * this iface.
- * If the underlying iface is removed, then all RPC method calls
- * on this object will return failure.
+ * Retrieve the underlying |wpa_supplicant| struct
+ * pointer for this iface.
+ * If the underlying iface is removed, then all RPC method calls on this object
+ * will return failure.
  */
 wpa_supplicant *Iface::retrieveIfacePtr()
 {
 	return wpa_supplicant_get_iface(
 	    (struct wpa_global *)wpa_global_, ifname_.c_str());
 }
-}  // namespace wpa_supplicant_hidl
+
+}  // namespace implementation
+}  // namespace V1_0
+}  // namespace wifi
+}  // namespace supplicant
+}  // namespace hardware
+}  // namespace android