isolationserver/isoserver/src/isoservermain.c
changeset 0 d0f3a028347a
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/isolationserver/isoserver/src/isoservermain.c	Tue Feb 02 01:10:06 2010 +0200
@@ -0,0 +1,496 @@
+/*
+* ============================================================================
+*  Name        : isoservermain.c
+*  Part of     : isolation server.
+*  Version     : %version: 33 %
+*
+*  Copyright © 2007-2008 Nokia.  All rights reserved.
+*  All rights reserved.
+*  Redistribution and use in source and binary forms, with or without modification, 
+*  are permitted provided that the following conditions are met:
+*  Redistributions of source code must retain the above copyright notice, this list 
+*  of conditions and the following disclaimer.Redistributions in binary form must 
+*  reproduce the above copyright notice, this list of conditions and the following 
+*  disclaimer in the documentation and/or other materials provided with the distribution.
+*  Neither the name of the Nokia Corporation nor the names of its contributors may be used 
+*  to endorse or promote products derived from this software without specific prior written 
+*  permission.
+*  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
+*  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
+*  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+*  SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+*  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+*  OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
+*  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
+*  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
+*  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+* ============================================================================
+* Template version: 1.0
+*/
+
+
+#include <glib.h>
+
+#include <gtypes.h>
+#include <sys/types.h>   
+#include <stdlib.h>
+#include <string.h>
+
+#include <netinet/in.h>
+#include <stdio.h>  
+#include <netdb.h>
+#include <unistd.h>
+#include <errno.h>
+#include "msgqlib.h"
+#include "msg_enums.h"
+#include "msgliterals.h"
+#include "isoservermain.h"
+#include "isoim.h"
+#include "isoconnectionmanager.h"
+#include "isomodifycontactlist.h"
+#include "isoutils.h"
+#include "isopresence.h"
+#include "isoutils.h"
+#include "isoavtar.h"
+#include "isosearch.h"
+#include "isogetsearchkeys.h"
+#include "isofetchcontactlist.h"
+
+/*!	\file 
+*	Impliments the functions in isoservermain.h
+*/
+
+/*!	\def Thread stack size
+*/
+#define THREAD_STACK_SIZE	26000
+
+/*! \var mainloop_struct global variable having a pointer to mainloop
+*/
+globalMainloop mainloop_struct;
+
+/*!	\var globalCon one object per login session
+*/
+userConnection globalCon;
+
+
+/*! /brief This message reads message type from the message buffer
+*   passed as argument
+*
+*   /var pc message buffer
+*   
+*   /return pointer to message header response which has the message type
+*/
+message_hdr_resp* read_message_type( gchar* buf ) 
+	{
+	
+	message_hdr_resp *msg_hdr = NULL;
+	iso_logger( "%s", "In - read_message_type\n" );
+	//allocate memory and check for error
+	msg_hdr = ( message_hdr_resp* ) malloc( sizeof( message_hdr_resp ) );
+	if ( NULL == msg_hdr ) 
+		{
+		return NULL;	
+		}
+	//initialze memory to 0
+    memset( msg_hdr, '\0', sizeof( message_hdr_resp ) );
+    //read message request header from buffer
+    memcpy( msg_hdr, buf, sizeof( message_hdr_req ) );
+    iso_logger( "%s", "Out - read_message_type\n" );
+    //return message header read from buffer
+	return msg_hdr;
+	}
+
+/*! /brief This is an entry point to the thread. isoserver.exe
+*   creates a thread which runs a mainloop. mainloop is passed as 
+*   argument to the thread entry function. This mainloop which is 
+*   run in the thread listens for the events from telepathygabble
+*
+*   /var data unused param
+*/
+gpointer thread_entry( gpointer data ) 
+	{
+	UNUSED_FORMAL_PARAM(data);
+	//wait till status_changed_cb to happen
+	//The only main loop is run in a thread..
+	iso_logger( "%s", "In - thread_entry\n" );
+	//run the mainloop in thread..
+	g_main_loop_run( mainloop_struct.mainloop ); 
+	iso_logger( "%s", "Out - thread_entry\n" );
+	return NULL;
+	}
+	
+/*! /brief If there are any parse error, this function is called to
+*   dispatch the error to client.
+*   
+*   /param msg_struct The response header to be sent 
+*   /param err Error
+*/
+gint send_error( message_hdr_resp* msg_struct, gint err )	
+	{
+	int result = 0;
+	int pri = MSG_PRI_NORMAL;
+	int timeout = NO_WAIT; 
+	int error = 0;  
+	
+	//set the error and reason
+	msg_struct->error_type = err;
+	//Since this is method to send error
+	//response is always 0
+	msg_struct->response = 0;
+	
+	//request has fialed send appr. response
+	result = MsgQCreate( RESPONSE_QUEUE, MAX_MSG_Q_SIZE, MSG_Q_FIFO, &error );
+	if ( ERROR == result )
+		{
+		//graceful exit?
+		return ERROR;
+		}
+		
+	//send message created to client		
+	result = MsgQSend( RESPONSE_QUEUE, (void*)msg_struct, sizeof( message_hdr_resp ),
+			 pri, timeout, &error );
+			
+	if( result != 0 )
+		{
+		// msg deliver falied 
+		return MSG_Q_SEND_FAILED;
+		}
+	return 0;	
+	}
+	
+/*! /brief This function waits for the requests from the client.
+*   Requests are parsed, validated and appropriate actions taken.
+*   A new thread is created when login happens. This function runs 
+*   a while loop which is only quit when a kill request is recieved 
+*   from the client.
+*
+*   /remark should this thread be created before login?
+*   /remark when is the mainloop quit ? (Should that be after logout or 
+*   after getting a kill request from the client)
+*/
+int message_send_recv() 
+	{
+    
+	int err = 0;
+	int result = 0;
+	int timeout1 = TIME_OUT; // block for 100 ms
+	char rmsg[MAX_MSG_SIZE];  // 1024 bytes
+	GMainLoop* mainloop = NULL;
+	GThread* join1 = NULL;
+	message_hdr_resp* msg_struct = NULL;
+	GArray* avtarcontent = NULL;
+	
+	globalCon.conn_stat = disconnected;
+	globalCon.logout_flag = 0;
+
+	/* Try to Create queueOne again, this will create the queue again,
+	   this will just return as its already created by main thread */
+	iso_logger( "%s", "In - message_send_recv\n" );
+	
+	result = MsgQCreate(REQUEST_QUEUE, MAX_MSG_Q_SIZE, MSG_Q_FIFO, &err);
+	
+	//logic here to accept multiple clients
+	mainloop = g_main_loop_new ( NULL, FALSE ); //global mainloop
+	
+	
+	if ( ERROR == result || NULL == mainloop )
+		{
+		return ERROR;
+		}
+	
+	mainloop_struct.mainloop = mainloop;
+
+	while( 1 ) 
+		{
+			
+		//initalize memory to 0
+		memset( rmsg, '\0', MAX_MSG_SIZE );
+		// Receive Message from queueTwo 
+		result = MsgQReceive(REQUEST_QUEUE, rmsg, MAX_MSG_SIZE, timeout1, &err); 
+		
+		//MRT bug - 4 more bytes recieved than sent..
+		result -= 4; 
+
+
+		//The message should be atleast of size msg_hdr_req
+		//sizeof should be type casted to gint 
+		//coz when comparing gint and guint(sizeof return value) 
+		//gint is converted to guint
+		if( result >= ( gint )sizeof( message_hdr_req ) )
+			{
+			gboolean stat_err = FALSE;
+			// read message header and get type..
+			msg_struct = read_message_type( rmsg );
+			if ( NULL == msg_struct ) 
+				{
+				//needs to be discussed what can be done..
+				//should exit from here?
+				return MEM_ALLOCATION_ERROR;	
+				}
+			switch( globalCon.conn_stat )
+			    {
+			    case connected:
+			        {
+			            //switch to the message type, where action to be performed
+			            //is decided dpending on the message type
+			            switch ( msg_struct->hdr_req.message_type ) 
+			            {
+                            
+                        case ESend_Request:
+                            {
+                            iso_logger( "%s", "In - ESend_Request\n" );
+                            //parse the request and 
+                            // send the request to telepathy
+                            err = action_parse_send( rmsg, result );
+                            if ( err < 0 ) 
+                                {
+                                //Send request has failed..
+                                //send the error code to the client
+                                send_error( msg_struct, err );
+                                }
+                        
+                            break;
+                            }
+                        case EUpdateOwnPresence:
+                            {
+                            iso_logger( "%s", "In - EUpdateOwnPresence\n" );
+                            //parse the request and 
+                            // send the request to telepathy
+                            err = action_parse_presence( rmsg, result );
+                            if ( err < 0 ) 
+                                {
+                                //Send request has failed..
+                                //send the error code to the client
+                                send_error( msg_struct, err );
+                                }
+                        
+                            break;
+                            } 
+                        //For accept, add and delete same function does the job
+                        //depending on the message type that is passed with rmsg
+                        case EReject_Contact_Request:
+                        
+                        case EAccept_Contact_Request:
+                        
+                        case EAdd_Contact_Request:
+                        
+                        case EDelete_Contact_Request:
+                            {
+                            iso_logger( "%s", "In - modify Contact \n" );
+                            //Parse the request for to add contact and 
+                            //request telepathy to add contact
+                            err = action_parse_modify_contact_list( rmsg, result );
+                            if ( err < 0 ) 
+                                {
+                                //addcontacts has fialed send appr. response
+                                send_error( msg_struct, err );
+                                }
+                        
+                            break;
+                            }
+                        
+                        case ESearch:
+                            {
+                            iso_logger( "%s", "In - ESearch\n" );
+                            //parse the request and 
+                            // send the request to telepathy
+                            err = action_parse_search( rmsg, result );
+                            if ( err < 0 ) 
+                                {
+                                //Send request has failed..
+                                //send the error code to the client
+                                iso_logger( "%s %d", "error in - ESearch error code:", err );
+                                send_error( msg_struct, err );
+                                }
+                            break;                      
+                            }
+                            
+                        case ESearch_Get_Keys:
+                            {
+                            iso_logger( "%s", "In - ESearch_Get_Keys\n" );
+                            err = get_search_keys( msg_struct );
+                            
+                            if ( err < 0 ) 
+                                {
+                                //Send request has failed..
+                                //send the error code to the client
+                                iso_logger( "%s %d", "error in - ESearch_Get_Keys error code:", err );
+                                send_error( msg_struct, err );
+                                }
+                                
+                            break;
+                            }
+                        case ELogout_Request:
+                            {
+                            //Message type is to logout
+                            iso_logger( "%s", "In - logout\n" );
+                            globalCon.conn_stat = disconnecting;
+                            action_logout( rmsg );
+                            //globalCon.logout_flag = 1;
+                            break;  
+                            }
+                        case EUpdateOwnAvtar:
+                           {
+                           err = update_own_avatar( rmsg,msg_struct,result, &avtarcontent);
+                           if ( err < 0 ) 
+                               {
+                               //Send request has failed..
+                               //send the error code to the client
+                               iso_logger( "%s %d", "error in - ESearch_Get_Keys error code:", err );
+                               send_error( msg_struct, err );
+                               }                     
+                           break;
+                           }
+                        case EClearOwnAvatar:
+                            {
+                            err = clear_avatar( &(msg_struct->hdr_req) );
+                            if ( err < 0 ) 
+                               {
+                               //Send request has failed..
+                               //send the error code to the client
+                               send_error( msg_struct, err );
+                               }
+                            break;
+                            }
+                        case EFetchCachedContacts:
+                            fetch_cached_contacts();
+                            break;
+                            
+                        default:
+                            {
+                            iso_logger( "%s", "In - default state is connected\n" );
+                            stat_err = TRUE;
+                            break;  
+                            }
+                        
+                         }
+			        }
+			        break;
+			    case disconnected:
+			        switch( msg_struct->hdr_req.message_type )
+                    {
+                    case ELogin_Request:
+                        {
+                        //parse the message buffer and login
+                        iso_logger( "%s", "In - login\n" );
+                        //parses the request message and does a login 
+                        //if all the parameters are correct
+                        globalCon.conn_stat = connecting;
+                        err = action_parse_login( rmsg, result );
+                        //If there is no error in login create a new thread
+                        //where mainloop will be run..
+                        if ( !err )  
+                            {
+                            //Create a thread for the mainloop to run..
+                            //Thread entry does a run on mainloop
+                            join1 = g_thread_create_full( thread_entry, mainloop, 
+                                    THREAD_STACK_SIZE, TRUE, FALSE,
+                                    G_THREAD_PRIORITY_NORMAL , NULL );  
+                        
+                            
+                            }
+                        else 
+                            {
+                            //There was some error while loging in.. send the error 
+                            //to client
+                            globalCon.conn_stat = disconnected;
+                            send_error( msg_struct, err );
+                            }
+                        break;
+                        }
+                        
+                    default:
+                        {
+                        iso_logger( "%s", "In - default state is disconnected\n" );
+                        stat_err = TRUE;
+                        }
+                    }
+			        break;
+			    case not_connected:
+			        switch( msg_struct->hdr_req.message_type )
+			            {
+			            case  EKill_Process :
+                            {
+                            //no need to change the state as anyways it is going to be killed
+                            //globalCon.conn_stat = not_connected;
+                            globalCon.logout_flag = 1;
+                            break;
+                            }
+			            default:
+                            {
+                            iso_logger( "%s", "In - default state is not_connected\n" );
+                            stat_err = TRUE;
+                            }
+			            }
+			        break;
+			    default:
+			        {
+			        iso_logger( "%s", "In - default state connecting or disconnecting \n" );
+                    stat_err = TRUE;
+                    break;  
+                    }
+			    }
+			if ( stat_err )
+			    {
+			    stat_err = FALSE;
+			    iso_logger( "%s", "In - stat_err true \n" );
+			    send_error( msg_struct, CONNECTION_STATUS_ERROR );
+			    }
+			if ( globalCon.logout_flag ) 
+				{
+				//quit mainloop before exiting the thread and then server
+				//quiting mainloop will inturn make the thread to fall off
+				g_main_loop_quit( mainloop_struct.mainloop );
+				iso_logger( "%s", "logout flag break \n" );
+				break;					
+				}
+			free ( msg_struct );
+
+			}
+		else 
+			{
+			break;			
+			}
+		}
+	iso_logger( "%s", "In - g_thread_join\n" );
+	
+	
+
+	//join the thread created for to run mainloop before exiting
+	g_thread_join( join1 );	
+	iso_logger( "%s", "After this should be after mainloop quit - g_thread_join\n" );
+	
+	/* delete message queueOne */
+	result=MsgQDelete( REQUEST_QUEUE, &err );
+	
+	iso_logger( "%s", "Out - MsgQDelete\n" );
+	return 0;
+	}
+
+/*! \brief server main process which listens to requests from client
+*	and processes those requests. A new thread is created to listen to
+*	the events from the telepathygabble. 
+*/
+int main()
+	{
+	int err = 0;
+	//FILE *fp = NULL;
+	    
+	g_type_init();
+	
+	g_thread_init( NULL );/*
+	_dbus_setenv("DBUS_VERBOSE","1");
+	fp= freopen("c:\\iso-dbus.txt", "a",stderr);*/
+	iso_logger( "%s", "In - main\n" );
+	//wait in a loop to accept requests from the client
+	//Can mainloop be used instead of waiting in a loop?
+	err = message_send_recv();
+	if ( err != 0 ) 
+		{
+		printf("exit err code is %d\n", err );	
+		}
+	iso_logger( "%s", "Out - main\n" );
+	
+	//fclose(fp);
+	return 0;
+	}