[Asterisk-cvs] asterisk/channels Makefile,1.51,1.52 chan_oss.c,1.25,1.26 chan_sip.c,1.401,1.402

markster at lists.digium.com markster at lists.digium.com
Thu May 27 17:58:08 CDT 2004


Update of /usr/cvsroot/asterisk/channels
In directory mongoose.digium.com:/tmp/cvs-serv4664/channels

Modified Files:
	Makefile chan_oss.c chan_sip.c 
Log Message:
Merge OSS fixes for FreeBSD, implement rtptimeout and rtpholdtimeout


Index: Makefile
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/Makefile,v
retrieving revision 1.51
retrieving revision 1.52
diff -u -d -r1.51 -r1.52
--- Makefile	19 May 2004 17:16:46 -0000	1.51
+++ Makefile	27 May 2004 22:12:55 -0000	1.52
@@ -47,10 +47,8 @@
 endif
 
 ifneq (${OSARCH},Darwin)
-ifneq (${OSARCH},FreeBSD)
 CHANNEL_LIBS+=chan_oss.so
 endif
-endif
 
 CHANNEL_LIBS+=$(shell [ -f /usr/include/linux/ixjuser.h ] && echo chan_phone.so)
 CHANNEL_LIBS+=$(shell [ -f h323/libchanh323.a ] && echo chan_h323.so)
@@ -64,6 +62,7 @@
 ZAPPRI=$(shell [ -f /usr/lib/libpri.so.1 ] && echo "-lpri")
 ZAPR2=$(shell [ -f /usr/lib/libmfcr2.so.1 ] && echo "-lmfcr2")
 CFLAGS+=$(shell [ -f /usr/include/linux/zaptel.h ] && echo "-DIAX_TRUNKING")
+# xxx CFLAGS+=$(shell [ -f /usr/local/include/zaptel.h ] && echo "-DIAX_TRUNKING")
 CHANNEL_LIBS+=$(shell [ -f /usr/include/vpbapi.h ] && echo "chan_vpb.so" )
 CFLAGS+=$(shell [ -f /usr/include/vpbapi.h ] && echo " -DLINUX")
 

Index: chan_oss.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_oss.c,v
retrieving revision 1.25
retrieving revision 1.26
diff -u -d -r1.25 -r1.26
--- chan_oss.c	2 May 2004 17:52:45 -0000	1.25
+++ chan_oss.c	27 May 2004 22:12:55 -0000	1.26
@@ -36,7 +36,7 @@
 #ifdef __linux
 #include <linux/soundcard.h>
 #elif defined(__FreeBSD__)
-#include <machine/soundcard.h>
+#include <sys/soundcard.h>
 #else
 #include <soundcard.h>
 #endif

Index: chan_sip.c
===================================================================
RCS file: /usr/cvsroot/asterisk/channels/chan_sip.c,v
retrieving revision 1.401
retrieving revision 1.402
diff -u -d -r1.401 -r1.402
--- chan_sip.c	27 May 2004 16:14:46 -0000	1.401
+++ chan_sip.c	27 May 2004 22:12:55 -0000	1.402
@@ -150,6 +150,10 @@
 
 static int relaxdtmf = 0;
 
+static int globalrtptimeout = 0;
+
+static int globalrtpholdtimeout = 0;
+
 static int usecnt =0;
 static ast_mutex_t usecnt_lock = AST_MUTEX_INITIALIZER;
 
@@ -314,6 +318,9 @@
 	int maxtime;				/* Max time for first response */
 	int initid;				/* Auto-congest ID if appropriate */
 	int autokillid;				/* Auto-kill ID */
+	time_t lastrtprx;			/* Last RTP received */
+	int rtptimeout;				/* RTP timeout time */
+	int rtpholdtimeout;			/* RTP timeout when on hold */
 
 	int subscribed;
     	int stateid;
@@ -396,6 +403,8 @@
 	int expire;
 	int expiry;
 	int capability;
+	int rtptimeout;
+	int rtpholdtimeout;
 	int insecure;
 	int nat;
 	int canreinvite;
@@ -1519,7 +1528,7 @@
 	ast_mutex_unlock(&usecnt_lock);
 	ast_update_use_count();
 
-	needdestroy = 1;
+	needdestroy = 1; 
 	/* Start the process if it's not already started */
 	if (!p->alreadygone && !ast_strlen_zero(p->initreq.data)) {
 		if (needcancel) {
@@ -1982,6 +1991,7 @@
 	struct sip_pvt *p = ast->pvt->pvt;
 	ast_mutex_lock(&p->lock);
 	fr = sip_rtp_read(ast, p);
+	time(&p->lastrtprx);
 	ast_mutex_unlock(&p->lock);
 	return fr;
 }
@@ -2059,6 +2069,8 @@
 	/* Assign default music on hold class */
         strncpy(p->musicclass, globalmusicclass, sizeof(p->musicclass));
 	p->dtmfmode = globaldtmfmode;
+	p->rtptimeout = globalrtptimeout;
+	p->rtpholdtimeout = globalrtpholdtimeout;
 	p->capability = capability;
 	if (p->dtmfmode & SIP_DTMF_RFC2833)
 		p->noncodeccapability |= AST_RTP_DTMF;
@@ -2360,6 +2372,9 @@
 	int sendonly = 0;
 	int x;
 
+	/* Update our last rtprx when we receive an SDP, too */
+	time(&p->lastrtprx);
+
 	/* Get codec and RTP info from SDP */
 	if (strcasecmp(get_header(req, "Content-Type"), "application/sdp")) {
 		ast_log(LOG_NOTICE, "Content is '%s', not 'application/sdp'\n", get_header(req, "Content-Type"));
@@ -3181,6 +3196,8 @@
 		add_line(resp, m2);
 		add_line(resp, a2);
 	}
+	/* Update lastrtprx when we send our SDP */
+	time(&p->lastrtprx);
 	return 0;
 }
 
@@ -5428,8 +5445,10 @@
 		   }
 		   transmit_response(p, "200 OK", req);
 		   return;
+		} else {
+			transmit_response(p, "481 Call leg/transaction does not exist", req);
+			p->needdestroy = 1;
 		}
-		transmit_response(p, "481 Call leg/transaction does not exist", req);
 		return;
 	}
 	/* Other type of INFO message, not really understood by Asterisk */
@@ -6353,7 +6372,7 @@
 			/* This call is no longer outgoing if it ever was */
 			p->outgoing = 0;
 			/* This also counts as a pending invite */
-			p->pendinginvite = 1;
+			p->pendinginvite = seqno;
 			copy_request(&p->initreq, req);
 			check_via(p, req);
 			if (!ast_strlen_zero(get_header(req, "Content-Type"))) {
@@ -6675,7 +6694,6 @@
 				ast_verbose("Receiving DTMF!\n");
 			receive_info(p, req);
 		}
-		transmit_response(p, "200 OK", req);
 	} else if (!strcasecmp(cmd, "REGISTER")) {
 		/* Use this as the basis */
 		if (sip_debug_test_pvt(p))
@@ -6690,16 +6708,16 @@
 		    sip_scheddestroy(p, 15*1000);
 		}
 	} else if (!strcasecmp(cmd, "ACK")) {
-		/* Uhm, I haven't figured out the point of the ACK yet.  Are we
-		   supposed to retransmit responses until we get an ack? 
-		   Make sure this is on a valid call */
-		p->pendinginvite = 0;
-		__sip_ack(p, seqno, FLAG_RESPONSE);
-		if (!ast_strlen_zero(get_header(req, "Content-Type"))) {
-			if (process_sdp(p, req))
-				return -1;
-		} 
-		check_pendings(p);
+		/* Make sure we don't ignore this */
+		if (seqno == p->pendinginvite) {
+			p->pendinginvite = 0;
+			__sip_ack(p, seqno, FLAG_RESPONSE);
+			if (!ast_strlen_zero(get_header(req, "Content-Type"))) {
+				if (process_sdp(p, req))
+					return -1;
+			} 
+			check_pendings(p);
+		}
 		if (!p->lastinvite && ast_strlen_zero(p->randdata))
 			p->needdestroy = 1;
 	} else if (!strcasecmp(cmd, "SIP/2.0")) {
@@ -6857,9 +6875,35 @@
 		/* Check for interfaces needing to be killed */
 		ast_mutex_lock(&iflock);
 restartsearch:		
+		time(&t);
 		sip = iflist;
 		while(sip) {
 			ast_mutex_lock(&sip->lock);
+			if (sip->rtp && sip->lastrtprx && (sip->rtptimeout || sip->rtpholdtimeout)) {
+				if (t > sip->lastrtprx + sip->rtptimeout) {
+					/* 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))) {
+						/* Needs a hangup */
+						if (sip->rtptimeout) {
+							while(sip->owner && ast_mutex_trylock(&sip->owner->lock)) {
+								ast_mutex_unlock(&sip->lock);
+								usleep(1);
+								ast_mutex_lock(&sip->lock);
+							}
+							if (sip->owner) {
+								ast_log(LOG_NOTICE, "Disconnecting call '%s' for lack of RTP activity in %ld seconds\n", sip->owner->name, (long)(t - sip->lastrtprx));
+								/* Issue a softhangup */
+								ast_softhangup(sip->owner, AST_SOFTHANGUP_DEV);
+								ast_mutex_unlock(&sip->owner->lock);
+							}
+						}
+					}
+				}
+			}
 			if (sip->needdestroy && !sip->packets) {
 				ast_mutex_unlock(&sip->lock);
 				__sip_destroy(sip, 1);
@@ -7262,6 +7306,8 @@
 	peer->canreinvite = globalcanreinvite;
 	peer->dtmfmode = globaldtmfmode;
 	peer->nat = globalnat;
+	peer->rtptimeout = globalrtptimeout;
+	peer->rtpholdtimeout = globalrtpholdtimeout;
 	peer->selfdestruct = 1;
 	peer->dynamic = 1;
 	reg_source_db(peer);
@@ -7320,6 +7366,8 @@
 		peer->capability = capability;
 		/* Assume can reinvite */
 		peer->canreinvite = globalcanreinvite;
+		peer->rtptimeout = globalrtptimeout;
+		peer->rtpholdtimeout = globalrtpholdtimeout;
 		peer->dtmfmode = 0;
 		while(v) {
 			if (!strcasecmp(v->name, "secret")) 
@@ -7425,6 +7473,16 @@
 					peer->insecure = 1;
 				else
 					peer->insecure = 0;
+			} else if (!strcasecmp(v->name, "rtptimeout")) {
+				if ((sscanf(v->value, "%d", &peer->rtptimeout) != 1) || (peer->rtptimeout < 0)) {
+					ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
+					peer->rtptimeout = globalrtptimeout;
+				}
+			} else if (!strcasecmp(v->name, "rtpholdtimeout")) {
+				if ((sscanf(v->value, "%d", &peer->rtpholdtimeout) != 1) || (peer->rtpholdtimeout < 0)) {
+					ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
+					peer->rtpholdtimeout = globalrtpholdtimeout;
+				}
 			} else if (!strcasecmp(v->name, "qualify")) {
 				if (!strcasecmp(v->value, "no")) {
 					peer->maxms = 0;
@@ -7493,6 +7551,8 @@
 	globalcanreinvite = REINVITE_INVITE;
 	videosupport = 0;
 	relaxdtmf = 0;
+	globalrtptimeout = 0;
+	globalrtpholdtimeout = 0;
 	pedanticsipchecking=0;
 	v = ast_variable_browse(cfg, "general");
 	while(v) {
@@ -7517,6 +7577,16 @@
 				ast_log(LOG_WARNING, "Unknown dtmf mode '%s', using rfc2833\n", v->value);
 				globaldtmfmode = SIP_DTMF_RFC2833;
 			}
+		} else if (!strcasecmp(v->name, "rtptimeout")) {
+			if ((sscanf(v->value, "%d", &globalrtptimeout) != 1) || (globalrtptimeout < 0)) {
+				ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
+				globalrtptimeout = 0;
+			}
+		} else if (!strcasecmp(v->name, "rtpholdtimeout")) {
+			if ((sscanf(v->value, "%d", &globalrtpholdtimeout) != 1) || (globalrtpholdtimeout < 0)) {
+				ast_log(LOG_WARNING, "'%s' is not a valid RTP hold time at line %d.  Using default.\n", v->value, v->lineno);
+				globalrtpholdtimeout = 0;
+			}
 		} else if (!strcasecmp(v->name, "videosupport")) {
 			videosupport = ast_true(v->value);
 		} else if (!strcasecmp(v->name, "notifymimetype")) {




More information about the svn-commits mailing list