[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