telephonyserverplugins/multimodetsy/test/Te_LoopBack/Te_LoopBackATIO.CPP
changeset 0 3553901f7fa8
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/telephonyserverplugins/multimodetsy/test/Te_LoopBack/Te_LoopBackATIO.CPP	Tue Feb 02 01:41:59 2010 +0200
@@ -0,0 +1,692 @@
+// Copyright (c) 1997-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 file defines classes to handle serial port input/output and implement 
+// the "expect string" handling.  These "expect strings" are strings 
+// that are expected to be received on the serial line with the 
+// relevant callbacks.  This is a portion of code that has been reused
+// from the GSM TSY.  In this component, it is a bit like taking a 
+// sledgehammer to crack a nut, but it does do the job. 
+// 
+//
+
+/**
+ @file
+ @note  There are mulitple classes implemented in this file.
+ @note  These classes are CCompletionEntry and CATIO
+*/
+
+#include "Te_LoopBackATIO.H"
+#include "Te_LoopBackATBASE.H"
+#include "Te_LoopBackSLOGGER.H"
+
+CCompletionEntry* CCompletionEntry::NewL(CCommChatString* aCs,	CATBase* aAtCommand)
+/**
+ * This method creates an instance of CCompletionEntry.
+ *
+ * @param aCS: pointer to expected string response from the GSM TSY.
+ * @param aAtCommand: pointer to the script engine processing the line of script.
+ * @leave Leaves if out-of-memory.
+ * @return pointer to the instance of "CCompletionEntry".
+ */
+	{
+	return new(ELeave) CCompletionEntry(aCs,aAtCommand);
+	}
+
+CCompletionEntry::CCompletionEntry(CCommChatString* aCs, CATBase* aAtCommand) : iCs(aCs), iAtCommand(aAtCommand)
+/**
+ * This method is the constructor for CCompletionEntry.
+ *
+ * @param aCS: pointer to expected string response from the GSM TSY.
+ * @param aAtCommand: pointer to the script engine processing the line of script.
+ * @note Initializes private data "iCs" and "iAtCommand" to received parameters.
+ */
+	{}
+
+CCompletionEntry::~CCompletionEntry()
+/**
+ * This method is the Destructor for CCompletionEntry.
+ */
+	{}
+
+//
+// CATIo
+//
+CATIO* CATIO::NewL(const TDesC& aCsy, const TDesC& aPort)
+/**
+ * 2 Phase Constructor
+ *
+ * This method creates an instance of CATIO.
+ *
+ * @param aCsy: reference to a DLL name of the CSY.
+ * @param aPort: reference to the port name.
+ * @leave Leaves if out-of-memory.
+ * @return pointer to the instance of "CATIO".
+ */
+	{
+	CATIO* atIo=new(ELeave) CATIO();
+	CleanupStack::PushL(atIo);
+	atIo->ConstructL(aCsy,aPort);
+	CleanupStack::Pop();
+	return atIo;
+	}
+
+CATIO::CATIO()
+/**
+ * This method is the constructor for CATIO.  Private data is initialized and 
+ * a new value for the byte offset into the class for member data iLink is retrieved.
+ */
+	{
+	__DECLARE_NAME(_S("CATIO"));
+	iExpectList.SetOffset(_FOFF(CCompletionEntry,iLink));
+	iReadPending=EFalse;
+	iWritePending=EFalse;
+	iWaitTimerPending=EFalse;
+	}
+
+void CATIO::ConstructL(const TDesC& aCsy, const TDesC& aPort)
+/**
+ * This method is used to implement the 2 Phase Constructor for CATIO.
+ * This method sets up new iCommReader and iCommWriter data for CATIO.
+ * It also sets up a new iChat for and creates the buffer for iChat.
+ * The Comm port indicated by the DLL and port name is then opened with 
+ * as a shared resource.
+ *
+ * @param   aCsy:  reference to a DLL name of the CSY.
+ * @param   aPort: reference to the port name.
+ * @leave  Leaves if comm port can not be opened or if out-of-memory when creating other objects.
+ * @return	pointer to the instance of "CATIO".
+ */
+	{
+	CommConstructL(KCommReadPriority,KCommWritePriority);
+	iChat = new (ELeave) CCommChatter(this, KChatterPriority);
+	iChat->CreateL(KChatBufferSize);
+ 	User::LeaveIfError(CommOpen(aCsy, aPort, ECommShared));
+	iChatStringFound= new(ELeave) CArrayFixFlat<CCommChatString*>(5);
+	}
+
+CATIO::~CATIO()
+/**
+ * This method is used to delete the instantion of CATIO.  This method 
+ * initiates the removal of the intantiations of iChatStringFound and iChat 
+ * that were created for this CATIO. 
+ *
+ * @param   None.
+ * @return	None.
+ * @note	None.
+ */
+	{
+	delete iChatStringFound;
+	delete iChat;
+	}
+
+TInt CATIO::ConfigurePort(TCommConfig aConfiguration)
+/**
+ * This method is used to update the comm port configuration with data received 
+ * from the input parameter.
+ *
+ * @param   aConfiguration: reference to port configuration data.
+ * @return	error value for attempt to configure port.
+ */
+	{
+	TInt ret;
+	TCommConfig cbuf;
+	TCommConfigV01 &cfg=cbuf();
+	iCommPort.Config(cbuf);				// Get the Configuration
+
+	// overwrite port configuration with input configuration
+	TCommConfigV01 &newCfg=aConfiguration();
+	cfg.iRate=newCfg.iRate;
+	cfg.iDataBits=newCfg.iDataBits;
+	cfg.iStopBits=newCfg.iStopBits;
+	cfg.iParity=newCfg.iParity;
+	cfg.iHandshake=newCfg.iHandshake;
+	ret = iCommPort.SetConfig(cbuf);		// Set the Configuration
+	if(ret!=KErrNone)
+		{
+		LOGTEXT2(_L8("CATIO:\tError %d configuring port"),ret);
+		return ret;
+		}
+	return KErrNone;
+	}
+
+TInt CATIO::Start(CATBase* aCompletionClass)
+/**
+ * This method is used to make sure the comm port is ready and a read is outstanding on 
+ * the comm port.  This is done by making sure the comm port is initialized for both read 
+ * and write capabilities.  After the comm port is initialized for read and write, a read
+ * is posted to the comm port to have a read outstanding for CATIO.
+ *
+ * @param   aCompletionClass: pointer to a CATBase class indicating port and data.
+ * @return	error value for attempt to read port.
+ */
+	{
+	iControllingClass=aCompletionClass;
+	CommReadReady();
+	LOGTEXT(_S8("CATIO::Start() - ReadReady Completed"));
+	CommWriteReady();
+	LOGTEXT(_S8("CATIO::Start() - WriteReady Completed"));
+	return Read();
+	}
+
+void CATIO::GetExcessData(TDes8& aBuffer)
+/**
+ * This function is currently not used by the Etel regression test harness.
+ */
+	{
+	TPtrC8 des(iRxBuf.Ptr()+iRxBufOffset, iRxBuf.Length()-iRxBufOffset);
+	aBuffer.Copy(des);
+	}
+
+void CATIO::MarkRxBuffer(TInputBufferMark& aBufferMarker)
+/**
+ * Set markers for last character received from the GSM TSY.
+ *
+ * @param   aBufferMark: reference to markers in buffer for last character received from comm port.
+ * @return	None.
+ */
+	{
+	iChat->GetChatBufferMarker(aBufferMarker);
+	}
+
+TPtrC8 CATIO::GetRxBufferLC(TInputBufferMark& aBufferMarker)
+/**
+ * This function is currently not used by the Etel regression test harness.
+ *
+ * @note: This function is designed to return a descriptor for the buffer between the
+ *        marker passed as a parameter and the current append marker.
+ */
+	{
+	return iChat->GetChatBufferLC(aBufferMarker);
+	}
+
+void CATIO::CommReadComplete(TInt aStatus)
+/**
+ * This method is invoked by the RunL of the active object to complete a read.
+ * When read complete is for KErrCommsLineFail, then a check will be made to make sure 
+ * there have been 2 KErrCommsLineFail's in succession before signaling the line error.
+ * When no errors or 1st KErrCommsLineFail, call ProcessReadCharsL to process the 
+ * characters read from the comm port.  If an error occurs processing the comm port
+ * read buffer characters, the ProcessReadCharsL method will leave and will be trapped
+ * in this function and the call is canceled.
+ *
+ * @param   aStatus: status from server indicating why read completed.
+ * @return	None.
+ */
+	{
+	LOGTEXT(_S8("CATIO Read Completion"));
+	__ASSERT_ALWAYS(iReadPending,HayesPanic(EATCommand_IllegalCompletionReadNotExpected));
+//	if(!iReadPending)
+  //
+	//	{
+	//	SignalCommandsWithError(KErrIllegalReadComplete);
+	//	return;
+	//	}
+	if (aStatus==KErrCommsLineFail)
+		{
+		if (iSecondChanceForCommsError++!=1)	
+			aStatus=KErrNone;		// only signal error if get 2 KErrCommsLineFail's in succession
+		else
+			iSecondChanceForCommsError=0;
+		}
+	if (aStatus!=KErrNone)
+		{
+		SignalCommandsWithError(aStatus);
+		return;
+		}
+	iReadPending = EFalse;
+	TRAPD(ret,ProcessReadCharsL());
+	if(ret!=KErrNone)
+		{
+		Cancel();	// This error cannot be related to a command - so they'll all be cleaned up.
+		iChat->DeleteAllAndStop();
+		}
+	}
+
+void CATIO::SignalCommandsWithError(TInt aStatus)
+//
+//	Complete all current AT commands with the error and call the error handler
+//
+/**
+ * This method is invoked when an error is detected.  All current strings with the
+ * error are removed and iControllingClass->GenericEventSignal method is called to
+ * signal EReadCompletion.
+ *
+ * @param   aStatus: status indicating error of the read.
+ * @return	None.
+ */
+	{	
+	LOGTEXT2(_L8("Received an error of %d"),aStatus);
+	Cancel();
+	CCompletionEntry* ce;
+	TDblQueIter<CCompletionEntry> iter(iExpectList);
+	while (ce = iter, ce!=NULL)
+		{
+		ce->iAtCommand->GenericEventSignal(EReadCompletion,aStatus);
+		iter.SetToLast();
+		CCompletionEntry* removeSimilar;
+		while (removeSimilar=iter--, removeSimilar!=ce)
+			{
+			if(removeSimilar->iAtCommand==ce->iAtCommand)
+				{
+				iChat->RemoveString(removeSimilar->iCs);
+				delete removeSimilar->iCs;
+				removeSimilar->iLink.Deque();
+				delete removeSimilar;
+				}
+			}
+		iChat->RemoveString(ce->iCs);
+		delete ce->iCs;
+		ce->iLink.Deque();
+		delete ce;
+		iter.SetToFirst();
+		}
+	if(iControllingClass!=NULL)
+		iControllingClass->GenericEventSignal(EReadCompletion,aStatus);
+	}
+
+void CATIO::ProcessReadCharsL()
+/**
+ * This method processes the characters read from the comm port. It uses 
+ * these characters to lookup any string from the script to complete.
+ * If the string to complete is not found, this method will leave.
+ * If the string to complete is found, a read complete is signaled and 
+ * another read is queued.  
+ * 
+ * @leave Leaves if string to complete is not found in the expected list.
+ */
+	{
+	LOGTEXT3(_L8("Rx:\t(%d) %S"),iRxBuf.Length(),&iRxBuf);
+	LOGTEXTREL2(_L8("Rx:\t%S"),&iRxBuf);
+
+	TBool hitFlag=EFalse;
+	TInt len;
+
+	for (iRxBufOffset=0; iRxBufOffset<iRxBuf.Length(); iRxBufOffset++)
+		{
+		iChat->AddCharL(iRxBuf[iRxBufOffset]);
+// Check for hits and one up-call per hit NOW
+		if((len=iChatStringFound->Count())>0)
+			{
+			for(TInt i=0;i<len;i++)
+				{
+				hitFlag=ETrue;
+// Find the string to complete
+				CCompletionEntry* ce;
+				TDblQueIter<CCompletionEntry> iter(iExpectList);
+				TBool aFoundFlag=EFalse;
+				while (ce = iter++, ce!=NULL)
+					{
+					if(ce->iCs==iChatStringFound->At(i))
+						{
+						iCurrentFoundChatString=ce->iCs;
+						ce->iAtCommand->GenericEventSignal(EReadCompletion,KErrNone);
+						aFoundFlag=ETrue;
+						break;
+						}
+					}
+				if(!aFoundFlag)
+					{
+					LOGTEXT(_S8("CATIO Internal Error - Chat String signalled, but not found"));
+					User::Leave(KErrGeneral);
+					}
+				}
+			iChatStringFound->Delete(0,iChatStringFound->Count());
+			}
+		}
+	if(hitFlag)
+		{
+		//iReadPending=EFalse;		  
+		Read();							// Queue Another...
+		}
+	else
+		{
+		iReadPending = ETrue;
+		CommReadOneOrMore(iRxBuf);
+		}
+	}
+
+CCommChatString* CATIO::FoundChatString()
+/**
+ * This returns a pointer to the string from the script to complete.
+ * 
+ * @param   None.
+ * @return	pointer to CComChatString containing string to complete..
+ */
+	{
+	return iCurrentFoundChatString;
+	}
+
+CCommChatString* CATIO::AddExpectString(CATBase* aATBase, const TDesC8& aString)
+/**
+ * This method is used to instantiate a CCompletionEntry object with a
+ * CCommChatString object containing the expected string to complete the
+ * string from the GSM TSY.  This CCompletionEntry is then added to 
+ * the end of the expected list of strings from the GSM TSY.
+ *
+ * @param aATBase: pointer to the script engine processing the line of script.
+ * @param aString: reference to the expected string for aATBase to be returned from the GSM TSY.
+ * @return pointer to the chat string used in the instatiated CCompletionEntry.
+ */
+	{
+	CCommChatString* cs=iChat->AddString(aString);
+	CCompletionEntry* completionEntry=NULL;
+	TRAP_IGNORE(completionEntry=CCompletionEntry::NewL(cs,aATBase));		// TRAP but ignore error
+	if(completionEntry)
+		iExpectList.AddLast(*completionEntry);
+	return cs;
+	}
+
+void CATIO::RemoveExpectString(CCommChatString* aExpectString)
+/**
+ * This method uses the CCommChatString input parameter to remove a single 
+ * CCompletionEntry from the list of expected completion strings.
+ *
+ * @param aExpectString: reference to the string in the list of expected string returned from the GSM TSY.
+ */
+	{
+// Find the AT Command to complete
+	CCompletionEntry* ce;
+	TDblQueIter<CCompletionEntry> iter(iExpectList);
+	while (ce = iter++, ce!=NULL)
+		{
+		if(ce->iCs==aExpectString)
+			{
+			iChat->RemoveString(ce->iCs);
+			delete ce->iCs;
+			ce->iLink.Deque();
+			delete ce;
+			break;
+			}
+		}
+	}
+
+void CATIO::RemoveExpectStrings(CATBase* aATBase)
+/**
+ * This method uses the CATBase input parameter to remove all of the 
+ * CCompletionEntry(s) that have the same CATBase-derived callback class
+ * from the list of expected completion strings.
+ *
+ * @param aTBase: reference to the string in the list of expected string returned from the GSM TSY.
+ */
+	{
+// Find the AT Command to complete
+	CCompletionEntry* ce;
+	TDblQueIter<CCompletionEntry> iter(iExpectList);
+	while (ce = iter++, ce!=NULL)
+		{
+		if(ce->iAtCommand==aATBase)
+			{
+			iChat->RemoveString(ce->iCs);
+			delete ce->iCs;
+			ce->iLink.Deque();
+			delete ce;
+			}
+		}
+	}
+
+void CATIO::CommWriteComplete(TInt aStatus)
+/**
+ * This method is used to indicate a write to the comm port has completed.
+ * The timer is stopped and if a write is NOT pending, then PANIC.
+ * Set the write pending flag to EFalse and signal the write completion event 
+ * with the status from the input parameter.
+ * 
+ * @param aStatus: status indicating reason for write complete.
+ */
+	{
+	LOGTEXT(_S8("CATIO Comm Write Completion"));
+	iChat->StopTimer();
+	__ASSERT_ALWAYS(iWritePending,HayesPanic(EATCommand_IllegalCompletionWriteNotExpected));
+	iWritePending=EFalse;
+	iWriteCommand->GenericEventSignal(EWriteCompletion,aStatus);
+	}
+
+void CATIO::ChatStringMatchL(CCommChatString* aCs)
+/**
+ * This method is used to append the input string onto a list of found strings.
+ * 
+ * @param aCs: pointer to the chat string matched.
+ * @leave Leaves if can not place string on end of found string list.
+ */
+	{
+	LOGTEXT(_S8("CATIO Found Match."));
+	iStringFound=ETrue;
+	iChatStringFound->AppendL(aCs);
+	}
+
+void CATIO::ChatTimeout()
+/**
+ * This method is used to indicate a chat time-out has completed.
+ * If a timer is NOT pending, then PANIC.  When the timer is pending, 
+ * set the timer pending flag to EFalse and signal the timeout completion event.
+ */
+	{
+	LOGTEXT(_S8("CATIO Chat Time-out Completion"));
+	if(iWaitTimerPending)
+		{
+		iWaitTimerPending=EFalse;
+		iTimeOutCommand->GenericEventSignal(ETimeOutCompletion,KErrNone);
+		}
+	else
+		HayesPanic(EATCommand_IllegalWaitCompletion);
+	}
+
+void CATIO::SetTimeOut(CATBase* aCompletionClass, TUint aTimePeriodMillisec)
+/*
+ * This method starts the timer with the command in the input aCompletionClass
+ * for the input specified period.  The indicater for timer pending is set to ETrue.
+ *
+ * @param aCompletionClass: pointer to object containing the time-out command.
+ * @param aTimePeriodMillisec: time-out period in milliseconds.
+ */
+	{
+	iTimeOutCommand=aCompletionClass;
+	iChat->StartTimer(aTimePeriodMillisec*1000);
+	iWaitTimerPending=ETrue;
+	}
+
+TInt CATIO::Read()
+/*
+ * This method attempts to read from the comm port only if there is currently 
+ * not a read pending.  If a read is pending, this method simply returns without
+ * attempting a read.  If no read is pending, this routing attempts to read as 
+ * much data as is ready up to the maximum length specified in the descriptor, iRxBuf.
+ * The data is read into the iRxBuf.
+ */
+ 	{
+	if(iReadPending==EFalse)
+		{
+ 		iReadPending=ETrue;
+		iStringFound=EFalse;
+		CommReadOneOrMore(iRxBuf);
+		iRxBufOffset = 0;
+		LOGTEXT(_S8("CATIO Queued a Read"));
+		}
+	return KErrNone;
+	}
+
+TInt CATIO::Write(CATBase* aCompletionClass, const TDesC8& aString)
+/*
+ * This method attempts to write the input data into comm port using the 
+ * write command in the input aCompletionClass.
+ *
+ * @param aCompletionClass: pointer to object containing function to call when the write completes.
+ * @param aString, a descriptor reference containing the data to be written to the port.
+ */
+	{
+	iWriteCommand=aCompletionClass;
+	iWritePending=ETrue;
+	CommWrite(aString);
+	LOGTEXT2(_L8("Tx:\t%S"),&aString);
+	LOGTEXTREL2(_L8("Tx:\t%S"),&aString);
+	LOGTEXT(_S8("CATIO Queued a Transmission"));
+	return KErrNone;
+	}
+
+TBool CATIO::RWPending()
+/*
+ * This method returns to the caller a boolean indicating True when 
+ * either a Write is Pending  OR  a ReadPending is pending.
+ *
+ * @return Boolean indicating either a Write is Pending OR a Read is Pending.
+ */
+	{
+	return (iWritePending)||(iReadPending);
+	}
+
+TBool CATIO::ReadPending()
+/*
+ * This method returns to the caller a boolean indicating True when 
+ * a ReadPending is pending.
+ *
+ * @return Boolean indicating if a Read is Pending.
+ */
+	{
+	return iReadPending;
+	}
+
+void CATIO::Disconnect()
+/**
+ * This function is currently not used by the Etel regression test harness.
+ */
+	{
+	TCommConfig cbuf;
+	TCommConfigV01 &cfg=cbuf();
+	iCommPort.Config(cbuf);
+	cfg.iHandshake = KConfigFreeRTS	| KConfigFreeDTR;
+	iCommPort.SetConfig(cbuf);
+	iCommPort.SetSignalsToSpace(KSignalRTS | KSignalDTR);
+	CommClose();
+	}
+
+void CATIO::Cancel()
+/**
+ * This function is currently not used by the Etel regression test harness.
+ */
+	{
+	LOGTEXT(_S8("CATIO CATIO:\tCancel called"));
+	CommCancel();
+	iReadPending = EFalse;
+	iWritePending = EFalse;
+	iChat->StopTimer();
+	}
+
+void CATIO::WriteAndTimerCancel(CATBase* aATBase)
+/**
+ * This method is used by the caller to either cancel a write command or stop a timer.
+ * The action to be taken is determined by the command type received as a parameter.
+ *
+ * @param aATBase: pointer to the command type to be processed.
+ */
+	{
+	if (aATBase==iWriteCommand)
+		{
+		CommWriteCancel();
+		}
+	if (aATBase==iTimeOutCommand)
+		{
+		iChat->StopTimer();
+		}
+	}
+
+void CATIO::WriteAndTimerCancelAll()
+/**
+ * This function is currently not used by the Etel regression test harness.
+ */
+	{
+	CommWriteCancel();
+	iChat->StopTimer();
+	}
+
+void CATIO::DropDtr()
+/**
+ * This function is currently not used by the Etel regression test harness.
+ */
+	{
+	LOGTEXT(_S8("CATIO Dropping DTR"));
+	iCommPort.SetSignals(0,KSignalDTR);
+	}
+
+void CATIO::RaiseDTR()
+/**
+ * This function is currently not used by the Etel regression test harness.
+ */
+	{
+	LOGTEXT(_S8("CATIO Raising DTR"));
+	iCommPort.SetSignals(KSignalDTR,0);
+	}
+
+void CATIO::ResetReadAndWriteBuffers()
+/**
+ * This function is currently not used by the Etel regression test harness.
+ */
+	{
+	iCommPort.ResetBuffers();
+	}
+
+TInt CATIO::GetSizeOfRxBuffer()
+/**
+ * This function is currently not used by the Etel regression test harness.
+ */
+	{
+	return iCommPort.QueryReceiveBuffer();
+	}
+
+TUint CATIO::Signals()
+/**
+ * This function is currently not used by the Etel regression test harness.
+ */
+	{
+	return iCommPort.Signals();
+	}
+
+void CATIO::DropRTS()
+/**
+ * This function is currently not used by the Etel regression test harness.
+ */
+	{
+	LOGTEXT(_S8("CATIO Dropping RTS"));
+	iCommPort.SetSignals(0,KSignalRTS);
+	}
+
+void CATIO::RaiseRTS()
+/**
+ * This function is currently not used by the Etel regression test harness.
+ */
+	{
+	LOGTEXT(_S8("CATIO Raising RTS"));
+	iCommPort.SetSignals(KSignalRTS,0);
+	}
+
+void CATIO::SignalMark (TUint aSignal)
+/**
+ * This method is used by the caller on the emulator side to assert signals.
+ *
+ * @param aSignal: integer indicating the signal to assert.
+ */
+	{
+	LOGTEXT2(_L8("CATIO CATIO::SignalSet(%x)"),aSignal); 
+	iCommPort.SetSignalsToMark(aSignal);
+	}
+
+void CATIO::SignalSpace (TUint aSignal)
+/**
+ * This method is used by the caller on the emulator side to deassert signals.
+ *
+ * @param aSignal: integer indicating the signal to deassert.
+ */
+	{
+	LOGTEXT2(_L8("CATIO CATIO::SignalClear(%x)"),aSignal);
+	iCommPort.SetSignalsToSpace (aSignal);
+	}