isolationserver/isoserver/src/isomodifycontactlist.c
changeset 10 59927b2d3b75
parent 0 d0f3a028347a
equal deleted inserted replaced
0:d0f3a028347a 10:59927b2d3b75
     1 /*
       
     2 * ============================================================================
       
     3 *  Name        : isomodifycontacts.h
       
     4 *  Part of     : isolation server.
       
     5 *  Version     : %version: 16 %
       
     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 #include <stdio.h>
       
    31 #include <stdlib.h>
       
    32 #include <string.h>
       
    33 #include <glib.h>
       
    34 #include "msgliterals.h"
       
    35 #include "isomodifycontactlist.h"
       
    36 #include "isoutils.h"
       
    37 #include "isofetchcontactlist.h" //For send_contact_to_client func
       
    38 
       
    39 /*!	\file 
       
    40 *	Impliments the functions in isomodifycontactlist.h
       
    41 */
       
    42 
       
    43 /*!
       
    44  *  /brief This function is called by message_send_recv function in isoservermain.c if message type
       
    45  *  is EReject_Contact_Request, EAccept_Contact_Request, EAdd_Contact_Request and EDelete_Contact_Request. 
       
    46  *  Contacts added/removed to/from list. This function parses the message buffer, 
       
    47  *  validates for the arguments and calls modify_contact_list to add/remove contacts
       
    48  * 
       
    49  *  /param buf : buffer to be parsed
       
    50  *  /param buf_len : buffer length
       
    51  *  /return : error code if any, 0 on success 
       
    52  */
       
    53 gint action_parse_modify_contact_list( gchar* buf, gint buf_len ) 
       
    54 	{
       
    55 	gchar** contactid = NULL;
       
    56 	gchar* msg = NULL;
       
    57 	gint meesage_type_err = 0;
       
    58 	gint len = 0;
       
    59 	gint contact_count = 0;
       
    60 	
       
    61 	//parse contacts, message.. 	
       
    62 	iso_logger( "%s", "In - action_parse_modify_contact_list" );
       
    63 	len += sizeof( message_hdr_req );
       
    64 	//example send message - message header omitted..
       
    65 	//test.ximp@gmail.com\0ximp.telepathy@gmail.com\0\0I would like to add u!\0
       
    66 	//					  ^ 						^ ^	                      ^ 
       
    67 	//contact1------------|contact2-----------------|-|message----------------|
       
    68 	//Till Message part is parsed by the following function
       
    69 	meesage_type_err = parse_into_array_of_strings( buf, &contactid, &len, buf_len, &contact_count );
       
    70 	if ( meesage_type_err < 0 ) 
       
    71 		{
       
    72 		gchar* msg = NULL;
       
    73 		//An error has occured, so propagate to next level
       
    74 		free_msg_args( contactid, contact_count, msg );
       
    75 		//got error, print to file
       
    76 		return meesage_type_err;
       
    77 		}
       
    78 	
       
    79 	//Parse the message
       
    80 	//message is optional.. so check if message has been sent
       
    81 	if ( len < buf_len ) 
       
    82 		{
       
    83 		
       
    84 		gint err = 0;
       
    85 		
       
    86 	//	iso_logger( "%x", len );
       
    87     //		iso_logger( "%f", len );
       
    88 		
       
    89 		//parse for the message..
       
    90 		err = parse_a_string( buf, &msg, &len, buf_len );
       
    91 		
       
    92 		if ( err < 0 ) 
       
    93 			{
       
    94 			//return err; 
       
    95 			//ignoring the error..
       
    96 			//as message is not that important
       
    97 			msg = NULL;
       
    98 			}
       
    99 		}	
       
   100 	//If there is atleast one contact to add
       
   101 	if ( contact_count > 0 ) 
       
   102 		{
       
   103 		//Add the header and message to the msg struct
       
   104 		//this struct will be used in the callbacks
       
   105 		send_msg_struct* msg_struct = NULL;
       
   106 		msg_struct = ( send_msg_struct* ) malloc( sizeof( send_msg_struct ) );
       
   107 		if ( NULL == msg_struct ) 
       
   108 			{
       
   109 			//An error has occured, so propagate to next level
       
   110 			free_msg_args( contactid, contact_count, msg );
       
   111 			return MEM_ALLOCATION_ERROR;
       
   112 			}
       
   113 		//allocate memory and check for the returned value	
       
   114 		msg_struct->hdr_req = ( message_hdr_req* ) malloc( sizeof( message_hdr_req ) );
       
   115 		if ( NULL == msg_struct->hdr_req ) 
       
   116 			{
       
   117 			//An error has occured, so propagate to next level
       
   118 			free_msg_args( contactid, contact_count, msg );
       
   119 			free ( msg_struct );
       
   120 			return MEM_ALLOCATION_ERROR;
       
   121 			}
       
   122 		//initalize to 0...
       
   123 	    memset( msg_struct->hdr_req, '\0', sizeof( message_hdr_req ) );
       
   124 	    //read message header from buffer
       
   125 	    memcpy( msg_struct->hdr_req, buf, sizeof( message_hdr_req ) );
       
   126 	    //message, msg can be NULL as well
       
   127 	    msg_struct->msg = msg;
       
   128 	    
       
   129 		meesage_type_err = modify_contact_list( msg_struct, 
       
   130 				( const char** )contactid, meesage_type_err );	
       
   131 		if ( meesage_type_err < 0 ) 
       
   132 			{
       
   133 			//Do cleanup here
       
   134 			//delete contact_ids and message
       
   135 			//An error has occured, so propagate to next level
       
   136 			free_msg_args( contactid, contact_count, msg );
       
   137 			free ( msg_struct->hdr_req );
       
   138 			free ( msg_struct );
       
   139 			return meesage_type_err;
       
   140 			}
       
   141 		}
       
   142 	
       
   143 	iso_logger( "%s", "In - action_parse_modify_contact_list" );	
       
   144 		
       
   145 	return meesage_type_err;	
       
   146 	}
       
   147 
       
   148 
       
   149 /*!
       
   150  *  /brief gets the handles for contacts. Handles are returned in request_modify_contact_list_handles_cb 
       
   151  *  callback which is an arg for the async request to get handles.
       
   152  *  
       
   153  *  /param msg_hdr : The header and message passed to callbacks
       
   154  *  /param contact_id : contact ids whose handles to be returned
       
   155  *  /param no_cntcts : total no. of contacts to be added
       
   156  *  /return : error code if any, handle on success 
       
   157  */
       
   158 guint get_handles_for_contacts ( send_msg_struct* msg_hdr, const gchar  **contact_id, 
       
   159 		gint no_cntcts )
       
   160 	{
       
   161 	
       
   162 	iso_logger( "%s", "in -- get_handles_for_contacts" );
       
   163 	
       
   164 	//check for the return value if 0 is ok or should some negative value to be passed
       
   165 	g_return_val_if_fail (contact_id != NULL, 0); 	
       
   166 
       
   167 	//Send request to get the handles for the contacts..
       
   168 	//handles will be returned in request_addcontacts_handles_cb
       
   169 	tp_conn_request_handles_async( DBUS_G_PROXY(globalCon.conn), 
       
   170 			TP_CONN_HANDLE_TYPE_CONTACT, contact_id, 
       
   171 	 		request_modify_contact_list_handles_cb, ( gpointer )msg_hdr );
       
   172 	 		
       
   173 	iso_logger( "%s", "in -- get_handles_for_contacts" );
       
   174 	//no of contacts is returned on successful completion of getting handles
       
   175 	return no_cntcts;
       
   176 	}
       
   177 
       
   178 
       
   179 /*!
       
   180  *  /brief Handles are returned in this callback. Which will then actually do modify 
       
   181  *  the contact list based on the request type(add/remove/accept/reject)
       
   182  *  modify_contact_list_cb is registered as the callback.
       
   183  *
       
   184  *  /param proxy : unused
       
   185  *  /param handles : handles of the contacts
       
   186  *  /param error : error if any
       
   187  *  /param message : userdata(send_msg_struct) passed back
       
   188  *  /return : error code if any, handle on success 
       
   189  */     
       
   190 void request_modify_contact_list_handles_cb( DBusGProxy *proxy, GArray *handles, 
       
   191 			GError* error, gpointer message ) 
       
   192 	{
       
   193 	send_msg_struct* msg_hdr = ( send_msg_struct* ) message;
       
   194     UNUSED_FORMAL_PARAM(proxy);
       
   195 	iso_logger( "%s", "in -- request_modify_contact_list_handles_cb" );
       
   196 
       
   197 	if ( !handles || error ) 
       
   198 		{
       
   199 		 send_response_to_client( msg_hdr->hdr_req,  error->code, 0 );
       
   200 		
       
   201 		if ( error ) 
       
   202 			{
       
   203 			g_error_free(error);
       
   204 			}
       
   205 		free ( msg_hdr->msg );
       
   206 		free ( msg_hdr->hdr_req );
       
   207 		free ( msg_hdr );
       
   208 		iso_logger( "%s", "handle got is invalid" );
       
   209 		return;
       
   210 		}
       
   211 		
       
   212 	//Check if the request is to add contact or delete contact
       
   213 	if ( EAdd_Contact_Request == msg_hdr->hdr_req->message_type ) 
       
   214 		{
       
   215 		//got the handles for contacts now send request to add those contacts
       
   216 		tp_chan_iface_group_add_members_async ( globalCon.group_iface_subscribe, handles, 
       
   217 			msg_hdr->msg, modify_contact_list_cb, msg_hdr->hdr_req );
       
   218 		}
       
   219 	else if ( EDelete_Contact_Request == msg_hdr->hdr_req->message_type ) 
       
   220 		{
       
   221 		//got the handles for contacts now send request to delete those contacts
       
   222 		tp_chan_iface_group_remove_members_async ( globalCon.group_iface_known, handles, 
       
   223 			msg_hdr->msg, modify_contact_list_cb, msg_hdr->hdr_req );	
       
   224 		}
       
   225 	else if ( EAccept_Contact_Request == msg_hdr->hdr_req->message_type ) 
       
   226 		{
       
   227 		//got the handles for contacts now send request to add those contacts
       
   228 		tp_chan_iface_group_add_members_async ( globalCon.group_iface_publish, handles, 
       
   229 			msg_hdr->msg, modify_contact_list_cb, msg_hdr->hdr_req );
       
   230 		}
       
   231 	else if ( EReject_Contact_Request == msg_hdr->hdr_req->message_type ) 
       
   232 		{
       
   233 		//got the handles for contacts now send request to delete those contacts
       
   234 		tp_chan_iface_group_remove_members_async ( globalCon.group_iface_publish, handles, 
       
   235 			msg_hdr->msg, modify_contact_list_cb, msg_hdr->hdr_req );	
       
   236 		}
       
   237 			
       
   238 	//free handles
       
   239 	g_array_free ( handles, TRUE );
       
   240 	//free header
       
   241 	//hdr_req not to be freed, it is freed by modify_contact_list_cb
       
   242 	free ( msg_hdr->msg );
       
   243 	free ( msg_hdr );
       
   244 	iso_logger( "%s", "out -- request_modify_contact_list_handles_cb" );	
       
   245 	}
       
   246 	
       
   247 /*!
       
   248  *  /brief Calls get_handles_for_contacts to get the handles for contact. 
       
   249  * 
       
   250  *  /param msg_hdr : message request header passed to callbacks
       
   251  *  /param contact_id : contact ids to be added
       
   252  *  /param message : messgae if any
       
   253  *  /param no_cntcts : no of contacts to be added
       
   254  *  /return void 
       
   255  */
       
   256 gint modify_contact_list ( send_msg_struct* msg_hdr, const gchar  **contact_ids, 
       
   257 				gint no_cntcts )
       
   258 	{
       
   259 
       
   260 	guint err = 0;
       
   261 	
       
   262 	iso_logger( "%s", "in -- modify_contact_list" );	
       
   263 	
       
   264 	//g_array_append_val ( handles, handle );
       
   265 	//gets the handles for contacts
       
   266 	//Handles are returned in request_addcontacts_handles_cb callback
       
   267 	err = get_handles_for_contacts( msg_hdr, contact_ids, no_cntcts );
       
   268 	
       
   269 	iso_logger( "%s", "Out -- -- modify_contact_list" );
       
   270 	
       
   271 	return err;
       
   272 	
       
   273 	 	
       
   274 	}
       
   275 
       
   276 /*!
       
   277  *  /brief called as callback for request for modify contact list 
       
   278  *  This function then sends the result to client
       
   279  * 
       
   280  *  /param proxy unused 
       
   281  *  /param error Error if any
       
   282  *  /param userdata request message header
       
   283  *  /return void 
       
   284  */
       
   285 void modify_contact_list_cb( DBusGProxy *proxy, GError *error, gpointer userdata )
       
   286 	{
       
   287 	
       
   288 	int err = 0;
       
   289 	//user data is of type message_hdr_req
       
   290 	message_hdr_req *msg_hdr = ( message_hdr_req * )userdata;
       
   291 	UNUSED_FORMAL_PARAM(proxy);	
       
   292 	iso_logger( "%s", "In - modify_contact_list_cb\n" );
       
   293 	//Check if there is any error
       
   294 	if ( NULL != error ) 
       
   295 		{
       
   296 		//Failed to add contact:
       
   297 		iso_logger ( "%s", "Failed to modify contact: \n" );	
       
   298 			
       
   299 		err = send_response_to_client( msg_hdr,  error->code, 0 );
       
   300 		g_error_free(error);
       
   301 		}
       
   302 	else 
       
   303 		{
       
   304 		//Contact added successfully:
       
   305 		iso_logger ( "%s", "Contact modify successfully:" );			
       
   306 		err = send_response_to_client( msg_hdr, 0, 1 );
       
   307 		}
       
   308 	//free the msg hdr
       
   309 	free( msg_hdr );
       
   310 
       
   311 	if ( err < 0 )
       
   312 		{
       
   313 		// failed to delievered	
       
   314 		return ;
       
   315 		}
       
   316 	iso_logger( "%s", "out -- modify_contact_list_cb" );			     	
       
   317 	}
       
   318 
       
   319 
       
   320 /*!
       
   321  *  /brief The contact names corresponding to the contact handles that are changed 
       
   322  *  are passed to the client
       
   323  *  /param proxy 
       
   324  *  /param handles_name
       
   325  *  /param error
       
   326  *  /param userdata
       
   327  *  /return void 
       
   328  */
       
   329 static void rosters_changed_contacts_cb( DBusGProxy *proxy,
       
   330 	gchar **handles_names, GError *error, gpointer userdata )
       
   331 	{
       
   332 	gint i = 0;
       
   333 	gchar* member = NULL;
       
   334 	gint mem_count = 0;
       
   335 	
       
   336 	gint* msg_type = ( gint* ) userdata;
       
   337 	
       
   338 	iso_logger( "%s", "In -- rosters_changed_contacts_cb" );
       
   339 	UNUSED_FORMAL_PARAM(proxy);
       
   340 	if ( !handles_names || error )
       
   341 		{
       
   342 		if ( error ) 
       
   343 			{
       
   344 			g_error_free(error);	
       
   345 			}
       
   346 		free ( msg_type );
       
   347 		iso_logger( "%s", "handle names error" );
       
   348 		return;
       
   349 		}
       
   350 	
       
   351 	//read all the contacts
       
   352 	//The handles_names will have NULL as it last elemnt in the array
       
   353 	for ( i = 0; handles_names[i]; i++ ) 
       
   354 		{
       
   355 		member = handles_names[i];
       
   356 		iso_logger( "This member : %s is trying to add you", 
       
   357 			member );
       
   358 		mem_count++;
       
   359 		}
       
   360 	//code to send the added contact to client
       
   361 	if ( mem_count ) 
       
   362 		{
       
   363 		gint err = 0;
       
   364 		err = send_contacts_to_client( handles_names, mem_count, *msg_type );	
       
   365 		if ( err ) 
       
   366 			{
       
   367 			//How to handle the error?
       
   368 			for ( i = 0; i < mem_count; i++ ) 
       
   369 				{
       
   370 				free ( handles_names[i] );
       
   371 				}
       
   372 			iso_logger( "%s", "There was error in send_contacts_to_client" );
       
   373 			free ( msg_type );
       
   374 			return;
       
   375 			}	
       
   376 		}
       
   377 	
       
   378 	free ( msg_type );
       
   379 	
       
   380 	iso_logger( "%s", "Out -- rosters_changed_contacts_cb" );
       
   381 	
       
   382 	}
       
   383 	
       
   384 /*! /brief Whenever contact list is changed by others( someone trying to add this user
       
   385  *  or someone rejecting the add request etc., ) this callback registered as a signal
       
   386  *  is called with the handles of the changed contacts. rosters_changed_contacts_cb is
       
   387  *  passed as callback to get the contact name of the changed handles
       
   388  * 
       
   389  * /param group_iface unused 
       
   390  * /param message unused
       
   391  * /param added List of contacts that are recently added
       
   392  * /param removed List of contacts that were recently removed
       
   393  * /param local_pending List of contacts that are locally pending for approval
       
   394  * /param remote_pending List of contacts that are remotely pending for approval
       
   395  * /param actor unused
       
   396  * /param reason unused
       
   397  * /param userdata unused
       
   398  * /return void
       
   399  */
       
   400 void roster_members_changed_cb ( DBusGProxy           *group_iface,
       
   401 									    gchar                *message,
       
   402 									    GArray               *added,
       
   403 									    GArray               *removed,
       
   404 									    GArray               *local_pending,
       
   405 									    GArray               *remote_pending,
       
   406 									    guint                 actor,
       
   407 									    guint                 reason,
       
   408 									    gpointer  			  userdata )
       
   409 	{
       
   410 	
       
   411 	gint* msg_type = ( gint* ) malloc ( sizeof( gint* ) );
       
   412 	
       
   413 	iso_logger( "%s", "In - roster_members_changed_cb\n" );
       
   414 
       
   415 	//members in the contact list have changed 
       
   416 	//Get the contact name of the handles thru rosters_changed_contacts_cb
       
   417 	UNUSED_FORMAL_PARAM(message);
       
   418 	UNUSED_FORMAL_PARAM(actor);
       
   419 	UNUSED_FORMAL_PARAM(reason);
       
   420 	UNUSED_FORMAL_PARAM(userdata);
       
   421 	if ( group_iface == globalCon.group_iface_subscribe  && remote_pending 
       
   422 		&& 0 < remote_pending->len ) 
       
   423 		{
       
   424 		*msg_type = ESubscribe_Remote_Pending;
       
   425 		tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ),
       
   426 						  TP_CONN_HANDLE_TYPE_CONTACT ,remote_pending,
       
   427 						  rosters_changed_contacts_cb, msg_type );
       
   428 		}
       
   429 	if ( group_iface == globalCon.group_iface_subscribe  && removed 
       
   430 		&& 0 < removed->len ) 
       
   431 		{
       
   432 		//User is trying to remove the contact from list
       
   433 		//
       
   434 		*msg_type = ESubscribe_Removed_Or_Rejected;
       
   435 		tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ),
       
   436 						  TP_CONN_HANDLE_TYPE_CONTACT ,removed,
       
   437 						  rosters_changed_contacts_cb, msg_type );
       
   438 		}
       
   439 	if ( group_iface == globalCon.group_iface_subscribe  && added 
       
   440 		&& 0 < added->len ) 
       
   441 		{
       
   442 		//
       
   443 		*msg_type = ESubscribe_RP_Accepted;
       
   444 		tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ),
       
   445 						  TP_CONN_HANDLE_TYPE_CONTACT ,added,
       
   446 						  rosters_changed_contacts_cb, msg_type );
       
   447 		}
       
   448 	if ( group_iface == globalCon.group_iface_publish  && added
       
   449 		&& 0 < added->len ) 
       
   450 		{
       
   451 		*msg_type = EPublish_RP_Accepted;
       
   452 		tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ),
       
   453 						  TP_CONN_HANDLE_TYPE_CONTACT ,added,
       
   454 						  rosters_changed_contacts_cb, msg_type );
       
   455 		}
       
   456 		
       
   457 	if ( group_iface == globalCon.group_iface_publish  && local_pending 
       
   458 		&& 0 < local_pending->len ) 
       
   459 		{
       
   460 		*msg_type = ETrying_To_Add_Contact_Publish;
       
   461 		tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ),
       
   462 						  TP_CONN_HANDLE_TYPE_CONTACT ,local_pending,
       
   463 						  rosters_changed_contacts_cb, msg_type );
       
   464 		}
       
   465 	if ( group_iface == globalCon.group_iface_publish  && removed 
       
   466 		&& 0 < removed->len ) 
       
   467 		{
       
   468 		*msg_type = EPublish_Removed_Or_Rejected;
       
   469 		tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ),
       
   470 						  TP_CONN_HANDLE_TYPE_CONTACT ,removed,
       
   471 						  rosters_changed_contacts_cb, msg_type );
       
   472 		}
       
   473 	if ( group_iface == globalCon.group_iface_known && removed 
       
   474 		&& 0 < removed->len ) 
       
   475 		{
       
   476 		//User is trying to remove the contact from list
       
   477 		//
       
   478 		*msg_type = ESubscribe_Removed_Or_Rejected;
       
   479 		tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ),
       
   480 						  TP_CONN_HANDLE_TYPE_CONTACT ,removed,
       
   481 						  rosters_changed_contacts_cb, msg_type );
       
   482 		}
       
   483 	if ( group_iface == globalCon.group_iface_known && added 
       
   484 		&& 0 < added->len ) 
       
   485 		{
       
   486 		//User is trying to remove the contact from list
       
   487 		//
       
   488 		*msg_type = ETrying_To_Add_Contact_Known;
       
   489 		tp_conn_inspect_handles_async( DBUS_G_PROXY( globalCon.conn ),
       
   490 						  TP_CONN_HANDLE_TYPE_CONTACT ,added,
       
   491 						  rosters_changed_contacts_cb, msg_type );
       
   492 		}
       
   493 	       
       
   494 	//log message 					       
       
   495 	iso_logger( "%s", "out - roster_members_changed_cb\n" );
       
   496 	}
       
   497