testexecmgmt/ucc/Source/MobsterRPCService/CSvcMobster.cpp
changeset 0 3da2a79470a7
--- /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 <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+
+
+/****************************************************************************************
+ * 
+ * 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<CSMobster> *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<CSMobster> *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
+}
+