--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/hti/HtiServicePlugins/HtiStifTfServicePlugin/src/HtiStifTfIf.cpp Wed Oct 13 16:17:58 2010 +0300
@@ -0,0 +1,2092 @@
+/*
+* 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: Implements the functions to control STIF Test Framework
+* through the STIF TF interface.
+*
+*/
+
+
+
+// INCLUDE FILES
+#include <badesca.h>
+#include <bautils.h>
+#include <charconv.h>
+#include <e32cons.h>
+#include <HtiLogging.h>
+#include "HtiStifTfIf.h"
+
+// EXTERNAL DATA STRUCTURES
+
+// EXTERNAL FUNCTION PROTOTYPES
+
+// CONSTANTS
+
+// MACROS
+
+// LOCAL CONSTANTS AND MACROS
+const static TUid KStifTfServiceUid = { 0x10210CC3 };
+
+enum TStifTfCommands
+ {
+ ECmdOpen = 0x01,
+ ECmdClose = 0x02,
+ ECmdLoadModule = 0x03,
+ ECmdUnloadModule = 0x04,
+ ECmdListCases = 0x05,
+ ECmdStartCase = 0x06,
+ ECmdCancelCase = 0x07,
+ ECmdPauseCase = 0x08,
+ ECmdResumeCase = 0x09,
+ ECmdAddCaseFile = 0x0A,
+ ECmdRemoveCaseFile = 0x0B,
+ ECmdCaseMsg = 0x0C,
+ ECmdSetDevId = 0x0D,
+ ECmdTestCompleted = 0x0E,
+ ECmdAtsMessage = 0x0F,
+ ECmdSetAttribute = 0x10
+ };
+
+_LIT8( KParameterDelimiter, "|" );
+
+// NOTE: Max length for error description is defined
+// in HtiDispatcherInterface.h (currently 118).
+_LIT8( KErrorStifTfNotOpen, "ERROR: STIF TF is not open" );
+_LIT8( KErrorOpen, "ERROR: Failed to open STIF TF" );
+_LIT8( KErrorAlreadyOpen, "ERROR: STIF TF is already open" );
+_LIT8( KErrorClose, "ERROR: Failed to close STIF TF" );
+_LIT8( KErrorUnknownCmd, "ERROR: Unknown STIF TF command" );
+_LIT8( KErrorNoCmd, "ERROR: No command given" );
+_LIT8( KErrorParameterMissing, "ERROR: Mandatory parameter missing" );
+_LIT8( KErrorParameterTooLong, "ERROR: Parameter too long" );
+_LIT8( KErrorTooManyParameters, "ERROR: Too many parameters" );
+_LIT8( KErrorNoMemory, "ERROR: Memory allocation failure" );
+_LIT8( KErrorLoadModule, "ERROR: Load Module failed" );
+_LIT8( KErrorUnloadModule, "ERROR: Unload Module failed" );
+_LIT8( KErrorInvalidCaseNumber, "ERROR: Invalid test case number parameter" );
+_LIT8( KErrorModuleNotLoaded, "ERROR: Given test module is not loaded" );
+_LIT8( KErrorGetTestCases, "ERROR: Failed to get test cases from module" );
+_LIT8( KErrorGetTestCaseInfos, "ERROR: Failed to get test case infos" );
+_LIT8( KErrorStartTestCase, "ERROR: Failed to start test case" );
+_LIT8( KErrorCancelTestCase, "ERROR: Failed to cancel test case" );
+_LIT8( KErrorPauseTestCase, "ERROR: Failed to pause test case" );
+_LIT8( KErrorResumeTestCase, "ERROR: Failed to resume test case" );
+_LIT8( KErrorInvalidDeviceId, "ERROR: Invalid device ID parameter" );
+_LIT8( KErrorAddCaseFile, "ERROR: Add Case File failed" );
+_LIT8( KErrorRemoveCaseFile, "ERROR: Remove Case File failed" );
+_LIT8( KErrorFileServer, "ERROR: Failed to connect to file server" );
+_LIT8( KErrorCaseFileNotFound, "ERROR: Given test case file was not found" );
+_LIT8( KErrorIniFileNotFound, "ERROR: Given ini-file was not found" );
+_LIT8( KErrorCaseMessage, "ERROR: Test case message sending failed" );
+_LIT8( KErrorCharConv, "ERROR: Character conversion failed" );
+_LIT8( KErrorInvalidAttributeId, "ERROR: Invalid attribute id parameter" );
+_LIT8( KErrorSetAttribute, "ERROR: Failed to set attribute" );
+_LIT8( KErrorUnknown, "ERROR: Unspecified error occured" );
+
+// MODULE DATA STRUCTURES
+
+// LOCAL FUNCTION PROTOTYPES
+
+// FORWARD DECLARATIONS
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::CHtiStifTfIf
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CHtiStifTfIf::CHtiStifTfIf():iIsBusy( EFalse ),
+ iMessage( NULL ),
+ iErrorCode( 0 ),
+ iStifTfOpen( EFalse ),
+ iDevId( KDefaultDevId ),
+ iConsole( NULL )
+ {
+ }
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::ConstructL( CHtiStifTfServicePlugin* aPlugin )
+ {
+ iCommandId = 0;
+ iParameters = new (ELeave) CDesC8ArrayFlat( 5 );
+ iPlugin = aPlugin;
+ }
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CHtiStifTfIf* CHtiStifTfIf::NewL( CHtiStifTfServicePlugin* aPlugin )
+ {
+ CHtiStifTfIf* self = new( ELeave ) CHtiStifTfIf;
+ CleanupStack::PushL( self );
+ self->ConstructL( aPlugin );
+ CleanupStack::Pop();
+ return self;
+ }
+
+
+// Destructor
+CHtiStifTfIf::~CHtiStifTfIf()
+ {
+ if ( iParameters )
+ {
+ iParameters->Reset();
+ }
+ delete iParameters;
+ iLoadedInfos.ResetAndDestroy();
+ iLoadedInfos.Close();
+ delete iMessage;
+ if ( iStifTfOpen ) Close();
+ iPlugin = NULL; // Not owned, so not deleted.
+ iConsole = NULL; // Not owned, so not deleted.
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::ProcessMessageL
+// Interpretes the message and calls appropriate command handling method.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::ProcessMessageL( const TDesC8& aMessage,
+ THtiMessagePriority /*aPriority*/)
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::ProcessMessageL" );
+ HTI_LOG_FORMAT( "Message length = %d", aMessage.Length() );
+
+ if ( iIsBusy )
+ {
+ HTI_LOG_TEXT( "Plugin is busy - leaving" );
+ User::Leave( KErrInUse );
+ }
+
+ iIsBusy = ETrue;
+
+ if ( aMessage.Length() < 1 )
+ {
+ User::LeaveIfError(
+ SendErrorResponseMsg( KErrArgument, KErrorNoCmd ) );
+ return;
+ }
+
+ iCommandId = aMessage[0];
+ HTI_LOG_FORMAT( "Command = %d", iCommandId );
+
+ TRAPD( err, ParseParametersL( aMessage ) );
+
+ if ( err == KErrNoMemory )
+ {
+ User::LeaveIfError( SendErrorResponseMsg( err, KErrorNoMemory ) );
+ return;
+ }
+
+ else if ( err )
+ {
+ User::LeaveIfError(
+ SendErrorResponseMsg( KErrGeneral, KErrorUnknown ) );
+ return;
+ }
+
+ // If STIF TF is not open, any other command than OPEN returns KErrNotReady
+ if ( !iStifTfOpen )
+ {
+ if ( iCommandId == ECmdOpen )
+ {
+ HandleOpenCmdL();
+ return;
+ }
+ else
+ {
+ User::LeaveIfError(
+ SendErrorResponseMsg( KErrNotReady, KErrorStifTfNotOpen ) );
+ return;
+ }
+ }
+
+
+ // Go through the rest of the commands
+ if ( iCommandId == ECmdLoadModule )
+ {
+ HandleLoadModuleCmdL();
+ }
+
+ else if ( iCommandId == ECmdUnloadModule )
+ {
+ HandleUnloadModuleCmdL();
+ }
+
+ else if ( iCommandId == ECmdListCases )
+ {
+ HandleListCasesCmdL();
+ }
+
+ else if ( iCommandId == ECmdStartCase )
+ {
+ HandleStartCaseCmdL();
+ }
+
+ else if ( iCommandId == ECmdCancelCase )
+ {
+ HandleCancelCaseCmdL();
+ }
+
+ else if ( iCommandId == ECmdPauseCase )
+ {
+ HandlePauseCaseCmdL();
+ }
+
+ else if ( iCommandId == ECmdResumeCase )
+ {
+ HandleResumeCaseCmdL();
+ }
+
+ else if ( iCommandId == ECmdAddCaseFile )
+ {
+ HandleAddCaseFileCmdL();
+ }
+
+ else if ( iCommandId == ECmdRemoveCaseFile )
+ {
+ HandleRemoveCaseFileCmdL();
+ }
+
+ else if ( iCommandId == ECmdCaseMsg )
+ {
+ HandleCaseMsgCmdL();
+ }
+
+ else if ( iCommandId == ECmdSetDevId )
+ {
+ HandleSetDevIdCmdL();
+ }
+
+ else if ( iCommandId == ECmdSetAttribute )
+ {
+ HandleSetAttributeCmdL();
+ }
+
+ else if ( iCommandId == ECmdClose )
+ {
+ HandleCloseCmdL();
+ }
+
+ else if ( iCommandId == ECmdOpen )
+ {
+ User::LeaveIfError(
+ SendErrorResponseMsg( KErrArgument, KErrorAlreadyOpen ) );
+ }
+
+ else
+ {
+ User::LeaveIfError(
+ SendErrorResponseMsg( KErrArgument, KErrorUnknownCmd ) );
+ }
+
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::ProcessMessageL" );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::HandleOpenCmdL
+// Handles opening of the STIF Test Framework.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::HandleOpenCmdL()
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::HandleOpenCmdL" );
+
+ TInt err = KErrNone;
+
+ // OPEN command has 1 optional parameter (test framework ini-file)
+ if ( iParameters->Count() == 0 )
+ {
+ err = Open();
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorOpen );
+ return;
+ }
+
+ iStifTfOpen = ETrue;
+ SendResponseMsg( _L8( "OK" ) );
+ }
+
+ else if ( iParameters->Count() == 1 )
+ {
+ TBuf<KMaxFileName> iniFilePath;
+ if ( (*iParameters)[0].Length() > iniFilePath.MaxLength() )
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorParameterTooLong );
+ return;
+ }
+
+ iniFilePath.Copy( (*iParameters)[0] );
+
+ RFs fsSession;
+ err = fsSession.Connect();
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorFileServer );
+ return;
+ }
+
+ if ( !( BaflUtils::FileExists( fsSession, iniFilePath ) ) )
+ {
+ SendErrorResponseMsg( KErrNotFound, KErrorIniFileNotFound );
+ fsSession.Close();
+ return;
+ }
+
+ fsSession.Close();
+
+ err = Open( iniFilePath );
+
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorOpen );
+ return;
+ }
+
+ // Load the test case infos of all currently loaded test
+ // modules (modules listed in the given ini-file).
+ TRAP( err, LoadTestCaseInfosL() );
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorGetTestCaseInfos );
+ return;
+ }
+
+ iStifTfOpen = ETrue;
+ SendResponseMsg( _L8( "OK" ) );
+ }
+
+ else
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorTooManyParameters );
+ }
+
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::HandleOpenCmdL" );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::HandleCloseCmdL
+// Closes the STIF Test Framework.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::HandleCloseCmdL()
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::HandleCloseCmdL" );
+
+ TInt err = KErrNone;
+
+ // CLOSE command has no parameters
+ if ( iParameters->Count() == 0 )
+ {
+ err = Close();
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorClose );
+ return;
+ }
+
+ iStifTfOpen = EFalse;
+ iLoadedInfos.ResetAndDestroy(); // empty the cache of test case infos
+ SendResponseMsg( _L8( "OK" ) );
+ }
+
+ else
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorTooManyParameters );
+ }
+
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::HandleCloseCmdL" );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::HandleLoadModuleCmdL
+// Loads a STIF TF test module (optionally with ini-file).
+// Also calls the LoadTestCaseInfosL helper method to load the test case info
+// objects from the test module.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::HandleLoadModuleCmdL()
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::HandleLoadModuleCmdL" );
+
+ TInt err = KErrNone;
+
+ TBuf<KMaxFileName> moduleName;
+ TBuf<KMaxFileName> iniFilePath;
+
+ // LOAD_MODULE command has 1 mandatory parameter (module name)
+ // and 1 optional parameter (ini-file path).
+ if ( iParameters->Count() == 0 )
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorParameterMissing );
+ return;
+ }
+
+ else if ( iParameters->Count() == 1 )
+ {
+ if ( (*iParameters)[0].Length() > moduleName.MaxLength() )
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorParameterTooLong );
+ return;
+ }
+ moduleName.Copy( (*iParameters)[0] );
+ err = AddTestModule( moduleName );
+ }
+
+ else if ( iParameters->Count() == 2 )
+ {
+ if ( (*iParameters)[0].Length() > moduleName.MaxLength() ||
+ (*iParameters)[1].Length() > iniFilePath.MaxLength() )
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorParameterTooLong );
+ return;
+ }
+
+ moduleName.Copy( (*iParameters)[0] );
+ iniFilePath.Copy( (*iParameters)[1] );
+
+ RFs fsSession;
+ err = fsSession.Connect();
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorFileServer );
+ return;
+ }
+
+ if ( !( BaflUtils::FileExists( fsSession, iniFilePath ) ) )
+ {
+ SendErrorResponseMsg( KErrNotFound, KErrorIniFileNotFound );
+ fsSession.Close();
+ return;
+ }
+
+ fsSession.Close();
+
+ err = AddTestModule( moduleName, iniFilePath );
+ }
+
+ else
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorTooManyParameters );
+ return;
+ }
+
+ if ( err )
+ {
+ HTI_LOG_FORMAT( "LoadModule: Error %d", err );
+ SendErrorResponseMsg( err, KErrorLoadModule );
+ }
+
+ else
+ {
+ TRAP( err, LoadTestCaseInfosL( moduleName ) );
+
+ if ( err )
+ {
+ HTI_LOG_FORMAT(
+ "LoadModule - Error from LoadTestCaseInfosL %d", err );
+ RemoveTestModule( moduleName );
+ SendErrorResponseMsg( err, KErrorGetTestCases );
+ return;
+ }
+
+ // Sends the name of the loaded module as a response.
+ SendResponseMsg( (*iParameters)[0] );
+ }
+
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::HandleLoadModuleCmdL" );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::HandleUnloadModuleCmdL
+// Unloads a STIF TF test module.
+// Also removes and deletes the corresponding CHtiTestModuleCaseInfos object
+// from iLoadedInfos pointer array.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::HandleUnloadModuleCmdL()
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::HandleUnloadModuleCmdL" );
+
+ TInt err = KErrNone;
+
+ TBuf<KMaxFileName> moduleName;
+
+ // UNLOAD_MODULE command has always 1 parameter (module name).
+ if ( iParameters->Count() == 0 )
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorParameterMissing );
+ return;
+ }
+
+ if ( iParameters->Count() == 1 )
+ {
+ if ( (*iParameters)[0].Length() > moduleName.MaxLength() )
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorParameterTooLong );
+ return;
+ }
+ moduleName.Copy( (*iParameters)[0] );
+ err = RemoveTestModule( moduleName );
+ }
+
+ else
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorTooManyParameters );
+ return;
+ }
+
+ if ( err )
+ {
+ HTI_LOG_FORMAT( "UnloadModule: Error %d", err );
+ SendErrorResponseMsg( err, KErrorUnloadModule );
+ }
+
+ else
+ {
+ // Remove the test case infos of the unloaded module.
+ TInt moduleIndex = IndexByModuleName( moduleName );
+ if ( moduleIndex != KErrNotFound )
+ {
+ CHtiTestModuleCaseInfos* module = iLoadedInfos[moduleIndex];
+ iLoadedInfos.Remove( moduleIndex );
+ delete module;
+ }
+
+ // Sends the name of the unloaded module as a response.
+ SendResponseMsg( (*iParameters)[0] );
+ }
+
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::HandleUnloadModuleCmdL" );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::HandleListCasesCmdL
+// Creates a list of titles of the test cases inside the given test module.
+// Output is a string of test case titles separated with the | character.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::HandleListCasesCmdL()
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::HandleListCasesCmdL" );
+
+ TInt err = KErrNone;
+
+ TBuf<KMaxFileName> moduleName;
+ TBuf8<128> buf8; // temporary buffer for case titles
+
+ CHtiTestModuleCaseInfos* module = NULL;
+ CTestInfo* caseInfo = NULL;
+
+ // LIST_CASES command has 1 optional parameter (module name).
+
+ // If no parameter given all cases of all currently loaded
+ // modules are listed.
+ if ( iParameters->Count() == 0 )
+ {
+ /*
+ // (Re)load case infos from all loaded modules
+ TRAP( err, LoadTestCaseInfosL() );
+
+ if ( err )
+ {
+ HTI_LOG_FORMAT(
+ "ListCases - Error from LoadTestCaseInfosL %d", err );
+ SendErrorResponseMsg( err, KErrorGetTestCaseInfos );
+ }
+ */
+ CBufFlat* caseListBuf = NULL;
+ TRAP( err, caseListBuf = CBufFlat::NewL( 128 ) );
+ if ( err )
+ {
+ SendErrorResponseMsg( KErrNoMemory, KErrorNoMemory );
+ return;
+ }
+
+ // Loop all loaded test modules
+ TInt pos = 0;
+ for ( TInt i = 0; i < iLoadedInfos.Count(); i++ )
+ {
+ module = NULL;
+ module = iLoadedInfos[i];
+ HTI_LOG_FORMAT( "Listing cases from module %S",
+ module->iModuleName );
+
+ // Loop all case infos in this module
+ for ( TInt j = 0; j < module->iTestInfos.Count(); j++ )
+ {
+ caseInfo = NULL;
+ caseInfo = module->iTestInfos[j];
+
+ if ( !( i == 0 && j == 0 ) )
+ {
+ buf8.Append( KParameterDelimiter );
+ }
+
+ buf8.Append( caseInfo->TestCaseTitle() );
+
+ TRAP( err, caseListBuf->ExpandL( pos, buf8.Length() ) );
+ if ( err )
+ {
+ SendErrorResponseMsg( KErrNoMemory, KErrorNoMemory );
+ delete caseListBuf;
+ return;
+ }
+ caseListBuf->Write( pos, buf8, buf8.Length() );
+ pos += buf8.Length();
+ buf8.Zero();
+ }
+ }
+
+ if ( caseListBuf->Size() > 0 )
+ {
+ TPtr8 ptr = caseListBuf->Ptr( 0 );
+ SendResponseMsg( ptr );
+ }
+
+ else
+ {
+ SendResponseMsg( buf8 );
+ }
+
+ delete caseListBuf;
+ }
+
+ else if ( iParameters->Count() == 1 )
+ {
+ if ( (*iParameters)[0].Length() > moduleName.MaxLength() )
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorParameterTooLong );
+ return;
+ }
+
+ moduleName.Copy( (*iParameters)[0] );
+ TInt moduleIndex = IndexByModuleName( moduleName );
+
+ if ( moduleIndex == KErrNotFound )
+ {
+ HTI_LOG_TEXT( "Module is not loaded" );
+ SendErrorResponseMsg( KErrNotFound, KErrorModuleNotLoaded );
+ return;
+ }
+ /*
+ // (Re)load the case infos of given module
+ TRAP( err, LoadTestCaseInfosL( moduleName ) );
+ if ( err )
+ {
+ HTI_LOG_FORMAT(
+ "ListCases - Error from LoadTestCaseInfosL %d", err );
+ SendErrorResponseMsg( err, KErrorGetTestCaseInfos );
+ return;
+ }
+ */
+ module = iLoadedInfos[moduleIndex];
+ CBufFlat* caseListBuf = NULL;
+
+ TRAP( err, caseListBuf = CBufFlat::NewL( 128 ) );
+
+ if ( err )
+ {
+ SendErrorResponseMsg( KErrNoMemory, KErrorNoMemory );
+ return;
+ }
+
+ TInt pos = 0;
+ for ( TInt i = 0; i < module->iTestInfos.Count(); i++ )
+ {
+ caseInfo = NULL;
+ caseInfo = module->iTestInfos[i];
+ buf8.Copy( caseInfo->TestCaseTitle() );
+ if ( !( i == module->iTestInfos.Count() - 1 ) )
+ {
+ buf8.Append( KParameterDelimiter );
+ }
+ TRAP( err, caseListBuf->ExpandL( pos, buf8.Length() ) );
+ if ( err )
+ {
+ SendErrorResponseMsg( KErrNoMemory, KErrorNoMemory );
+ delete caseListBuf;
+ return;
+ }
+ caseListBuf->Write( pos, buf8, buf8.Length() );
+ pos += buf8.Length();
+ buf8.Zero();
+ }
+
+ if ( module->iTestInfos.Count() > 0 )
+ {
+ TPtr8 ptr = caseListBuf->Ptr( 0 );
+ SendResponseMsg( ptr );
+ }
+
+ else
+ {
+ SendResponseMsg( buf8 );
+ }
+
+ delete caseListBuf;
+ }
+
+ else
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorTooManyParameters );
+ }
+
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::HandleListCasesCmdL" );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::HandleStartCaseCmdL
+// Starts one test case based on test module name and test case index number.
+// STIF TF gives an ID to the started case and that ID is sent as a response
+// message.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::HandleStartCaseCmdL()
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::HandleStartCaseCmdL" );
+
+ TInt err = KErrNone;
+ TInt caseNumber = -1;
+
+ // START_CASE command has 1 or 2 parameters.
+ // If only one parameter given, it's the index of test case to start. The
+ // index refers to the list of test cases of all currently loaded modules.
+ // If two parameters given, then the first one is the module name and
+ // second is the test case index number inside the given module,
+
+ if ( iParameters->Count() == 0 )
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorParameterMissing );
+ return;
+ }
+
+ else if ( iParameters->Count() == 1 )
+ {
+ TLex8 lex( (*iParameters)[0] );
+ err = lex.Val( caseNumber );
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorInvalidCaseNumber );
+ return;
+ }
+
+ CTestInfo* caseInfo = NULL;
+ TRAP( err, caseInfo = GetCaseInfoL( caseNumber ) );
+
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorInvalidCaseNumber );
+ return;
+ }
+
+ TInt caseId = -1;
+
+ err = StartTestCase( caseId, *caseInfo );
+
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorStartTestCase );
+ return;
+ }
+
+ TBuf8<32> msg;
+ msg.AppendNum( caseId );
+ SendResponseMsg( msg );
+ }
+
+ else if ( iParameters->Count() == 2 )
+ {
+ TBuf<KMaxFileName> moduleName;
+ if ( (*iParameters)[0].Length() > moduleName.MaxLength() )
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorParameterTooLong );
+ return;
+ }
+
+ moduleName.Copy( (*iParameters)[0] );
+ TLex8 lex( (*iParameters)[1] );
+ err = lex.Val( caseNumber );
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorInvalidCaseNumber );
+ return;
+ }
+
+ TInt moduleIndex = IndexByModuleName( moduleName );
+
+ if ( moduleIndex == KErrNotFound )
+ {
+ // We don't have case infos of given module loaded - try to
+ // load them.
+ TRAP( err, LoadTestCaseInfosL( moduleName ) );
+ if ( err )
+ {
+ HTI_LOG_FORMAT(
+ "StartCase - Error from LoadTestCaseInfosL %d", err );
+ SendErrorResponseMsg( err, KErrorModuleNotLoaded );
+ return;
+ }
+ // Now there should be the module added - get its index
+ moduleIndex = IndexByModuleName( moduleName );
+ }
+
+ CHtiTestModuleCaseInfos* module = iLoadedInfos[moduleIndex];
+
+ if ( caseNumber < 0 ||
+ caseNumber >= module->iTestInfos.Count() ||
+ module->iTestInfos.Count() == 0 )
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorInvalidCaseNumber );
+ return;
+ }
+
+ CTestInfo* caseInfo = module->iTestInfos[caseNumber];
+ TInt caseId = -1;
+
+ err = StartTestCase( caseId, *caseInfo );
+
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorStartTestCase );
+ return;
+ }
+
+ TBuf8<32> msg;
+ msg.AppendNum( caseId );
+ SendResponseMsg( msg );
+ }
+
+ else
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorTooManyParameters );
+ }
+
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::HandleStartCaseCmdL" );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::HandleCancelCaseCmdL
+// Cancels test case execution based on test case ID.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::HandleCancelCaseCmdL()
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::HandleCancelCaseCmdL" );
+
+ TInt err = KErrNone;
+
+ // CANCEL_CASE command always has 1 parameter (test case id).
+ if ( iParameters->Count() == 0 )
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorParameterMissing );
+ return;
+ }
+
+ else if ( iParameters->Count() == 1 )
+ {
+ TInt caseId = -1;
+ TLex8 lex( (*iParameters)[0] );
+ err = lex.Val( caseId );
+
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorInvalidCaseNumber );
+ return;
+ }
+
+ err = CancelTestCase( caseId );
+
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorCancelTestCase );
+ }
+
+ else
+ {
+ SendResponseMsg( _L8( "OK" ) );
+ }
+ }
+
+ else
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorTooManyParameters );
+ }
+
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::HandleCancelCaseCmdL" );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::HandlePauseCaseCmdL
+// Pauses test case execution based on test case ID.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::HandlePauseCaseCmdL()
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::HandlePauseCaseCmdL" );
+
+ TInt err = KErrNone;
+
+ // PAUSE_CASE command always has 1 parameter (test case id).
+ if ( iParameters->Count() == 0 )
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorParameterMissing );
+ return;
+ }
+
+ else if ( iParameters->Count() == 1 )
+ {
+ TInt caseId = -1;
+ TLex8 lex( (*iParameters)[0] );
+ err = lex.Val( caseId );
+
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorInvalidCaseNumber );
+ return;
+ }
+
+ err = PauseTestCase( caseId );
+
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorPauseTestCase );
+ }
+
+ else
+ {
+ SendResponseMsg( _L8( "OK" ) );
+ }
+ }
+
+ else
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorTooManyParameters );
+ }
+
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::HandlePauseCaseCmdL" );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::HandleResumeCaseCmdL
+// Resumes execution of a paused test case based on test case ID.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::HandleResumeCaseCmdL()
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::HandleResumeCaseCmdL" );
+
+ TInt err = KErrNone;
+
+ // RESUME_CASE command always has 1 parameter (test case id).
+ if ( iParameters->Count() == 0 )
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorParameterMissing );
+ return;
+ }
+
+ else if ( iParameters->Count() == 1 )
+ {
+ TInt caseId = -1;
+ TLex8 lex( (*iParameters)[0] );
+ err = lex.Val( caseId );
+
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorInvalidCaseNumber );
+ return;
+ }
+
+ err = ResumeTestCase( caseId );
+
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorResumeTestCase );
+ }
+
+ else
+ {
+ SendResponseMsg( _L8( "OK" ) );
+ }
+ }
+
+ else
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorTooManyParameters );
+ }
+
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::HandleResumeCaseCmdL" );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::HandleAddCaseFileCmdL
+// Adds a test case file to an earlier loaded test module.
+// Checks that the module is loaded and that the given test case file exists.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::HandleAddCaseFileCmdL()
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::HandleAddCaseFileCmdL" );
+
+ TInt err = KErrNone;
+
+ TBuf<KMaxFileName> moduleName;
+ TBuf<KMaxFileName> caseFilePath;
+
+ // ADD_CASE_FILE command always has 2 mandatory parameters (module name
+ // and test case file path).
+ if ( iParameters->Count() == 0 || iParameters->Count() == 1 )
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorParameterMissing );
+ return;
+ }
+
+ else if ( iParameters->Count() == 2 )
+ {
+ if ( (*iParameters)[0].Length() > moduleName.MaxLength() ||
+ (*iParameters)[1].Length() > caseFilePath.MaxLength() )
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorParameterTooLong );
+ return;
+ }
+
+ moduleName.Copy( (*iParameters)[0] );
+ caseFilePath.Copy( (*iParameters)[1] );
+
+ RFs fsSession;
+ err = fsSession.Connect();
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorFileServer );
+ return;
+ }
+
+ if ( !( BaflUtils::FileExists( fsSession, caseFilePath ) ) )
+ {
+ SendErrorResponseMsg( KErrNotFound, KErrorCaseFileNotFound );
+ fsSession.Close();
+ return;
+ }
+
+ fsSession.Close();
+
+ err = AddTestCaseFile( moduleName, caseFilePath );
+
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorAddCaseFile );
+ return;
+ }
+
+ // Test case file has been added - update test case infos
+ TRAP( err, LoadTestCaseInfosL( moduleName ) );
+
+ if ( err )
+ {
+ HTI_LOG_FORMAT(
+ "AddCaseFile - Error from LoadTestCaseInfosL %d", err );
+ SendErrorResponseMsg( err, KErrorGetTestCases );
+ return;
+ }
+
+ SendResponseMsg( _L8( "OK" ) );
+ }
+
+ else
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorTooManyParameters );
+ }
+
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::HandleAddCaseFileCmdL" );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::HandleRemoveCaseFileCmdL
+// Removes a test case file from test module.
+// Checks that the module is loaded and that the given test case file exists.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::HandleRemoveCaseFileCmdL()
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::HandleRemoveCaseFileCmdL" );
+
+ TInt err = KErrNone;
+
+ TBuf<KMaxFileName> moduleName;
+ TBuf<KMaxFileName> caseFilePath;
+
+ // REMOVE_CASE_FILE command always has 2 mandatory parameters (module name
+ // and test case file path).
+ if ( iParameters->Count() == 0 || iParameters->Count() == 1 )
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorParameterMissing );
+ return;
+ }
+
+ else if ( iParameters->Count() == 2 )
+ {
+ if ( (*iParameters)[0].Length() > moduleName.MaxLength() ||
+ (*iParameters)[1].Length() > caseFilePath.MaxLength() )
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorParameterTooLong );
+ return;
+ }
+
+ moduleName.Copy( (*iParameters)[0] );
+ caseFilePath.Copy( (*iParameters)[1] );
+
+ RFs fsSession;
+ err = fsSession.Connect();
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorFileServer );
+ return;
+ }
+
+ if ( !( BaflUtils::FileExists( fsSession, caseFilePath ) ) )
+ {
+ SendErrorResponseMsg( KErrNotFound, KErrorCaseFileNotFound );
+ fsSession.Close();
+ return;
+ }
+
+ fsSession.Close();
+
+ err = RemoveTestCaseFile( moduleName, caseFilePath );
+
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorRemoveCaseFile );
+ return;
+ }
+
+ // Test case file has been removed - update test case infos
+ TRAP( err, LoadTestCaseInfosL( moduleName ) );
+
+ if ( err )
+ {
+ HTI_LOG_FORMAT(
+ "RemoveCaseFile - Error from LoadTestCaseInfosL %d", err );
+ SendErrorResponseMsg( err, KErrorGetTestCases );
+ return;
+ }
+
+ SendResponseMsg( _L8( "OK" ) );
+ }
+
+ else
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorTooManyParameters );
+ }
+
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::HandleRemoveCaseFileCmdL" );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::HandleCaseMsgCmdL
+// Sends a message to STIF Test Framework.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::HandleCaseMsgCmdL()
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::HandleCaseMsgCmdL" );
+
+ TInt err = KErrNone;
+
+ // CASE_MESSAGE command always has 1 parameter (the message).
+ if ( iParameters->Count() == 0 )
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorParameterMissing );
+ return;
+ }
+
+ else if ( iParameters->Count() == 1 )
+ {
+ HBufC* msg = HBufC::New( (*iParameters)[0].Length() );
+ if ( msg == NULL )
+ {
+ SendErrorResponseMsg( KErrNoMemory, KErrorNoMemory );
+ return;
+ }
+ msg->Des().Copy( (*iParameters)[0] );
+ HTI_LOG_TEXT( "Sending case message:" );
+ HTI_LOG_DES( *msg );
+ err = AtsReceive( *msg );
+ delete msg;
+
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorCaseMessage );
+ }
+
+ else
+ {
+ SendResponseMsg( _L8( "OK" ) );
+ }
+ }
+
+ else
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorTooManyParameters );
+ }
+
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::HandleCaseMsgCmdL" );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::HandleSetDevIdCmdL
+// Sets device ID. If successfull sends the set ID back as response message.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::HandleSetDevIdCmdL()
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::HandleSetDevIdCmdL" );
+
+ TInt err = KErrNone;
+
+ // SET_DEVICEID command always has 1 parameter (device id).
+ if ( iParameters->Count() == 0 )
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorParameterMissing );
+ return;
+ }
+
+ else if ( iParameters->Count() == 1 )
+ {
+ TUint16 deviceId = KDefaultDevId;
+ TLex8 lex( (*iParameters)[0] );
+ err = lex.Val( deviceId, EDecimal );
+
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorInvalidDeviceId );
+ return;
+ }
+
+ iDevId = deviceId;
+
+ // On success sends the set device id as response.
+ TBuf8<32> msg;
+ msg.AppendNum( (TInt)iDevId );
+ SendResponseMsg( msg );
+ }
+
+ else
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorTooManyParameters );
+ }
+
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::HandleSetDevIdCmdL" );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::HandleSetAttributeCmdL
+// Sets attributes for test framework.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::HandleSetAttributeCmdL()
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::HandleSetAttributeCmdL" );
+
+ TInt err = KErrNone;
+
+ // SET_ATTRIBUTE command always has 2 paramters (attribute id and value)
+ if ( iParameters->Count() < 2 )
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorParameterMissing );
+ }
+
+ else if ( iParameters->Count() == 2 )
+ {
+ TInt attributeId = -1;
+ TLex8 lex( (*iParameters)[0] );
+ err = lex.Val( attributeId );
+
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorInvalidAttributeId );
+ return;
+ }
+
+ TBuf<256> value;
+ if ( (*iParameters)[1].Length() > value.MaxLength() )
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorParameterTooLong );
+ return;
+ }
+ value.Copy( (*iParameters)[1] );
+
+ err = SetAttribute( (TAttribute)attributeId, value );
+
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorSetAttribute );
+ }
+
+ else
+ {
+ SendResponseMsg( _L8( "OK" ) );
+ }
+ }
+
+ else
+ {
+ SendErrorResponseMsg( KErrArgument, KErrorTooManyParameters );
+ }
+
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::HandleSetAttributeCmdL" );
+ }
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::TestCompleted
+// This method is called by the STIF TF when a test case execution completes.
+// The test case result is send out as a formatted string.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::TestCompleted( TInt aTestId,
+ TInt aTestExecutionResult,
+ TTestResult& aTestResult )
+ {
+ // Note that the STIF TF is not aware whether the service is busy processing,
+ // sending, or waiting to send a previous message. So if this method
+ // is called by the STIF TF while the service is busy, the currently
+ // pending message will be overridden by the message sent from this method.
+
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::TestCompleted" );
+
+ iIsBusy = ETrue; // Will be set to EFalse when response have been sent
+
+ // The maximum length of TResultDes is 128, so a buffer of 256
+ // should be enough for the whole "Test Completed" message.
+ TBuf8<256> buf8;
+
+ // Add first the test id
+ buf8.AppendFormat( _L8( "%d" ), aTestId );
+ buf8.Append( KParameterDelimiter );
+
+ // Add the test result - if it's 0 case has passed
+ buf8.AppendFormat( _L8( "%d" ), aTestResult.iResult );
+ buf8.Append( KParameterDelimiter );
+
+ // Add the test execution result
+ buf8.AppendFormat( _L8( "%d" ), aTestExecutionResult );
+ buf8.Append( KParameterDelimiter );
+
+ // Finally add the description (if there's any)
+ if ( aTestResult.iResultDes.Length() > 0 )
+ {
+ buf8.Append( aTestResult.iResultDes );
+ }
+
+ // and send it
+ SendResponseMsg( buf8, ECmdTestCompleted );
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::TestCompleted" );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::AtsSend
+// This method is called by the STIF TF when it needs to send a message to ATS
+// (or some other PC-side component listening for messages)
+// The message is converted to 8-bit representation before sending.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::AtsSend( const TDesC& aMessage )
+ {
+ // Note that the STIF TF is not aware whether the service is busy processing,
+ // sending, or waiting to send a previous message. So if this method
+ // is called by the STIF TF while the service is busy, the currently
+ // pending message will be overridden by the message sent from this method.
+
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::AtsSend" );
+ HTI_LOG_TEXT( "Message: " );
+ HTI_LOG_DES( aMessage );
+
+ iIsBusy = ETrue; // Will be set to EFalse when response have been sent
+
+ TInt err = KErrNone;
+
+ CCnvCharacterSetConverter* converter = NULL;
+ TRAP( err, converter = CCnvCharacterSetConverter::NewL() );
+
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorCharConv );
+ return;
+ }
+
+ RFs fsSession;
+ err = fsSession.Connect();
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorFileServer );
+ delete converter;
+ return;
+ }
+
+ CCnvCharacterSetConverter::TAvailability availability =
+ CCnvCharacterSetConverter::ENotAvailable;
+
+ TRAP( err, availability = converter->PrepareToConvertToOrFromL(
+ KCharacterSetIdentifierAscii, fsSession ) );
+
+ if ( err || availability == CCnvCharacterSetConverter::ENotAvailable )
+ {
+ SendErrorResponseMsg( err, KErrorCharConv );
+ fsSession.Close();
+ delete converter;
+ return;
+ }
+
+ fsSession.Close();
+
+ HBufC8* asciiBuffer = NULL;
+ TRAP( err, asciiBuffer = HBufC8::NewL( aMessage.Length() ) );
+
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorNoMemory );
+ delete converter;
+ return;
+ }
+
+ TPtr8 ptr8 = asciiBuffer->Des();
+ ptr8.Zero();
+
+ err = converter->ConvertFromUnicode( ptr8, aMessage );
+
+ if ( err )
+ {
+ SendErrorResponseMsg( err, KErrorCharConv );
+ }
+
+ else
+ {
+ TPtr8 converted = asciiBuffer->Des();
+ HTI_LOG_TEXT( "Converted message: " );
+ HTI_LOG_DES( converted );
+ SendResponseMsg( converted, ECmdAtsMessage );
+ }
+
+ delete converter;
+ delete asciiBuffer;
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::AtsSend" );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::Print
+// This method is called by the STIF TF when a test case prints.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::Print( TInt /*aTestId*/,
+ TTestProgress& aProgress )
+ {
+ if ( iConsole )
+ {
+ iConsole->Printf( _L("%S: %S\n"),
+ &aProgress.iDescription,
+ &aProgress.iText );
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::LoadTestCaseInfosL
+// A helper method that loads the test case info objects from all currently
+// loaded test modules. Creates and inserts new CHtiTestModuleCaseInfos objects
+// to iLoadedInfos pointer array. Leaves on failure.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::LoadTestCaseInfosL()
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::LoadTestCaseInfosL()" );
+
+ RPointerArray<CTestInfo> allTestInfos;
+ CleanupClosePushL( allTestInfos );
+
+ HTI_LOG_TEXT( "Getting test cases" );
+ // Ignoring possible errors
+ GetTestCases( allTestInfos );
+ HTI_LOG_FORMAT( "Got %d cases", allTestInfos.Count() );
+
+ // Clear all old test case infos from iLoadedInfos
+ iLoadedInfos.ResetAndDestroy();
+
+ // Loop through all test case infos and add them to the correct modules
+ // to iLoadedInfos
+ for ( TInt i = 0; i < allTestInfos.Count(); i++ )
+ {
+ CHtiTestModuleCaseInfos* currentModule = NULL;
+ CTestInfo* caseInfo = NULL;
+
+ caseInfo = allTestInfos[i];
+
+ // Get or create the CHtiTestModuleCaseInfos where this case belongs.
+ TInt moduleIndex = IndexByModuleName( caseInfo->ModuleName() );
+
+ if ( moduleIndex == KErrNotFound )
+ {
+ HTI_LOG_TEXT( "Module not found - adding it" );
+ currentModule = CHtiTestModuleCaseInfos::NewLC(
+ caseInfo->ModuleName() );
+ User::LeaveIfError( iLoadedInfos.Append( currentModule ) );
+ CleanupStack::Pop(); // currentModule
+ }
+
+ else
+ {
+ HTI_LOG_TEXT( "Module found - getting it" );
+ currentModule = iLoadedInfos[moduleIndex];
+ }
+
+ // Add the case info to the CHtiTestModuleCaseInfos object
+ currentModule->iTestInfos.Append( caseInfo );
+ }
+
+ HTI_LOG_FORMAT( "Case infos of %d modules added", iLoadedInfos.Count() );
+ allTestInfos.Reset();
+ CleanupStack::PopAndDestroy(); // allTestInfos
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::LoadTestCaseInfosL()" );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::LoadTestCaseInfosL
+// A helper method that loads the test case info objects from the given test
+// module. Creates and inserts a new CHtiTestModuleCaseInfos object to
+// iLoadedInfos pointer array. Leaves on failure.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::LoadTestCaseInfosL( TDesC& aModuleName )
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::LoadTestCaseInfosL( moduleName )" );
+
+ // Check if test case infos of this module already loaded
+ TInt index = IndexByModuleName( aModuleName );
+ if ( index != KErrNotFound )
+ {
+ // If infos already loaded, delete and load again
+ HTI_LOG_TEXT( "Already loaded - updating" );
+ CHtiTestModuleCaseInfos* module = iLoadedInfos[index];
+ iLoadedInfos.Remove( index );
+ delete module;
+ }
+
+ CHtiTestModuleCaseInfos* newModule =
+ CHtiTestModuleCaseInfos::NewLC( aModuleName );
+
+ HTI_LOG_TEXT( "Getting test cases" );
+
+ // If the module is not loaded STIF TF seems to behave so that
+ // GetTestCases method does not return error but it returns
+ // zero test cases.
+ // At least in some cases if the module is loaded but it does not have
+ // any test cases, GetTestCases returns KErrNotFound.
+ // So possible errors or zero test case situations from GetTestCases
+ // are ignored here - if there's an error then the module will just
+ // have 0 test case infos.
+ GetTestCases( newModule->iTestInfos, aModuleName );
+
+ HTI_LOG_FORMAT( "Got %d cases", newModule->iTestInfos.Count() );
+
+ User::LeaveIfError( iLoadedInfos.Append( newModule ) );
+ CleanupStack::Pop(); // newModule
+
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::LoadTestCaseInfosL( moduleName )" );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::ParseParametersL
+// A helper method for parsing the parameters from the given command message.
+// Parameters must be separated with a character defined by the
+// KParameterDelimiter. Parsed parameters are stored to iParameters array.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::ParseParametersL( const TDesC8& aCommand )
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::ParseParametersL" );
+
+ // Clear the parameter array
+ iParameters->Reset();
+
+ // Then loop all the parameters.
+ TInt sectionStart = 0;
+ TInt sectionEnd = 0;
+ while ( true )
+ {
+ sectionStart = sectionEnd + 1;
+ if ( sectionStart >= aCommand.Length() )
+ {
+ HTI_LOG_FORMAT( "Parameters %d", iParameters->Count() );
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::ParseParametersL" );
+ return;
+ }
+
+ sectionEnd = aCommand.Mid( sectionStart ).Find( KParameterDelimiter )
+ + sectionStart;
+
+ if ( sectionEnd >= sectionStart )
+ {
+ iParameters->AppendL(
+ aCommand.Mid( sectionStart, sectionEnd - sectionStart ) );
+ HTI_LOG_DES( aCommand.Mid( sectionStart, sectionEnd - sectionStart ) );
+ }
+ else
+ {
+ iParameters->AppendL( aCommand.Mid( sectionStart ) );
+ HTI_LOG_DES( aCommand.Mid( sectionStart ) );
+ HTI_LOG_FORMAT( "Parameters %d", iParameters->Count() );
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::ParseParametersL" );
+ return; // End of parameters.
+ }
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::SetDispatcher
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::SetDispatcher( MHtiDispatcher* aDispatcher )
+ {
+ iDispatcher = aDispatcher;
+ iConsole = iDispatcher->GetConsole();
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::NotifyMemoryChange
+// Called when HTI Framework has dispatched a message forward and the amount
+// of free memory in the message queue has changed.
+// -----------------------------------------------------------------------------
+//
+void CHtiStifTfIf::NotifyMemoryChange( TInt aAvailableMemory )
+ {
+ if ( iIsBusy && iMessage )
+ {
+ if ( aAvailableMemory >= iMessage->Size() )
+ {
+
+ if ( iErrorCode == 0 )
+ {
+ TInt err = iDispatcher->DispatchOutgoingMessage(
+ iMessage, KStifTfServiceUid );
+
+ if ( err == KErrNone )
+ {
+ // Ownership of iMessage has been transferred
+ iMessage = NULL;
+ iIsBusy = EFalse;
+ iDispatcher->RemoveMemoryObserver(
+ ( MHtiMemoryObserver* ) iPlugin );
+ }
+
+ else if ( err == KErrNoMemory )
+ {
+ // Just keep retrying.
+ }
+
+ else // Give up on sending
+ {
+ delete iMessage;
+ iMessage = NULL;
+ iIsBusy = EFalse;
+ iDispatcher->RemoveMemoryObserver(
+ ( MHtiMemoryObserver* ) iPlugin );
+ }
+
+ }
+
+ else
+ {
+ TInt err = iDispatcher->DispatchOutgoingErrorMessage(
+ iErrorCode, *iMessage, KStifTfServiceUid );
+
+ // If it was success or some other error than KErrNoMemory
+ // we are done sending or trying to send this message.
+ if ( err != KErrNoMemory )
+ {
+ delete iMessage;
+ iMessage = NULL;
+ iIsBusy = EFalse;
+ iDispatcher->RemoveMemoryObserver(
+ ( MHtiMemoryObserver* ) iPlugin );
+ }
+
+ else
+ {
+ // Just keep retrying.
+ }
+ }
+ }
+ }
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::SendResponseMsg
+// Sends a message out to the message dispatcher.
+// -----------------------------------------------------------------------------
+//
+TInt CHtiStifTfIf::SendResponseMsg( const TDesC8& aMsg,
+ const TUint8 aCommandId )
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::SendResponseMsg" );
+
+ iErrorCode = 0;
+
+ if ( iDispatcher == NULL )
+ {
+ iIsBusy = EFalse;
+ return KErrGeneral;
+ }
+
+ iDispatcher->RemoveMemoryObserver( ( MHtiMemoryObserver* ) iPlugin );
+
+ delete iMessage;
+ iMessage = NULL;
+ iMessage = HBufC8::New( aMsg.Length() + 1 );
+
+
+ if ( iMessage == NULL )
+ {
+ iIsBusy = EFalse;
+ return KErrNoMemory;
+ }
+
+ TPtr8 ptr8 = iMessage->Des();
+ if ( aCommandId != 0 )
+ {
+ ptr8.Append( aCommandId );
+ }
+ else
+ {
+ ptr8.Append( iCommandId );
+ }
+
+ ptr8.Append( aMsg );
+
+ TInt err = KErrNone;
+
+ err = iDispatcher->DispatchOutgoingMessage( iMessage, KStifTfServiceUid );
+
+ if ( err == KErrNoMemory )
+ {
+ HTI_LOG_TEXT( "Message queue memory full - waiting" );
+ iIsBusy = ETrue; // Should already be true, but just in case
+ iDispatcher->AddMemoryObserver( ( MHtiMemoryObserver* ) iPlugin );
+ // For the caller of this method all is OK, sending is just delayed
+ err = KErrNone;
+ }
+
+ else if ( err == KErrNone )
+ {
+ HTI_LOG_TEXT( "Message sent to dispatcher" );
+ iMessage = NULL; // Ownership of iMessage has been transferred
+ iIsBusy = EFalse;
+ }
+
+ else // give up on sending
+ {
+ HTI_LOG_FORMAT( "Other dispatcher error %d", err );
+ delete iMessage;
+ iMessage = NULL;
+ iIsBusy = EFalse;
+ }
+
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::SendResponseMsg" );
+ return err;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::SendErrorResponseMsg
+// Sends an error message out to the message dispatcher.
+// -----------------------------------------------------------------------------
+//
+TInt CHtiStifTfIf::SendErrorResponseMsg( TInt aErrorCode,
+ const TDesC8& aErrorDescription,
+ const TUint8 aCommandId )
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::SendErrorResponseMsg" );
+
+ iErrorCode = aErrorCode;
+
+ if ( iDispatcher == NULL )
+ {
+ iIsBusy = EFalse;
+ return KErrGeneral;
+ }
+
+ iDispatcher->RemoveMemoryObserver( ( MHtiMemoryObserver* ) iPlugin );
+
+ delete iMessage;
+ iMessage = NULL;
+ iMessage = HBufC8::New( aErrorDescription.Length() + 1 );
+
+ if ( iMessage == NULL )
+ {
+ iIsBusy = EFalse;
+ return KErrNoMemory;
+ }
+
+ TPtr8 ptr8 = iMessage->Des();
+ if ( aCommandId != 0 )
+ {
+ ptr8.Append( aCommandId );
+ }
+ else
+ {
+ ptr8.Append( iCommandId );
+ }
+
+ ptr8.Append( aErrorDescription );
+
+ TInt err = KErrNone;
+
+ err = iDispatcher->DispatchOutgoingErrorMessage(
+ aErrorCode, *iMessage, KStifTfServiceUid );
+
+ if ( err == KErrNoMemory )
+ {
+ HTI_LOG_TEXT( "Message queue memory full - waiting" );
+ iIsBusy = ETrue; // Should already be true, but just in case
+ iDispatcher->AddMemoryObserver( ( MHtiMemoryObserver* ) iPlugin );
+ // For the caller of this method all is OK, sending is just delayed
+ err = KErrNone;
+ }
+
+ else if ( err == KErrNone )
+ {
+ HTI_LOG_TEXT( "Error message sent to dispatcher" );
+ delete iMessage;
+ iMessage = NULL;
+ iIsBusy = EFalse;
+ }
+
+ else // give up on sending
+ {
+ HTI_LOG_FORMAT( "Other dispatcher error %d", err );
+ delete iMessage;
+ iMessage = NULL;
+ iIsBusy = EFalse;
+ }
+
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::SendErrorResponseMsg" );
+ return err;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::IndexByModuleName
+// A helper method to search for a CHtiTestModuleCaseInfos object from the
+// iLoadedInfos array based on the module name.
+// -----------------------------------------------------------------------------
+//
+TInt CHtiStifTfIf::IndexByModuleName( const TDesC& aModuleName )
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::IndexByModuleName" );
+
+ CHtiTestModuleCaseInfos* module;
+ for ( TInt i = 0; i < iLoadedInfos.Count(); i++ )
+ {
+ module = NULL;
+ module = iLoadedInfos[i];
+ if ( module->iModuleName->Compare( aModuleName ) == 0 )
+ {
+ HTI_LOG_FORMAT( "Module found from index %d", i );
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::IndexByModuleName" );
+ return i;
+ }
+ }
+ HTI_LOG_TEXT( "Module not found" );
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::IndexByModuleName" );
+ return KErrNotFound;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiStifTfIf::GetCaseInfoL
+// A helper method to get the correct CTestInfo object based on the index
+// number, referring to list of case infos of all loaded test modules.
+// -----------------------------------------------------------------------------
+//
+CTestInfo* CHtiStifTfIf::GetCaseInfoL( TInt aCaseIndex )
+ {
+ HTI_LOG_FUNC_IN( "CHtiStifTfIf::GetCaseInfoL" );
+
+ if ( aCaseIndex < 0 )
+ {
+ User::Leave( KErrArgument );
+ }
+
+ TInt index = -1;
+ TInt caseCount = 0;
+ CHtiTestModuleCaseInfos* module = NULL;
+ for ( TInt i = 0; i < iLoadedInfos.Count(); i++ )
+ {
+ module = NULL;
+ module = iLoadedInfos[i];
+ caseCount += module->iTestInfos.Count();
+ HTI_LOG_FORMAT( "Case count = %d", caseCount );
+ if ( aCaseIndex < caseCount )
+ {
+ // This is the right module
+ // Get the case index inside this module
+ index = module->iTestInfos.Count() - ( caseCount - aCaseIndex );
+ }
+ if ( index >= 0 ) break; // Case found - break out of loop
+ }
+
+ if ( index < 0 )
+ {
+ HTI_LOG_TEXT( "Given index was too big - case not found" );
+ User::Leave( KErrNotFound );
+ }
+
+ // Following should never be true - this is for testing.
+ if ( index > module->iTestInfos.Count() )
+ {
+ HTI_LOG_TEXT( "**Calculated index > test info count of module**" );
+ User::Leave( KErrGeneral );
+ }
+
+ HTI_LOG_FORMAT( "Case found from index %d", index );
+ HTI_LOG_FUNC_OUT( "CHtiStifTfIf::GetCaseInfoL" );
+ return module->iTestInfos[index];
+ }
+
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+
+// -----------------------------------------------------------------------------
+// CHtiTestModuleCaseInfos::NewL
+// -----------------------------------------------------------------------------
+//
+CHtiTestModuleCaseInfos* CHtiTestModuleCaseInfos::NewL(
+ const TDesC& aModuleName )
+ {
+ CHtiTestModuleCaseInfos* self = NewLC( aModuleName );
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiTestModuleCaseInfos::NewLC
+// -----------------------------------------------------------------------------
+//
+CHtiTestModuleCaseInfos* CHtiTestModuleCaseInfos::NewLC(
+ const TDesC& aModuleName )
+ {
+ CHtiTestModuleCaseInfos* self = new (ELeave) CHtiTestModuleCaseInfos;
+ CleanupStack::PushL( self );
+ self->ConstructL( aModuleName );
+ return self;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiTestModuleCaseInfos::ConstructL
+// 2nd phase constructor.
+// -----------------------------------------------------------------------------
+//
+void CHtiTestModuleCaseInfos::ConstructL( const TDesC& aModuleName )
+ {
+ iModuleName = aModuleName.AllocL();
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiTestModuleCaseInfos::CHtiTestModuleCaseInfos
+// C++ default constructor
+// -----------------------------------------------------------------------------
+//
+CHtiTestModuleCaseInfos::CHtiTestModuleCaseInfos()
+ {
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiTestModuleCaseInfos::~CHtiTestModuleCaseInfos
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CHtiTestModuleCaseInfos::~CHtiTestModuleCaseInfos()
+ {
+ delete iModuleName;
+ iTestInfos.ResetAndDestroy();
+ iTestInfos.Close();
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiTestModuleCaseInfos::Compare
+// Compares the order of two CHtiTestModuleCaseInfos objects using module name
+// as the ordering key.
+// -----------------------------------------------------------------------------
+//
+TInt CHtiTestModuleCaseInfos::Compare( const CHtiTestModuleCaseInfos& aFirst,
+ const CHtiTestModuleCaseInfos& aSecond )
+ {
+ return ( aFirst.iModuleName )->Compare( *aSecond.iModuleName );
+ }
+
+
+// -----------------------------------------------------------------------------
+// CHtiTestModuleCaseInfos::Match
+// Checks the equality of two CHtiTestModuleCaseInfos objects.
+// Objects are considered to be equal if their module name is equal.
+// -----------------------------------------------------------------------------
+//
+TBool CHtiTestModuleCaseInfos::Match( const CHtiTestModuleCaseInfos& aFirst,
+ const CHtiTestModuleCaseInfos& aSecond )
+ {
+ if ( ( aFirst.iModuleName )->Compare( *aSecond.iModuleName ) == 0 )
+ {
+ return true;
+ }
+
+ return false;
+ }
+
+
+// End of File