[asterisk-commits] kharwell: branch kharwell/pimp_sip_video r383402 - in /team/kharwell/pimp_sip...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Mar 19 18:17:12 CDT 2013


Author: kharwell
Date: Tue Mar 19 18:17:08 2013
New Revision: 383402

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383402
Log:
incremental update for video playback for chan_gulp\n\n video playback is still available.  added was filtering of available codec offerings.  some bugs still remain like why fmtp sometimes outputs empty lines

Modified:
    team/kharwell/pimp_sip_video/channels/chan_gulp.c
    team/kharwell/pimp_sip_video/include/asterisk/res_sip_session.h
    team/kharwell/pimp_sip_video/res/res_sip_sdp_video.c
    team/kharwell/pimp_sip_video/res/res_sip_session.c

Modified: team/kharwell/pimp_sip_video/channels/chan_gulp.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_video/channels/chan_gulp.c?view=diff&rev=383402&r1=383401&r2=383402
==============================================================================
--- team/kharwell/pimp_sip_video/channels/chan_gulp.c (original)
+++ team/kharwell/pimp_sip_video/channels/chan_gulp.c Tue Mar 19 18:17:08 2013
@@ -314,7 +314,7 @@
 	pvt->media[SIP_MEDIA_VIDEO] = ao2_find(session->media, "video", OBJ_KEY);
 	ast_channel_tech_pvt_set(chan, pvt);
 
-	ast_format_cap_copy(ast_channel_nativeformats(chan), session->endpoint->codecs);
+	ast_format_cap_copy(ast_channel_nativeformats(chan), session->caps); /* session->endpoint->codecs); */
 	ast_codec_choose(&session->endpoint->prefs, session->endpoint->codecs, 1, &fmt);
 
 	ast_format_copy(ast_channel_writeformat(chan), &fmt);
@@ -384,19 +384,15 @@
 
 	switch (fdno) {
 	case 0:
-		/* media = pvt->media[SIP_MEDIA_AUDIO]; */
 		f = ast_rtp_instance_read(media->rtp, 0);
 		break;
 	case 1:
-		/* media = pvt->media[SIP_MEDIA_AUDIO]; */
 		f = ast_rtp_instance_read(media->rtp, 1);
 		break;
 	case 2:
-		/* media = pvt->media[SIP_MEDIA_VIDEO]; */
 		f = ast_rtp_instance_read(media->rtp, 0);
 		break;
 	case 3:
-		/* media = pvt->media[SIP_MEDIA_VIDEO]; */
 		f = ast_rtp_instance_read(media->rtp, 1);
 		break;
 	default:
@@ -879,6 +875,7 @@
 
 struct request_data {
 	struct ast_sip_session *session;
+	struct ast_format_cap *caps;
 	const char *dest;
 	int cause;
 };
@@ -919,12 +916,14 @@
 		return -1;
 	}
 
-	if (!(session = ast_sip_session_create_outgoing(endpoint, args.aor, request_user))) {
+	if (!(session = ast_sip_session_create_outgoing(endpoint, args.aor, request_user, req_data->caps))) {
 		req_data->cause = AST_CAUSE_NO_ROUTE_DESTINATION;
 		return -1;
 	}
 
 	req_data->session = session;
+	ast_format_cap_copy(session->caps, req_data->caps);
+
 	return 0;
 }
 
@@ -934,6 +933,7 @@
 	struct request_data req_data;
 	struct ast_sip_session *session;
 
+	req_data.caps = cap;
 	req_data.dest = data;
 
 	if (ast_sip_push_task_synchronous(NULL, request, &req_data)) {

Modified: team/kharwell/pimp_sip_video/include/asterisk/res_sip_session.h
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_video/include/asterisk/res_sip_session.h?view=diff&rev=383402&r1=383401&r2=383402
==============================================================================
--- team/kharwell/pimp_sip_video/include/asterisk/res_sip_session.h (original)
+++ team/kharwell/pimp_sip_video/include/asterisk/res_sip_session.h Tue Mar 19 18:17:08 2013
@@ -79,6 +79,8 @@
 	struct ao2_container *media;
 	/* Serializer for tasks relating to this SIP session */
 	struct ast_taskprocessor *serializer;
+	/* Capabilities */
+	struct ast_format_cap *caps;
 };
 
 /*!
@@ -245,8 +247,9 @@
  * \param endpoint The endpoint that this session uses for settings
  * \param location Optional name of the location to call, be it named location or explicit URI
  * \param request_user Optional request user to place in the request URI if permitted
- */
-struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint, const char *location, const char *request_user);
+ * \param caps The negotiated capabilities
+ */
+struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint, const char *location, const char *request_user, struct ast_format_cap *caps);
 
 /*!
  * \brief Register an SDP handler

Modified: team/kharwell/pimp_sip_video/res/res_sip_sdp_video.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_video/res/res_sip_sdp_video.c?view=diff&rev=383402&r1=383401&r2=383402
==============================================================================
--- team/kharwell/pimp_sip_video/res/res_sip_sdp_video.c (original)
+++ team/kharwell/pimp_sip_video/res/res_sip_sdp_video.c Tue Mar 19 18:17:08 2013
@@ -3,7 +3,7 @@
  *
  * Copyright (C) 2013, Digium, Inc.
  *
- * Joshua Colp <jcolp at digium.com>
+ * Kevin Harwell <kharwell at digium.com>
  *
  * See http://www.asterisk.org for more information about
  * the Asterisk project. Please do not directly contact
@@ -18,7 +18,7 @@
 
 /*! \file
  *
- * \author Joshua Colp <jcolp at digium.com>
+ * \author Kevin Harwell <kharwell at digium.com>
  *
  * \brief SIP SDP 'video' media stream handling
  */
@@ -50,21 +50,20 @@
 #include "asterisk/res_sip.h"
 #include "asterisk/res_sip_session.h"
 
+static const char STR_VIDEO[] = "video";
+
 /*! \brief Scheduler for RTCP purposes */
 static struct ast_sched_context *sched;
 
 /*! \brief Forward declarations for SDP handler functions */
 static int video_negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream);
 static int video_create_outgoing_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct pjmedia_sdp_session *sdp);
-static int video_apply_negotiated_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_media *local_stream,
-	const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream);
-
-/*! \brief Forward declaration for session supplement functions */
+static int video_apply_negotiated_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_media *local_stream, const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream);
 static void video_stream_destroy(struct ast_sip_session_media *session_media);
 
 /*! \brief SDP handler for 'video' media stream */
 static struct ast_sip_session_sdp_handler video_sdp_handler = {
-	.id = "video",
+	.id = STR_VIDEO,
 	.negotiate_incoming_sdp_stream = video_negotiate_incoming_sdp_stream,
 	.create_outgoing_sdp_stream = video_create_outgoing_sdp_stream,
 	.apply_negotiated_sdp_stream = video_apply_negotiated_sdp_stream,
@@ -101,6 +100,98 @@
 	return 0;
 }
 
+static void get_peer_codecs(struct ast_sip_session *session, const struct pjmedia_sdp_media *stream, struct ast_rtp_codecs *codecs, const char *type)
+{
+	pjmedia_sdp_attr *attr;
+	int i, num = 0;
+
+	ast_rtp_codecs_payloads_initialize(codecs);
+
+	/* Iterate through provided formats */
+	for (i = 0; i < stream->desc.fmt_count; ++i) {
+		/* The payload is kept as a string for things like t38 but for video it is always numerical */
+		ast_rtp_codecs_payloads_set_m_type(codecs, NULL, pj_strtoul(&stream->desc.fmt[i]));
+		/* Look for the optional rtpmap attribute */
+		if ((attr = pjmedia_sdp_media_find_attr2(stream, "rtpmap", &stream->desc.fmt[i]))) {
+			pjmedia_sdp_rtpmap *rtpmap;
+			/* Interpret the attribute as an rtpmap */
+			if ((pjmedia_sdp_attr_to_rtpmap(session->inv_session->pool_active, attr, &rtpmap)) == PJ_SUCCESS) {
+				char name[32];
+				ast_copy_pj_str(name, &rtpmap->enc_name, sizeof(name));
+				ast_rtp_codecs_payloads_set_rtpmap_type_rate(codecs, NULL, pj_strtoul(&stream->desc.fmt[i]),
+									     (char*)type, name, 0, rtpmap->clock_rate);
+				/* Look for an optional associated fmtp attribute */
+				if ((attr = pjmedia_sdp_media_find_attr2(stream, "fmtp", &rtpmap->pt))) {
+					pjmedia_sdp_fmtp fmtp;
+					if ((pjmedia_sdp_attr_get_fmtp(attr, &fmtp)) == PJ_SUCCESS) {
+						struct ast_format *format;
+						sscanf(pj_strbuf(&fmtp.fmt), "%d", &num);
+						if ((format = ast_rtp_codecs_get_payload_format(codecs, num))) {
+							ast_format_sdp_parse(format, pj_strbuf(&fmtp.fmt_param));
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+static int get_peer_caps(struct ast_sip_session *session, const struct pjmedia_sdp_media *stream, const char *type)
+{
+	struct ast_rtp_codecs codecs;
+	RAII_VAR(struct ast_format_cap *, peer, NULL, ast_format_cap_destroy);
+	int fmts = 0;
+
+	if (!(peer = ast_format_cap_alloc_nolock())) {
+		ast_log(LOG_ERROR, "Failed to allocate %s capabilities\n", type);
+		return -1;
+	}
+
+	get_peer_codecs(session, stream, &codecs, type);
+	ast_rtp_codecs_payload_formats(&codecs, peer, &fmts);
+
+	ast_format_cap_append(session->caps, peer);
+	ast_rtp_codecs_payloads_destroy(&codecs);
+
+	return 1;
+}
+
+static struct ast_format_cap* get_joint_caps(struct ast_sip_session *session, const struct ast_format_cap *caps, 
+					     const char *type, enum ast_format_type remove_fmt)
+{
+	RAII_VAR(struct ast_format_cap *, conf, NULL, ast_format_cap_destroy);
+	RAII_VAR(struct ast_format_cap *, peer, NULL, ast_format_cap_destroy);
+	struct ast_format_cap *joint;
+
+	if (!(conf = ast_format_cap_alloc_nolock()) ||
+	    !(peer = ast_format_cap_alloc_nolock())) {
+		ast_log(LOG_ERROR, "Failed to allocate %s capabilities\n", type);
+		return NULL;
+	}
+
+	ast_format_cap_copy(conf, session->endpoint->codecs);
+	ast_format_cap_remove_bytype(conf, remove_fmt);
+
+	ast_format_cap_copy(peer, caps);
+	ast_format_cap_remove_bytype(peer, remove_fmt);
+
+	/* ast_format_cap_joint_copy */
+	if (!(joint = ast_format_cap_joint(conf, peer))) {
+		char usbuf[64], thembuf[64];
+
+		if (session->channel) {
+			ast_channel_hangupcause_set(session->channel, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
+		}
+
+		ast_getformatname_multiple(usbuf, sizeof(usbuf), conf);
+		ast_getformatname_multiple(thembuf, sizeof(thembuf), peer);
+		ast_log(LOG_WARNING, "No joint capabilities between our configuration(%s) and incoming SDP(%s)\n", usbuf, thembuf);
+		return NULL;
+	}
+
+	return joint;
+}
+
 /*! \brief Function which negotiates an incoming 'video' stream */
 static int video_negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream)
 {
@@ -124,32 +215,36 @@
 	if (!session_media->rtp && video_create_rtp(session, session_media, ast_sockaddr_is_ipv6(addrs))) {
 		return -1;
 	}
-
 	/* pjmedia takes care of the formats and such */
-	return 1;
+	return get_peer_caps(session, stream, STR_VIDEO);
 }
 
 /*! \brief Function which creates an outgoing 'video' stream */
 static int video_create_outgoing_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct pjmedia_sdp_session *sdp)
 {
-	static const pj_str_t STR_VIDEO = { "video", 5};
 	static const pj_str_t STR_IN = { "IN", 2 };
 	static const pj_str_t STR_IP4 = { "IP4", 3};
 	static const pj_str_t STR_IP6 = { "IP6", 3};
 	static const pj_str_t STR_RTP_AVP = { "RTP/AVP", 7 };
 	static const pj_str_t STR_SENDRECV = { "sendrecv", 8 };
+
 	pj_pool_t *pool = session->inv_session->pool_active;
 	pjmedia_sdp_media *media;
 	struct ast_sockaddr addr;
-	char tmp[32];
-	pj_str_t stmp;
+
+	int rtp_code0;
+	char rtp_code1[32];
+	struct ast_str *fmtp0 = ast_str_alloca(256);
+	pj_str_t fmtp1;
+	pjmedia_sdp_rtpmap rtpmap;
 	pjmedia_sdp_attr *attr;
-	int index = 0, min_packet_size = 0, noncodec = (session->endpoint->dtmf == AST_SIP_DTMF_RFC_4733) ? AST_RTP_DTMF : 0;
 
 	if (!ast_format_cap_has_type(session->endpoint->codecs, AST_FORMAT_TYPE_VIDEO)) {
 		/* If no video formats are configured don't add a stream */
 		return 0;
-	} else if (!session_media->rtp && video_create_rtp(session, session_media, session->endpoint->rtp_ipv6)) {
+	}
+
+	if (!session_media->rtp && video_create_rtp(session, session_media, session->endpoint->rtp_ipv6)) {
 		return -1;
 	}
 
@@ -159,7 +254,7 @@
 	}
 
 	/* TODO: This should eventually support SRTP */
-	media->desc.media = STR_VIDEO;
+	media->desc.media = pj_str((char*)STR_VIDEO);
 	media->desc.transport = STR_RTP_AVP;
 
 	/* Add connection level details */
@@ -170,24 +265,32 @@
 	media->desc.port = (pj_uint16_t) ast_sockaddr_port(&addr);
 	media->desc.port_count = 1;
 
-	/* Add formats */
-	for (index = 0; (index < AST_CODEC_PREF_SIZE); index++) {
-		struct ast_format format;
-		int rtp_code;
-		pjmedia_sdp_rtpmap rtpmap;
-		struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(session_media->rtp)->pref;
-
-		if (!ast_codec_pref_index(&session->endpoint->prefs, index, &format)) {
-			break;
-		} else if (AST_FORMAT_GET_TYPE(format.id) != AST_FORMAT_TYPE_VIDEO) {
-			continue;
-		} else if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media->rtp),
-								   1, &format, 0)) == -1) {
+	struct ast_format format;
+	RAII_VAR(struct ast_format_cap *, joint, NULL, ast_format_cap_destroy);
+
+	if (!ast_format_cap_is_empty(session->caps)) {
+		joint = get_joint_caps(session, session->caps, "video", AST_FORMAT_TYPE_AUDIO);
+	}
+	
+	if (!joint) {
+		if (!(joint = ast_format_cap_alloc_nolock())) {
+			ast_log(LOG_ERROR, "Failed to allocate video capabilities\n");
 			return -1;
 		}
-
-		snprintf(tmp, sizeof(tmp), "%d", rtp_code);
-		pj_strdup2(pool, &media->desc.fmt[media->desc.fmt_count++], tmp);
+		ast_format_cap_copy(joint, session->endpoint->codecs);
+	}
+
+	ast_format_cap_iter_start(joint);
+	while (!(ast_format_cap_iter_next(joint, &format))) {
+		/* if (AST_FORMAT_GET_TYPE(format.id) != AST_FORMAT_TYPE_VIDEO) { */
+		/* 	continue; */
+		/* } */
+		if ((rtp_code0 = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media->rtp), 1, &format, 0)) == -1) {
+			return -1;
+		}
+
+		snprintf(rtp_code1, sizeof(rtp_code1), "%d", rtp_code0);
+		pj_strdup2(pool, &media->desc.fmt[media->desc.fmt_count++], rtp_code1);
 		rtpmap.pt = media->desc.fmt[media->desc.fmt_count - 1];
 		rtpmap.clock_rate = ast_rtp_lookup_sample_rate2(1, &format, 0);
 		pj_strdup2(pool, &rtpmap.enc_name, ast_rtp_lookup_mime_subtype2(1, &format, 0, 0));
@@ -196,47 +299,15 @@
 		pjmedia_sdp_rtpmap_to_attr(pool, &rtpmap, &attr);
 		media->attr[media->attr_count++] = attr;
 
-		if (pref) {
-			struct ast_format_list fmt = ast_codec_pref_getsize(pref, &format);
-			if (fmt.cur_ms && ((fmt.cur_ms < min_packet_size) || !min_packet_size)) {
-				min_packet_size = fmt.cur_ms;
+		ast_format_sdp_generate(&format, rtp_code0, &fmtp0);
+		if (ast_str_strlen(fmtp0)) {
+			fmtp1 = pj_str(ast_str_buffer(fmtp0));
+			if ((attr = pjmedia_sdp_attr_create(pool, "fmtp", &fmtp1))) {
+				media->attr[media->attr_count++] = attr;
 			}
 		}
 	}
-
-	/* Add non-codec formats */
-	for (index = 1LL; index <= AST_RTP_MAX; index <<= 1) {
-		int rtp_code;
-		pjmedia_sdp_rtpmap rtpmap;
-
-		if (!(noncodec & index) || (rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media->rtp),
-										   0, NULL, index)) == -1) {
-			continue;
-		}
-
-		snprintf(tmp, sizeof(tmp), "%d", rtp_code);
-		pj_strdup2(pool, &media->desc.fmt[media->desc.fmt_count++], tmp);
-		rtpmap.pt = media->desc.fmt[media->desc.fmt_count - 1];
-		rtpmap.clock_rate = ast_rtp_lookup_sample_rate2(0, NULL, index);
-		pj_strdup2(pool, &rtpmap.enc_name, ast_rtp_lookup_mime_subtype2(0, NULL, index, 0));
-		rtpmap.param.slen = 0;
-
-		pjmedia_sdp_rtpmap_to_attr(pool, &rtpmap, &attr);
-		media->attr[media->attr_count++] = attr;
-
-		if (index == AST_RTP_DTMF) {
-			snprintf(tmp, sizeof(tmp), "%d 0-16", rtp_code);
-			attr = pjmedia_sdp_attr_create(pool, "fmtp", pj_cstr(&stmp, tmp));
-			media->attr[media->attr_count++] = attr;
-		}
-	}
-
-	/* If ptime is set add it as an attribute */
-	if (min_packet_size) {
-		snprintf(tmp, sizeof(tmp), "%d", min_packet_size);
-		attr = pjmedia_sdp_attr_create(pool, "ptime", pj_cstr(&stmp, tmp));
-		media->attr[media->attr_count++] = attr;
-	}
+	ast_format_cap_iter_end(joint);
 
 	/* Add the sendrecv attribute - we purposely don't keep track because pjmedia-sdp will automatically change our offer for us */
 	attr = PJ_POOL_ZALLOC_T(pool, pjmedia_sdp_attr);
@@ -250,8 +321,7 @@
 }
 
 /*! \brief Function which applies a negotiated SDP stream */
-static int video_apply_negotiated_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_media *local_stream,
-	const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream)
+static int video_apply_negotiated_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_media *local_stream, const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream)
 {
 	int format, othercapability = 0;
 	char host[NI_MAXHOST];
@@ -311,28 +381,6 @@
 
 	ast_rtp_codecs_payload_formats(&codecs, peercap, &othercapability);
 
-	/* Apply packetization if available and configured to do so */
-	if (session->endpoint->use_ptime && (attr = pjmedia_sdp_media_find_attr2(remote_stream, "ptime", NULL))) {
-		pj_str_t value = attr->value;
-		unsigned long framing = pj_strtoul(pj_strltrim(&value));
-		int codec;
-		struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(session_media->rtp)->pref;
-
-		for (codec = 0; codec < AST_RTP_MAX_PT; codec++) {
-			struct ast_rtp_payload_type format = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(
-				session_media->rtp), codec);
-
-			if (!format.asterisk_format) {
-				continue;
-			}
-
-			ast_codec_pref_setsize(pref, &format.format, framing);
-		}
-
-		ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(session_media->rtp),
-			session_media->rtp, pref);
-	}
-
 	/* Using the configured codecs and the codecs in this SDP we determine the joint formats for *video only* */
 	ast_format_cap_copy(cap, session->endpoint->codecs);
 	ast_format_cap_remove_bytype(cap, AST_FORMAT_TYPE_AUDIO);
@@ -368,24 +416,6 @@
 	ast_channel_set_fd(session->channel, 2, ast_rtp_instance_fd(session_media->rtp, 0));
 	ast_channel_set_fd(session->channel, 3, ast_rtp_instance_fd(session_media->rtp, 1));
 
-	if (session_media->held && (!ast_sockaddr_isnull(addrs) ||
-							  !pjmedia_sdp_media_find_attr2(remote_stream, "sendonly", NULL))) {
-		/* The remote side has taken us off hold */
-		ast_queue_control(session->channel, AST_CONTROL_UNHOLD);
-		ast_queue_frame(session->channel, &ast_null_frame);
-		session_media->held = 0;
-	} else if (ast_sockaddr_isnull(addrs) || ast_sockaddr_is_any(addrs) || pjmedia_sdp_media_find_attr2(remote_stream, "sendonly", NULL)) {
-		/* The remote side has put us on hold */
-		ast_queue_control_data(session->channel, AST_CONTROL_HOLD, S_OR(session->endpoint->mohsuggest, NULL),
-				       !ast_strlen_zero(session->endpoint->mohsuggest) ? strlen(session->endpoint->mohsuggest) + 1 : 0);
-		ast_rtp_instance_stop(session_media->rtp);
-		ast_queue_frame(session->channel, &ast_null_frame);
-		session_media->held = 1;
-	} else {
-		/* The remote side has not changed state, but make sure the instance is active */
-		ast_rtp_instance_activate(session_media->rtp);
-	}
-
 	ast_rtp_codecs_payloads_destroy(&codecs);
 	return 1;
 }
@@ -400,6 +430,21 @@
 	ast_rtp_instance_stop(session_media->rtp);
 	ast_rtp_instance_destroy(session_media->rtp);
 }
+
+static int incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
+{
+	if (!pj_strcmp2(&rdata->msg_info.msg->body->content_type.type, "application") &&
+	    !pj_strcmp2(&rdata->msg_info.msg->body->content_type.subtype, "media_control+xml")) {
+		ast_queue_control(session->channel, AST_CONTROL_VIDUPDATE);
+	}
+
+	return 0;
+}
+
+static struct ast_sip_session_supplement info_supplement = {
+	.method = "INFO",
+	.incoming_request = incoming_request,
+};
 
 /*!
  * \brief Load the module
@@ -428,6 +473,8 @@
 		goto end;
 	}
 
+	ast_sip_session_register_supplement(&info_supplement);
+
 	return AST_MODULE_LOAD_SUCCESS;
 end:
 	if (sched) {
@@ -440,6 +487,7 @@
 /*! \brief Unload the Gulp channel from Asterisk */
 static int unload_module(void)
 {
+	ast_sip_session_unregister_supplement(&info_supplement);
 	ast_sip_session_unregister_sdp_handler(&video_sdp_handler, "video");
 	ast_sched_context_destroy(sched);
 	return 0;

Modified: team/kharwell/pimp_sip_video/res/res_sip_session.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_video/res/res_sip_session.c?view=diff&rev=383402&r1=383401&r2=383402
==============================================================================
--- team/kharwell/pimp_sip_video/res/res_sip_session.c (original)
+++ team/kharwell/pimp_sip_video/res/res_sip_session.c Tue Mar 19 18:17:08 2013
@@ -699,6 +699,7 @@
 	ao2_cleanup(session->media);
 	AST_LIST_HEAD_DESTROY(&session->supplements);
 	ao2_cleanup(session->endpoint);
+	ast_format_cap_destroy(session->caps);
 }
 
 static int add_supplements(struct ast_sip_session *session)
@@ -761,6 +762,8 @@
 	inv_session->mod_data[session_module.id] = session;
 	session->endpoint = endpoint;
 	session->inv_session = inv_session;
+	session->caps = ast_format_cap_alloc_nolock();
+
 	if (add_supplements(session)) {
 		return NULL;
 	}
@@ -779,7 +782,7 @@
 	return CMP_MATCH | CMP_STOP;
 }
 
-struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint, const char *location, const char *request_user)
+struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint *endpoint, const char *location, const char *request_user, struct ast_format_cap *caps)
 {
 	char *aor_name, *rest;
 	const char *uri = NULL;
@@ -837,9 +840,14 @@
 	timer.sess_expires = endpoint->sess_expires;
 	pjsip_timer_init_session(inv_session, &timer);
 
-	if (!(session = ast_sip_session_alloc(endpoint, inv_session)) ||
-		(pjsip_dlg_add_usage(dlg, &session_module, NULL) != PJ_SUCCESS) ||
-		!(offer = create_local_sdp(inv_session, session, NULL))) {
+	if (!(session = ast_sip_session_alloc(endpoint, inv_session))) {
+		pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
+		return NULL;
+	}
+
+	ast_format_cap_copy(session->caps, caps);
+	if ((pjsip_dlg_add_usage(dlg, &session_module, NULL) != PJ_SUCCESS) ||
+	    !(offer = create_local_sdp(inv_session, session, NULL))) {
 		pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
 		return NULL;
 	}




More information about the asterisk-commits mailing list