P2P: Delay send_action call if p2p_scan is in progress
In order to avoid confusing the driver with a new remain-on-channel request, delay sending of a new Action frame if the driver indicates Action frame RX diromg a scan.
This commit is contained in:
		
							parent
							
								
									0b8889d8e5
								
							
						
					
					
						commit
						3f9285ff19
					
				
					 7 changed files with 107 additions and 64 deletions
				
			
		|  | @ -691,6 +691,25 @@ static int p2p_run_after_scan(struct p2p_data *p2p) | |||
| 	struct p2p_device *dev; | ||||
| 	enum p2p_after_scan op; | ||||
| 
 | ||||
| 	if (p2p->after_scan_tx) { | ||||
| 		int ret; | ||||
| 		/* TODO: schedule p2p_run_after_scan to be called from TX
 | ||||
| 		 * status callback(?) */ | ||||
| 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Send pending " | ||||
| 			"Action frame at p2p_scan completion"); | ||||
| 		ret = p2p->cfg->send_action(p2p->cfg->cb_ctx, | ||||
| 					    p2p->after_scan_tx->freq, | ||||
| 					    p2p->after_scan_tx->dst, | ||||
| 					    p2p->after_scan_tx->src, | ||||
| 					    p2p->after_scan_tx->bssid, | ||||
| 					    (u8 *) (p2p->after_scan_tx + 1), | ||||
| 					    p2p->after_scan_tx->len, | ||||
| 					    p2p->after_scan_tx->wait_time); | ||||
| 		os_free(p2p->after_scan_tx); | ||||
| 		p2p->after_scan_tx = NULL; | ||||
| 		return 1; | ||||
| 	} | ||||
| 
 | ||||
| 	op = p2p->start_after_scan; | ||||
| 	p2p->start_after_scan = P2P_AFTER_SCAN_NOTHING; | ||||
| 	switch (op) { | ||||
|  | @ -1831,6 +1850,7 @@ void p2p_deinit(struct p2p_data *p2p) | |||
| 	os_free(p2p->cfg->dev_name); | ||||
| 	os_free(p2p->groups); | ||||
| 	wpabuf_free(p2p->sd_resp); | ||||
| 	os_free(p2p->after_scan_tx); | ||||
| 	os_free(p2p); | ||||
| } | ||||
| 
 | ||||
|  | @ -2675,11 +2695,9 @@ int p2p_presence_req(struct p2p_data *p2p, const u8 *go_interface_addr, | |||
| 		return -1; | ||||
| 
 | ||||
| 	p2p->pending_action_state = P2P_NO_PENDING_ACTION; | ||||
| 	if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, go_interface_addr, | ||||
| 				  own_interface_addr, | ||||
| 	if (p2p_send_action(p2p, freq, go_interface_addr, own_interface_addr, | ||||
| 			    go_interface_addr, | ||||
| 				  wpabuf_head(req), wpabuf_len(req), 200) < 0) | ||||
| 	{ | ||||
| 			    wpabuf_head(req), wpabuf_len(req), 200) < 0) { | ||||
| 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, | ||||
| 			"P2P: Failed to send Action frame"); | ||||
| 	} | ||||
|  | @ -2776,9 +2794,8 @@ fail: | |||
| 		return; | ||||
| 
 | ||||
| 	p2p->pending_action_state = P2P_NO_PENDING_ACTION; | ||||
| 	if (p2p->cfg->send_action(p2p->cfg->cb_ctx, rx_freq, sa, da, da, | ||||
| 				  wpabuf_head(resp), wpabuf_len(resp), 200) < | ||||
| 	    0) { | ||||
| 	if (p2p_send_action(p2p, rx_freq, sa, da, da, | ||||
| 			    wpabuf_head(resp), wpabuf_len(resp), 200) < 0) { | ||||
| 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, | ||||
| 			"P2P: Failed to send Action frame"); | ||||
| 	} | ||||
|  | @ -3062,3 +3079,34 @@ void p2p_update_channel_list(struct p2p_data *p2p, struct p2p_channels *chan) | |||
| 	wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Update channel list"); | ||||
| 	os_memcpy(&p2p->cfg->channels, chan, sizeof(struct p2p_channels)); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| int p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst, | ||||
| 		    const u8 *src, const u8 *bssid, const u8 *buf, | ||||
| 		    size_t len, unsigned int wait_time) | ||||
| { | ||||
| 	if (p2p->p2p_scan_running) { | ||||
| 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Delay Action " | ||||
| 			"frame TX until p2p_scan completes"); | ||||
| 		if (p2p->after_scan_tx) { | ||||
| 			wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, "P2P: Dropped " | ||||
| 				"previous pending Action frame TX"); | ||||
| 			os_free(p2p->after_scan_tx); | ||||
| 		} | ||||
| 		p2p->after_scan_tx = os_malloc(sizeof(*p2p->after_scan_tx) + | ||||
| 					       len); | ||||
| 		if (p2p->after_scan_tx == NULL) | ||||
| 			return -1; | ||||
| 		p2p->after_scan_tx->freq = freq; | ||||
| 		os_memcpy(p2p->after_scan_tx->dst, dst, ETH_ALEN); | ||||
| 		os_memcpy(p2p->after_scan_tx->src, src, ETH_ALEN); | ||||
| 		os_memcpy(p2p->after_scan_tx->bssid, bssid, ETH_ALEN); | ||||
| 		p2p->after_scan_tx->len = len; | ||||
| 		p2p->after_scan_tx->wait_time = wait_time; | ||||
| 		os_memcpy(p2p->after_scan_tx + 1, buf, len); | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	return p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, dst, src, bssid, | ||||
| 				     buf, len, wait_time); | ||||
| } | ||||
|  |  | |||
|  | @ -99,11 +99,9 @@ int p2p_send_dev_disc_req(struct p2p_data *p2p, struct p2p_device *dev) | |||
| 	os_memcpy(p2p->pending_client_disc_addr, dev->p2p_device_addr, | ||||
| 		  ETH_ALEN); | ||||
| 	p2p->pending_action_state = P2P_PENDING_DEV_DISC_REQUEST; | ||||
| 	if (p2p->cfg->send_action(p2p->cfg->cb_ctx, dev->oper_freq, | ||||
| 				  go->p2p_device_addr, p2p->cfg->dev_addr, | ||||
| 				  go->p2p_device_addr, | ||||
| 				  wpabuf_head(req), wpabuf_len(req), 1000) < 0) | ||||
| 	{ | ||||
| 	if (p2p_send_action(p2p, dev->oper_freq, go->p2p_device_addr, | ||||
| 			    p2p->cfg->dev_addr, go->p2p_device_addr, | ||||
| 			    wpabuf_head(req), wpabuf_len(req), 1000) < 0) { | ||||
| 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, | ||||
| 			"P2P: Failed to send Action frame"); | ||||
| 		wpabuf_free(req); | ||||
|  | @ -160,10 +158,9 @@ static void p2p_send_dev_disc_resp(struct p2p_data *p2p, u8 dialog_token, | |||
| 		MAC2STR(addr), status, freq); | ||||
| 
 | ||||
| 	p2p->pending_action_state = P2P_PENDING_DEV_DISC_RESPONSE; | ||||
| 	if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, addr, | ||||
| 				  p2p->cfg->dev_addr, p2p->cfg->dev_addr, | ||||
| 				  wpabuf_head(resp), wpabuf_len(resp), 200) < | ||||
| 	    0) { | ||||
| 	if (p2p_send_action(p2p, freq, addr, p2p->cfg->dev_addr, | ||||
| 			    p2p->cfg->dev_addr, | ||||
| 			    wpabuf_head(resp), wpabuf_len(resp), 200) < 0) { | ||||
| 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, | ||||
| 			"P2P: Failed to send Action frame"); | ||||
| 	} | ||||
|  |  | |||
|  | @ -209,11 +209,9 @@ int p2p_connect_send(struct p2p_data *p2p, struct p2p_device *dev) | |||
| 	p2p->pending_action_state = P2P_PENDING_GO_NEG_REQUEST; | ||||
| 	p2p->go_neg_peer = dev; | ||||
| 	dev->flags |= P2P_DEV_WAIT_GO_NEG_RESPONSE; | ||||
| 	if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, | ||||
| 				  dev->p2p_device_addr, p2p->cfg->dev_addr, | ||||
| 				  dev->p2p_device_addr, | ||||
| 				  wpabuf_head(req), wpabuf_len(req), 200) < 0) | ||||
| 	{ | ||||
| 	if (p2p_send_action(p2p, freq, dev->p2p_device_addr, | ||||
| 			    p2p->cfg->dev_addr, dev->p2p_device_addr, | ||||
| 			    wpabuf_head(req), wpabuf_len(req), 200) < 0) { | ||||
| 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, | ||||
| 			"P2P: Failed to send Action frame"); | ||||
| 		/* Use P2P find to recover and retry */ | ||||
|  | @ -616,10 +614,9 @@ fail: | |||
| 	} else | ||||
| 		p2p->pending_action_state = | ||||
| 			P2P_PENDING_GO_NEG_RESPONSE_FAILURE; | ||||
| 	if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, sa, | ||||
| 				  p2p->cfg->dev_addr, p2p->cfg->dev_addr, | ||||
| 				  wpabuf_head(resp), wpabuf_len(resp), 200) < | ||||
| 	    0) { | ||||
| 	if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, | ||||
| 			    p2p->cfg->dev_addr, | ||||
| 			    wpabuf_head(resp), wpabuf_len(resp), 200) < 0) { | ||||
| 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, | ||||
| 			"P2P: Failed to send Action frame"); | ||||
| 	} | ||||
|  | @ -982,10 +979,8 @@ fail: | |||
| 		freq = rx_freq; | ||||
| 	else | ||||
| 		freq = dev->listen_freq; | ||||
| 	if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, sa, | ||||
| 				  p2p->cfg->dev_addr, sa, | ||||
| 				  wpabuf_head(conf), wpabuf_len(conf), 200) < | ||||
| 	    0) { | ||||
| 	if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, sa, | ||||
| 			    wpabuf_head(conf), wpabuf_len(conf), 200) < 0) { | ||||
| 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, | ||||
| 			"P2P: Failed to send Action frame"); | ||||
| 		p2p_go_neg_failed(p2p, dev, -1); | ||||
|  |  | |||
|  | @ -113,6 +113,16 @@ struct p2p_sd_query { | |||
| 	struct wpabuf *tlvs; | ||||
| }; | ||||
| 
 | ||||
| struct p2p_pending_action_tx { | ||||
| 	unsigned int freq; | ||||
| 	u8 dst[ETH_ALEN]; | ||||
| 	u8 src[ETH_ALEN]; | ||||
| 	u8 bssid[ETH_ALEN]; | ||||
| 	size_t len; | ||||
| 	unsigned int wait_time; | ||||
| 	/* Followed by len octets of the frame */ | ||||
| }; | ||||
| 
 | ||||
| /**
 | ||||
|  * struct p2p_data - P2P module data (internal to P2P module) | ||||
|  */ | ||||
|  | @ -351,6 +361,7 @@ struct p2p_data { | |||
| 		P2P_AFTER_SCAN_CONNECT | ||||
| 	} start_after_scan; | ||||
| 	u8 after_scan_peer[ETH_ALEN]; | ||||
| 	struct p2p_pending_action_tx *after_scan_tx; | ||||
| 
 | ||||
| 	struct p2p_group **groups; | ||||
| 	size_t num_groups; | ||||
|  | @ -597,5 +608,8 @@ int dev_type_list_match(const u8 *dev_type, const u8 *req_dev_type[], | |||
| 			size_t num_req_dev_type); | ||||
| struct wpabuf * p2p_build_probe_resp_ies(struct p2p_data *p2p); | ||||
| void p2p_build_ssid(struct p2p_data *p2p, u8 *ssid, size_t *ssid_len); | ||||
| int p2p_send_action(struct p2p_data *p2p, unsigned int freq, const u8 *dst, | ||||
| 		    const u8 *src, const u8 *bssid, const u8 *buf, | ||||
| 		    size_t len, unsigned int wait_time); | ||||
| 
 | ||||
| #endif /* P2P_I_H */ | ||||
|  |  | |||
|  | @ -271,10 +271,9 @@ fail: | |||
| 	p2p->inv_op_freq = op_freq; | ||||
| 
 | ||||
| 	p2p->pending_action_state = P2P_PENDING_INVITATION_RESPONSE; | ||||
| 	if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, sa, | ||||
| 				  p2p->cfg->dev_addr, p2p->cfg->dev_addr, | ||||
| 				  wpabuf_head(resp), wpabuf_len(resp), 200) < | ||||
| 	    0) { | ||||
| 	if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, | ||||
| 			    p2p->cfg->dev_addr, | ||||
| 			    wpabuf_head(resp), wpabuf_len(resp), 200) < 0) { | ||||
| 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, | ||||
| 			"P2P: Failed to send Action frame"); | ||||
| 	} | ||||
|  | @ -357,11 +356,9 @@ int p2p_invite_send(struct p2p_data *p2p, struct p2p_device *dev, | |||
| 	p2p->pending_action_state = P2P_PENDING_INVITATION_REQUEST; | ||||
| 	p2p->invite_peer = dev; | ||||
| 	dev->invitation_reqs++; | ||||
| 	if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, | ||||
| 				  dev->p2p_device_addr, p2p->cfg->dev_addr, | ||||
| 				  dev->p2p_device_addr, | ||||
| 				  wpabuf_head(req), wpabuf_len(req), 200) < 0) | ||||
| 	{ | ||||
| 	if (p2p_send_action(p2p, freq, dev->p2p_device_addr, | ||||
| 			    p2p->cfg->dev_addr, dev->p2p_device_addr, | ||||
| 			    wpabuf_head(req), wpabuf_len(req), 200) < 0) { | ||||
| 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, | ||||
| 			"P2P: Failed to send Action frame"); | ||||
| 		/* Use P2P find to recover and retry */ | ||||
|  |  | |||
|  | @ -165,10 +165,9 @@ out: | |||
| 		return; | ||||
| 	} | ||||
| 	p2p->pending_action_state = P2P_NO_PENDING_ACTION; | ||||
| 	if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, sa, | ||||
| 				  p2p->cfg->dev_addr, p2p->cfg->dev_addr, | ||||
| 				  wpabuf_head(resp), wpabuf_len(resp), 200) < | ||||
| 	    0) { | ||||
| 	if (p2p_send_action(p2p, freq, sa, p2p->cfg->dev_addr, | ||||
| 			    p2p->cfg->dev_addr, | ||||
| 			    wpabuf_head(resp), wpabuf_len(resp), 200) < 0) { | ||||
| 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, | ||||
| 			"P2P: Failed to send Action frame"); | ||||
| 	} | ||||
|  | @ -292,11 +291,9 @@ int p2p_send_prov_disc_req(struct p2p_data *p2p, struct p2p_device *dev, | |||
| 		return -1; | ||||
| 
 | ||||
| 	p2p->pending_action_state = P2P_PENDING_PD; | ||||
| 	if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, | ||||
| 				  dev->p2p_device_addr, p2p->cfg->dev_addr, | ||||
| 				  dev->p2p_device_addr, | ||||
| 				  wpabuf_head(req), wpabuf_len(req), 200) < 0) | ||||
| 	{ | ||||
| 	if (p2p_send_action(p2p->cfg->cb_ctx, freq, dev->p2p_device_addr, | ||||
| 			    p2p->cfg->dev_addr, dev->p2p_device_addr, | ||||
| 			    wpabuf_head(req), wpabuf_len(req), 200) < 0) { | ||||
| 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, | ||||
| 			"P2P: Failed to send Action frame"); | ||||
| 		wpabuf_free(req); | ||||
|  |  | |||
|  | @ -149,8 +149,7 @@ static void p2p_send_gas_comeback_req(struct p2p_data *p2p, const u8 *dst, | |||
| 		return; | ||||
| 
 | ||||
| 	p2p->pending_action_state = P2P_NO_PENDING_ACTION; | ||||
| 	if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, | ||||
| 				  dst, p2p->cfg->dev_addr, dst, | ||||
| 	if (p2p_send_action(p2p, freq, dst, p2p->cfg->dev_addr, dst, | ||||
| 			    wpabuf_head(req), wpabuf_len(req), 200) < 0) | ||||
| 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, | ||||
| 			"P2P: Failed to send Action frame"); | ||||
|  | @ -286,11 +285,9 @@ int p2p_start_sd(struct p2p_data *p2p, struct p2p_device *dev) | |||
| 	p2p->sd_query = query; | ||||
| 	p2p->pending_action_state = P2P_PENDING_SD; | ||||
| 
 | ||||
| 	if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, | ||||
| 				  dev->p2p_device_addr, p2p->cfg->dev_addr, | ||||
| 				  dev->p2p_device_addr, | ||||
| 				  wpabuf_head(req), wpabuf_len(req), 5000) < 0) | ||||
| 	{ | ||||
| 	if (p2p_send_action(p2p->cfg->cb_ctx, freq, dev->p2p_device_addr, | ||||
| 			    p2p->cfg->dev_addr, dev->p2p_device_addr, | ||||
| 			    wpabuf_head(req), wpabuf_len(req), 5000) < 0) { | ||||
| 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, | ||||
| 			"P2P: Failed to send Action frame"); | ||||
| 		ret = -1; | ||||
|  | @ -452,10 +449,9 @@ void p2p_sd_response(struct p2p_data *p2p, int freq, const u8 *dst, | |||
| 		return; | ||||
| 
 | ||||
| 	p2p->pending_action_state = P2P_NO_PENDING_ACTION; | ||||
| 	if (p2p->cfg->send_action(p2p->cfg->cb_ctx, freq, | ||||
| 				  dst, p2p->cfg->dev_addr, p2p->cfg->dev_addr, | ||||
| 				  wpabuf_head(resp), wpabuf_len(resp), 200) < | ||||
| 	    0) | ||||
| 	if (p2p_send_action(p2p->cfg->cb_ctx, freq, dst, p2p->cfg->dev_addr, | ||||
| 			    p2p->cfg->dev_addr, | ||||
| 			    wpabuf_head(resp), wpabuf_len(resp), 200) < 0) | ||||
| 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, | ||||
| 			"P2P: Failed to send Action frame"); | ||||
| 
 | ||||
|  | @ -691,10 +687,9 @@ void p2p_rx_gas_comeback_req(struct p2p_data *p2p, const u8 *sa, | |||
| 	} | ||||
| 
 | ||||
| 	p2p->pending_action_state = P2P_NO_PENDING_ACTION; | ||||
| 	if (p2p->cfg->send_action(p2p->cfg->cb_ctx, rx_freq, | ||||
| 				  sa, p2p->cfg->dev_addr, p2p->cfg->dev_addr, | ||||
| 				  wpabuf_head(resp), wpabuf_len(resp), 200) < | ||||
| 	    0) | ||||
| 	if (p2p_send_action(p2p, rx_freq, sa, p2p->cfg->dev_addr, | ||||
| 			    p2p->cfg->dev_addr, | ||||
| 			    wpabuf_head(resp), wpabuf_len(resp), 200) < 0) | ||||
| 		wpa_msg(p2p->cfg->msg_ctx, MSG_DEBUG, | ||||
| 			"P2P: Failed to send Action frame"); | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
		Reference in a new issue
	
	 Jouni Malinen
						Jouni Malinen