isolationserver/isoserver/src/isosearch.c
changeset 10 59927b2d3b75
parent 0 d0f3a028347a
equal deleted inserted replaced
0:d0f3a028347a 10:59927b2d3b75
     1 /*
       
     2 * ============================================================================
       
     3 *  Name        : isosearch.c
       
     4 *  Part of     : isolation server.
       
     5 *  Version     : %version: 17 %
       
     6 *
       
     7 *  Copyright © 2007-2008 Nokia.  All rights reserved.
       
     8 *  Redistribution and use in source and binary forms, with or without modification, 
       
     9 *  are permitted provided that the following conditions are met:
       
    10 *  Redistributions of source code must retain the above copyright notice, this list 
       
    11 *  of conditions and the following disclaimer.Redistributions in binary form must 
       
    12 *  reproduce the above copyright notice, this list of conditions and the following 
       
    13 *  disclaimer in the documentation and/or other materials provided with the distribution.
       
    14 *  Neither the name of the Nokia Corporation nor the names of its contributors may be used 
       
    15 *  to endorse or promote products derived from this software without specific prior written 
       
    16 *  permission.
       
    17 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
       
    18 *  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
       
    19 *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
       
    20 *  SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
       
    21 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
       
    22 *  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
       
    23 *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
       
    24 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
       
    25 *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    26 * ============================================================================
       
    27 * Template version: 1.0
       
    28 */
       
    29 
       
    30 /*!	\file 
       
    31 *	Impliments the functions in isosearch.h
       
    32 */
       
    33 
       
    34 /*! \def For malloc
       
    35 */
       
    36 #include <stdlib.h>
       
    37 
       
    38 /*! \def For string operations
       
    39 */
       
    40 #include <string.h>
       
    41 
       
    42 /*! \def For GHashTable
       
    43 */
       
    44 #include <glib/ghash.h>
       
    45 
       
    46 /*! \def For search related declarations
       
    47 */
       
    48 #include "isosearch.h"
       
    49 
       
    50 /*! \def For globalCon
       
    51 */
       
    52 #include "isoservermain.h"
       
    53 
       
    54 /*! \def For tp_chan_type_search_async
       
    55 */
       
    56 #include "tp-chan-type-search-gen.h"
       
    57 
       
    58 /*! \def For MSG_PRI_NORMAL
       
    59 */
       
    60 #include "msgqlib.h"
       
    61 
       
    62 /*! \def For message_hdr_req
       
    63 */
       
    64 #include "isoutils.h"
       
    65 
       
    66 /*! \def For RESPONSE_QUEUE
       
    67 */
       
    68 #include "msgliterals.h"
       
    69 
       
    70 /*!	\struct key_value_struct isoserach.h
       
    71 *	\brief This struct is used for to form the msg buffer that will be sent to client
       
    72 *	\var msg As the key/value pairs are read those will be appended to msg
       
    73 * 	\var len is the no. of bytes appended to msg
       
    74 */
       
    75 struct key_value_struct 
       
    76 	{
       
    77 	gchar* msg;
       
    78 	gint len;		
       
    79 	};
       
    80 	
       
    81 /*! \typedef struct key_value_struct to key_value_struct
       
    82 * 
       
    83 */	
       
    84 typedef struct key_value_struct key_value_struct;
       
    85 
       
    86 
       
    87 static void search_result_received_cb ( DBusGProxy	*proxy,
       
    88 									guint       contact_handle,
       
    89 									GHashTable	*values, 
       
    90 									gpointer	user_data
       
    91 								   );
       
    92 								   
       
    93 static void search_state_changed_cb ( DBusGProxy	*proxy,
       
    94 										guint       search_state,
       
    95 										gpointer	user_data
       
    96 									   );
       
    97 									   
       
    98 static void searchreply_cb( DBusGProxy *proxy, GError *error, gpointer userdata );
       
    99 
       
   100 
       
   101 static void do_search_again( GHashTable* search_hash );
       
   102 
       
   103 		
       
   104                       
       
   105 /*! \brief This function called by action_parse_search parses rmsg and 
       
   106 *	validates the arguments(key/value pairs). If value for any key found missing
       
   107 *	returns INVALID_PARAMETERES
       
   108 *
       
   109 *	\param rmsg Message which is parsed
       
   110 *	\param rmsg_len message len 
       
   111 *	\param search_hash parsed key/value pairs are filled into this hash table
       
   112 *
       
   113 *	\return error if any else 0
       
   114 */
       
   115 gint parse_for_search( gchar* rmsg, gint rmsg_len, GHashTable* search_hash )
       
   116 	{
       
   117 	gint pointer_nav = 0;
       
   118 	gchar* value_str = NULL;
       
   119 	gchar* key_str = NULL;
       
   120 	gint err = 0;
       
   121 	GValue *value = NULL; 
       
   122 	
       
   123 	iso_logger( "in parse_for_search");
       
   124 	//Skip the header field
       
   125 	pointer_nav += sizeof( message_hdr_req );
       
   126 	
       
   127 	while ( '\0' != *( rmsg + pointer_nav ) && pointer_nav < rmsg_len ) 
       
   128 		{
       
   129 		//Copy the key
       
   130 		err = parse_a_string( rmsg, &key_str, &pointer_nav, rmsg_len );
       
   131 		if ( err < 0 ) 
       
   132 			{
       
   133 			//if error, return error
       
   134 			return err;
       
   135 			}
       
   136 		//End of message reached and no value found for
       
   137 		//corresponding key
       
   138 		if ( '\0' == *( rmsg + pointer_nav ) ) 
       
   139 			{
       
   140 			return INVALID_PARAMETERES;				
       
   141 			}
       
   142 		//Copy the value
       
   143 		err = parse_a_string( rmsg, &value_str, &pointer_nav, rmsg_len );
       
   144 		if ( err < 0 )
       
   145 			{
       
   146 			//if error, return error
       
   147 			return err;				
       
   148 			}
       
   149 			
       
   150 		value = g_new0( GValue, 1 );
       
   151 		g_value_init( value, G_TYPE_STRING );
       
   152 		g_value_set_string ( value, value_str );
       
   153 	
       
   154 	
       
   155 		//insert the key value pair into the hash table
       
   156 		g_hash_table_insert ( search_hash, key_str, value );						
       
   157 		}
       
   158 	iso_logger( "out parse_for_search");
       
   159 	return 0;			
       
   160 	}
       
   161 	
       
   162 /*!	\brief This function is called as a callback to search chan request
       
   163 *	This function creates a search channel and interface which are
       
   164 *	used for subsequent search requests. Logically this function is called 
       
   165 *	only once per login session.
       
   166 *	\remark Not creating a search channel each time is a workaround
       
   167 *
       
   168 *	\param proxy unused
       
   169 *	\param chan_object_path channel object path to create a new channel
       
   170 *	\param error if any
       
   171 *	\param user_data hash table entry(key/value pair)
       
   172 *
       
   173 *	\return void
       
   174 */
       
   175 
       
   176  void do_search_reply( DBusGProxy *proxy, char *chan_object_path, 
       
   177  			GError *error, gpointer user_data )
       
   178  {
       
   179  	GHashTable *search_hash = ( GHashTable* ) user_data;
       
   180  	TpChan *search_chan = NULL;
       
   181 	DBusGProxy *search_iface = NULL;
       
   182 	
       
   183 	
       
   184 	UNUSED_FORMAL_PARAM( proxy );
       
   185  
       
   186  	iso_logger( "in do_search_reply");
       
   187  	/* Create the object to represent the channel */
       
   188 	if ( error ) 
       
   189 		{
       
   190 		iso_logger( "Error in do_search_reply");
       
   191 		//There was an error.. send it to client
       
   192 		send_response_to_client( globalCon.search_hdr_req, error->code, 0 );
       
   193 		//Should error be returned to the client ?
       
   194 		return;
       
   195 		}
       
   196 	search_chan = tp_chan_new( globalCon.dbusConn, globalCon.connmgr_bus, chan_object_path, 
       
   197 	TP_IFACE_CHANNEL_TYPE_CONTACT_SEARCH, TP_CONN_HANDLE_TYPE_NONE, 0 );
       
   198 	                         
       
   199     globalCon.search_chan = search_chan;
       
   200 	                    
       
   201 	g_free(chan_object_path);
       
   202   
       
   203   
       
   204   	if ( NULL == search_chan ) 
       
   205 		{
       
   206 		iso_logger( "returning because of search_chan");
       
   207 		//search chan not created
       
   208 		//sending to client
       
   209 		send_response_to_client( globalCon.search_hdr_req, TP_SEARCH_CHAN_ERROR, 0 );
       
   210 		return ;	
       
   211 		}
       
   212 	//Get chan interface					
       
   213 	search_iface = tp_chan_get_interface( search_chan, 
       
   214 		TELEPATHY_CHAN_IFACE_CONTACTSEARCH_QUARK );	
       
   215 	
       
   216 	if ( NULL == search_iface ) 
       
   217 		{
       
   218 		iso_logger( "returning because of search_iface");
       
   219 		//interface for search chan not created 
       
   220 		//send that to client
       
   221 		send_response_to_client( globalCon.search_hdr_req, TP_SEARCH_IFACE_ERROR, 0 );
       
   222 		return ;	
       
   223 		}					
       
   224 	
       
   225 	//Register for the SearchResultReceived signal
       
   226 	//ownership of the srch_result->user_data is transfered
       
   227 	dbus_g_proxy_connect_signal( search_iface, "SearchResultReceived",
       
   228 							G_CALLBACK( search_result_received_cb ),
       
   229 							NULL, NULL );
       
   230 	
       
   231 	
       
   232 	//Register for the SearchStateChanged signal
       
   233 	dbus_g_proxy_connect_signal( search_iface, "SearchStateChanged",
       
   234 							G_CALLBACK( search_state_changed_cb ),
       
   235 							NULL , NULL );
       
   236 	//Call the search on tp		      										      
       
   237 	tp_chan_type_search_async( search_iface, search_hash , searchreply_cb, 
       
   238 								NULL );
       
   239 			
       
   240 	iso_logger( "out do_search_reply");			
       
   241 	
       
   242   
       
   243  }
       
   244 
       
   245 
       
   246 /*! \brief This function is called by action_parse_search to search for fields
       
   247 *	\remark This function routes the searches to do_search_again if searched more 
       
   248 *	than once. This is a workaround because we are getting the signal callbacks 
       
   249 *	'n'ths( where n is nth search ) time if search channel is created each time. 
       
   250 *
       
   251 *	\param search_hash Hash table having the search key and value pairs to be searched
       
   252 *
       
   253 *	\return void
       
   254 */
       
   255 
       
   256 gint do_search( GHashTable* search_hash ) 
       
   257 	{
       
   258 	
       
   259 	iso_logger( "in do_search");
       
   260 	
       
   261 	if(globalCon.search_chan == NULL)
       
   262 		{
       
   263 		tp_conn_request_channel_async( DBUS_G_PROXY( globalCon.conn ),
       
   264 	                               TP_IFACE_CHANNEL_TYPE_CONTACT_SEARCH, 
       
   265 	                               TP_CONN_HANDLE_TYPE_NONE, 0, TRUE,
       
   266 	                               do_search_reply, (gpointer)search_hash ) ;
       
   267 		}
       
   268 
       
   269 	else
       
   270 		{
       
   271 		 iso_logger( "calling do_search_again");
       
   272 		 do_search_again(search_hash);
       
   273 		}
       
   274 	iso_logger( "out do_search");
       
   275 	
       
   276 	return 0;		
       
   277 	}
       
   278 
       
   279 /*! \brief This function is called if search is done more than once in same login session. 
       
   280 *	\remark This is a workaround because we are getting the signal callbacks 
       
   281 *	'n'ths( where n is nth search ) time. 
       
   282 *
       
   283 *	\param search_hash Hash table having the search key and value pairs to be searched
       
   284 *
       
   285 *	\return void
       
   286 */
       
   287 void do_search_again( GHashTable* search_hash )
       
   288  {
       
   289  
       
   290 	DBusGProxy *search_iface = NULL;
       
   291 	
       
   292 	iso_logger( "in do_search_again");
       
   293  	
       
   294   	if ( NULL == globalCon.search_chan ) 
       
   295 		{
       
   296 		iso_logger( "returning because of search_chan");
       
   297 		//search chan not created
       
   298 		//sending to client
       
   299 		send_response_to_client( globalCon.search_hdr_req, TP_SEARCH_CHAN_ERROR, 0 );
       
   300 		return ;	
       
   301 		}
       
   302 	//Get chan interface					
       
   303 	search_iface = tp_chan_get_interface( globalCon.search_chan, 
       
   304 		TELEPATHY_CHAN_IFACE_CONTACTSEARCH_QUARK );	
       
   305 	
       
   306 	if ( NULL == search_iface ) 
       
   307 		{
       
   308 		iso_logger( "returning because of search_iface");
       
   309 		//interface for search chan not created 
       
   310 		//send that to client
       
   311 		send_response_to_client( globalCon.search_hdr_req, TP_SEARCH_IFACE_ERROR, 0 );
       
   312 		return ;	
       
   313 		}					
       
   314 	
       
   315 
       
   316 	//Call the search on tp		      										      
       
   317 	tp_chan_type_search_async( search_iface, search_hash, searchreply_cb, 
       
   318 			NULL );
       
   319 			
       
   320 	iso_logger( "out do_search_again");			
       
   321 	
       
   322   
       
   323  }
       
   324 
       
   325 
       
   326 /*
       
   327 ! /brief This function is called by message_send_recv function in isoservermain.c if message type
       
   328 *   is ESearch. This function parses the rmsg, validates the parameter passed, if parameters are 
       
   329 *   correct a search performed for them. else INVALID_PARAMETERES error is returned
       
   330 *
       
   331 *   /param rmsg message buffer to be parsed
       
   332 *   /param rmsg_len the length of the rmsg
       
   333 *   /remark rmsg_len is not strlen(rmsg)
       
   334 *   /return returns error code or 0 on success
       
   335 */
       
   336 gint action_parse_search( gchar* rmsg, gint rmsg_len ) 
       
   337 	{
       
   338 		
       
   339 	gint err = 0;
       
   340 	GHashTable* search_hash = NULL;
       
   341 	message_hdr_req* hdr_req = NULL;
       
   342 	//Allocate memory and set the memory to '\0'
       
   343 	iso_logger( "in action_parse_search");	
       
   344 	hdr_req = ( message_hdr_req* ) malloc ( sizeof ( message_hdr_req ) );
       
   345 	
       
   346 	if ( NULL == hdr_req ) 
       
   347 		{
       
   348 		return MEM_ALLOCATION_ERROR;			
       
   349 		}
       
   350 	memset( hdr_req, '\0', sizeof( message_hdr_req ) );
       
   351 	//Copy the header into message struct
       
   352 	memcpy( hdr_req, rmsg, sizeof( message_hdr_req ) );
       
   353 	//Create the hash table
       
   354 	search_hash = g_hash_table_new( g_str_hash, g_str_equal );
       
   355 	if ( NULL == search_hash ) 
       
   356 		{
       
   357 		return MEM_ALLOCATION_ERROR;			
       
   358 		}
       
   359 	//Parse the key value pairs to be searched into the hash
       
   360 	err = parse_for_search( rmsg, rmsg_len, search_hash );
       
   361 	if ( !err ) 
       
   362 		{
       
   363 		//Do the search on the fields
       
   364 		globalCon.search_hdr_req = hdr_req;
       
   365 		err = do_search( search_hash );		
       
   366 		}
       
   367 	iso_logger( "out action_parse_search");	
       
   368 	
       
   369 	return err;	
       
   370 	}
       
   371 	
       
   372 /*! \brief This function is called by search_results_recieved for each key/value 
       
   373 * 	pair of search result(one entry). This function appends the key/value pair 
       
   374 * 	to the message buffer in the key_value_struct(.msg) and increments 
       
   375 *	the no. of bytes written to(key_value_struct.len)
       
   376 *
       
   377 *	Format of response header(msg buffer)	
       
   378 *	key1\0value1\0key2\0value2\0(key3\0value3\0) (3rd round append)
       
   379 *
       
   380 *	\param key one field of the search entry
       
   381 *	\param value value for the above field
       
   382 *	\param user_data unused
       
   383 *
       
   384 *	\return void
       
   385 */
       
   386 
       
   387 void key_value_store( gpointer key, gpointer value, gpointer user_data ) 
       
   388 	{
       
   389 	
       
   390 	key_value_struct* pairs = ( key_value_struct * ) user_data;	
       
   391 	GValue* value1 = ( GValue* ) value;
       
   392 	const gchar *value_str = NULL; 
       
   393 	const gchar *key_str = ( gchar* ) key; 
       
   394 	
       
   395 	iso_logger( "in key_value_store");
       
   396 	
       
   397 	value_str = g_value_get_string ( value1 );
       
   398 	
       
   399 	if ( '\0' == *value_str ) 
       
   400 		{
       
   401 		iso_logger( "No value");
       
   402 		return;			
       
   403 		}
       
   404 	
       
   405 	iso_logger( "key is %s", key_str );
       
   406 	//copy The results key part 
       
   407 	strcpy( pairs->msg + pairs->len, key_str );
       
   408 	pairs->len += strlen( key_str ) + 1;
       
   409 	
       
   410 	iso_logger( "value is %s", value_str );
       
   411 	//copy The results value part 
       
   412 	strcpy( pairs->msg + pairs->len, value_str );
       
   413 	pairs->len += strlen( value_str ) + 1;
       
   414 	iso_logger( "out key_value_store");	
       
   415 	}
       
   416 	
       
   417 	
       
   418 /*!
       
   419 * 	\brief This function is called when the search results are recieved
       
   420 * 	This function is called for each contact found matching the 
       
   421 * 	search criteria. 
       
   422 *
       
   423 *	\param proxy unused
       
   424 *	\param contact_handle unused
       
   425 *	\param results Key value pair of one search result entry
       
   426 *	\param user_data unused
       
   427 *
       
   428 *	\return void
       
   429 */
       
   430 static void search_result_received_cb ( DBusGProxy	*proxy,
       
   431 										guint       contact_handle,
       
   432 										GHashTable	*results, 
       
   433 										gpointer	user_data
       
   434 									   )
       
   435 	{
       
   436 	message_hdr_resp hdr_resp;
       
   437 	//Get the header request
       
   438 
       
   439 	message_hdr_req* hdr_request = globalCon.search_hdr_req;
       
   440 	key_value_struct pairs;
       
   441 	
       
   442 	gint pri = MSG_PRI_NORMAL;
       
   443 	gint result = 0;
       
   444 	gint timeout = NO_WAIT;
       
   445 	gint err = 0;
       
   446 	
       
   447 	//Create the handle 
       
   448 	iso_logger( "in search_result_received_cb");
       
   449 	
       
   450 	UNUSED_FORMAL_PARAM( proxy );
       
   451 	UNUSED_FORMAL_PARAM( contact_handle );
       
   452 	UNUSED_FORMAL_PARAM( user_data );
       
   453 	
       
   454 	if ( g_hash_table_size( results ) <= 0 ) 
       
   455 		{
       
   456 		iso_logger( "No results recieved");
       
   457 		return;			
       
   458 		}
       
   459 	
       
   460 	iso_logger("search result count for hash table %d", 
       
   461 			g_hash_table_size( results ) );
       
   462 	iso_logger("contact handle is %d", 
       
   463 			contact_handle );
       
   464 	
       
   465 	//Create the response header to be sent to client
       
   466 	//Copy the message header request
       
   467 	//Not copying from hdr req because it could have been modified
       
   468 	//in search_state_changed_cb
       
   469 	hdr_resp.hdr_req.message_type = ESearch;
       
   470 	hdr_resp.hdr_req.protocol_id = hdr_request->protocol_id;
       
   471 	hdr_resp.hdr_req.request_id = hdr_request->request_id;
       
   472 	hdr_resp.hdr_req.session_id = hdr_request->session_id;
       
   473 	//set continue flag
       
   474 	hdr_resp.continue_flag = 0;
       
   475 	hdr_resp.error_type = 0;
       
   476 	hdr_resp.response = 1;
       
   477 	//Allocate memory for the message and set memory to '\0'	
       
   478 	pairs.msg = ( gchar* ) malloc ( MAX_PARAM_LEN );
       
   479 	if ( NULL == pairs.msg ) 
       
   480 		{
       
   481 		iso_logger( "malloc error @ pairs.msg" );
       
   482 		return ;			
       
   483 		}
       
   484 	memset( pairs.msg, '\0', MAX_PARAM_LEN );
       
   485 	pairs.len = 0;
       
   486 	//Copy the response
       
   487 	memcpy( pairs.msg, &hdr_resp, sizeof ( message_hdr_resp ) );
       
   488 	pairs.len += sizeof( message_hdr_resp );
       
   489 	//Copy the contact name
       
   490 	iso_logger( "%s%d", "message type in search_result_received_cb", hdr_request->message_type );
       
   491 
       
   492 
       
   493 	iso_logger( "%s", "start -------------------------------------------------" );
       
   494 
       
   495 	iso_logger( "%s", "contacts key value pair start" );
       
   496 
       
   497 	//Copy all the key/value pairs : 
       
   498 	//no need to check for size here as it is already done at top
       
   499 	g_hash_table_foreach ( results, key_value_store, &pairs );	
       
   500 	
       
   501 	iso_logger( "%s", "end -------------------------------------------------" );
       
   502 
       
   503 	//End the message with a '\0'
       
   504 	pairs.len += 1;
       
   505 	pairs.msg[pairs.len] = '\0';
       
   506 	//Send the message to client
       
   507 	result = MsgQSend( RESPONSE_QUEUE, pairs.msg, pairs.len, 
       
   508 						pri, timeout, &err );
       
   509 						
       
   510 	if ( result < 0 )
       
   511 		{
       
   512 			
       
   513 		}
       
   514 		
       
   515 	//Free the hash table itself
       
   516 	g_hash_table_destroy ( results );
       
   517 	
       
   518 	iso_logger( "in search_result_received_cb");
       
   519 	}
       
   520 	
       
   521 /*! \brief This function is a callback registered to searchstatechanged signal.
       
   522 *	This function is called by telepathygabble when status of the search is changed.
       
   523 *
       
   524 *	\param proxy unused
       
   525 *	\param search_state state of the search
       
   526 *	\param user_data unused
       
   527 *
       
   528 *	\return void
       
   529 */
       
   530 static void search_state_changed_cb ( DBusGProxy	*proxy,
       
   531 										guint       search_state,
       
   532 										gpointer	user_data
       
   533 									   )
       
   534 	{
       
   535 
       
   536 	gint err = 0;
       
   537 	//Get the header request
       
   538 	
       
   539 	iso_logger( "in search_state_changed_cb");
       
   540 	
       
   541 	UNUSED_FORMAL_PARAM( proxy );
       
   542 	UNUSED_FORMAL_PARAM( user_data );
       
   543 	
       
   544 
       
   545 	if ( 1 == search_state && globalCon.search_hdr_req )
       
   546 		{
       
   547 		globalCon.search_hdr_req->message_type = ESearch_State_During;
       
   548 		err = send_response_to_client( globalCon.search_hdr_req, 0, 1 );
       
   549 		if ( err ) 
       
   550 			{
       
   551 			iso_logger( " 1 == search_state Error sending to client");
       
   552 			//?			
       
   553 			}
       
   554 		}
       
   555 	else if ( TP_CHANNEL_CONTACT_SEARCH_STATE_AFTER == search_state 
       
   556 					 && globalCon.search_hdr_req )
       
   557 		{
       
   558 		globalCon.search_hdr_req->message_type = ESearch_State_Finished;
       
   559 		err = send_response_to_client( globalCon.search_hdr_req, 0, 1 );
       
   560 		if ( err ) 
       
   561 			{
       
   562 			iso_logger( "Error sending to client");
       
   563 			//?			
       
   564 			}
       
   565 		//Since the search is finished delete the hdr request
       
   566 		free ( globalCon.search_hdr_req );
       
   567 		globalCon.search_hdr_req  = NULL;
       
   568 		}
       
   569 	
       
   570 	
       
   571 	iso_logger( "out search_state_changed_cb");
       
   572 	}
       
   573 	
       
   574 /*!	\brief Function called by telepathygabble when search channel is closed
       
   575 *	This function is regisered when calling the async function to close channel
       
   576 *
       
   577 *	\param	proxy unused
       
   578 *	\param	error Error if any
       
   579 *	\param	user_data unused
       
   580 *
       
   581 *	\return void
       
   582 */
       
   583 void search_chan_closed_cb ( DBusGProxy	*proxy,
       
   584 									GError *error,
       
   585 									gpointer	user_data
       
   586 								  )
       
   587 	{
       
   588 	iso_logger( "in search_chan_closed_cb");
       
   589 	UNUSED_FORMAL_PARAM( proxy );
       
   590 	UNUSED_FORMAL_PARAM( error );
       
   591 	UNUSED_FORMAL_PARAM( user_data );
       
   592 	g_object_unref(globalCon.search_chan);
       
   593 	globalCon.search_chan = NULL;
       
   594 	iso_logger( "out search_chan_closed_cb");
       
   595 	}
       
   596 	
       
   597 /*!	\brief Function called by telepathygabble when search request is sent to server.
       
   598 *	This function is can be thought of as an ack for search request from server.
       
   599 *
       
   600 *	\param	proxy unused
       
   601 *	\param	error Network error if any
       
   602 *	\param	user_data unused
       
   603 *
       
   604 *	\return void
       
   605 */	
       
   606 static void searchreply_cb( DBusGProxy *proxy, GError *error, gpointer userdata ) 
       
   607 	{
       
   608 	
       
   609 	
       
   610 	iso_logger( "in searchreply_cb" );
       
   611 	UNUSED_FORMAL_PARAM( proxy );
       
   612 	UNUSED_FORMAL_PARAM( userdata );
       
   613 	
       
   614 	if ( error ) 
       
   615 		{
       
   616 		
       
   617 		iso_logger( "Error!!!!!" );
       
   618 		//err cant be handled as of now/this is a special case
       
   619 		//where mem alloc is not possible when sending to client..
       
   620 		send_response_to_client( globalCon.search_hdr_req, error->code, 0 );
       
   621 		
       
   622 		tp_chan_close_async( DBUS_G_PROXY( globalCon.search_chan ), 
       
   623 					search_chan_closed_cb, NULL );
       
   624 		//Header request is deleted only in case of error
       
   625 		//Because the search_state_finished_cb will not be called
       
   626 		//In othr cases ownership of user_data is with search_state_finished_cb
       
   627 		
       
   628 		free ( globalCon.search_hdr_req );
       
   629 		globalCon.search_hdr_req = NULL;
       
   630 		}
       
   631 	
       
   632 	iso_logger( "out searchreply_cb");
       
   633 
       
   634 	}