diff -r 7fdc9a71d314 -r 8ad140f3dd41 stif/TestServer/src/Testexecution.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/stif/TestServer/src/Testexecution.cpp Wed Oct 13 16:17:58 2010 +0300 @@ -0,0 +1,4821 @@ +/* +* Copyright (c) 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 module contains implementation of CTestExecution +* class member functions. CTestExecution class handles a test +* execution subsession specific operations. +* +*/ + +// INCLUDE FILES +#include +#include +#include "TestEngineClient.h" +#include "StifTFwIfProt.h" +#include +#include "TestServer.h" +#include "TestServerModuleIf.h" +#include "TestServerCommon.h" +#include "PrintQueue.h" +#include "TestServerEvent.h" +#include "TestThreadContainer.h" +#include "STIFMeasurement.h" + +// EXTERNAL DATA STRUCTURES + +// EXTERNAL FUNCTION PROTOTYPES + +// CONSTANTS + +// MACROS + +// LOCAL CONSTANTS AND MACROS + +// MODULE DATA STRUCTURES + +// LOCAL FUNCTION PROTOTYPES + +// FORWARD DECLARATIONS + +// ==================== LOCAL FUNCTIONS ======================================= + +// ================= MEMBER FUNCTIONS ========================================= + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: NewL + + Description: Returns new CTestExecution instance. + + Parameters: CTestModule* aModuleSession :in: "Parent" module + TInt aCaseNumber :in: Test case number + const TFileName& aConfig :in: Configuration filename + + Return Values: CTestExecution* New instance + + Errors/Exceptions: Function leaves if memory allocation fails or + CTestExecution construction leaves. + Panics is aModuleSession is NULL. + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +CTestExecution* CTestExecution::NewL( CTestModule* aModuleSession, + TInt aCaseNumber, + const TFileName& aConfig ) + { + + __ASSERT_ALWAYS ( aModuleSession, + CTestServer::PanicServer( ENullModuleSession ) ); + + CTestExecution* self=new( ELeave ) CTestExecution; + CleanupClosePushL( *self ); + self->ConstructL( aModuleSession, aCaseNumber, aConfig ); + CleanupStack::Pop(); + + return self; + + } + + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: CTestExecution + + Description: Constructor. + Initialises member variables whose default state is not zero or NULL. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +CTestExecution::CTestExecution() : + iConfig( 0, 0 ), + iTestThreadOpen( EFalse ), + iTestThreadFailure( ETestThreadOk ) + { + + iPrintNotifyAvailable = EFalse; + iThreadState = ENotStarted; + iRemoteSendAvailable = EFalse; + iRemoteReceiveAvailable = EFalse; + iEventNotifyAvailable = EFalse; + iCommandNotifyAvailable = EFalse; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: ~CTestExecution + + Description: Destructor + + Parameters: None + + Return Values: None + + Errors/Exceptions: Panics is threadmutex is taken. + + Status: Approved + +------------------------------------------------------------------------------- +*/ +CTestExecution::~CTestExecution() + { + // Thread must be stopped before CTestExecution can be deleted + if( iThreadState == EOnGoing ) + { + if( iModuleContainer != NULL ) + { + iModuleContainer->KillThread( KErrCancel ); + } + delete iModuleContainer; + iModuleContainer = NULL; + CTestServer::PanicServer( EClosingWhileTestRunning ); + } + + delete iPrintHandler; + iPrintHandler = NULL; + delete iEventHandler; + iEventHandler = NULL; + delete iSndHandler; + iSndHandler = NULL; + delete iRcvHandler; + iRcvHandler = NULL; + delete iInterferenceHandler; + iInterferenceHandler = NULL; + delete iMeasurementHandler; + iMeasurementHandler = NULL; + delete iCommandHandler; + iCommandHandler = NULL; + + // Test interference array(Needed cases when test interference thread is + // needed to Kill()) + iSTIFTestInterferenceArray.Reset(); + iSTIFTestInterferenceArray.Close(); + + // Reset test measurement array + iMeasurementHandlingArray.Reset(); + iMeasurementHandlingArray.Close(); + + // iPrintQueue must be emptied here, because it items are allocated from server heap + delete iPrintQueue; + iPrintQueue = NULL; + + // Delete name buffer + delete iConfigNameBuffer; + iConfigNameBuffer = NULL; + + delete iTestCaseArgs; + iTestCaseArgs = NULL; + + iStateEvents.ResetAndDestroy(); + iStateEvents.Close(); + + iEventArray.ResetAndDestroy(); + iEventArray.Close(); + + // Close mutexes + if ( iPrintMutex.Handle() != 0 ) iPrintMutex.Close(); + if ( iEventMutex.Handle() != 0 ) iEventMutex.Close(); + if ( iSndMutex.Handle() != 0 ) iSndMutex.Close(); + if ( iRcvMutex.Handle() != 0 ) iRcvMutex.Close(); + if ( iInterferenceMutex.Handle() != 0 ) iInterferenceMutex.Close(); + if ( iMeasurementMutex.Handle() != 0 ) iMeasurementMutex.Close(); + if ( iCommandMutex.Handle() != 0 ) iCommandMutex.Close(); + + // Mutex for testcomplete and cancel operations. Close mutex + if ( iTestThreadMutex.Handle() != 0 ) iTestThreadMutex.Close(); + + // Close semaphores + if ( iPrintSem.Handle() != 0 ) iPrintSem.Close(); + if ( iEventSem.Handle() != 0 ) iEventSem.Close(); + if ( iSndSem.Handle() != 0 ) iSndSem.Close(); + if ( iRcvSem.Handle() != 0 ) iRcvSem.Close(); + if ( iInterferenceSem.Handle() != 0 ) iInterferenceSem.Close(); + if ( iMeasurementSem.Handle() != 0 ) iMeasurementSem.Close(); + //if ( iReceiverSem.Handle() != 0 ) iReceiverSem.Close(); + if ( iCommandSem.Handle() != 0 ) iCommandSem.Close(); + + iMessageQueue.Close(); + + iTestThread.Close(); + + delete iCommandDef; + iCommandDef = NULL; + } + + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: ConstructL + + Description: Second level constructor + + Parameters: CTestModule* aModuleSession :in: "Parent" module + TInt aCaseNumber :: :in: Test case number + const TFileName& aConfig :in: Configuration filename + + Return Values: None + + Errors/Exceptions: None + + Status: Approved + +------------------------------------------------------------------------------- +*/ +void CTestExecution::ConstructL( CTestModule *aModuleSession, + TInt aCaseNumber, + const TFileName& aConfig ) + { + + // Get the parameters + iModuleSession = aModuleSession; + iCaseNumber = aCaseNumber; + + // Construct heap buffer for configuration file + iConfigNameBuffer = HBufC::NewL( aConfig.Length() ); + iConfig.Set ( iConfigNameBuffer->Des() ); + iConfig.Copy ( aConfig ); + + // Create mutexes + User::LeaveIfError( iPrintMutex.CreateLocal() ); + User::LeaveIfError( iEventMutex.CreateLocal() ); + User::LeaveIfError( iSndMutex.CreateLocal() ); + User::LeaveIfError( iRcvMutex.CreateLocal() ); + User::LeaveIfError( iInterferenceMutex.CreateLocal() ); + User::LeaveIfError( iMeasurementMutex.CreateLocal() ); + User::LeaveIfError( iCommandMutex.CreateLocal() ); + + // Mutex for testcomplete and cancel operations. Create mutex + User::LeaveIfError( iTestThreadMutex.CreateLocal() ); + + // Create semaphores + User::LeaveIfError( iPrintSem.CreateLocal( 0 ) ); + User::LeaveIfError( iEventSem.CreateLocal( 0 ) ); + User::LeaveIfError( iSndSem.CreateLocal( 0 ) ); + User::LeaveIfError( iRcvSem.CreateLocal( 0 ) ); + User::LeaveIfError( iInterferenceSem.CreateLocal( 0 ) ); + User::LeaveIfError( iMeasurementSem.CreateLocal( 0 ) ); + //User::LeaveIfError( iReceiverSem.CreateLocal( 0 ) ); + User::LeaveIfError( iCommandSem.CreateLocal( 0 ) ); + + // Create handlers + iPrintHandler = CPrintHandler::NewL( *this ); + iEventHandler = CEventHandler::NewL( *this ); + iSndHandler = CSndHandler::NewL( *this ); + iRcvHandler = CRcvHandler::NewL( *this ); + iInterferenceHandler = CInterferenceHandler::NewL( *this ); + iMeasurementHandler = CMeasurementHandler::NewL( *this ); + iCommandHandler = CCommandHandler::NewL( *this ); + + // Create print queue + iPrintQueue = CPrintQueue::NewL(); + + // Start print handler + iPrintHandler->StartL(); + + // Start rcv handler + iRcvHandler->StartL(); + + // Start interference handler + iInterferenceHandler->StartL(); + + // Start measurement handler + iMeasurementHandler->StartL(); + + iCommandDef = CCommandDef::NewL(); + } + + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: RunTestCase + + Description: Starts to execute test case in separate thread. + + Parameters: const RMessage& aMessage :in: Message from client. + + Return Values: TInt Error code + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::RunTestCase( const RMessage2& aMessage ) + { + + __TRACE ( KInit, ( _L( "CTestExecution::RunTestCase in" ) ) ); + + TInt ret = KErrNone; + + // Store message to be completed when case is finished + iTestExeMessage = aMessage; + + iFullResult.iStartTime.HomeTime(); + + delete iTestCaseArgs; + iTestCaseArgs = NULL; + + TInt testCaseArgsLength = iTestExeMessage.GetDesLength( 1 ); + if ( ( testCaseArgsLength != KErrArgument ) && ( testCaseArgsLength != KErrBadDescriptor ) ) + { + iTestCaseArgs = HBufC::New( testCaseArgsLength ); + if ( iTestCaseArgs == NULL ) + { + _LIT(KRunError,"Can't allocate memory for test case arguments"); + __TRACE ( KError, ( CStifLogger::ERed, KRunError() ) ); + CompleteTestExecution( KErrNone, + TFullTestResult::ECaseException, + KErrNoMemory, + KErrGeneral, + KRunError ); + return KErrNone; + } + + TPtr testCaseArgsPtr( iTestCaseArgs->Des() ); + TRAP( ret, iTestExeMessage.Read( 1, testCaseArgsPtr ) ); + if ( ret != KErrNone ) + { + _LIT(KRunError,"Can't read test case arguments"); + __TRACE ( KError, ( CStifLogger::ERed, KRunError() ) ); + CompleteTestExecution( KErrNone, + TFullTestResult::ECaseException, + ret, + KErrGeneral, + KRunError ); + return KErrNone; + } + } + + // Get a test module, which executes the test case. + // The test module will be freed either when the test case + // completes, or the test case is aborted. + ret = iModuleSession->GetTestModule( iModuleContainer, iConfig ); + if ( ret != KErrNone || iModuleContainer == NULL ) + { + _LIT(KRunError,"Can't get test module"); + __TRACE ( KError, ( CStifLogger::ERed, KRunError() ) ); + CompleteTestExecution( KErrNone, + TFullTestResult::ECaseException, + ret, + KErrGeneral, + KRunError ); + return KErrNone; + } + + + // Thread is created, so all thread specific operations are possible, + // even if thread is not yet resumed, so mark thread to be "Running" + SetThreadState ( EOnGoing ); + + // Start the test + iModuleContainer->SetExecutionSubSession( this ); + iModuleContainer->RunTestCase( iConfig, iCaseNumber, aMessage ); + + __TRACE ( KRunTestCase, ( _L( "CTestExecution::RunTestCase out. Case ongoing" ) ) ); + + return KErrNone; + + } + + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: NotifyPrint + + Description: Handles print request from engine. If print queue is empty, + message is stored to be used later when there is something to + print, otherwise the first queue item is returned and request + completes immediately. + + Parameters: const RMessage& aMessage :in: Message from client. + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::NotifyPrint( const RMessage2& aMessage ) + { + + __ASSERT_ALWAYS( iPrintNotifyAvailable == EFalse, + CTestServer::PanicServer( EPrintQueueBroken ) ); + + // Get first item from queue + TPrintQueueItem *item = iPrintQueue->Pop(); + + if ( item == NULL ) + { + + // If thread can't print anymore, and queue is empty, then + // complete with Eof, because there will not be any new prints + if ( iThreadState == EFinished || iThreadState == ECancelled ) + { + __TRACE ( KPrint, ( _L( "CTestExecution::NotifyPrint to finished thread" ) ) ); + aMessage.Complete ( KErrEof ); + } + else + { + // Print request available, do not complete request + iNotifyPrintMessage = aMessage; + iPrintNotifyAvailable = ETrue; + } + + } + else + { + // Construct message + TTestProgress progress; + progress.iPosition = item->iPriority; + progress.iDescription = item->iData1; + progress.iText = item->iData2; + + iNotifyPrintMessage = aMessage; + // Write message to client space and complete request + WritePrint( progress ); + + delete item; + } + + + return KErrNone; + + } +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: DoNotifyPrint + + Description: If print notification available, notification is copied to + client memory space and request is completed. + Else new print queue item is created and appended to print + queue. If queue is full or memory can't be allocated, + then message will be discarded. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CTestExecution::DoNotifyPrint() + { + + if ( iPrintNotifyAvailable ) + { + // Write message to client space + WritePrint( iProgress ); + } + else + { + + TPrintQueueItem *item = + new TPrintQueueItem( iProgress.iPosition, + iProgress.iDescription, + iProgress.iText ); + + if ( item != NULL ) + { + // Item constructed ok, add it to queue + if ( iPrintQueue->Push( *item ) != KErrNone ) + { + // Queue is full, clean-up + delete item; + } + } + // else: Could not construct TPrintQueueItem, no free memory. + // drop printing + } + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: DoNotifyInterference + + Description: Handles Test Interference thread append and remove operations. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CTestExecution::DoNotifyInterference() + { + // Information for this context => information is in this thread's heap and + // if CUndertaker::RunL is called then test interface thread can called + // with function call and kill() test interference thread + + // Take information from struct given in + // CTestThreadContainer::AddInterferenceThread or + // CTestThreadContainer::RemoveInterferenceThread + + RThread thread; + TInt ret = thread.Open ( iTestInterference.iThreadId ); + if( ret != KErrNone ) + { + RDebug::Print( _L("CTestExecution::DoNotifyInterference %d"), ret ); + User::Panic( _L("CTestExecution::DoNotifyInterference"), ret ); + } + + if ( iTestInterference.iOperation == TTestInterference::EAppend ) + { + iSTIFTestInterferenceArray.Append( thread ); + } + else if (iTestInterference.iOperation == TTestInterference::ERemove ) + { + // Remove thread from Array.Test interference thread is stopped and killed + // successfully + for( TInt i = 0; i < iSTIFTestInterferenceArray.Count(); i++ ) + { + if( iSTIFTestInterferenceArray[i].Id() == thread.Id() ) + { + iSTIFTestInterferenceArray.Remove( i ); + break; + } + } + } + else + { + return; + } + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: DoNotifyMeasurement + + Description: Handles test measurement operations: NewL, Start and Stop. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Approved + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::DoNotifyMeasurement() + { + // Information for this context => information is in this thread's heap: + // From CUndertaker::RunL() or CTestModuleContainer::RunL() method can + // handle stop and clean operations if these operations are not done + // before. + // Erronous cases(CUndertaker::RunL will be called) or when test case is + // executed(CTestModuleContainer::RunL() will be called) there can handle + // test measurement stop and clean operation. + + if( iTestMeasurement.iMeasurementStruct.iMeasurementOperation == + CSTIFTestMeasurement::KMeasurementNew) + { + // Check that same measurement module don't try to create several times + // Only one measurement type per test is allowed + for( TInt i = 0; i < iMeasurementHandlingArray.Count(); i++ ) + { + if( iMeasurementHandlingArray[i]->iMeasurementModulePtr->MeasurementType() == + iTestMeasurement.iMeasurementStruct.iMeasurementType ) + { + return KErrAlreadyExists; + } + } + + TMeasurementHandling* measurementHandling = NULL; + measurementHandling = new TMeasurementHandling(); + + TBuf modulename; + if( iTestMeasurement.iMeasurementStruct.iMeasurementType == 1 ) + { + modulename.Copy( KStifMeasurement01 ); + } + else if( iTestMeasurement.iMeasurementStruct.iMeasurementType == 2 ) + { + modulename.Copy( KStifMeasurement02 ); + } + else if( iTestMeasurement.iMeasurementStruct.iMeasurementType == 3 ) + { + modulename.Copy( KStifMeasurement03 ); + } + else if( iTestMeasurement.iMeasurementStruct.iMeasurementType == 4 ) + { + modulename.Copy( KStifMeasurement04 ); + } + else if( iTestMeasurement.iMeasurementStruct.iMeasurementType == 5 ) + { + modulename.Copy( KStifMeasurement05 ); + } + else if( iTestMeasurement.iMeasurementStruct.iMeasurementType == 6 ) + { + modulename.Copy( KStifMeasurementBappea ); + } + else + { + __TRACE( KError, ( _L("CTestExecution::DoNotifyMeasurement(): unknown measurement type" ) ) ); + return KErrArgument; + } + + // Loading should work with and without '.dll' extension. + TInt r = measurementHandling->iMeasurementModule.Load( modulename ); + if ( r != KErrNone ) + { + __TRACE( KError, ( CStifLogger::EError, _L("Can't load test measurement module[%S], code = %d"), + &modulename, r ) ); + delete measurementHandling; + return KErrNotFound; + } + else + { + //Print test measururement module name + __TRACE( KInit, ( _L("Loaded test measurement module[%S]"), + &modulename ) ); + } + + // Get pointer to first exported function + // Verify that there is function + measurementHandling->iMeasurementLibEntry = (CTestMeasurementFactory) measurementHandling->iMeasurementModule.Lookup( 1 ); + if ( measurementHandling->iMeasurementLibEntry == NULL ) + { + // New instance can't be created + __TRACE( KInit, (_L( "Test measurement module instance cannot create." ) ) ); + measurementHandling->iMeasurementModule.Close(); + delete measurementHandling; + return KErrNotFound; + } + else + { + __TRACE ( KInit, ( _L("Pointer to 1st exported received"))); + } + + CSTIFTestMeasurementImplementation* measurement; + measurement = NULL; + + // initialize test measurement module + __TRACE ( KVerbose, (_L("Calling 1st exported at 0x%x"), (TUint32) measurementHandling->iMeasurementLibEntry )); + TRAPD ( err, measurement = (*measurementHandling->iMeasurementLibEntry)( + iTestMeasurement.iMeasurementStruct.iConfigurationInfo, iTestMeasurement.iMeasurementStruct.iMeasurementType ) ); + + // Handle leave from test module + if ( err != KErrNone ) + { + __TRACE (KError, ( CStifLogger::EError, _L( "Leave when calling 1st exported function, code %d"), err ) ); + delete measurementHandling; + return err; + } + else if ( measurementHandling->iMeasurementLibEntry == NULL ) // Handle NULL from test measurement + { + __TRACE (KError, ( CStifLogger::EError, _L( "NULL pointer received when constructing test measurement module" ) ) ); + delete measurementHandling; + // Set error codes + return KErrNoMemory; + } + else + { + measurementHandling->iMeasurementModulePtr = measurement; + __TRACE (KInit, (_L("Entrypoint successfully called, Measurement module instance at 0x%x"), + (TUint32)measurementHandling->iMeasurementLibEntry ) ); + } + iMeasurementHandlingArray.Append( measurementHandling ); + } // End of NewL operations + + else if( iTestMeasurement.iMeasurementStruct.iMeasurementOperation == + CSTIFTestMeasurement::KMeasurementStart) + { + for( TInt i = 0; i < iMeasurementHandlingArray.Count(); i++ ) + { + if( iMeasurementHandlingArray[i]->iMeasurementModulePtr->MeasurementType() == iTestMeasurement.iMeasurementStruct.iMeasurementType ) + { + return iMeasurementHandlingArray[i]->iMeasurementModulePtr->Start(); + } + } + + } + else if( iTestMeasurement.iMeasurementStruct.iMeasurementOperation == + CSTIFTestMeasurement::KMeasurementStop) + { + for( TInt i = 0; i < iMeasurementHandlingArray.Count(); i++ ) + { + if( iMeasurementHandlingArray[i]->iMeasurementModulePtr->MeasurementType() == iTestMeasurement.iMeasurementStruct.iMeasurementType ) + { + TInt stop_ret = iMeasurementHandlingArray[i]->iMeasurementModulePtr->Stop(); + delete iMeasurementHandlingArray[i]; + iMeasurementHandlingArray.Remove(i); + return stop_ret; + } + } + } + else + { + __TRACE (KError, ( CStifLogger::EError, _L("CTestExecution::DoNotifyMeasurement(): Not supported operation") ) ); + return KErrNotSupported; + } + + return KErrNone; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: WritePrint + + Description: Writes print notification to client memory space. + + Parameters: const TInt aPriority :in: Priority + const TStifInfoName& aDes :in: Description + const TName& aBuffer :in: Value + + Return Values: TInt Return value from message write + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::WritePrint( TTestProgress& aProgress ) + { + + TTestProgressPckg progressPckg( aProgress ); + + // Write message to client space + TRAPD( res, iNotifyPrintMessage.WriteL( 0, progressPckg ) ); + + iPrintNotifyAvailable = EFalse; + + // Complete request with possible error code + iNotifyPrintMessage.Complete( res ); + + return res; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: NotifyEvent + + Description: Handles event request from engine. + + ESetEvent and EUnsetEvent change event status. EEnable enables + event notify. + + Parameters: const RMessage& aMessage :in: Message from client. + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::NotifyEvent( const RMessage2& aMessage ) + { + + TEventIf event; + TEventIfPckg eventPckg( event ); + + TRAPD( res, aMessage.ReadL( 0, eventPckg ) ); + + if( res != KErrNone ) + { + __TRACE( KError, ( _L( "CTestExecution::NotifyEvent: ReadL failed" ) )); + return res; + } + + switch( event.Type() ) + { + case TEventIf::ESetEvent: + { + TInt ind = 0; + TInt count = iEventArray.Count(); + for( ind=0; ind < count; ind++ ) + { + if( iEventArray[ind]->Name() == event.Name() ) + { + __TRACE( KMessage, ( _L( "CTestExecution::NotifyEvent(%d): SetEvent %S ( count %i )" ), + this, &event.Name(), count ) ); + TEventIf::TEventType etype = TEventIf::EIndication; + // To get state events working with testcombiner + if( ( event.EventType() == TEventIf::EState ) || + ( iEventArray[ind]->EventType() == TEventIf::EState ) ) + { + etype = TEventIf::EState; + } + iEventArray[ind]->Set( etype ); + } + } + } + break; + case TEventIf::EUnsetEvent: + { + return UnsetEvent( event, aMessage ); + } + case TEventIf::EEnable: + { + // Store event message + iNotifyEventMessage = aMessage; + iEventNotifyAvailable = ETrue; + TInt errorFromPreviousCmd = aMessage.Int1(); + + __TRACE( KMessage, ( _L( "CTestExecution::NotifyEvent: enable (%d) notify %d" ), + errorFromPreviousCmd, this ) ); + + // Complete previous Event command + CompleteEvent( errorFromPreviousCmd ); + iEventHandler->StartL(); + + // iNotifyEventMessage is completed from DoNotifyEvent + return KErrNone; + } + + default: + __TRACE( KError, ( _L( "CTestExecution::NotifyEvent: Unknown command %i" ), + event.Type() )); + return KErrArgument; + } + + __TRACE( KMessage, ( _L( "CTestExecution::NotifyEvent(%d): Done" ), this ) ); + + aMessage.Complete( KErrNone ); + //User::After(1000); //Stif-95 This pause is needed to let Info::TestFrameworkEngine thread + //get some processor time and run exactly at this moment (by calling + //CTestEventController::EventCallBack). When Stif is focused on the screen, + //there is no problem if this line is absent, however when another + //application (like screen saver) is focused this is required. + return KErrNone; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: DoNotifyEvent + + Description: Forward event request. + + Parameters: None + + Return Values: None + + Errors/Exceptions: Panics if event array can't be created + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::DoNotifyEvent() + { + + TInt ret = KErrNone; + + switch( iEventDef.iEvent.Type() ) + { + case TEventIf::EReqEvent: + { + __TRACE( KMessage, + ( _L( "CTestExecution::DoNotifyEvent(%d): ReqEvent %S" ), + this, &iEventDef.iEvent.Name() ) ); + ret = RequestEvent( iEventDef.iEvent ); + // If error, return error, + // otherwise proceed with sending information to engine + if( ret != KErrNone ) + { + iEventHandler->StartL(); + return ret; + } + } + break; + case TEventIf::EWaitEvent: + case TEventIf::ESetWaitPending: + { + __TRACE( KMessage, + ( _L( "CTestExecution::DoNotifyEvent(%d): WaitEvent %S" ), + this, &iEventDef.iEvent.Name() ) ); + // We return from here, i.e. nothing is sent to engine + ret = WaitEvent( iEventDef.iEvent, iEventDef.iStatus ); + iEventHandler->StartL(); + return ret; + } + // Add state events to internal array + case TEventIf::ESetEvent: + case TEventIf::EUnsetEvent: + { + __TRACE( KMessage, + ( _L( "CTestExecution::DoNotifyEvent(%d): Set/UnsetEvent %S" ), + this, &iEventDef.iEvent.Name() ) ); + EventStateChange( iEventDef.iEvent ); + } + break; + case TEventIf::ERelEvent: + // This is handled later + __TRACE( KMessage, + ( _L( "CTestExecution::DoNotifyEvent(%d): RelEvent %S" ), + this, &iEventDef.iEvent.Name() ) ); + break; + default: + iEventHandler->StartL(); + return KErrArgument; + } + + // Construct message + TEventIfPckg eventPckg( iEventDef.iEvent ); + + // Write message to client space + TRAPD( res, iNotifyEventMessage.WriteL( 0, eventPckg ) ); + + if( res != KErrNone ) + { + __TRACE( KError, ( _L( "CTestExecution::DoNotifyEvent: WriteL failed" ) ) ); + ret = res; + } + // Complete request + // Complete with WriteL result + // MUST be done before ERelEvent + iEventNotifyAvailable = EFalse; + iNotifyEventMessage.Complete( res ); + User::After(1000); //Stif-95 This pause is needed to let Info::TestFrameworkEngine thread + //get some processor time and run exactly at this moment (by calling + //CTestEventNotifier::RunL). When Stif is focused on the screen, + //there is no problem if this line is absent, however when another + //application (like screen saver) is focused this is required. + + if( iEventDef.iEvent.Type() == TEventIf::ERelEvent ) + { + ret = ReleaseEvent( iEventDef.iEvent ); + if( ret != KErrNone ) + { + // If error, return immediately + return ret; + } + } + + __TRACE( KMessage, ( _L( "CTestExecution::DoNotifyEvent(%d): Done" ), this ) ); + + return ret; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: RequestEvent + + Description: Handles TestModule event requests. + + Parameters: const TEventIf& aEvent: in: Event requested + + Return Values: TInt: Success/Error code + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::RequestEvent( TEventIf& aEvent ) + { + + // Requested events are added to iEventArray + // There can be multiple simultaneous requests for the same event + TEvent* event = new TEvent( iTestThreadId ); + if( !event ) + { + return KErrNoMemory; + } + event->Copy( aEvent ); + if( iEventArray.Append( event ) != KErrNone ) + { + delete event; + return KErrNoMemory; + } + + __TRACE( KMessage,( _L( "CTestExecution::DoNotifyEvent: Req added %S ( count %i )" ), + &aEvent.Name(), iEventArray.Count() )); + + return KErrNone; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: WaitEvent + + Description: Handles TestModule event waits. Waiting is implemented here + and completed in NotifyEvent + + + Parameters: const TEventIf& aEvent: in: Event wait + + Return Values: TInt: Success/Error code + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::WaitEvent( TEventIf& aEvent, TRequestStatus* aStatus ) + { + + // Get first "free" event entry from requested events + TInt ind = 0; + TInt count = iEventArray.Count(); + TEvent* event = NULL; + for( ind=0; ind < count; ind++ ) + { + if( ( iEventArray[ind]->Name() == aEvent.Name() ) && + ( iEventArray[ind]->WaitEventPending() == EFalse ) ) + { + // Found event with correct name and one that is still free + // i.e. nobody is waiting for it. + event = iEventArray[ind]; + if( aEvent.Type() == TEventIf::EWaitEvent ) + { + // For EWaitEvent we complete immediately if event is pending + if( event->EventPending() ) + { + // Event was already pending, so we may return immediately + if( aStatus ) + { + TestThreadRequestComplete( aStatus, KErrNone ); + } + return KErrNone; + } + } + } + } + if( event == NULL ) + { + // Event is not in the iEventArray, + // so event is not currently requested + return KErrNotFound; + } + + __TRACE( KMessage,( _L( "CTestExecution::DoNotifyEvent: Waiting %S ( count %i )" ), + &aEvent.Name(), count )); + + // Event is not pending so we have to wait for it + // Set wait pending + TInt ret = event->SetWaitPending( aStatus ); + // event cannot be freed by the test module, + // because it is waiting the event, + + if( ( aStatus == NULL ) && + ( ret == KErrNone ) && + ( aEvent.Type() == TEventIf::EWaitEvent ) ) + { + // This is synchronous wait + // Go waiting, completed from set event + event->Wait(); + } + + return ret; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: ReleaseEvent + + Description: Handles TestModule event releases. + + Parameters: const TEventIf& aEvent: in: Event released + + Return Values: TInt: Success/Error code + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::ReleaseEvent( TEventIf& aEvent ) + { + + // Get last event entry from requested events + TInt ind = 0; + TInt freeFound = 0; + TInt eventIndex = 0; + TInt count = iEventArray.Count(); + for( ind=0; ind < count; ind++ ) + { + if( iEventArray[ind]->Name() == aEvent.Name() ) + { + if( iEventArray[ind]->WaitEventPending() == EFalse ) + { + freeFound++; + eventIndex = ind; + } + } + } + + if( freeFound == 0 ) + { + return KErrNotFound; + } + __TRACE( KMessage,( + _L( "CTestExecution::DoNotifyEvent: Release event %S ( count %i )" ), + &aEvent.Name(), iEventArray.Count() )); + + TEvent* event = iEventArray[eventIndex]; + iEventArray.Remove( eventIndex ); + // Release and free event entry + event->Release(); + + // Delete used event entry + delete event; + + return KErrNone; +} + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: UnsetEvent + + Description: Handles TestModule event unsets. + + Parameters: const TEventIf& aEvent: in: Event unset + + Return Values: TInt: Success/Error code + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::UnsetEvent( TEventIf& aEvent, const RMessage2& aMessage ) + { + + TInt ret = KErrNone; + TInt ind = 0; + TInt count = iEventArray.Count(); + TBool activeEventReq = EFalse; + for( ind=0; ind < count; ind++ ) + { + if( iEventArray[ind]->Name() == aEvent.Name() ) + { + __TRACE( KMessage, ( + _L( "CTestExecution::NotifyEvent(%d): UnsetEvent %S ( count %i )" ), + this, &aEvent.Name(), count ) ); + + ret = iEventArray[ind]->Unset( aMessage, this ); + if( ret == KErrNone ) + { + activeEventReq = ETrue; + } + break; + } + } + if( activeEventReq ) + { + // Unset is completed by release + return KErrNone; + } + + // No pending requests or error from unset + aMessage.Complete( ret ); + + return KErrNone; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: EventStateChange + + Description: Handles event setting and unsetting. Saves status of + state events to enable unsetting of set state events when + killing the testcase abnormally. + + Parameters: const TEventIf& aEvent: in: Event set/unset + + Return Values: TInt: Success/Error code + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::EventStateChange( TEventIf& aEvent ) + { + + TInt ret = KErrNotFound; + if( aEvent.EventType() == TEventIf::EState ) + { + + TInt count = iStateEvents.Count(); + TInt index = 0; + for(; index < count; index++ ) + { + TPtrC name = *(iStateEvents[index]); + if( name == aEvent.Name() ) + { + break; + } + } + + + if( aEvent.Type() == TEventIf::ESetEvent ) + { + if( index < count ) + { + ret = KErrAlreadyExists; + } + else + { + // add event to iStateEvents + HBufC* name = aEvent.Name().Alloc(); + if( name == NULL ) + { + ret = KErrNoMemory; + } + else if( iStateEvents.Append( name ) != KErrNone ) + { + delete name; + ret = KErrNoMemory; + } + else + { + ret = KErrNone; + } + } + } + else if( aEvent.Type() == TEventIf::EUnsetEvent ) + { + if( index == count ) + { + ret = KErrNotFound; + } + else + { + ret = KErrNone; + delete iStateEvents[index]; + iStateEvents.Remove( index ); + } + } + } + + return ret; + + } +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: CancelEvent + + Description: Cancels pending event request. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CTestExecution::CancelEvent() + { + + TInt ret = KErrNotFound; + + __TRACE( KMessage, ( _L( "CTestThreadContainer::CancelEvent(%d): %S [%p]" ), + iEventDef.iEvent.Type(), &iEventDef.iEvent.Name(), iEventDef.iStatus ) ); + + switch( iEventDef.iEvent.Type() ) + { + case TEventIf::EReqEvent: + case TEventIf::ERelEvent: + case TEventIf::ESetEvent: + case TEventIf::EUnsetEvent: + CompleteEvent( KErrCancel ); + break; + case TEventIf::EWaitEvent: + case TEventIf::ESetWaitPending: + { + // Get waited event entry from requested events + TInt ind = 0; + TInt count = iEventArray.Count(); + for( ind=0; ind < count; ind++ ) + { + if( ( iEventArray[ind]->Name() == iEventDef.iEvent.Name() ) && + ( iEventArray[ind]->WaitEventPending() != EFalse ) && + ( iEventArray[ind]->RequestStatus() == iEventDef.iStatus ) ) + { + TEvent* event = iEventArray[ind]; + // Found event with correct name and one that is waited. + event->CompletePendingWait( KErrCancel ); + ret = KErrNone; + break; + } + } + if( ret != KErrNone ) + { + // Request has been already completed, not handled + // by ActiveScheduler yet. + // DoCancel will do the job, don't worry. + __TRACE( KError, ( _L( "CTestThreadContainer::CancelEvent(%d): %S, not found 2" ), + iEventDef.iEvent.Type(), &iEventDef.iEvent.Name() ) ); + } + } + break; + default: + CTestServer::PanicServer( EUnknownEventCmd ); + break; + } + + // Synchonize + iEventHandler->StartL(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: NotifyRemoteCmd + + Description: Handles the first phase of the RemoteCmd request from engine. + + Parameters: const RMessage& aMessage: in: Message from client. + + Return Values: Symbian OS error code. + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::NotifyRemoteCmd( const RMessage2& aMessage ) + { + + // Store RemoteCmd message + // and the length buffer address + iNotifyRemoteCmdMessage = aMessage; + iRemoteSendAvailable = ETrue; + iSndHandler->StartL(); + + return KErrNone; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: DoRemoteReceive + + Description: Enable remote receive. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CTestExecution::DoRemoteReceive() + { + + switch( iRcvCmdDef.iCommand ) + { + case EStifCmdReceive: // "Receive" + { + // @js If there's pointer in array, we'll send it down + if(iMessageQueue.Count() > 0) + { + HBufC8 * buf = iMessageQueue[0]; + iRcvCmdDef.iParam.aRemoteMsgRef->Copy( iMessageQueue[0]->Des() ); + iMessageQueue.Remove(0); + delete buf; + __TRACE( KMessage, + (_L("CTestExecution::ReadRemoteCmdInfo: complete receive 0x%x"), + iRcvCmdDef.iStatus )); + + // calls the TestCombiner's CRemoteReceiver::RunL() + TestThreadRequestComplete( iRcvCmdDef.iStatus, KErrNone ); + } + else + { + iRemoteReceiveAvailable = ETrue; + } + + break; + } + case EStifCmdReceiveCancel: + if( iRemoteReceiveAvailable ) + { + iRemoteReceiveAvailable = EFalse; + TestThreadRequestComplete( iRcvCmdDef.iStatus, KErrCancel ); + } + break; + default: + CTestServer::PanicServer( EUnknownRemoteCmd ); + break; + } + // Signal test thread + iRcvHandler->StartL(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: DoRemoteSend + + Description: Send remote messages. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Approved + +------------------------------------------------------------------------------- +*/ +void CTestExecution::DoRemoteSend() + { + switch( iCmdDef.iCommand ) + { + case EStifCmdSend: // "Send" + case EStifCmdReboot: // "Send" + case EStifCmdStoreState: // "Send" + case EStifCmdGetStoredState: // "Receive, this must be done with two phase" + case EStifCmdMeasurement: // "Receive, this must be done with two phase" + { + if( iRemoteSendAvailable ) + { + TInt ret = KErrNone; + TPckg remoteCommandPckg( iCmdDef.iCommand ); + + // Start first phase of the writing message to client space + TRAP( ret, + iNotifyRemoteCmdMessage.WriteL( 0, remoteCommandPckg ) ); + + if( ret != KErrNone ) + { + __TRACE( KError, ( _L( "CTestExecution::DoRemoteSend: WriteL failed" ) ) ); + } + TPckg lenPckg( iCmdDef.iLen ); + + TRAP( ret, + iNotifyRemoteCmdMessage.WriteL( 1, lenPckg ) ); + + if( ret != KErrNone ) + { + __TRACE( KError, ( _L( "CTestExecution::DoRemoteSend: WriteL failed" ) ) ); + } + + // Complete request + // Complete with WriteL result + // CTestRemoteCmdNotifier::RunL() will called + iRemoteSendAvailable = EFalse; + iNotifyRemoteCmdMessage.Complete( ret ); + break; + } + } + TestThreadRequestComplete( iCmdDef.iStatus, KErrNotSupported ); + break; + default: + CTestServer::PanicServer( EUnknownRemoteCmd ); + break; + } + + } + + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: ReadRemoteCmdInfo + + Description: Handles the second phase of the RemoteCmd request from engine. + + Parameters: const RMessage& aMessage: in: Message from client. + + Return Values: Symbian OS error code. + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::ReadRemoteCmdInfo( const RMessage2& aMessage ) + { + + TInt ret( KErrNone ); + TInt completeSend = EFalse; + TInt returnedErrorCode = KErrNone; + TInt len = 0; + TInt value( aMessage.Int2() ); + if( value < 0 ) + { + returnedErrorCode = value; + } + else + { + len = value; + } + + switch( aMessage.Int1() ) + { + case EStifCmdReceive: // "Receive" + { + + if( len <= 0 ) + { + __TRACE( KError, + (_L("CTestExecution::ReadRemoteCmdInfo: empty message"))); + ret = KErrGeneral; + break; + } + if( iRcvCmdDef.iParam.aRemoteMsgRef->MaxLength() < len ) + { + __TRACE( KError, + (_L("CTestExecution::ReadRemoteCmdInfo: message overflow"))); + ret = KErrGeneral; + break; + } + + HBufC8* buf = HBufC8::New( len ); + if( buf == NULL ) + { + ret = KErrNoMemory; + break; + } + TPtr8 tmp = buf->Des(); + // Read message from client space + TRAP( ret, aMessage.ReadL( 0, tmp ) ); + + + if( ret != KErrNone ) + { + __TRACE( KError, + (_L("CTestExecution::ReadRemoteCmdInfo: ReadL failed"))); + break; + } + + if( iRemoteReceiveAvailable ) + // @js Checking moved here + { + iRcvCmdDef.iParam.aRemoteMsgRef->Copy( buf->Des() ); + delete buf; + + __TRACE( KMessage, + (_L("CTestExecution::ReadRemoteCmdInfo: complete receive 0x%x"), + iRcvCmdDef.iStatus )); + // calls the TestCombiner's CRemoteReceiver::RunL() + TestThreadRequestComplete( iRcvCmdDef.iStatus, ret ); + + iRemoteReceiveAvailable = EFalse; + } + else + // @js Adding buf to RPointerArray, handling it in DoRemoteReceive function + { + iMessageQueue.Append( buf ); + } + + break; + } + case EStifCmdSend: // "Send" + { + HBufC8* buf = HBufC8::New( iCmdDef.iParam.aRemoteMsgConstRef->Length() ); + if( buf == NULL ) + { + ret = KErrNoMemory; + break; + } + TPtr8 tmp = buf->Des(); + tmp.Copy( *iCmdDef.iParam.aRemoteMsgConstRef ); + // Second phase of the writing. Write information to the Engine. + TRAP( ret, aMessage.WriteL( 0, tmp ) ); + + delete buf; + + if( ret != KErrNone ) + { + __TRACE( KError, ( _L( "CTestExecution::ReadRemoteCmdInfo: WriteL failed" ) ) ); + } + completeSend = ETrue; + break; + } + case EStifCmdReboot: // "Send" + { + TRebootParamsPckg remoteTypePckg( *iCmdDef.iParam.aRebootType ); + + // Second phase of the writing. Write information to the Engine. + TRAP( ret, aMessage.WriteL( 0, remoteTypePckg ) ); + + if( ret != KErrNone ) + { + __TRACE( KError, ( _L( "CTestExecution::ReadRemoteCmdInfo: WriteL failed" ) ) ); + } + // Because Reboot must block...Don't complete, so now we wait for + // ever phone booting operation !!!!! + break; + } + case EStifCmdStoreState: // "Send" + { + TRebootStateParamsPckg remoteStatePckg( *iCmdDef.iParam.aRebootState ); + + // Second phase of the writing. Write information to the Engine. + TRAP( ret, aMessage.WriteL( 0, remoteStatePckg ) ); + + if( ret != KErrNone ) + { + __TRACE( KError, ( _L( "CTestExecution::ReadRemoteCmdInfo: WriteL failed" ) ) ); + } + // Completed from EStifCmdRebootProceed + break; + } + case EStifCmdMeasurement: // "Receive" + { + TGetMeasurementOptions getMeasurementOptions; + TGetMeasurementOptionsPckg measurementParamsPckg( getMeasurementOptions ); + + // Read message from client space + TRAP( ret, aMessage.ReadL( 0, measurementParamsPckg ) ); + + if( ret != KErrNone ) + { + __TRACE( KError, ( _L( "CTestExecution::ReadRemoteCmdInfo: ReadL failed" ) ) ); + } + iCmdDef.iParam.aMeasurementOption->iOptions = getMeasurementOptions.iOptions; + + completeSend = ETrue; + break; + } + case EStifCmdGetStoredState: // "Receive" + { + TGetRebootStoredParams getRebootStoredParams; + TGetRebootStoredParamsPckg rebootStoredParamsPckg( getRebootStoredParams ); + + // Read message from client space + TRAP( ret, aMessage.ReadL( 0, rebootStoredParamsPckg ) ); + + if( ret != KErrNone ) + { + __TRACE( KError, ( _L( "CTestExecution::ReadRemoteCmdInfo: ReadL failed" ) ) ); + } + iCmdDef.iParam.aRebootStoredRef->iCode = getRebootStoredParams.aCode; + iCmdDef.iParam.aRebootStoredRef->iName = getRebootStoredParams.aName; + + completeSend = ETrue; + break; + } + case EStifCmdRebootProceed: + { + completeSend = ETrue; // Complete EStifCmdStoreState + } + break; + default: + { + iModuleSession->PanicClient( EUnknownRemoteCmd, aMessage ); + break; + } + } + // Complete request with ret + aMessage.Complete( ret ); + + if( completeSend ) + { + // Calls the TestCombiner's CRemoteReceiver::RunL() and + // returns error code to test module. + TestThreadRequestComplete( iCmdDef.iStatus, returnedErrorCode ); + } + + return KErrNone; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: Pause + + Description: Pauses a test case + + Only ongoing tests can be paused. If test is not ongoing, then + function does nothing. + + Parameters: const RMessage& aMessage :in: Message from client. + + Return Values: TInt Always KErrNone + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::Pause( const RMessage2& aMessage ) + { + + __TRACE ( KThreadOperation, ( _L( "CTestExecution::Pause" ) ) ); + + TInt completionCode = KErrNone; + + // Note that it is allowed to suspend already suspended thread, so + // there is no need for states to verify that thread is really in + // resumed state. + switch ( iThreadState ) + { + case EOnGoing: + completionCode = iModuleContainer->PauseThread(); + break; + + case ENotStarted: + completionCode = KErrNotReady; + break; + + case EFinished: + case ECancelled: + completionCode = KErrCompletion; + break; + + default: + CTestServer::PanicServer( EInvalidThreadState ); + break; + } + + + // Complete the request + aMessage.Complete( completionCode ); + + return KErrNone; + + } + + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: Resume + + Description: Resumes a test case. If test is not ongoing, + then do not resume. + + Parameters: const RMessage& aMessage :in: Message from client. + + Return Values: TInt Always KErrNone + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::Resume( const RMessage2& aMessage ) + { + + __TRACE ( KThreadOperation, ( _L( "CTestExecution::Resume" ) ) ); + + TInt completionCode = KErrNone; + + // Note that it is allowed to resume already resumed thread, so + // there is no need for states to verify that thread is really in + // suspended state. + switch ( iThreadState ) + { + case EOnGoing: + completionCode = iModuleContainer->ResumeThread(); + break; + + case ENotStarted: + completionCode = KErrNotReady; + break; + + case EFinished: + case ECancelled: + completionCode = KErrCompletion; + break; + + default: + CTestServer::PanicServer( EInvalidThreadState ); + break; + } + + + // Complete the request + aMessage.Complete( completionCode ); + + return KErrNone; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: CloseTestExecution + + Description: Closes Test Execution subsession + + Parameters: const RMessage& aMessage :in: Message from client. + + Return Values: TInt Always KErrNone + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::CloseTestExecution( const RMessage2& aMessage ) + { + + // Cancel test request + CancelTestRequest(); + + // Cancel print request + CancelPrintRequest(); + + // Cancel event request + CancelEventRequest(); + + // Delete this subsession + const TUint subsession = aMessage.Int3(); + iModuleSession->DeleteTestExecution( subsession, aMessage ); + + // Complete the request + aMessage.Complete( KErrNone ); + + return KErrNone; + + } + + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: CancelPrintRequest + + Description: Cancel print request. Completes ongoing print request + with KErrCancel. + + Parameters: None + + Return Values: TInt Always KErrNone + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::CancelPrintRequest() + { + + if ( iPrintNotifyAvailable ) + { + iPrintHandler->Cancel(); + + iPrintNotifyAvailable = EFalse; + iNotifyPrintMessage.Complete ( KErrCancel ); + //@spe iPrintNotifyAvailable = EFalse; + } + + return KErrNone; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: CancelEventRequest + + Description: Cancel event request. Completes ongoing event request + with KErrCancel. + + Parameters: None + + Return Values: TInt Always KErrNone + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::CancelEventRequest() + { + iEventHandler->Cancel(); + + if( iEventNotifyAvailable ) + { + // Cancel request + iEventNotifyAvailable = EFalse; + iNotifyEventMessage.Complete ( KErrCancel ); + } + + return KErrNone; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: CancelInterferenceRequest + + Description: Cancel print request. Completes ongoing print request + with KErrCancel. + + Parameters: None + + Return Values: TInt: Always KErrNone + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::CancelInterferenceRequest() + { + + if ( iInterferenceNotifyAvailable ) + { + iInterferenceHandler->Cancel(); + + iInterferenceNotifyAvailable = EFalse; + iNotifyInterferenceMessage.Complete ( KErrCancel ); + } + + return KErrNone; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: CancelRemoteCmdRequest + + Description: Cancel RemoteCmd request. Completes ongoing RemoteCmd request + with KErrCancel. + + Parameters: None + + Return Values: TInt: Always KErrNone + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::CancelRemoteCmdRequest() + { + iSndHandler->Cancel(); + + // Cancel request + if( iRemoteSendAvailable ) + { + iRemoteSendAvailable = EFalse; + iNotifyRemoteCmdMessage.Complete ( KErrCancel ); + } + + return KErrNone; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: NotifyCommand + + Description: Handles the first phase of the Command request from engine. + + Parameters: const RMessage& aMessage: in: Message from client. + + Return Values: Symbian OS error code. + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::NotifyCommand( const RMessage2& aMessage ) + { + iNotifyCommandMessage = aMessage; + iCommandNotifyAvailable = ETrue; + iCommandHandler->StartL(); + + return KErrNone; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: CancelCommandRequest + + Description: Cancel Command request. Completes ongoing Command request + with KErrCancel. + + Parameters: None + + Return Values: TInt: Always KErrNone + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::CancelCommandRequest() + { + iCommandHandler->Cancel(); + + // Cancel request + if(iCommandNotifyAvailable) + { + iCommandNotifyAvailable = EFalse; + iNotifyCommandMessage.Complete(KErrCancel); + } + + return KErrNone; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: GetTestCaseArguments + + Description: Get test case arguments + + Parameters: None + + Return Values: Test case arguments + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +const TDesC& CTestExecution::GetTestCaseArguments() const + { + if ( iTestCaseArgs != NULL ) + { + return *iTestCaseArgs; + } + return KNullDesC; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: CancelTestRequest + + Description: Cancel test execution request. + If thread is not in OnGoing state, function does not do anything. + + Otherwise following operations are done: + 1 ) Obtain access to both PrintMutex and EventMutex to make sure that + thread can't be accessing print queue or events. + 2 ) Kill the thread + 3 ) Complete original "RunTestCase" request with KErrCancel + 4 ) If print queue is empty, complete print request + 5 ) Give up mutexes + 6 ) Delete module container + + Parameters: None + + Return Values: TInt: Always KErrNone + + Errors/Exceptions: None + + Status: Approved + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::CancelTestRequest() + { + // This mutex block and make sure that cancel operation is done succesfully + // and test case e.g. cannot complete at the same time. Get mutex. + iTestThreadMutex.Wait(); + + // iModuleContainer is an active object, check is active. + if ( iModuleContainer == NULL || ( iModuleContainer != NULL && !iModuleContainer->IsActive() ) ) + { + // Test case is already ready, return. + iTestThreadMutex.Signal(); + return KErrNone; + } + + if ( iThreadState == EOnGoing ) + { + // Print mutex access is required to make sure that the dying thread + // does not have access to print queue. Same is true for event queue. + + // NOTE: iEventArrayMutex is now taken, so the ongoing thread + // can't set any events so queue will be empty. + iPrintHandler->Cancel(); + iEventHandler->Cancel(); + iInterferenceHandler->Cancel(); + iCommandHandler->Cancel(); + + // Kill the thread + iModuleContainer->KillThread( KErrCancel ); + + // Complete the test execution request + CompleteTestExecution( KErrCancel, TFullTestResult::ECaseCancelled, + KErrCancel, KErrCancel, _L( "Cancelled" ) ); + iThreadState = ECancelled; + + + /** + * Removed, because may block in certain situations. Implemented now in + * TestCombiner instead. + // Unset all pending state events, + // because we have killed the testcase abnormally + // UnsetStateEvents(); + */ + + // Complete print request if queue is empty + CompletePrintRequestIfQueueEmpty(); + + // Delete the module containter + delete iModuleContainer; + iModuleContainer = NULL; + } + + // Relinquish mutex. + iTestThreadMutex.Signal(); + + return KErrNone; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: CancelRequestL + + Description: Cancel asynchronous request + + Parameters: const RMessage& aMessage :in: Message from client. + + Return Values: TInt Error code from CancelXXX- + function + + Errors/Exceptions: Function panics the client, if invalid message + received. + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::CancelRequestL( const RMessage2& aMessage ) + { + TInt r = KErrNone; + + switch ( aMessage.Int0() ) + { + case ETestExecutionRunTestCase: + { + r = CancelTestRequest(); + break; + } + case ETestExecutionNotifyProgress: + { + r = CancelPrintRequest(); + break; + } + case ETestExecutionNotifyEvent: + { + r = CancelEventRequest(); + break; + } + case ETestExecutionNotifyRemoteCmd: + { + r = CancelRemoteCmdRequest(); + break; + } + case ETestExecutionNotifyCommand: + { + r = CancelCommandRequest(); + break; + } + default: + iModuleSession->PanicClient( EInvalidRequestCancel, aMessage ); + break; + } + + aMessage.Complete( r ); + + return r; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: SetThreadState + + Description: A multithread safe thread state modification function + + Parameters: const TTestState aState :in: New state + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CTestExecution::SetThreadState( const TTestState aState ) + { + + iThreadState = aState; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: Complete event + + Description: Completes pending event request. Must be + called with iEventSem taken. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CTestExecution::CompleteEvent( TInt aError ) + { + if( iEventDef.iStatus ) + { + __TRACE( KMessage,(_L("Comp Stat %d, %x (error %d)"), + this, iEventDef.iStatus, aError)); + TestThreadRequestComplete( iEventDef.iStatus, aError ); + + iEventDef.iStatus = NULL; + + } + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: CompletePrintRequestIfQueueEmpty + + Description: Completes print request if queue is empty. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CTestExecution::CompletePrintRequestIfQueueEmpty() + { + + if ( iPrintNotifyAvailable && iPrintQueue->Count() == 0 ) + { + iNotifyPrintMessage.Complete ( KErrEof ); + iPrintNotifyAvailable = EFalse; + } + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: CleanupEvents + + Description: Cleanups Events. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CTestExecution::CleanupEvents() + { + + iEventArray.ResetAndDestroy(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: GetRq + + Description: Get request pointers. + + Parameters: None + + Return Values: TRequestStatus* + + Errors/Exceptions: None + + Status: Approved + +------------------------------------------------------------------------------- +*/ +TRequestStatus* CTestExecution::GetRq( TRequestType aType ) + { + + TRequestStatus* status = NULL; + + switch( aType ) + { + case ERqPrint: + status = &iPrintHandler->iStatus; + break; + case ERqEvent: + status = &iEventHandler->iStatus; + break; + case ERqSnd: + status = &iSndHandler->iStatus; + break; + case ERqRcv: + status = &iRcvHandler->iStatus; + break; + case ERqInterference: + status = &iInterferenceHandler->iStatus; + break; + case ERqMeasurement: + status = &iMeasurementHandler->iStatus; + break; + case ERqCommand: + status = &iCommandHandler->iStatus; + break; + default: + break; + } + + return status; + + } + + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: CompleteTestExecution + + Description: Completes test execution + + Parameters: const TInt aCompletionCode :in: Request completion code + const TInt aCaseExecutionCode in: Case execution code + const TFullTestResult::TCaseExecutionResult aCaseExecutionType, + const TInt aCaseResult :in: Case result + const TDesC& aText :in: Completion text + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CTestExecution::CompleteTestExecution( const TInt aCompletionCode, + const TFullTestResult::TCaseExecutionResult aCaseExecutionType, + const TInt aCaseExecutionCode, + const TInt aCaseResult, + const TDesC& aText ) + { + + TInt completionCode = aCompletionCode; + + if( iModuleContainer != NULL ) + { + // Fill the description + iFullResult.iEndTime.HomeTime(); + iFullResult.iCaseExecutionResultType = aCaseExecutionType; + iFullResult.iCaseExecutionResultCode = aCaseExecutionCode; + iFullResult.iTestResult.iResult = aCaseResult; + iFullResult.iTestResult.iResultDes = aText; + CompleteTestExecution( aCompletionCode ); + return; + } + else + { + completionCode = KErrGeneral; + __TRACE ( KError, ( CStifLogger::ERed, + _L("CTestExecution::CompleteTestExecution: ModuleContainer NULL") ) ); + } + + iTestExeMessage.Complete ( completionCode ); + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: CompleteTestExecution + + Description: Completes test execution + + Parameters: const TInt aCompletionCode: in: completion code + TFullTestResult&: in: test case result + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CTestExecution::CompleteTestExecution( const TInt aCompletionCode ) + { + + TInt completionCode = aCompletionCode; + + TFullTestResultPckg fullResultPckg( iFullResult ); + TRAPD( res, iTestExeMessage.WriteL( 0, fullResultPckg ) ); + if ( res != KErrNone ) + { + completionCode = res; + } + + iTestExeMessage.Complete ( completionCode ); + + // @js Now it returns completionCode, used to return res + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: UnsetStateEvents + + Description: Unsets all state events. Must be done if testcase is exited + abnormally (i.e. aborted by the user). + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CTestExecution::UnsetStateEvents() + { + + + // Unset all state events that are set currently + TInt count = iStateEvents.Count(); + TEventIf event; + for( TInt i = 0; i < count; i++ ) + { + TPtrC name = *(iStateEvents[i]); + event.Set( TEventIf::EUnsetEvent, name, TEventIf::EState ); + + // Construct message + TEventIfPckg eventPckg( event ); + + // Write message to client space + TRAPD( res, iNotifyEventMessage.WriteL( 0, eventPckg ) ); + + // Complete with WriteL result + iEventNotifyAvailable = EFalse; + iNotifyEventMessage.Complete( res ); + if( res != KErrNone ) + { + __TRACE( KError,( _L( "CTestExecution::UnsetStateEvents: WriteL failed" ) )); + break; + } + } + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: TestThreadRequestComplete + + Description: Complete test thread request. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CTestExecution::TestThreadRequestComplete( TRequestStatus* aStatus, + TInt aCode) + { + + if( iThreadState != EOnGoing ) + { + __TRACE( KError, + ( _L( "CTestExecution::TestThreadRequestComplete: test thread killed" ) )); + return; + } + + if( iTestThreadOpen == EFalse ) + { + if( iTestThread.Open( iTestThreadId ) != KErrNone ) + { + __TRACE( KError, + ( _L( "CTestExecution::TestThreadRequestComplete: test thread cannot be opened" ) )); + return; + } + iTestThreadOpen = ETrue; + } + if( iTestThread.ExitType() != EExitPending ) + { + // test thread has died + __TRACE( KError, + ( _L( "CTestExecution::TestThreadRequestComplete: test thread has died" ) )); + return; + } + + iTestThread.RequestComplete( aStatus, aCode ); + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: CancelTestExecution + + Description: Cancels test(s) execution in special cases e.g. timeout, + exit etc. + + Parameters: None + + Return Values: TInt: Symbian error code. + + Errors/Exceptions: None + + Status: Approved + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::CancelTestExecution() + { + TInt ret( KErrNone ); + ret = CancelTestRequest(); + + return ret; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: KillTestinterferenceThread + + Description: Make sure that any of the test interference thread's won't + stay to run if test case is crashed of test interference + object is not deleted. + + Parameters: None + + Return Values: TInt: Symbian OS error code. + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::KillTestinterferenceThread() + { + for( TInt i = 0; i < iSTIFTestInterferenceArray.Count(); i++ ) + { + RDebug::Print( + _L( "Test interference's thread[%x] killed by STIF" ), (TInt)iSTIFTestInterferenceArray[i].Id() ); + __TRACE( KInit, + ( _L( "Test interference's thread[%x] killed by STIF" ), (TInt)iSTIFTestInterferenceArray[i].Id() ) ); + iSTIFTestInterferenceArray[i].Kill( KErrCancel ); + //iSTIFTestInterferenceArray.Remove( i ); + } + + iSTIFTestInterferenceArray.Reset(); + iSTIFTestInterferenceArray.Close(); + + return KErrNone; + + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: DoNotifyCommand + + Description: Completes command message. + + Parameters: None. + + Return Values: Symbian OS error code. + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::DoNotifyCommand() + { + if(!iCommandNotifyAvailable) + { + __TRACE(KPrint, (_L("CTestExecution::DoNotifyCommand(): unable to complete notification"))) + return KErrNone; + } + + TInt ret = KErrNone; + + switch(iCommandDef->iCommand) + { + case EStopExecution: + { + //Unpack received parameters + TStopExecutionCommandParams par; + TStopExecutionCommandParamsPckg parPack(par); + parPack.Copy(iCommandDef->iParamsPckg); + + //Set test case handle + par.iTestCaseHandle = iNotifyCommandMessage.Int3(); + + __TRACE(KPrint, (_L("CTestExecution::DoNotifyCommand(): command [%d] type [%d] code [%d] test handle [%d]"), TInt(iCommandDef->iCommand), TInt(par.iType), TInt(par.iCode), par.iTestCaseHandle)); + iCommandDef->iParamsPckg.Copy(parPack); + break; + } + case ESendTestModuleVersion: + { + TSendTestModuleVesionCommandParams par; + TSendTestModuleVesionCommandParamsPckg parPack(par); + parPack.Copy(iCommandDef->iParamsPckg); + + __TRACE(KPrint, (_L("CTestExecution::DoNotifyCommand(): command ESendTestModuleVersion"))); + break; + } + default: + __TRACE(KError, (_L("CTestExecution::DoNotifyCommand(): Unknown command [%d]"), TInt(iCommandDef->iCommand))); + return KErrNotFound; + } + // Construct message + TPckg commandPckg(iCommandDef->iCommand); + + // Start first phase of the writing message to client space + TRAP(ret, iNotifyCommandMessage.WriteL(0, commandPckg)); + if(ret != KErrNone) + { + __TRACE(KError, (_L( "CTestExecution::DoNotifyCommand(): WriteL failed (0)"))); + } + + TRAP(ret, iNotifyCommandMessage.WriteL(1, iCommandDef->iParamsPckg)); + if(ret != KErrNone) + { + __TRACE(KError, (_L( "CTestExecution::DoNotifyCommand(): WriteL failed (1)"))); + } + + // Complete request with WriteL result + iCommandNotifyAvailable = EFalse; + iNotifyCommandMessage.Complete(ret); + + return KErrNone; + } + +/* +------------------------------------------------------------------------------- + + Class: CTestExecution + + Method: KillTestMeasurement + + Description: Make sure that any of the test measurement operations won't + stay to run if test case is crashed or test measurement object + is not stopped by user. + + Parameters: None + + Return Values: TInt: Symbian OS error code. + + Errors/Exceptions: None + + Status: Approved + +------------------------------------------------------------------------------- +*/ +TInt CTestExecution::KillTestMeasurement() + { + for( TInt i = 0; i < iMeasurementHandlingArray.Count(); i++ ) + { + iMeasurementHandlingArray[i]->iMeasurementModulePtr->Stop(); + } + + iMeasurementHandlingArray.ResetAndDestroy(); + iMeasurementHandlingArray.Close(); + + return KErrNone; + + } + +/* +------------------------------------------------------------------------------- + + DESCRIPTION + + This module contains implementation of CPrintHandler class member functions. + CPrintHandler listens print notifications from test thread. + +------------------------------------------------------------------------------- +*/ + +// ================= MEMBER FUNCTIONS ========================================= + + +/* +------------------------------------------------------------------------------- + + Class: CPrintHandler + + Method: NewL + + Description: Constructs a new CPrintHandler object. + + Parameters: CTestExecution& aExecution: in: "Parent" + + Return Values: CPrintHandler*: New undertaker + + Errors/Exceptions: Leaves if memory allocation or ConstructL leaves. + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +CPrintHandler* CPrintHandler::NewL( CTestExecution& aExecution ) + { + + CPrintHandler* self = new( ELeave ) CPrintHandler( aExecution ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + + } + +/* +------------------------------------------------------------------------------- + + Class: CPrintHandler + + Method: ConstructL + + Description: Second level constructor. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CPrintHandler::ConstructL() + { + + } + +/* +------------------------------------------------------------------------------- + + Class: CPrintHandler + + Method: CPrintHandler + + Description: Constructor + + Parameters: CTestModuleContainer& aExecution :in: "Parent" + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +CPrintHandler::CPrintHandler( CTestExecution& aExecution ) : + CActive( CActive::EPriorityStandard ), + iExecution( aExecution ) + { + + CActiveScheduler::Add ( this ); + + } + +/* +------------------------------------------------------------------------------- + + Class: CPrintHandler + + Method: ~CPrintHandler + + Description: Destructor. + Cancels active request. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +CPrintHandler::~CPrintHandler() + { + + Cancel(); + + } + + + + +/* +------------------------------------------------------------------------------- + + Class: CPrintHandler + + Method: StartL + + Description: Starts to monitor thread. + + Parameters: None + + Return Values: TInt Always KErrNone + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CPrintHandler::StartL() + { + + __TRACE( KPrint, ( _L( "CPrintHandler::StartL" ) ) ); + + if( IsActive() ) + { + CTestServer::PanicServer( EAlreadyActive ); + } + + iStatus = KRequestPending; + SetActive(); + + // Signal test thread + iExecution.iPrintSem.Signal(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CPrintHandler + + Method: RunL + + Description: Handles thread death. + Function does: + 1 ) Stops monitoring thread + 1 ) Marks thread death + 2 ) Completes ongoing requests + 3 ) Cleans the memory + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CPrintHandler::RunL() + { + + __TRACE( KPrint, ( _L( "CPrintHandler::RunL [%d]" ), iStatus.Int() ) ); + + iExecution.DoNotifyPrint(); + + // enable print request + //@speiExecution.iPrintHandler->StartL(); + StartL(); + } + + +/* +------------------------------------------------------------------------------- + + Class: CPrintHandler + + Method: DoCancel + + Description: Stops print notification listening. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ + +void CPrintHandler::DoCancel() + { + + __TRACE( KPrint, ( _L( "CPrintHandler::DoCancel" ) ) ); + + iExecution.iPrintMutex.Wait(); // Take mutex and check test case print + // operation. If pending take print semaphore + // and complete + if( iStatus == KRequestPending ) + { + // Signal test thread + // @remove iExecution.iPrintSem.Wait(); + + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrCancel ); + } + + iExecution.iPrintMutex.Signal(); + } + +/* +------------------------------------------------------------------------------- + + Class: CPrintHandler + + Method: RunError + + Description: Handle errors. RunL function does not leave, so one should + never come here. + + Print trace and let framework handle error( i.e to do Panic ) + + Parameters: TInt aError: :in: Error code + + Return Values: TInt Error code + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CPrintHandler::RunError( TInt aError ) + { + + __TRACE( KError,( _L( "CPrintHandler::RunError" ) ) ); + + return aError; + + } + +/* +------------------------------------------------------------------------------- + + DESCRIPTION + + This module contains implementation of CEventHandler class member functions. + CEventHandler listens print notifications from test thread. + +------------------------------------------------------------------------------- +*/ + +// ================= MEMBER FUNCTIONS ========================================= + + +/* +------------------------------------------------------------------------------- + + Class: CEventHandler + + Method: NewL + + Description: Constructs a new CEventHandler object. + + Parameters: CTestExecution& aExecution: in: "Parent" + + Return Values: CEventHandler*: New undertaker + + Errors/Exceptions: Leaves if memory allocation or ConstructL leaves. + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +CEventHandler* CEventHandler::NewL( CTestExecution& aExecution ) + { + + CEventHandler* self = new( ELeave ) CEventHandler( aExecution ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + + } + +/* +------------------------------------------------------------------------------- + + Class: CEventHandler + + Method: ConstructL + + Description: Second level constructor. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CEventHandler::ConstructL() + { + + } + +/* +------------------------------------------------------------------------------- + + Class: CEventHandler + + Method: CEventHandler + + Description: Constructor + + Parameters: CTestModuleContainer& aExecution :in: "Parent" + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +CEventHandler::CEventHandler( CTestExecution& aExecution ) : + CActive( CActive::EPriorityStandard ), + iExecution( aExecution ) + { + + CActiveScheduler::Add ( this ); + + } + +/* +------------------------------------------------------------------------------- + + Class: CEventHandler + + Method: ~CEventHandler + + Description: Destructor. + Cancels active request. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +CEventHandler::~CEventHandler() + { + + Cancel(); + + } + + + + +/* +------------------------------------------------------------------------------- + + Class: CEventHandler + + Method: StartL + + Description: Starts to monitor thread. + + Parameters: None + + Return Values: TInt Always KErrNone + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CEventHandler::StartL() + { + + __TRACE( KPrint, ( _L( "CEventHandler::StartL" ) ) ); + + if( IsActive() ) + { + CTestServer::PanicServer( EAlreadyActive ); + } + + iStatus = KRequestPending; + SetActive(); + + // Signal test thread + iExecution.iEventSem.Signal(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CEventHandler + + Method: RunL + + Description: Handles thread death. + Function does: + 1 ) Stops monitoring thread + 1 ) Marks thread death + 2 ) Completes ongoing requests + 3 ) Cleans the memory + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CEventHandler::RunL() + { + + __TRACE( KPrint, ( _L( "CEventHandler::RunL [%d]" ), iStatus.Int() ) ); + + switch( iExecution.EventDef().iType ) + { + case TEventDef::EEventCmd: + iExecution.DoNotifyEvent(); + break; + case TEventDef::EEventCmdCancel: + iExecution.CancelEvent(); + break; + default: + CTestServer::PanicServer( EUnknownEventCmd ); + break; + } + + } + + +/* +------------------------------------------------------------------------------- + + Class: CEventHandler + + Method: DoCancel + + Description: Stops print notification listening. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ + +void CEventHandler::DoCancel() + { + + __TRACE( KPrint, ( _L( "CEventHandler::DoCancel" ) ) ); + + iExecution.iEventMutex.Wait(); // Take mutex and check test case event + // operation. If pending take event + // semaphore and complete + if( iStatus == KRequestPending ) + { + // Signal test thread + // @remove iExecution.iEventSem.Wait(); + + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrCancel ); + + } + + iExecution.iEventMutex.Signal(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CEventHandler + + Method: RunError + + Description: Handle errors. RunL function does not leave, so one should + never come here. + + Print trace and let framework handle error( i.e to do Panic ) + + Parameters: TInt aError: :in: Error code + + Return Values: TInt Error code + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CEventHandler::RunError( TInt aError ) + { + + __TRACE( KError,( _L( "CEventHandler::RunError" ) ) ); + + return aError; + + } + +/* +------------------------------------------------------------------------------- + + DESCRIPTION + + This module contains implementation of CSndHandler class member functions. + CSndHandler listens print notifications from test thread. + +------------------------------------------------------------------------------- +*/ + +// ================= MEMBER FUNCTIONS ========================================= + + +/* +------------------------------------------------------------------------------- + + Class: CSndHandler + + Method: NewL + + Description: Constructs a new CSndHandler object. + + Parameters: CTestExecution& aExecution: in: "Parent" + + Return Values: CSndHandler*: New undertaker + + Errors/Exceptions: Leaves if memory allocation or ConstructL leaves. + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +CSndHandler* CSndHandler::NewL( CTestExecution& aExecution ) + { + + CSndHandler* self = new( ELeave ) CSndHandler( aExecution ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + + } + +/* +------------------------------------------------------------------------------- + + Class: CSndHandler + + Method: ConstructL + + Description: Second level constructor. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CSndHandler::ConstructL() + { + + } + +/* +------------------------------------------------------------------------------- + + Class: CSndHandler + + Method: CSndHandler + + Description: Constructor + + Parameters: CTestModuleContainer& aExecution :in: "Parent" + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +CSndHandler::CSndHandler( CTestExecution& aExecution ) : + CActive( CActive::EPriorityStandard ), + iExecution( aExecution ) + { + + CActiveScheduler::Add ( this ); + + } + +/* +------------------------------------------------------------------------------- + + Class: CSndHandler + + Method: ~CSndHandler + + Description: Destructor. + Cancels active request. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +CSndHandler::~CSndHandler() + { + + Cancel(); + + } + + + + +/* +------------------------------------------------------------------------------- + + Class: CSndHandler + + Method: StartL + + Description: Starts to monitor thread. + + Parameters: None + + Return Values: TInt Always KErrNone + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CSndHandler::StartL() + { + + __TRACE( KPrint, ( _L( "CSndHandler::StartL" ) ) ); + + if( IsActive() ) + { + CTestServer::PanicServer( EAlreadyActive ); + } + + iStatus = KRequestPending; + SetActive(); + + // Signal test thread + iExecution.iSndSem.Signal(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CSndHandler + + Method: RunL + + Description: Handles thread death. + Function does: + 1 ) Stops monitoring thread + 1 ) Marks thread death + 2 ) Completes ongoing requests + 3 ) Cleans the memory + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CSndHandler::RunL() + { + + __TRACE( KPrint, ( _L( "CSndHandler::RunL [%d]" ), iStatus.Int() ) ); + + iExecution.DoRemoteSend(); + + } + + +/* +------------------------------------------------------------------------------- + + Class: CSndHandler + + Method: DoCancel + + Description: Stops print notification listening. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ + +void CSndHandler::DoCancel() + { + + __TRACE( KPrint, ( _L( "CSndHandler::DoCancel" ) ) ); + + iExecution.iSndMutex.Wait(); // Take mutex and check test case send + // operation. If pending take send + // semaphore and complete + if( iStatus == KRequestPending ) + { + // Signal test thread + // @remove iExecution.iSndSem.Wait(); + + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrCancel ); + + } + + iExecution.iSndMutex.Signal(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CSndHandler + + Method: RunError + + Description: Handle errors. RunL function does not leave, so one should + never come here. + + Print trace and let framework handle error( i.e to do Panic ) + + Parameters: TInt aError: :in: Error code + + Return Values: TInt Error code + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CSndHandler::RunError( TInt aError ) + { + + __TRACE( KError,( _L( "CSndHandler::RunError" ) ) ); + + return aError; + + } + +/* +------------------------------------------------------------------------------- + + DESCRIPTION + + This module contains implementation of CSndHandler class member functions. + CRcvHandler listens print notifications from test thread. + +------------------------------------------------------------------------------- +*/ + +// ================= MEMBER FUNCTIONS ========================================= + + +/* +------------------------------------------------------------------------------- + + Class: CRcvHandler + + Method: NewL + + Description: Constructs a new CRcvHandler object. + + Parameters: CTestExecution& aExecution: in: "Parent" + + Return Values: CRcvHandler*: New undertaker + + Errors/Exceptions: Leaves if memory allocation or ConstructL leaves. + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +CRcvHandler* CRcvHandler::NewL( CTestExecution& aExecution ) + { + + CRcvHandler* self = new( ELeave ) CRcvHandler( aExecution ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + + } + +/* +------------------------------------------------------------------------------- + + Class: CRcvHandler + + Method: ConstructL + + Description: Second level constructor. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CRcvHandler::ConstructL() + { + + } + +/* +------------------------------------------------------------------------------- + + Class: CRcvHandler + + Method: CRcvHandler + + Description: Constructor + + Parameters: CTestModuleContainer& aExecution :in: "Parent" + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +CRcvHandler::CRcvHandler( CTestExecution& aExecution ) : + CActive( CActive::EPriorityStandard ), + iExecution( aExecution ) + { + + CActiveScheduler::Add ( this ); + + } + +/* +------------------------------------------------------------------------------- + + Class: CRcvHandler + + Method: ~CRcvHandler + + Description: Destructor. + Cancels active request. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +CRcvHandler::~CRcvHandler() + { + + Cancel(); + + } + + + + +/* +------------------------------------------------------------------------------- + + Class: CRcvHandler + + Method: StartL + + Description: Starts to monitor thread. + + Parameters: None + + Return Values: TInt Always KErrNone + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CRcvHandler::StartL() + { + + __TRACE( KPrint, ( _L( "CRcvHandler::StartL" ) ) ); + + if( IsActive() ) + { + CTestServer::PanicServer( EAlreadyActive ); + } + iStatus = KRequestPending; + SetActive(); + + // Signal test thread + iExecution.iRcvSem.Signal(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CRcvHandler + + Method: RunL + + Description: Handles thread death. + Function does: + 1 ) Stops monitoring thread + 1 ) Marks thread death + 2 ) Completes ongoing requests + 3 ) Cleans the memory + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CRcvHandler::RunL() + { + + __TRACE( KPrint, ( _L( "CRcvHandler::RunL [%d]" ), iStatus.Int() ) ); + + iExecution.DoRemoteReceive(); + + } + + +/* +------------------------------------------------------------------------------- + + Class: CRcvHandler + + Method: DoCancel + + Description: Stops print notification listening. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ + +void CRcvHandler::DoCancel() + { + + __TRACE( KPrint, ( _L( "CRcvHandler::DoCancel" ) ) ); + + iExecution.iRcvMutex.Wait(); // Take mutex and check test case receive + // operation. If pending take reveive + // semaphore and complete + if( iStatus == KRequestPending ) + { + // Signal test thread + // @remove iExecution.iRcvSem.Wait(); + + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrCancel ); + } + + iExecution.iRcvMutex.Signal(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CRcvHandler + + Method: RunError + + Description: Handle errors. RunL function does not leave, so one should + never come here. + + Print trace and let framework handle error( i.e to do Panic ) + + Parameters: TInt aError: :in: Error code + + Return Values: TInt Error code + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CRcvHandler::RunError( TInt aError ) + { + + __TRACE( KError,( _L( "CRcvHandler::RunError" ) ) ); + + return aError; + + } + + +/* +------------------------------------------------------------------------------- + + DESCRIPTION + + This module contains implementation of CTestInterferenceHandler class + member functions. CTestInterferenceHandler listens print notifications from + test thread. + +------------------------------------------------------------------------------- +*/ + +// ================= MEMBER FUNCTIONS ========================================= + + +/* +------------------------------------------------------------------------------- + + Class: CInterferenceHandler + + Method: NewL + + Description: Constructs a new CInterferenceHandler object. + + Parameters: CTestExecution& aExecution: in: "Parent" + + Return Values: CInterferenceHandler*: New undertaker + + Errors/Exceptions: Leaves if memory allocation or ConstructL leaves. + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +CInterferenceHandler* CInterferenceHandler::NewL( + CTestExecution& aExecution ) + { + CInterferenceHandler* self = + new( ELeave ) CInterferenceHandler( aExecution ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + + } + +/* +------------------------------------------------------------------------------- + + Class: CInterferenceHandler + + Method: ConstructL + + Description: Second level constructor. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CInterferenceHandler::ConstructL() + { + + } + +/* +------------------------------------------------------------------------------- + + Class: CInterferenceHandler + + Method: CInterferenceHandler + + Description: Constructor + + Parameters: CTestModuleContainer& aExecution :in: "Parent" + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +CInterferenceHandler::CInterferenceHandler( CTestExecution& aExecution ) : + CActive( CActive::EPriorityStandard ), + iExecution( aExecution ) + { + CActiveScheduler::Add ( this ); + + } + +/* +------------------------------------------------------------------------------- + + Class: CInterferenceHandler + + Method: ~CInterferenceHandler + + Description: Destructor. + Cancels active request. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +CInterferenceHandler::~CInterferenceHandler() + { + Cancel(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CInterferenceHandler + + Method: StartL + + Description: Starts to monitor thread. + + Parameters: None + + Return Values: TInt: Always KErrNone + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CInterferenceHandler::StartL() + { + __TRACE( KPrint, ( _L( "CInterferenceHandler::StartL" ) ) ); + + if( IsActive() ) + { + CTestServer::PanicServer( EAlreadyActive ); + } + + iStatus = KRequestPending; + SetActive(); + + // Signal test thread, Notify test thread that operation is done. + iExecution.iInterferenceSem.Signal(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CInterferenceHandler + + Method: RunL + + Description: Handles thread death. + Function does: + 1 ) Stops monitoring thread + 1 ) Marks thread death + 2 ) Completes ongoing requests + 3 ) Cleans the memory + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CInterferenceHandler::RunL() + { + __TRACE( KPrint, ( _L( "CInterferenceHandler::RunL [%d]" ), iStatus.Int() ) ); + + iExecution.DoNotifyInterference(); + + StartL(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CInterferenceHandler + + Method: DoCancel + + Description: Stops interference notification listening. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CInterferenceHandler::DoCancel() + { + __TRACE( KPrint, ( _L( "CInterferenceHandler::DoCancel" ) ) ); + + iExecution.iInterferenceMutex.Wait(); // Take mutex and check test + // interference operation. If + // pending take interference + // semaphore and complete + if( iStatus == KRequestPending ) + { + + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrCancel ); + } + + iExecution.iInterferenceMutex.Signal(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CInterferenceHandler + + Method: RunError + + Description: Handle errors. RunL function does not leave, so one should + never come here. + + Print trace and let framework handle error( i.e to do Panic ) + + Parameters: TInt aError: in: Error code + + Return Values: TInt: Error code + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CInterferenceHandler::RunError( TInt aError ) + { + __TRACE( KError,( _L( "CTestInterferenceHandler::RunError" ) ) ); + + return aError; + + } + +/* +------------------------------------------------------------------------------- + + DESCRIPTION + + This module contains implementation of CMeasurementHandler class + member functions. CMeasurementHandler handles test measurement operations + that comes from test execution side to TestServer side. + +------------------------------------------------------------------------------- +*/ + +// ================= MEMBER FUNCTIONS ========================================= + + +/* +------------------------------------------------------------------------------- + + Class: CMeasurementHandler + + Method: NewL + + Description: Constructs a new CMeasurementHandler object. + + Parameters: CTestExecution& aExecution: in: Pointer to test execution side. + + Return Values: CMeasurementHandler*: New undertaker + + Errors/Exceptions: Leaves if memory allocation or ConstructL leaves. + + Status: Approved + +------------------------------------------------------------------------------- +*/ +CMeasurementHandler* CMeasurementHandler::NewL( CTestExecution& aExecution ) + { + CMeasurementHandler* self = + new( ELeave ) CMeasurementHandler( aExecution ); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + return self; + + } + +/* +------------------------------------------------------------------------------- + + Class: CMeasurementHandler + + Method: ConstructL + + Description: Second level constructor. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Approved + +------------------------------------------------------------------------------- +*/ +void CMeasurementHandler::ConstructL() + { + + } + +/* +------------------------------------------------------------------------------- + + Class: CMeasurementHandler + + Method: CMeasurementHandler + + Description: Constructor + + Parameters: CTestModuleContainer& aExecution :in: Pointer to test + execution side. + + Return Values: None + + Errors/Exceptions: None + + Status: Approved + +------------------------------------------------------------------------------- +*/ +CMeasurementHandler::CMeasurementHandler( CTestExecution& aExecution ) : + CActive( CActive::EPriorityStandard ), + iExecution( aExecution ) + { + CActiveScheduler::Add ( this ); + + } + +/* +------------------------------------------------------------------------------- + + Class: CMeasurementHandler + + Method: ~CMeasurementHandler + + Description: Destructor. + Cancels active request. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Approved + +------------------------------------------------------------------------------- +*/ +CMeasurementHandler::~CMeasurementHandler() + { + Cancel(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CMeasurementHandler + + Method: StartL + + Description: Starts to monitor thread. + + Parameters: None + + Return Values: TInt: Always KErrNone + + Errors/Exceptions: None + + Status: Approved + +------------------------------------------------------------------------------- +*/ +void CMeasurementHandler::StartL() + { + __TRACE( KPrint, ( _L( "CMeasurementHandler::StartL" ) ) ); + + if( IsActive() ) + { + CTestServer::PanicServer( EAlreadyActive ); + } + + iStatus = KRequestPending; + SetActive(); + + // Do not Signal here because synchronous operations will be executed and we + // don't want to signal at first time: iExecution.iMeasurementSem.Signal(); + // Signal() operation will be handled in RunL in this case. + + } + +/* +------------------------------------------------------------------------------- + + Class: CMeasurementHandler + + Method: RunL + + Description: Derived from CActive, handles test measurement execution. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Approved + +------------------------------------------------------------------------------- +*/ +void CMeasurementHandler::RunL() + { + __TRACE( KPrint, ( _L( "CMeasurementHandler::RunL [%d]" ), iStatus.Int() ) ); + + TInt ret( 0 ); + ret = iExecution.DoNotifyMeasurement(); + + // ret value is copied to struct so it can be handled later. + iExecution.iTestMeasurement.iMeasurementStruct.iOperationResult = ret; + + // SetActive again + StartL(); + + // TestServer side operations are done, Signal that operation is done. + iExecution.iMeasurementSem.Signal(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CMeasurementHandler + + Method: DoCancel + + Description: Stops measurement notification listening. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Approved + +------------------------------------------------------------------------------- +*/ +void CMeasurementHandler::DoCancel() + { + __TRACE( KPrint, ( _L( "CMeasurementHandler::DoCancel" ) ) ); + + iExecution.iMeasurementMutex.Wait(); // Take mutex and check test + // measurement operation. If + // pending take measurement + // semaphore and complete + if( iStatus == KRequestPending ) + { + + TRequestStatus* status = &iStatus; + User::RequestComplete( status, KErrCancel ); + } + + iExecution.iMeasurementMutex.Signal(); + + } + +/* +------------------------------------------------------------------------------- + + Class: CMeasurementHandler + + Method: RunError + + Description: Handle errors. RunL function does not leave, so one should + never come here. + + Print trace and let framework handle error( i.e to do Panic ) + + Parameters: TInt aError: in: Error code + + Return Values: TInt: Error code + + Errors/Exceptions: None + + Status: Approved + +------------------------------------------------------------------------------- +*/ +TInt CMeasurementHandler::RunError( TInt aError ) + { + __TRACE( KError,( + _L( "CMeasurementHandler::RunError with error: %d" ), aError ) ); + + return aError; + + } + +/* +------------------------------------------------------------------------------- + + DESCRIPTION + + This module contains implementation of CCommandHandler class member functions. + CCommandHandler listens command notifications from test thread. + +------------------------------------------------------------------------------- +*/ + +// ================= MEMBER FUNCTIONS ========================================= + + +/* +------------------------------------------------------------------------------- + + Class: CCommandHandler + + Method: NewL + + Description: Constructs a new CCommandHandler object. + + Parameters: CTestExecution& aExecution: in: "Parent" + + Return Values: CCommandHandler*: New object + + Errors/Exceptions: Leaves if memory allocation or ConstructL leaves. + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +CCommandHandler* CCommandHandler::NewL(CTestExecution& aExecution) + { + CCommandHandler* self = new (ELeave) CCommandHandler(aExecution); + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +/* +------------------------------------------------------------------------------- + + Class: CCommandHandler + + Method: ConstructL + + Description: Second level constructor. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CCommandHandler::ConstructL() + { + } + +/* +------------------------------------------------------------------------------- + + Class: CCommandHandler + + Method: CCommandHandler + + Description: Constructor + + Parameters: CTestExecution& aExecution :in: "Parent" + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +CCommandHandler::CCommandHandler(CTestExecution& aExecution): + CActive(CActive::EPriorityStandard), + iExecution(aExecution) + { + CActiveScheduler::Add (this); + } + +/* +------------------------------------------------------------------------------- + + Class: CCommandHandler + + Method: ~CCommandHandler + + Description: Destructor. + Cancels active request. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +CCommandHandler::~CCommandHandler() + { + Cancel(); + } + +/* +------------------------------------------------------------------------------- + + Class: CCommandHandler + + Method: StartL + + Description: Starts to monitor thread. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CCommandHandler::StartL() + { + __TRACE(KPrint, (_L( "CCommandHandler::StartL" ))); + + if(IsActive()) + { + CTestServer::PanicServer(EAlreadyActive); + } + iStatus = KRequestPending; + SetActive(); + + // Signal test thread + iExecution.iCommandSem.Signal(); + } + +/* +------------------------------------------------------------------------------- + + Class: CCommandHandler + + Method: RunL + + Description: + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +void CCommandHandler::RunL() + { + __TRACE(KPrint, (_L( "CCommandHandler::RunL [%d]"), iStatus.Int())); + + iExecution.DoNotifyCommand(); +// StartL(); + } + + +/* +------------------------------------------------------------------------------- + + Class: CCommandHandler + + Method: DoCancel + + Description: Stops command notification listening. + + Parameters: None + + Return Values: None + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ + +void CCommandHandler::DoCancel() + { + __TRACE(KPrint, (_L("CCommandHandler::DoCancel"))); + + iExecution.iCommandMutex.Wait(); // Take mutex and check test case receive + // operation. If pending take reveive + // semaphore and complete + if(iStatus == KRequestPending) + { + TRequestStatus* status = &iStatus; + User::RequestComplete(status, KErrCancel); + } + + iExecution.iCommandMutex.Signal(); + } + +/* +------------------------------------------------------------------------------- + + Class: CCommandHandler + + Method: RunError + + Description: Handle errors. RunL function does not leave, so one should + never come here. + + Print trace and let framework handle error( i.e to do Panic ) + + Parameters: TInt aError: :in: Error code + + Return Values: TInt Error code + + Errors/Exceptions: None + + Status: Proposal + +------------------------------------------------------------------------------- +*/ +TInt CCommandHandler::RunError(TInt aError) + { + __TRACE(KError, (_L("CCommandHandler::RunError"))); + + return aError; + } + +/* +------------------------------------------------------------------------------- + + Class: CCommandDef + + Method: CCommandDef + + Description: private constructor + + Return Values: void + +------------------------------------------------------------------------------- +*/ + +CCommandDef::CCommandDef() + { + } + +/* +------------------------------------------------------------------------------- + + Class: CCommandDef + + Method: ConstructL + + Description: Second phase constructor + + Return Values: void + +------------------------------------------------------------------------------- +*/ + +void CCommandDef::ConstructL() + { + + } + +/* +------------------------------------------------------------------------------- + + Class: CCommandDef + + Method: NewL + + Description: First phase constructor + + Return Values: void + +------------------------------------------------------------------------------- +*/ + +CCommandDef* CCommandDef::NewL() + { + CCommandDef* self = new(ELeave) CCommandDef; + CleanupStack::PushL(self); + self->ConstructL(); + CleanupStack::Pop(self); + return self; + } + +/* +------------------------------------------------------------------------------- + + Class: CCommandDef + + Method: ~CCommandDef + + Description: destructor + +------------------------------------------------------------------------------- +*/ + +CCommandDef::~CCommandDef() + { + + } + +// End of File