[svn-commits] kpfleming: branch kpfleming/sofiasdp r131130 - /team/kpfleming/sofiasdp/chann...

SVN commits to the Digium repositories svn-commits at lists.digium.com
Tue Jul 15 18:38:11 CDT 2008


Author: kpfleming
Date: Tue Jul 15 18:38:11 2008
New Revision: 131130

URL: http://svn.digium.com/view/asterisk?view=rev&rev=131130
Log:
more media stream setup, don't initialize temporary RTP structures until we know they are really needed, check the SDP session version as early as possible to avoid extra work

Modified:
    team/kpfleming/sofiasdp/channels/chan_sip.c

Modified: team/kpfleming/sofiasdp/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/kpfleming/sofiasdp/channels/chan_sip.c?view=diff&rev=131130&r1=131129&r2=131130
==============================================================================
--- team/kpfleming/sofiasdp/channels/chan_sip.c (original)
+++ team/kpfleming/sofiasdp/channels/chan_sip.c Tue Jul 15 18:38:11 2008
@@ -6557,6 +6557,48 @@
 	return 1;
 }
 
+static int setup_media_stream(const sdp_session_t *session, const sdp_media_t *media, struct sockaddr_in *sin, int debug)
+{
+	sdp_connection_t *conn;
+	struct hostent *host;
+	struct ast_hostent hostbuf;
+
+	for (conn = media->m_connections; conn; conn = conn->c_next) {
+		if (connection_usable(conn)) {
+			break;
+		}
+	}
+	if (!conn) {
+		conn = session->sdp_connection;
+	}
+	
+	if (!(host = ast_gethostbyname(conn->c_address, &hostbuf))) {
+		ast_log(LOG_WARNING, "Host lookup failed for '%s'\n", conn->c_address);
+		return -1;
+	}
+	
+	sin->sin_family = AF_INET;
+	memcpy(&sin->sin_addr, host->h_addr, sizeof(sin->sin_addr));
+	sin->sin_port = media->m_port;
+
+	return 0;
+}
+
+static int setup_rtp_media_stream(const sdp_session_t *session, const sdp_media_t *media, struct ast_rtp *rtp, struct sockaddr_in *sin, int debug)
+{
+	sdp_rtpmap_t *rtpmap;
+
+	for (rtpmap = media->m_rtpmaps; rtpmap; rtpmap = rtpmap->rm_next) {
+		if (debug)
+			ast_verbose("Found RTP %s format %d\n", media->m_type_name, rtpmap->rm_pt);
+		ast_rtp_set_m_type(rtp, rtpmap->rm_pt);
+	}
+	
+	/* TODO: parse attributes here */
+	
+	return setup_media_stream(session, media, sin, debug);
+}
+
 /*! \brief Process SIP SDP offer, select formats and activate RTP channels
 	If offer is rejected, we will not change any properties of the call
  	Return 0 on success, a negative value on errors.
@@ -6570,11 +6612,16 @@
 	sdp_parser_t *sdp = NULL;
 	sdp_session_t *session;
 	sdp_media_t *media;
-	struct ast_rtp *newaudiortp, *newvideortp, *newtextrtp;	/* Buffers for stream handling */
+	struct ast_rtp *newaudiortp = NULL, *newvideortp = NULL, *newtextrtp = NULL;	/* Buffers for stream handling */
 	int numberofmediastreams = 0;
 	int debug = sip_debug_test_pvt(p);
 	struct ast_str *parsebuf;
 	sdp_rtpmap_t *rtpmap;
+	sdp_connection_t *conn;
+	struct sockaddr_in asin = { .sin_port = 0 };	/*!< audio socket address */
+	struct sockaddr_in vsin = { .sin_port = 0 };	/*!< video socket address */
+	struct sockaddr_in tsin = { .sin_port = 0 };	/*!< text socket address */
+	struct sockaddr_in isin = { .sin_port = 0 };	/*!< image socket address */
 
 	if (!p->rtp) {
 		ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n");
@@ -6612,119 +6659,6 @@
 		ast_log(LOG_WARNING, "SDP syntax error. SDP without an o= line\n");
 		goto exit_free;
 	}
-
-	/* must have at least one media stream */
-	if (!session->sdp_media) {
-		ast_log(LOG_WARNING, "SDP does not contain any media streams\n");
-		goto exit_free;
-	}
-
-	/* sanity check media streams */
-	for (media = session->sdp_media; media; media = media->m_next) {
-		sdp_connection_t *conn;
-
-		/* does it have a usable connection? */
-		for (conn = media->m_connections; conn; conn = conn->c_next) {
-			if (connection_usable(conn)) {
-				break;
-			}
-		}
-
-		/* if not, and there is no session-level usable connection, we can't
-		   support this stream
-		*/
-		if (!conn && !connection_usable(session->sdp_connection)) {
-			ast_log(LOG_WARNING, "Media stream has no usable connection information\n");
-			goto exit_free;
-		}
-
-		/* ensure that the stream's type is supported */
-		switch (media->m_type) {
-		case sdp_media_audio:
-			break;
-		case sdp_media_video:
-			break;
-		case sdp_media_image:
-			break;
-		default:
-			if (strcasecmp(media->m_type_name, "text")) {
-				ast_log(LOG_WARNING, "Media stream is not a supported type (%s)\n", media->m_type_name);
-				goto exit_free;
-			}
-			break;
-		}
-
-		/* we can't handle streams that use more than one port */
-		if (media->m_number_of_ports > 1) {
-			ast_log(LOG_WARNING, "Media stream needs %d set of ports; only one is supported\n", (int) media->m_number_of_ports);
-		}
-
-		switch (media->m_proto) {
-		case sdp_proto_rtp:
-			for (rtpmap = media->m_rtpmaps; rtpmap; rtpmap = rtpmap->rm_next) {
-				if (rtpmap->rm_any) {
-					ast_log(LOG_WARNING, "Media stream uses an RTP map of 'any'; not supported\n");
-					goto exit_free;
-				}
-			}
-			break;
-		case sdp_proto_udptl:
-			/* TODO: anything to check here? */
-			break;
-		case sdp_proto_tcp:
-		case sdp_proto_srtp:
-		case sdp_proto_udp:
-		case sdp_proto_tls:
-		default:
-			ast_log(LOG_WARNING, "Media stream uses an unsupported protocol (%s)\n", media->m_proto_name);
-			goto exit_free;
-		}
-
-		/* this media stream is sane and can be supported */
-		numberofmediastreams++;
-	}
-
-	if (numberofmediastreams > 3) {
-		/* We have too many media streams, fail this offer */
-		ast_log(LOG_WARNING, "Too many media streams offered (%d)\n", numberofmediastreams);
-		res = -3;
-		goto exit_free;
-	} else if (numberofmediastreams == 0) {
-		ast_log(LOG_WARNING, "No compatible media streams offered\n");
-		res = -2;
-		goto exit_free;
-	}
-
-	/* Initialize the temporary RTP structures we use to evaluate the offer from the peer */
-#ifdef LOW_MEMORY
-	newaudiortp = ast_threadstorage_get(&ts_audio_rtp, ast_rtp_alloc_size());
-#else
-	newaudiortp = alloca(ast_rtp_alloc_size());
-#endif
-	memset(newaudiortp, 0, ast_rtp_alloc_size());
-	ast_rtp_new_init(newaudiortp);
-	ast_rtp_pt_clear(newaudiortp);
-
-#ifdef LOW_MEMORY
-	newvideortp = ast_threadstorage_get(&ts_video_rtp, ast_rtp_alloc_size());
-#else
-	newvideortp = alloca(ast_rtp_alloc_size());
-#endif
-	memset(newvideortp, 0, ast_rtp_alloc_size());
-	ast_rtp_new_init(newvideortp);
-	ast_rtp_pt_clear(newvideortp);
-
-#ifdef LOW_MEMORY
-	newtextrtp = ast_threadstorage_get(&ts_text_rtp, ast_rtp_alloc_size());
-#else
-	newtextrtp = alloca(ast_rtp_alloc_size());
-#endif
-	memset(newtextrtp, 0, ast_rtp_alloc_size());
-	ast_rtp_new_init(newtextrtp);
-	ast_rtp_pt_clear(newtextrtp);
-
-	/* Update our last rtprx when we receive an SDP, too */
-	p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
 
 	/* Store the SDP version number of remote UA. This will allow us to 
 	distinguish between session modifications and session refreshes. If 
@@ -6745,36 +6679,158 @@
 		goto exit_free;
 	}
 
+	/* must have at least one media stream */
+	if (!session->sdp_media) {
+		ast_log(LOG_WARNING, "SDP does not contain any media streams\n");
+		goto exit_free;
+	}
+
+	/* sanity check media streams */
+	for (media = session->sdp_media; media; media = media->m_next) {
+		/* does it have a usable connection? */
+		for (conn = media->m_connections; conn; conn = conn->c_next) {
+			if (connection_usable(conn)) {
+				break;
+			}
+		}
+
+		/* if not, and there is no session-level usable connection, we can't
+		   support this stream
+		*/
+		if (!conn && !connection_usable(session->sdp_connection)) {
+			ast_log(LOG_WARNING, "Media stream has no usable connection information\n");
+			goto exit_free;
+		}
+
+		/* ensure that the stream's type is supported */
+		switch (media->m_type) {
+		case sdp_media_audio:
+			break;
+		case sdp_media_video:
+			break;
+		case sdp_media_image:
+			break;
+		default:
+			if (strcasecmp(media->m_type_name, "text")) {
+				ast_log(LOG_WARNING, "Media stream is not a supported type (%s)\n", media->m_type_name);
+				goto exit_free;
+			}
+			break;
+		}
+
+		/* we can't handle streams that use more than one port */
+		if (media->m_number_of_ports > 1) {
+			ast_log(LOG_WARNING, "Media stream needs %d set of ports; only one is supported\n", (int) media->m_number_of_ports);
+		}
+
+		switch (media->m_proto) {
+		case sdp_proto_rtp:
+			if (media->m_type == sdp_media_image) {
+				ast_log(LOG_WARNING, "'image' media streams not supported using RTP protocol\n");
+				goto exit_free;
+			}
+			for (rtpmap = media->m_rtpmaps; rtpmap; rtpmap = rtpmap->rm_next) {
+				if (rtpmap->rm_any) {
+					ast_log(LOG_WARNING, "Media stream uses an RTP map of 'any'; not supported\n");
+					goto exit_free;
+				}
+			}
+			break;
+		case sdp_proto_udptl:
+			if (media->m_type != sdp_media_image) {
+				ast_log(LOG_WARNING, "Only 'image' media streams supported using UDPTL protocol\n");
+				goto exit_free;
+			}
+			break;
+		case sdp_proto_tcp:
+		case sdp_proto_srtp:
+		case sdp_proto_udp:
+		case sdp_proto_tls:
+		default:
+			ast_log(LOG_WARNING, "Media stream uses an unsupported protocol (%s)\n", media->m_proto_name);
+			goto exit_free;
+		}
+
+		/* this media stream is sane and can be supported */
+		numberofmediastreams++;
+
+		/* Initialize the temporary RTP structures we use to evaluate the offer from the peer */
+		switch (media->m_type) {
+		case sdp_media_audio:
+#ifdef LOW_MEMORY
+			newaudiortp = ast_threadstorage_get(&ts_audio_rtp, ast_rtp_alloc_size());
+#else
+			newaudiortp = alloca(ast_rtp_alloc_size());
+#endif
+			memset(newaudiortp, 0, ast_rtp_alloc_size());
+			ast_rtp_new_init(newaudiortp);
+			ast_rtp_pt_clear(newaudiortp);
+			break;
+		case sdp_media_video:
+#ifdef LOW_MEMORY
+			newvideortp = ast_threadstorage_get(&ts_video_rtp, ast_rtp_alloc_size());
+#else
+			newvideortp = alloca(ast_rtp_alloc_size());
+#endif
+			memset(newvideortp, 0, ast_rtp_alloc_size());
+			ast_rtp_new_init(newvideortp);
+			ast_rtp_pt_clear(newvideortp);
+			break;
+		case sdp_media_image:
+			break;
+		default:
+#ifdef LOW_MEMORY
+			newtextrtp = ast_threadstorage_get(&ts_text_rtp, ast_rtp_alloc_size());
+#else
+			newtextrtp = alloca(ast_rtp_alloc_size());
+#endif
+			memset(newtextrtp, 0, ast_rtp_alloc_size());
+			ast_rtp_new_init(newtextrtp);
+			ast_rtp_pt_clear(newtextrtp);
+			break;
+		}
+	}
+
+	if (numberofmediastreams > 3) {
+		/* We have too many media streams, fail this offer */
+		ast_log(LOG_WARNING, "Too many media streams offered (%d)\n", numberofmediastreams);
+		res = -3;
+		goto exit_free;
+	} else if (numberofmediastreams == 0) {
+		ast_log(LOG_WARNING, "No compatible media streams offered\n");
+		res = -2;
+		goto exit_free;
+	}
+
+	/* Update our last rtprx when we receive an SDP, too */
+	p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
+
 	/* default: novideo and notext set */
 	p->novideo = TRUE;
 	p->notext = TRUE;
 
-	/* process the media streams */
+	/* setup the media streams */
 	for (media = session->sdp_media; media; media = media->m_next) {
 		switch (media->m_type) {
 		case sdp_media_audio:
-			for (rtpmap = media->m_rtpmaps; rtpmap; rtpmap = rtpmap->rm_next) {
-				if (debug)
-					ast_verbose("Found RTP audio format %d\n", rtpmap->rm_pt);
-				ast_rtp_set_m_type(newaudiortp, rtpmap->rm_pt);
+			if ((res = setup_rtp_media_stream(session, media, newaudiortp, &asin, debug))) {
+				goto exit_free;
 			}
 			break;
 		case sdp_media_video:
-			for (rtpmap = media->m_rtpmaps; rtpmap; rtpmap = rtpmap->rm_next) {
-				if (debug)
-					ast_verbose("Found RTP video format %d\n", rtpmap->rm_pt);
-				ast_rtp_set_m_type(newvideortp, rtpmap->rm_pt);
+			if ((res = setup_rtp_media_stream(session, media, newvideortp, &vsin, debug))) {
+				goto exit_free;
 			}
 			break;
 		case sdp_media_image:
-			for (rtpmap = media->m_rtpmaps; rtpmap; rtpmap = rtpmap->rm_next) {
-				if (debug)
-					ast_verbose("Found RTP text format %d\n", rtpmap->rm_pt);
-				ast_rtp_set_m_type(newtextrtp, rtpmap->rm_pt);
+			if ((res = setup_media_stream(session, media, &isin, debug))) {
+				goto exit_free;
 			}
 			break;
 		default:
-			/* must be "text", because we filtered out everything else already */
+			if ((res = setup_rtp_media_stream(session, media, newtextrtp, &tsin, debug))) {
+				goto exit_free;
+			}
 			break;
 		}
 	}




More information about the svn-commits mailing list