diff -r 000000000000 -r d0f3a028347a isolationserver/isoserver/src/isoconnectionmanager.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/isolationserver/isoserver/src/isoconnectionmanager.c Tue Feb 02 01:10:06 2010 +0200 @@ -0,0 +1,829 @@ +/* +* ============================================================================ +* Name : isoconnectionmanager.c +* Part of : isolation server. +* Version : %version: 24 % +* +* 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 "isoconnectionmanager.h" +#include "isomodifycontactlist.h" //For roster_members_changed_cb +#include "isoutils.h" //for loger and othr func +#include "isofetchcontactlist.h" //For request_roster + +#include "msgliterals.h" +#include "isoservermain.h" +#include "isopresence.h" +#include "isosearch.h" +#include "msg_enums.h" + +enum disconnect_reason + { + EConnection_Status_Reason_None_Specified = 0, + EConnection_Status_Reason_Requested, + EConnection_Status_Reason_Network_Error, + EConnection_Status_Reason_Authentication_Failed, + }; +//userConnection globalCon; + +/*! \file +* Impliments the functions in isoconnectionmanager.h +*/ + +/*! \brief Documented in the header file +*/ +static void check_conn_properties(TpConn *conn) +{ + TpPropsIface *pres_iface; + + pres_iface = TELEPATHY_PROPS_IFACE (tp_conn_get_interface ( + conn, TELEPATHY_CONN_IFACE_PRESENCE_QUARK)); + if (pres_iface != NULL) + { + globalCon.pres_iface = pres_iface; + dbus_g_proxy_connect_signal(DBUS_G_PROXY(pres_iface), + "PresenceUpdate", + G_CALLBACK(telepathy_presence_handler), + NULL, NULL); + } + else + { + g_warning ("The connection object does not support " TP_IFACE_PROPERTIES); + } +} + +/*! \brief This function is registered in action_login for statuschanged signal. + * This function is called by telepathygabble when the status of the user changes + * Once user is connected this function registers for NewChannel signal with telepathygabble + * client is also informed of the status change.. + * + * \param proxy + * \param status status of the user ( connected/connecting/disconnected ) + * \param reason reason for status change(server disconnected/ user requested etc.,) + * \param user_data message header request + * + * \return : Boolean True on success, false on failure + */ + +static gboolean status_changed_cb(DBusGProxy *proxy, + guint status, guint reason, + gpointer user_data) + { + + + int err = 0; + + message_hdr_req* hdr_req = ( message_hdr_req* )user_data; + // create the msg queue + iso_logger( "%s", "In - status_changed_cb\n" ); + + //switch to the connection status + switch ( status ) + { + case EConnected: + { + //Connected.. + iso_logger( "%s", "connected\n" ); + //Get connection interfaces + check_conn_properties(TELEPATHY_CONN(proxy)); + //Connect to the signal for new channels + dbus_g_proxy_connect_signal( DBUS_G_PROXY( globalCon.conn ), "NewChannel", + G_CALLBACK( new_channel_handler ), + NULL, NULL ); + //send response to client.. + err = send_response_to_client( hdr_req, reason, 1 ); + //hdr_req would be freed here + //Disconnect the previous signal for connected + //This is to pass the diff msg hdr as cb userdata for disconnect + /*dbus_g_proxy_disconnect_signal( DBUS_G_PROXY( globalCon.conn ), StatusChangedStr, + G_CALLBACK( status_changed_cb ), + hdr_req );*/ + + globalCon.conn_stat = connected; + break; + } + case EConnecting: + {//Connecting.. + iso_logger( "%s", "connecting\n" ); + //already done after creating the thread + //globalCon.conn_stat = connecting; + break; + } + case ENotConnected: + { + //DisConnected.... + //Set the reason for disconnection + iso_logger( "%s : %d : %s : %d", "disconnected and reason is", reason, "state is ", globalCon.conn_stat ); + //reset the flag to not connected + + //should here be not_connected != globalCon.conn_stat && disconnected != globalCon.conn_stat + //and all login errors should set the conn_stat to disconnected + if ( not_connected != globalCon.conn_stat && disconnected != globalCon.conn_stat ) + { + int success = 1; + int error = 0; + + action_logedout(); + + //switch for the reason of logout + switch ( reason ) + { + //set appropriate message types and error if any + case EConnection_Status_Reason_None_Specified: + if ( connecting == globalCon.conn_stat ) + { + //not yet connected and user has cancelled the a/p + hdr_req->message_type = ELogin_Request; + error = ELOGIN_NONE_SPECIFIED; + success = 0; + } + else { + //connected and user has cancelled the a/p + //state is going to be not connected as fr these cases ossadaptation is + //going to send handle request terminated signal + hdr_req->message_type = EUserEndGprs; + + } + + break; + case EConnection_Status_Reason_Requested: + hdr_req->message_type = ELogout_Request; + + break; + case EConnection_Status_Reason_Network_Error: + if ( connecting == globalCon.conn_stat ) + { + //not yet connected and user has cancelled the a/p + hdr_req->message_type = ELogin_Request; + error = ELOGIN_NETWORK_ERROR; + success = 0; + } + else { + //state is going to be not connected as fr these cases ossadaptation is + //going to send handle request terminated signal + hdr_req->message_type = EServer_DisConnect_Request; + + } + + break; + case EConnection_Status_Reason_Authentication_Failed: + hdr_req->message_type = ELogin_Request; + error = ELOGIN_AUTHENTICATION; + success = 0; + + break; + default: + hdr_req->message_type = ELogin_Request; + error = ELOGIN_AUTHORIZATION; + success = 0; + + break; + + } + //to set to no more requests allowed + globalCon.conn_stat = not_connected; + + err = send_response_to_client( hdr_req, error, success ); + + } + + break; + } + default: + { + break; + } + + } + + if ( 0 != err ) + { + //failed + return ERROR; + } + iso_logger( "%s", "out - status_changed_cb\n" ); + return TRUE; + } + +/*! \brief new_channel_handler is registered as a callback for any new + * channels craetion request, in function status_changed_cb after status is changed + * to log in. new_channel_handler creates channel and also registers for the signals + * MembersChanged for contact related channels and Recieved and SendError for IM + * related channels. + * + * \param proxy unused + * \param object_path object path of the channel + * \param channel_type used to get a new channel + * \param handle_type used to get a new channel, channel handle type + * \param handle used to get a new channel, channel handle + * \param suppress_handler unused + * \param user_data unused + * + * \return void + */ +static void new_channel_handler( DBusGProxy *proxy, const char *object_path, + const gchar *g_channel_type, guint handle_type, + guint handle, gboolean suppress_handler, + gpointer user_data ) + { + + TpChan *new_chan = NULL; + UNUSED_FORMAL_PARAM(proxy); + UNUSED_FORMAL_PARAM(suppress_handler); + UNUSED_FORMAL_PARAM(user_data); + iso_logger( "%s", "In - new_channel_handler\n" ); + + //create new channel + new_chan = tp_chan_new( globalCon.dbusConn, + globalCon.connmgr_bus, object_path, + g_channel_type, handle_type, handle ); + + if ( !new_chan ) + { + return ; + } + + + if ( strcmp( g_channel_type, TP_IFACE_CHANNEL_TYPE_CONTACT_LIST ) == 0 + && ( g_strrstr(object_path, "RosterChannel/known" ) ) ) + { + //channel type is contact rosters.. + //request for the roster + + globalCon.group_iface_known = + tp_chan_get_interface( new_chan, + TELEPATHY_CHAN_IFACE_GROUP_QUARK); + //register for the members changed signal + dbus_g_proxy_connect_signal (globalCon.group_iface_known, "MembersChanged", + G_CALLBACK (roster_members_changed_cb), + NULL, NULL); + + } + else if ( strcmp( g_channel_type, TP_IFACE_CHANNEL_TYPE_CONTACT_LIST ) == 0 + && ( g_strrstr(object_path, "RosterChannel/publish" ) ) ) + { + //channel type is contact rosters.. + //request for the roster + + globalCon.group_iface_publish = + tp_chan_get_interface( new_chan, + TELEPATHY_CHAN_IFACE_GROUP_QUARK); + //register for the members changed signal + dbus_g_proxy_connect_signal (globalCon.group_iface_publish, "MembersChanged", + G_CALLBACK (roster_members_changed_cb), + NULL, NULL); + + request_roster( EPublish_Channel ); + } + else if ( strcmp( g_channel_type, TP_IFACE_CHANNEL_TYPE_CONTACT_LIST ) == 0 + && (g_strrstr(object_path, "RosterChannel/subscribe") ) ) + + { + //roster fetch should be done using subscribe, as it will give + //current and remote pending members in differnet arrays, that can be sued on ui side + //local pending members can be fetched only using "RosterChannel/publish",that can be fetched if required + + globalCon.group_iface_subscribe = + tp_chan_get_interface( new_chan, + TELEPATHY_CHAN_IFACE_GROUP_QUARK); + + + //register for the members changed signal + dbus_g_proxy_connect_signal (globalCon.group_iface_subscribe, "MembersChanged", + G_CALLBACK (roster_members_changed_cb), + NULL, NULL); + request_roster( ESubscribe_Channel ); + + + } + + //recieve message channel handlers + else if ( ( strcmp( g_channel_type, TP_IFACE_CHANNEL_TYPE_TEXT ) == 0 ) ) + { + //recieve message + if ( globalCon.text_channels == NULL ) + { + globalCon.text_channels = g_hash_table_new_full( g_str_hash, + g_str_equal, + ( GDestroyNotify ) g_free, + ( GDestroyNotify ) g_object_unref ); + } + if ( globalCon.text_channels ) + { + g_hash_table_insert( globalCon.text_channels, + g_strdup( object_path ), new_chan ); + } + + iso_logger( "b4 text_channel_init" ); + //check for new_chan objects for text channel should be loaclly stored/freed + text_channel_init( new_chan ); + } + iso_logger( "%s", "Out - new_channel_handler\n" ); + } + + +/*! \brief Is called after logout.. Any cleanup operations to + * be performed here. Setting isConnected to EFalse, cleaning up + * of resources is done + */ +void action_logedout() + { + + iso_logger( "%s", "In - action_logedout\n" ); + //not quiting the main loop + //release the connection manager + if ( globalCon.connmgr ) + { + g_object_unref ( globalCon.connmgr ); + globalCon.connmgr = NULL; + } + //release the dbus connection + if ( globalCon.dbusConn ) + { + dbus_g_connection_unref ( globalCon.dbusConn ); + globalCon.dbusConn = NULL; + } + //release the connection object + if ( globalCon.conn ) + { + g_object_unref ( globalCon.conn ); + globalCon.conn = NULL; + } + //release the text channels + if ( globalCon.text_channels ) + { + g_hash_table_destroy( globalCon.text_channels ); + globalCon.text_channels = NULL; + } + //release the subscribe interface + if ( globalCon.group_iface_subscribe ) + { + g_object_unref ( globalCon.group_iface_subscribe ); + globalCon.group_iface_subscribe = NULL; + } + //release the publish interface + if ( globalCon.group_iface_publish ) + { + g_object_unref ( globalCon.group_iface_publish ); + globalCon.group_iface_publish = NULL; + } + //release the known interface + if ( globalCon.group_iface_known ) + { + g_object_unref ( globalCon.group_iface_known ); + globalCon.group_iface_known = NULL; + } + + iso_logger( "%s", "Out - action_logedout\n" ); + } + +/*! \brief Callback for the logout + * + * \param proxy : unused + * \param error : unused + * \param userdata : unused + * \return : void + */ +void logout_cb( DBusGProxy *proxy, GError *error, gpointer userdata ) + { + + iso_logger( "%s", "In - logout_cb\n" ); + UNUSED_FORMAL_PARAM(proxy); + UNUSED_FORMAL_PARAM(error); + UNUSED_FORMAL_PARAM(userdata); + iso_logger( "%s", "Out - logout_cb\n" ); + } + +/*! \brief requests for closing of session. Also closes the search channel. + * \remark should not close the search channel + * + * Request for log - out + * \param pc - message which has the request header + * \return : MEM_ALLOCATION_ERROR or 0 + */ +int action_logout( char* pc ) + { + + TpConn* conn = globalCon.conn; + message_hdr_req *msg_hdr = NULL; + + iso_logger( "%s", "In - action_logout\n" ); + + if( globalCon.search_chan ) + { + tp_chan_close_async( DBUS_G_PROXY( globalCon.search_chan ), search_chan_closed_cb, NULL ); + } + + //allocate memory and check for errors + msg_hdr = ( message_hdr_req* ) malloc( sizeof( message_hdr_req ) ); + if ( NULL == msg_hdr ) + { + return MEM_ALLOCATION_ERROR; + } + //intialize the memory to 0s + memset( msg_hdr, '\0', sizeof( message_hdr_req ) ); + //read message header from buffer + memcpy( msg_hdr, pc, sizeof( message_hdr_req ) ); + + //disconnect in async way as glib signal is not workin + tp_conn_disconnect_async( DBUS_G_PROXY( conn ), logout_cb, msg_hdr ); + iso_logger( "%s", "Out - action_logout\n" ); + + return 0; + } + +/*! \brief validates params, gets a dbus, creates a connection manager, + * and connection. Registers for the statuschange + * + * \param ls_hdr login struct + * \return Errors if invalid param or getting dbus, conn mgr or conn fails else 0 + */ +gint action_login( login_struct* ls_hdr ) + { + + DBusGConnection *connection = NULL; + TpConnMgr *connmgr = NULL; + TpConn *conn = NULL; + GError *error = NULL; + + gchar* def1 = NULL; + char* def2 = NULL; + char* def3 = NULL; + + gchar* def4 = NULL; + guint def5 = 0; + gboolean def6 = 0; + + #ifdef __WINSCW__ + gchar* def8 = NULL; + guint def9 = 0; + #endif + + //Build hash table + GHashTable *connection_parameters = NULL; + //initalize the Gvalues + GValue *value1 = g_new0(GValue, 1); + GValue *value2 = g_new0(GValue, 1); + GValue *value3 = g_new0(GValue, 1); + GValue *value4 = g_new0(GValue, 1); + GValue *value5 = g_new0(GValue, 1); + GValue *value6 = g_new0(GValue, 1); + + #ifdef __WINSCW__ + GValue *value9 = g_new0(GValue, 1); + GValue *value10 = g_new0(GValue, 1); + #endif + + //log message + iso_logger( "%s", "In - action_login\n" ); + + //Check if all the mandatory settings are there + if ( NULL == ls_hdr->strs[0] || NULL == ls_hdr->strs[1] || NULL == ls_hdr->strs[2] + || NULL == ls_hdr->strs[4] || NULL == ls_hdr->strs[5] || + NULL == ls_hdr->strs[7] || NULL == ls_hdr->strs[8] || NULL == ls_hdr->strs[9] ) + { + return INVALID_PARAMETERES; + } + //Only for winscw + #ifdef __WINSCW__ + if ( NULL == ls_hdr->strs[10] || NULL == ls_hdr->strs[11] ) + { + return INVALID_PARAMETERES; + } + #endif + + //0 is username + def1 = g_strdup( ls_hdr->strs[0] ); + //1 is passwd + def2 = g_strdup( ls_hdr->strs[1] ) ; + //2 is server addr + def3 = g_strdup( ls_hdr->strs[2] ) ; + if ( NULL != ls_hdr->strs[3] ) + { + //3 is resource + def4 = g_strdup( ls_hdr->strs[3] ) ; + } + else + { + //Fix required from lalitha + //Is this manadatory? or Can this be NULL + def4 = g_strdup( TestId ); + } + //4 is ssl + def5 = atoi( ls_hdr->strs[4] ); + //5 is server port + def6 = atoi( ls_hdr->strs[5] ); + //6 is IapId is not used + //def7 = g_strdup( ls_hdr->strs[6] ) ; + + iso_logger( "username is %s", ls_hdr->strs[0] ); + iso_logger( "server is %s", ls_hdr->strs[2] ); + iso_logger( "resource is %s", ls_hdr->strs[3] ); + iso_logger( "ssl is %s", ls_hdr->strs[4] ); + iso_logger( "server port is %s", ls_hdr->strs[5] ); + iso_logger( "connmgr bus is %s", ls_hdr->strs[7] ); + iso_logger( "connmgr path is %s", ls_hdr->strs[8] ); + iso_logger( "protocol is %s", ls_hdr->strs[9] ); + + + globalCon.connmgr_bus = strdup( ls_hdr->strs[7]); + + if ( NULL == globalCon.connmgr_bus ) + { + return MEM_ALLOCATION_ERROR; + } + + #ifdef __WINSCW__ + //7 is ProxyServer + def8 = g_strdup( ls_hdr->strs[10] ) ; + //proxy port + def9 = atoi( ls_hdr->strs[11] ); + #endif + + //Get DBus - do not change the order of following calls to + //dbus, g_hash_table_new + + + connection = dbus_g_bus_get( DBUS_BUS_SESSION , &error); + + //DBus Connection is NULL + //return with error + if ( connection == NULL ) + { + if ( error ) + { + g_error_free(error); + } + iso_logger( "failed in connection == NULL " ); + return DBUS_CONNECTION_ERROR; + } + /* printf("connected to DBus with connection %p\n", connection);*/ + globalCon.dbusConn = connection; + + //Get connection manager + connmgr = tp_connmgr_new(connection, ls_hdr->strs[7], ls_hdr->strs[8],TP_IFACE_CONN_MGR_INTERFACE); + if ( connmgr == NULL ) + { + iso_logger( "failed in tp_connmgr_new" ); + //Free already allocated resources + //return with error + dbus_g_connection_unref ( globalCon.dbusConn ); + globalCon.dbusConn = NULL; + return TP_CONNMGR_ERROR; + } + + //Create values for hash table + connection_parameters = g_hash_table_new( g_str_hash, g_str_equal ); + if ( NULL == connection_parameters ) + { + //Free already allocated resources + //return with error + g_object_unref (connmgr); + connmgr = NULL; + dbus_g_connection_unref ( globalCon.dbusConn ); + globalCon.dbusConn = NULL; + iso_logger( "failed in g_hash_table_new" ); + return TP_HASHTABLE_ERROR; + } + + //Add AccountStr values to hash table + g_value_init( value1, G_TYPE_STRING ); + g_value_set_string ( value1, def1 ); + g_hash_table_insert( connection_parameters, ( gpointer ) AccountStr, value1 ); + + //Add PasswdStr values to hash table + g_value_init( value2, G_TYPE_STRING ); + g_value_set_string ( value2, def2 ); + g_hash_table_insert( connection_parameters, ( gpointer ) PasswdStr, value2 ); + //Add ServerStr values to hash table + g_value_init(value3, G_TYPE_STRING); + g_value_set_string (value3, def3); + g_hash_table_insert( connection_parameters, ( gpointer ) ServerStr, value3 ); + //Add ResourceStr values to hash table + if ( NULL != def4 ) + { + //This is not mandatory settings item + //so check for NULL value before useing it.. + g_value_init( value4, G_TYPE_STRING ); + g_value_set_string ( value4, def4 ); + g_hash_table_insert( connection_parameters, ( gpointer ) ResourceStr, value4 ); + } + + //Add PortStr values to hash table + g_value_init(value5, G_TYPE_UINT); + g_value_set_uint (value5, def6); + g_hash_table_insert(connection_parameters, ( gpointer ) PortStr, value5); + //Add OldsslStr values to hash table + g_value_init(value6, G_TYPE_BOOLEAN); + g_value_set_boolean (value6, def5); + g_hash_table_insert(connection_parameters, ( gpointer ) OldsslStr, value6 ); + //Settings Only for emulator + #ifdef __WINSCW__ + //Add proxy server values to hash table + g_value_init(value9, G_TYPE_STRING); + g_value_set_string (value9, def8); + g_hash_table_insert(connection_parameters, "https-proxy-server", value9); + + //Add proxy port values to hash table + g_value_init(value10, G_TYPE_UINT); + g_value_set_uint (value10, def9); + g_hash_table_insert(connection_parameters, "https-proxy-port", value10); + #endif + + + //Get connection from connection manager - i.e., Login + conn = tp_connmgr_new_connection( connmgr,connection_parameters, ls_hdr->strs[9] ); + + if ( !conn ) + { + iso_logger( "failed in tp_connmgr_new_connection" ); + //Free already allocated resources + //return with error + g_object_unref (connmgr); + connmgr = NULL; + dbus_g_connection_unref ( globalCon.dbusConn ); + globalCon.dbusConn = NULL; + + g_hash_table_destroy( connection_parameters ); + return TP_CONNECTION_ERROR; + } + + + //register for StatusChanged callback - login / logout + dbus_g_proxy_connect_signal( DBUS_G_PROXY( conn ), StatusChangedStr, + G_CALLBACK( status_changed_cb ), + ls_hdr->hdr_req, NULL ); + //Assign to global variable struct + globalCon.conn = conn; + globalCon.connmgr = connmgr; + globalCon.dbusConn = connection; + //Free + g_hash_table_destroy( connection_parameters ); + iso_logger( "%s", "Out - action_login\n" ); + + return 0; + } + +/*! \brief parses the message buffer and validates the parameters. The values are written + * to ls_hdr + * + * \param aMsgBuffer - buf to be parsed + * \param ls_hdr - login_struct struct to which values are written + * \param msg_len - no. of bytes in the message buffer aMsgBuffer + * + */ + +gint parse_for_login( gchar* msg_buffer, login_struct** msg_struct, int msg_len ) + { + + char* bufPtr = NULL; + gint index = 0; + gint arg_count = 0; + gint str_len = 0; + char *str1 = NULL; + + message_hdr_req *msg_hdr = NULL; + + iso_logger( "%s","In - parse_for_login\n" ); + //Reading of the message_hdr_req is done twice.. + //should be changed to read once.. + //Allocate memory and check for the error + msg_hdr = ( message_hdr_req* ) malloc( sizeof( message_hdr_req ) ); + if ( NULL == msg_hdr ) + { + return MEM_ALLOCATION_ERROR; + } + //initalize memory to zero + memset( msg_hdr, '\0', sizeof( message_hdr_req ) ); + memcpy( msg_hdr, msg_buffer, sizeof( message_hdr_req ) ); + //ownership of msg_hdr is transefred to msg_struct + ( *msg_struct )->hdr_req = msg_hdr; + + bufPtr = msg_buffer + sizeof( message_hdr_req ); + + //validating each arg and copying it.. + + while ( arg_count < LOGIN_ARG_COUNT ) + { + //Get one string + while( index + str_len < msg_len && '\0' != *( bufPtr + index + str_len ) ) + { + str_len++; + //Check if max param len no. of chars already read.. + //if so return with error + if ( MAX_PARAM_LEN == index + str_len ) + { + return INVALID_PARAMETERES; + } + } + //str_len == 0, means one setting attrib missing.. + //Assign that to NULL..and continue + if ( 0 == str_len ) + { + ( *msg_struct )->strs[arg_count] = NULL; + //Increment the no of args read by one + arg_count++; + index++; + continue; + } + //ownership of these strs is transfered to msg_struct + //Allocate memory and check for the error + str1 = ( char* ) malloc ( str_len + 1 ); + if ( NULL == str1 ) + { + return MEM_ALLOCATION_ERROR; + } + //Copy the string from buffer + //copy '\0' as well + memcpy( str1, bufPtr + index, str_len + 1 ); + //Assign to the array + ( *msg_struct )->strs[arg_count] = str1; + //Skip the '\0' already read.. + index += str_len + 1; + //reset the str_len to read next char + str_len = 0; + //Increment the no of args read by one + arg_count++; + + } + iso_logger( "%s", "Out - parse_for_login\n" ); + return 0; + } +/*! \brief Calls parse_for_login to parse and validate the arguments + * And then calls action_login for to do actual login + * + * \param aMsgBuf message buffer + * \param msg_len - len of the message + */ +gint action_parse_login( char* aMsgBuf, int msg_len ) + { + + gint message_type_err = 0; + login_struct* message_struct; + gint arg_count = 0; + + iso_logger( "%s", "In - action_parse_login\n" ); + //Allocate memory and check for errors + message_struct = ( login_struct* ) malloc( sizeof ( login_struct ) ); + if ( NULL == message_struct ) + { + return MEM_ALLOCATION_ERROR; + } + //intialize memory to 0s + memset ( message_struct, '\0', sizeof ( login_struct ) ); + + //Parse the message into login parameters + message_type_err = parse_for_login( aMsgBuf, &message_struct, msg_len ); + //If no error in parsing do a login + if ( !message_type_err ) + { + //parse passed + message_type_err = action_login( message_struct ); + + } + //check if the pointer is not pointing to NULL + //And free the memory + for( arg_count = 0; arg_count < LOGIN_ARG_COUNT; arg_count++ ) + { + if ( NULL != message_struct->strs[arg_count] ) + { + free ( message_struct->strs[arg_count] ); + } + } + free ( message_struct ); + iso_logger( "%s", "Out - action_parse_login\n" ); + return message_type_err; + } + +