diff -r 000000000000 -r d0f3a028347a isolationserver/isoserver/src/isoservermain.c --- /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 + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#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; + }