[asterisk-commits] phsultan: branch phsultan/gmail-voice-video r167175 - in /team/phsultan/gmail...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Mon Jan 5 09:03:06 CST 2009


Author: phsultan
Date: Mon Jan  5 09:03:03 2009
New Revision: 167175

URL: http://svn.digium.com/view/asterisk?view=rev&rev=167175
Log:
New branch to make Asterisk work with Gmail's voice and video plugin.

Currently, voice calls are working. Here is a summary of the modifications.
- advertise media capabilities (voice/video) in presence packets ;
- properly interpret gmail's XMPP node names, that contain a semicolon ;
- distinguish between client types (GoogleTalk or Gmail) ;
- do not send transport-info tags to gmail clients ;
- use constants for XMPP namespaces ;
- set a maximum length for XMPP tag attributes.

Modified:
    team/phsultan/gmail-voice-video/channels/chan_gtalk.c
    team/phsultan/gmail-voice-video/include/asterisk/jabber.h
    team/phsultan/gmail-voice-video/include/asterisk/jingle.h
    team/phsultan/gmail-voice-video/res/res_jabber.c

Modified: team/phsultan/gmail-voice-video/channels/chan_gtalk.c
URL: http://svn.digium.com/view/asterisk/team/phsultan/gmail-voice-video/channels/chan_gtalk.c?view=diff&rev=167175&r1=167174&r2=167175
==============================================================================
--- team/phsultan/gmail-voice-video/channels/chan_gtalk.c (original)
+++ team/phsultan/gmail-voice-video/channels/chan_gtalk.c Mon Jan  5 09:03:03 2009
@@ -65,11 +65,9 @@
 #include "asterisk/astobj.h"
 #include "asterisk/abstract_jb.h"
 #include "asterisk/jabber.h"
+#include "asterisk/jingle.h"
 
 #define GOOGLE_CONFIG "gtalk.conf"
-
-#define GOOGLE_NS "http://www.google.com/session"
-
 
 /*! Global jitterbuffer configuration - by default, jb is disabled */
 static struct ast_jb_conf default_jbconf =
@@ -90,6 +88,12 @@
 	AJI_CONNECT_STUN = 1,
 	AJI_CONNECT_LOCAL = 2,
 	AJI_CONNECT_RELAY = 3,
+};
+
+enum gtalk_client_type {
+	AJI_CLIENT_UNKNOWN,
+	AJI_CLIENT_GTALK,		/*!< Remote client type is GoogleTalk */
+	AJI_CLIENT_GMAIL,		/*!< Remote client type is Gmail */
 };
 
 struct gtalk_pvt {
@@ -102,6 +106,7 @@
 	char ring[10];                   /*!< Message ID of ring */
 	iksrule *ringrule;               /*!< Rule for matching RING request */
 	int initiator;                   /*!< If we're the initiator */
+	enum gtalk_client_type ctype;
 	int alreadygone;
 	int capability;
 	struct ast_codec_pref prefs;
@@ -398,7 +403,7 @@
 		ast_log(LOG_ERROR, "Could not allocate iksemel nodes\n");
 		return 0;
 	}
-	iks_insert_attrib(dcodecs, "xmlns", "http://www.google.com/session/phone");
+	iks_insert_attrib(dcodecs, "xmlns", GOOGLE_AUDIO_NS);
 	iks_insert_attrib(dcodecs, "xml:lang", "en");
 
 	for (x = 0; x < 32; x++) {
@@ -418,7 +423,7 @@
 		iks_insert_attrib(payload_telephone, "name", "telephone-event");
 		iks_insert_attrib(payload_telephone, "clockrate", "8000");
 	}
-	iks_insert_attrib(transport,"xmlns","http://www.google.com/transport/p2p");
+	iks_insert_attrib(transport,"xmlns",GOOGLE_TRANSPORT_NS);
 	
 	iks_insert_attrib(iq, "type", "set");
 	iks_insert_attrib(iq, "to", to);
@@ -426,7 +431,7 @@
 	iks_insert_attrib(iq, "id", client->connection->mid);
 	ast_aji_increment_mid(client->connection->mid);
 
-	iks_insert_attrib(gtalk, "xmlns", "http://www.google.com/session");
+	iks_insert_attrib(gtalk, "xmlns", GOOGLE_NS);
 	iks_insert_attrib(gtalk, "type",initiator ? "initiate": "accept");
 	iks_insert_attrib(gtalk, "initiator", initiator ? from : to);
 	iks_insert_attrib(gtalk, "id", sid);
@@ -466,8 +471,8 @@
 	iks_insert_attrib(session, "type", "transport-accept");
 	iks_insert_attrib(session, "id", sid);
 	iks_insert_attrib(session, "initiator", initiator ? from : to);
-	iks_insert_attrib(session, "xmlns", "http://www.google.com/session");
-	iks_insert_attrib(transport, "xmlns", "http://www.google.com/transport/p2p");
+	iks_insert_attrib(session, "xmlns", GOOGLE_NS);
+	iks_insert_attrib(transport, "xmlns", GOOGLE_TRANSPORT_NS);
 	iks_insert_node(iq,session);
 	iks_insert_node(session,transport);
 	ast_aji_send(p->parent->connection, iq);
@@ -734,7 +739,7 @@
 	ast_debug(1, "The client is %s\n", client->name);
 	/* Make sure our new call doesn't exist yet */
 	for (tmp = client->p; tmp; tmp = tmp->next) {
-		if (iks_find_with_attrib(pak->x, "session", "id", tmp->sid))
+		if (iks_find_with_attrib(pak->x, "session", "id", tmp->sid) || !strcmp(iks_find_attrib(pak->query, "id"), tmp->sid))
 			break;
 	}
 	from = iks_find_attrib(pak->x, "to");
@@ -776,11 +781,14 @@
 	if (!ours1 || !ours2)
 		goto safeout;
 
-	iks_insert_attrib(transport, "xmlns","http://www.google.com/transport/p2p");
+	iks_insert_attrib(transport, "xmlns",GOOGLE_TRANSPORT_NS);
 	iks_insert_node(iq, gtalk);
-	iks_insert_node(gtalk,transport);
-	iks_insert_node(transport, candidate);
-
+	if (p->ctype == AJI_CLIENT_GMAIL) {
+		iks_insert_node(gtalk,candidate);
+	} else { 
+		iks_insert_node(gtalk,transport);
+		iks_insert_node(transport, candidate);
+	}
 	for (; p; p = p->next) {
 		if (!strcasecmp(p->sid, sid))
 			break;
@@ -837,7 +845,18 @@
 		iks_insert_attrib(iq, "type", "set");
 		iks_insert_attrib(iq, "id", c->mid);
 		ast_aji_increment_mid(c->mid);
-		iks_insert_attrib(gtalk, "type", "transport-info");
+		switch (p->ctype) {
+		case AJI_CLIENT_GTALK:
+			iks_insert_attrib(gtalk, "type", "transport-info");
+			break;
+		case AJI_CLIENT_GMAIL:
+			iks_insert_attrib(gtalk, "type", "candidates");
+			break;
+		default:
+			ast_log(LOG_WARNING, "Client type is unknown\n");
+			iks_insert_attrib(gtalk, "type", "transport-info");
+			break;	
+		}
 		iks_insert_attrib(gtalk, "id", sid);
 		iks_insert_attrib(gtalk, "initiator", (p->initiator) ? to : from);
 		iks_insert_attrib(gtalk, "xmlns", GOOGLE_NS);
@@ -908,6 +927,8 @@
 	if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
 		return NULL;
 	}
+	/* set client type to unknown until we have more info */
+	tmp->ctype = AJI_CLIENT_UNKNOWN;
 
 	memcpy(&tmp->prefs, &client->prefs, sizeof(struct ast_codec_pref));
 
@@ -1062,7 +1083,7 @@
 			iks_insert_attrib(session, "type", action);
 			iks_insert_attrib(session, "id", p->sid);
 			iks_insert_attrib(session, "initiator", p->initiator ? p->us : p->them);
-			iks_insert_attrib(session, "xmlns", "http://www.google.com/session");
+			iks_insert_attrib(session, "xmlns", GOOGLE_NS);
 			iks_insert_node(request, session);
 			ast_aji_send(client->connection, request);
 			res = 0;
@@ -1129,7 +1150,7 @@
 		from = client->connection->jid->full;
 	
 	while (tmp) {
-		if (iks_find_with_attrib(pak->x, "session", "id", tmp->sid)) {
+		if (iks_find_with_attrib(pak->x, "session", "id", tmp->sid) || !strcmp(iks_find_attrib(pak->query, "id"), tmp->sid)) {
 			ast_log(LOG_NOTICE, "Ignoring duplicate call setup on SID %s\n", tmp->sid);
 			gtalk_response(client, from, pak, "out-of-order", NULL);
 			return -1;
@@ -1153,6 +1174,14 @@
 		return -1;
 	}
 
+	/* if the node name of the query contains a semicolon, the remote peer
+	 * is a gmail type client. If not, treat it as a regular GoogleTalk
+	 * client */
+	if (strchr(iks_name(pak->query), ':')) {
+		p->ctype = AJI_CLIENT_GMAIL;
+	} else {
+		p->ctype = AJI_CLIENT_GTALK;
+	}
 	chan = gtalk_new(client, p, AST_STATE_DOWN, pak->from->user);
 	if (!chan) {
 		gtalk_free_pvt(client, p);
@@ -1170,8 +1199,14 @@
 	codec = iks_child(iks_child(iks_child(pak->x)));
 	
 	while (codec) {
-		ast_rtp_set_m_type(p->rtp, atoi(iks_find_attrib(codec, "id")));
-		ast_rtp_set_rtpmap_type(p->rtp, atoi(iks_find_attrib(codec, "id")), "audio", iks_find_attrib(codec, "name"), 0);
+		ast_log(LOG_NOTICE, "iks_name(codec) : %s\n", iks_name(codec));
+		if (!strcmp(iks_name(codec), "vid:payload-type")) {
+			ast_rtp_set_m_type(p->vrtp, atoi(iks_find_attrib(codec, "id")));
+			ast_rtp_set_rtpmap_type(p->vrtp, atoi(iks_find_attrib(codec, "id")), "video", iks_find_attrib(codec, "name"), 0);
+		} else	{
+			ast_rtp_set_m_type(p->rtp, atoi(iks_find_attrib(codec, "id")));
+			ast_rtp_set_rtpmap_type(p->rtp, atoi(iks_find_attrib(codec, "id")), "audio", iks_find_attrib(codec, "name"), 0);
+		}
 		codec = iks_next(codec);
 	}
 	
@@ -1206,7 +1241,9 @@
 		break;
 	case AST_PBX_SUCCESS:
 		gtalk_response(client, from, pak, NULL, NULL);
-		gtalk_invite_response(p, p->them, p->us,p->sid, 0);
+		if (p->ctype == AJI_CLIENT_GTALK) {
+			gtalk_invite_response(p, p->them, p->us,p->sid, 0);
+		}
 		gtalk_create_candidates(client, p, p->sid, p->them, p->us);
 		/* nothing to do */
 		break;
@@ -1245,12 +1282,11 @@
 		/* If the STUN result is different from the IP of the hostname,
 			lock on the stun IP of the hostname advertised by the
 			remote client */
-		if (aux.sin_addr.s_addr && 
-		    aux.sin_addr.s_addr != sin.sin_addr.s_addr)
+		if (aux.sin_addr.s_addr && aux.sin_addr.s_addr != sin.sin_addr.s_addr) {
 			ast_rtp_stun_request(p->rtp, &aux, username);
-		else 
+		} else { 
 			ast_rtp_stun_request(p->rtp, &sin, username);
-		
+		}
 		if (aux.sin_addr.s_addr) {
 			ast_debug(4, "Receiving RTP traffic from IP %s, matches with remote candidate's IP %s\n", ast_inet_ntoa(aux.sin_addr), tmp->ip);
 			ast_debug(4, "Sending STUN request to %s\n", tmp->ip);
@@ -1274,26 +1310,30 @@
 		from = c->jid->full;
 
 	for (tmp = client->p; tmp; tmp = tmp->next) {
-		if (iks_find_with_attrib(pak->x, "session", "id", tmp->sid)) {
+		if (iks_find_with_attrib(pak->x, "session", "id", tmp->sid) || !strcmp(iks_find_attrib(pak->query, "id"), tmp->sid)) {
 			p = tmp;
 			break;
 		}
 	}
 
-	if (!p)
+	if (!p) {
 		return -1;
-
+	}
 	traversenodes = pak->query;
 	while(traversenodes) {
 		if(!strcasecmp(iks_name(traversenodes), "session")) {
 			traversenodes = iks_child(traversenodes);
 			continue;
 		}
+		if(!strcasecmp(iks_name(traversenodes), "ses:session")) {
+			traversenodes = iks_child(traversenodes);
+			continue;
+		}
 		if(!strcasecmp(iks_name(traversenodes), "transport")) {
 			traversenodes = iks_child(traversenodes);
 			continue;
 		}
-		if(!strcasecmp(iks_name(traversenodes), "candidate")) {
+		if(!strcasecmp(iks_name(traversenodes), "candidate") || !strcasecmp(iks_name(traversenodes), "ses:candidate")) {
 			newcandidate = ast_calloc(1, sizeof(*newcandidate));
 			if (!newcandidate)
 				return 0;
@@ -1718,26 +1758,31 @@
 static int gtalk_parser(void *data, ikspak *pak)
 {
 	struct gtalk *client = ASTOBJ_REF((struct gtalk *) data);
+	int res;
 
 	if (iks_find_attrib(pak->x, "type") && !strcmp(iks_find_attrib (pak->x, "type"),"error")) {
 		ast_log(LOG_NOTICE, "Remote peer reported an error, trying to establish the call anyway\n");
 	}
-	else if (iks_find_with_attrib(pak->x, "session", "type", "initiate")) {
+	else if (!strcmp(iks_find_attrib(pak->query, "type"), "initiate")) {
 		/* New call */
 		gtalk_newcall(client, pak);
-	} else if (iks_find_with_attrib(pak->x, "session", "type", "candidates") || iks_find_with_attrib(pak->x, "session", "type", "transport-info")) {
+	} else if (!strcmp(iks_find_attrib(pak->query, "type"), "candidates") || !strcmp(iks_find_attrib(pak->query, "type"), "transport-info")) {
 		ast_debug(3, "About to add candidate!\n");
-		gtalk_add_candidate(client, pak);
-		ast_debug(3, "Candidate Added!\n");
-	} else if (iks_find_with_attrib(pak->x, "session", "type", "accept")) {
+		res = gtalk_add_candidate(client, pak);
+		if (!res) {
+			ast_log(LOG_WARNING, "Could not add any candidate\n");
+		} else {
+			ast_debug(3, "Candidate Added!\n");
+		}
+	} else if (!strcmp(iks_find_attrib(pak->query, "type"), "accept")) {
 		gtalk_is_answered(client, pak);
-	} else if (iks_find_with_attrib(pak->x, "session", "type", "transport-accept")) {
+	} else if (!strcmp(iks_find_attrib(pak->query, "type"), "transport-accept")) {
 		gtalk_is_accepted(client, pak);
-	} else if (iks_find_with_attrib(pak->x, "session", "type", "content-info") || iks_find_with_attrib(pak->x, "gtalk", "action", "session-info")) {
+	} else if (!strcmp(iks_find_attrib(pak->query, "type"), "content-info") || iks_find_with_attrib(pak->x, "gtalk", "action", "session-info")) {
 		gtalk_handle_dtmf(client, pak);
-	} else if (iks_find_with_attrib(pak->x, "session", "type", "terminate")) {
+	} else if (!strcmp(iks_find_attrib(pak->query, "type"), "terminate")) {
 		gtalk_hangup_farend(client, pak);
-	} else if (iks_find_with_attrib(pak->x, "session", "type", "reject")) {
+	} else if (!strcmp(iks_find_attrib(pak->query, "type"), "reject")) {
 		gtalk_hangup_farend(client, pak);
 	}
 	ASTOBJ_UNREF(client, gtalk_member_destroy);
@@ -1834,7 +1879,7 @@
 				iks_filter_add_rule(client->f, gtalk_parser, member, 
 						    IKS_RULE_TYPE, IKS_PAK_IQ, 
 						    IKS_RULE_FROM_PARTIAL, member->user,
-						    IKS_RULE_NS, "http://www.google.com/session",
+						    IKS_RULE_NS, GOOGLE_NS,
 						    IKS_RULE_DONE);
 
 			} else {
@@ -1959,7 +2004,7 @@
 						ASTOBJ_WRLOCK(iterator);
 						ASTOBJ_WRLOCK(member);
 						member->connection = NULL;
-						iks_filter_add_rule(iterator->f, gtalk_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, "http://www.google.com/session", IKS_RULE_DONE);
+						iks_filter_add_rule(iterator->f, gtalk_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, GOOGLE_NS, IKS_RULE_DONE);
 						iks_filter_add_rule(iterator->f, gtalk_parser, member, IKS_RULE_TYPE, IKS_PAK_IQ, IKS_RULE_NS, "http://jabber.org/protocol/gtalk", IKS_RULE_DONE);
 						ASTOBJ_UNLOCK(member);
 						ASTOBJ_UNLOCK(iterator);

Modified: team/phsultan/gmail-voice-video/include/asterisk/jabber.h
URL: http://svn.digium.com/view/asterisk/team/phsultan/gmail-voice-video/include/asterisk/jabber.h?view=diff&rev=167175&r1=167174&r2=167175
==============================================================================
--- team/phsultan/gmail-voice-video/include/asterisk/jabber.h (original)
+++ team/phsultan/gmail-voice-video/include/asterisk/jabber.h Mon Jan  5 09:03:03 2009
@@ -70,8 +70,9 @@
  * resulting in a maximum total size (including the '@' and '/' separators) 
  * of 3071 bytes.
  */
-#define AJI_MAX_JIDLEN 3071
+#define AJI_MAX_JIDLEN    3071
 #define AJI_MAX_RESJIDLEN 1023
+#define AJI_MAX_ATTRLEN   256
 
 enum aji_state {
 	AJI_DISCONNECTING,
@@ -92,14 +93,15 @@
 };
 
 struct aji_version {
-	char version[50];
+	char version[AJI_MAX_ATTRLEN];
+	char ext[AJI_MAX_ATTRLEN];
 	int jingle;
 	struct aji_capabilities *parent;
 	struct aji_version *next;
 };
 
 struct aji_capabilities {
-	char node[200];
+	char node[AJI_MAX_ATTRLEN];
 	struct aji_version *versions;
 	struct aji_capabilities *next;
 };
@@ -116,14 +118,14 @@
 struct aji_message {
 	char *from;
 	char *message;
-	char id[25];
+	char id[AJI_MAX_ATTRLEN];
 	time_t arrived;
 	AST_LIST_ENTRY(aji_message) list;
 };
 
 struct aji_buddy {
 	ASTOBJ_COMPONENTS_FULL(struct aji_buddy, AJI_MAX_JIDLEN, 1);
-	char channel[160];
+	char channel[AST_CHANNEL_NAME];
 	struct aji_resource *resources;
 	enum aji_btype btype;
 	struct ast_flags flags;
@@ -139,13 +141,13 @@
 
 struct aji_client {
 	ASTOBJ_COMPONENTS(struct aji_client);
-	char password[160];
+	char password[AJI_MAX_ATTRLEN];
 	char user[AJI_MAX_JIDLEN];
 	char serverhost[AJI_MAX_RESJIDLEN];
-	char statusmessage[256];
-	char name_space[256];
-	char sid[10]; /* Session ID */
-	char mid[6]; /* Message ID */
+	char statusmessage[AJI_MAX_ATTRLEN];
+	char name_space[AJI_MAX_ATTRLEN];
+	char sid[AJI_MAX_ATTRLEN]; /* Session ID */
+	char mid[AJI_MAX_ATTRLEN]; /* Message ID */
 	iksid *jid;
 	iksparser *p;
 	iksfilter *f;

Modified: team/phsultan/gmail-voice-video/include/asterisk/jingle.h
URL: http://svn.digium.com/view/asterisk/team/phsultan/gmail-voice-video/include/asterisk/jingle.h?view=diff&rev=167175&r1=167174&r2=167175
==============================================================================
--- team/phsultan/gmail-voice-video/include/asterisk/jingle.h (original)
+++ team/phsultan/gmail-voice-video/include/asterisk/jingle.h Mon Jan  5 09:03:03 2009
@@ -44,6 +44,9 @@
 #define JINGLE_DTMF_NS "urn:xmpp:tmp:jingle:dtmf"
 
 #define GOOGLE_NS "http://www.google.com/session"
+#define GOOGLE_AUDIO_NS "http://www.google.com/session/phone"
+#define GOOGLE_VIDEO_NS "http://www.google.com/session/video"
+#define GOOGLE_TRANSPORT_NS "http://www.google.com/transport/p2p"
 
 #define JINGLE_SID "sid"
 #define GOOGLE_SID "id"

Modified: team/phsultan/gmail-voice-video/res/res_jabber.c
URL: http://svn.digium.com/view/asterisk/team/phsultan/gmail-voice-video/res/res_jabber.c?view=diff&rev=167175&r1=167174&r2=167175
==============================================================================
--- team/phsultan/gmail-voice-video/res/res_jabber.c (original)
+++ team/phsultan/gmail-voice-video/res/res_jabber.c Mon Jan  5 09:03:03 2009
@@ -210,7 +210,7 @@
  * \param pak struct The XML stanza we're processing
  * \return a pointer to the added or found aji_version structure
  */ 
-static struct aji_version *aji_find_version(char *node, char *version, ikspak *pak)
+static struct aji_version *aji_find_version(char *node, char *version, char *ext, ikspak *pak)
 {
 	struct aji_capabilities *list = NULL;
 	struct aji_version *res = NULL;
@@ -225,8 +225,9 @@
 		if(!strcasecmp(list->node, node)) {
 			res = list->versions;
 			while(res) {
-				 if(!strcasecmp(res->version, version))
+				 if(!strcasecmp(res->version, version)) {
 					 return res;
+				 }
 				 res = res->next;
 			}
 			/* Specified version not found. Let's add it to 
@@ -240,6 +241,7 @@
 				res->jingle = 0;
 				res->parent = list;
 				ast_copy_string(res->version, version, sizeof(res->version));
+				ast_copy_string(res->ext, ext ? ext : "none", sizeof(res->ext));
 				res->next = list->versions;
 				list->versions = res;
 				return res;
@@ -262,6 +264,7 @@
 		}
 		ast_copy_string(list->node, node, sizeof(list->node));
 		ast_copy_string(res->version, version, sizeof(res->version));
+		ast_copy_string(res->ext, ext ? ext : "none", sizeof(res->ext));
 		res->jingle = 0;
 		res->parent = list;
 		res->next = NULL;
@@ -299,8 +302,13 @@
 */
 static int gtalk_yuck(iks *node)
 {
-	if (iks_find_with_attrib(node, "c", "node", "http://www.google.com/xmpp/client/caps"))
+	if (iks_find_with_attrib(node, "c", "node", "http://www.google.com/xmpp/client/caps")) {
+		ast_debug(1, "Found resource with Googletalk voice capabilities\n");
 		return 1;
+	} else if (iks_find_with_attrib(node, "caps:c", "ext", "pmuc-v1 sms-v1 camera-v1 video-v1 voice-v1")) {
+		ast_debug(1, "Found resource with Gmail voice/video chat capabilities\n");
+		return 1;
+	}
 	return 0;
 }
 
@@ -872,6 +880,21 @@
 	}
 
 	pak = iks_packet(node);
+	/* work around iksemel's impossibility to recognize node names
+	 * containing a semicolon. Set the namespace of the corresponding
+	 * node accordingly. */
+	if (iks_has_children(node) && strchr(iks_name(iks_child(node)), ':')) {
+		char *node_ns = NULL;
+		char attr[AJI_MAX_ATTRLEN];
+		char *node_name = iks_name(iks_child(node));
+		char *aux = strchr(node_name, ':') + 1;
+		snprintf(attr, strlen("xmlns:") + aux - node_name, "xmlns:%s", node_name);
+		node_ns = iks_find_attrib(iks_child(node), attr);
+		if (node_ns) {
+			pak->ns = node_ns;
+			pak->query = iks_child(node);
+		}
+	}
 
 	if (!client->component) { /*client */
 		switch (type) {
@@ -1519,7 +1542,8 @@
 	struct aji_buddy *buddy;
 	struct aji_resource *tmp = NULL, *last = NULL, *found = NULL;
 	char *ver, *node, *descrip, *type;
-	
+	char *ext = NULL;
+
 	if(client->state != AJI_CONNECTED)
 		aji_create_buddy(pak->from->partial, client);
 
@@ -1655,19 +1679,22 @@
 
 	node = iks_find_attrib(iks_find(pak->x, "c"), "node");
 	ver = iks_find_attrib(iks_find(pak->x, "c"), "ver");
+	ext = iks_find_attrib(iks_find(pak->x, "c"), "ext");
 
 	/* handle gmail client's special caps:c tag */
-	if (!node && !ver) {
+	if (!node && !ver && !ext) {
 		node = iks_find_attrib(iks_find(pak->x, "caps:c"), "node");
 		ver = iks_find_attrib(iks_find(pak->x, "caps:c"), "ver");
+		ext = iks_find_attrib(iks_find(pak->x, "caps:c"), "ext");
 	}
 
 	/* retrieve capabilites of the new resource */
 	if(status !=6 && found && !found->cap) {
-		found->cap = aji_find_version(node, ver, pak);
-		if(gtalk_yuck(pak->x)) /* gtalk should do discover */
+		found->cap = aji_find_version(node, ver, ext, pak);
+		if(gtalk_yuck(pak->x)) {/* gtalk should do discover */
 			found->cap->jingle = 1;
-		if(found->cap->jingle && option_debug > 4) {
+		}
+		if(found->cap->jingle) {
 			ast_debug(1,"Special case for google till they support discover.\n");
 		}
 		else {
@@ -2323,7 +2350,7 @@
 	iks *presence = iks_make_pres(level, desc);
 	iks *cnode = iks_new("c");
 	iks *priority = iks_new("priority");
-	char priorityS[10];
+	char priorityS[AJI_MAX_ATTRLEN];
 
 	if (presence && cnode && client && priority) {
 		if(to)
@@ -2335,8 +2362,10 @@
 		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, "xmlns", "http://jabber.org/protocol/caps");
+		if (ast_module_check("chan_gtalk.so") || ast_module_check("chan_gtalk")) {
+			iks_insert_attrib(cnode, "ext", "camera-v1 video-v1 voice-v1");
+		}
+			iks_insert_attrib(cnode, "xmlns", "http://jabber.org/protocol/caps");
 		iks_insert_node(presence, cnode);
 		res = ast_aji_send(client, presence);
 	} else




More information about the asterisk-commits mailing list