--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/stif/TestServer/src/Testexecution.cpp Tue Feb 02 01:57:15 2010 +0200
@@ -0,0 +1,4754 @@
+/*
+* 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 <e32std.h>
+#include <e32svr.h>
+#include "TestEngineClient.h"
+#include "StifTFwIfProt.h"
+#include <stifinternal/TestServerClient.h>
+#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;
+
+ 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" ) ) );
+
+ // Store message to be completed when case is finished
+ iTestExeMessage = aMessage;
+
+ iFullResult.iStartTime.HomeTime();
+
+ // 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.
+ TInt 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<KStifMeasurementTypeLength> 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<TStifCommand> 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<TInt> 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: 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<TCommand> 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