--- /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;
+ }