Revert "Revert "[wpa_supplicant] cumilative patch from commit 4b..."

Revert submission 28102966-revert-26533062-Supplicant_merge_June24-CUATTSRBBR

Fixed the regression issue (ag/28389573)
Bug: 329004037

Reverted changes: /q/submissionid:28102966-revert-26533062-Supplicant_merge_June24-CUATTSRBBR

Test: Turn ON/OFF SoftAp

Change-Id: Ie7ea1ee7f8b1311fce280907d37a2e321542f547
diff --git a/wpa_supplicant/dpp_supplicant.c b/wpa_supplicant/dpp_supplicant.c
index 801e698..e223450 100644
--- a/wpa_supplicant/dpp_supplicant.c
+++ b/wpa_supplicant/dpp_supplicant.c
@@ -238,6 +238,12 @@
 		wait_time = wpa_s->dpp_resp_retry_time;
 	else
 		wait_time = 1000;
+	if (wpa_s->dpp_tx_chan_change) {
+		wpa_s->dpp_tx_chan_change = false;
+		if (wait_time > 100)
+			wait_time = 100;
+	}
+
 	wpa_printf(MSG_DEBUG,
 		   "DPP: Schedule retransmission of Authentication Response frame in %u ms",
 		wait_time);
@@ -487,6 +493,21 @@
 }
 
 
+static void wpas_dpp_neg_freq_timeout(void *eloop_ctx, void *timeout_ctx)
+{
+	struct wpa_supplicant *wpa_s = eloop_ctx;
+	struct dpp_authentication *auth = wpa_s->dpp_auth;
+
+	if (!wpa_s->dpp_listen_on_tx_expire || !auth || !auth->neg_freq)
+		return;
+
+	wpa_printf(MSG_DEBUG,
+		   "DPP: Start listen on neg_freq %u MHz based on timeout for TX wait expiration",
+		   auth->neg_freq);
+	wpas_dpp_listen_start(wpa_s, auth->neg_freq);
+}
+
+
 static void wpas_dpp_tx_status(struct wpa_supplicant *wpa_s,
 			       unsigned int freq, const u8 *dst,
 			       const u8 *src, const u8 *bssid,
@@ -605,7 +626,9 @@
 			   wpa_s->dpp_auth->curr_freq,
 			   wpa_s->dpp_auth->neg_freq);
 		offchannel_send_action_done(wpa_s);
-		wpas_dpp_listen_start(wpa_s, wpa_s->dpp_auth->neg_freq);
+		wpa_s->dpp_listen_on_tx_expire = true;
+		eloop_register_timeout(0, 100000, wpas_dpp_neg_freq_timeout,
+				       wpa_s, NULL);
 	}
 
 	if (wpa_s->dpp_auth_ok_on_ack)
@@ -1035,6 +1058,8 @@
 	wpa_s->off_channel_freq = 0;
 	wpa_s->roc_waiting_drv_freq = lwork->freq;
 	wpa_drv_dpp_listen(wpa_s, true);
+	wpa_s->dpp_tx_auth_resp_on_roc_stop = false;
+	wpa_s->dpp_tx_chan_change = false;
 }
 
 
@@ -1134,11 +1159,58 @@
 }
 
 
+static void wpas_dpp_tx_auth_resp(struct wpa_supplicant *wpa_s)
+{
+	struct dpp_authentication *auth = wpa_s->dpp_auth;
+
+	if (!auth)
+		return;
+
+	wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
+		MAC2STR(auth->peer_mac_addr), auth->curr_freq,
+		DPP_PA_AUTHENTICATION_RESP);
+	offchannel_send_action(wpa_s, auth->curr_freq,
+			       auth->peer_mac_addr, wpa_s->own_addr, broadcast,
+			       wpabuf_head(auth->resp_msg),
+			       wpabuf_len(auth->resp_msg),
+			       500, wpas_dpp_tx_status, 0);
+}
+
+
+static void wpas_dpp_tx_auth_resp_roc_timeout(void *eloop_ctx,
+					      void *timeout_ctx)
+{
+	struct wpa_supplicant *wpa_s = eloop_ctx;
+	struct dpp_authentication *auth = wpa_s->dpp_auth;
+
+	if (!auth || !wpa_s->dpp_tx_auth_resp_on_roc_stop)
+		return;
+
+	wpa_s->dpp_tx_auth_resp_on_roc_stop = false;
+	wpa_s->dpp_tx_chan_change = true;
+	wpa_printf(MSG_DEBUG,
+		   "DPP: Send postponed Authentication Response on remain-on-channel termination timeout");
+	wpas_dpp_tx_auth_resp(wpa_s);
+}
+
+
 void wpas_dpp_cancel_remain_on_channel_cb(struct wpa_supplicant *wpa_s,
 					  unsigned int freq)
 {
+	wpa_printf(MSG_DEBUG, "DPP: Remain on channel cancel for %u MHz", freq);
 	wpas_dpp_listen_work_done(wpa_s);
 
+	if (wpa_s->dpp_auth && wpa_s->dpp_tx_auth_resp_on_roc_stop) {
+		eloop_cancel_timeout(wpas_dpp_tx_auth_resp_roc_timeout,
+				     wpa_s, NULL);
+		wpa_s->dpp_tx_auth_resp_on_roc_stop = false;
+		wpa_s->dpp_tx_chan_change = true;
+		wpa_printf(MSG_DEBUG,
+			   "DPP: Send postponed Authentication Response on remain-on-channel termination");
+		wpas_dpp_tx_auth_resp(wpa_s);
+		return;
+	}
+
 	if (wpa_s->dpp_auth && wpa_s->dpp_in_response_listen) {
 		unsigned int new_freq;
 
@@ -1256,17 +1328,17 @@
 		wpa_printf(MSG_DEBUG,
 			   "DPP: Stop listen on %u MHz to allow response on the request %u MHz",
 			   wpa_s->dpp_listen_freq, wpa_s->dpp_auth->curr_freq);
+		wpa_s->dpp_tx_auth_resp_on_roc_stop = true;
+		eloop_register_timeout(0, 100000,
+				       wpas_dpp_tx_auth_resp_roc_timeout,
+				       wpa_s, NULL);
 		wpas_dpp_listen_stop(wpa_s);
+		return;
 	}
+	wpa_s->dpp_tx_auth_resp_on_roc_stop = false;
+	wpa_s->dpp_tx_chan_change = false;
 
-	wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_TX "dst=" MACSTR " freq=%u type=%d",
-		MAC2STR(src), wpa_s->dpp_auth->curr_freq,
-		DPP_PA_AUTHENTICATION_RESP);
-	offchannel_send_action(wpa_s, wpa_s->dpp_auth->curr_freq,
-			       src, wpa_s->own_addr, broadcast,
-			       wpabuf_head(wpa_s->dpp_auth->resp_msg),
-			       wpabuf_len(wpa_s->dpp_auth->resp_msg),
-			       500, wpas_dpp_tx_status, 0);
+	wpas_dpp_tx_auth_resp(wpa_s);
 }
 
 
@@ -1275,6 +1347,15 @@
 	struct dpp_authentication *auth = wpa_s->dpp_auth;
 	int freq;
 
+	if (wpa_s->dpp_listen_on_tx_expire && auth && auth->neg_freq) {
+		wpa_printf(MSG_DEBUG,
+			   "DPP: Start listen on neg_freq %u MHz based on TX wait expiration on the previous channel",
+			   auth->neg_freq);
+		eloop_cancel_timeout(wpas_dpp_neg_freq_timeout, wpa_s, NULL);
+		wpas_dpp_listen_start(wpa_s, auth->neg_freq);
+		return;
+	}
+
 	if (!wpa_s->dpp_gas_server || !auth) {
 		if (auth && auth->waiting_auth_resp &&
 		    eloop_is_timeout_registered(wpas_dpp_drv_wait_timeout,
@@ -4816,6 +4897,8 @@
 	eloop_cancel_timeout(wpas_dpp_gas_initial_resp_timeout, wpa_s, NULL);
 	eloop_cancel_timeout(wpas_dpp_gas_client_timeout, wpa_s, NULL);
 	eloop_cancel_timeout(wpas_dpp_drv_wait_timeout, wpa_s, NULL);
+	eloop_cancel_timeout(wpas_dpp_tx_auth_resp_roc_timeout, wpa_s, NULL);
+	eloop_cancel_timeout(wpas_dpp_neg_freq_timeout, wpa_s, NULL);
 #ifdef CONFIG_DPP2
 	eloop_cancel_timeout(wpas_dpp_config_result_wait_timeout, wpa_s, NULL);
 	eloop_cancel_timeout(wpas_dpp_conn_status_result_wait_timeout,
@@ -5627,6 +5710,7 @@
 	eloop_register_timeout(100, 0, wpas_dpp_push_button_expire,
 			       wpa_s, NULL);
 
+	wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_PB_STATUS "started");
 	return 0;
 }
 
@@ -5688,6 +5772,7 @@
 	wpa_s->scan_req = MANUAL_SCAN_REQ;
 	wpa_s->scan_res_handler = wpas_dpp_pb_scan_res_handler;
 	wpa_supplicant_req_scan(wpa_s, 0, 0);
+	wpa_msg(wpa_s, MSG_INFO, DPP_EVENT_PB_STATUS "started");
 	return 0;
 }