isolationserver/isoserver/src/isoim.c
branchRCL_3
changeset 11 3404599e4dda
parent 9 46cc8e302e43
equal deleted inserted replaced
9:46cc8e302e43 11:3404599e4dda
     1 /*
       
     2 * ============================================================================
       
     3 *  Name        : isoim.c
       
     4 *  Part of     : isolation server instant messaing componenet.
       
     5 *  Version     : %version: bh1cfmsg#28 %
       
     6 *
       
     7 *  Copyright © 2007-2008 Nokia.  All rights reserved.
       
     8 *  All rights reserved.
       
     9 *  Redistribution and use in source and binary forms, with or without modification, 
       
    10 *  are permitted provided that the following conditions are met:
       
    11 *  Redistributions of source code must retain the above copyright notice, this list 
       
    12 *  of conditions and the following disclaimer.Redistributions in binary form must 
       
    13 *  reproduce the above copyright notice, this list of conditions and the following 
       
    14 *  disclaimer in the documentation and/or other materials provided with the distribution.
       
    15 *  Neither the name of the Nokia Corporation nor the names of its contributors may be used 
       
    16 *  to endorse or promote products derived from this software without specific prior written 
       
    17 *  permission.
       
    18 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
       
    19 *  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
       
    20 *  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
       
    21 *  SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
       
    22 *  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
       
    23 *  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
       
    24 *  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
       
    25 *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
       
    26 *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
       
    27 * ============================================================================
       
    28 * Template version: 1.0
       
    29 */
       
    30 
       
    31 #include "tp-conn-gen.h"
       
    32 #include <stdlib.h>
       
    33 #include <string.h>
       
    34 #include <stdio.h>
       
    35 
       
    36 #include "isoim.h"
       
    37 #include "isoutils.h"
       
    38 
       
    39 #include "msgliterals.h"
       
    40 #include "msg_enums.h"
       
    41 
       
    42 /*!	\file 
       
    43 *	Impliments the functions in isoim.h
       
    44 */
       
    45 
       
    46 /*! /brief requests the handles for the contacts to which message should be sent.
       
    47  *  request_handles_cb is registered as a callback. necessary data to be sent is 
       
    48  *  passed as userdata 
       
    49  *
       
    50  *  /param msghdr request header that will be passed back to client
       
    51  *  /param contact_id all contacts
       
    52  *  /param message
       
    53  *  /param no_cntcts  no. of contacts the msg shld be sent to
       
    54  *  /return : error code on failure, 0 on success
       
    55  */
       
    56 void send_message( send_msg_struct* msg_hdr,
       
    57 					const gchar **contact_id ) 
       
    58 	{
       
    59 	 
       
    60 	//request for the handles to contact
       
    61 	tp_conn_request_handles_async( DBUS_G_PROXY( globalCon.conn ),
       
    62 						TP_CONN_HANDLE_TYPE_CONTACT,
       
    63 						contact_id,request_handles_cb, ( gpointer ) msg_hdr );	 							
       
    64 	}
       
    65 
       
    66 
       
    67 /*! /brief handles for contacts are recieved and text channel created (if already
       
    68  *  there same is used) message is sent to those contacts.
       
    69  *  
       
    70  *  
       
    71  *  /param proxy unused
       
    72  *  /param handles contact handles
       
    73  *  /param error error if any in getting the handles for contact 
       
    74  *  /param userdata Has request header and message to be sent to reciever
       
    75  *  The request header is used for mapping of response to correct request
       
    76  *
       
    77  */
       
    78 void request_handles_cb(DBusGProxy *proxy, GArray *handles, GError* error, gpointer message)
       
    79 	{
       
    80 	TpChan* text_chan = NULL; //for send msg
       
    81 	guint contact_handle;
       
    82 	DBusGProxy  *text_iface = NULL;
       
    83 	send_msg_struct* msg_hdr = ( send_msg_struct* ) message;
       
    84 
       
    85 	UNUSED_FORMAL_PARAM(proxy);
       
    86 	//There was error in requesting handles to the contacts
       
    87 	if ( error )
       
    88 		{
       
    89 		iso_logger( "%s", error->message);
       
    90 		 
       
    91 		iso_logger( "err code: %d ", error->code );
       
    92 		//Send error to client
       
    93 		//What happens if 
       
    94 		send_response_to_client( msg_hdr->hdr_req,  error->code, 0 );
       
    95 		g_error_free(error);
       
    96 		return; 	
       
    97 		}
       
    98 	 
       
    99 	contact_handle = g_array_index( handles, guint, 0 );
       
   100 	//get the text channel for the contact handle 
       
   101 	text_chan = g_hash_table_find( globalCon.text_channels,
       
   102 					      (GHRFunc) text_channels_find_func,
       
   103 					      &contact_handle);	 
       
   104 
       
   105 	iso_logger( "text_chan : %d ", text_chan );
       
   106 	
       
   107 	//create a text channel						      
       
   108 	if ( text_chan == NULL )	
       
   109 		{
       
   110 			 
       
   111 		text_chan = tp_conn_new_channel( globalCon.dbusConn,globalCon.conn,globalCon.connmgr_bus,TP_IFACE_CHANNEL_TYPE_TEXT,
       
   112 									TP_CONN_HANDLE_TYPE_CONTACT,contact_handle, TRUE );	
       
   113 									
       
   114 		if(!text_chan)
       
   115 			{
       
   116 			send_response_to_client( msg_hdr->hdr_req, NOT_CONNECTED , 0 );
       
   117 			g_error_free(error);
       
   118 			return;	
       
   119 			}
       
   120 			
       
   121 		iso_logger( "%s", dbus_g_proxy_get_path(DBUS_G_PROXY(text_chan)));							
       
   122 		g_hash_table_insert( globalCon.text_channels,g_strdup(dbus_g_proxy_get_path(DBUS_G_PROXY(text_chan))),text_chan);							
       
   123 		}
       
   124 	 	
       
   125 	//get interface..	
       
   126 	text_iface = tp_chan_get_interface( text_chan,TELEPATHY_CHAN_IFACE_TEXT_QUARK );	
       
   127 	
       
   128 
       
   129 	
       
   130 	if ( NULL == text_iface ) 
       
   131 		{
       
   132 		free( msg_hdr->msg );
       
   133 		free( msg_hdr->hdr_req );	
       
   134 		free( msg_hdr );
       
   135 
       
   136 		//Free proxy ?
       
   137 		return ;
       
   138 		}
       
   139 
       
   140 	//send async
       
   141 	tp_chan_type_text_send_async( text_iface, TP_CHANNEL_TEXT_MESSAGE_TYPE_NORMAL, 
       
   142 		( const char * )msg_hdr->msg,sendreply_cb, msg_hdr->hdr_req ); // see if any user date should be passed
       
   143 	
       
   144 	
       
   145 	iso_logger( "Message being sent is %s", msg_hdr->msg ); 	 
       
   146 	
       
   147 	free( msg_hdr->msg );
       
   148 	free( msg_hdr );
       
   149 	 	
       
   150 	iso_logger( "%s", "tp_chan_type_text_send_async after\n"); 	
       
   151 	}
       
   152 
       
   153 /*! /brief parse the params for send and validates them
       
   154  * 
       
   155  *  /param aMsgBuffer message buffer to be parsed
       
   156  *  /param aContactId pointer to an array of strings, After this function this 
       
   157  *  arg wil have the contacts to which message should be sent to
       
   158  *  /param aSendMsg message to be sent
       
   159  *  /param len : msg_len no. of bytes in aMsgBuffer
       
   160  *  /param contact_count : no. of contacts
       
   161  *  /return returns error code on failure, or 0
       
   162  */
       
   163 gint parse_for_send( gchar* msg_buf, gchar*** contact_ids, 
       
   164 			gchar** send_msg, gint msg_len, gint* contact_count ) 
       
   165 	{
       
   166 	gchar* users = NULL;
       
   167 	
       
   168 	gint len = 0;
       
   169 	gint err = 0;
       
   170 	
       
   171 	iso_logger( "%s", "In - parse_for_send\n" );
       
   172 	//skip the msg_hdr part
       
   173 	len += sizeof( message_hdr_req );
       
   174 	//example send message - message header omitted..
       
   175 	//test.ximp@gmail.com\0ximp.telepathy@gmail.com\0\0hi, how r u?\0
       
   176 	//					  ^ 						^ ^	            ^ 
       
   177 	//contact1------------|contact2-----------------|-|message------|
       
   178 	
       
   179 	//gets the contacts, returns no. of contacts on success 
       
   180 	//error code on error
       
   181 	err = parse_into_array_of_strings( msg_buf, contact_ids, &len, msg_len,
       
   182 	 contact_count );
       
   183 	if ( err < 0 ) 
       
   184 		{
       
   185 		//An error has occured, so propagate to next level
       
   186 		return err;
       
   187 		}
       
   188 	
       
   189 		
       
   190 	/*
       
   191 	Will never come here.. coz it has been already handled in 
       
   192 	parse_into_array_of_strings
       
   193 	if ( *contact_count > MAX_MSG_RECEIPIENTS ) 
       
   194 		{
       
   195 		return INVALID_PARAMETERES;
       
   196 		}*/
       
   197 	//reset the userlen	
       
   198 	
       
   199 	//parse for the message..
       
   200 	err = parse_a_string( msg_buf, &users, &len, msg_len );
       
   201 	
       
   202 	if ( err < 0 ) 
       
   203 		{
       
   204 		return err; 
       
   205 		}
       
   206 	//set the pointer to send message
       
   207 	*send_msg = users;
       
   208 	
       
   209 	iso_logger( "%s", "Out - parse_for_send\n" );	
       
   210 	//return the no. of contacts to be sent to	
       
   211 	return 0;
       
   212 	}
       
   213 /*! /brief calls parse_for_send to parse the parameters, and calls 
       
   214  *  send_message for sending the message
       
   215  * 
       
   216  *  /param buf : message buffer to be parsed
       
   217  *  /param len : msg_len no. of bytes in msg_buf
       
   218  *
       
   219  *  /return gint : parse error code if any
       
   220  */
       
   221 int action_parse_send( gchar* buf, gint msg_len ) 
       
   222 	{
       
   223 	gchar** contactid = NULL;
       
   224 	gchar* sendmsg = NULL;
       
   225 	message_hdr_req *msg_hdr = NULL;
       
   226 	gint meesage_type_err = 0;
       
   227 	//It is very imp to initailize the contact_count to 0 here
       
   228 	gint contact_count = 0;
       
   229 	send_msg_struct* msg_struct = NULL;
       
   230 	//parse contacts, message.. 	
       
   231 	iso_logger( "%s", "In - action_parse_send\n" );
       
   232 	meesage_type_err = parse_for_send( buf, 
       
   233 			&contactid,&sendmsg, msg_len, &contact_count );
       
   234 	
       
   235 	//if <= 0 there is some error in the message formation
       
   236 	if ( contact_count > 0  && meesage_type_err == 0 ) 
       
   237 		{
       
   238 		
       
   239 		//send message
       
   240 		msg_hdr = ( message_hdr_req* ) malloc( sizeof( message_hdr_req ) );
       
   241 		if ( NULL == msg_hdr ) 
       
   242 			{
       
   243 			//free resources allocated for this operation
       
   244 			free_msg_args( contactid, contact_count, sendmsg );
       
   245 			return MEM_ALLOCATION_ERROR;
       
   246 			}
       
   247 	    memset( msg_hdr, '\0', sizeof( message_hdr_req ) );
       
   248 	    //read message header from buffer
       
   249 	    memcpy( msg_hdr, buf, sizeof( message_hdr_req ) );
       
   250 	    
       
   251 	    //fill the contacts and message into a struct
       
   252 	    msg_struct = ( send_msg_struct* ) malloc ( sizeof ( send_msg_struct ) );
       
   253 	    if ( NULL == msg_struct ) 
       
   254 			{
       
   255 			free ( msg_hdr );
       
   256 			free_msg_args( contactid, contact_count, sendmsg );
       
   257 			return MEM_ALLOCATION_ERROR;
       
   258 			}
       
   259 		msg_struct->hdr_req = msg_hdr;
       
   260 		msg_struct->msg = sendmsg;
       
   261 		//msg_struct is sent callback... which should be feed there..
       
   262 		send_message( msg_struct, 
       
   263 				( const gchar** ) contactid );
       
   264 		}
       
   265 	else  
       
   266 		{
       
   267 		//there was some error, free resources allocated for this operation
       
   268 		free_msg_args( contactid, contact_count, sendmsg );
       
   269 		}
       
   270 	
       
   271 	iso_logger( "%s", "Out - action_parse_send\n" );
       
   272 	//return error on failure, or no. of contacts message sent to on success
       
   273 	return meesage_type_err;
       
   274 	
       
   275 	}
       
   276 
       
   277 /*! /brief Function to check if the channel is already present in the maintained hash
       
   278  *  text_channels_find_func. 
       
   279  *
       
   280  *  /param key unused
       
   281  *  /param text_channel hash table element
       
   282  *  /param contact_handle to be searched item 
       
   283  *  /return boolean 
       
   284  */
       
   285 gboolean text_channels_find_func(	gchar *key,
       
   286 									TpChan *text_channel,
       
   287 									guint *contact_handle )
       
   288 	{
       
   289 	iso_logger( "%s", "In - text_channels_find_func\n" );
       
   290 	//Check for the handles
       
   291 	UNUSED_FORMAL_PARAM(key);
       
   292 	if ( ( text_channel->handle == *contact_handle ) )
       
   293 		return TRUE;
       
   294 
       
   295 	return FALSE;
       
   296 	} 
       
   297 
       
   298 /*! /brief Once the send request is sent to n/w server this callback is called
       
   299  * 
       
   300  *  /param proxy unused
       
   301  *  /param error n/w error if any
       
   302  *  /param userdata message header from which a response is formed
       
   303  *  /return void
       
   304  */
       
   305 void sendreply_cb( DBusGProxy *proxy, GError *error, gpointer userdata ) 
       
   306 	{
       
   307 	int err = 0;
       
   308 
       
   309 	message_hdr_req* msg_hdr = ( message_hdr_req* ) userdata;
       
   310 	// create the msg queue
       
   311 	//user data is of type message_hdr_req
       
   312 	iso_logger( "%s", "In - sendreply_cb\n" );
       
   313     UNUSED_FORMAL_PARAM(proxy);
       
   314 	if ( NULL != error ) 
       
   315 		{
       
   316 		//There was some error
       
   317 		//send the response for the msg_hdr request to client
       
   318 		err = send_response_to_client( msg_hdr,  error->code, 0 );
       
   319 		//free the message
       
   320 		g_error_free(error);
       
   321 		
       
   322 		}
       
   323 	else 
       
   324 		{
       
   325 		//send the response for the msg_hdr request to client
       
   326 		err = send_response_to_client( msg_hdr, 0, 1 );
       
   327 		}
       
   328 	//Free the header recved as callback userdata
       
   329 	free( msg_hdr );
       
   330 
       
   331 	if ( err < 0 )
       
   332 		{
       
   333 		// failed to delievered	
       
   334 		return ;
       
   335 		}
       
   336 	iso_logger( "%s", "Out - sendreply_cb\n" );
       
   337 	}
       
   338 	
       
   339 /*! /brief This function is called by tg to as a response to request for the 
       
   340  *  handles from the text channel. If there is no error, sent message( 
       
   341  *  which has failed ) with its deatils is then sent to client
       
   342  * 
       
   343  *  /param proxy unused
       
   344  *  /param handles_names contac names (sender name)
       
   345  *  /param error error if any
       
   346  *  /param userdata send_error_struct
       
   347  *  /return void
       
   348  */     
       
   349 static void inspect_handles_for_error_cb( DBusGProxy *proxy,char **handles_names,
       
   350 				 GError *error, gpointer userdata ) 
       
   351 	{
       
   352 	
       
   353 	gint pri = MSG_PRI_NORMAL;
       
   354 	gint result = 0;
       
   355 	gint timeout = NO_WAIT;
       
   356 	gint err = 0;
       
   357 	
       
   358 	send_error_struct* msg_struct = ( send_error_struct* ) userdata;
       
   359 	gchar* rmsg = NULL;
       
   360 	gint index = 0;
       
   361 	gint len = 0;
       
   362 	UNUSED_FORMAL_PARAM(proxy);
       
   363 	iso_logger( "%s", "In - inspect_handles_for_error_cb" );		
       
   364 	if ( !handles_names || error || NULL == handles_names[0] ) 
       
   365 		{
       
   366 		if ( error ) 
       
   367 			{
       
   368 			g_error_free( error );	
       
   369 			}
       
   370 		//Free the userdata passed to the callback 
       
   371 		if ( NULL != msg_struct ) 
       
   372 			{
       
   373 			if ( msg_struct->msg_body ) 
       
   374 				{
       
   375 				g_free( msg_struct->msg_body );		
       
   376 				}
       
   377 			g_free( msg_struct );			
       
   378 			}
       
   379 		return;
       
   380 		}
       
   381 	//Allocate the memory and check for NULL	
       
   382 	rmsg = ( gchar* ) malloc ( MAX_MSG_SIZE );
       
   383 	if ( NULL == rmsg ) 
       
   384 		{
       
   385 		goto mem_clean;
       
   386 		}
       
   387 	//set memory to 0
       
   388 	memset( rmsg, '\0', MAX_MSG_SIZE );
       
   389     //copy the header
       
   390     //the response header, message type(from libtp), timestamp
       
   391 	memcpy( rmsg + index, msg_struct, sizeof( message_hdr_resp )
       
   392 	+ 2 * sizeof( guint )  );
       
   393 	
       
   394     index += sizeof( message_hdr_resp ) + 2 * sizeof( guint );
       
   395     
       
   396     //Copy the name to whom message was sent
       
   397     len = strlen( handles_names[0] );
       
   398     strcpy( rmsg + index, handles_names[0] );
       
   399     index += len + 1;
       
   400     
       
   401     //Copy the message body
       
   402     if ( msg_struct->msg_body ) 
       
   403 	    {
       
   404 	    len = strlen( msg_struct->msg_body );
       
   405 	    strcpy( rmsg + index, msg_struct->msg_body );
       
   406 	    index += len + 1;	   	
       
   407 	    }
       
   408     rmsg[index++] = '\0';
       
   409     //Header format
       
   410     //msgHdr|msg_type|timestamp|reciepient_name\0sent_msg\0
       
   411 	// 		^                                   ^         ^
       
   412     //      |			                        |		  |
       
   413     //no dilimeter here                        nul		 nul
       
   414     //send to the client
       
   415     result = MsgQSend( RESPONSE_QUEUE, rmsg, index, 
       
   416 						pri, timeout, &err );
       
   417 	iso_logger( "%s", "After MsgQSend" );						
       
   418 //If memory allocation for rmsg has failed control comes
       
   419 //here
       
   420 mem_clean:
       
   421 
       
   422 	for ( len = 0; handles_names[len]; len++ )	
       
   423 		{
       
   424 		free ( handles_names[len] );
       
   425 		}
       
   426 		
       
   427 	if ( msg_struct->msg_body ) 
       
   428 		{
       
   429 		g_free( msg_struct->msg_body );		
       
   430 		}
       
   431 	g_free( msg_struct );
       
   432 						
       
   433 	if ( result < 0 )
       
   434 		{
       
   435 		//Failed to deliver the message
       
   436 		iso_logger( "%s", "Failed to deliver the message to client" );
       
   437 		return;
       
   438 		}
       
   439 	iso_logger( "%s", "Out - inspect_handles_for_error_cb" );
       
   440 	
       
   441 	}
       
   442 
       
   443 /*! /brief This function on registered for "senderror" signal is called when the message 
       
   444  *  sending is failed. Calls tp_conn_inspect_handles_async to get the contact name 
       
   445  *  from text channel
       
   446  *
       
   447  *  /param proxy : unused
       
   448  *  /param error : error code
       
   449  *  /param timestamp : sent to inspect_handles_for_error_cb thru' send_error_struct
       
   450  *  /param message_type : sent to inspect_handles_for_error_cb thru' send_error_struct
       
   451  *  /param message_body : sent to inspect_handles_for_error_cb thru' send_error_struct
       
   452  *  /param user_data text_chan from where to get the contatc name of reciepien
       
   453  *  /return void
       
   454  */
       
   455 static void senderror_cb (  DBusGProxy *proxy,
       
   456 								guint            error,
       
   457 							   	guint            timestamp,
       
   458 							    guint            message_type,
       
   459 							    gchar           *message_body,
       
   460 							    gpointer		user_data )
       
   461 	{
       
   462 	
       
   463 	TpChan *text_chan = ( TpChan * ) user_data;
       
   464 	send_error_struct* msg_struct = NULL;
       
   465 	GArray* fetch_members = NULL;
       
   466 	DBusGProxyCall* call_id = NULL;
       
   467 	
       
   468 	//Logs
       
   469 	iso_logger( "%s", "In - SendError_cb\n" );
       
   470 	iso_logger( "error is %d", error );
       
   471 	iso_logger( "error is %d", message_type );
       
   472 	iso_logger( "error is %d", timestamp );
       
   473 	iso_logger( "error is %s", message_body );
       
   474 	UNUSED_FORMAL_PARAM(proxy);
       
   475 	//Allocate memory and check for NULL
       
   476 	//This msg_struct is passed to callback..
       
   477 	//So not deleting here.. ownership is transfered
       
   478 	msg_struct = ( send_error_struct* ) malloc ( sizeof( send_error_struct ) );
       
   479 
       
   480 	if ( NULL == text_chan || NULL == msg_struct ) 
       
   481 		{
       
   482 		return;
       
   483 		}
       
   484 	//Set the values to NULL		
       
   485 	memset( msg_struct, '\0', sizeof( send_error_struct ) );
       
   486 	//Message type is send error
       
   487 	msg_struct->hdr_resp.hdr_req.message_type = ESend_Error;
       
   488 	//other values are set to 0
       
   489 	msg_struct->hdr_resp.hdr_req.protocol_id = 0;
       
   490 	msg_struct->hdr_resp.hdr_req.session_id = 0;
       
   491 	msg_struct->hdr_resp.hdr_req.request_id = 0;
       
   492 	
       
   493 	//Message is sent as single entity..
       
   494 	//Message is not long enough to be broken into 
       
   495 	msg_struct->hdr_resp.continue_flag = 0;
       
   496 	msg_struct->hdr_resp.response = 0;
       
   497 	
       
   498 	//Set the error type
       
   499 	msg_struct->hdr_resp.error_type = error;
       
   500 	//Set the values from libtelepathy
       
   501 	msg_struct->msg_type = message_type;
       
   502 	msg_struct->timestamp = timestamp;
       
   503 	//Not checking for NULL here.. 
       
   504 	//I feel it is ok to send without the message 
       
   505 	//Taken care of this in inspect_handles_for_error_cb
       
   506 	msg_struct->msg_body = strdup( message_body );
       
   507 	
       
   508 	//Create an array of handles to get the handle name
       
   509 	fetch_members = g_array_new ( FALSE, FALSE, sizeof ( guint32 ) );
       
   510 	g_array_append_val( fetch_members, text_chan->handle );
       
   511 	//Call libtp function to get the contact name for the handle
       
   512 	//msg_struct is passed to inspect handles call back to be passed to 
       
   513 	//client as error
       
   514 	call_id = tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ),
       
   515 					       TP_CONN_HANDLE_TYPE_CONTACT ,fetch_members,
       
   516 					       inspect_handles_for_error_cb, msg_struct );
       
   517 	
       
   518 	g_array_free( fetch_members, TRUE );
       
   519 	if ( NULL == call_id )
       
   520 		{
       
   521 		return ;
       
   522 		}
       
   523 	
       
   524 	iso_logger( "%s", "Out - SendError_cb" );
       
   525 	
       
   526 	}
       
   527 
       
   528 
       
   529 
       
   530 
       
   531 /*! /brief called as a callback to acknowledge the msg ack. 
       
   532  * 
       
   533  *  /param proxy unused 
       
   534  *  /param error error if any
       
   535  *  /param userdata unused
       
   536  *  /return void
       
   537  */
       
   538 static void msg_ack_pending_cb( DBusGProxy *proxy, GError *error, gpointer userdata ) 
       
   539 
       
   540 	{	
       
   541 	gchar *str = "Inside msg_ack_pending_cb";
       
   542 	UNUSED_FORMAL_PARAM(proxy);
       
   543 	UNUSED_FORMAL_PARAM(userdata);
       
   544 	if ( error ) 
       
   545 		{
       
   546 		//If there was error, ignore it and free the memory
       
   547 		g_error_free(error);	
       
   548 		}
       
   549 	
       
   550 	iso_logger(  str );
       
   551 	}
       
   552 
       
   553 
       
   554 	
       
   555 /*! /brief This function is a callback for to get the contact name from handles.
       
   556  *  This function acknowledges the recieved message and send that to client(adap)
       
   557  *  
       
   558  *  /param proxy unused
       
   559  *  /param handles_names 2D array of message sender(one contact ended with a NULL string)
       
   560  *  /param error error if any
       
   561  *  /param userdata Received_UserData that has message body, response header etc.,
       
   562  *  /return void
       
   563  */  
       
   564 static void getting_sender_cb( DBusGProxy *proxy,char **handles_names, GError *error, gpointer userdata ) 
       
   565 	{
       
   566 
       
   567 	gchar *str = "Inside getting_sender_cb";
       
   568 	GArray  *message_ids;
       
   569 	gint result = 0;
       
   570 	Received_UserData *user_data = ( Received_UserData* )userdata;
       
   571 	iso_logger(  "%s", str );
       
   572 	UNUSED_FORMAL_PARAM(proxy);
       
   573 	if ( !handles_names || error )
       
   574 		{
       
   575 		if ( error ) 
       
   576 			{
       
   577 			//If there was error, ignore it and free the memory
       
   578 			g_error_free(error);	
       
   579 			}
       
   580 		//Free the userdata passed to the callback 
       
   581 		g_free( user_data->message_body );
       
   582 		g_free( user_data );
       
   583 		iso_logger( "%s", "handle names error" );
       
   584 		return;
       
   585 		}
       
   586 	
       
   587 	message_ids = g_array_new ( FALSE, FALSE, sizeof ( guint ) );
       
   588 	if ( NULL == message_ids ) 
       
   589 		{
       
   590 		//Free the userdata passed to the callback 
       
   591 		g_free( user_data->message_body );
       
   592 		g_free( user_data );
       
   593 		return ;	
       
   594 		}
       
   595 	g_array_append_val ( message_ids, user_data->message_id );
       
   596 	//Acknowledge that message has been recieved
       
   597 	tp_chan_type_text_acknowledge_pending_messages_async( user_data->proxy, message_ids, 
       
   598 			msg_ack_pending_cb, NULL );
       
   599 	//Send to the client the messgae and the sender name			
       
   600 	result = send_message_to_client( user_data->message_body , *handles_names );
       
   601 	
       
   602 	if ( 0 > result ) 
       
   603 		{
       
   604 		return;
       
   605 		}
       
   606 		
       
   607 	iso_logger(  "%s", "getting_sender_cb" );
       
   608 	iso_logger(  "%s", user_data->message_body );
       
   609 	
       
   610 	//Free the messgae ids array		
       
   611 	g_array_free ( message_ids, TRUE );
       
   612 	//free the recieved data
       
   613 	g_free( user_data->message_body );
       
   614 	g_free( user_data );
       
   615 	
       
   616 	
       
   617 	}
       
   618 
       
   619     
       
   620     
       
   621 
       
   622 /*! /brief when a message is recieved this function is called by 
       
   623  *  telepathygabble(by emitting signal). This function then requests tg 
       
   624  *  to get the contact names corresponding to handles.
       
   625  * 
       
   626  *  /param proxy sent to getting_sender_cb as param in userdata
       
   627  *  /param timestamp unused
       
   628  *  /param handles_names
       
   629  *  /param message_type unused
       
   630  *  /param message_flags unused
       
   631  *  /param message_body recieved message
       
   632  *  /param userdata unused
       
   633  */
       
   634 void receivedMessage_cb (  DBusGProxy *proxy,
       
   635 								guint            message_id,
       
   636 							   	guint            timestamp,
       
   637 							    guint            from_handle,
       
   638 							    guint            message_type,
       
   639 							    guint            message_flags,
       
   640 							    gchar           *message_body,
       
   641 							    gpointer		user_data )
       
   642     {
       
   643 	GArray  *handles = NULL;
       
   644 	Received_UserData *recv_userdata = NULL;
       
   645 	
       
   646 	iso_logger(  "%s", "receivedMessage_cb:" );
       
   647 	UNUSED_FORMAL_PARAM(timestamp);
       
   648 	UNUSED_FORMAL_PARAM(message_type);
       
   649 	UNUSED_FORMAL_PARAM(message_flags);
       
   650 	UNUSED_FORMAL_PARAM(user_data);
       
   651 	//Allocate memory and initalize the structure
       
   652 	recv_userdata =  g_new ( Received_UserData, 1 );
       
   653 	if ( NULL == recv_userdata ) 
       
   654 		{
       
   655 		
       
   656 		free ( message_body );
       
   657 		return ;
       
   658 		}
       
   659 	//TBD : Check if this assignment works..
       
   660 	//previously it was strdup of message_body 
       
   661 	recv_userdata->message_body =  strdup( message_body );
       
   662 	recv_userdata->message_id = message_id;
       
   663 	recv_userdata->proxy = proxy;
       
   664 	
       
   665 	//logs
       
   666 	iso_logger(  "%s", message_body );
       
   667 	//allocate memory for the handles
       
   668 	handles = g_array_new ( FALSE, FALSE, sizeof ( guint32 ) );
       
   669 	if ( NULL == handles ) 
       
   670 		{
       
   671 		//free previously allocated struct
       
   672 		g_free( recv_userdata->message_body );
       
   673 		g_free( recv_userdata );
       
   674 		return ;
       
   675 		}
       
   676 		
       
   677 	g_array_append_val ( handles, from_handle );
       
   678 	//get the sender name corresponding to the handles
       
   679 	tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ),
       
   680 					       TP_CONN_HANDLE_TYPE_CONTACT ,handles,
       
   681 					       getting_sender_cb,recv_userdata );
       
   682 	//free handles				       	
       
   683 	g_array_free ( handles, TRUE );
       
   684 		
       
   685     }
       
   686 
       
   687 
       
   688 /*! /brief whenevr a new channel handler for text is created, this function is called. This 
       
   689  *  function also registers that channel for Received and SendError signals. Also the pending
       
   690  *  messages are also retrieved in this function
       
   691  * 
       
   692  *  /param tp_chan new channel created
       
   693  */
       
   694  void text_channel_init( TpChan *text_chan )
       
   695 	{
       
   696 	
       
   697 	GPtrArray  *messages_list ;
       
   698 	guint       i = 0;
       
   699 	GArray     *message_ids;
       
   700 	DBusGProxy *text_iface;
       
   701 	GArray *handles = NULL;
       
   702 	Received_UserData *recv_userdata = NULL;
       
   703 	
       
   704 	
       
   705 	iso_logger(  "%s", "inside  text_channel_init" );
       
   706 	//text_chan has been checked for NULL in the callee function
       
   707     text_iface = tp_chan_get_interface( text_chan ,
       
   708 	   								   TELEPATHY_CHAN_IFACE_TEXT_QUARK );
       
   709 	
       
   710 	message_ids = g_array_new ( FALSE, TRUE, sizeof ( guint ) );
       
   711 	
       
   712 	handles = g_array_new ( FALSE, FALSE, sizeof ( guint32 ) );
       
   713 	//If memory allocation fialure, return from here
       
   714 	if ( !text_iface || !message_ids || !handles ) 
       
   715 		{
       
   716 		return ;	
       
   717 		}
       
   718 	
       
   719 	tp_chan_type_text_list_pending_messages( text_iface,
       
   720 						FALSE,
       
   721 						&messages_list,
       
   722 						NULL );
       
   723 	//For all the pending messages get the sender name
       
   724 	//and send to client the sender name and recv msg
       
   725 	for ( i = 0; i < messages_list->len ; i++ )
       
   726 		{
       
   727 		guint          message_id;
       
   728 		guint          from_handle;
       
   729 		const gchar   *message_body;
       
   730 		GValueArray   *message_struct;
       
   731 		
       
   732 		message_struct = ( GValueArray * ) g_ptr_array_index ( messages_list, i );
       
   733 		
       
   734 		//Not all the fields used currently
       
   735 		//Ignoring the unused fields
       
   736 		message_id = g_value_get_uint( g_value_array_get_nth( message_struct, 0 ) );
       
   737 		//get the handle to sender
       
   738 		from_handle = g_value_get_uint(g_value_array_get_nth( message_struct, 2 ) );
       
   739 		//Get the message body
       
   740 		message_body = g_value_get_string( g_value_array_get_nth( message_struct, 5 ) );
       
   741 		
       
   742 		iso_logger ( "%s", message_body );
       
   743 			    
       
   744     	g_array_append_val( handles, from_handle );
       
   745     	//Allocate memory for the recv data
       
   746        	recv_userdata =  g_new( Received_UserData, 1 );
       
   747        	if ( !recv_userdata ) 
       
   748 	       	{
       
   749 	       	break; //Break from the loop
       
   750 	       	}
       
   751 	    //Set all the necessary fields
       
   752 	    recv_userdata->message_body = g_strdup( message_body );
       
   753 	    recv_userdata->message_id = message_id;
       
   754  	    recv_userdata->proxy = text_iface;
       
   755  	    //get the name for the sender handle
       
   756 	    tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ),
       
   757 					       TP_CONN_HANDLE_TYPE_CONTACT ,handles,
       
   758 					       getting_sender_cb, recv_userdata );	
       
   759 					       
       
   760     	g_array_append_val ( message_ids, message_id );
       
   761     	
       
   762     	//To reuse the array, remove the 1 that was inserted
       
   763     	g_array_remove_range( handles, 0, handles->len );
       
   764 
       
   765 		}
       
   766 	iso_logger ( "%s", "before ack pending msg");
       
   767 	//acknowledge the recved messages
       
   768 	tp_chan_type_text_acknowledge_pending_messages( text_iface, message_ids,
       
   769 					       NULL );
       
   770 	
       
   771 	iso_logger ( "%s", "after ack pending msg" );
       
   772 	
       
   773 	//Listen to Received signal
       
   774 	dbus_g_proxy_connect_signal( text_iface, "Received",
       
   775 				G_CALLBACK( receivedMessage_cb ),
       
   776 					NULL, NULL );
       
   777 					
       
   778 	//Register for the senderror signal
       
   779 	dbus_g_proxy_connect_signal( text_iface, "SendError",
       
   780 				G_CALLBACK( senderror_cb ),
       
   781 					text_chan, NULL );					
       
   782 					
       
   783 	//Should the messages_list be freed?	
       
   784 	g_array_free( message_ids, TRUE );
       
   785 	g_array_free( handles, TRUE );
       
   786 	
       
   787 	
       
   788 	}
       
   789 
       
   790 
       
   791  
       
   792 
       
   793  /*! /brief called by getting_sender_cb to send the recieved message to client
       
   794   * 
       
   795   *  /param msg message recieved
       
   796   *  /param sender message from whom recieved
       
   797   */ 
       
   798 gint send_message_to_client( const gchar *msg , const gchar *sender )
       
   799 
       
   800     {
       
   801 	gint len=0;
       
   802 	gint pri = MSG_PRI_NORMAL;
       
   803 	gchar *rmsg = NULL;
       
   804 	gint index = 0;
       
   805 	gint err;
       
   806 	message_hdr_resp* msg_resp = NULL;
       
   807 	gint result;
       
   808 	gint timeout = NO_WAIT;
       
   809 	
       
   810 	msg_resp = ( message_hdr_resp* ) malloc ( sizeof( message_hdr_resp ) );
       
   811 	if ( NULL == msg_resp ) 
       
   812 		{
       
   813 		return 	MEM_ALLOCATION_ERROR;
       
   814 		}
       
   815 	//Allocate memory and initialze to 0 
       
   816 	rmsg = ( gchar* ) malloc ( MAX_MSG_SIZE );
       
   817 	if ( NULL == rmsg ) 
       
   818 		{
       
   819 		free ( msg_resp );
       
   820 		return 	MEM_ALLOCATION_ERROR;
       
   821 		}
       
   822 	   
       
   823 	//Initialze the memory to 0
       
   824 	memset( msg_resp, '\0', sizeof( message_hdr_resp ) );
       
   825     //Set the message type to EText_Message_Receive and set other fields
       
   826     //to default values
       
   827 	msg_resp->hdr_req.message_type = EText_Message_Receive;
       
   828 	msg_resp->hdr_req.protocol_id = 1;
       
   829 	msg_resp->hdr_req.session_id = 1;
       
   830 	msg_resp->hdr_req.request_id =1;
       
   831 	//Set the respone as success and error is 0
       
   832 	msg_resp->response = 1;
       
   833 	msg_resp->error_type = 0;
       
   834 		
       
   835     memset( rmsg, '\0', MAX_MSG_SIZE );
       
   836     //copy the header
       
   837 	memcpy( rmsg, msg_resp, sizeof( message_hdr_resp ) );
       
   838     index += sizeof( message_hdr_resp );
       
   839     
       
   840     //copy the sender
       
   841     //putting sender in message queue
       
   842     len = strlen(sender);
       
   843     strcpy( rmsg + index, sender );
       
   844     index += len + 1;
       
   845     
       
   846     //putting message body   
       
   847     len = strlen(msg);
       
   848     strcpy( rmsg + index, msg );
       
   849     index += len + 1;
       
   850     
       
   851     //Header format
       
   852     //msgHdr|sender_name\0recved_msg\0
       
   853 	// 		^            ^           ^
       
   854     //      |			 |			 |
       
   855     //no dilimeter here  nul		nul
       
   856     //send to the client
       
   857     result = MsgQSend( RESPONSE_QUEUE, rmsg, index, 
       
   858 						pri, timeout, &err );
       
   859 	free ( rmsg );
       
   860 	
       
   861 	free ( msg_resp );
       
   862 	
       
   863     if ( result < 0 )
       
   864     	{
       
   865     	return MSG_Q_SEND_FAILED;
       
   866     	}
       
   867     	
       
   868 	iso_logger(  "%s", "message is:\n" );
       
   869 	return TRUE;
       
   870     }
       
   871 
       
   872 // end of files
       
   873 
       
   874