[asterisk-commits] kpfleming: branch kpfleming/sofiasdp r131130 - /team/kpfleming/sofiasdp/chann...
SVN commits to the Asterisk project
asterisk-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 asterisk-commits
mailing list