mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	chan_psip, res_pjsip_sdp_rtp: ignore rtptimeout if direct-media is active
Do not hang up a PJSIP channel on RTP timeout if that channel is in a direct-media bridge. Also reset the time of the last received RTP packet when direct-media ends (wait full rtp_timeout period before checking first time after audio came back to Asterisk). ASTERISK-28774 Reported-by: Michael Neuhauser Change-Id: I8b62012be7685849e8fb2b1c5dd39d35313ca2d1
This commit is contained in:
		
				
					committed by
					
						 George Joseph
						George Joseph
					
				
			
			
				
	
			
			
			
						parent
						
							82c3939c38
						
					
				
				
					commit
					5562fb2ea0
				
			| @@ -332,6 +332,14 @@ static int check_for_rtp_changes(struct ast_channel *chan, struct ast_rtp_instan | ||||
| 		ast_sockaddr_setnull(&media->direct_media_addr); | ||||
| 		changed = 1; | ||||
| 		if (media->rtp) { | ||||
| 			/* Direct media has ended - reset time of last received RTP packet | ||||
| 			 * to avoid premature RTP timeout. Synchronisation between the | ||||
| 			 * modification of direct_mdedia_addr+last_rx here and reading the | ||||
| 			 * values in res_pjsip_sdp_rtp.c:rtp_check_timeout() is provided | ||||
| 			 * by the channel's lock (which is held while this function is | ||||
| 			 * executed). | ||||
| 			 */ | ||||
| 			ast_rtp_instance_set_last_rx(media->rtp, time(NULL)); | ||||
| 			ast_rtp_instance_set_prop(media->rtp, AST_RTP_PROPERTY_RTCP, 1); | ||||
| 			if (position != -1) { | ||||
| 				ast_channel_set_fd(chan, position + AST_EXTENDED_FDS, ast_rtp_instance_fd(media->rtp, 1)); | ||||
|   | ||||
| @@ -106,30 +106,53 @@ static int rtp_check_timeout(const void *data) | ||||
| 	struct ast_sip_session_media *session_media = (struct ast_sip_session_media *)data; | ||||
| 	struct ast_rtp_instance *rtp = session_media->rtp; | ||||
| 	int elapsed; | ||||
| 	int timeout; | ||||
| 	struct ast_channel *chan; | ||||
|  | ||||
| 	if (!rtp) { | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	elapsed = time(NULL) - ast_rtp_instance_get_last_rx(rtp); | ||||
| 	if (elapsed < ast_rtp_instance_get_timeout(rtp)) { | ||||
| 		return (ast_rtp_instance_get_timeout(rtp) - elapsed) * 1000; | ||||
| 	} | ||||
|  | ||||
| 	chan = ast_channel_get_by_name(ast_rtp_instance_get_channel_id(rtp)); | ||||
| 	if (!chan) { | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	ast_log(LOG_NOTICE, "Disconnecting channel '%s' for lack of RTP activity in %d seconds\n", | ||||
| 		ast_channel_name(chan), elapsed); | ||||
|  | ||||
| 	/* Get channel lock to make sure that we access a consistent set of values | ||||
| 	 * (last_rx and direct_media_addr) - the lock is held when values are modified | ||||
| 	 * (see send_direct_media_request()/check_for_rtp_changes() in chan_pjsip.c). We | ||||
| 	 * are trying to avoid a situation where direct_media_addr has been reset but the | ||||
| 	 * last-rx time was not set yet. | ||||
| 	 */ | ||||
| 	ast_channel_lock(chan); | ||||
| 	ast_channel_hangupcause_set(chan, AST_CAUSE_REQUESTED_CHAN_UNAVAIL); | ||||
| 	ast_channel_unlock(chan); | ||||
|  | ||||
| 	elapsed = time(NULL) - ast_rtp_instance_get_last_rx(rtp); | ||||
| 	timeout = ast_rtp_instance_get_timeout(rtp); | ||||
| 	if (elapsed < timeout) { | ||||
| 		ast_channel_unlock(chan); | ||||
| 		ast_channel_unref(chan); | ||||
| 		return (timeout - elapsed) * 1000; | ||||
| 	} | ||||
|  | ||||
| 	/* Last RTP packet was received too long ago | ||||
| 	 * - disconnect channel unless direct media is in use. | ||||
| 	 */ | ||||
| 	if (!ast_sockaddr_isnull(&session_media->direct_media_addr)) { | ||||
| 		ast_debug(3, "Not disconnecting channel '%s' for lack of %s RTP activity in %d seconds " | ||||
| 			"since direct media is in use\n", ast_channel_name(chan), | ||||
| 			ast_codec_media_type2str(session_media->type), elapsed); | ||||
| 		ast_channel_unlock(chan); | ||||
| 		ast_channel_unref(chan); | ||||
| 		return timeout * 1000; /* recheck later, direct media may have ended then */ | ||||
| 	} | ||||
|  | ||||
| 	ast_log(LOG_NOTICE, "Disconnecting channel '%s' for lack of %s RTP activity in %d seconds\n", | ||||
| 		ast_channel_name(chan), ast_codec_media_type2str(session_media->type), elapsed); | ||||
|  | ||||
| 	ast_channel_hangupcause_set(chan, AST_CAUSE_REQUESTED_CHAN_UNAVAIL); | ||||
| 	ast_softhangup(chan, AST_SOFTHANGUP_DEV); | ||||
|  | ||||
| 	ast_channel_unlock(chan); | ||||
| 	ast_channel_unref(chan); | ||||
|  | ||||
| 	return 0; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user