wpa_supplicant(hidl): Invoke disconnect/assoc reject calbacks

Invoke the HIDL callbacks to notify about disconnect reasons and
association rejects.

Bug: 33416261
Test: Compiles
Change-Id: I13f0ff3aa0958ec78344afdaf27f05915763efd5
diff --git a/wpa_supplicant/hidl/hidl.cpp b/wpa_supplicant/hidl/hidl.cpp
index 55a541e..09f09ce 100644
--- a/wpa_supplicant/hidl/hidl.cpp
+++ b/wpa_supplicant/hidl/hidl.cpp
@@ -258,3 +258,35 @@
 	hidl_manager->notifyHs20RxDeauthImminentNotice(
 	    wpa_s, code, reauth_delay, url);
 }
+
+void wpas_hidl_notify_disconnect_reason(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(
+	    MSG_DEBUG, "Notifying disconnect reason to hidl control: %d",
+	    wpa_s->disconnect_reason);
+
+	HidlManager *hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager)
+		return;
+
+	hidl_manager->notifyDisconnectReason(wpa_s);
+}
+
+void wpas_hidl_notify_assoc_reject(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	wpa_printf(
+	    MSG_DEBUG, "Notifying assoc reject to hidl control: %d",
+	    wpa_s->assoc_status_code);
+
+	HidlManager *hidl_manager = HidlManager::getInstance();
+	if (!hidl_manager)
+		return;
+
+	hidl_manager->notifyAssocReject(wpa_s);
+}
diff --git a/wpa_supplicant/hidl/hidl.h b/wpa_supplicant/hidl/hidl.h
index 598120f..0e51b3c 100644
--- a/wpa_supplicant/hidl/hidl.h
+++ b/wpa_supplicant/hidl/hidl.h
@@ -46,6 +46,8 @@
     struct wpa_supplicant *wpa_s, const char *url, u8 osu_method);
 void wpas_hidl_notify_hs20_rx_deauth_imminent_notice(
     struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay, const char *url);
+void wpas_hidl_notify_disconnect_reason(struct wpa_supplicant *wpa_s);
+void wpas_hidl_notify_assoc_reject(struct wpa_supplicant *wpa_s);
 #else   // CONFIG_CTRL_IFACE_HIDL
 static inline int wpas_hidl_register_interface(struct wpa_supplicant *wpa_s)
 {
@@ -93,6 +95,8 @@
     struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay, const char *url)
 {
 }
+static void wpas_hidl_notify_disconnect_reason(struct wpa_supplicant *wpa_s) {}
+static void wpas_hidl_notify_assoc_reject(struct wpa_supplicant *wpa_s) {}
 #endif  // CONFIG_CTRL_IFACE_HIDL
 
 #ifdef _cplusplus
diff --git a/wpa_supplicant/hidl/hidl_manager.cpp b/wpa_supplicant/hidl/hidl_manager.cpp
index 8dc3ef5..ec6b847 100644
--- a/wpa_supplicant/hidl/hidl_manager.cpp
+++ b/wpa_supplicant/hidl/hidl_manager.cpp
@@ -720,6 +720,67 @@
 }
 
 /**
+ * Notify all listeners about the reason code for disconnection from the
+ * currently connected network.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
+ * the network is present.
+ */
+void HidlManager::notifyDisconnectReason(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	const std::string ifname(wpa_s->ifname);
+	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
+		return;
+
+	const u8 *bssid = wpa_s->bssid;
+	if (is_zero_ether_addr(bssid)) {
+		bssid = wpa_s->pending_bssid;
+	}
+	std::array<uint8_t, 6> hidl_bssid;
+	os_memcpy(hidl_bssid.data(), bssid, ETH_ALEN);
+
+	callWithEachStaIfaceCallback(
+	    wpa_s->ifname,
+	    std::bind(
+		&ISupplicantStaIfaceCallback::onDisconnected,
+		std::placeholders::_1, hidl_bssid, wpa_s->disconnect_reason < 0,
+		wpa_s->disconnect_reason));
+}
+
+/**
+ * Notify all listeners about association reject from the access point to which
+ * we are attempting to connect.
+ *
+ * @param wpa_s |wpa_supplicant| struct corresponding to the interface on which
+ * the network is present.
+ */
+void HidlManager::notifyAssocReject(struct wpa_supplicant *wpa_s)
+{
+	if (!wpa_s)
+		return;
+
+	const std::string ifname(wpa_s->ifname);
+	if (sta_iface_object_map_.find(ifname) == sta_iface_object_map_.end())
+		return;
+
+	const u8 *bssid = wpa_s->bssid;
+	if (is_zero_ether_addr(bssid)) {
+		bssid = wpa_s->pending_bssid;
+	}
+	std::array<uint8_t, 6> hidl_bssid;
+	os_memcpy(hidl_bssid.data(), bssid, ETH_ALEN);
+
+	callWithEachStaIfaceCallback(
+	    wpa_s->ifname,
+	    std::bind(
+		&ISupplicantStaIfaceCallback::onAssociationRejected,
+		std::placeholders::_1, hidl_bssid, wpa_s->assoc_status_code));
+}
+
+/**
  * Retrieve the |ISupplicantP2pIface| hidl object reference using the provided
  * ifname.
  *
diff --git a/wpa_supplicant/hidl/hidl_manager.h b/wpa_supplicant/hidl/hidl_manager.h
index 468c16a..8c4aa7f 100644
--- a/wpa_supplicant/hidl/hidl_manager.h
+++ b/wpa_supplicant/hidl/hidl_manager.h
@@ -74,6 +74,8 @@
 	void notifyHs20RxDeauthImminentNotice(
 	    struct wpa_supplicant *wpa_s, u8 code, u16 reauth_delay,
 	    const char *url);
+	void notifyDisconnectReason(struct wpa_supplicant *wpa_s);
+	void notifyAssocReject(struct wpa_supplicant *wpa_s);
 
 	// Methods called from hidl objects.
 	int getP2pIfaceHidlObjectByIfname(