diff -r 000000000000 -r d0f3a028347a telepathygabble/src/jingle-info.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/telepathygabble/src/jingle-info.c Tue Feb 02 01:10:06 2010 +0200 @@ -0,0 +1,238 @@ +/* + * jingle-info.c - Source for Jingle info discovery + * Copyright (C) 2006 Collabora Ltd. + * Portions and/or its subsidiary/subsidiaries.All rights reserved. + * @author Ole Andre Vadla Ravnaas + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +#define DEBUG_FLAG GABBLE_DEBUG_MEDIA + +#include "debug.h" +#include "jingle-info.h" +#include "gabble-error.h" +#include "namespaces.h" +#include "util.h" + +#ifdef DEBUG_FLAG +//#define DEBUG(format, ...) +#define DEBUGGING 0 +#define NODE_DEBUG(n, s) +#endif /* DEBUG_FLAG */ + +/** + * jingle_info_discover_servers: + * + * Discover available Jingle servers. + * + * @conn: The GabbleConnection# object initiating the discovery. + */ +void +jingle_info_discover_servers (GabbleConnection *conn) +{ + LmMessage *msg = NULL; + LmMessageNode *node; + GError *error = NULL; + GabbleHandle handle = conn->self_handle; + const gchar *jid = gabble_handle_inspect (conn->handles, TP_HANDLE_TYPE_CONTACT, handle); + + msg = lm_message_new_with_sub_type (jid, LM_MESSAGE_TYPE_IQ, + LM_MESSAGE_SUB_TYPE_GET); + + node = lm_message_node_add_child (msg->node, "query", NULL); + lm_message_node_set_attribute (node, "xmlns", NS_GOOGLE_JINGLE_INFO); + + if (!_gabble_connection_send (conn, msg, &error)) + { + g_warning ("%s: send failed: %s\n", G_STRFUNC, error->message); + goto OUT; + } + +OUT: + if (msg) + lm_message_unref (msg); + + if (error) + g_error_free (error); +} + + +/** + * jingle_info_iq_callback + * + * Called by loudmouth when we get an incoming . This handler + * is concerned only with Jingle info queries. + */ +LmHandlerResult +jingle_info_iq_callback (LmMessageHandler *handler, + LmConnection *lmconn, + LmMessage *message, + gpointer user_data) +{ + GabbleConnection *conn = GABBLE_CONNECTION (user_data); + LmMessageSubType sub_type; + LmMessageNode *query_node, *parent_node, *node; + const gchar *str; + guint port; + + if ( NULL == conn ) + { + g_debug ("%s: accesing after dereferenced connection", G_STRFUNC); + return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; + } + + query_node = lm_message_node_get_child_with_namespace (message->node, + "query", NS_GOOGLE_JINGLE_INFO); + + if (query_node == NULL) + return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS; + + NODE_DEBUG (message->node, "got"); + + sub_type = lm_message_get_sub_type (message); + + if (sub_type == LM_MESSAGE_SUB_TYPE_RESULT || + sub_type == LM_MESSAGE_SUB_TYPE_SET) + { + parent_node = lm_message_node_get_child (query_node, "stun"); + if (parent_node) + { + for (node = parent_node->children; node; node = node->next) + { + if (strcmp (node->name, "server") == 0) + { + str = lm_message_node_get_attribute (node, "host"); + if (str) + { + gabble_debug (DEBUG_FLAG, "setting 'stun-server' to '%s'", str); + + g_object_set (conn, "stun-server", str, NULL); + } + + str = lm_message_node_get_attribute (node, "udp"); + if (str) + { + port = atoi (str); + + gabble_debug (DEBUG_FLAG, "setting 'stun-port' to %d", port); + + g_object_set (conn, "stun-port", port, NULL); + } + + /* only grab the first one for now */ + break; + } + } + } + + parent_node = lm_message_node_get_child (query_node, "relay"); + if (parent_node) + { + gboolean found_server = FALSE; + + for (node = parent_node->children; node; node = node->next) + { + if (!found_server && strcmp (node->name, "server") == 0) + { + str = lm_message_node_get_attribute (node, "host"); + if (str) + { + gabble_debug (DEBUG_FLAG, "setting 'stun-relay-server' to '%s'", + str); + + g_object_set (conn, "stun-relay-server", str, NULL); + } + + str = lm_message_node_get_attribute (node, "udp"); + if (str) + { + port = atoi (str); + + gabble_debug (DEBUG_FLAG, "setting 'stun-relay-udp-port' to %d", + port); + + g_object_set (conn, "stun-relay-udp-port", port, NULL); + } + + str = lm_message_node_get_attribute (node, "tcp"); + if (str) + { + port = atoi (str); + + gabble_debug (DEBUG_FLAG, "setting 'stun-relay-tcp-port' to %d", + port); + + g_object_set (conn, "stun-relay-tcp-port", port, NULL); + } + + str = lm_message_node_get_attribute (node, "tcpssl"); + if (str) + { + port = atoi (str); + + gabble_debug (DEBUG_FLAG, "setting 'stun-relay-ssltcp-port' to %d", + port); + + g_object_set (conn, "stun-relay-ssltcp-port", port, NULL); + } + + found_server = TRUE; + } + else if (strcmp (node->name, "token") == 0) + { + str = lm_message_node_get_value (node); + if (str) + { + gabble_debug (DEBUG_FLAG, "setting 'stun-relay-magic-cookie' to '%s'", + str); + + g_object_set (conn, "stun-relay-magic-cookie", str, NULL); + } + } + } + } + + if (sub_type == LM_MESSAGE_SUB_TYPE_SET) + { + _gabble_connection_acknowledge_set_iq (conn, message); + } + } + else if (sub_type == LM_MESSAGE_SUB_TYPE_ERROR) + { + GabbleXmppError xmpp_error = INVALID_XMPP_ERROR; + + node = lm_message_node_get_child (message->node, "error"); + if (node) + { + xmpp_error = gabble_xmpp_error_from_node (node); + } + + str = gabble_xmpp_error_string (xmpp_error); + + g_warning ("%s: jingle info error: %s", G_STRFUNC, + (str) ? str : "unknown error"); + } + else + { + NODE_DEBUG (message->node, "unknown message sub type"); + } + + return LM_HANDLER_RESULT_REMOVE_MESSAGE; +} +