cbsref/csyrefplugins/csy27010/src/PortC32InterfaceBase.cpp
author hgs
Tue, 22 Jun 2010 11:02:32 +0100
changeset 44 8b72faa1200f
permissions -rw-r--r--
201024_02

//
// * Copyright 2004 Neusoft America Inc.
// * All rights reserved.
// * This component and the accompanying materials are made available
// * under the terms of the Eclipse Public License v1.0
// * which accompanies this distribution, and is available
// * at the URL "http://www.eclipse.org/legal/epl-v10.html".
// *
// * Contributors:
// * Keith Collins (Neusoft America Inc.)  original software development and additional code and modifications.
// * Thomas Gahagen (Neusoft America Inc.)  additional code and modifications.
// * Zhen Yuan (Neusoft America Inc.)  additional code and modifications.
// *
// * Description:  This file contains the implementation for the CPortC32Interface class.
// *               This class contains methods which are invoked by C32 when the
// *               associated client RComm public API is invoked. These methods
// *               are used to create, configure, read, write, and close logical
// *               serial ports. Instances of this class are created by the CSY's
// *               Port Factory.
//

/** @file PortC32InterfaceBase.cpp
 * This file contains the implementation for the CPortC32InterfaceBase class.
 * This base class contains methods which are invoked by C32 when the
 * associated client RComm public API is invoked. These methods
 * are used to create, configure, read, write, and close logical
 * serial ports. Instances of this class are created by the CSY's
 * Port Factory.
 */

#include <cdbcols.h>

#include "PortC32InterfaceBase.h"
#include "Portfactory.h"
#include "Mux0710Protocol.h"
#include "CsyMsgBufBPFrame.h"
#include "ChannelMgrCmdData.h"
#include "CommFrameReaderAo.h"
#include "CsyDebugLogger.h"

CPortC32InterfaceBase::CPortC32InterfaceBase(CPortFactory& aPortFactory,
									 CPortFactory::TC32PortInfo& aPortInfo)
/**
 * Constructor.
 *
 * @param aPortFactory - Reference to the port factory
 * @param aPortInfo - Reference to the port information
 */
 : CPort(),
 	iFramesWaitingToBeReadList(_FOFF(CCsyMsgBufBpFrame, iMsgLink)),
    iFramesWaitingToBeReadIter(iFramesWaitingToBeReadList),
    iRole(ECommRoleDTE),
	iPortFactory(aPortFactory),
	iPortInfo(aPortInfo)
	{}

void CPortC32InterfaceBase::ConstructL()
/**
 * Base construction for channels
 */
	{
	_LOG_L4C1("CPortC32InterfaceBase::ConstructL");

	// create active objects to handle events
	iConfig.iTerminatorCount = 0;
	}

CPortC32InterfaceBase::~CPortC32InterfaceBase()
/**
 * Destructor.
 */
	{
	_LOG_L4C1(">>CPortC32InterfaceBase::~CPortC32InterfaceBase");

	// remove all frames from queue and delete
	RemoveWaitingAllFrames(EFalse);

	if (iMuxChannel)
		iMuxChannel->Close(this);

	_LOG_L4C1("<<CPortC32InterfaceBase::~CPortC32InterfaceBase");
	}

void CPortC32InterfaceBase::RemoveWaitingAllFrames(TBool aAddToFreeList)
/**
 * 
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::RemoveWaitingAllFrames [aAddToFreeList=%d]",
		aAddToFreeList);

	CCsyMsgBufBpFrame* frame = NULL;
	iFramesWaitingToBeReadIter.SetToFirst();
	while ((frame = iFramesWaitingToBeReadIter++) != NULL)
		{
		iFramesWaitingToBeReadList.Remove(*frame);
		if (aAddToFreeList)
			iPortFactory.GetMux0710Protocol()->AddFrameFreeQ(frame);
		else
			delete frame;
		}
	}

/********************************************************************************/
/*                       Start of methods from CPort                            */
/********************************************************************************/

void CPortC32InterfaceBase::NotifySignalChange(TUint aSignalMask)
/**
 * Called by C32 when the client requests NotifySignalChange.
 *
 * @param aSignal
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::NotifySignalChange [port=%d]", GetPortNumber());

	TUint reqSigs = aSignalMask & ~KSignalBreak;
	if (!reqSigs)
		{
		// User has only asked to be notified of break.
		SignalChangeCompleted(iSignals, KErrArgument);
		return;
		}
	iSignalMask |= reqSigs;

	iSignalChangeNotifyPending = ETrue;
	}		   

void CPortC32InterfaceBase::NotifySignalChangeCancel()
/**
 * Called by C32 when the client requests to cancel a NotifySignalChange 
 * request.
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::NotifySignalChangeCancel [port=%d]", GetPortNumber());

	iSignalMask &= (KSignalBreak);	// set mask to zero, excluding BREAK
	if (iSignalChangeNotifyPending)
		{
		iSignalChangeNotifyPending = EFalse;
		SignalChangeCompleted(iSignals, KErrCancel);
		}
	}

void CPortC32InterfaceBase::StartRead(const TAny* aClientBuffer, TInt aLength)
/**
 * This method is called by C32 to read data from the CSY in response to a 
 * read request by a client RComm object.
 *
 * @param aClientBuffer - Pointer to where to put the new data
 * @param aLength - Length of data to read
 */
	{
	_LOG_L4C1(" "); // please leave in this separator
	_LOG_L4C3(">>CPortC32InterfaceBase::StartRead [aLength=%d, port=%d] called by client",
			 aLength, GetPortNumber());

	if (iIsReadInProgress)
		{
		// Something has gone wrong - either the flag was not reset correctly
		// or C32 has lost track of a read
		// MAF __ASSERT_DEBUG(EFalse,PANIC(KPanicIllegalState));
		_LOG_L1C1("** Read waiting to complete already set **");
		}

	// Set the flag that there is a read request outstanding
	iIsReadInProgress = ETrue;

	if (aLength == 0)
		{
		_LOG_L3C1("<<CPortC32InterfaceBase::StartRead - Length of 0?");
		CompleteReadRequest(KErrArgument);
		return;
		}

	// save client info
	iClientBuffer = (TAny*) aClientBuffer;
	iPos = 0;

	if (aLength > 0)
		{
		_LOG_L3C1("Normal read");
		iClientLength = aLength;
		iOneOrMore = EFalse;
		}
	else
		{
		_LOG_L3C1("Read one or more");
		iClientLength = -aLength;
		iOneOrMore = ETrue;
		}

	if(!ReadFromBufOrQueue())
		{
		_LOG_L3C1("No data to be read - request is outstanding");
		}

	_LOG_L4C1("<<CPortC32InterfaceBase::StartRead");
	_LOG_L4C1(" "); // please leave in this separator
	}

void CPortC32InterfaceBase::StartWrite(const TAny* aClientBuffer, TInt aLength)
/**
 * This method is called by C32 to write data to the CSY in response to a 
 * write request by a client RComm object.
 *
 * @param aClientBuffer - Pointer to where to put the new data
 * @param aLength - Length of data to read
 */
	{
	_LOG_L4C1(" "); // please leave in this separator
	_LOG_L4C3(">>CPortC32InterfaceBase::StartWrite [aLength=%d, port=%d] called by client",
			 aLength, GetPortNumber());

	if (iIsWriteInProgress)
		{
		// Something has gone wrong - either the flag was not reset correctly
		// or C32 has lost track of a write
		// MAF __ASSERT_DEBUG(EFalse,PANIC(KPanicIllegalState));
		_LOG_L1C1("** Write already waiting to complete **");
		iIsWriteInProgress = EFalse;
		}

	iIsWriteInProgress = ETrue;

	if (aLength > 0)
		{
		// Get the outgoing message buffer for this dlc/port
		TDes8& buffer = iMuxChannel->RefToMsgBuffer();

		// zero the buffer
		buffer.Zero();

		// read data from client's address space
		TInt err = IPCRead(aClientBuffer, buffer); 
		if (err == KErrNone)
			{
			iMuxChannel->SetOwner(this);
			err = iMuxChannel->PlaceOnOutboundQueue();
			}
		else
			{
			_LOG_L1C2("** Read of client buffer failed [err=%d] **",err);
			}

		if (err)
			{
			CompleteWriteRequest(err);
			}
		}
	else
		{
		// no data to write is not an error, so just complete
		CompleteWriteRequest(KErrNone);
		}

	_LOG_L4C1("<<CPortC32InterfaceBase::StartWrite");
	_LOG_L4C1(" "); // please leave in this separator
	}

void CPortC32InterfaceBase::Destruct()
/**
 * Called by C32 in response to a client Close request.
 */
	{
	_LOG_L4C2(">>CPortC32InterfaceBase::Destruct [port=%d]", GetPortNumber());

	// C32 requires us to do this here.
	delete this;

	_LOG_L4C1("<<CPortC32InterfaceBase::Destruct()");
	}

TInt CPortC32InterfaceBase::SetConfig(const TDesC8& aConfiguration)
/**
 * Called by C32 in response to a client calling RComm::SetConfig().
 * This method is used by the client to tell the CSY what parameters
 * are needed to instantiate the lower-level driver.
 * Note that the CSY reads the config data from CommDb and bpcaps.ini
 * and does not need or want the client to overwrite the config
 * parameters.
 *
 * @param aConfiguration - Descriptor containing the config params
 * @return KErrNone
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::SetConfig [port=%d]",iPortInfo.iPortNumber);

    TCommConfigV01 c;

    Mem::FillZ(&c,sizeof(c));
	TInt len=Min(aConfiguration.Length(),sizeof(c));
	Mem::Copy(&c, aConfiguration.Ptr(),len);

	if(c.iTerminatorCount > KConfigMaxTerminators)
		{
		return KErrNotSupported;
		}
	else
		{
		for (TInt i=0; i < c.iTerminatorCount;i++)
			{
			_LOG_L4C2("Terminator: %d" ,c.iTerminator[i]);
			}
		}

	iConfig = c;
	//we will only use Terminators of this configure
	return KErrNone;
	}

void CPortC32InterfaceBase::ReadCancel()
/**
 * Called by C32 when the client requests to cancel a Read.
 */
	{
	_LOG_L4C2(">>CPortC32InterfaceBase::ReadCancel [port=%d]", GetPortNumber());

	iClientBuffer = NULL;
	iClientLength = 0;

	CompleteReadRequest(KErrCancel);

	_LOG_L4C1("<<CPortC32InterfaceBase::ReadCancel()");
	}

void CPortC32InterfaceBase::WriteCancel()
/**
 * Called by C32 when the client requests to cancel a write operation.
 * Empty the mux queue of a possible message that is destined for the 
 * baseband on the channel associated with this C32 port interface
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::WriteCancel [port=%d]", GetPortNumber());

	iMuxChannel->WriteCancel();

	CompleteWriteRequest(KErrCancel);
	}

/*****************************************************************************/
// Functions below here are the C32 pure virtuals which must be implemented  //
// by the CSY, but may not be supported by the CSY.                          //
/*****************************************************************************/

void CPortC32InterfaceBase::Break(TInt /*aTime*/)
/**
 * Called by C32.
 * Note that this method is not supported.
 *
 * @param aTime
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::Break [port=%d]", GetPortNumber());
	}

void CPortC32InterfaceBase::BreakCancel()
/**
 * Called by C32.
 * Note that this method is not supported.
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::BreakCancel [port=%d]", GetPortNumber());
	}

TInt CPortC32InterfaceBase::GetConfig(TDes8& /*aPackage*/) const
/**
 * Called by C32.
 * Note that this method is not supported.
 * @param aPackage - Reference to package
 * @return KErrNotSupported
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::GetConfig [port=%d]", GetPortNumber());
	return KErrNotSupported;
	}

TInt CPortC32InterfaceBase::SetServerConfig(const TDesC8& /*aPackage*/)
/**
 * Called by C32.
 * Note that this method is not supported.
 * @param aPackage - Reference to package
 * @return KErrNotSupported
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::SetServerConfig [port=%d]", GetPortNumber());
	return KErrNotSupported;
	}

TInt CPortC32InterfaceBase::GetServerConfig(TDes8& /*aPackage*/)
/**
 * Called by C32.
 * Note that this method is not supported.
 * @param aPackage - Reference to package
 * @return KErrNotSupported
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::GetServerConfig [port=%d]", GetPortNumber());
	return KErrNotSupported;
	}

TInt CPortC32InterfaceBase::GetCaps(TDes8& aPackage)
/**
 * Called by C32.
 * @param aPackage - Reference to package
 * @return KErrNone
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::GetCaps [port=%d]", GetPortNumber());

	// create a Package pointer
	TCommCaps* pckg = (TCommCaps*) &aPackage;

	// create a V01 reference
	TCommCapsV01& caps = (*pckg)();

	// fill in the capabilities
	caps.iRate       = KCapsBps19200 | KCapsBps115200;

	caps.iDataBits   = KCapsData8;
	caps.iStopBits   = KCapsStop1;
	caps.iParity     = KCapsParityNone;
	caps.iHandshake  = KCapsSignalCTSSupported |
		               KCapsSignalDSRSupported |
					   KCapsSignalDCDSupported |
					   KCapsSignalRTSSupported |
					   KCapsSignalDTRSupported;
	caps.iSignals    = KCapsObeyCTSSupported | KCapsObeyDSRSupported;
	caps.iFifo       = KCapsHasFifo;
	caps.iSIR        = KCapsSIR115kbps;

	// TCommCapsV02 support
	if (aPackage.Length()==sizeof(TCommCapsV02))
		{
		TCommCapsV02* commcaps = (TCommCapsV02*)(aPackage.Ptr());
		commcaps->iNotificationCaps = 
			KNotifyFlowControlChangeSupported |
			KNotifyDataAvailableSupported;
		commcaps->iFlowControlCaps = KCapsFlowControlStatusSupported;
		}

	return KErrNone;
	}

TInt CPortC32InterfaceBase::GetSignals(TUint& aSignals)
/**
 * get the status of the signal pins
 *
 * @param aSignals signals will be written to this descriptor
 * @return KErrNone always
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::GetSignals [port=%d]", GetPortNumber());
	aSignals = iSignals;
	return KErrNone;
	}

TInt CPortC32InterfaceBase::SetSignalsToMark(TUint aSignals)
/**
 * set selected signals to high (logical 1)
 *
 * @param aSignals bitmask with the signals to be set
 * @return KErrNone always
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::SetSignalsToMark [port=%d]", GetPortNumber());

	TInt ret = KErrNone;
	TUint alreadySent = iSentSignals & aSignals;
	if (alreadySent == aSignals)
		{
		_LOG_L4C1("Signals already set to high");
		}
	else
		{
		TUint temp = iSentSignals | aSignals;
		ret = SetV24Signals(temp);
		if (ret == KErrNone)
			{
			iSentSignals = temp;
			_LOG_L4C2("iSentSignals 0x%08x",iSentSignals);
			}
		}
	
	return ret;
	}

TInt CPortC32InterfaceBase::SetSignalsToSpace(TUint aSignals)
/**
 * set selected signals to low (logical 0)
 *
 * @param aSignals bitmask with the signals to be cleared
 * @return KErrNone always
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::SetSignalsToSpace [port=%d]", GetPortNumber());

	TInt ret = KErrNone;
	TUint change = iSentSignals & aSignals;
	if (change)
		{
		TUint temp = iSentSignals & ~aSignals;
		ret = SetV24Signals(temp);
		if (ret == KErrNone)
			{
			iSentSignals = temp;
			_LOG_L4C2("iSentSignals 0x%08x",iSentSignals);
			}
		}
	else
		{
		_LOG_L4C1("Signals already set to low");
		}
	
	return ret;
	}

TInt CPortC32InterfaceBase::GetReceiveBufferLength(TInt& aLength) const
/**
 * Called by C32.
 * @param aLength
 * @return KErrNone
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::GetReceiveBufferLength [port=%d]", GetPortNumber());

	aLength = KMaxIpPacketSize;
	return KErrNone;
	}

TInt CPortC32InterfaceBase::SetReceiveBufferLength(TInt /*aLength*/)
/**
 * Called by C32.
 * Note that this method is not supported.
 * @param aLength
 * @return KErrNotSupported
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::SetReceiveBufferLength [port=%d]", GetPortNumber());
	return KErrNotSupported;
	}

void CPortC32InterfaceBase::NotifyConfigChange()
/**
 * Called by C32.
 * Note that this method is not supported.
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::NotifyConfigChange [port=%d]", GetPortNumber());
 	}

void CPortC32InterfaceBase::NotifyDataAvailable()
/**
 * Called by C32.
 * Note that this method is not supported.
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::NotifyDataAvailable [port=%d]", GetPortNumber());

	iDataAvailableNotifyPending = ETrue;
	}

void CPortC32InterfaceBase::NotifyDataAvailableCancel()
/**
 * Called by C32.
 * Note that this method is not supported.
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::NotifyDataAvailableCancel [port=%d]", GetPortNumber());

	if (iDataAvailableNotifyPending)
		{
		iDataAvailableNotifyPending = EFalse;
		NotifyDataAvailableCompleted(KErrCancel);
		}
	}

void CPortC32InterfaceBase::NotifyConfigChangeCancel()
/**
 * Called by C32.
 * Note that this method is not supported.
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::NotifyConfigChangeCancel [port=%d]", GetPortNumber());
	}

void CPortC32InterfaceBase::NotifyFlowControlChange()
/**
 * Called by C32.
 * Note that this method is not supported.
 */
	{
	_LOG_L3C2("CPortC32InterfaceBase::NotifyFlowControlChange [port=%d]", GetPortNumber());

	iFlowControlNotifyPending = ETrue;
	}

void CPortC32InterfaceBase::NotifyFlowControlChangeCancel()
/**
 * Called by C32 to cancel a previous notification request.
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::NotifyFlowControlChangeCancel [port=%d]", GetPortNumber());

	if (iFlowControlNotifyPending)
		{
		iFlowControlNotifyPending = EFalse;
		FlowControlChangeCompleted(iCsyAllowedToSendFrames, KErrCancel);
		}
	}

void CPortC32InterfaceBase::NotifyBreak()
/**
 * Called by C32.
 * Note that this method is not supported.
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::NotifyBreak [port=%d]", GetPortNumber());
	}

void CPortC32InterfaceBase::NotifyBreakCancel()
/**
 * Called by C32.
 * Note that this method is not supported.
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::NotifyBreakCancel [port=%d]", GetPortNumber());
	}

void CPortC32InterfaceBase::NotifyOutputEmpty()
/**
 * Called by C32.
 * Note that this method is not supported.
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::NotifyOutputEmpty [port=%d]", GetPortNumber());
	}

void CPortC32InterfaceBase::NotifyOutputEmptyCancel()
/**
 * Called by C32.
 * Note that this method is not supported.
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::NotifyOutputEmptyCancel [port=%d]", GetPortNumber());
	}

TInt CPortC32InterfaceBase::GetFlowControlStatus(TFlowControl& aFlowControl)
/**
 * Called by C32 to return the port's flow control state.
 *
 * @param aFlowControl Reference to location to write the flow control value
 * @return KErrNone
 */
	{
	_LOG_L3C2("CPortC32InterfaceBase::GetFlowControlStatus [Port=%d]", GetPortNumber());

	aFlowControl = EFlowControlOff;
	if ((iCsyAllowedToSendFrames == EFlowControlOn) ||
		(iMuxChannel->CsyToModemFlowControl() == EFlowControlOn))
		aFlowControl = EFlowControlOn;

	return KErrNone;
	}

TInt CPortC32InterfaceBase::GetRole(TCommRole& aRole)
/**
 * Called by C32 to return the port's role. The role will be either
 * DTE or DCE.
 * @param aRole - Reference to location to write the port role (DTE or DCE).
 * @return KErrNone
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::GetRole [port=%d]", GetPortNumber());

	aRole = iRole;  // or get from RDevComm instance ???
	return KErrNone;
	}

TInt CPortC32InterfaceBase::SetRole(TCommRole aRole)
/**
 * Called by C32 to set the port role to either DTE or DCE.
 * @param aRole - DTE or DCE
 * @return KErrNone.
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::SetRole [aRole=%d]", aRole);

#if defined _DEBUG
	if (aRole == ECommRoleDTE)
		{
		_LOG_L4C2("CPortC32InterfaceBase::SetRole() - DTE for Port %d", iPortInfo.iPortNumber);
		}
	else if (aRole == ECommRoleDCE)
		{
		_LOG_L4C2("CPortC32InterfaceBase::SetRole() - DCE for Port %d", iPortInfo.iPortNumber);
		}
	else
		{
		_LOG_L4C3("CPortC32InterfaceBase::SetRole() - Unknown Role %d for Port %d", aRole, iPortInfo.iPortNumber);
		}
#endif

	iRole = aRole;
	return KErrNone;
	}


void CPortC32InterfaceBase::FreeMemory()
/**
 * Called by C32 when the client wishes the CSY to free some memory. 
 * Note that this method does nothing. The CSY uses statically-allocated 
 * memory. In principle there is no memory that can be freed within the CSY.
 *
 *
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::FreeMemory [port=%d]", GetPortNumber());

	// MAF missing functionality
	}

/********************************************************************************/
/*                       End of methods from CPort                              */
/********************************************************************************/

void CPortC32InterfaceBase::CompleteWriteRequest(TInt aStatus)
/**
 * This method is called by the CSY object writing to the LDD and is used to
 * signal C32 that its message has been sent to the BP.  C32 is now free to
 * write another message to the CSY on this port interface.
 * @param aStatus - Status of message write to BP
 *
 */
	{
	_LOG_L4C3("CPortC32InterfaceBase::CompleteWriteRequest [aStatus=%d, Port=%d]", aStatus, GetPortNumber());

	if (iIsWriteInProgress)
		{
		iIsWriteInProgress = EFalse;
		WriteCompleted(aStatus);
		}
	else
		{
		_LOG_L3C1("* No write outstanding to complete *");
		}
	}

void CPortC32InterfaceBase::CompleteReadRequest(TInt aStatus)
/**
 * This method is called to complete the C32 client's read request.
 *
 * @param aStatus - Status read result
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::CompleteReadRequest [aStatus=%d]", aStatus);

	if (iIsReadInProgress)
		{
		iIsReadInProgress = EFalse;
		ReadCompleted(aStatus);
		}
	else
		{
		_LOG_L3C1("* No read outstanding to complete *");
		}
	}

void CPortC32InterfaceBase::Shutdown()
/**
 * Returns all the used memory 
 *
 *
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::Shutdown [port=%d]", GetPortNumber());

	// MAF missing functionality
	}

void CPortC32InterfaceBase::ModemAndCsyToClientFlowCtrl(const TFlowControl aFlowControl)
/**
 * This method is called to update the port's flow control state.
 * If a notification is pending then complete it.
 * @param aFlowControl New flow control state
 *
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::ModemAndCsyToClientFlowCtrl [aFlowControl=%d]", aFlowControl);
	_LOG_L4C2("[port=%d]", GetPortNumber());

	if (iCsyAllowedToSendFrames != aFlowControl)
		{
		iCsyAllowedToSendFrames = aFlowControl;
		if (iFlowControlNotifyPending)
			{
			iFlowControlNotifyPending = EFalse;
			FlowControlChangeCompleted(iCsyAllowedToSendFrames, KErrNone);
			}
		}
	}

TInt CPortC32InterfaceBase::SetV24Signals(const TUint aRs232Signals)
	{
	_LOG_L4C2("CPortC32InterfaceBase::SetV24Signals [aRs232Signals=0x%08x]",
		aRs232Signals);
	_LOG_L4C2("port=%d", GetPortNumber());

	// From 27.010 Sending
	//
	// Bit number/name	DTE			DCE
	//
	// 3, RTC			DTR			DSR
	// 4, RTR			RTS			CTS	
	// 7, IC			always 0	RI
	// 8, DV			always 1	DCD

	TUint8 v24signals = 0;
	if (iRole == ECommRoleDTE)
		{
		_LOG_L3C1("DTE sending entity");

		if (aRs232Signals & KSignalDTR)
			{
			_LOG_L3C1("DTR set (setting RTC)");
			v24signals |= KV24SignalRTC;
			}

		if (aRs232Signals & KSignalRTS)
			{
			_LOG_L3C1("RTS set (setting RTR)");
			v24signals |= KV24SignalRTR;
			}

		// DV always 1
		v24signals |= 0x80;
		}
	else if (iRole == ECommRoleDCE)
		{
		_LOG_L3C1("DCE sending entity");

		if (aRs232Signals & KSignalDSR)
			{
			_LOG_L3C1("DSR set (setting RTC)");
			v24signals |= KV24SignalRTC;
			}

		if (aRs232Signals & KSignalCTS)
			{
			_LOG_L3C1("CTS set (setting RTR)");
			v24signals |= KV24SignalRTR;
			}

		if (aRs232Signals & KSignalRNG)
			{
			_LOG_L3C1("RNG set (setting IC)");
			v24signals |= KV24SignalIC;
			}

		if (aRs232Signals & KSignalDCD)
			{
			_LOG_L3C1("DCD set (setting DV)");
			v24signals |= KV24SignalDV;
			}
		}
	else
		{
		_LOG_L3C1("** Unknown role **");
		}

	return iMuxChannel->SendMscCommand(v24signals);
	}

void CPortC32InterfaceBase::ReceivedV24Signals(const TUint8 aV24Signals)
	{
	_LOG_L4C2("CPortC32InterfaceBase::ReceivedV24Signals [aV24Signals=0x%x]",
		aV24Signals);
	_LOG_L4C2("port=%d", GetPortNumber());

	// From 27.010 Receiving (mapping from control signal octet)
	//
	// Bit number/name	DTE		DCE
	// 	
	// 3, RTC			DSR		DTR
	// 4, RTR			CTS		RFR/RTS
	// 7, IC			RI		-ignored
	// 8, DV			DCD		-ignored

	TUint signals = 0;
	if (iRole == ECommRoleDTE)
		{
		_LOG_L3C1("DTE receiving entity");

		// RTC (bit 3)
		if (aV24Signals & KV24SignalRTC)
			{
			_LOG_L3C1("Device ready to communicate (setting DSR)");
			signals |= KSignalDSR;
			}
		// RTR (bit 4)
		if (aV24Signals & KV24SignalRTR)
			{
			_LOG_L3C1("Device ready to receive (setting CTS)");
			signals |= KSignalCTS;
			}
		// IC (bit 7)
		if (aV24Signals & KV24SignalIC)
			{
			_LOG_L3C1("Incoming call (setting RNG)");
			signals |= KSignalRNG;
			}
		// DV (bit 8)
		if (aV24Signals & KV24SignalDV)
			{
			_LOG_L3C1("Data valid (setting DCD)");
			signals |= KSignalDCD;
			}
		}
	else if (iRole == ECommRoleDCE)
		{
		_LOG_L3C1("DCE receiving entity");

		// RTC (bit 3)
		if (aV24Signals & KV24SignalRTC)
			{
			_LOG_L3C1("Device ready to communicate (setting DTR)");
			signals |= KSignalDTR;
			}
		// RTR (bit 4)
		if (aV24Signals & KV24SignalRTR)
			{
			_LOG_L3C1("Device ready to receive (setting RTS)");
			signals |= KSignalRTS;
			}
		}
	else
		{
		_LOG_L3C1("** Unknown role **");
		}

	signals &= iSignalMask;
	if (signals != iSignals)
		{
		iSignals = signals;

		// notification processing
		if (iSignalChangeNotifyPending)
			SignalChangeCompleted(iSignals, KErrNone);
		}
	}

void CPortC32InterfaceBase::SetMuxChannel(CChannelMgrCmdData* aMuxChannel)
/**
 * This method sets the flow control state for the port object
 * by reading the specified channel's flow control state.
 * @param aMuxChannel - Pointer to the channel
 *
 */
	{
	iMuxChannel = aMuxChannel;
	if (iMuxChannel != NULL)
		{
		ModemAndCsyToClientFlowCtrl(iMuxChannel->
			GetModemAndCsyToClientFlowControl());
		}
	else
		{
		_LOG_L1C1("** SetMuxChannel - channel not ready **");
		}
	}

void CPortC32InterfaceBase::SetDataAvailable()
/**
 * This method is called to set the port's data available state.
 * If the data available notification is pending then complete it.
 */
	{
	_LOG_L4C2("CPortC32InterfaceBase::SetDataAvailable [port=%d]", GetPortNumber());

	if (iDataAvailableNotifyPending)
		{
		iDataAvailableNotifyPending = EFalse;
		NotifyDataAvailableCompleted(KErrNone);
		}
	}

void CPortC32InterfaceBase::CompleteOutstandingRequest()
/**
 * This method is called to complete an outstanding request.
 * There can be read and write requests that are outstanding.
 */
	{
	_LOG_L4C1("CPortC32InterfaceBase::CompleteOutstandingRequest");

	if (iIsReadInProgress)
		CompleteReadRequest(KErrCancel);

	if (iIsWriteInProgress)
		CompleteWriteRequest(KErrCancel);
	}