telepathygabble/src/search-keys-info.c
changeset 10 59927b2d3b75
parent 0 d0f3a028347a
equal deleted inserted replaced
0:d0f3a028347a 10:59927b2d3b75
     1 /*
       
     2  * search-keys-info.c - Source for Jingle info discovery
       
     3  * Copyright (C) 2008 Collabora Ltd.
       
     4  *  and/or its 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 "search-keys-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  * get_search_keys_info:
       
    41  *
       
    42  * get search keys 
       
    43  *
       
    44  */
       
    45 void
       
    46 get_search_keys_info (GabbleConnection *conn,  const gchar *jid )
       
    47 {
       
    48   LmMessage *msg;
       
    49   LmMessageNode *query_node;
       
    50   gboolean result;
       
    51   gchar *service = NULL;
       
    52   GError *error = NULL;
       
    53 
       
    54   conn->search_service_jid = g_strdup( jid );
       
    55   
       
    56   msg= lm_message_new_with_sub_type ( jid,
       
    57                                       LM_MESSAGE_TYPE_IQ,
       
    58                                       LM_MESSAGE_SUB_TYPE_GET);
       
    59   query_node = lm_message_node_add_child (msg->node, "query", NULL);
       
    60   
       
    61   lm_message_node_set_attribute (query_node, "xmlns", NS_SEARCH);
       
    62 
       
    63   if (!_gabble_connection_send (conn, msg, &error))
       
    64     {
       
    65       g_warning ("%s: send failed: %s\n", G_STRFUNC, error->message);
       
    66       goto OUT;
       
    67     }
       
    68 
       
    69 OUT:
       
    70   if (msg)
       
    71     lm_message_unref (msg);
       
    72 
       
    73   if (error)
       
    74     g_error_free (error);
       
    75  
       
    76 }
       
    77 
       
    78 
       
    79 /**
       
    80  * _gabble_submit_search_form:
       
    81  *
       
    82  * Submit search form 
       
    83  *
       
    84  */
       
    85 gboolean
       
    86 _gabble_submit_search_form (GabbleConnection *conn)
       
    87 {
       
    88   LmMessage *msg;
       
    89   LmMessageNode *query_node;
       
    90   LmMessageNode *x_node;
       
    91   LmMessageNode *field_node, *value_node;
       
    92   gboolean result;
       
    93   const gchar *jid;
       
    94   gchar *service = NULL;
       
    95   GError **error = NULL;
       
    96 
       
    97   g_message("_gabble_submit_search_form\n");
       
    98   jid = gabble_handle_inspect (conn->handles, TP_HANDLE_TYPE_CONTACT, conn->self_handle);
       
    99   g_message("jid is %s\n",jid);
       
   100   gabble_decode_jid(jid, NULL /*username*/,&service,NULL/*resource*/);
       
   101   g_message("service is %s\n",service);
       
   102   
       
   103   msg= lm_message_new_with_sub_type ( service,
       
   104                                       LM_MESSAGE_TYPE_IQ,
       
   105                                       LM_MESSAGE_SUB_TYPE_SET);
       
   106   query_node = lm_message_node_add_child (msg->node, "query", NULL);
       
   107   
       
   108   lm_message_node_set_attribute (query_node, "xmlns", NS_SEARCH);
       
   109   
       
   110   x_node = lm_message_node_add_child ( query_node, "x", NULL );
       
   111   
       
   112   lm_message_node_set_attributes (x_node,
       
   113                                   "xmlns", NS_X_DATA,
       
   114                                   "type", "submit",
       
   115                                   NULL);
       
   116                                   
       
   117   field_node = lm_message_node_add_child ( x_node, "x", NULL );
       
   118   
       
   119   lm_message_node_set_attributes (x_node,
       
   120                                   "type", "hidden",
       
   121                                   "var", "FORM_TYPE",
       
   122                                   NULL); 
       
   123                                   
       
   124   value_node = lm_message_node_get_child(field_node, "value");
       
   125   lm_message_node_set_value(value_node,"NS_SEARCH");   
       
   126   
       
   127   g_message("_gabble_submit_search_form b4 _gabble_connection_send\n");                                                                
       
   128   
       
   129   result = _gabble_connection_send (conn, msg, error);
       
   130   lm_message_unref (msg);
       
   131 
       
   132   if (!result)
       
   133     return FALSE;
       
   134   
       
   135   return TRUE;
       
   136 }
       
   137 
       
   138 
       
   139 /**
       
   140  * search_keys_iq_cb
       
   141  *
       
   142  * Called by loudmouth when we get an incoming <iq>. This handler
       
   143  * is concerned only with Requesting Search Keys info queries.
       
   144  */
       
   145 LmHandlerResult
       
   146 search_keys_iq_cb (LmMessageHandler *handler,
       
   147                          LmConnection *lmconn,
       
   148                          LmMessage *message,
       
   149                          gpointer user_data)
       
   150 {
       
   151   GabbleConnection *conn = GABBLE_CONNECTION (user_data);
       
   152   
       
   153   LmMessageSubType sub_type;
       
   154   LmMessageNode *query_node, *x_node, *result_node,*x_item_node;
       
   155   const gchar *str;
       
   156   const gchar *type, *field_label,*field_var, *field_type;
       
   157   guint  i = 0;
       
   158   
       
   159   if ( NULL == conn )
       
   160         {
       
   161         g_debug ("%s: accesing after dereferenced connection", G_STRFUNC);
       
   162         return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
       
   163         }
       
   164   
       
   165   query_node = lm_message_node_get_child_with_namespace (message->node,
       
   166       "query", NS_SEARCH);
       
   167 
       
   168   if (query_node == NULL)
       
   169     return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
       
   170 
       
   171   sub_type = lm_message_get_sub_type (message);
       
   172   
       
   173   if (sub_type != LM_MESSAGE_SUB_TYPE_RESULT)
       
   174     {
       
   175       return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
       
   176     }
       
   177 
       
   178   if (sub_type == LM_MESSAGE_SUB_TYPE_RESULT)
       
   179   {
       
   180 	  x_node = lm_message_node_get_child_with_namespace (query_node, "x", NS_X_DATA);
       
   181 	  
       
   182 	  if( x_node )
       
   183 			{
       
   184 			    //if service supports data forms 
       
   185 		    	result_node = x_node; 
       
   186 				type   = lm_message_node_get_attribute (x_node, "type" );
       
   187 				  
       
   188 		       if (0 == strcmp (type, "form"))
       
   189 		          {
       
   190 		          gint filed_count = 0;
       
   191 		          
       
   192 		          for (x_item_node = result_node->children; x_item_node; x_item_node = x_item_node->next)
       
   193                       {
       
   194                       if( 0 == strcmp (x_item_node->name, "field") )
       
   195                           {
       
   196                           filed_count++;
       
   197                           }
       
   198                       }
       
   199 		          
       
   200 		          if(conn->search_key_names == NULL)
       
   201                         {
       
   202                           conn->search_key_names = (gchar**)g_new0( gchar*, filed_count);
       
   203                         }
       
   204                     
       
   205                   if(conn->search_key_ht == NULL)
       
   206                         {
       
   207                           conn->search_key_ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, g_free);
       
   208                         }
       
   209 
       
   210 		            conn->search_form = TRUE;
       
   211 		            for (x_item_node = result_node->children; x_item_node; x_item_node = x_item_node->next)
       
   212 		            {
       
   213 		                
       
   214 		                 // "reported" should also be used to get the types of search result fields
       
   215 		                 //'g' type currently not supported by dbus-glib-binding
       
   216 		                 if (0 != strcmp (x_item_node->name, "field") 
       
   217 		                        && 0 != strcmp (x_item_node->name, "instructions"))
       
   218 		                    continue;
       
   219 		                    
       
   220 		                
       
   221 		                 if( 0 == strcmp (x_item_node->name, "instructions") )
       
   222 		                     {
       
   223 		                        //get the instructions
       
   224 		                        g_message("get the instuction\n");
       
   225 		                        conn->search_instr = g_strdup( lm_message_node_get_value(x_item_node) );    
       
   226 		                        g_message("after gettting the instuction\n");
       
   227 		                        continue;
       
   228 		                     }
       
   229 		                     
       
   230 		                 if( 0 == strcmp (x_item_node->name, "field") )
       
   231 		                    {
       
   232 		                        //node is a field node
       
   233 		                        //get the name of each field
       
   234 		                        //type also ..later
       
   235 		                        field_type = lm_message_node_get_attribute(x_item_node, "type");
       
   236 		                        if( 0 == strcmp (field_type, "hidden") )
       
   237 		                            {
       
   238 		                            //see later if this must be sent while sending request to the server
       
   239 		                            continue;   
       
   240 		                            }
       
   241 		                       //get the "type" of the attr as well along with "var"
       
   242 		                       //to send it to the client later 
       
   243 		                       //dbus-glib-binding tool support 'g' type 
       
   244 		                       field_label = lm_message_node_get_attribute(x_item_node, "label");
       
   245 		                      
       
   246 		                       g_message("b4 gettting the search_key_names\n");
       
   247 		                       conn->search_key_names[i] = g_strdup(field_label);
       
   248 		                       g_message("after gettting the search_key_names\n");
       
   249 		                       g_message("%s\n",conn->search_key_names[i]);
       
   250 		                       field_var = lm_message_node_get_attribute(x_item_node, "var");
       
   251 		                       g_hash_table_insert(conn->search_key_ht,g_strdup(field_label),g_strdup(field_var));
       
   252 		                       i++;                    
       
   253 		                       
       
   254 		                    }
       
   255 		               }
       
   256 		               
       
   257 		            conn->search_key_names[i] = NULL;
       
   258 		            // this should be done when we need to give the 
       
   259 		            // search result attributes in advance to the client
       
   260 		            // and if we are able to give the type also     
       
   261 		            
       
   262 		        
       
   263 		          }
       
   264 		        
       
   265 			}
       
   266 	   else
       
   267 	       {
       
   268 	       return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
       
   269 	       }
       
   270 	    
       
   271 	   return LM_HANDLER_RESULT_REMOVE_MESSAGE;
       
   272 		  
       
   273       }
       
   274 
       
   275    else if (sub_type == LM_MESSAGE_SUB_TYPE_ERROR)
       
   276     {
       
   277       GabbleXmppError xmpp_error = INVALID_XMPP_ERROR;
       
   278 
       
   279       result_node = lm_message_node_get_child (message->node, "error");
       
   280       if (result_node)
       
   281         {
       
   282           xmpp_error = gabble_xmpp_error_from_node (result_node);
       
   283         }
       
   284 
       
   285       str = gabble_xmpp_error_string (xmpp_error);
       
   286 
       
   287       g_warning ("%s: jingle info error: %s", G_STRFUNC,
       
   288           (str) ? str : "unknown error");
       
   289     }
       
   290   else
       
   291     {
       
   292       NODE_DEBUG (message->node, "unknown message sub type");
       
   293     }
       
   294 
       
   295   return LM_HANDLER_RESULT_ALLOW_MORE_HANDLERS;
       
   296 }
       
   297 
       
   298