P2P: Support driver preferred freq list for invitation case

When using P2P invitation to re-invoke a persistent P2P group without
specifying the operating channel, query the driver for the preferred
frequency list, and use it to select the operating channel of the group.

Signed-off-by: Jouni Malinen <jouni@qca.qualcomm.com>
diff --git a/src/p2p/p2p_go_neg.c b/src/p2p/p2p_go_neg.c
index 4322bbb..83b4356 100644
--- a/src/p2p/p2p_go_neg.c
+++ b/src/p2p/p2p_go_neg.c
@@ -673,8 +673,8 @@
 }
 
 
-static void p2p_check_pref_chan(struct p2p_data *p2p, int go,
-				struct p2p_device *dev, struct p2p_message *msg)
+void p2p_check_pref_chan(struct p2p_data *p2p, int go,
+			 struct p2p_device *dev, struct p2p_message *msg)
 {
 	unsigned int freq_list[P2P_MAX_PREF_CHANNELS], size;
 	unsigned int i;
@@ -725,7 +725,7 @@
 
 	/*
 	  Check if peer's preferred channel list is
-	  * _not_ included in the GO Negotiation Request.
+	  * _not_ included in the GO Negotiation Request or Invitation Request.
 	  */
 	if (msg->pref_freq_list_len == 0)
 		p2p_check_pref_chan_no_recv(p2p, go, dev, msg, freq_list, size);
diff --git a/src/p2p/p2p_i.h b/src/p2p/p2p_i.h
index d45471a..0ce4058 100644
--- a/src/p2p/p2p_i.h
+++ b/src/p2p/p2p_i.h
@@ -803,6 +803,8 @@
 u16 p2p_wps_method_pw_id(enum p2p_wps_method wps_method);
 void p2p_reselect_channel(struct p2p_data *p2p,
 			  struct p2p_channels *intersection);
+void p2p_check_pref_chan(struct p2p_data *p2p, int go,
+			 struct p2p_device *dev, struct p2p_message *msg);
 
 /* p2p_pd.c */
 void p2p_process_prov_disc_req(struct p2p_data *p2p, const u8 *sa,
diff --git a/src/p2p/p2p_invitation.c b/src/p2p/p2p_invitation.c
index f5454f7..108e5b7 100644
--- a/src/p2p/p2p_invitation.c
+++ b/src/p2p/p2p_invitation.c
@@ -85,6 +85,9 @@
 	p2p_buf_add_device_info(buf, p2p, peer);
 	p2p_buf_update_ie_hdr(buf, len);
 
+	p2p_buf_add_pref_channel_list(buf, p2p->pref_freq_list,
+				      p2p->num_pref_freq);
+
 #ifdef CONFIG_WIFI_DISPLAY
 	if (wfd_ie)
 		wpabuf_put_buf(buf, wfd_ie);
@@ -343,6 +346,12 @@
 			p2p_reselect_channel(p2p, &intersection);
 		}
 
+		/*
+		 * Use the driver preferred frequency list extension if
+		 * supported.
+		 */
+		p2p_check_pref_chan(p2p, go, dev, &msg);
+
 		op_freq = p2p_channel_to_freq(p2p->op_reg_class,
 					      p2p->op_channel);
 		if (op_freq < 0) {
@@ -534,6 +543,12 @@
 				peer_oper_freq = 0;
 		}
 
+		/*
+		 * Use the driver preferred frequency list extension if
+		 * supported.
+		 */
+		p2p_check_pref_chan(p2p, 0, dev, &msg);
+
 		p2p->cfg->invitation_result(p2p->cfg->cb_ctx, *msg.status,
 					    msg.group_bssid, channels, sa,
 					    freq, peer_oper_freq);
diff --git a/wpa_supplicant/p2p_supplicant.c b/wpa_supplicant/p2p_supplicant.c
index 066ff22..8465b88 100644
--- a/wpa_supplicant/p2p_supplicant.c
+++ b/wpa_supplicant/p2p_supplicant.c
@@ -6488,6 +6488,7 @@
 				   pref_freq_list, &size);
 	if (res)
 		return res;
+	p2p_set_own_pref_freq_list(wpa_s->global->p2p, pref_freq_list, size);
 
 	if (wpa_s->global->p2p_disabled || wpa_s->global->p2p == NULL)
 		return -1;