[asterisk-commits] trunk r26019 - in /trunk: ./ apps/ channels/ include/asterisk/

asterisk-commits at lists.digium.com asterisk-commits at lists.digium.com
Tue May 9 04:44:50 MST 2006


Author: markster
Date: Tue May  9 06:44:50 2006
New Revision: 26019

URL: http://svn.digium.com/view/asterisk?rev=26019&view=rev
Log:
Make SIP early media work more efficiently without so many reinvites

Modified:
    trunk/apps/app_dial.c
    trunk/channels/chan_sip.c
    trunk/include/asterisk/rtp.h
    trunk/rtp.c

Modified: trunk/apps/app_dial.c
URL: http://svn.digium.com/view/asterisk/trunk/apps/app_dial.c?rev=26019&r1=26018&r2=26019&view=diff
==============================================================================
--- trunk/apps/app_dial.c (original)
+++ trunk/apps/app_dial.c Tue May  9 06:44:50 2006
@@ -482,7 +482,7 @@
 					ast_clear_flag(o, DIAL_STILLGOING);	
 					HANDLE_CAUSE(cause, in);
 				} else {
-					ast_rtp_make_compatible(c, in);
+					ast_rtp_make_compatible(c, in, single);
 					if (c->cid.cid_num)
 						free(c->cid.cid_num);
 					c->cid.cid_num = NULL;
@@ -550,6 +550,8 @@
 							       OPT_CALLEE_HANGUP | OPT_CALLER_HANGUP |
 							       OPT_CALLEE_MONITOR | OPT_CALLER_MONITOR |
 							       DIAL_NOFORWARDHTML);
+						/* Setup early media if appropriate */
+						ast_rtp_early_media(in, peer);
 					}
 					/* If call has been answered, then the eventual hangup is likely to be normal hangup */
 					in->hangupcause = AST_CAUSE_NORMAL_CLEARING;
@@ -576,6 +578,9 @@
 				case AST_CONTROL_RINGING:
 					if (option_verbose > 2)
 						ast_verbose(VERBOSE_PREFIX_3 "%s is ringing\n", c->name);
+					/* Setup early media if appropriate */
+					if (single)
+						ast_rtp_early_media(in, c);
 					if (!(*sentringing) && !ast_test_flag(outgoing, OPT_MUSICBACK)) {
 						ast_indicate(in, AST_CONTROL_RINGING);
 						(*sentringing)++;
@@ -584,6 +589,9 @@
 				case AST_CONTROL_PROGRESS:
 					if (option_verbose > 2)
 						ast_verbose (VERBOSE_PREFIX_3 "%s is making progress passing it to %s\n", c->name, in->name);
+					/* Setup early media if appropriate */
+					if (single)
+						ast_rtp_early_media(in, c);
 					if (!ast_test_flag(outgoing, OPT_RINGBACK))
 						ast_indicate(in, AST_CONTROL_PROGRESS);
 					break;
@@ -595,6 +603,8 @@
 				case AST_CONTROL_PROCEEDING:
 					if (option_verbose > 2)
 						ast_verbose (VERBOSE_PREFIX_3 "%s is proceeding passing it to %s\n", c->name, in->name);
+					if (single)
+						ast_rtp_early_media(in, c);
 					if (!ast_test_flag(outgoing, OPT_RINGBACK))
 						ast_indicate(in, AST_CONTROL_PROCEEDING);
 					break;
@@ -1056,7 +1066,7 @@
 		}
 
 		/* Setup outgoing SDP to match incoming one */
-		ast_rtp_make_compatible(tmp->chan, chan);
+		ast_rtp_make_compatible(tmp->chan, chan, !outgoing && !rest);
 		
 		/* Inherit specially named variables from parent channel */
 		ast_channel_inherit_variables(chan, tmp->chan);
@@ -1550,6 +1560,7 @@
 		sentringing = 0;
 		ast_indicate(chan, -1);
 	}
+	ast_rtp_early_media(chan, NULL);
 	hanguptree(outgoing, NULL);
 	pbx_builtin_setvar_helper(chan, "DIALSTATUS", status);
 	if (option_debug)

Modified: trunk/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_sip.c?rev=26019&r1=26018&r2=26019&view=diff
==============================================================================
--- trunk/channels/chan_sip.c (original)
+++ trunk/channels/chan_sip.c Tue May  9 06:44:50 2006
@@ -13588,6 +13588,7 @@
 static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp *rtp, struct ast_rtp *vrtp, int codecs, int nat_active)
 {
 	struct sip_pvt *p;
+	int changed = 0;
 
 	p = chan->tech_pvt;
 	if (!p) 
@@ -13598,17 +13599,23 @@
 		ast_mutex_unlock(&p->lock);
 		return 0;
 	}
-	if (rtp)
-		ast_rtp_get_peer(rtp, &p->redirip);
+	if (rtp) 
+		changed |= ast_rtp_get_peer(rtp, &p->redirip);
 	else
 		memset(&p->redirip, 0, sizeof(p->redirip));
 	if (vrtp)
-		ast_rtp_get_peer(vrtp, &p->vredirip);
+		changed |= ast_rtp_get_peer(vrtp, &p->vredirip);
 	else
 		memset(&p->vredirip, 0, sizeof(p->vredirip));
-	p->redircodecs = codecs;
-	if (!ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
-		if (!p->pendinginvite) {
+	if (p->redircodecs != codecs) {
+		p->redircodecs = codecs;
+		changed = 1;
+	}
+	if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER)) {
+		if (chan->_state != AST_STATE_UP) {
+				char iabuf[INET_ADDRSTRLEN];
+				ast_log(LOG_DEBUG, "Early media setting SIP '%s' - Sending early media to %s\n", p->callid, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp ? p->redirip.sin_addr : p->ourip));
+		} else if (!p->pendinginvite) {
 			if (option_debug > 2) {
 				char iabuf[INET_ADDRSTRLEN];
 				ast_log(LOG_DEBUG, "Sending reinvite on SIP '%s' - It's audio soon redirected to IP %s\n", p->callid, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp ? p->redirip.sin_addr : p->ourip));

Modified: trunk/include/asterisk/rtp.h
URL: http://svn.digium.com/view/asterisk/trunk/include/asterisk/rtp.h?rev=26019&r1=26018&r2=26019&view=diff
==============================================================================
--- trunk/include/asterisk/rtp.h (original)
+++ trunk/include/asterisk/rtp.h Tue May  9 06:44:50 2006
@@ -97,7 +97,8 @@
 
 void ast_rtp_set_peer(struct ast_rtp *rtp, struct sockaddr_in *them);
 
-void ast_rtp_get_peer(struct ast_rtp *rtp, struct sockaddr_in *them);
+/* Copies from rtp to them and returns 1 if there was a change or 0 if it was already the same */
+int ast_rtp_get_peer(struct ast_rtp *rtp, struct sockaddr_in *them);
 
 void ast_rtp_get_us(struct ast_rtp *rtp, struct sockaddr_in *us);
 
@@ -154,7 +155,9 @@
 
 void ast_rtp_proto_unregister(struct ast_rtp_protocol *proto);
 
-int ast_rtp_make_compatible(struct ast_channel *dest, struct ast_channel *src);
+int ast_rtp_make_compatible(struct ast_channel *dest, struct ast_channel *src, int media);
+
+int ast_rtp_early_media(struct ast_channel *dest, struct ast_channel *src);
 
 void ast_rtp_stop(struct ast_rtp *rtp);
 

Modified: trunk/rtp.c
URL: http://svn.digium.com/view/asterisk/trunk/rtp.c?rev=26019&r1=26018&r2=26019&view=diff
==============================================================================
--- trunk/rtp.c (original)
+++ trunk/rtp.c Tue May  9 06:44:50 2006
@@ -733,11 +733,83 @@
 	return cur;
 }
 
-int ast_rtp_make_compatible(struct ast_channel *dest, struct ast_channel *src)
+int ast_rtp_early_media(struct ast_channel *dest, struct ast_channel *src)
+{
+	struct ast_rtp *destp, *srcp=NULL;		/* Audio RTP Channels */
+	struct ast_rtp *vdestp, *vsrcp=NULL;		/* Video RTP channels */
+	struct ast_rtp_protocol *destpr, *srcpr=NULL;
+	int srccodec;
+	/* Lock channels */
+	ast_channel_lock(dest);
+	if (src) {
+		while(ast_channel_trylock(src)) {
+			ast_channel_unlock(dest);
+			usleep(1);
+			ast_channel_lock(dest);
+		}
+	}
+
+	/* Find channel driver interfaces */
+	destpr = get_proto(dest);
+	if (src)
+		srcpr = get_proto(src);
+	if (!destpr) {
+		if (option_debug)
+			ast_log(LOG_DEBUG, "Channel '%s' has no RTP, not doing anything\n", dest->name);
+		ast_channel_unlock(dest);
+		if (src)
+			ast_channel_unlock(src);
+		return 0;
+	}
+	if (!srcpr) {
+		if (option_debug)
+			ast_log(LOG_DEBUG, "Channel '%s' has no RTP, not doing anything\n", src->name);
+		ast_channel_unlock(dest);
+		if (src)
+			ast_channel_unlock(src);
+		return 0;
+	}
+
+	/* Get audio and video interface (if native bridge is possible) */
+	destp = destpr->get_rtp_info(dest);
+	vdestp = (destpr->get_vrtp_info) ? destpr->get_vrtp_info(dest) : NULL;
+	if (srcpr) {
+		srcp = srcpr->get_rtp_info(src);
+		vsrcp = (srcpr->get_vrtp_info) ? srcpr->get_vrtp_info(src) : NULL;
+	}
+
+	/* Check if bridge is still possible (In SIP canreinvite=no stops this, like NAT) */
+	if (!destp) {
+		/* Somebody doesn't want to play... */
+		ast_channel_unlock(dest);
+		if (src)
+			ast_channel_unlock(src);
+		return 0;
+	}
+	if (srcpr && srcpr->get_codec)
+		srccodec = srcpr->get_codec(src);
+	else
+		srccodec = 0;
+	/* Consider empty media as non-existant */
+	if (srcp && !srcp->them.sin_addr.s_addr)
+		srcp = NULL;
+	/* Bridge early media */
+	if (destpr->set_rtp_peer(dest, srcp, vsrcp, srccodec, srcp ? ast_test_flag(srcp, FLAG_NAT_ACTIVE) : 0))
+		ast_log(LOG_WARNING, "Channel '%s' failed to send early media to '%s'\n", dest->name, src ? src->name : "<unspecified>");
+	ast_channel_unlock(dest);
+	if (src)
+		ast_channel_unlock(src);
+	if (option_debug)
+		ast_log(LOG_DEBUG, "Setting early  media SDP of '%s' with that of '%s'\n", dest->name, src ? src->name : "<unspecified>");
+	return 1;
+}
+
+int ast_rtp_make_compatible(struct ast_channel *dest, struct ast_channel *src, int media)
 {
 	struct ast_rtp *destp, *srcp;		/* Audio RTP Channels */
 	struct ast_rtp *vdestp, *vsrcp;		/* Video RTP channels */
 	struct ast_rtp_protocol *destpr, *srcpr;
+	int srccodec;
 	/* Lock channels */
 	ast_channel_lock(dest);
 	while(ast_channel_trylock(src)) {
@@ -780,6 +852,15 @@
 	ast_rtp_pt_copy(destp, srcp);
 	if (vdestp && vsrcp)
 		ast_rtp_pt_copy(vdestp, vsrcp);
+	if (srcpr->get_codec)
+		srccodec = srcpr->get_codec(src);
+	else
+		srccodec = 0;
+	if (media) {
+		/* Bridge early media */
+		if (destpr->set_rtp_peer(dest, srcp, vsrcp, srccodec, ast_test_flag(srcp, FLAG_NAT_ACTIVE)))
+			ast_log(LOG_WARNING, "Channel '%s' failed to send early media to '%s'\n", dest->name, src->name);
+	}
 	ast_channel_unlock(dest);
 	ast_channel_unlock(src);
 	if (option_debug)
@@ -1086,11 +1167,17 @@
 	rtp->rxseqno = 0;
 }
 
-void ast_rtp_get_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
-{
-	them->sin_family = AF_INET;
-	them->sin_port = rtp->them.sin_port;
-	them->sin_addr = rtp->them.sin_addr;
+int ast_rtp_get_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
+{
+	if ((them->sin_family != AF_INET) ||
+		(them->sin_port != rtp->them.sin_port) ||
+		(them->sin_addr.s_addr != rtp->them.sin_addr.s_addr)) {
+		them->sin_family = AF_INET;
+		them->sin_port = rtp->them.sin_port;
+		them->sin_addr = rtp->them.sin_addr;
+		return 1;
+	}
+	return 0;
 }
 
 void ast_rtp_get_us(struct ast_rtp *rtp, struct sockaddr_in *us)



More information about the asterisk-commits mailing list