testexecmgmt/ucc/Source/Uccs.v2/Core/UCCS_CServMgr.cpp
changeset 0 3da2a79470a7
equal deleted inserted replaced
-1:000000000000 0:3da2a79470a7
       
     1 /*
       
     2 * Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  
       
    15 * Filename: UCCSServMgr.cpp
       
    16 * System Includes
       
    17 *
       
    18 */
       
    19 
       
    20 
       
    21 
       
    22 #include <string.h>
       
    23 #include <stdio.h>
       
    24 #include <stdlib.h>
       
    25 #include <assert.h>
       
    26 
       
    27 
       
    28 /***********************************************************************************
       
    29  *
       
    30  * Local Includes
       
    31  *
       
    32  **********************************************************************************/
       
    33 #include "strncpynt.h"
       
    34 #include "UCCS_CServMgr.h"
       
    35 #include "UCCS_ErrorCodes.h"
       
    36 #include "UCCS_ServiceValues.h"
       
    37 #include "../ServiceStubs/Mobster.v2/CMobsterStub.h"
       
    38 #include "../ServiceStubs/Internal/CInternalStub.h"
       
    39 #include "../ServiceStubs/Ppp/CPppControllerStub.h"
       
    40 #include "../ServiceStubs/HostExecute/CHostExecuteStub.h"
       
    41 #include "../ServiceStubs/UuInterface/CUuinterfaceStub.h"
       
    42 #include "../ServiceStubs/MobileAgent/CMobileAgentServiceStub.h"
       
    43 #include "../ServiceStubs/ForeignAgent/CForeignAgentServiceStub.h"
       
    44 #include "../ServiceStubs/HomeAgent/CHomeAgentServiceStub.h"
       
    45 #include "../ServiceStubs/HostExecuteAsync/CHostExecuteAsyncStub.h"
       
    46 #include "../ServiceStubs/Test/CTestStub.h"
       
    47 //#include "..\ServiceStubs\TestService\CTestServiceStub.h"
       
    48 #include "../ServiceStubs/GPSSimulator/CAPICommandHandlerStub.h"
       
    49 #include "../ServiceStubs/GenericStub/CGenericStub.h"
       
    50 //#include "..\..\include\penstd.h"
       
    51 #include "CUCCIniFile.h"
       
    52 
       
    53 /***********************************************************************************
       
    54  *
       
    55  * Definitions
       
    56  *
       
    57  **********************************************************************************/
       
    58 #define UCC_INI_FILE	".\\UCC.ini"
       
    59 #define SERVICE_INI		"ini"
       
    60 #define SERVICE_HOST	"host"
       
    61 
       
    62 #define STARTUP_GENERIC_SERVICE_STUB(rpcid,ini,servicename) \
       
    63 			service = iServiceList[localserviceindex] = new CGenericStub(ini,servicename);	\
       
    64 			assert( service != NULL );														\
       
    65 			localerror = remoteerror = 0;													\
       
    66 			rv = service->StartUccsService( aServiceHost, &localerror, &remoteerror );		\
       
    67 			if( rv != 0 ) {																	\
       
    68 				delete iServiceList[localserviceindex];										\
       
    69 				iServiceList[localserviceindex] = NULL;										\
       
    70 			} else {																		\
       
    71 				strcpy( iServiceDescTable[localserviceindex].iHostname, aServiceHost );		\
       
    72 				iServiceDescTable[localserviceindex].iServiceID = rpcid;					\
       
    73 			}																				\
       
    74 			break;																
       
    75 
       
    76 #define STARTUP_SERVICE_STUB(rpcid,classname) \
       
    77 			service = iServiceList[localserviceindex] = new classname();	\
       
    78 			assert( service != NULL );													\
       
    79 			localerror = remoteerror = 0;												\
       
    80 			rv = service->StartUccsService( aServiceHost, &localerror, &remoteerror );	\
       
    81 			if( rv != 0 ) {																\
       
    82 				delete iServiceList[localserviceindex];									\
       
    83 				iServiceList[localserviceindex] = NULL;									\
       
    84 			} else {																	\
       
    85 				strcpy( iServiceDescTable[localserviceindex].iHostname, aServiceHost );	\
       
    86 				iServiceDescTable[localserviceindex].iServiceID = rpcid;				\
       
    87 			}
       
    88 
       
    89 #define STARTUP_SERVICE_STUB_CASE(rpcid,classname)	case rpcid: \
       
    90 			STARTUP_SERVICE_STUB(rpcid, classname);				\
       
    91 			break;																
       
    92 
       
    93 #define SHUTDOWN_SERVICE_STUB(rpcid,classname) \
       
    94 			delete ((classname*)(iServiceList[aLocalServiceID]));		\
       
    95 			iServiceList[aLocalServiceID] = NULL;						\
       
    96 			iServiceDescTable[aLocalServiceID].iHostname[0] = 0;		\
       
    97 			iServiceDescTable[aLocalServiceID].iServiceID = RPCSVC_INVALID;
       
    98 
       
    99 #define SHUTDOWN_SERVICE_STUB_CASE(rpcid,classname)		case rpcid:			\
       
   100 			SHUTDOWN_SERVICE_STUB(rpcid, classname);						\
       
   101 			break;
       
   102 
       
   103 /***********************************************************************************
       
   104  *
       
   105  * Construction 
       
   106  *
       
   107  **********************************************************************************/
       
   108 CServiceManager::CServiceManager( IOutput *aOutput )
       
   109 	: iNumGenericServices(0)
       
   110 {
       
   111 	// verify the params
       
   112 	assert( aOutput != NULL );
       
   113 	iOutput = aOutput;
       
   114 
       
   115 	// initialise the service list
       
   116 	for( int i = 0; i <= MAXSERVICES; i++ ) {
       
   117 		iServiceList[i] = NULL;
       
   118 	}
       
   119 
       
   120 	// *** This need refactoring into a private method ***
       
   121 	// Open the ucc.ini file
       
   122 	CUCCIniFile iniFile(UCC_INI_FILE);
       
   123 	vector<string> sections = iniFile.SectionNames();
       
   124 
       
   125 	// Check to see if there are any sections defined
       
   126 	iNumGenericServices = sections.size();
       
   127 	if( iNumGenericServices > 0 && iNumGenericServices<(MAXSERVICES-RPCSVC_LAST) )
       
   128 	{
       
   129 		for( int i=0 ; i<iNumGenericServices ; i++ )
       
   130 		{
       
   131 			// *** No error checking currently ***
       
   132 
       
   133 			// Set the service IID to the next available one
       
   134 			iGenericServices[i].iServiceID = RPCSVC_LAST+i;
       
   135 
       
   136 			// Set the service name to the section name
       
   137 			strcpy( iGenericServices[i].iServiceName, sections[i].c_str() );
       
   138 
       
   139 			// Retrieve the ini file location
       
   140 			string service_ini;
       
   141 			bool ret = iniFile.KeyValue(SERVICE_INI, sections[i].c_str(), service_ini);
       
   142 			assert( ret == true );
       
   143 			assert( service_ini.size() > 0 );
       
   144 			strcpy( iGenericServices[i].iIniFile, service_ini.c_str() );
       
   145 
       
   146 			// Retrieve the host name/ip address
       
   147 			string host;
       
   148 			ret = iniFile.KeyValue(SERVICE_HOST, sections[i].c_str(), host);
       
   149 			assert( ret == true );
       
   150 			assert( host.size() > 0 );
       
   151 			strcpy( iGenericServices[i].iHost, host.c_str() );
       
   152 		}
       
   153 	}
       
   154 }
       
   155 
       
   156 
       
   157 /***********************************************************************************
       
   158  *
       
   159  * Destruction
       
   160  *
       
   161  **********************************************************************************/
       
   162 CServiceManager::~CServiceManager()
       
   163 {
       
   164 	// shutdown all loaded services -- log any errors
       
   165 	ShutdownAll();
       
   166 
       
   167 	// verify all services are stopped (or trying to connect)
       
   168 	for( int i = 0; i < MAXSERVICES; i++ ) {
       
   169 		assert( (iServiceList[i] == NULL) || (iServiceDescTable[i].iServiceID == RPCSVC_INVALID) );
       
   170 	}
       
   171 }
       
   172 
       
   173 
       
   174 /***********************************************************************************
       
   175  *
       
   176  * ShutdownAll - Close the connections to all services
       
   177  *
       
   178  **********************************************************************************/
       
   179 int CServiceManager::ShutdownAll()
       
   180 {
       
   181 	int localserviceindex = 0;
       
   182 
       
   183 	//check each service and if it is alive then stop it
       
   184 	for( localserviceindex = 0; localserviceindex < MAXSERVICES; localserviceindex++ ) {
       
   185 		if( iServiceList[localserviceindex] != NULL ) {
       
   186 			LocalStopService( localserviceindex );
       
   187 		}
       
   188 	}
       
   189 	return UCCS_OK;
       
   190 }
       
   191 
       
   192 
       
   193 /***********************************************************************************
       
   194  *
       
   195  * PUBLIC METHOD: ResetService -- resets a service by starting then stopping it
       
   196  *
       
   197  **********************************************************************************/
       
   198 int CServiceManager::ResetService( int aServiceID, char *aHostname )
       
   199 {
       
   200 	assert( !"Method withdrawn" );
       
   201 	return 0;
       
   202 }
       
   203 
       
   204 
       
   205 /***********************************************************************************
       
   206  *
       
   207  * PUBLIC METHOD: ResetAllServices -- resets all the services in the oldservices
       
   208  * list
       
   209  *
       
   210  **********************************************************************************/
       
   211 int CServiceManager::ResetAllServices()
       
   212 {
       
   213 	assert( !"Method withdrawn" );
       
   214 	return 0;
       
   215 }
       
   216 
       
   217 
       
   218 /***********************************************************************************
       
   219  *
       
   220  * PUBLIC METHOD: IssueCommand -- sends the command to the appropriate service
       
   221  *
       
   222  **********************************************************************************/
       
   223 int CServiceManager::IssueCommand( CDataRecord* aRequestRecord, CDataRecord** aReturnedDataRecord )
       
   224 {
       
   225 	int returncode = ERR_NONE;
       
   226 	int service_id;
       
   227 	int err;
       
   228 	int service_index;
       
   229 	char *service_name;
       
   230 	char *service_host;
       
   231 	IService *service = NULL;
       
   232 
       
   233 	// ensure that the passed buffer is set to NULL
       
   234 	assert( *aReturnedDataRecord == NULL );
       
   235 
       
   236 
       
   237 	// Look for the service name initially
       
   238 	//   if the name doesn't exist then revert to the legacy method
       
   239 	err = aRequestRecord->GetFieldAsString( "SVCNAME", &service_name );
       
   240 	if( err == UCCS_OK ) {
       
   241 		// If a generic service is being used then retrieve the 
       
   242 		// service id and service name from the generic services list.
       
   243 		bool found = false;
       
   244 		for( int i=0; i<iNumGenericServices; i++ )
       
   245 		{
       
   246 			if( strcmp(iGenericServices[i].iServiceName, service_name) == 0 )
       
   247 			{
       
   248 				service_id = iGenericServices[i].iServiceID;
       
   249 				service_host = iGenericServices[i].iHost;
       
   250 				found = true;
       
   251 				break;
       
   252 			}
       
   253 		}
       
   254         if (!found)
       
   255             return UCCS_NO_MATCHING_GENERIC_SERVICE_FOUND;
       
   256 	}
       
   257 	else
       
   258 	{
       
   259 		// retrieve the service id for the request 
       
   260 		err = aRequestRecord->GetFieldAsInt( "SVCID", &service_id );
       
   261 		if( err != UCCS_OK ) {
       
   262 			return UCCS_NOSERVICEID;
       
   263 		}
       
   264 
       
   265 		// verify that this is a valid service id 
       
   266 		if( (service_id <= RPCSVC_INVALID) || (service_id >= RPCSVC_LAST+iNumGenericServices) ) {
       
   267 			return UCCS_INVALIDSERVICEID;
       
   268 		}
       
   269 
       
   270 		// retrieve the hostname for the request
       
   271 		err = aRequestRecord->GetFieldAsString( "SVCHOST", &service_host ); 
       
   272 		if( err != UCCS_OK ) {
       
   273 			return UCCS_NOSERVICEHOST;
       
   274 		}
       
   275 	}
       
   276 
       
   277 	// execute command
       
   278     // - performed within a loop to provide for a retry mechanism (eg. after new RPC connetion established)
       
   279     for (int i=0; i < 2; i++)
       
   280     {
       
   281 	    service_index = GetLocalServiceIndex( service_id, service_host );
       
   282 	    if( service_index == -1 )
       
   283         {
       
   284             // start service (RPC connect)
       
   285 		    err = LocalStartService(service_id, service_host);
       
   286 		    if (err != UCCS_OK) 
       
   287 			    return err;
       
   288     	    service_index = GetLocalServiceIndex( service_id, service_host );
       
   289 	    }
       
   290 
       
   291 	    // get a pointer to the service 
       
   292 	    assert( service_index != -1 );	
       
   293 	    service = iServiceList[service_index];
       
   294 	    assert( service != NULL );	
       
   295 
       
   296 	    // now issue the command to the service
       
   297 	    *aReturnedDataRecord = service->IssueCommand( aRequestRecord );
       
   298 
       
   299 	    // Check the completion code and result
       
   300 	    int completion_code = ERR_NONE;
       
   301 	    err = (*aReturnedDataRecord)->GetFieldAsInt( STD_REPLY_FIELD_REQUESTCOMPLETIONCODE, &completion_code );
       
   302 	    if( err == UCCS_OK )
       
   303 	    {
       
   304 		    // If the completion code is ok, check the call result
       
   305 		    if( completion_code == ERR_NONE )
       
   306 		    {
       
   307 			    int call_result = ERR_NONE;
       
   308 			    err = (*aReturnedDataRecord)->GetFieldAsInt( "RESULT", &call_result );
       
   309 			    if( err == UCCS_OK )
       
   310 			    {
       
   311 				    returncode = call_result;
       
   312                     break;  // no need to retry since it worked (either first or second time)
       
   313 			    }
       
   314 		    }
       
   315 		    else
       
   316 		    {
       
   317 			    returncode = completion_code;
       
   318                 err = LocalStopService(service_index);
       
   319 		    }
       
   320 	    }
       
   321     } // for loop
       
   322 
       
   323 	return returncode;
       
   324 }
       
   325 
       
   326 
       
   327 /***********************************************************************************
       
   328  *
       
   329  * PRIVATE METHOD: StartService - creates and starts up a service. The passed id
       
   330  * must map to an entry in the service table which stores the RPC service and 
       
   331  * the host that the service is targetted at. 
       
   332  *
       
   333  **********************************************************************************/
       
   334 int CServiceManager::LocalStartService( int aServiceID, char *aServiceHost )
       
   335 {
       
   336 	int rv;
       
   337 	int i;
       
   338 	int localerror = 0;
       
   339 	int remoteerror = 0;
       
   340 	int localserviceindex = -1;
       
   341 	IService *service;
       
   342 
       
   343 	// look for a free index in the service table
       
   344 	for( i = 0; i < MAXSERVICES; i++ ) {
       
   345 		if( iServiceList[i] == NULL ) {
       
   346 			localserviceindex = i;
       
   347 			break;
       
   348 		}
       
   349 	}
       
   350 
       
   351 	// check that a slot was found
       
   352 	if( localserviceindex == -1 ) {
       
   353 		return UCCS_SERVICELISTFULL;
       
   354 	}
       
   355 	
       
   356 	// startup each legacy service
       
   357 	switch( aServiceID ) {
       
   358 
       
   359 	STARTUP_SERVICE_STUB_CASE( RPCSVC_HOMEAGENT,		CHomeAgentServiceStub );
       
   360 	STARTUP_SERVICE_STUB_CASE( RPCSVC_FOREIGNAGENT,		CForeignAgentServiceStub );
       
   361 	STARTUP_SERVICE_STUB_CASE( RPCSVC_MOBILEAGENT,		CMobileAgentServiceStub );
       
   362 	STARTUP_SERVICE_STUB_CASE( RPCSVC_MOBSTER,			CMobsterServiceStub );
       
   363 	STARTUP_SERVICE_STUB_CASE( RPCSVC_UUINTERFACE,		CUuinterfaceStub );
       
   364 	STARTUP_SERVICE_STUB_CASE( RPCSVC_HOSTEXECUTE,		CHostExecuteStub );
       
   365 	STARTUP_SERVICE_STUB_CASE( RPCSVC_PPPCONTROLLER,	CPppControllerServiceStub );
       
   366 	STARTUP_SERVICE_STUB_CASE( RPCSVC_INTERNAL,			CInternalStub );
       
   367 	STARTUP_SERVICE_STUB_CASE( RPCSVC_HOSTEXECUTEASYNC,	CHostExecuteAsyncStub );
       
   368 	STARTUP_SERVICE_STUB_CASE( RPCSVC_TEST,				CTestStub );
       
   369 	STARTUP_SERVICE_STUB_CASE( RPCSVC_GPSSIMULATOR,		CAPICommandHandlerStub );
       
   370 
       
   371 	default:
       
   372 		{
       
   373 			// Check to see if it is a generic service stub
       
   374 			if( (aServiceID >= RPCSVC_LAST) &&
       
   375 				(aServiceID <= RPCSVC_LAST+iNumGenericServices) )
       
   376 			{
       
   377 				STARTUP_GENERIC_SERVICE_STUB(	(TRpcServiceID)aServiceID,
       
   378 												iGenericServices[aServiceID-RPCSVC_LAST].iIniFile,
       
   379 												iGenericServices[aServiceID-RPCSVC_LAST].iServiceName);
       
   380 			}
       
   381 			else
       
   382 			{
       
   383 				rv = ERR_INVALID_SERVICE;
       
   384 			}
       
   385 		}
       
   386 		break;
       
   387 	}
       
   388 
       
   389 	// update the status
       
   390 	iOutput->StartServiceResult( aServiceID, aServiceHost, rv, localerror, 0 );
       
   391 	return ((rv == ERR_NONE) ? UCCS_OK : UCCS_CANTSTARTSERVICE );
       
   392 }
       
   393 
       
   394 
       
   395 /***********************************************************************************
       
   396  *
       
   397  * PRIVATE METHOD: StopService - destroys the service object
       
   398  *
       
   399  **********************************************************************************/
       
   400 int CServiceManager::LocalStopService( int aLocalServiceID )
       
   401 {
       
   402 	int err;
       
   403 	int localerror;
       
   404 	int remoteerror;
       
   405 	TServiceTableEntry this_entry;
       
   406 
       
   407 	// check parameters
       
   408 	assert( (aLocalServiceID >= 0) && (aLocalServiceID < MAXSERVICES) );
       
   409 	localerror = remoteerror = 0;
       
   410 
       
   411 
       
   412 	// get the service
       
   413 	if( iServiceList[aLocalServiceID] == NULL ) {
       
   414 		return UCCS_INVALIDSERVICEINDEX;
       
   415 	}
       
   416 
       
   417 	// save this entry in-case 
       
   418 	this_entry.iServiceID = iServiceDescTable[aLocalServiceID].iServiceID;
       
   419 	STRNCPY_NULL_TERMINATE( this_entry.iHostname, iServiceDescTable[aLocalServiceID].iHostname, MAXHOSTNAME );
       
   420 
       
   421 	// stop the service and log the result
       
   422 	err = (iServiceList[aLocalServiceID])->StopUccsService( &localerror, &remoteerror );
       
   423 
       
   424 	// regardless of success we still want to destroy the object
       
   425 	switch( iServiceDescTable[aLocalServiceID].iServiceID ) {
       
   426 
       
   427 	SHUTDOWN_SERVICE_STUB_CASE( RPCSVC_HOMEAGENT,			CHomeAgentServiceStub );
       
   428 	SHUTDOWN_SERVICE_STUB_CASE( RPCSVC_FOREIGNAGENT,		CForeignAgentServiceStub );
       
   429 	SHUTDOWN_SERVICE_STUB_CASE( RPCSVC_MOBILEAGENT,			CMobileAgentServiceStub );
       
   430 	SHUTDOWN_SERVICE_STUB_CASE( RPCSVC_MOBSTER,				CMobsterServiceStub );
       
   431 	SHUTDOWN_SERVICE_STUB_CASE( RPCSVC_UUINTERFACE,			CUuinterfaceStub );
       
   432 	SHUTDOWN_SERVICE_STUB_CASE( RPCSVC_HOSTEXECUTE,			CHostExecuteStub );
       
   433 	SHUTDOWN_SERVICE_STUB_CASE( RPCSVC_PPPCONTROLLER,		CPppControllerServiceStub );
       
   434 	SHUTDOWN_SERVICE_STUB_CASE( RPCSVC_INTERNAL,			CInternalStub );
       
   435 	SHUTDOWN_SERVICE_STUB_CASE( RPCSVC_HOSTEXECUTEASYNC,	CHostExecuteAsyncStub );
       
   436 	SHUTDOWN_SERVICE_STUB_CASE( RPCSVC_TEST,				CTestStub );
       
   437 	SHUTDOWN_SERVICE_STUB_CASE( RPCSVC_GPSSIMULATOR,		CAPICommandHandlerStub );
       
   438 
       
   439 	// this means that the other thread is trying to connect to the service as 
       
   440 	// we speak - if we just ignore this then it should be ok?
       
   441 	case RPCSVC_INVALID:
       
   442 		break;
       
   443 
       
   444 	default:
       
   445 		{
       
   446 			// Check to see if it is a generic service stub
       
   447 			if( (iServiceDescTable[aLocalServiceID].iServiceID >= RPCSVC_LAST) &&
       
   448 				(iServiceDescTable[aLocalServiceID].iServiceID <= RPCSVC_LAST+iNumGenericServices) )
       
   449 			{
       
   450 				SHUTDOWN_SERVICE_STUB( iServiceDescTable[aLocalServiceID].iServiceID, CGenericStub );
       
   451 			}
       
   452 			else
       
   453 			{
       
   454 				assert( !"INVALID CODE PATH" );
       
   455 			}
       
   456 		}
       
   457 		break;
       
   458 	}
       
   459 
       
   460 	// update the status
       
   461 	iOutput->StopServiceResult( this_entry.iServiceID, this_entry.iHostname, err, localerror, remoteerror );
       
   462 	return ((err == ERR_NONE) ? UCCS_OK : UCCS_CANTSTOPSERVICE );
       
   463 }
       
   464 
       
   465 
       
   466 /***********************************************************************************
       
   467  *
       
   468  * PRIVATE METHOD: GetLocalServiceIndex 
       
   469  *
       
   470  **********************************************************************************/
       
   471 int CServiceManager::GetLocalServiceIndex( int aServiceID, char *aServiceHost )
       
   472 {
       
   473 	int i;
       
   474 	int match;
       
   475 
       
   476 	// check params
       
   477 	assert( aServiceHost != NULL );
       
   478 	assert( (aServiceID > RPCSVC_INVALID) && (aServiceID < RPCSVC_LAST+iNumGenericServices) );
       
   479 
       
   480 	// now look for a match
       
   481 	for( i = 0; i < MAXSERVICES; i++ ) {
       
   482 
       
   483 		// make sure this index is active
       
   484 		if( iServiceList[i] == NULL ) {
       
   485 			continue;
       
   486 		}
       
   487 
       
   488 		// try and match
       
   489 		if( aServiceID != iServiceDescTable[i].iServiceID ) {
       
   490 			continue;
       
   491 		}
       
   492 		match = strcmp( iServiceDescTable[i].iHostname, aServiceHost );
       
   493 		if( match != 0 ) {
       
   494 			continue;
       
   495 		}
       
   496 
       
   497 		// we have a match
       
   498 		return i;
       
   499 	}
       
   500 
       
   501 	// done -- failed
       
   502 	return -1;
       
   503 }
       
   504 
       
   505 
       
   506 
       
   507