[asterisk-commits] oej: branch 1.4 r48199 - in /branches/1.4: channels/ configs/ include/asteris...

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Sat Dec 2 04:32:52 MST 2006


Author: oej
Date: Sat Dec  2 05:32:51 2006
New Revision: 48199

URL: http://svn.digium.com/view/asterisk?view=rev&rev=48199
Log:
- Disable RTP hold timers while T.38 fax transmission happens
- Encapsulate RTP timers in the rtp structure so we have one for video and one for audio
   The video one is not used in 1.4, really. Will be used for RTP keepalives when we can send
   something that video phones support in the RTP stream.
   I now this is a big architectual change at this stage for 1.4, but decided it was needed
   to avoid future bug reports.
- Document the RTP NAT keepalive option in sip.conf.sample

Issue 7679 in the bug tracker. Please test.


Modified:
    branches/1.4/channels/chan_sip.c
    branches/1.4/configs/sip.conf.sample
    branches/1.4/include/asterisk/rtp.h
    branches/1.4/main/rtp.c

Modified: branches/1.4/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/channels/chan_sip.c?view=diff&rev=48199&r1=48198&r2=48199
==============================================================================
--- branches/1.4/channels/chan_sip.c (original)
+++ branches/1.4/channels/chan_sip.c Sat Dec  2 05:32:51 2006
@@ -948,8 +948,6 @@
 	time_t lastrtprx;			/*!< Last RTP received */
 	time_t lastrtptx;			/*!< Last RTP sent */
 	int rtptimeout;				/*!< RTP timeout time */
-	int rtpholdtimeout;			/*!< RTP timeout when on hold */
-	int rtpkeepalive;			/*!< Send RTP packets for keepalive */
 	struct sockaddr_in recv;		/*!< Received as */
 	struct in_addr ourip;			/*!< Our IP */
 	struct ast_channel *owner;		/*!< Who owns us (if we have an owner) */
@@ -2593,17 +2591,21 @@
 	if (dialog->rtp) {
 		ast_rtp_setdtmf(dialog->rtp, ast_test_flag(&dialog->flags[0], SIP_DTMF) != SIP_DTMF_INFO);
 		ast_rtp_setdtmfcompensate(dialog->rtp, ast_test_flag(&dialog->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
+		ast_rtp_set_rtptimeout(dialog->rtp, peer->rtptimeout);
+		ast_rtp_set_rtpholdtimeout(dialog->rtp, peer->rtpholdtimeout);
+		ast_rtp_set_rtpkeepalive(dialog->rtp, peer->rtpkeepalive);
+		/* Set Frame packetization */
+		ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs);
+		dialog->autoframing = peer->autoframing;
 	}
 	if (dialog->vrtp) {
 		ast_rtp_setdtmf(dialog->vrtp, 0);
 		ast_rtp_setdtmfcompensate(dialog->vrtp, 0);
-	}
-
-	/* Set Frame packetization */
-	if (dialog->rtp) {
-		ast_rtp_codec_setpref(dialog->rtp, &dialog->prefs);
-		dialog->autoframing = peer->autoframing;
-	}
+		ast_rtp_set_rtptimeout(dialog->vrtp, peer->rtptimeout);
+		ast_rtp_set_rtpholdtimeout(dialog->vrtp, peer->rtpholdtimeout);
+		ast_rtp_set_rtpkeepalive(dialog->vrtp, peer->rtpkeepalive);
+	}
+
 	ast_string_field_set(dialog, peername, peer->username);
 	ast_string_field_set(dialog, authname, peer->username);
 	ast_string_field_set(dialog, username, peer->username);
@@ -2642,8 +2644,6 @@
 		dialog->noncodeccapability &= ~AST_RTP_DTMF;
 	ast_string_field_set(dialog, context, peer->context);
 	dialog->rtptimeout = peer->rtptimeout;
-	dialog->rtpholdtimeout = peer->rtpholdtimeout;
-	dialog->rtpkeepalive = peer->rtpkeepalive;
 	if (peer->call_limit)
 		ast_set_flag(&dialog->flags[0], SIP_CALL_LIMIT);
 	dialog->maxcallbitrate = peer->maxcallbitrate;
@@ -4171,16 +4171,19 @@
 		ast_rtp_setdtmf(p->rtp, ast_test_flag(&p->flags[0], SIP_DTMF) != SIP_DTMF_INFO);
 		ast_rtp_setdtmfcompensate(p->rtp, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
 		ast_rtp_settos(p->rtp, global_tos_audio);
+		ast_rtp_set_rtptimeout(p->rtp, global_rtptimeout);
+		ast_rtp_set_rtpholdtimeout(p->rtp, global_rtpholdtimeout);
+		ast_rtp_set_rtpkeepalive(p->rtp, global_rtpkeepalive);
 		if (p->vrtp) {
 			ast_rtp_settos(p->vrtp, global_tos_video);
 			ast_rtp_setdtmf(p->vrtp, 0);
 			ast_rtp_setdtmfcompensate(p->vrtp, 0);
+			ast_rtp_set_rtptimeout(p->vrtp, global_rtptimeout);
+			ast_rtp_set_rtpholdtimeout(p->vrtp, global_rtpholdtimeout);
+			ast_rtp_set_rtpkeepalive(p->vrtp, global_rtpkeepalive);
 		}
 		if (p->udptl)
 			ast_udptl_settos(p->udptl, global_tos_audio);
-		p->rtptimeout = global_rtptimeout;
-		p->rtpholdtimeout = global_rtpholdtimeout;
-		p->rtpkeepalive = global_rtpkeepalive;
 		p->maxcallbitrate = default_maxcallbitrate;
 	}
 
@@ -10184,6 +10187,7 @@
 	ast_cli(fd, "  T1 minimum:             %d\n", global_t1min);
 	ast_cli(fd, "  Relax DTMF:             %s\n", global_relaxdtmf ? "Yes" : "No");
 	ast_cli(fd, "  Compact SIP headers:    %s\n", compactheaders ? "Yes" : "No");
+	ast_cli(fd, "  RTP Keepalive:          %d %s\n", global_rtpkeepalive, global_rtpkeepalive ? "" : "(Disabled)" );
 	ast_cli(fd, "  RTP Timeout:            %d %s\n", global_rtptimeout, global_rtptimeout ? "" : "(Disabled)" );
 	ast_cli(fd, "  RTP Hold Timeout:       %d %s\n", global_rtpholdtimeout, global_rtpholdtimeout ? "" : "(Disabled)");
 	ast_cli(fd, "  MWI NOTIFY mime type:   %s\n", default_notifymime);
@@ -11598,6 +11602,9 @@
 				if (bridgepvt->udptl) {
 					if (p->t38.state == T38_PEER_REINVITE) {
 						sip_handle_t38_reinvite(bridgepeer, p, 0);
+						ast_rtp_set_rtptimers_onhold(p->rtp);
+						if (p->vrtp)
+							ast_rtp_set_rtptimers_onhold(p->vrtp);	/* Turn off RTP timers while we send fax */
 					} else if (p->t38.state == T38_DISABLED && bridgepeer && (bridgepvt->t38.state == T38_ENABLED)) {
 						ast_log(LOG_WARNING, "RTP re-inivte after T38 session not handled yet !\n");
 						/* Insted of this we should somehow re-invite the other side of the bridge to RTP */
@@ -14714,23 +14721,23 @@
 			    (sip->owner->_state == AST_STATE_UP) &&
 			    !sip->redirip.sin_addr.s_addr) {
 				if (sip->lastrtptx &&
-				    sip->rtpkeepalive &&
-				    (t > sip->lastrtptx + sip->rtpkeepalive)) {
+				    ast_rtp_get_rtpkeepalive(sip->rtp) &&
+				    (t > sip->lastrtptx + ast_rtp_get_rtpkeepalive(sip->rtp))) {
 					/* Need to send an empty RTP packet */
 					sip->lastrtptx = time(NULL);
 					ast_rtp_sendcng(sip->rtp, 0);
 				}
 				if (sip->lastrtprx &&
-				    (sip->rtptimeout || sip->rtpholdtimeout) &&
-				    (t > sip->lastrtprx + sip->rtptimeout)) {
+					(ast_rtp_get_rtptimeout(sip->rtp) || ast_rtp_get_rtpholdtimeout(sip->rtp)) &&
+				    (t > sip->lastrtprx + ast_rtp_get_rtptimeout(sip->rtp))) {
 					/* Might be a timeout now -- see if we're on hold */
 					struct sockaddr_in sin;
 					ast_rtp_get_peer(sip->rtp, &sin);
 					if (sin.sin_addr.s_addr || 
-					    (sip->rtpholdtimeout && 
-					     (t > sip->lastrtprx + sip->rtpholdtimeout))) {
+					    (ast_rtp_get_rtpholdtimeout(sip->rtp) &&
+					     (t > sip->lastrtprx + ast_rtp_get_rtpholdtimeout(sip->rtp)))) {
 						/* Needs a hangup */
-						if (sip->rtptimeout) {
+						if (ast_rtp_get_rtptimeout(sip->rtp)) {
 							while (sip->owner && ast_channel_trylock(sip->owner)) {
 								ast_mutex_unlock(&sip->lock);
 								usleep(1);
@@ -14751,8 +14758,12 @@
 								   has already been requested and we don't want to
 								   repeatedly request hangups
 								*/
-								sip->rtptimeout = 0;
-								sip->rtpholdtimeout = 0;
+								ast_rtp_set_rtptimeout(sip->rtp, 0);
+								ast_rtp_set_rtpholdtimeout(sip->rtp, 0);
+								if (sip->vrtp) {
+									ast_rtp_set_rtptimeout(sip->vrtp, 0);
+									ast_rtp_set_rtpholdtimeout(sip->vrtp, 0);
+								}
 							}
 						}
 					}

Modified: branches/1.4/configs/sip.conf.sample
URL: http://svn.digium.com/view/asterisk/branches/1.4/configs/sip.conf.sample?view=diff&rev=48199&r1=48198&r2=48199
==============================================================================
--- branches/1.4/configs/sip.conf.sample (original)
+++ branches/1.4/configs/sip.conf.sample Sat Dec  2 05:32:51 2006
@@ -91,12 +91,6 @@
 ;language=en			; Default language setting for all users/peers
 				; This may also be set for individual users/peers
 ;relaxdtmf=yes			; Relax dtmf handling
-;rtptimeout=60			; Terminate call if 60 seconds of no RTP or RTCP activity
-				; when we're not on hold. This is to be able to hangup
-				; a call in the case of a phone disappearing from the net,
-				; like a powerloss or grandma tripping over a cable.
-;rtpholdtimeout=300		; Terminate call if 300 seconds of no RTP or RTCP activity
-				; when we're on hold (must be > rtptimeout)
 ;trustrpid = no			; If Remote-Party-ID should be trusted
 ;sendrpid = yes			; If Remote-Party-ID should be sent
 ;progressinband=never		; If we should generate in-band ringing always
@@ -152,6 +146,21 @@
 ;
 ;regcontext=sipregistrations
 ;
+;--------------------------- RTP timers ----------------------------------------------------
+; These timers are currently used for both audio and video streams. The RTP timeouts
+; are only applied to the audio channel.
+; The settings are settable in the global section as well as per device
+;
+;rtptimeout=60			; Terminate call if 60 seconds of no RTP or RTCP activity
+				; on the audio channel
+				; when we're not on hold. This is to be able to hangup
+				; a call in the case of a phone disappearing from the net,
+				; like a powerloss or grandma tripping over a cable.
+;rtpholdtimeout=300		; Terminate call if 300 seconds of no RTP or RTCP activity
+				; on the audio channel
+				; when we're on hold (must be > rtptimeout)
+;rtpkeepalive=<secs>		; Send keepalives in the RTP stream to keep NAT open
+				; (default is off - zero)
 ;--------------------------- SIP DEBUGGING ---------------------------------------------------
 ;sipdebug = yes			; Turn on SIP debugging by default, from
 				; the moment the channel loads this configuration
@@ -196,8 +205,9 @@
 ;
 ; This setting is available in the [general] section as well as in device configurations.
 ; Setting this to yes, enables T.38 fax (UDPTL) passthrough on SIP to SIP calls, provided
-; both parties have T38 support enabled in their Asterisk configuration (either general or
-; peer/user/friend sections)
+; both parties have T38 support enabled in their Asterisk configuration 
+; This has to be enabled in the general section for all devices to work. You can then
+; disable it on a per device basis. 
 ;
 ; t38pt_udptl = yes            ; Default false
 ;

Modified: branches/1.4/include/asterisk/rtp.h
URL: http://svn.digium.com/view/asterisk/branches/1.4/include/asterisk/rtp.h?view=diff&rev=48199&r1=48198&r2=48199
==============================================================================
--- branches/1.4/include/asterisk/rtp.h (original)
+++ branches/1.4/include/asterisk/rtp.h Sat Dec  2 05:32:51 2006
@@ -219,6 +219,21 @@
 
 int ast_rtp_codec_getformat(int pt);
 
+/*! \brief Set rtp timeout */
+void ast_rtp_set_rtptimeout(struct ast_rtp *rtp, int timeout);
+/*! \brief Set rtp hold timeout */
+void ast_rtp_set_rtpholdtimeout(struct ast_rtp *rtp, int timeout);
+/*! \brief set RTP keepalive interval */
+void ast_rtp_set_rtpkeepalive(struct ast_rtp *rtp, int period);
+/*! \brief Get RTP keepalive interval */
+int ast_rtp_get_rtpkeepalive(struct ast_rtp *rtp);
+/*! \brief Get rtp hold timeout */
+int ast_rtp_get_rtpholdtimeout(struct ast_rtp *rtp);
+/*! \brief Get rtp timeout */
+int ast_rtp_get_rtptimeout(struct ast_rtp *rtp);
+/* \brief Put RTP timeout timers on hold during another transaction, like T.38 */
+void ast_rtp_set_rtptimers_onhold(struct ast_rtp *rtp);
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif

Modified: branches/1.4/main/rtp.c
URL: http://svn.digium.com/view/asterisk/branches/1.4/main/rtp.c?view=diff&rev=48199&r1=48198&r2=48199
==============================================================================
--- branches/1.4/main/rtp.c (original)
+++ branches/1.4/main/rtp.c Sat Dec  2 05:32:51 2006
@@ -128,6 +128,11 @@
 	double rxtransit;               /*!< Relative transit time for previous packet */
 	int lasttxformat;
 	int lastrxformat;
+
+	int rtptimeout;			/*!< RTP timeout time (negative or zero means disabled, negative value means temporarily disabled) */
+	int rtpholdtimeout;		/*!< RTP timeout when on hold (negative or zero means disabled, negative value means temporarily disabled). */
+	int rtpkeepalive;		/*!< Send RTP comfort noice packets for keepalive */
+
 	/* DTMF Reception Variables */
 	char resp;
 	unsigned int lasteventendseqn;
@@ -519,6 +524,53 @@
 	* Look in RFC 3550 Section A.7 for an example*/
 	interval = rtcpinterval;
 	return interval;
+}
+
+/* \brief Put RTP timeout timers on hold during another transaction, like T.38 */
+void ast_rtp_set_rtptimers_onhold(struct ast_rtp *rtp)
+{
+	rtp->rtptimeout = (-1) * rtp->rtptimeout;
+	rtp->rtpholdtimeout = (-1) * rtp->rtpholdtimeout;
+}
+
+/*! \brief Set rtp timeout */
+void ast_rtp_set_rtptimeout(struct ast_rtp *rtp, int timeout)
+{
+	rtp->rtptimeout = timeout;
+}
+
+/*! \brief Set rtp hold timeout */
+void ast_rtp_set_rtpholdtimeout(struct ast_rtp *rtp, int timeout)
+{
+	rtp->rtpholdtimeout = timeout;
+}
+
+/*! \brief set RTP keepalive interval */
+void ast_rtp_set_rtpkeepalive(struct ast_rtp *rtp, int period)
+{
+	rtp->rtpkeepalive = period;
+}
+
+/*! \brief Get rtp timeout */
+int ast_rtp_get_rtptimeout(struct ast_rtp *rtp)
+{
+	if (rtp->rtptimeout < 0)	/* We're not checking, but remembering the setting (during T.38 transmission) */
+		return 0;
+	return rtp->rtptimeout;
+}
+
+/*! \brief Get rtp hold timeout */
+int ast_rtp_get_rtpholdtimeout(struct ast_rtp *rtp)
+{
+	if (rtp->rtptimeout < 0)	/* We're not checking, but remembering the setting (during T.38 transmission) */
+		return 0;
+	return rtp->rtpholdtimeout;
+}
+
+/*! \brief Get RTP keepalive interval */
+int ast_rtp_get_rtpkeepalive(struct ast_rtp *rtp)
+{
+	return rtp->rtpkeepalive;
 }
 
 void ast_rtp_set_data(struct ast_rtp *rtp, void *data)



More information about the asterisk-commits mailing list