[asterisk-commits] dvossel: branch dvossel/fixtheworld_phase1_step3 r301726 - in /team/dvossel/f...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jan 12 17:21:53 CST 2011


Author: dvossel
Date: Wed Jan 12 17:21:48 2011
New Revision: 301726

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=301726
Log:
conversion of chan_sip to ast_format api

Modified:
    team/dvossel/fixtheworld_phase1_step3/channels/chan_local.c
    team/dvossel/fixtheworld_phase1_step3/channels/chan_sip.c
    team/dvossel/fixtheworld_phase1_step3/channels/sip/include/globals.h
    team/dvossel/fixtheworld_phase1_step3/channels/sip/include/sip.h
    team/dvossel/fixtheworld_phase1_step3/include/asterisk/format_cap.h
    team/dvossel/fixtheworld_phase1_step3/main/format_cap.c
    team/dvossel/fixtheworld_phase1_step3/main/rtp_engine.c

Modified: team/dvossel/fixtheworld_phase1_step3/channels/chan_local.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/channels/chan_local.c?view=diff&rev=301726&r1=301725&r2=301726
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/channels/chan_local.c (original)
+++ team/dvossel/fixtheworld_phase1_step3/channels/chan_local.c Wed Jan 12 17:21:48 2011
@@ -106,7 +106,7 @@
 static int local_setoption(struct ast_channel *chan, int option, void *data, int datalen);
 
 /* PBX interface structure for channel registration */
-static const struct ast_channel_tech local_tech = {
+static struct ast_channel_tech local_tech = {
 	.type = "Local",
 	.description = tdesc,
 	.requester = local_request,
@@ -1198,14 +1198,13 @@
 /*! \brief Load module into PBX, register channel */
 static int load_module(void)
 {
-	struct ast_channel_tech *tmp = (struct ast_channel_tech *) &local_tech;
-	if (!(tmp->capabilities = ast_cap_alloc())) {
+	if (!(local_tech.capabilities = ast_cap_alloc())) {
 		return AST_MODULE_LOAD_FAILURE;
 	}
-	ast_cap_add_all(tmp->capabilities);
+	ast_cap_add_all(local_tech.capabilities);
 
 	if (!(locals = ao2_container_alloc(BUCKET_SIZE, NULL, locals_cmp_cb))) {
-		ast_cap_destroy(tmp->capabilities);
+		ast_cap_destroy(local_tech.capabilities);
 		return AST_MODULE_LOAD_FAILURE;
 	}
 
@@ -1213,7 +1212,7 @@
 	if (ast_channel_register(&local_tech)) {
 		ast_log(LOG_ERROR, "Unable to register channel class 'Local'\n");
 		ao2_ref(locals, -1);
-		ast_cap_destroy(tmp->capabilities);
+		ast_cap_destroy(local_tech.capabilities);
 		return AST_MODULE_LOAD_FAILURE;
 	}
 	ast_cli_register_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));

Modified: team/dvossel/fixtheworld_phase1_step3/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/dvossel/fixtheworld_phase1_step3/channels/chan_sip.c?view=diff&rev=301726&r1=301725&r2=301726
==============================================================================
--- team/dvossel/fixtheworld_phase1_step3/channels/chan_sip.c (original)
+++ team/dvossel/fixtheworld_phase1_step3/channels/chan_sip.c Wed Jan 12 17:21:48 2011
@@ -1199,7 +1199,7 @@
 	in coming releases. */
 
 /*--- PBX interface functions */
-static struct ast_channel *sip_request_call(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
+static struct ast_channel *sip_request_call(const char *type, struct ast_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
 static int sip_devicestate(void *data);
 static int sip_sendtext(struct ast_channel *ast, const char *text);
 static int sip_call(struct ast_channel *ast, char *dest, int timeout);
@@ -1291,7 +1291,7 @@
 static int process_sdp_a_video(const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newvideortp, int *last_rtpmap_codec);
 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);
 static int process_sdp_a_image(const char *a, struct sip_pvt *p);
-static void add_codec_to_sdp(const struct sip_pvt *p, format_t codec,
+static void add_codec_to_sdp(const struct sip_pvt *p, struct ast_format *codec,
 			     struct ast_str **m_buf, struct ast_str **a_buf,
 			     int debug, int *min_packet_size);
 static void add_noncodec_to_sdp(const struct sip_pvt *p, int format,
@@ -1565,7 +1565,7 @@
 static struct sip_st_dlg* sip_st_alloc(struct sip_pvt *const p);
 
 /*------- RTP Glue functions -------- */
-static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, format_t codecs, int nat_active);
+static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, const struct ast_cap *cap, int nat_active);
 
 /*!--- SIP MWI Subscription support */
 static int sip_subscribe_mwi(const char *value, int lineno);
@@ -1575,10 +1575,9 @@
 static int __sip_subscribe_mwi_do(struct sip_subscription_mwi *mwi);
 
 /*! \brief Definition of this channel for PBX channel registration */
-const struct ast_channel_tech sip_tech = {
+struct ast_channel_tech sip_tech = {
 	.type = "SIP",
 	.description = "Session Initiation Protocol (SIP)",
-	.capabilities = AST_FORMAT_AUDIO_MASK,	/* all audio formats */
 	.properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
 	.requester = sip_request_call,			/* called with chan unlocked */
 	.devicestate = sip_devicestate,			/* called with chan unlocked (not chan-specific) */
@@ -4037,10 +4036,10 @@
 
 	switch (option) {
 	case AST_OPTION_FORMAT_READ:
-		res = ast_rtp_instance_set_read_format(p->rtp, *(int *) data);
+		res = ast_rtp_instance_set_read_format(p->rtp, (struct ast_format *) data);
 		break;
 	case AST_OPTION_FORMAT_WRITE:
-		res = ast_rtp_instance_set_write_format(p->rtp, *(int *) data);
+		res = ast_rtp_instance_set_write_format(p->rtp, (struct ast_format *) data);
 		break;
 	case AST_OPTION_MAKE_COMPATIBLE:
 		res = ast_rtp_instance_make_compatible(chan, p->rtp, (struct ast_channel *) data);
@@ -4384,6 +4383,9 @@
 	ast_cc_config_params_destroy(peer->cc_params);
 
 	ast_string_field_free_memory(peer);
+
+	peer->caps = ast_cap_destroy(peer->caps);
+	sip_cfg.caps = ast_cap_destroy(sip_cfg.caps);
 }
 
 /*! \brief Update peer data in database (if used) */
@@ -4825,7 +4827,7 @@
 	}
 
 	if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS) ||
-			(ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) && (dialog->capability & AST_FORMAT_VIDEO_MASK))) {
+			(ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) && (ast_cap_has_type(dialog->caps, AST_FORMAT_TYPE_VIDEO)))) {
 		if (!(dialog->vrtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
 			return -1;
 		}
@@ -4886,7 +4888,7 @@
 	ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
 	ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
 	ast_copy_flags(&dialog->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY);
-	dialog->capability = peer->capability;
+	ast_cap_append(peer->caps, dialog->caps);
 	dialog->prefs = peer->prefs;
 	if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) {
 		/* t38pt_udptl was enabled in the peer and not in [general] */
@@ -5252,11 +5254,11 @@
 		return res;
 	}
 	p->callingpres = ast_party_id_presentation(&ast->caller.id);
-	p->jointcapability = ast_rtp_instance_available_formats(p->rtp, p->capability, p->prefcodec);
+	ast_rtp_instance_available_formats(p->rtp, p->caps, p->prefcaps, p->jointcaps);
 	p->jointnoncodeccapability = p->noncodeccapability;
 
 	/* If there are no audio formats left to offer, punt */
-	if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
+	if (!(ast_cap_has_type(p->jointcaps, AST_FORMAT_TYPE_AUDIO))) {
 		ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username);
 		res = -1;
 	} else {
@@ -5462,6 +5464,10 @@
 		ao2_ref(p->socket.tcptls_session, -1);
 		p->socket.tcptls_session = NULL;
 	}
+	p->caps = ast_cap_destroy(p->caps);
+	p->jointcaps = ast_cap_destroy(p->jointcaps);
+	p->peercaps = ast_cap_destroy(p->peercaps);
+	p->redircaps = ast_cap_destroy(p->redircaps);
 }
 
 /*! \brief  update_call_counter: Handle call_limit for SIP devices
@@ -6024,7 +6030,9 @@
 /*! \brief Try setting codec suggested by the SIP_CODEC channel variable */
 static void try_suggested_sip_codec(struct sip_pvt *p)
 {
-	format_t fmt;
+	struct ast_format fmt = {
+		.id = 0,
+	};
 	const char *codec;
 
 	if (p->outgoing_call) {
@@ -6036,12 +6044,14 @@
 	if (!codec) 
 		return;
 
-	fmt = ast_getformatbyname(codec);
-	if (fmt) {
+	ast_getformatbyname(codec, &fmt);
+	if (fmt.id) {
 		ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec);
-		if (p->jointcapability & fmt) {
-			p->jointcapability &= fmt;
-			p->capability &= fmt;
+		if (ast_cap_iscompatible(p->jointcaps, &fmt)) {
+			ast_cap_remove_all(p->jointcaps);
+			ast_cap_add(p->jointcaps, &fmt);
+			ast_cap_remove_all(p->caps);
+			ast_cap_add(p->caps, &fmt);
 		} else
 			ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n");
 	} else
@@ -6078,13 +6088,13 @@
 
 	switch (frame->frametype) {
 	case AST_FRAME_VOICE:
-		if (!(frame->subclass.codec & ast->nativeformats)) {
-			char s1[512], s2[512], s3[512];
+		if (!(ast_cap_iscompatible(ast->nativeformats, &frame->subclass.format))) {
+			char s1[512];
 			ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s read/write = %s/%s\n",
-				ast_getformatname(frame->subclass.codec),
-				ast_getformatname_multiple(s1, sizeof(s1), ast->nativeformats & AST_FORMAT_AUDIO_MASK),
-				ast_getformatname_multiple(s2, sizeof(s2), ast->readformat),
-				ast_getformatname_multiple(s3, sizeof(s3), ast->writeformat));
+				ast_getformatname(&frame->subclass.format),
+				ast_getformatname_multiple(s1, sizeof(s1), ast->nativeformats),
+				ast_getformatname(&ast->readformat),
+				ast_getformatname(&ast->writeformat));
 			return 0;
 		}
 		if (p) {
@@ -6537,15 +6547,18 @@
 {
 	struct ast_channel *tmp;
 	struct ast_variable *v = NULL;
-	format_t fmt;
-	format_t what;
-	format_t video;
-	format_t text;
-	format_t needvideo = 0;
+	struct ast_format fmt;
+	struct ast_cap *what = ast_cap_alloc();
+	struct ast_cap *video = NULL;
+	struct ast_cap *text = NULL;
+	int needvideo = 0;
 	int needtext = 0;
 	char buf[SIPBUFSIZE];
 	char *decoded_exten;
 
+	if (!what) {
+		return NULL;
+	}
 	{
 		const char *my_name;	/* pick a good name */
 	
@@ -6562,6 +6575,7 @@
 	if (!tmp) {
 		ast_log(LOG_WARNING, "Unable to allocate AST channel structure for SIP channel\n");
 		sip_pvt_lock(i);
+		ast_cap_destroy(what);
 		return NULL;
 	}
 	ast_channel_lock(tmp);
@@ -6574,32 +6588,35 @@
 
 	/* Select our native format based on codec preference until we receive
 	   something from another device to the contrary. */
-	if (i->jointcapability) { 	/* The joint capabilities of us and peer */
-		what = i->jointcapability;
-		video = i->jointcapability & AST_FORMAT_VIDEO_MASK;
-		text = i->jointcapability & AST_FORMAT_TEXT_MASK;
-	} else if (i->capability) {		/* Our configured capability for this peer */
-		what = i->capability;
-		video = i->capability & AST_FORMAT_VIDEO_MASK;
-		text = i->capability & AST_FORMAT_TEXT_MASK;
+	if (!(ast_cap_is_empty(i->jointcaps))) {	/* The joint capabilities of us and peer */
+		ast_cap_append(i->jointcaps, what);
+		video = ast_cap_get_type(i->jointcaps, AST_FORMAT_TYPE_VIDEO);
+		text = ast_cap_get_type(i->jointcaps, AST_FORMAT_TYPE_TEXT);
+	} else if (!(ast_cap_is_empty(i->caps))) {		/* Our configured capability for this peer */
+		ast_cap_append(i->caps, what);
+		video = ast_cap_get_type(i->caps, AST_FORMAT_TYPE_VIDEO);
+		text = ast_cap_get_type(i->caps, AST_FORMAT_TYPE_TEXT);
 	} else {
-		what = sip_cfg.capability;	/* Global codec support */
-		video = sip_cfg.capability & AST_FORMAT_VIDEO_MASK;
-		text = sip_cfg.capability & AST_FORMAT_TEXT_MASK;
+		ast_cap_append(sip_cfg.caps, what);	/* Global codec support */
+		video = ast_cap_get_type(sip_cfg.caps, AST_FORMAT_TYPE_VIDEO);
+		text = ast_cap_get_type(sip_cfg.caps, AST_FORMAT_TYPE_TEXT);
 	}
 
 	/* Set the native formats for audio  and merge in video */
-	tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video | text;
+	ast_codec_choose(&i->prefs, what, 1, &fmt);
+	ast_cap_append(video, tmp->nativeformats);
+	ast_cap_append(text, tmp->nativeformats);
+	ast_cap_add(tmp->nativeformats, &fmt);
 	ast_debug(3, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats));
-	ast_debug(3, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability));
-	ast_debug(3, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability));
-	ast_debug(3, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1)));
-	if (i->prefcodec) {
-		ast_debug(3, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec));
+	ast_debug(3, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcaps));
+	ast_debug(3, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->caps));
+	ast_debug(3, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname(&fmt));
+	if (!ast_cap_is_empty(i->prefcaps)) {
+		ast_debug(3, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcaps));
 	}
 
 	/* XXX Why are we choosing a codec from the native formats?? */
-	fmt = ast_best_codec(tmp->nativeformats);
+	ast_best_codec(tmp->nativeformats, &fmt);
 
 	/* If we have a prefcodec setting, we have an inbound channel that set a
 	   preferred format for this call. Otherwise, we check the jointcapability
@@ -6607,18 +6624,18 @@
 	 */
 	if (i->vrtp) {
 		if (ast_test_flag(&i->flags[1], SIP_PAGE2_VIDEOSUPPORT))
-			needvideo = AST_FORMAT_VIDEO_MASK;
-		else if (i->prefcodec)
-			needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK;	/* Outbound call */
+			needvideo = 1;
+		else if (!ast_cap_is_empty(i->prefcaps))
+			needvideo = ast_cap_has_type(i->prefcaps, AST_FORMAT_TYPE_VIDEO);	/* Outbound call */
  		else
-			needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK;	/* Inbound call */
+			needvideo = ast_cap_has_type(i->jointcaps, AST_FORMAT_TYPE_VIDEO);	/* Inbound call */
 	}
 
 	if (i->trtp) {
-		if (i->prefcodec)
-			needtext = i->prefcodec & AST_FORMAT_TEXT_MASK;	/* Outbound call */
+		if (!ast_cap_is_empty(i->prefcaps))
+			needtext = ast_cap_has_type(i->prefcaps, AST_FORMAT_TYPE_TEXT);	/* Outbound call */
  		else
-			needtext = i->jointcapability & AST_FORMAT_TEXT_MASK;	/* Inbound call */
+			needtext = ast_cap_has_type(i->jointcaps, AST_FORMAT_TYPE_TEXT);	/* Inbound call */
 	}
 
 	if (needvideo) {
@@ -6661,13 +6678,13 @@
 	}
 	tmp->adsicpe = AST_ADSI_UNAVAILABLE;
 
-	tmp->writeformat = fmt;
-	tmp->rawwriteformat = fmt;
-	ast_rtp_instance_set_write_format(i->rtp, fmt);
-
-	tmp->readformat = fmt;
-	tmp->rawreadformat = fmt;
-	ast_rtp_instance_set_read_format(i->rtp, fmt);
+	ast_format_copy(&fmt, &tmp->writeformat);
+	ast_format_copy(&fmt, &tmp->rawwriteformat);
+	ast_rtp_instance_set_write_format(i->rtp, &fmt);
+
+	ast_format_copy(&fmt, &tmp->readformat);
+	ast_format_copy(&fmt, &tmp->rawreadformat);
+	ast_rtp_instance_set_read_format(i->rtp, &fmt);
 
 	tmp->tech_pvt = dialog_ref(i, "sip_new: set chan->tech_pvt to i");
 
@@ -6755,6 +6772,10 @@
 			"Channel: %s\r\nUniqueid: %s\r\nChanneltype: %s\r\nSIPcallid: %s\r\nSIPfullcontact: %s\r\n",
 			tmp->name, tmp->uniqueid, "SIP", i->callid, i->fullcontact);
 	}
+
+	ast_cap_destroy(what);
+	ast_cap_destroy(video);
+	ast_cap_destroy(text);
 
 	return tmp;
 }
@@ -6975,17 +6996,18 @@
 		return f;
 	}
 
-	if (f && f->subclass.codec != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
-		if (!(f->subclass.codec & p->jointcapability)) {
+	if (f && !ast_cap_iscompatible(p->owner->nativeformats, &f->subclass.format)) {
+		if (!ast_cap_iscompatible(p->jointcaps, &f->subclass.format)) {
 			ast_debug(1, "Bogus frame of format '%s' received from '%s'!\n",
-				ast_getformatname(f->subclass.codec), p->owner->name);
+				ast_getformatname(&f->subclass.format), p->owner->name);
 			return &ast_null_frame;
 		}
 		ast_debug(1, "Oooh, format changed to %s\n",
-			ast_getformatname(f->subclass.codec));
-		p->owner->nativeformats = (p->owner->nativeformats & (AST_FORMAT_VIDEO_MASK | AST_FORMAT_TEXT_MASK)) | f->subclass.codec;
-		ast_set_read_format(p->owner, p->owner->readformat);
-		ast_set_write_format(p->owner, p->owner->writeformat);
+			ast_getformatname(&f->subclass.format));
+		ast_cap_remove_bytype(p->owner->nativeformats, AST_FORMAT_TYPE_AUDIO);
+		ast_cap_add(p->owner->nativeformats, &f->subclass.format);
+		ast_set_read_format(p->owner, &p->owner->readformat);
+		ast_set_write_format(p->owner, &p->owner->writeformat);
 	}
 
 	if (f && p->dsp) {
@@ -7148,6 +7170,20 @@
 		ao2_t_ref(p, -1, "Yuck, couldn't allocate cc_params struct. Get rid o' p");
 		return NULL;
 	}
+	p->caps = ast_cap_alloc();
+	p->jointcaps = ast_cap_alloc();
+	p->peercaps = ast_cap_alloc();
+	p->redircaps = ast_cap_alloc();
+
+	if (!p->caps|| !p->jointcaps || !p->peercaps || !p->redircaps) {
+		p->caps = ast_cap_destroy(p->caps);
+		p->jointcaps = ast_cap_destroy(p->jointcaps);
+		p->peercaps = ast_cap_destroy(p->peercaps);
+		p->redircaps = ast_cap_destroy(p->redircaps);
+		ao2_t_ref(p, -1, "Yuck, couldn't allocate cc_params struct. Get rid o' p");
+		return NULL;
+	}
+
 
 	/* If this dialog is created as a result of a request or response, lets store
 	 * some information about it in the dialog. */
@@ -7251,7 +7287,7 @@
 	/* Assign default music on hold class */
 	ast_string_field_set(p, mohinterpret, default_mohinterpret);
 	ast_string_field_set(p, mohsuggest, default_mohsuggest);
-	p->capability = sip_cfg.capability;
+	ast_cap_append(sip_cfg.caps, p->caps);
 	p->allowtransfer = sip_cfg.allowtransfer;
 	if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
 	    (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
@@ -8216,6 +8252,8 @@
 */
 static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action)
 {
+	int res = 0;
+
 	/* Iterators for SDP parsing */
 	int start = req->sdp_start;
 	int next = start;
@@ -8238,18 +8276,21 @@
 	struct ast_sockaddr *vsa = NULL;	/*!< RTP video host IP */
 	struct ast_sockaddr *tsa = NULL;	/*!< RTP text host IP */
 	struct ast_sockaddr *isa = NULL;     /*!< UDPTL host ip */
- 	int portno = -1;		/*!< RTP Audio port number */
- 	int vportno = -1;		/*!< RTP Video port number */
+	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 */
 
 	/* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */	
-	format_t peercapability = 0, vpeercapability = 0, tpeercapability = 0;
+	struct ast_cap *peercapability = ast_cap_alloc();
+	struct ast_cap *vpeercapability = ast_cap_alloc();
+	struct ast_cap *tpeercapability = ast_cap_alloc();
+
 	int peernoncodeccapability = 0, vpeernoncodeccapability = 0, tpeernoncodeccapability = 0;
 
 	struct ast_rtp_codecs newaudiortp, newvideortp, newtextrtp;
-	format_t newjointcapability;				/* Negotiated capability */
-	format_t newpeercapability;
+	struct ast_cap *newjointcapability = ast_cap_alloc(); /* Negotiated capability */
+	struct ast_cap *newpeercapability = ast_cap_alloc();
 	int newnoncodeccapability;
 
 	const char *codecs;
@@ -8272,12 +8313,18 @@
 
 	/* START UNKNOWN */
 	char buf[SIPBUFSIZE];
+	struct ast_format tmp_fmt;
 	/* END UNKNOWN */
 
 	/* Initial check */
 	if (!p->rtp) {
 		ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n");
-		return -1;
+		res = -1;
+		goto process_sdp_cleanup;
+	}
+	if (!peercapability || !vpeercapability || !tpeercapability || !newpeercapability || !newjointcapability) {
+		res = -1;
+		goto process_sdp_cleanup;
 	}
 
 	/* Make sure that the codec structures are all cleared out */
@@ -8307,7 +8354,8 @@
 	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;
+		res = -1;
+		goto process_sdp_cleanup;
  	}
 
 	/* Scan session level SDP parameters (lines before first media stream) */
@@ -8319,7 +8367,8 @@
 			 * 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;
+				res = (p->session_modify == FALSE) ? 0 : -1;
+				goto process_sdp_cleanup;
 			break;
 		case 'c':
 			if (process_sdp_c(value, &sessionsa)) {
@@ -8387,7 +8436,8 @@
 			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;
+					res = -1;
+					goto process_sdp_cleanup;
 				}
 				if (debug)
 					ast_verbose("Found RTP audio format %d\n", codec);
@@ -8415,7 +8465,8 @@
 			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;
+					res = -1;
+					goto process_sdp_cleanup;
 				}
 				if (debug)
 					ast_verbose("Found RTP video format %d\n", codec);
@@ -8436,7 +8487,8 @@
 			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;
+					res = -1;
+					goto process_sdp_cleanup;
 				}
 				if (debug)
 					ast_verbose("Found RTP text format %d\n", codec);
@@ -8541,45 +8593,53 @@
 	/* Sanity checks */
 	if (!sa && !vsa && !tsa && !isa) {
 		ast_log(LOG_WARNING, "Insufficient information in SDP (c=)...\n");
-		return -1;
+		res = -1;
+		goto process_sdp_cleanup;
 	}
 
 	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;
+		res = -2;
+		goto process_sdp_cleanup;
 	}
 
 	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;
+		res = -3;
+		goto process_sdp_cleanup;
 	}
 
 	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;
+		res = -4;
+		goto process_sdp_cleanup;
 	}
 
 	if (!secure_audio && p->srtp) {
 		ast_log(LOG_WARNING, "We are requesting SRTP, but they responded without it!\n");
-		return -4;
+		res = -4;
+		goto process_sdp_cleanup;
 	}
 
 	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;
+		res = -4;
+		goto process_sdp_cleanup;
 	}
 
 	if (!p->novideo && !secure_video && p->vsrtp) {
 		ast_log(LOG_WARNING, "We are requesting SRTP, but they responded without it!\n");
-		return -4;
+		res = -4;
+		goto process_sdp_cleanup;
 	}
 
 	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;
+		res = -4;
+		goto process_sdp_cleanup;
 	}
 
 	if (udptlportno == -1) {
@@ -8587,12 +8647,22 @@
 	}
 
 	/* 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);
+	ast_rtp_codecs_payload_formats(&newaudiortp, peercapability, &peernoncodeccapability);
+	ast_rtp_codecs_payload_formats(&newvideortp, vpeercapability, &vpeernoncodeccapability);
+	ast_rtp_codecs_payload_formats(&newtextrtp, tpeercapability, &tpeernoncodeccapability);
+
+	ast_cap_append(newpeercapability, peercapability);
+	ast_cap_append(newpeercapability, vpeercapability);
+	ast_cap_append(newpeercapability, tpeercapability);
+
+	ast_cap_joint_copy(p->caps, newpeercapability, newjointcapability);
+	if (ast_cap_is_empty(newjointcapability) && (portno != -1)) {
+		ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n");
+		/* Do NOT Change current setting */
+		res = -1;
+		goto process_sdp_cleanup;
+	}
+
 	newnoncodeccapability = p->noncodeccapability & peernoncodeccapability;
 
 	if (debug) {
@@ -8600,7 +8670,7 @@
 		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(s1, SIPBUFSIZE, p->caps),
 			    ast_getformatname_multiple(s2, SIPBUFSIZE, peercapability),
 			    ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability),
 			    ast_getformatname_multiple(s4, SIPBUFSIZE, tpeercapability),
@@ -8612,14 +8682,9 @@
 		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;
+			    ast_rtp_lookup_mime_multiple2(s1, NULL, p->noncodeccapability, 0, 0),
+			    ast_rtp_lookup_mime_multiple2(s2, NULL, peernoncodeccapability, 0, 0),
+			    ast_rtp_lookup_mime_multiple2(s3, NULL, newnoncodeccapability, 0, 0));
 	}
 
 	/* Setup audio address and port */
@@ -8633,12 +8698,18 @@
 			}
 			/* 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 */
+			ast_cap_remove_all(p->jointcaps);
+			ast_cap_append(newjointcapability, p->jointcaps);                /* Our joint codec profile for this call */
+
+			ast_cap_remove_all(p->peercaps);
+			ast_cap_append(newpeercapability, p->peercaps);                  /* 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_codec_choose(&p->prefs, p->jointcaps, 1, &tmp_fmt);
+				ast_cap_remove_all(p->jointcaps);
+				ast_cap_add(p->jointcaps, &tmp_fmt);
 			}
 
 			ast_rtp_codecs_payloads_copy(&newaudiortp, ast_rtp_instance_get_codecs(p->rtp), p->rtp);
@@ -8691,7 +8762,7 @@
 				ast_verbose("Peer T.140 RTP is at port %s\n",
 					    ast_sockaddr_stringify(tsa));
 			}
-			if ((p->jointcapability & AST_FORMAT_T140RED)) {
+			if (ast_cap_iscompatible(p->jointcaps, ast_format_set(&tmp_fmt, AST_FORMAT_T140RED, 0))) {
 				p->red = 1;
 				ast_rtp_red_init(p->trtp, 300, red_data_pt, 2);
 			} else {
@@ -8761,27 +8832,37 @@
 
 	if ((portno == -1) && (p->t38.state != T38_DISABLED)) {
 		ast_debug(3, "Have T.38 but no audio, accepting offer anyway\n");
-		return 0;
-        }
+		res = 0;
+		goto process_sdp_cleanup;
+	}
 
 	/* 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(2, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcaps));
+
+	if (!p->owner) { /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */
+		res = 0;
+		goto process_sdp_cleanup;
+	}
 
 	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 (!(ast_cap_has_joint(p->owner->nativeformats, p->jointcaps)) && ast_cap_has_type(p->jointcaps, AST_FORMAT_TYPE_AUDIO)) {
 		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(s1, SIPBUFSIZE, p->jointcaps),
 				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);
+
+		ast_codec_choose(&p->prefs, p->jointcaps, 1, &tmp_fmt);
+		ast_cap_remove_all(p->owner->nativeformats);
+
+		ast_cap_add(p->owner->nativeformats, &tmp_fmt);
+		ast_cap_joint_copy(p->caps, vpeercapability, p->owner->nativeformats);
+		ast_cap_joint_copy(p->caps, tpeercapability, p->owner->nativeformats);
+
+		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) && (!ast_sockaddr_isnull(sa) || !ast_sockaddr_isnull(vsa) || !ast_sockaddr_isnull(tsa) || !ast_sockaddr_isnull(isa)) && (!sendonly || sendonly == -1)) {
@@ -8800,8 +8881,14 @@
 		ast_queue_frame(p->owner, &ast_null_frame);
 		change_hold_state(p, req, TRUE, sendonly);
 	}
-	
-	return 0;
+
+process_sdp_cleanup:
+	ast_cap_destroy(peercapability);
+	ast_cap_destroy(vpeercapability);
+	ast_cap_destroy(tpeercapability);
+	ast_cap_destroy(newjointcapability);
+	ast_cap_destroy(newpeercapability);
+	return res;
 }
 
 static int process_sdp_o(const char *o, struct sip_pvt *p)
@@ -8955,10 +9042,10 @@
 			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 */
+				if (!format.asterisk_format)	/* non-codec or not found */
 					continue;
-				ast_debug(1, "Setting framing for %s to %ld\n", ast_getformatname(format.code), framing);
-				ast_codec_pref_setsize(pref, format.code, framing);
+				ast_debug(1, "Setting framing for %s to %ld\n", ast_getformatname(&format.format), framing);
+				ast_codec_pref_setsize(pref, &format.format, framing);
 			}
 			ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, pref);
 		}
@@ -8986,10 +9073,10 @@
 		struct ast_rtp_payload_type payload;
 
 		payload = ast_rtp_codecs_payload_lookup(newaudiortp, codec);
-		if (payload.code && payload.asterisk_format) {
+		if (payload.format.id && payload.asterisk_format) {
 			unsigned int bit_rate;
 
-			switch (payload.code) {
+			switch ((int) payload.format.id) {
 			case AST_FORMAT_SIREN7:
 				if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) {
 					if (bit_rate != 32000) {
@@ -10318,31 +10405,34 @@
 }
 
 /*! \brief Add codec offer to SDP offer/answer body in INVITE or 200 OK */
-static void add_codec_to_sdp(const struct sip_pvt *p, format_t codec,
-			     struct ast_str **m_buf, struct ast_str **a_buf,
-			     int debug, int *min_packet_size)
+static void add_codec_to_sdp(const struct sip_pvt *p,
+	struct ast_format *format,
+	struct ast_str **m_buf,
+	struct ast_str **a_buf,
+	int debug,
+	int *min_packet_size)
 {
 	int rtp_code;
 	struct ast_format_list fmt;
 
 
 	if (debug)
-		ast_verbose("Adding codec 0x%" PRIx64 " (%s) to SDP\n", codec, ast_getformatname(codec));
-	if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 1, codec)) == -1)
+		ast_verbose("Adding codec %d (%s) to SDP\n", format->id, ast_getformatname(format));
+	if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 1, format, 0)) == -1)
 		return;
 
 	if (p->rtp) {
 		struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref;
-		fmt = ast_codec_pref_getsize(pref, codec);
+		fmt = ast_codec_pref_getsize(pref, format);
 	} else /* I don't see how you couldn't have p->rtp, but good to check for and error out if not there like earlier code */
 		return;
 	ast_str_append(m_buf, 0, " %d", rtp_code);
-	ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
-		       ast_rtp_lookup_mime_subtype2(1, codec,
-						   ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
-		       ast_rtp_lookup_sample_rate2(1, codec));
-
-	switch (codec) {
+	ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n",
+		rtp_code,
+		ast_rtp_lookup_mime_subtype2(1, format, 0, ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
+		ast_rtp_lookup_sample_rate2(1, format, 0));
+
+	switch ((int) format->id) {
 	case AST_FORMAT_G729A:
 		/* Indicate that we don't support VAD (G.729 annex B) */
 		ast_str_append(a_buf, 0, "a=fmtp:%d annexb=no\r\n", rtp_code);
@@ -10379,7 +10469,7 @@
 
 /*! \brief Add video codec offer to SDP offer/answer body in INVITE or 200 OK */
 /* This is different to the audio one now so we can add more caps later */
-static void add_vcodec_to_sdp(const struct sip_pvt *p, format_t codec,
+static void add_vcodec_to_sdp(const struct sip_pvt *p, struct ast_format *format,
 			     struct ast_str **m_buf, struct ast_str **a_buf,
 			     int debug, int *min_packet_size)
 {
@@ -10389,20 +10479,20 @@
 		return;
 
 	if (debug)
-		ast_verbose("Adding video codec 0x%" PRIx64 " (%s) to SDP\n", codec, ast_getformatname(codec));
-
-	if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->vrtp), 1, codec)) == -1)
+		ast_verbose("Adding video codec %d (%s) to SDP\n", format->id, ast_getformatname(format));
+
+	if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->vrtp), 1, format, 0)) == -1)
 		return;
 
 	ast_str_append(m_buf, 0, " %d", rtp_code);
 	ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
-		       ast_rtp_lookup_mime_subtype2(1, codec, 0),
-		       ast_rtp_lookup_sample_rate2(1, codec));
+		       ast_rtp_lookup_mime_subtype2(1, format, 0, 0),
+		       ast_rtp_lookup_sample_rate2(1, format, 0));
 	/* Add fmtp code here */
 }
 
 /*! \brief Add text codec offer to SDP offer/answer body in INVITE or 200 OK */
-static void add_tcodec_to_sdp(const struct sip_pvt *p, int codec,
+static void add_tcodec_to_sdp(const struct sip_pvt *p, struct ast_format *format,
 			     struct ast_str **m_buf, struct ast_str **a_buf,
 			     int debug, int *min_packet_size)
 {
@@ -10412,19 +10502,20 @@
 		return;
 
 	if (debug)
-		ast_verbose("Adding text codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
-
-	if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, codec)) == -1)
+		ast_verbose("Adding text codec %d (%s) to SDP\n", format->id, ast_getformatname(format));
+
+	if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, format, 0)) == -1)
 		return;
 
 	ast_str_append(m_buf, 0, " %d", rtp_code);
 	ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
-		       ast_rtp_lookup_mime_subtype2(1, codec, 0),
-		       ast_rtp_lookup_sample_rate2(1, codec));
+		       ast_rtp_lookup_mime_subtype2(1, format, 0, 0),
+		       ast_rtp_lookup_sample_rate2(1, format, 0));
 	/* Add fmtp code here */
 
-	if (codec == AST_FORMAT_T140RED) {
-		int t140code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, AST_FORMAT_T140);
+	if (format->id == AST_FORMAT_T140RED) {
+		struct ast_format tmp_fmt;
+		int t140code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, ast_format_set(&tmp_fmt, AST_FORMAT_T140, 0), 0);
 		ast_str_append(a_buf, 0, "a=fmtp:%d %d/%d/%d\r\n", rtp_code,
 			 t140code,
 			 t140code,
@@ -10463,14 +10554,14 @@
 	int rtp_code;
 
 	if (debug)
-		ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype2(0, format, 0));
-	if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 0, format)) == -1)
+		ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype2(0, NULL, format, 0));
+	if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 0, NULL, format)) == -1)
 		return;
 
 	ast_str_append(m_buf, 0, " %d", rtp_code);
 	ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
-		       ast_rtp_lookup_mime_subtype2(0, format, 0),
-		       ast_rtp_lookup_sample_rate2(0, format));
+		       ast_rtp_lookup_mime_subtype2(0, NULL, format, 0),
+		       ast_rtp_lookup_sample_rate2(0, NULL, format));
 	if (format == AST_RTP_DTMF)	/* Indicate we support DTMF and FLASH... */
 		ast_str_append(a_buf, 0, "a=fmtp:%d 0-16\r\n", rtp_code);
 }
@@ -10596,8 +10687,8 @@
 */
 static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int oldsdp, int add_audio, int add_t38)
 {
-	format_t alreadysent = 0;
-
+	struct ast_cap *alreadysent = ast_cap_alloc();
+	int res = AST_SUCCESS;
 	struct ast_sockaddr addr = { {0,} };
 	struct ast_sockaddr vaddr = { {0,} };
 	struct ast_sockaddr taddr = { {0,} };
@@ -10627,8 +10718,9 @@
 	const char *v_a_crypto = NULL;
 	const char *t_a_crypto = NULL;
 
-	format_t x;
-	format_t capability = 0;
+	int x;
+	struct ast_format tmp_fmt;
+	struct ast_cap *capability = NULL; /* this holds a shallow copy and should never be destroyed */
 	int needaudio = FALSE;
 	int needvideo = FALSE;
 	int needtext = FALSE;
@@ -10644,9 +10736,16 @@
 	/* Set the SDP session name */
 	snprintf(subject, sizeof(subject), "s=%s\r\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession);
 
+	if (!alreadysent) {
+		res = AST_FAILURE;
+		goto add_sdp_cleanup;
+	}
 	if (!p->rtp) {
+		ast_cap_destroy(alreadysent);
 		ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
-		return AST_FAILURE;
+		res = AST_FAILURE;
+		goto add_sdp_cleanup;
+
 	}
 	/* XXX We should not change properties in the SIP dialog until
 		we have acceptance of the offer if this is a re-invite */
@@ -10662,7 +10761,7 @@
 
 	if (add_audio) {
 		/* Check if we need video in this call */
-		if ((p->jointcapability & AST_FORMAT_VIDEO_MASK) && !p->novideo) {
+		if ((ast_cap_has_type(p->jointcaps, AST_FORMAT_TYPE_VIDEO)) && !p->novideo) {
 			if (p->vrtp) {
 				needvideo = TRUE;
 				ast_debug(2, "This call needs video offers!\n");
@@ -10670,7 +10769,7 @@
 				ast_debug(2, "This call needs video offers, but there's no video support enabled!\n");
 		}
 		/* Check if we need text in this call */
-		if ((p->jointcapability & AST_FORMAT_TEXT_MASK) && !p->notext) {

[... 770 lines stripped ...]



More information about the asterisk-commits mailing list