[svn-commits] loren: branch loren/sdp-parser r275546 - /team/loren/sdp-parser/channels/

SVN commits to the Digium repositories svn-commits at lists.digium.com
Sun Jul 11 02:21:08 CDT 2010


Author: loren
Date: Sun Jul 11 02:21:04 2010
New Revision: 275546

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=275546
Log:
current version of sdp parsing code

Modified:
    team/loren/sdp-parser/channels/chan_sip.c

Modified: team/loren/sdp-parser/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/loren/sdp-parser/channels/chan_sip.c?view=diff&rev=275546&r1=275545&r2=275546
==============================================================================
--- team/loren/sdp-parser/channels/chan_sip.c (original)
+++ team/loren/sdp-parser/channels/chan_sip.c Sun Jul 11 02:21:04 2010
@@ -273,7 +273,7 @@
 #include "asterisk/xml.h"
 #include "sip/include/dialog.h"
 #include "sip/include/dialplan_functions.h"
-
+#include "sip/include/sdp_parser.h"
 
 /*** DOCUMENTATION
 	<application name="SIPDtmfMode" language="en_US">
@@ -7468,1189 +7468,6 @@
 	return determine_firstline_parts(req);
 }
 
-/*!
-  \brief Determine whether a SIP message contains an SDP in its body
-  \param req the SIP request to process
-  \return 1 if SDP found, 0 if not found
-
-  Also updates req->sdp_start and req->sdp_count to indicate where the SDP
-  lives in the message body.
-*/
-static int find_sdp(struct sip_request *req)
-{
-	const char *content_type;
-	const char *content_length;
-	const char *search;
-	char *boundary;
-	unsigned int x;
-	int boundaryisquoted = FALSE;
-	int found_application_sdp = FALSE;
-	int found_end_of_headers = FALSE;
-
-	content_length = get_header(req, "Content-Length");
-
-	if (!ast_strlen_zero(content_length)) {
-		if (sscanf(content_length, "%30u", &x) != 1) {
-			ast_log(LOG_WARNING, "Invalid Content-Length: %s\n", content_length);
-			return 0;
-		}
-
-		/* Content-Length of zero means there can't possibly be an
-		   SDP here, even if the Content-Type says there is */
-		if (x == 0)
-			return 0;
-	}
-
-	content_type = get_header(req, "Content-Type");
-
-	/* if the body contains only SDP, this is easy */
-	if (!strncasecmp(content_type, "application/sdp", 15)) {
-		req->sdp_start = 0;
-		req->sdp_count = req->lines;
-		return req->lines ? 1 : 0;
-	}
-
-	/* if it's not multipart/mixed, there cannot be an SDP */
-	if (strncasecmp(content_type, "multipart/mixed", 15))
-		return 0;
-
-	/* if there is no boundary marker, it's invalid */
-	if ((search = strcasestr(content_type, ";boundary=")))
-		search += 10;
-	else if ((search = strcasestr(content_type, "; boundary=")))
-		search += 11;
-	else
-		return 0;
-
-	if (ast_strlen_zero(search))
-		return 0;
-
-	/* If the boundary is quoted with ", remove quote */
-	if (*search == '\"')  {
-		search++;
-		boundaryisquoted = TRUE;
-	}
-
-	/* make a duplicate of the string, with two extra characters
-	   at the beginning */
-	boundary = ast_strdupa(search - 2);
-	boundary[0] = boundary[1] = '-';
-	/* Remove final quote */
-	if (boundaryisquoted)
-		boundary[strlen(boundary) - 1] = '\0';
-
-	/* search for the boundary marker, the empty line delimiting headers from
-	   sdp part and the end boundry if it exists */
-
-	for (x = 0; x < (req->lines); x++) {
-		const char *line = REQ_OFFSET_TO_STR(req, line[x]);
-		if (!strncasecmp(line, boundary, strlen(boundary))){
-			if (found_application_sdp && found_end_of_headers) {
-				req->sdp_count = (x - 1) - req->sdp_start;
-				return 1;
-			}
-			found_application_sdp = FALSE;
-		}
-		if (!strcasecmp(line, "Content-Type: application/sdp"))
-			found_application_sdp = TRUE;
-		
-		if (ast_strlen_zero(line)) {
-			if (found_application_sdp && !found_end_of_headers){
-				req->sdp_start = x;
-				found_end_of_headers = TRUE;
-			}
-		}
-	}
-	if (found_application_sdp && found_end_of_headers) {
-		req->sdp_count = x - req->sdp_start;
-		return TRUE;
-	}
-	return FALSE;
-}
-
-
-static int get_ip_and_port_from_sdp(struct sip_request *req, const enum media_type media, struct sockaddr_in *sin)
-{
-	const char *m;
-	const char *c;
-	int miterator = req->sdp_start;
-	int citerator = req->sdp_start;
-	int x = 0;
-	int numberofports;
-	int len;
-	char host[258] = ""; /*Initialize to empty so we will know if we have any input */
-	struct ast_hostent audiohp;
-	struct hostent *hp;
-
-	c = get_sdp_iterate(&citerator, req, "c");
-	if (sscanf(c, "IN IP4 %256s", host) != 1) {
-		ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
-		/* Continue since there may be a valid host in a c= line specific to the audio stream */
-	}
-	/* We only want the m and c lines for audio */
-	for (m = get_sdp_iterate(&miterator, req, "m"); !ast_strlen_zero(m); m = get_sdp_iterate(&miterator, req, "m")) {
-		if ((media == SDP_AUDIO && ((sscanf(m, "audio %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
-		    (sscanf(m, "audio %30u RTP/AVP %n", &x, &len) == 1 && len > 0))) ||
-			(media == SDP_VIDEO && ((sscanf(m, "video %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
-		    (sscanf(m, "video %30u RTP/AVP %n", &x, &len) == 1 && len > 0)))) {
-			/* See if there's a c= line for this media stream.
-			 * XXX There is no guarantee that we'll be grabbing the c= line for this
-			 * particular media stream here. However, this is the same logic used in process_sdp.
-			 */
-			c = get_sdp_iterate(&citerator, req, "c");
-			if (!ast_strlen_zero(c)) {
-				sscanf(c, "IN IP4 %256s", host);
-			}
-			break;
-		}
-	}
-
-	if (ast_strlen_zero(host) || x == 0) {
-		ast_log(LOG_WARNING, "Failed to read an alternate host or port in SDP. Expect %s problems\n", media == SDP_AUDIO ? "audio" : "video");
-		return -1;
-	}
-
-	hp = ast_gethostbyname(host, &audiohp);
-	if (!hp) {
-		ast_log(LOG_WARNING, "Could not look up IP address of alternate hostname. Expect %s problems\n", media == SDP_AUDIO? "audio" : "video");
-		return -1;
-	}
-
-	memcpy(&sin->sin_addr, hp->h_addr, sizeof(sin->sin_addr));
-	sin->sin_port = htons(x);
-	return 0;
-}
-
-/*! \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.
-	Must be called after find_sdp().
-*/
-static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action)
-{
-	/* Iterators for SDP parsing */
-	int start = req->sdp_start;
-	int next = start;
-	int iterator = start;
-
-	/* Temporary vars for SDP parsing */
-	char type = '\0';
-	const char *value = NULL;
-	const char *m = NULL;           /* SDP media offer */
-	const char *nextm = NULL;
-	int len = -1;
-
-	/* Host information */
-	struct ast_hostent sessionhp;
-	struct ast_hostent audiohp;
-	struct ast_hostent videohp;
-	struct ast_hostent texthp;
-	struct ast_hostent imagehp;
-	struct hostent *hp = NULL;	/*!< RTP Audio host IP */
-	struct hostent *vhp = NULL;	/*!< RTP video host IP */
-	struct hostent *thp = NULL;	/*!< RTP text host IP */
-	struct hostent *ihp = NULL;     /*!< UDPTL host ip */
- 	int portno = -1;		/*!< RTP Audio port number */
- 	int vportno = -1;		/*!< RTP Video port number */
-	int tportno = -1;		/*!< RTP Text port number */
-	int udptlportno = -1;		/*!< UDPTL Image port number */
-	struct sockaddr_in sin;		/*!< media socket address */
-	struct sockaddr_in vsin;	/*!< video socket address */
-	struct sockaddr_in isin;	/*!< image socket address */
-	struct sockaddr_in tsin;	/*!< text socket address */
-
-	/* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */	
-	format_t peercapability = 0, vpeercapability = 0, tpeercapability = 0;
-	int peernoncodeccapability = 0, vpeernoncodeccapability = 0, tpeernoncodeccapability = 0;
-
-	struct ast_rtp_codecs newaudiortp, newvideortp, newtextrtp;
-	format_t newjointcapability;				/* Negotiated capability */
-	format_t newpeercapability;
-	int newnoncodeccapability;
-
-	const char *codecs;
-	int codec;
-
-	/* SRTP */
-	int secure_audio = FALSE;
-	int secure_video = FALSE;
-
-	/* Others */
-	int sendonly = -1;
-	int vsendonly = -1;
-	int numberofports;
-	int numberofmediastreams = 0;
-	int last_rtpmap_codec = 0;
-	int red_data_pt[10];		/* For T.140 red */
-	int red_num_gen = 0;		/* For T.140 red */
-	char red_fmtp[100] = "empty";	/* For T.140 red */
-	int debug = sip_debug_test_pvt(p);
-
-	/* START UNKNOWN */
-	char buf[SIPBUFSIZE];
-	/* END UNKNOWN */
-
-	/* Initial check */
-	if (!p->rtp) {
-		ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n");
-		return -1;
-	}
-
-	/* Make sure that the codec structures are all cleared out */
-	ast_rtp_codecs_payloads_clear(&newaudiortp, NULL);
-	ast_rtp_codecs_payloads_clear(&newvideortp, NULL);
-	ast_rtp_codecs_payloads_clear(&newtextrtp, NULL);
-
-	/* Update our last rtprx when we receive an SDP, too */
-	p->lastrtprx = p->lastrtptx = time(NULL); /* XXX why both ? */
-
-	memset(p->offered_media, 0, sizeof(p->offered_media));
-
-
-	/* default: novideo and notext set */
-	p->novideo = TRUE;
-	p->notext = TRUE;
-
-	if (p->vrtp) {
-		ast_rtp_codecs_payloads_clear(&newvideortp, NULL);
-	}
-
-	if (p->trtp) {
-		ast_rtp_codecs_payloads_clear(&newtextrtp, NULL);
-	}
-
-	/* Scan for the first media stream (m=) line to limit scanning of globals */
-	nextm = get_sdp_iterate(&next, req, "m");
-	if (ast_strlen_zero(nextm)) {
-		ast_log(LOG_WARNING, "Insufficient information for SDP (m= not found)\n");
- 		return -1;
- 	}
-
-	/* Scan session level SDP parameters (lines before first media stream) */
-	while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') {
-		int processed = FALSE;
-		switch (type) {
-		case 'o':
-			/* If we end up receiving SDP that doesn't actually modify the session we don't want to treat this as a fatal
-			 * error. We just want to ignore the SDP and let the rest of the packet be handled as normal.
-			 */
-			if (!process_sdp_o(value, p))
-				return (p->session_modify == FALSE) ? 0 : -1;
-			break;
-		case 'c':
-			if (process_sdp_c(value, &sessionhp)) {
-				processed = TRUE;
-				hp = &sessionhp.hp;
-				vhp = hp;
-				thp = hp;
-				ihp = hp;
-			}
-			break;
-		case 'a':
-			if (process_sdp_a_sendonly(value, &sendonly)) {
-				processed = TRUE;
-				vsendonly = sendonly;
-			}
-			else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec))
-				processed = TRUE;
-			else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec))
-				processed = TRUE;
-			else if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec))
-				processed = TRUE;
-			else if (process_sdp_a_image(value, p))
-				processed = TRUE;
-			break;
-		}
-
-		if (option_debug > 2)
-			ast_log(LOG_DEBUG, "Processing session-level SDP %c=%s... %s\n", type, value, (processed == TRUE)? "OK." : "UNSUPPORTED.");
- 	}
-
-
-
-	/* Scan media stream (m=) specific parameters loop */
-	while (!ast_strlen_zero(nextm)) {
-		int audio = FALSE;
-		int video = FALSE;
-		int image = FALSE;
-		int text = FALSE;
-		char protocol[5] = {0,};
-		int x;
-
-		numberofports = 1;
-		len = -1;
-		start = next;
-		m = nextm;
-		iterator = next;
-		nextm = get_sdp_iterate(&next, req, "m");
-
-		/* Search for audio media definition */
-		if ((sscanf(m, "audio %30u/%30u RTP/%4s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) ||
-		    (sscanf(m, "audio %30u RTP/%4s %n", &x, protocol, &len) == 2 && len > 0)) {
-			if (!strcmp(protocol, "SAVP")) {
-				secure_audio = 1;
-			} else if (strcmp(protocol, "AVP")) {
-				ast_log(LOG_WARNING, "unknown SDP media protocol in offer: %s\n", protocol);
-				continue;
-			}
-			audio = TRUE;
-			p->offered_media[SDP_AUDIO].offered = TRUE;
-			numberofmediastreams++;
-			portno = x;
-
-			/* Scan through the RTP payload types specified in a "m=" line: */
-			codecs = m + len;
-			ast_copy_string(p->offered_media[SDP_AUDIO].codecs, codecs, sizeof(p->offered_media[SDP_AUDIO].codecs));
-			for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
-				if (sscanf(codecs, "%30u%n", &codec, &len) != 1) {
-					ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
-					return -1;
-				}
-				if (debug)
-					ast_verbose("Found RTP audio format %d\n", codec);
-				
-				ast_rtp_codecs_payloads_set_m_type(&newaudiortp, NULL, codec);
-			}
-		/* Search for video media definition */
-		} else if ((sscanf(m, "video %30u/%30u RTP/%4s %n", &x, &numberofports, protocol, &len) == 3 && len > 0) ||
-			   (sscanf(m, "video %30u RTP/%4s %n", &x, protocol, &len) == 2 && len >= 0)) {
-			if (!strcmp(protocol, "SAVP")) {
-				secure_video = 1;
-			} else if (strcmp(protocol, "AVP")) {
-				ast_log(LOG_WARNING, "unknown SDP media protocol in offer: %s\n", protocol);
-				continue;
-			}
-			video = TRUE;
-			p->novideo = FALSE;
-			p->offered_media[SDP_VIDEO].offered = TRUE;
-			numberofmediastreams++;
-			vportno = x;
-
-			/* Scan through the RTP payload types specified in a "m=" line: */
-			codecs = m + len;
-			ast_copy_string(p->offered_media[SDP_VIDEO].codecs, codecs, sizeof(p->offered_media[SDP_VIDEO].codecs));
-			for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
-				if (sscanf(codecs, "%30u%n", &codec, &len) != 1) {
-					ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
-					return -1;
-				}
-				if (debug)
-					ast_verbose("Found RTP video format %d\n", codec);
-				ast_rtp_codecs_payloads_set_m_type(&newvideortp, NULL, codec);
-			}
-		/* Search for text media definition */
-		} else if ((sscanf(m, "text %30u/%30u RTP/AVP %n", &x, &numberofports, &len) == 2 && len > 0) ||
-			   (sscanf(m, "text %30u RTP/AVP %n", &x, &len) == 1 && len > 0)) {
-			text = TRUE;
-			p->notext = FALSE;
-			p->offered_media[SDP_TEXT].offered = TRUE;
-			numberofmediastreams++;
-			tportno = x;
-
-			/* Scan through the RTP payload types specified in a "m=" line: */
-			codecs = m + len;
-			ast_copy_string(p->offered_media[SDP_TEXT].codecs, codecs, sizeof(p->offered_media[SDP_TEXT].codecs));
-			for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
-				if (sscanf(codecs, "%30u%n", &codec, &len) != 1) {
-					ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
-					return -1;
-				}
-				if (debug)
-					ast_verbose("Found RTP text format %d\n", codec);
-				ast_rtp_codecs_payloads_set_m_type(&newtextrtp, NULL, codec);
-			}
-		/* Search for image media definition */
-		} else if (p->udptl && ((sscanf(m, "image %30u udptl t38%n", &x, &len) == 1 && len > 0) ||
-					(sscanf(m, "image %30u UDPTL t38%n", &x, &len) == 1 && len > 0) )) {
-			image = TRUE;
-			if (debug)
-				ast_verbose("Got T.38 offer in SDP in dialog %s\n", p->callid);
-			p->offered_media[SDP_IMAGE].offered = TRUE;
-			udptlportno = x;
-			numberofmediastreams++;
-
-			if (p->t38.state != T38_ENABLED) {
-				memset(&p->t38.their_parms, 0, sizeof(p->t38.their_parms));
-			}
-		} else {
-			ast_log(LOG_WARNING, "Unsupported SDP media type in offer: %s\n", m);
-			continue;
-		}
-
-		/* Check for number of ports */
-		if (numberofports > 1)
-			ast_log(LOG_WARNING, "SDP offered %d ports for media, not supported by Asterisk. Will try anyway...\n", numberofports);
-		
-		/* Media stream specific parameters */
-		while ((type = get_sdp_line(&iterator, next - 1, req, &value)) != '\0') {
-			int processed = FALSE;
-
-			switch (type) {
-			case 'c':
-				if (audio) {
-					if (process_sdp_c(value, &audiohp)) {
-						processed = TRUE;
-						hp = &audiohp.hp;
-					}
-				} else if (video) {
-					if (process_sdp_c(value, &videohp)) {
-						processed = TRUE;
-						vhp = &videohp.hp;
-					}
-				} else if (text) {
-					if (process_sdp_c(value, &texthp)) {
-						processed = TRUE;
-						thp = &texthp.hp;
-					}
-				} else if (image) {
-					if (process_sdp_c(value, &imagehp)) {
-						processed = TRUE;
-						ihp = &imagehp.hp;
-					}
-				}
-				break;
-			case 'a':
-				/* Audio specific scanning */
-				if (audio) {
-					if (process_sdp_a_sendonly(value, &sendonly))
-						processed = TRUE;
-					else if (process_crypto(p, p->rtp, &p->srtp, value))
-						processed = TRUE;
-					else if (process_sdp_a_audio(value, p, &newaudiortp, &last_rtpmap_codec))
-						processed = TRUE;
-				}
-				/* Video specific scanning */
-				else if (video) {
-					if (process_sdp_a_sendonly(value, &vsendonly))
-						processed = TRUE;
-					else if (process_crypto(p, p->vrtp, &p->vsrtp, value))
-						processed = TRUE;
-					else if (process_sdp_a_video(value, p, &newvideortp, &last_rtpmap_codec))
-						processed = TRUE;
-				}
-				/* Text (T.140) specific scanning */
-				else if (text) {
-					if (process_sdp_a_text(value, p, &newtextrtp, red_fmtp, &red_num_gen, red_data_pt, &last_rtpmap_codec))
-						processed = TRUE;
-					else if (process_crypto(p, p->trtp, &p->tsrtp, value))
-						processed = TRUE;
-				}
-				/* Image (T.38 FAX) specific scanning */
-				else if (image) {
-					if (process_sdp_a_image(value, p))
-						processed = TRUE;
-				}
-				break;
-			}
-
-			if (option_debug > 2)
-				ast_log(LOG_DEBUG, "Processing media-level (%s) SDP %c=%s... %s\n",
-						(audio == TRUE)? "audio" : (video == TRUE)? "video" : "image",
-						type, value,
-						(processed == TRUE)? "OK." : "UNSUPPORTED.");
-		}
-	}
-
-
-	/* Sanity checks */
-	if (!hp && !vhp && !thp && !ihp) {
-		ast_log(LOG_WARNING, "Insufficient information in SDP (c=)...\n");
-		return -1;
-	}
-
-	if (portno == -1 && vportno == -1 && udptlportno == -1  && tportno == -1) {
-		/* No acceptable offer found in SDP  - we have no ports */
-		/* Do not change RTP or VRTP if this is a re-invite */
-		ast_log(LOG_WARNING, "Failing due to no acceptable offer found\n");
-		return -2;
-	}
-
-	if (numberofmediastreams > 3) {
-		/* We have too many fax, audio and/or video and/or text media streams, fail this offer */
-		ast_log(LOG_WARNING, "Faling due to too many media streams\n");
-		return -3;
-	}
-
-	if (secure_audio && !(p->srtp && (ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK)))) {
-		ast_log(LOG_WARNING, "Can't provide secure audio requested in SDP offer\n");
-		return -4;
-	}
-
-	if (!secure_audio && p->srtp) {
-		ast_log(LOG_WARNING, "We are requesting SRTP, but they responded without it!\n");
-		return -4;
-	}
-
-	if (secure_video && !(p->vsrtp && (ast_test_flag(p->vsrtp, SRTP_CRYPTO_OFFER_OK)))) {
-		ast_log(LOG_WARNING, "Can't provide secure video requested in SDP offer\n");
-		return -4;
-	}
-
-	if (!p->novideo && !secure_video && p->vsrtp) {
-		ast_log(LOG_WARNING, "We are requesting SRTP, but they responded without it!\n");
-		return -4;
-	}
-
-	if (!(secure_audio || secure_video) && ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) {
-		ast_log(LOG_WARNING, "Matched device setup to use SRTP, but request was not!\n");
-		return -4;
-	}
-
-	if (udptlportno == -1) {
-		change_t38_state(p, T38_DISABLED);
-	}
-
-	/* Now gather all of the codecs that we are asked for: */
-	ast_rtp_codecs_payload_formats(&newaudiortp, &peercapability, &peernoncodeccapability);
-	ast_rtp_codecs_payload_formats(&newvideortp, &vpeercapability, &vpeernoncodeccapability);
-	ast_rtp_codecs_payload_formats(&newtextrtp, &tpeercapability, &tpeernoncodeccapability);
-
-	newjointcapability = p->capability & (peercapability | vpeercapability | tpeercapability);
-	newpeercapability = (peercapability | vpeercapability | tpeercapability);
-	newnoncodeccapability = p->noncodeccapability & peernoncodeccapability;
-
-	if (debug) {
-		/* shame on whoever coded this.... */
-		char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE], s5[SIPBUFSIZE];
-
-		ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s/text=%s, combined - %s\n",
-			    ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability),
-			    ast_getformatname_multiple(s2, SIPBUFSIZE, peercapability),
-			    ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability),
-			    ast_getformatname_multiple(s4, SIPBUFSIZE, tpeercapability),
-			    ast_getformatname_multiple(s5, SIPBUFSIZE, newjointcapability));
-	}
-	if (debug) {
-		struct ast_str *s1 = ast_str_alloca(SIPBUFSIZE);
-		struct ast_str *s2 = ast_str_alloca(SIPBUFSIZE);
-		struct ast_str *s3 = ast_str_alloca(SIPBUFSIZE);
-
-		ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n",
-			    ast_rtp_lookup_mime_multiple2(s1, p->noncodeccapability, 0, 0),
-			    ast_rtp_lookup_mime_multiple2(s2, peernoncodeccapability, 0, 0),
-			    ast_rtp_lookup_mime_multiple2(s3, newnoncodeccapability, 0, 0));
-	}
-	if (!newjointcapability && (portno != -1)) {
-		ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n");
-		/* Do NOT Change current setting */
-		return -1;
-	}
-
-	/* Setup audio address and port */
-	if (p->rtp) {
-		if (portno > 0) {
-			sin.sin_family = AF_INET;
-			sin.sin_port = htons(portno);
-			memcpy(&sin.sin_addr, hp->h_addr, sizeof(sin.sin_addr));
-			ast_rtp_instance_set_remote_address(p->rtp, &sin);
-			if (debug)
-				ast_verbose("Peer audio RTP is at port %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
-			/* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since                                                                                                    
-			   they are acceptable */
-			p->jointcapability = newjointcapability;                /* Our joint codec profile for this call */
-			p->peercapability = newpeercapability;                  /* The other sides capability in latest offer */
-			p->jointnoncodeccapability = newnoncodeccapability;     /* DTMF capabilities */
-
-			if (ast_test_flag(&p->flags[1], SIP_PAGE2_PREFERRED_CODEC)) { /* respond with single most preferred joint codec, limiting the other side's choice */
-				p->jointcapability = ast_codec_choose(&p->prefs, p->jointcapability, 1);
-			}
-
-			ast_rtp_codecs_payloads_copy(&newaudiortp, ast_rtp_instance_get_codecs(p->rtp), p->rtp);
-
-			if (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO) {
-				ast_clear_flag(&p->flags[0], SIP_DTMF);
-				if (newnoncodeccapability & AST_RTP_DTMF) {
-					/* XXX Would it be reasonable to drop the DSP at this point? XXX */
-					ast_set_flag(&p->flags[0], SIP_DTMF_RFC2833);
-					/* Since RFC2833 is now negotiated we need to change some properties of the RTP stream */
-					ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF, 1);
-					ast_rtp_instance_set_prop(p->rtp, AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_test_flag(&p->flags[1], SIP_PAGE2_RFC2833_COMPENSATE));
-				} else {
-					ast_set_flag(&p->flags[0], SIP_DTMF_INBAND);
-				}
-			}
-		} else if (udptlportno > 0) {
-			if (debug)
-				ast_verbose("Got T.38 Re-invite without audio. Keeping RTP active during T.38 session.\n");
-		} else {
-			ast_rtp_instance_stop(p->rtp);
-			if (debug)
-				ast_verbose("Peer doesn't provide audio\n");
-		}
-	}
-
-	/* Setup video address and port */
-	if (p->vrtp) {
-		if (vportno > 0) {
-			vsin.sin_family = AF_INET;
-			vsin.sin_port = htons(vportno);
-			memcpy(&vsin.sin_addr, vhp->h_addr, sizeof(vsin.sin_addr));
-			ast_rtp_instance_set_remote_address(p->vrtp, &vsin);
-			if (debug) 
-				ast_verbose("Peer video RTP is at port %s:%d\n", ast_inet_ntoa(vsin.sin_addr), ntohs(vsin.sin_port));
-			ast_rtp_codecs_payloads_copy(&newvideortp, ast_rtp_instance_get_codecs(p->vrtp), p->vrtp);
-		} else {
-			ast_rtp_instance_stop(p->vrtp);
-			if (debug)
-				ast_verbose("Peer doesn't provide video\n");
-		}
-	}
-
-	/* Setup text address and port */
-	if (p->trtp) {
-		if (tportno > 0) {
-			tsin.sin_family = AF_INET;
-			tsin.sin_port = htons(tportno);
-			memcpy(&tsin.sin_addr, thp->h_addr, sizeof(tsin.sin_addr));
-			ast_rtp_instance_set_remote_address(p->trtp, &tsin);
-			if (debug) 
-				ast_verbose("Peer T.140 RTP is at port %s:%d\n", ast_inet_ntoa(tsin.sin_addr), ntohs(tsin.sin_port));
-			if ((p->jointcapability & AST_FORMAT_T140RED)) {
-				p->red = 1;
-				ast_rtp_red_init(p->trtp, 300, red_data_pt, 2);
-			} else {
-				p->red = 0;
-			}
-			ast_rtp_codecs_payloads_copy(&newtextrtp, ast_rtp_instance_get_codecs(p->trtp), p->trtp);
-		} else {
-			ast_rtp_instance_stop(p->trtp);
-			if (debug)
-				ast_verbose("Peer doesn't provide T.140\n");
-		}
-	}
-	/* Setup image address and port */
-	if (p->udptl) {
-		if (udptlportno > 0) {
-			isin.sin_family = AF_INET;
-			isin.sin_port = htons(udptlportno);
-			if (ast_test_flag(&p->flags[1], SIP_PAGE2_SYMMETRICRTP) && ast_test_flag(&p->flags[1], SIP_PAGE2_UDPTL_DESTINATION)) {
-				struct sockaddr_in remote_address = { 0, };
-				ast_rtp_instance_get_remote_address(p->rtp, &remote_address);
-				if (remote_address.sin_addr.s_addr) {
-					memcpy(&isin, &remote_address, sizeof(isin));
-					if (debug) {
-						ast_log(LOG_DEBUG, "Peer T.38 UDPTL is set behind NAT and with destination, destination address now %s\n", ast_inet_ntoa(isin.sin_addr));
-					}
-				}
-			} else {
-				memcpy(&isin.sin_addr, ihp->h_addr, sizeof(isin.sin_addr));
-			}
-			ast_udptl_set_peer(p->udptl, &isin);
-			if (debug)
-				ast_debug(1,"Peer T.38 UDPTL is at port %s:%d\n", ast_inet_ntoa(isin.sin_addr), ntohs(isin.sin_port));
-
-			/* verify the far max ifp can be calculated. this requires far max datagram to be set. */
-			if (!ast_udptl_get_far_max_datagram(p->udptl)) {
-				/* setting to zero will force a default if none was provided by the SDP */
-				ast_udptl_set_far_max_datagram(p->udptl, 0);
-			}
-
-			/* Remote party offers T38, we need to update state */
-			if ((t38action == SDP_T38_ACCEPT) &&
-			    (p->t38.state == T38_LOCAL_REINVITE)) {
-				change_t38_state(p, T38_ENABLED);
-			} else if ((t38action == SDP_T38_INITIATE) &&
-				   p->owner && p->lastinvite) {
-				change_t38_state(p, T38_PEER_REINVITE); /* T38 Offered in re-invite from remote party */
-				/* If fax detection is enabled then send us off to the fax extension */
-				if (ast_test_flag(&p->flags[1], SIP_PAGE2_FAX_DETECT_T38)) {
-					ast_channel_lock(p->owner);
-					if (strcmp(p->owner->exten, "fax")) {
-						const char *target_context = S_OR(p->owner->macrocontext, p->owner->context);
-						ast_channel_unlock(p->owner);
-						if (ast_exists_extension(p->owner, target_context, "fax", 1, p->owner->cid.cid_num)) {
-							ast_verbose(VERBOSE_PREFIX_2 "Redirecting '%s' to fax extension due to peer T.38 re-INVITE\n", p->owner->name);
-							pbx_builtin_setvar_helper(p->owner, "FAXEXTEN", p->owner->exten);
-							if (ast_async_goto(p->owner, target_context, "fax", 1)) {
-								ast_log(LOG_NOTICE, "Failed to async goto '%s' into fax of '%s'\n", p->owner->name, target_context);
-							}
-						} else {
-							ast_log(LOG_NOTICE, "T.38 re-INVITE detected but no fax extension\n");
-						}
-					} else {
-						ast_channel_unlock(p->owner);
-					}
-				}
-			}
-		} else {
-			ast_udptl_stop(p->udptl);
-			if (debug)
-				ast_debug(1, "Peer doesn't provide T.38 UDPTL\n");
-		}
-	}
-
-	if ((portno == -1) && (p->t38.state != T38_DISABLED)) {
-		ast_debug(3, "Have T.38 but no audio, accepting offer anyway\n");
-		return 0;
-        }
-
-	/* Ok, we're going with this offer */
-	ast_debug(2, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability));
-
-	if (!p->owner) 	/* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */
-		return 0;
-
-	ast_debug(4, "We have an owner, now see if we need to change this call\n");
-
-	if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
-		if (debug) {
-			char s1[SIPBUFSIZE], s2[SIPBUFSIZE];
-			ast_debug(1, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n",
-				ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability),
-				ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats));
-		}
-		p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability) | (p->capability & tpeercapability);
-		ast_set_read_format(p->owner, p->owner->readformat);
-		ast_set_write_format(p->owner, p->owner->writeformat);
-	}
-	
-	if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && sin.sin_addr.s_addr && (!sendonly || sendonly == -1)) {
-		ast_queue_control(p->owner, AST_CONTROL_UNHOLD);
-		/* Activate a re-invite */
-		ast_queue_frame(p->owner, &ast_null_frame);
-		/* Queue Manager Unhold event */
-		append_history(p, "Unhold", "%s", req->data->str);
-		if (sip_cfg.callevents)
-			ast_manager_event(p->owner, EVENT_FLAG_CALL, "Hold",
-				      "Status: Off\r\n"
-				      "Channel: %s\r\n"
-				      "Uniqueid: %s\r\n",
-				      p->owner->name,
-				      p->owner->uniqueid);
-		if (sip_cfg.notifyhold)
-			sip_peer_hold(p, FALSE);
-		ast_clear_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD); /* Clear both flags */
-	} else if (!sin.sin_addr.s_addr || (sendonly && sendonly != -1)) {
-		int already_on_hold = ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD);
-		ast_queue_control_data(p->owner, AST_CONTROL_HOLD,
-				       S_OR(p->mohsuggest, NULL),
-				       !ast_strlen_zero(p->mohsuggest) ? strlen(p->mohsuggest) + 1 : 0);
-		if (sendonly)
-			ast_rtp_instance_stop(p->rtp);
-		/* RTCP needs to go ahead, even if we're on hold!!! */
-		/* Activate a re-invite */
-		ast_queue_frame(p->owner, &ast_null_frame);
-		/* Queue Manager Hold event */
-		append_history(p, "Hold", "%s", req->data->str);
-		if (sip_cfg.callevents && !ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD)) {
-			ast_manager_event(p->owner, EVENT_FLAG_CALL, "Hold",
-				      "Status: On\r\n"
-				      "Channel: %s\r\n"
-				      "Uniqueid: %s\r\n",
-				      p->owner->name,
-				      p->owner->uniqueid);
-		}
-		if (sendonly == 1)	/* One directional hold (sendonly/recvonly) */
-			ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ONEDIR);
-		else if (sendonly == 2)	/* Inactive stream */
-			ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_INACTIVE);
-		else
-			ast_set_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD_ACTIVE);
-		if (sip_cfg.notifyhold && !already_on_hold)
-			sip_peer_hold(p, TRUE);
-	}
-	
-	return 0;
-}
-
-static int process_sdp_o(const char *o, struct sip_pvt *p)
-{
-	char *o_copy;
-	char *token;
-	int64_t rua_version;
-
-	/* Store the SDP version number of remote UA. This will allow us to
-	distinguish between session modifications and session refreshes. If
-	the remote UA does not send an incremented SDP version number in a
-	subsequent RE-INVITE then that means its not changing media session.
-	The RE-INVITE may have been sent to update connected party, remote
-	target or to refresh the session (Session-Timers).  Asterisk must not
-	change media session and increment its own version number in answer
-	SDP in this case. */
-
-	p->session_modify = TRUE;
-
-	if (ast_strlen_zero(o)) {
-		ast_log(LOG_WARNING, "SDP syntax error. SDP without an o= line\n");
-		return FALSE;
-	}
-
-	o_copy = ast_strdupa(o);
-	token = strsep(&o_copy, " ");  /* Skip username   */
-	if (!o_copy) {
-		ast_log(LOG_WARNING, "SDP syntax error in o= line username\n");
-		return FALSE;
-	}
-	token = strsep(&o_copy, " ");  /* Skip session-id */
-	if (!o_copy) {
-		ast_log(LOG_WARNING, "SDP syntax error in o= line session-id\n");
-		return FALSE;
-	}
-	token = strsep(&o_copy, " ");  /* Version         */
-	if (!o_copy) {
-		ast_log(LOG_WARNING, "SDP syntax error in o= line\n");
-		return FALSE;
-	}
-	if (!sscanf(token, "%30" SCNd64, &rua_version)) {
-		ast_log(LOG_WARNING, "SDP syntax error in o= line version\n");
-		return FALSE;
-	}
-
-	/* we need to check the SDP version number the other end sent us;
-	 * our rules for deciding what to accept are a bit complex.
-	 *
-	 * 1) if 'ignoresdpversion' has been set for this dialog, then
-	 *    we will just accept whatever they sent and assume it is
-	 *    a modification of the session, even if it is not
-	 * 2) otherwise, if this is the first SDP we've seen from them
-	 *    we accept it
-	 * 3) otherwise, if the new SDP version number is higher than the
-	 *    old one, we accept it
-	 * 4) otherwise, if this SDP is in response to us requesting a switch
-	 *    to T.38, we accept the SDP, but also generate a warning message
-	 *    that this peer should have the 'ignoresdpversion' option set,
-	 *    because it is not following the SDP offer/answer RFC; if we did
-	 *    not request a switch to T.38, then we stop parsing the SDP, as it
-	 *    has not changed from the previous version
-	 */
-
-	if (ast_test_flag(&p->flags[1], SIP_PAGE2_IGNORESDPVERSION) ||
-	    (p->sessionversion_remote < 0) ||
-	    (p->sessionversion_remote < rua_version)) {
-		p->sessionversion_remote = rua_version;
-	} else {
-		if (p->t38.state == T38_LOCAL_REINVITE) {
-			p->sessionversion_remote = rua_version;
-			ast_log(LOG_WARNING, "Call %s responded to our T.38 reinvite without changing SDP version; 'ignoresdpversion' should be set for this peer.\n", p->callid);
-		} else {
-			p->session_modify = FALSE;
-			ast_debug(2, "Call %s responded to our reinvite without changing SDP version; ignoring SDP.\n", p->callid);
-			return FALSE;
-		}
-	}
-
-	return TRUE;
-}
-
-static int process_sdp_c(const char *c, struct ast_hostent *ast_hp)
-{
-	char host[258];
-	struct hostent *hp;
-
-	/* Check for Media-description-level-address */
-	if (sscanf(c, "IN IP4 %255s", host) != 1) {
-		ast_log(LOG_WARNING, "Invalid host in c= line, '%s'\n", c);
-		return FALSE;
-	} else {
-		if (!(hp = ast_gethostbyname(host, ast_hp))) {
-			ast_log(LOG_WARNING, "Unable to lookup RTP Audio host in c= line, '%s'\n", c);
-			return FALSE;
-		}
-		return TRUE;
-	}
-	return FALSE;
-}
-
-static int process_sdp_a_sendonly(const char *a, int *sendonly)
-{
-	int found = FALSE;
-
-	if (!strcasecmp(a, "sendonly")) {
-		if (*sendonly == -1)
-			*sendonly = 1;
-		found = TRUE;
-	} else if (!strcasecmp(a, "inactive")) {
-		if (*sendonly == -1)
-			*sendonly = 2;
-		found = TRUE;
-	}  else if (!strcasecmp(a, "sendrecv")) {
-		if (*sendonly == -1)
-			*sendonly = 0;
-		found = TRUE;
-	}
-	return found;
-}
-
-static int process_sdp_a_audio(const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newaudiortp, int *last_rtpmap_codec)
-{
-	int found = FALSE;
-	int codec;
-	char mimeSubtype[128];
-	char fmtp_string[64];
-	unsigned int sample_rate;
-	int debug = sip_debug_test_pvt(p);
-
-	if (!strncasecmp(a, "ptime", 5)) {
-		char *tmp = strrchr(a, ':');
-		long int framing = 0;
-		if (tmp) {
-			tmp++;
-			framing = strtol(tmp, NULL, 10);
-			if (framing == LONG_MIN || framing == LONG_MAX) {
-				framing = 0;
-				ast_debug(1, "Can't read framing from SDP: %s\n", a);
-			}
-		}
-		if (framing && p->autoframing) {
-			struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref;
-			int codec_n;
-			for (codec_n = 0; codec_n < AST_RTP_MAX_PT; codec_n++) {
-				struct ast_rtp_payload_type format = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(p->rtp), codec_n);
-				if (!format.asterisk_format || !format.code)	/* non-codec or not found */
-					continue;
-				if (option_debug)
-					ast_log(LOG_DEBUG, "Setting framing for %s to %ld\n", ast_getformatname(format.code), framing);
-				ast_codec_pref_setsize(pref, format.code, framing);
-			}
-			ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, pref);
-		}
-		found = TRUE;
-	} else if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) {
-		/* We have a rtpmap to handle */
-		if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
-			if (ast_rtp_codecs_payloads_set_rtpmap_type_rate(newaudiortp, NULL, codec, "audio", mimeSubtype,
-			    ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0, sample_rate) != -1) {
-				if (debug)
-					ast_verbose("Found audio description format %s for ID %d\n", mimeSubtype, codec);
-				//found_rtpmap_codecs[last_rtpmap_codec] = codec;
-				(*last_rtpmap_codec)++;
-				found = TRUE;
-			} else {
-				ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec);
-				if (debug)
-					ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec);
-			}
-		} else {
-			if (debug)
-				ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec);
-		}
-	} else if (sscanf(a, "fmtp: %30u %63s", &codec, fmtp_string) == 2) {
-		struct ast_rtp_payload_type payload;
-
-		payload = ast_rtp_codecs_payload_lookup(newaudiortp, codec);
-		if (payload.code && payload.asterisk_format) {
-			unsigned int bit_rate;
-
-			switch (payload.code) {
-			case AST_FORMAT_SIREN7:
-				if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) {
-					if (bit_rate != 32000) {
-						ast_log(LOG_WARNING, "Got Siren7 offer at %d bps, but only 32000 bps supported; ignoring.\n", bit_rate);
-						ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec);
-					} else {
-						found = TRUE;
-					}
-				}
-				break;
-			case AST_FORMAT_SIREN14:
-				if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) {
-					if (bit_rate != 48000) {
-						ast_log(LOG_WARNING, "Got Siren14 offer at %d bps, but only 48000 bps supported; ignoring.\n", bit_rate);
-						ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec);
-					} else {
-						found = TRUE;
-					}
-				}
-				break;
-			case AST_FORMAT_G719:
-				if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) {
-					if (bit_rate != 64000) {
-						ast_log(LOG_WARNING, "Got G.719 offer at %d bps, but only 64000 bps supported; ignoring.\n", bit_rate);
-						ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec);
-					} else {
-						found = TRUE;
-					}
-				}
-			}
-		}
-	}
-
-	return found;
-}
-
-static int process_sdp_a_video(const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newvideortp, int *last_rtpmap_codec)
-{
-	int found = FALSE;
-	int codec;
-	char mimeSubtype[128];
-	unsigned int sample_rate;
-	int debug = sip_debug_test_pvt(p);
-
-	if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) {
-		/* We have a rtpmap to handle */
-		if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
-			/* Note: should really look at the '#chans' params too */
-			if (!strncasecmp(mimeSubtype, "H26", 3) || !strncasecmp(mimeSubtype, "MP4", 3)) {
-				if (ast_rtp_codecs_payloads_set_rtpmap_type_rate(newvideortp, NULL, codec, "video", mimeSubtype, 0, sample_rate) != -1) {
-					if (debug)
-						ast_verbose("Found video description format %s for ID %d\n", mimeSubtype, codec);
-					//found_rtpmap_codecs[last_rtpmap_codec] = codec;
-					(*last_rtpmap_codec)++;
-					found = TRUE;
-				} else {
-					ast_rtp_codecs_payloads_unset(newvideortp, NULL, codec);
-					if (debug)
-						ast_verbose("Found unknown media description format %s for ID %d\n", mimeSubtype, codec);
-				}
-			}
-		} else {
-			if (debug)
-				ast_verbose("Discarded description format %s for ID %d\n", mimeSubtype, codec);
-		}
-	}
-
-	return found;
-}
-
-static int process_sdp_a_text(const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newtextrtp, char *red_fmtp, int *red_num_gen, int *red_data_pt, int *last_rtpmap_codec)
-{
-	int found = FALSE;
-	int codec;
-	char mimeSubtype[128];
-	unsigned int sample_rate;
-	char *red_cp;
-	int debug = sip_debug_test_pvt(p);
-
-	if (sscanf(a, "rtpmap: %30u %127[^/]/%30u", &codec, mimeSubtype, &sample_rate) == 3) {
-		/* We have a rtpmap to handle */
-		if (*last_rtpmap_codec < SDP_MAX_RTPMAP_CODECS) {
-			if (!strncasecmp(mimeSubtype, "T140", 4)) { /* Text */
-				if (p->trtp) {
-					/* ast_verbose("Adding t140 mimeSubtype to textrtp struct\n"); */
-					ast_rtp_codecs_payloads_set_rtpmap_type_rate(newtextrtp, NULL, codec, "text", mimeSubtype, 0, sample_rate);
-					found = TRUE;
-				}
-			} else if (!strncasecmp(mimeSubtype, "RED", 3)) { /* Text with Redudancy */
-				if (p->trtp) {
-					ast_rtp_codecs_payloads_set_rtpmap_type_rate(newtextrtp, NULL, codec, "text", mimeSubtype, 0, sample_rate);
-					sprintf(red_fmtp, "fmtp:%d ", codec);
-					if (debug)
-						ast_verbose("RED submimetype has payload type: %d\n", codec);
-					found = TRUE;
-				}
-			}
-		} else {
-			if (debug)

[... 124 lines stripped ...]



More information about the svn-commits mailing list