basebandabstraction/basebandchanneladaptor/Test/TE_BCA/src/te_xxBcaUnitSteps.cpp
author hgs
Fri, 14 May 2010 13:52:48 +0100
changeset 38 b6a16c6baaa3
parent 0 3553901f7fa8
child 24 6638e7f4bd8f
permissions -rw-r--r--
201019_06

// Copyright (c) 2005-2009 Nokia Corporation and/or its subsidiary(-ies).
// All rights reserved.
// This component and the accompanying materials are made available
// under the terms of "Eclipse Public License v1.0"
// which accompanies this distribution, and is available
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
//
// Initial Contributors:
// Nokia Corporation - initial contribution.
//
// Contributors:
//
// Description:
// te_xxBcaUnitTestSteps.cpp
// Implements the unit test classes for xxBca.
// 
//

/**
 @file
 @internalComponent
*/


#include "te_xxBcaUnitSteps.h"
#include "BcaTestProxy.h"
#include <c32comm.h> // uniquely for the call to StartC32WithCMISuppressions

using namespace te_xxBcaUnitTests; // all xxBca tests



/** BCA version type */
typedef TUint32 TBcaVersion;

/** Special error code for test that require a leaving function.
This code is not used by any of Symbian system components */
static const TInt KNonSystemErrCode(-9876);
_LIT8(KWriteBuf1Lit, "WriteBuffer_1");
_LIT8(KWriteBuf2Lit, "WriteBuffer_2");


/**
 C++ constructor 
 */
CxxBcaTestBase::CxxBcaTestBase()
	: CTestStep(),
	iUut(NULL),
	iPeer(NULL),
	iWriteBuf1(KWriteBuf1Lit),
	iWriteBuf2(KWriteBuf2Lit)
	{	
	}

/**
C++ destructor */
CxxBcaTestBase::~CxxBcaTestBase()
	{
		
	if(iUut)
		{
		iUut->Release();
		}
		
	
	if(iPeer)
		{
		iPeer->Release();
		}
		
	}

/**
 Implements the pure virtual doTestStepPreambleL defined in CTestStep. 
 Used to disable the phone book synchronizer which may cause the tests to fail.
 
 
 @return EPass if successful.
 @leave If Phonebook synchronizer disabling fails. 
 */
TVerdict CxxBcaTestBase::doTestStepPreambleL()
	{	
	_LIT(KPhbkSyncCMI, "phbsync.cmi");
	TInt err = StartC32WithCMISuppressions(KPhbkSyncCMI);
	TESTL(KErrNone == err || KErrAlreadyExists == err);
	INFO_PRINTF1(_L("Test Step Preamble: disabled Phonebook Synchronizer."));	
	return EPass;
	}
	
/**
 Implements the pure virtual doTestStepL defined in CTestStep. 
 Allows the base class to execute before any of the derived tests is called.
 
 @leave If any of the called methods leaves.
 */
TVerdict CxxBcaTestBase::doTestStepL()
	{
	__UHEAP_MARK;
	TVerdict testResult = EFail;
	
	TRAPD(
		configErr, 
		LoadBcaSettingsFromConfigFileL();
		LoadBcaIapSettingsFromConfigFileL()
		);
	if(KErrNone != configErr)
		{
		ERR_PRINTF1(_L("Test Step Failure: Could not load Configuration Settings"));
		SetTestStepResult(EAbort);
		return TestStepResult();		
		}
		
	ASSERT(!CActiveScheduler::Current()); // We should not have an AS at this point.
	CActiveScheduler* testSched = new(ELeave) CActiveScheduler;
	CleanupStack::PushL(testSched);
	CActiveScheduler::Install(testSched);
	TRAPD(err, testResult = RunTestStepL());
	if(KErrNone == err)
		{
		INFO_PRINTF1(_L("Test Step Completion."));
		SetTestStepResult(testResult);
		}
	else
		{
		ERR_PRINTF2(_L("Test Step Failure: left with [%d]"), err);
		TestEnvironmentCleanup(); // Make sure test code has released everything. 
		SetTestStepResult(EFail);
		}
	CActiveScheduler::Install(NULL); // uninstall the test scheduler
	CleanupStack::PopAndDestroy(testSched);
		
	// Heap checking targets incorrect memory handling in the UUT, 
	// rather than in the test code.
	// It is Ok for the test code to leave without releasing memory - 
	// cleanup is forced if the test step leaves.
	// Heap checking should fail if UUT was cleaned up, but not all
	// memory was released by the owned objects.		
	__UHEAP_MARKEND; // Check the Heap after test code is finished.
	
	return TestStepResult();	
	}
	
/**
Makes sure that the test environment has released all the resources */
void CxxBcaTestBase::TestEnvironmentCleanup()
	{
	if(iUut)
		{
		ERR_PRINTF1(_L("Test Environment cleanup: unloading UUT."));
		iUut->Release();
		iUut = NULL;
		}
	
	if(iPeer)
		{
		ERR_PRINTF1(_L("Test Environment cleanup: unloading Peer."));
		iPeer->Release();
		iPeer = NULL;
		}		 
	}


/** 
Read optional IAP settings from Config file 

@leave if settings could not be loaded.
*/
void CxxBcaTestBase::LoadBcaIapSettingsFromConfigFileL()
	{
	TInt uutIap(0); // 0 is an invalid value for IAP
	TInt peerIap(0);
	
	if(	!GetIntFromConfig(ConfigSection(), _L("UUT_IapId"), uutIap) ||
		!GetIntFromConfig(ConfigSection(), _L("Peer_IapId"), peerIap)) 
		{
		ERR_PRINTF2(_L("FAILED to read one of IAP Settings from config file. Leaving with KErrNotFound[%d]"), KErrNotFound);
		User::Leave(KErrNotFound);	
		}
	iUutIapId = static_cast<TUint32>(uutIap);
	iPeerIapId = static_cast<TUint32>(peerIap);
	}

/** 
Reads test configuration file and applies the settings 

@leave if the settings could not be loaded.
*/	
void CxxBcaTestBase::LoadBcaSettingsFromConfigFileL()
	{
	if(
		!GetStringFromConfig(ConfigSection(), _L("UUT_Name"),      iUutName) ||
		!GetStringFromConfig(ConfigSection(), _L("Peer_Name"), 	   iPeerName) ||
		!GetStringFromConfig(ConfigSection(), _L("UUT_PortName"),  iUutPortName) ||
		!GetStringFromConfig(ConfigSection(), _L("Peer_PortName"), iPeerPortName))
		{
		ERR_PRINTF2(_L("FAILED to read one of BCA Settings (BcaCSY_Name, UUT_PortName, etc) from config file. Leaving with KErrNotFound[%d]"), KErrNotFound);
		User::Leave(KErrNotFound);	
		}
	INFO_PRINTF5(_L("BCA Settings: %S Port[%S], %S Port[%S]"), &iUutName, &iUutPortName, &iPeerName, &iPeerPortName);
	}


/**
Logs a message and leaves on error 

@param aErrCode error code to check
@param aMsg message to log 
@leave if aError is other than KErrNone
*/
void CxxBcaTestBase::LogAndLeaveIfErrorL(TInt aErrCode, const TDesC& aMsg)
	{	
	if(KErrNone == aErrCode)
		{
		INFO_PRINTF3(_L("[%S]. err[%d]. OK."), &aMsg, aErrCode);
		}
	else
		{
		ERR_PRINTF4(_L("Failed: [%S]. err[%d]. Leaving with [%d])."), &aMsg, aErrCode, aErrCode);
		User::Leave(aErrCode);
		}
	}

/**
Loads UUT proxy 

@leave if UUT cannot be loaded */
void CxxBcaTestBase::LoadUutL()
	{
	INFO_PRINTF1(_L("Loading UUT"));
	ASSERT(NULL == iUut);
	
	iUut = CxxBcaProxy::NewL(*this, iUutName);
	
	ASSERT(iUut);
	INFO_PRINTF1(_L("UUT Loaded"));	
	}

/**
Unloads UUT 

*/
void CxxBcaTestBase::UnloadUut()
	{
	INFO_PRINTF1(_L("Unloading UUT"));
	ASSERT(iUut);
	
	iUut->Release();
	iUut = NULL;
	INFO_PRINTF1(_L("UUT Unloaded"));
	}

/**
Loads Peer (to the UUT )

@leave if Peer cannot be loaded */
void CxxBcaTestBase::LoadPeerL()
	{
	INFO_PRINTF1(_L("Loading Peer"));
	ASSERT(NULL == iPeer);
	
	iPeer = CxxBcaProxy::NewL(*this, iPeerName); 
	
	ASSERT(iPeer);
	INFO_PRINTF1(_L("Peer Loaded"));
	}
	
/**
Unloads Peer */
void CxxBcaTestBase::UnloadPeer()
	{
	INFO_PRINTF1(_L("Unloading Peer"));
	ASSERT(NULL != iPeer);
	
	iPeer->Release();
	iPeer = NULL;
	INFO_PRINTF1(_L("Peer Unloaded"));	
	}
	
/**
Checks if the two buffers are equal, for TDesC16

@param aBuf1 Buffer 1
@param aBuf2 Buffer 2

@leave if the buffers are not equal */ 	
void CxxBcaTestBase::CheckBuffersEqualL(const TDesC16& aBuf1,const TDesC16& aBuf2)
	{
	INFO_PRINTF3(_L("Buffer Equality: [%S]-[%S]"), &aBuf1, &aBuf2);
	if(aBuf1 != aBuf2)
		{
		User::Leave(KErrArgument);
		}
	INFO_PRINTF1(_L("Buffer Equality Check OK."));	
	}

/**
Checks if the two buffers are equal, for TDesC8

@param aBuf1 Buffer 1
@param aBuf2 Buffer 2

@leave if the buffers are not equal */ 		
void CxxBcaTestBase::CheckBuffersEqualL(const TDesC8& aBuf1,const TDesC8& aBuf2)
	{
	if(aBuf1 != aBuf2)
		{
		INFO_PRINTF1(_L("Buffer Equality Check Failed."));
		User::Leave(KErrArgument);
		}
	INFO_PRINTF1(_L("Buffer Equality Check OK."));		
	}



//Sets a CSY name in a BCA 

//@param aProxy the BCA proxy 
//@param aCsy CSY name
//@leave on failure 
void CxxBcaTestBase::SetProxyIapIdL(MBcaProxy& aProxy, TUint32 aIapId)
	{
	// Ioctl: Set Iap Id
	TPckgBuf<TUint32> commDbIapIdPckg(aIapId);
	aProxy.Ioctl(KBcaOptLevelGeneric, KBCASetIapId, commDbIapIdPckg);
	aProxy.WaitForIoctlL(KErrNone);	
	}
	

	

	
//CLOSED STATE
//



/**
Test open when BCA is closed
*/

TVerdict CClosedState1::RunTestStepL()
	{
	LoadUutL();	
	
	// Ioctl: Set Iap ID for the proxy
	SetProxyIapIdL(*iUut, iUutIapId);
	
	// Open 
	iUut->Open(iUutPortName);
	iUut->WaitForOpenL(KErrNone);
	
	// Shutdown
	iUut->Shutdown();
	iUut->WaitForShutdownL(KErrNone);
	
	UnloadUut();
	
	return EPass;
	}



//

//SHUTTING DOWN STATE

/**
Close the BCA while it is trying to shutdown
*/

TVerdict CShutdownState1::RunTestStepL()
	{
	LoadUutL();
		
	SetProxyIapIdL(*iUut, iUutIapId);
	
	iUut->Open(iUutPortName);
	iUut->WaitForOpenL(KErrNone);
		
	iUut->Shutdown();
	iUut->Close(); // don't wait for Shutdown to complete
	
	UnloadUut();

	
	return EPass;
	}
	
/**	
Unload BCA while shutting down
*/

TVerdict CShutdownState2::RunTestStepL()
	{
	LoadUutL();
		
	SetProxyIapIdL(*iUut, iUutIapId);
	
	iUut->Open(iUutPortName);
	iUut->WaitForOpenL(KErrNone);
		
	iUut->Shutdown();		
	UnloadUut();

	
	return EPass;
	}


//
//OPENING STATE

/**
Shutdown while BCA is opening
*/

TVerdict COpeningState1::RunTestStepL()
	{
	LoadUutL();
		
	SetProxyIapIdL(*iUut, iUutIapId);
	
	iUut->Open(iUutPortName); // don't wait for Open to complete
			
	iUut->Shutdown();
	iUut->WaitForShutdownL(KErrNone);
	
	UnloadUut();
	
	return EPass;
	}
	

/**
Close while the BCA is openning	
*/

TVerdict COpeningState2::RunTestStepL()
	{
	LoadUutL();
		
	SetProxyIapIdL(*iUut, iUutIapId);
	
	iUut->Open(iUutPortName); //don't wait for the Open to complete
	
	iUut->Close();		
	
	UnloadUut();
	
	return EPass;
	}
	
/**	
Release while the BCA is openning
*/

TVerdict COpeningState3::RunTestStepL()
	{
	LoadUutL();
		
	SetProxyIapIdL(*iUut, iUutIapId);
	
	iUut->Open(iUutPortName); //don't wait for the Open to complete
			
	UnloadUut();
	
	return EPass;
	
	}





//
//OPEN STATE

/**
test for successful data tansfer between the 2 BCA's
*/

TVerdict COpenState1::RunTestStepL()
	{
	LoadUutL();
	LoadPeerL();
	
	// Set IAP Ids.	
	SetProxyIapIdL(*iUut, iUutIapId);	
	SetProxyIapIdL(*iPeer, iPeerIapId);
	
	// Open	
	iUut->Open(iUutPortName);
	iPeer->Open(iPeerPortName);
	
	iUut->WaitForOpenL(KErrNone);
	iPeer->WaitForOpenL(KErrNone);
	
	
	// Write - Read 
	iUut->Write(iWriteBuf1);
	iPeer->Read(iReadBuf1);
	
	// Peer should have read what Uut wrote
	iUut->WaitForWriteL(KErrNone);
	iPeer->WaitForReadL(KErrNone);
	CheckBuffersEqualL(iWriteBuf1, iReadBuf1);
	
	
	// Read - Write
	iReadBuf1.Zero();
	iUut->Read(iReadBuf1);
	iPeer->Write(iWriteBuf1);
	
	// Uut should have read what Peer wrote
	iUut->WaitForReadL(KErrNone);
	iUut->WaitForWriteL(KErrNone);
	CheckBuffersEqualL(iWriteBuf1, iReadBuf1);

	
	// normal Shutdown of Uut and Peer
	iUut->Shutdown();
	iUut->WaitForShutdownL(KErrNone);
	iPeer->Shutdown();
	iUut->WaitForShutdownL(KErrNone);
	UnloadUut();
	UnloadPeer();	


	return EPass;
	}
	



/**
Close when the BCA is opened
*/

TVerdict COpenState2::RunTestStepL()
	{
	LoadUutL();
	
	SetProxyIapIdL(*iUut, iUutIapId);
	
	iUut->Open(iUutPortName);	
	
	iUut->WaitForOpenL(KErrNone);
	
	iUut->Close();
	
	UnloadUut();
	
	return EPass;
	}
	
/**
Unload when the BCA is opened
*/

TVerdict COpenState3::RunTestStepL()
	{
	LoadUutL();
	
	SetProxyIapIdL(*iUut, iUutIapId);
	
	iUut->Open(iUutPortName);	
	
	iUut->WaitForOpenL(KErrNone);
	
	UnloadUut();
	
	return EPass;
	}
	
/**
Peforming a IOClt operation when BCA is opened	
*/

TVerdict COpenState4::RunTestStepL()
	{

    //get BCA major and minor version numbers from config file
	TInt majorFromConfig(0);
	TInt minorFromConfig(0);
	if(!GetIntFromConfig(ConfigSection(), _L("BcaVersionNumMajor"), majorFromConfig) ||
	   !GetIntFromConfig(ConfigSection(), _L("BcaVersionNumMinor"), minorFromConfig))
		{
		INFO_PRINTF1(_L("Error: BcaVersionNum is not specified in configuration file. Leaving with KErrNotFound"));
		User::Leave(KErrNotFound);
		}
	
	TBcaVersion bcaVersionNum(0x0);
	bcaVersionNum |= static_cast<TBcaVersion>(majorFromConfig) << 16; 
	bcaVersionNum |= static_cast<TBcaVersion>(minorFromConfig);
	if(bcaVersionNum <= 0)
		{
		INFO_PRINTF2(_L("Error: BcaVersionNum [%d] must be positive. Leaving with KErrCorrupt"), bcaVersionNum);
		User::Leave(KErrCorrupt);
		}
	
	
	LoadUutL();	
	
	SetProxyIapIdL(*iUut, iUutIapId);
	
	iUut->Open(iUutPortName);
	
	//get BCA major and minor version numbers from IOclt request
	TPckgBuf<TUint32> bcaVersionNumPckg;
	iUut->Ioctl(KBcaOptLevelGeneric, KVersionNumber, bcaVersionNumPckg);
	iUut->WaitForIoctlL(KErrNone);
	INFO_PRINTF3(_L("Retrieved BCA Version Number[%x], expecting [%x]."), bcaVersionNumPckg(), bcaVersionNum);
	
	//compare the version numbers
	if(bcaVersionNum != bcaVersionNumPckg())
		{
		User::Leave(KErrCorrupt);
		}
		
	UnloadUut();
	return EPass;
	
	}


//
//READING STATE

/**
Cancelread while the BCA is reading and sucessful Shutdown
*/

TVerdict CReadingState1::RunTestStepL()
	{
	
	LoadUutL();	
	SetProxyIapIdL(*iUut, iUutIapId);	
	iUut->Open(iUutPortName);		
	iUut->WaitForOpenL(KErrNone);
	
	LoadPeerL();	
	SetProxyIapIdL(*iPeer, iPeerIapId);	
	iPeer->Open(iPeerPortName);		
	iPeer->WaitForOpenL(KErrNone);
		
	
	iUut->Read(iReadBuf1);
	
	// Peer: do not write
	
		
	// Cancel Read:
	iUut->CancelRead();

	
	// Start another read to get back into reading state
	iReadBuf1.Zero();
	iUut->Read(iReadBuf1);
	
	//Shutdown on pending read
	iUut->Shutdown();
	iUut->WaitForShutdownL(KErrNone);
	
	iPeer->Shutdown();
	iPeer->WaitForShutdownL(KErrNone);
	

	UnloadUut();
	UnloadPeer();

	
	return EPass;
	}
	
/**
Close while the BCA is reading 
*/

TVerdict CReadingState2::RunTestStepL()
	{
	
    LoadUutL();	
	SetProxyIapIdL(*iUut, iUutIapId);	
	iUut->Open(iUutPortName);		
	iUut->WaitForOpenL(KErrNone);
	
	LoadPeerL();	
	SetProxyIapIdL(*iPeer, iPeerIapId);	
	iPeer->Open(iPeerPortName);		
	iPeer->WaitForOpenL(KErrNone);

	iReadBuf1.Zero();
	iUut->Read(iReadBuf1);
	
	//Close on a pending read	
	iUut->Close();
	
	iPeer->Shutdown();
	iPeer->WaitForShutdownL(KErrNone);
	
	UnloadUut();
	UnloadPeer();
	
	
	return EPass;
	}

/**
Unload while the BCA is reading 
*/

TVerdict CReadingState3::RunTestStepL()
	{
	
    LoadUutL();	
	SetProxyIapIdL(*iUut, iUutIapId);	
	iUut->Open(iUutPortName);		
	iUut->WaitForOpenL(KErrNone);
	
	LoadPeerL();	
	SetProxyIapIdL(*iPeer, iPeerIapId);	
	iUut->Open(iPeerPortName);		
	iUut->WaitForOpenL(KErrNone);

	iReadBuf1.Zero();
	iUut->Read(iReadBuf1);
	
	//Unload on a pending read
	UnloadUut();
	
	iPeer->Shutdown();
	iPeer->WaitForShutdownL(KErrNone);
	UnloadPeer();
	
	
	return EPass;
	}



//
// WRITING STATE

/**
CancelWrite while BCA is writing 	
*/

TVerdict CWritingState1::RunTestStepL()
	{
	
	
	LoadUutL();	
	SetProxyIapIdL(*iUut, iUutIapId);	
	iUut->Open(iUutPortName);		
	iUut->WaitForOpenL(KErrNone);
	
	LoadPeerL();	
	SetProxyIapIdL(*iPeer, iPeerIapId);	
	iUut->Open(iPeerPortName);		
	iUut->WaitForOpenL(KErrNone);


	
	iUut->Write(iWriteBuf1);
	
	//cancel the write
	iUut->CancelWrite();
	
	//start another write to get back in writing state
	iUut->Write(iWriteBuf1);
		
	//Unload the BCA while it is writing
	UnloadUut();
	
	iPeer->Shutdown();
	iPeer->WaitForShutdownL(KErrNone);
	
	UnloadPeer();		
	
	
	return EPass;
	
	}
	
/**
Shutdown the BCA while is writing
*/

TVerdict CWritingState2::RunTestStepL()
	{
	
	LoadUutL();	
	SetProxyIapIdL(*iUut, iUutIapId);	
	iUut->Open(iUutPortName);		
	iUut->WaitForOpenL(KErrNone);
	
	LoadPeerL();	
	SetProxyIapIdL(*iPeer, iPeerIapId);	
	iPeer->Open(iPeerPortName);		
	iPeer->WaitForOpenL(KErrNone);

	iUut->Write(iWriteBuf1);
	
	//shutdown the BCA while writing
	iUut->Shutdown();
	iUut->WaitForShutdownL(KErrNone);
	
	iPeer->Shutdown();
	iPeer->WaitForShutdownL(KErrNone);
	
	UnloadUut();
	UnloadPeer();
	
	return EPass;	
	
	}

/**
Close the BCA while it is writing
*/

TVerdict CWritingState3::RunTestStepL()
	{
	
	LoadUutL();	
	SetProxyIapIdL(*iUut, iUutIapId);	
	iUut->Open(iUutPortName);		
	iUut->WaitForOpenL(KErrNone);
	
	LoadPeerL();	
	SetProxyIapIdL(*iPeer, iPeerIapId);	
	iPeer->Open(iPeerPortName);		
	iPeer->WaitForOpenL(KErrNone);

	iUut->Write(iWriteBuf1);
	
	//close the BCA while writing
	iUut->Close();
	
	iPeer->Shutdown();
	iPeer->WaitForShutdownL(KErrNone);
	
	UnloadUut();
	UnloadPeer();
	
	return EPass;	
	
	}


//
//READING/WRITING

/**
Successful data transfer between the 2 BCA's	
*/

TVerdict CReadingWritingState1::RunTestStepL()
	{
	
	
	LoadUutL();	
	SetProxyIapIdL(*iUut, iUutIapId);	
	iUut->Open(iUutPortName);		
	iUut->WaitForOpenL(KErrNone);
	
	LoadPeerL();	
	SetProxyIapIdL(*iPeer, iPeerIapId);	
	iPeer->Open(iPeerPortName);		
	iPeer->WaitForOpenL(KErrNone);
		
	//Uut Read and Write
	iReadBuf1.Zero();
	iUut->Read(iReadBuf1);
	iUut->Write(iWriteBuf1);
				
	//Peer Read and Write
	iReadBuf2.Zero();
	iPeer->Read(iReadBuf2);
	iPeer->Write(iWriteBuf2);
	
	//Check 1st exchange
	iUut->WaitForReadL(KErrNone);
	iPeer->WaitForWriteL(KErrNone);
	
	
	//Check 2nd exchange
	iUut->WaitForWriteL(KErrNone);
	iPeer->WaitForReadL(KErrNone);
	
	
	CheckBuffersEqualL(iReadBuf1, iWriteBuf2);
	CheckBuffersEqualL(iReadBuf2, iWriteBuf1);
	
	iUut->Shutdown();
	iUut->WaitForShutdownL(KErrNone);
	
	iPeer->Shutdown();
	iPeer->WaitForShutdownL(KErrNone);
	
	UnloadUut();
	UnloadPeer();
	
	
	return EPass;
	}


/**
Test various operations while the BCA is reading and writing	
*/

TVerdict CReadingWritingState2::RunTestStepL()
	{	
	
	LoadUutL();	
	SetProxyIapIdL(*iUut, iUutIapId);	
	iUut->Open(iUutPortName);		
	iUut->WaitForOpenL(KErrNone);
	
	LoadPeerL();	
	SetProxyIapIdL(*iPeer, iPeerIapId);	
	iPeer->Open(iPeerPortName);		
	iPeer->WaitForOpenL(KErrNone);
	
	// BCA read and write
	iReadBuf1.Zero();
	iUut->Write(iWriteBuf1);
	iUut->Read(iReadBuf1);
	
	// Cancelwrite
	iUut->CancelWrite();
	
	// Start another write to get back to Read/Write State
	iUut->Write(iWriteBuf1);
		 
	// CancelRead	 
	iUut->CancelRead();
	
	// Start another Read to get back to Read/Write state
	iUut->Read(iReadBuf1);
	
	// Close the BCA while it is in Read/Write state			
	iUut->Close();
	
	iPeer->Shutdown();
	iPeer->WaitForShutdownL(KErrNone);
	
	UnloadUut();
	UnloadPeer();	
	
	return EPass;
	
	}

/**
Shutdown the BCA while it is in Read/Write state
*/

TVerdict CReadingWritingState3::RunTestStepL()
	{	
	
	LoadUutL();	
	SetProxyIapIdL(*iUut, iUutIapId);	
	iUut->Open(iUutPortName);		
	iUut->WaitForOpenL(KErrNone);
	
	LoadPeerL();	
	SetProxyIapIdL(*iPeer, iPeerIapId);	
	iPeer->Open(iPeerPortName);		
	iPeer->WaitForOpenL(KErrNone);
	
	//BCA Read and Write
	iReadBuf1.Zero();
	iUut->Read(iReadBuf1);
	iUut->Write(iWriteBuf1);
	
	//Shutdown the BCA while it is in Reading/Wrting state
	iUut->Shutdown();
	iUut->WaitForShutdownL(KErrNone);
	
	iPeer->Shutdown();
	iPeer->WaitForShutdownL(KErrNone);
	
	UnloadUut();
	UnloadPeer();	
	
	
	return EPass;	
	
	}

/**
Unload the BCA while it is Read/Write state	
*/

TVerdict CReadingWritingState4::RunTestStepL()
	{
	
	LoadUutL();	
	SetProxyIapIdL(*iUut, iUutIapId);	
	iUut->Open(iUutPortName);		
	iUut->WaitForOpenL(KErrNone);
	
	LoadPeerL();	
	SetProxyIapIdL(*iPeer, iPeerIapId);	
	iPeer->Open(iPeerPortName);		
	iPeer->WaitForOpenL(KErrNone);
	
	//BCA Read and Write
	iReadBuf1.Zero();
	iUut->Read(iReadBuf1);
	iUut->Write(iWriteBuf1);
	
	// Unload the BCA while it is Read/Write state
	UnloadUut();
	UnloadPeer();	
	
	return EPass;
	
	
	}






//
//IOCLTING STATE

/**
Unload the BCA while is performing IOClt 
*/

TVerdict CIoctlingState1::RunTestStepL()
	{
	
	LoadUutL();		
	
	//Setup IAP ID via IOClt
	TPckgBuf<TUint32> commDbIapIdPckg(iUutIapId);
	iUut->Ioctl(KBcaOptLevelGeneric, KBCASetIapId, commDbIapIdPckg);	
	
	// do not wait for IOClt to complete
	
	// Unload the BCA while it is IOCltling
	UnloadUut();
	
	return EPass;
	
	}


/**
CancelIoctl and shutdown while in IOClt state
*/


TVerdict CIoctlingState2::RunTestStepL()
	{
	
	LoadUutL();		
	
	//Setup IAP ID via IOClt
	TPckgBuf<TUint32> commDbIapIdPckg(iUutIapId);
	iUut->Ioctl(KBcaOptLevelGeneric, KBCASetIapId, commDbIapIdPckg);	
	
	// Do not wait for the IOClt to complete
	
	// Cancel the IOCtl 
	// This step is will not pass unless IOClt is asynchronous, refer to Test Spec
	// BCA IOClt api is synchronous - cancel does not work  
	iUut->CancelIoctl(); 	
	iUut->WaitForIoctlL(KErrNone);	
	
	// Start another one to get back into IOCtling state
	iUut->Ioctl(KBcaOptLevelGeneric, KBCASetIapId, commDbIapIdPckg);
	iUut->WaitForIoctlL(KErrNone);
	
	// Shutdown the BCA while it is IOClting state
	iUut->Shutdown();
	iUut->WaitForShutdownL(KErrNone);
	

	UnloadUut();
	
	return EPass;
	
	}
	
	

//



/**
Creates a new BCA Factory using the provided DLL.

@param aBcaDll The host BCA DLL
@return the BCA factory object
@leave if the factory object could not be created 
*/
MBcaFactory* CxxBcaTestBase::NewBcaFactoryL(TDllAutoClose& aBcaDll)
	{
	static const int KNewBcaFactoryProcOrdinal(1);
	TNewBcaFactoryProcL newBcaFactoryProcL = 
		(TNewBcaFactoryProcL)aBcaDll.iObj.Lookup(KNewBcaFactoryProcOrdinal);
	if(!newBcaFactoryProcL) // can't use User::LeaveIfNull, because it returns KErrNoMemory
		{
		ERR_PRINTF1(_L("Failed to located NewBcaFactoryL entry point."));	
		User::Leave(KErrBadLibraryEntryPoint);
		}
		
	MBcaFactory* bcaFactory = NULL; 
	TRAPD(err, bcaFactory = newBcaFactoryProcL());
	if(KErrNone != err)
		{
		ERR_PRINTF2(_L("NewBcaFactoryL left with[%d]."), err);	
		User::Leave(KErrCompletion);
		}
		
	return bcaFactory;
	}
	
/**
Creates an instance of BCA and Leaves

@param aBcaDll the BCA host Dll.
@leave always with KErrNonSystemErrCode
*/	
void CxxBcaTestBase::CreateBcaAndLeaveL(TDllAutoClose& aBcaDll)
	{
	MBcaFactory* bcaFactory = NewBcaFactoryL(aBcaDll);
	CleanupReleasePushL(*bcaFactory);
	MBca* bca = bcaFactory->NewBcaL();
	CleanupReleasePushL(*bca);
	User::Leave(KNonSystemErrCode);	
	}
	
	

/**
Tests the Release & Cleanup Stack functionality of the MBcaFactory
@panic on Heap checks when the test fails.
*/
TVerdict CCleanupBcaRelease::RunTestStepL()
	{
	_LIT(KxxBcaDllName, "C32Bca");
	TDllAutoClose bcaDll;	
	LogAndLeaveIfErrorL(bcaDll.iObj.Load(KxxBcaDllName), _L("Loading BCA Library"));
	
	__UHEAP_MARK;	
	TRAPD(err, CreateBcaAndLeaveL(bcaDll));
	__UHEAP_MARKEND; 
	
	INFO_PRINTF3(_L("CreateBcaAndLeave left with [%d]. Expected error[%d]."), err, KNonSystemErrCode);
	if(KNonSystemErrCode != err)// sanity check
		{
		return EInconclusive;
		}
	return EPass;
	}