[asterisk-commits] file: branch file/chan_jingle2 r365536 - in /team/file/chan_jingle2: channels...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon May 7 15:19:24 CDT 2012


Author: file
Date: Mon May  7 15:19:20 2012
New Revision: 365536

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=365536
Log:
Add video support for Jingle and Google Jingle.

Modified:
    team/file/chan_jingle2/channels/chan_jingle2.c
    team/file/chan_jingle2/include/asterisk/jabber.h
    team/file/chan_jingle2/res/res_jabber.c

Modified: team/file/chan_jingle2/channels/chan_jingle2.c
URL: http://svnview.digium.com/svn/asterisk/team/file/chan_jingle2/channels/chan_jingle2.c?view=diff&rev=365536&r1=365535&r2=365536
==============================================================================
--- team/file/chan_jingle2/channels/chan_jingle2.c (original)
+++ team/file/chan_jingle2/channels/chan_jingle2.c Mon May  7 15:19:20 2012
@@ -128,6 +128,9 @@
 /*! \brief Namespace for Google Phone description */
 #define GOOGLE_PHONE_NS "http://www.google.com/session/phone"
 
+/*! \brief Namespace for Google Video description */
+#define GOOGLE_VIDEO_NS "http://www.google.com/session/video"
+
 /*! \brief Namespace for XMPP stanzas */
 #define XMPP_STANZAS_NS "urn:ietf:params:xml:ns:xmpp-stanzas"
 
@@ -221,6 +224,7 @@
 	.answer = jingle_answer,
 	.read = jingle_read,
 	.write = jingle_write,
+	.write_video = jingle_write,
 	.exception = jingle_read,
 	.indicate = jingle_indicate,
 	.fixup = jingle_fixup,
@@ -383,6 +387,39 @@
 	.update_peer = jingle_set_rtp_peer,
 };
 
+/*! \brief Internal helper function which enables video support on a sesson if possible */
+static void jingle_enable_video(struct jingle_session *session)
+{
+	struct ast_sockaddr tmp;
+	struct ast_rtp_engine_ice *ice;
+
+	/* If video is already present don't do anything */
+	if (session->vrtp) {
+		return;
+	}
+
+	/* If there are no configured video codecs do not turn video support on, it just won't work */
+	if (!ast_format_cap_has_type(session->cap, AST_FORMAT_TYPE_VIDEO)) {
+		return;
+	}
+
+	ast_sockaddr_parse(&tmp, "0.0.0.0", 0);
+
+	if (!(session->vrtp = ast_rtp_instance_new("asterisk", sched, &tmp, NULL))) {
+		return;
+	}
+	
+	ast_rtp_instance_set_prop(session->vrtp, AST_RTP_PROPERTY_RTCP, 1);
+
+	ast_channel_set_fd(session->owner, 2, ast_rtp_instance_fd(session->vrtp, 0));
+	ast_channel_set_fd(session->owner, 3, ast_rtp_instance_fd(session->vrtp, 1));
+	ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(session->vrtp), session->vrtp, &session->prefs);
+
+	if (session->transport == JINGLE_TRANSPORT_GOOGLE_V2 && (ice = ast_rtp_instance_get_ice(session->vrtp))) {
+		ice->stop(session->vrtp);
+	}
+}
+
 /*! \brief Internal helper function used to allocate Jingle session on an endpoint */
 static struct jingle_session *jingle_alloc(struct jingle_endpoint *endpoint, const char *from, const char *sid)
 {
@@ -429,6 +466,7 @@
 	 * that we want IPv4 */
 	ast_sockaddr_parse(&tmp, "0.0.0.0", 0);
 
+	/* Sessions always carry audio, but video is optional so don't enable it here */
 	if (!(session->rtp = ast_rtp_instance_new("asterisk", sched, &tmp, NULL))) {
 		ao2_unlock(endpoint);
 		ao2_ref(endpoint, -1);
@@ -464,8 +502,8 @@
 	ast_channel_tech_pvt_set(chan, session);
 	session->owner = chan;
 
+	ast_format_cap_copy(ast_channel_nativeformats(chan), session->cap);
         ast_codec_choose(&session->prefs, session->cap, 1, &tmpfmt);
-        ast_format_cap_add(ast_channel_nativeformats(chan), &tmpfmt);
 
 	if (session->rtp) {
 		struct ast_rtp_engine_ice *ice;
@@ -479,18 +517,6 @@
 		    (ice = ast_rtp_instance_get_ice(session->rtp))) {
 			/* We stop built in ICE support because we need to fall back to old old old STUN support */
 			ice->stop(session->rtp);
-		}
-	}
-
-	if (session->vrtp) {
-		struct ast_rtp_engine_ice *ice;
-	
-		ast_channel_set_fd(chan, 0, ast_rtp_instance_fd(session->vrtp, 0));
-		ast_channel_set_fd(chan, 1, ast_rtp_instance_fd(session->vrtp, 1));
-		ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(session->vrtp), session->vrtp, &session->prefs);
-
-		if (session->transport == JINGLE_TRANSPORT_GOOGLE_V2 && (ice = ast_rtp_instance_get_ice(session->vrtp))) {
-			ice->stop(session->vrtp);
 		}
 	}
 
@@ -890,8 +916,11 @@
 		iks *payload;
 		char tmp[32];
 
-		if ((AST_FORMAT_GET_TYPE(format.id) != type) ||
-		    ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(rtp), 1, &format, 0)) == -1) ||
+		if (AST_FORMAT_GET_TYPE(format.id) != type) {
+			continue;
+		}
+
+		if (((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(rtp), 1, &format, 0)) == -1) ||
 		    (!(payload = iks_new("payload-type")))) {
 			res = -1;
 			goto end;
@@ -1001,7 +1030,8 @@
 	}
 
 	if ((session->transport != JINGLE_TRANSPORT_GOOGLE_V1) && !res && session->vrtp) {
-		if ((video = iks_new("content")) && (video_description = iks_new("description"))) {
+		if ((video = iks_new("content")) && (video_description = iks_new("description")) &&
+		    (video_transport = iks_new("transport"))) {
 			iks_insert_attrib(video, "creator", session->outgoing ? "initiator" : "responder");
 			iks_insert_attrib(video, "name", session->video_content_name);
 			iks_insert_node(jingle, video);
@@ -1416,6 +1446,13 @@
 			     AST_APP_ARG(target);
 		);
 
+	/* We require at a minimum one audio format to be requested */
+	if (!ast_format_cap_has_type(cap, AST_FORMAT_TYPE_AUDIO)) {
+		ast_log(LOG_ERROR, "Jingle channel driver requires an audio format when dialing a destination\n");
+		*cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
+		return NULL;
+	}
+
 	if (ast_strlen_zero(data) || !(dialed = ast_strdupa(data))) {
 		ast_log(LOG_ERROR, "Unable to create channel with empty destination.\n");
 		*cause = AST_CAUSE_CHANNEL_UNACCEPTABLE;
@@ -1504,6 +1541,11 @@
 		return NULL;
 	}
 
+	/* If video was requested try to enable it on the session */
+	if (ast_format_cap_has_type(cap, AST_FORMAT_TYPE_VIDEO)) {
+		jingle_enable_video(session);
+	}
+
 	/* We purposely don't decrement the session here as there is a reference on the channel */
 
 	ao2_link(endpoint->sessions, session);
@@ -1545,7 +1587,8 @@
 		/* If description information is available use it */
 		if ((description = iks_find_with_attrib(content, "description", "xmlns", JINGLE_RTP_NS)) ||
 		    (description = iks_find_with_attrib(content, "rtp:description", "xmlns:rtp", JINGLE_RTP_NS)) ||
-		    (description = iks_find_with_attrib(pak->query, "description", "xmlns", GOOGLE_PHONE_NS))) {
+		    (description = iks_find_with_attrib(pak->query, "description", "xmlns", GOOGLE_PHONE_NS)) ||
+		    (description = iks_find_with_attrib(pak->query, "vid:description", "xmlns", GOOGLE_VIDEO_NS))) {
 			char *media = iks_find_attrib(description, "media");
 			struct ast_rtp_codecs codecs;
 			iks *codec;
@@ -1571,7 +1614,16 @@
 				if (!ast_strlen_zero(name)) {
 					ast_copy_string(session->video_content_name, name, sizeof(session->video_content_name));
 				}
+
+				jingle_enable_video(session);
 				rtp = session->vrtp;
+
+				/* If video is not present cancel this session */
+				if (!session->vrtp) {
+					ast_queue_hangup_with_cause(session->owner, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
+					return;
+				}
+
 				ast_format_cap_remove_bytype(session->peercap, AST_FORMAT_TYPE_VIDEO);
 				ast_format_cap_remove_bytype(session->jointcap, AST_FORMAT_TYPE_VIDEO);
 			} else {
@@ -1588,11 +1640,14 @@
 				char *clockrate = iks_find_attrib(codec, "clockrate");
 				int rtp_id, rtp_clockrate;
 
-				if (!ast_strlen_zero(id) && !ast_strlen_zero(name) && !ast_strlen_zero(clockrate) &&
-				    (sscanf(id, "%30d", &rtp_id) == 1) && (sscanf(clockrate, "%30d", &rtp_clockrate) == 1)) {
-
+				if (!ast_strlen_zero(id) && !ast_strlen_zero(name) && (sscanf(id, "%30d", &rtp_id) == 1)) {
 					ast_rtp_codecs_payloads_set_m_type(&codecs, NULL, rtp_id);
-					ast_rtp_codecs_payloads_set_rtpmap_type_rate(&codecs, NULL, rtp_id, media, name, 0, rtp_clockrate);
+
+					if (!ast_strlen_zero(clockrate) && (sscanf(clockrate, "%30d", &rtp_clockrate) == 1)) {
+						ast_rtp_codecs_payloads_set_rtpmap_type_rate(&codecs, NULL, rtp_id, media, name, 0, rtp_clockrate);
+					} else {
+						ast_rtp_codecs_payloads_set_rtpmap_type(&codecs, NULL, rtp_id, media, name, 0);
+					}
 				}
 			}
 
@@ -1663,6 +1718,12 @@
 				local_candidate.transport = protocol;
 
 				ast_sockaddr_parse(&local_candidate.address, ip, PARSE_PORT_FORBID);
+
+				/* We only support IPv4 right now */
+				if (!ast_sockaddr_is_ipv4(&local_candidate.address)) {
+					continue;
+				}
+
 				ast_sockaddr_set_port(&local_candidate.address, real_port);
 
 				if (!strcasecmp(type, "host")) {
@@ -1762,10 +1823,10 @@
 	if (changed) {
 		struct ast_format fmt;
 
+		ast_format_cap_copy(ast_channel_nativeformats(session->owner), session->jointcap);
 		ast_codec_choose(&session->prefs, session->jointcap, 1, &fmt);
-		ast_format_cap_set(ast_channel_nativeformats(session->owner), &fmt);
-		ast_set_read_format(session->owner, ast_channel_readformat(session->owner));
-		ast_set_write_format(session->owner, ast_channel_writeformat(session->owner));
+		ast_set_read_format(session->owner, &fmt);
+		ast_set_write_format(session->owner, &fmt);
 	}
 }
 

Modified: team/file/chan_jingle2/include/asterisk/jabber.h
URL: http://svnview.digium.com/svn/asterisk/team/file/chan_jingle2/include/asterisk/jabber.h?view=diff&rev=365536&r1=365535&r2=365536
==============================================================================
--- team/file/chan_jingle2/include/asterisk/jabber.h (original)
+++ team/file/chan_jingle2/include/asterisk/jabber.h Mon May  7 15:19:20 2012
@@ -52,7 +52,7 @@
 
 #endif /* HAVE_OPENSSL */
 /* file is read by blocks with this size */
-#define NET_IO_BUF_SIZE 8192
+#define NET_IO_BUF_SIZE 12288
 /* Return value for timeout connection expiration */
 #define IKS_NET_EXPIRED 12
 

Modified: team/file/chan_jingle2/res/res_jabber.c
URL: http://svnview.digium.com/svn/asterisk/team/file/chan_jingle2/res/res_jabber.c?view=diff&rev=365536&r1=365535&r2=365536
==============================================================================
--- team/file/chan_jingle2/res/res_jabber.c (original)
+++ team/file/chan_jingle2/res/res_jabber.c Mon May  7 15:19:20 2012
@@ -2061,7 +2061,7 @@
 			resource->cap->jingle = 1;
 		}
 	} else if (pak->subtype == IKS_TYPE_GET) {
-		iks *iq, *disco, *ident, *google, *jingle, *ice, *rtp, *audio, *query;
+		iks *iq, *disco, *ident, *google, *jingle, *ice, *rtp, *audio, *video, *query;
 		iq = iks_new("iq");
 		query = iks_new("query");
 		ident = iks_new("identity");
@@ -2071,6 +2071,7 @@
 		ice = iks_new("feature");
 		rtp = iks_new("feature");
 		audio = iks_new("feature");
+		video = iks_new("feature");
 		if (iq && ident && disco && google) {
 			iks_insert_attrib(iq, "from", client->jid->full);
 			iks_insert_attrib(iq, "to", pak->from->full);
@@ -2086,6 +2087,7 @@
 			iks_insert_attrib(ice, "var", "urn:xmpp:jingle:transports:ice-udp:1");
 			iks_insert_attrib(rtp, "var", "urn:xmpp:jingle:apps:rtp:1");
 			iks_insert_attrib(audio, "var", "urn:xmpp:jingle:apps:rtp:audio");
+			iks_insert_attrib(video, "var", "urn:xmpp:jingle:apps:rtp:video");
 			iks_insert_node(iq, query);
 			iks_insert_node(query, ident);
 			iks_insert_node(query, google);
@@ -2094,6 +2096,7 @@
 			iks_insert_node(query, ice);
 			iks_insert_node(query, rtp);
 			iks_insert_node(query, audio);
+			iks_insert_node(query, video);
 			ast_aji_send(client, iq);
 		} else {
 			ast_log(LOG_ERROR, "Out of Memory.\n");
@@ -2104,6 +2107,11 @@
 		iks_delete(ident);
 		iks_delete(google);
 		iks_delete(disco);
+		iks_delete(jingle);
+		iks_delete(ice);
+		iks_delete(rtp);
+		iks_delete(audio);
+		iks_delete(video);
 	} else if (pak->subtype == IKS_TYPE_ERROR) {
 		ast_log(LOG_NOTICE, "User %s does not support discovery.\n", pak->from->full);
 	}
@@ -4031,7 +4039,7 @@
 		iks_insert_node(presence, priority);
 		iks_insert_attrib(cnode, "node", "http://www.asterisk.org/xmpp/client/caps");
 		iks_insert_attrib(cnode, "ver", "asterisk-xmpp");
-		iks_insert_attrib(cnode, "ext", "voice-v1");
+		iks_insert_attrib(cnode, "ext", "voice-v1 video-v1");
 		iks_insert_attrib(cnode, "xmlns", "http://jabber.org/protocol/caps");
 		iks_insert_node(presence, cnode);
 		ast_aji_send(client, presence);




More information about the asterisk-commits mailing list