diff -r 000000000000 -r 3da2a79470a7 testexecmgmt/ucc/Source/MobsterRPCService/CSvcMobster.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/testexecmgmt/ucc/Source/MobsterRPCService/CSvcMobster.cpp Mon Mar 08 15:04:18 2010 +0800 @@ -0,0 +1,333 @@ +/* +* Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies). +* All rights reserved. +* This component and the accompanying materials are made available +* under the terms of "Eclipse Public License v1.0" +* which accompanies this distribution, and is available +* at the URL "http://www.eclipse.org/legal/epl-v10.html". +* +* Initial Contributors: +* Nokia Corporation - initial contribution. +* +* Contributors: +* +* Description: +* This file was autogenerated by rpcgen, but should be modified by the developer. +* Make sure you don't use the -component_mod flag in future or this file will be overwritten. +* Fri Sep 19 13:14:28 2003 +* System Includes +* +*/ + + + + +#include +#include +#include + + +/**************************************************************************************** + * + * Local Includes + * + ***************************************************************************************/ +#include "CSvcMobster.h" +#include "mobster.h" +#include "../ThreadLibrary/CAThread.h" +#include "mobster_client_server_protocol.h" + + +/**************************************************************************************** + * + * Definitions + * + ***************************************************************************************/ +#ifndef WIN32 +#define ADDRESS_INTEGER s_addr +#define closesocket(x) (shutdown(x,SHUT_RDWR),close(x)) +#endif + +/**************************************************************************************** + * + * File-scope variables + * + ***************************************************************************************/ +static CComponentManager *iComponentManager; +static CAThread *iServerThread; +static int iServerListenSocket, iStopRequestedFlag; + +/**************************************************************************************** + * + * Implementation + * + ***************************************************************************************/ + + +/**************************************************************************************** + * + * PUBLIC: GetInstanceKeyFromArgs + * + ***************************************************************************************/ +int CSvcMobster::GetInstanceKeyFromArgs( int aMethod, void *aArgs ) +{ + int rv; + int *ia; + TUUAddress *ua; + + switch( aMethod ) { + + case DSTR_REMOVEDEVICE: + case GETDEVICEINFO: + case GETDEVICELOG: + case STOPDEVICE: + ia = (int*)aArgs; + rv = *ia; + break; + + case SETREMOTEUUADDRESS: + ua = (TUUAddress*)aArgs; + rv = ua->iDeviceID; + break; + + default: + rv = ERR_INVALID_METHOD; + break; + } + return rv; +} + + +/**************************************************************************************** + * + * PUBLIC: SetError + * + ***************************************************************************************/ +int CSvcMobster::SetError( int aMethod, void *aArgs, int aError ) +{ + int rv; + TComponentList *cl; + TDeviceDesc *dd; + TVarData *vd; + + switch( aMethod ) { + + case LIST_DEVICES: + cl = (TComponentList*)aArgs; + if( aError != ERR_NONE ) { + if( cl->TComponentList_val != NULL ) { + free(cl->TComponentList_val); + cl->TComponentList_val = NULL; + } + cl->TComponentList_len = 0; + } + rv = ERR_NONE; + break; + + case GETDEVICEINFO: + dd = (TDeviceDesc*)aArgs; + dd->iMTID = aError; + rv = ERR_NONE; + break; + + case GETDEVICELOG: + vd = (TVarData*)aArgs; + if( aError != ERR_NONE ) { + if( vd->TVarData_val != NULL ) { + free(vd->TVarData_val); + vd->TVarData_val = NULL; + } + vd->TVarData_len = 0; + } + rv = ERR_NONE; + break; + + default: + rv = ERR_INVALID_METHOD; + break; + } + return rv; +} + + +/**************************************************************************************** + * + * PUBLIC: StartRPCService + * + ***************************************************************************************/ +int CSvcMobster::StartRPCService( CComponentManager *aComponentManager, TChannelAddress *aArg ) +{ + TThreadError terr; + int err; + struct sockaddr_in local_address; + + // prologue + assert( iComponentManager == NULL ); + assert( iServerThread == NULL ); + + // create a socket to listen for connections + iServerListenSocket = socket( AF_INET, SOCK_STREAM, 0 ); + if( iServerListenSocket == -1 ) { + return ERR_CREATE_SOCKET_FAILED; + } + + // bind the specified port (ignore address) + local_address.sin_family = AF_INET; + local_address.sin_addr.ADDRESS_INTEGER = INADDR_ANY; + local_address.sin_port = htons(aArg->iPort); + err = bind( iServerListenSocket, (struct sockaddr *)&local_address, sizeof(local_address) ); + if( err == -1 ) { + closesocket( iServerListenSocket ); + return ERR_BIND_FAILED; + } + + // listen + err = listen( iServerListenSocket, 5 ); + if( err == -1 ) { + closesocket( iServerListenSocket ); + return ERR_LISTEN_FAILED; + } + + // ok the socket is all setup to do an accept - so we pass over to the other thread + // and let the main call continue + iStopRequestedFlag = 0; + iServerThread = new CAThread( "CSvcMobster::iServerThread" ); + assert( iServerThread != NULL ); + terr = iServerThread->StartThread( (void*)CSvcMobster::WaitForConnectionsFromTerminalEmulations, NULL, &err ); + if( terr != TE_NONE ) { + closesocket( iServerListenSocket ); + delete iServerThread; + iServerThread = NULL; + return ERR_CREATE_SERVER_THREAD_FAILED; + } + + // done + iComponentManager = aComponentManager; + return ERR_NONE; +} + + +/**************************************************************************************** + * + * PUBLIC: StopRPCService + * + ***************************************************************************************/ +int CSvcMobster::StopRPCService() +{ + TThreadError terr; + + // close the socket to stop the thread + iStopRequestedFlag = 1; + closesocket( iServerListenSocket ); + terr = iServerThread->WaitForThread( -1 ); + if( terr != TE_NONE ) { + fprintf( stderr, "WARNING: CSvcMobster::StopRPCService - WaitForThread returned %d.\n", terr ); + } + + // clean up the thread + if( iServerThread != NULL ) { + delete iServerThread; + iServerThread = NULL; + } + + // reset the component manager (though not responsible for delete) + iComponentManager = NULL; + return ERR_NONE; +} + + +/**************************************************************************************** + * + * PRIVATE: WaitForConnectionsFromTerminalEmulations + * + ***************************************************************************************/ +void CSvcMobster::WaitForConnectionsFromTerminalEmulations( void ) +{ + int client_sockfd; + + // repeat until StopRPCService is called (or an error occurs) + while( 1 ) { + + // wait for a connection + client_sockfd = accept( iServerListenSocket, NULL, NULL ); + if( client_sockfd == -1 ) { + if( ((errno != 0) && (errno != EINVAL)) || ((errno == EINVAL) && (iStopRequestedFlag == 0)) ) { + fprintf( stderr, "WARNING: Accept has failed with errno = %d.\n", errno ); + } + break; + } + + // we have a socket -- now it has to do the c/s protocol so that we know which + // MT to connect it to -- but if there is a problem then this could block + // forever -- so I'm going to create a thread per connection to deal with this. + // These threads are responsible for cleaning themselves up. +#ifdef WIN32 + { + HANDLE client_thread; + client_thread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)CSvcMobster::ConnectClientToMobileTermination, (void*)client_sockfd, 0, NULL ); + if( client_thread == NULL ) { + fprintf( stderr, "WARNING: Failed to create the client thread to connect to MobileTermination (%d).\n", GetLastError() ); + } + client_thread = NULL; +#else + { + int err; + pthread_t client_thread; + err = pthread_create( &client_thread, NULL, (void*(*)(void*))(CSvcMobster::ConnectClientToMobileTermination), (void*)client_sockfd ); + if( err != 0 ) { + fprintf( stderr, "WARNING: Failed to create the client thread to connect to MobileTermination (%d).\n", errno ); + } + client_thread = 0; + } +#endif + + // this is all we have to do + } + + // done + return; +} + + +/**************************************************************************************** + * + * PRIVATE: ConnectClientToMobileTermination + * + ***************************************************************************************/ +void CSvcMobster::ConnectClientToMobileTermination( int aSock ) +{ + int mtid, err; + CSMobster *mt; + + // do the csprotocol across the socket to get the config info + mtid = client_server_protocol( aSock ); + if( mtid < 0 ) { + fprintf( stderr, "WARNING: Invalid MTID received (%d).\n", mtid ); + closesocket( aSock ); + return; + } + + // try and get the instance + mt = iComponentManager->GetInstance( mtid ); + if( mt == NULL ) { + fprintf( stderr, "WARNING: Client requested non-existant device %d.\n", mtid ); + closesocket( aSock ); + return; + } + + // pass the new socket to the mt + err = mt->settesocket( aSock ); + if( err != ERR_NONE ) { + fprintf( stderr, "WARNING: Failed to set the socket on device %d (%d).\n", mtid, err ); + closesocket( aSock ); + return; + } + + // all done -- thread exit +#ifdef WIN32 + ExitThread( 0 ); +#else + pthread_exit( 0 ); +#endif +} +