telepathygabble/src/jingle-info.c
changeset 10 59927b2d3b75
parent 0 d0f3a028347a
equal deleted inserted replaced
0:d0f3a028347a 10:59927b2d3b75
     1 /*
       
     2  * jingle-info.c - Source for Jingle info discovery
       
     3  * Copyright (C) 2006 Collabora Ltd.
       
     4  * Portions  and/or its subsidiary/subsidiaries.All rights reserved.
       
     5  *   @author Ole Andre Vadla Ravnaas <ole.andre.ravnaas@collabora.co.uk>
       
     6  *
       
     7  * This library is free software; you can redistribute it and/or
       
     8  * modify it under the terms of the GNU Lesser General Public
       
     9  * License as published by the Free Software Foundation; either
       
    10  * version 2.1 of the License, or (at your option) any later version.
       
    11  *
       
    12  * This library is distributed in the hope that it will be useful,
       
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
       
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
       
    15  * Lesser General Public License for more details.
       
    16  *
       
    17  * You should have received a copy of the GNU Lesser General Public
       
    18  * License along with this library; if not, write to the Free Software
       
    19  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
       
    20  */
       
    21 
       
    22 #include <string.h>
       
    23 #include <stdlib.h>
       
    24 
       
    25 #define DEBUG_FLAG GABBLE_DEBUG_MEDIA
       
    26 
       
    27 #include "debug.h"
       
    28 #include "jingle-info.h"
       
    29 #include "gabble-error.h"
       
    30 #include "namespaces.h"
       
    31 #include "util.h"
       
    32 
       
    33 #ifdef DEBUG_FLAG
       
    34 //#define DEBUG(format, ...)
       
    35 #define DEBUGGING 0
       
    36 #define NODE_DEBUG(n, s)
       
    37 #endif /* DEBUG_FLAG */
       
    38 
       
    39 /**
       
    40  * jingle_info_discover_servers:
       
    41  *
       
    42  * Discover available Jingle servers.
       
    43  *
       
    44  * @conn: The GabbleConnection# object initiating the discovery.
       
    45  */
       
    46 void
       
    47 jingle_info_discover_servers (GabbleConnection *conn)
       
    48 {
       
    49   LmMessage *msg = NULL;
       
    50   LmMessageNode *node;
       
    51   GError *error = NULL;
       
    52   GabbleHandle handle = conn->self_handle;
       
    53   const gchar *jid = gabble_handle_inspect (conn->handles, TP_HANDLE_TYPE_CONTACT, handle);
       
    54 
       
    55   msg = lm_message_new_with_sub_type (jid, LM_MESSAGE_TYPE_IQ,
       
    56                                       LM_MESSAGE_SUB_TYPE_GET);
       
    57 
       
    58   node = lm_message_node_add_child (msg->node, "query", NULL);
       
    59   lm_message_node_set_attribute (node, "xmlns", NS_GOOGLE_JINGLE_INFO);
       
    60 
       
    61   if (!_gabble_connection_send (conn, msg, &error))
       
    62     {
       
    63       g_warning ("%s: send failed: %s\n", G_STRFUNC, error->message);
       
    64       goto OUT;
       
    65     }
       
    66 
       
    67 OUT:
       
    68   if (msg)
       
    69     lm_message_unref (msg);
       
    70 
       
    71   if (error)
       
    72     g_error_free (error);
       
    73 }
       
    74 
       
    75 
       
    76 /**
       
    77  * jingle_info_iq_callback
       
    78  *
       
    79  * Called by loudmouth when we get an incoming <iq>. This handler
       
    80  * is concerned only with Jingle info queries.
       
    81  */
       
    82 LmHandlerResult
       
    83 jingle_info_iq_callback (LmMessageHandler *handler,
       
    84                          LmConnection *lmconn,
       
    85                          LmMessage *message,
       
    86                          gpointer user_data)
       
    87 {
       
    88   GabbleConnection *conn = GABBLE_CONNECTION (user_data);
       
    89   LmMessageSubType sub_type;
       
    90   LmMessageNode *query_node, *parent_node, *node;
       
    91   const gchar *str;
       
    92   guint port;
       
    93 
       
    94   if ( NULL == conn )
       
    95         {
       
    96         g_debug ("%s: accesing after dereferenced connection", G_STRFUNC);
       
    97         return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
       
    98         }
       
    99   
       
   100   query_node = lm_message_node_get_child_with_namespace (message->node,
       
   101       "query", NS_GOOGLE_JINGLE_INFO);
       
   102 
       
   103   if (query_node == NULL)
       
   104     return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
       
   105 
       
   106   NODE_DEBUG (message->node, "got");
       
   107 
       
   108   sub_type = lm_message_get_sub_type (message);
       
   109 
       
   110   if (sub_type == LM_MESSAGE_SUB_TYPE_RESULT ||
       
   111       sub_type == LM_MESSAGE_SUB_TYPE_SET)
       
   112     {
       
   113       parent_node = lm_message_node_get_child (query_node, "stun");
       
   114       if (parent_node)
       
   115         {
       
   116           for (node = parent_node->children; node; node = node->next)
       
   117             {
       
   118               if (strcmp (node->name, "server") == 0)
       
   119                 {
       
   120                   str = lm_message_node_get_attribute (node, "host");
       
   121                   if (str)
       
   122                     {
       
   123                       gabble_debug (DEBUG_FLAG, "setting 'stun-server' to '%s'", str);
       
   124 
       
   125                       g_object_set (conn, "stun-server", str, NULL);
       
   126                     }
       
   127 
       
   128                   str = lm_message_node_get_attribute (node, "udp");
       
   129                   if (str)
       
   130                     {
       
   131                       port = atoi (str);
       
   132 
       
   133                       gabble_debug (DEBUG_FLAG, "setting 'stun-port' to %d", port);
       
   134 
       
   135                       g_object_set (conn, "stun-port", port, NULL);
       
   136                     }
       
   137 
       
   138                   /* only grab the first one for now */
       
   139                   break;
       
   140                 }
       
   141             }
       
   142         }
       
   143 
       
   144       parent_node = lm_message_node_get_child (query_node, "relay");
       
   145       if (parent_node)
       
   146         {
       
   147           gboolean found_server = FALSE;
       
   148 
       
   149           for (node = parent_node->children; node; node = node->next)
       
   150             {
       
   151               if (!found_server && strcmp (node->name, "server") == 0)
       
   152                 {
       
   153                   str = lm_message_node_get_attribute (node, "host");
       
   154                   if (str)
       
   155                     {
       
   156                       gabble_debug (DEBUG_FLAG, "setting 'stun-relay-server' to '%s'",
       
   157                                str);
       
   158 
       
   159                       g_object_set (conn, "stun-relay-server", str, NULL);
       
   160                     }
       
   161 
       
   162                   str = lm_message_node_get_attribute (node, "udp");
       
   163                   if (str)
       
   164                     {
       
   165                       port = atoi (str);
       
   166 
       
   167                       gabble_debug (DEBUG_FLAG, "setting 'stun-relay-udp-port' to %d",
       
   168                                port);
       
   169 
       
   170                       g_object_set (conn, "stun-relay-udp-port", port, NULL);
       
   171                     }
       
   172 
       
   173                   str = lm_message_node_get_attribute (node, "tcp");
       
   174                   if (str)
       
   175                     {
       
   176                       port = atoi (str);
       
   177 
       
   178                       gabble_debug (DEBUG_FLAG, "setting 'stun-relay-tcp-port' to %d",
       
   179                                port);
       
   180 
       
   181                       g_object_set (conn, "stun-relay-tcp-port", port, NULL);
       
   182                     }
       
   183 
       
   184                   str = lm_message_node_get_attribute (node, "tcpssl");
       
   185                   if (str)
       
   186                     {
       
   187                       port = atoi (str);
       
   188 
       
   189                       gabble_debug (DEBUG_FLAG, "setting 'stun-relay-ssltcp-port' to %d",
       
   190                                port);
       
   191 
       
   192                       g_object_set (conn, "stun-relay-ssltcp-port", port, NULL);
       
   193                     }
       
   194 
       
   195                   found_server = TRUE;
       
   196                 }
       
   197               else if (strcmp (node->name, "token") == 0)
       
   198                 {
       
   199                   str = lm_message_node_get_value (node);
       
   200                   if (str)
       
   201                     {
       
   202                       gabble_debug (DEBUG_FLAG, "setting 'stun-relay-magic-cookie' to '%s'",
       
   203                                str);
       
   204 
       
   205                       g_object_set (conn, "stun-relay-magic-cookie", str, NULL);
       
   206                     }
       
   207                 }
       
   208             }
       
   209         }
       
   210 
       
   211       if (sub_type == LM_MESSAGE_SUB_TYPE_SET)
       
   212         {
       
   213           _gabble_connection_acknowledge_set_iq (conn, message);
       
   214         }
       
   215     }
       
   216   else if (sub_type == LM_MESSAGE_SUB_TYPE_ERROR)
       
   217     {
       
   218       GabbleXmppError xmpp_error = INVALID_XMPP_ERROR;
       
   219 
       
   220       node = lm_message_node_get_child (message->node, "error");
       
   221       if (node)
       
   222         {
       
   223           xmpp_error = gabble_xmpp_error_from_node (node);
       
   224         }
       
   225 
       
   226       str = gabble_xmpp_error_string (xmpp_error);
       
   227 
       
   228       g_warning ("%s: jingle info error: %s", G_STRFUNC,
       
   229           (str) ? str : "unknown error");
       
   230     }
       
   231   else
       
   232     {
       
   233       NODE_DEBUG (message->node, "unknown message sub type");
       
   234     }
       
   235 
       
   236   return LM_HANDLER_RESULT_REMOVE_MESSAGE;
       
   237 }
       
   238