serialserver/c32serialserver/Test/TE_C32/dummy.cpp
changeset 0 dfb7c4ff071f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/serialserver/c32serialserver/Test/TE_C32/dummy.cpp	Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,1085 @@
+// 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:
+// Dummy CSY for testing.
+// 
+//
+
+/**
+ @file
+*/
+
+#include "CS_PORT.H"
+#include <d32comm.h>
+#include "C32COMM.H"
+#include <f32file.h>
+#include "dummy.h"
+#include "TTHREAD.H"	// Required for the "Start Server in CSY Test"
+
+
+//**********************************************************************
+//			            DUMMY PORT FACTORY CODE
+//**********************************************************************
+
+static void CleanupCObject(TAny* aCObject)
+/**
+ * Clean up a CObject
+ */
+    {
+    ((CObject*)aCObject)->Close();
+    }
+
+
+CPort* CDummyPortFactory::NewPortL(const TUint aUnit)
+/**
+ * Create a new port for the supplied unit number
+ */
+	{
+	return CDummyPort::NewL(aUnit);
+	}
+
+
+void CDummyPortFactory::Info(TSerialInfo& aSerialInfo)
+/**
+ * fill in the supplied structure.
+ */
+	{
+	const TUint KCommLowUnit=0;
+	const TUint KCommHighUnit=0;
+	aSerialInfo.iDescription=SERIAL_DESCRIPTION;
+#if defined(DUMMYCSY16)
+	aSerialInfo.iName=SERIAL_NAME_SMALL;
+#else
+	aSerialInfo.iName=SERIAL_NAME;
+#endif
+	aSerialInfo.iLowUnit=KCommLowUnit;
+	aSerialInfo.iHighUnit=KCommHighUnit;
+#ifdef DUMMYCSY10
+	LoadAnotherCSY();// Modified to handle stackable csy ie. loading csy by other csy
+#endif
+#ifdef DUMMYCSY17
+	LoadAnotherCSYNoClose();// Modified to handle stackable csy ie. loading csy by other csy. Session is not closed after unload csy
+#endif
+	}
+
+#ifdef DUMMYCSY10 // Load one csy by another csy. session is closed after unload csy
+void CDummyPortFactory::LoadAnotherCSY()
+	{
+	_LIT(KCSYName,"DUMMY");
+	RCommServ commSess;
+	TInt res = commSess.Connect();
+	if(res == KErrNone)
+		{
+		res = commSess.LoadCommModule(KCSYName);
+		if(res == KErrNone)
+			{
+			commSess.UnloadCommModule(KCSYName);
+			commSess.Close();
+			}
+		}
+
+	}
+#endif
+
+#ifdef DUMMYCSY17 // Load one csy by another csy. session is not closed after unload csy
+void CDummyPortFactory::LoadAnotherCSYNoClose()
+	{
+	_LIT(KCSYName,"DUMMY");
+	RCommServ commSess;
+	TInt res = commSess.Connect();
+	if(res == KErrNone)
+		{
+		res = commSess.LoadCommModule(KCSYName);
+		if(res == KErrNone)
+			{
+			commSess.UnloadCommModule(KCSYName);
+			//Session close statement should be commented to test the whether the function
+			//CCommSession::CC32SessionCloseTimer::RunL() is called
+			//server thread should panic since the session is not closed
+
+			//commSess.Close();
+			}
+		}
+
+	}
+#endif
+
+
+void CDummyPortFactory::ConstructL()
+/**
+ * Construct and init members
+ */
+	{
+	TName name(SERIAL_NAME);
+	SetNameL(&name);
+	}
+
+
+CDummyPortFactory* CDummyPortFactory::NewL()
+/**
+ * 2 phase constructor
+ */
+	{
+	CDummyPortFactory* c=new(ELeave) CDummyPortFactory;
+	CleanupStack::PushL(TCleanupItem(CleanupCObject, c));
+	c->ConstructL();
+	CleanupStack::Pop();
+	return c;
+	}
+
+
+CDummyPortFactory::CDummyPortFactory()
+/**
+ * C'tor
+ */
+	{
+	__DECLARE_NAME(_S("CDummyPortFactory"));
+	iVersion=TVersion(KMajorVersion,KMinorVersion,KBuild);
+	}
+
+/**
+Returns capabilities for requested port
+*/
+TSecurityPolicy CDummyPortFactory::PortPlatSecCapability(TUint aPort) const
+	{
+	TSecurityPolicy csySecurityPolicy;
+
+	switch(aPort)
+		{
+		case PORT_0_NOCAPS:
+		case PORT_6_NOCAPS:
+		csySecurityPolicy = TSecurityPolicy(TSecurityPolicy::EAlwaysPass);
+		break;
+		case PORT_1_NETWORKSERVICES:
+		csySecurityPolicy = TSecurityPolicy(ECapabilityNetworkServices);
+		break;
+		case PORT_2_NOTSUPPORT:
+		default:
+		csySecurityPolicy = TSecurityPolicy(TSecurityPolicy::EAlwaysFail);
+		break;
+		case PORT_3_ALLCAPS:
+		csySecurityPolicy = TSecurityPolicy(ECapabilityTCB);
+		break;
+		}
+	return csySecurityPolicy;
+	}
+
+//**********************************************************************
+//			            DUMMY PORT CODE
+//**********************************************************************
+
+
+CDummyPort::CDummyPort()
+/**
+ * C'tor
+ */
+	:iPtrDataIn(NULL,0)
+	,iPtrDataOut(NULL,0)
+	,iPtrCompData(NULL,0)
+	{
+	__DECLARE_NAME(_S("CDummyPort"));
+	iDummyCompleteDelayFast = KDummyCompleteDelayFast;
+    iDummyCompleteDelaySlow = KDummyCompleteDelaySlow;
+	iConfig.iRate=EBps9600;
+	iConfig.iDataBits=EData8;
+	iConfig.iStopBits=EStop1;
+	iConfig.iParity=EParityNone;
+	iConfig.iFifo=EFifoEnable;
+	iConfig.iHandshake=KConfigObeyCTS;
+	iConfig.iParityError=KConfigParityErrorIgnore;
+	iConfig.iSIREnable=ESIRDisable;
+	iConfig.iTerminatorCount=0;
+	iConfig.iXonChar=0x11; // XON
+	iConfig.iXoffChar=0x13; // XOFF
+	iConfig.iSpecialRate=0;
+	iConfig.iParityErrorChar=0;
+
+	iPeerConfig.iRate = EBpsSpecial;
+	iPeerConfig.iDataBits = EData8;
+	iPeerConfig.iStopBits = EStop1;
+	iPeerConfig.iParity = EParityNone;
+	iPeerConfig.iHandshake = KConfigObeyCTS;
+	}
+
+
+CDummyPort* CDummyPort::NewL(TUint aUnit)
+/**
+ * Make a new CPort for the comm server
+ */
+	{
+	CDummyPort *p=new(ELeave) CDummyPort;
+	CleanupStack::PushL(TCleanupItem(CleanupCObject, p));
+	p->ConstructL(aUnit);
+
+    CleanupStack::Pop();
+	return p;
+	}
+
+
+void CDummyPort::ConstructL(TUint aUnit)
+/**
+ * construct and init members
+ */
+	{
+    // To avoid thread lock we cannot actually connect to the socket server now if
+    // the socket server thread is calling us
+    // Similarly we cannot load IRDA synchronously because this will cause a
+    // different kind of thread lock.
+
+    // Should really have some sundry checks
+    // i.e. is irda.prt in the ESOCK.INI file
+    // is there enough heap
+    // will irda be able to access COMM::0
+    // Basically we need to be pretty sure IRDA will start but without
+    // actually starting it
+
+	/*
+	RDevComm comm;
+	TInt ret=comm.Open(0);
+	if (ret==KErrInUse)
+		User::Leave(KErrAccessDenied);
+	else
+		User::LeaveIfError(ret);
+	comm.Close();
+	*/
+	const TUint16 KDummyPacketMaxSize = 2048;
+	iRole=ECommRoleDTE;
+	iNotifySignalMask = 0;
+	iFlowControl=EFlowControlOff;
+	iRole=ECommRoleDTE;
+	iSignals = 0;
+	iCapsPtr = 0;
+
+	iCompleteSigPtr		= new(ELeave) CDummyCompleter(*this);
+	iCompleteFlowPtr	= new(ELeave) CDummyCompleter(*this);
+	iCompleteConfPtr	= new(ELeave) CDummyCompleter(*this);
+	iCompleteCapsPtr	= new(ELeave) CDummyCompleter(*this);
+	iCompleteReadPtr	= new(ELeave) CDummyCompleter(*this);
+	iCompleteWritePtr	= new(ELeave) CDummyCompleter(*this);
+	iCompleteBreakPtr	= new(ELeave) CDummyCompleter(*this);
+	iCompleteSetBreakPtr = new(ELeave) CDummyCompleter(*this);
+	iCompleteDataAvailablePtr	= new(ELeave) CDummyCompleter(*this);
+	iCompleteOutputEmptyPtr	= new(ELeave) CDummyCompleter(*this);
+	iCompleteClosePtr	= new(ELeave) CDummyCompleter(*this);
+
+	iBreakDelay = 1;
+
+	iDataIn = (TUint8*)User::Alloc(KDummyPacketMaxSize);
+        if(!iDataIn)
+            User::Leave(KErrNoMemory);
+	iPtrDataIn.Set(iDataIn, 0, KDummyPacketMaxSize);
+
+	iDataOut = (TUint8*)User::Alloc(KDummyPacketMaxSize);
+        if(!iDataOut)
+            User::Leave(KErrNoMemory);
+	iPtrDataOut.Set(iDataOut, 0, KDummyPacketMaxSize);
+
+	iCompData = (TUint8*)User::Alloc(KDummyPacketMaxSize);
+        if(!iCompData)
+            User::Leave(KErrNoMemory);
+	iPtrCompData.Set(iCompData, 0, KDummyPacketMaxSize);
+
+	TBuf8<64> testbufRead	=_L8("0123456789abcdefghijklmnopqrstuvxyxABCDEFGHIJKLMNOPQRSTUVXYZ[]\r\n");
+	TBuf8<100> testbufWrite	=_L8("This string has to be exactly like this othervice write returns KErrCommsLineFail.");
+	//ptrDataIn.Copy(testbufRead); /* Client Read */
+	TInt i;
+	for (i=0;i<KDummyPacketMaxSize/64;i++)
+		iPtrDataIn.Append(testbufRead);
+
+	iPtrCompData.Copy(testbufWrite); /* Client Read */
+	TName name;
+	name.Format(_L("%d"), aUnit);
+	SetNameL(&name);
+
+#if defined (_DEBUG_CONSOLE_)
+	name.Format(_L("IrCOMM::%d"),aUnit);
+	DEBUG_TRACE(iConsole.SetTitle(name);)
+    DEBUG_TRACE(iConsole.Control(_L("+S +M"));)
+#endif
+
+	}
+
+
+CDummyPort::~CDummyPort()
+/**
+ * D'tor called from the active shutterdowner
+ */
+	{
+	//User::After(iDummyCompleteDelaySlow);
+	delete iCompleteSigPtr;
+	delete iCompleteFlowPtr;
+	delete iCompleteConfPtr;
+	delete iCompleteCapsPtr;
+	delete iCompleteReadPtr;
+	delete iCompleteWritePtr;
+	delete iCompleteBreakPtr;
+	delete iCompleteSetBreakPtr;
+	delete iCompleteDataAvailablePtr;
+	delete iCompleteOutputEmptyPtr;
+	delete iCompleteClosePtr;
+
+	User::Free(iDataIn);
+	User::Free(iCompData);
+	User::Free(iDataOut);
+
+#if defined (_DEBUG_CONSOLE_)
+	DEBUG_TRACE(iConsole.Printf(_L("PortClosed\n\r"));)
+    DEBUG_TRACE(iConsole.Close();)
+#endif
+	}
+
+
+void CDummyPort::NotifySignalChange(TUint aSignalMask)
+/**
+ * Stores the pointer which is also used as a flag to indicate
+ * that we must notify C32 of signal changes
+ */
+	{
+	iNotifySignalMask = aSignalMask * KSignalChanged;
+	if (iRole==ECommRoleDTE)
+		{
+		iSignals = (KSignalDTEInputs|KCTSChanged);
+		}
+	else
+		{
+		iSignals = (KSignalDCEInputs|KRTSChanged);
+		}
+
+	if (iNotifySignalMask&iSignals)
+		{
+		iCompleteSigPtr->Complete(ECommNotifySignals,iDummyCompleteDelayFast,KErrNone,iSignals);
+		}
+	}
+
+
+void CDummyPort::NotifySignalChangeCancel()
+/**
+ * Clears the pointer which is also used as a flag to indicate
+ * that we must not notify C32 of signal changes
+ */
+	{
+	iCompleteSigPtr->CancelComplete();
+	}
+
+
+void CDummyPort::NotifyConfigChange()
+/**
+ * Stores the pointer which is also used as a flag to indicate
+ * that we must notify C32 of configuration changes
+ */
+	{
+	iPeerConfig.iChangedMembers=KHandshakeChanged;
+	iPeerConfig.iHandshake = KConfigObeyCTS;
+	iPeerConfig.iRate =EBps9600;
+	iPeerConfig.iDataBits =EData8;
+	iPeerConfig.iParity =EParityNone;
+	iPeerConfig.iStopBits =EStop1;
+	iPeerConfig.iHandshake =(KConfigObeyCTS|KConfigObeyRTS);
+
+	TPckg<TCommNotificationV01> cfg(iPeerConfig);
+	iCompleteConfPtr->Complete(ECommNotifyConfigChange,iDummyCompleteDelayFast,KErrNone,cfg);
+
+	}
+
+
+void CDummyPort::NotifyConfigChangeCancel()
+/**
+ * Clears the pointer which is also used as a flag to indicate
+ * that we must not notify C32 of signal changes
+ */
+	{
+	iCompleteConfPtr->CancelComplete();
+	}
+
+
+void CDummyPort::NotifyFlowControlChange()
+/**
+ * Stores the pointer which is also used as a flag to indicate
+ * that we must notify C32 of flow control changes
+ */
+	{
+	iFlowControl=EFlowControlOn;
+	iCompleteFlowPtr->Complete(ECommNotifyFlowControl,iDummyCompleteDelayFast,KErrNone,iFlowControl);
+	}
+
+
+void CDummyPort::NotifyFlowControlChangeCancel()
+/**
+ * Clears the pointer which is also used as a flag to indicate
+ * that we must not notify C32 of flow control changes
+ */
+	{
+	iCompleteFlowPtr->CancelComplete();
+	}
+
+
+void CDummyPort::NotifyBreak()
+/**
+ * Set the flag on that we must notify C32 of break signal changes
+ */
+	{
+	iCompleteBreakPtr->Complete(ECommNotifyBreak,iDummyCompleteDelayFast,KErrNone);
+	}
+
+
+void CDummyPort::NotifyBreakCancel()
+/**
+ * Set the flag on that we must not notify C32 of break signal changes
+ */
+	{
+	iCompleteBreakPtr->CancelComplete();
+	}
+
+
+TInt CDummyPort::GetFlowControlStatus(TFlowControl& aFlowControl)
+/**
+ * Returns the current flow control state
+ */
+	{
+	aFlowControl=EFlowControlOn;
+	return KErrNone;
+	}
+
+
+TInt CDummyPort::GetRole(TCommRole& aRole)
+/**
+ * Returns the current role
+ */
+	{
+	aRole = iRole;
+	return KErrNone;
+	}
+
+
+TInt CDummyPort::SetRole(TCommRole aRole)
+/**
+ * Sets the role as DCE or DTE, and also the handshake according the
+ * role set
+ */
+	{
+
+	switch(aRole)
+		{
+		case ECommRoleDCE:
+			iConfig.iHandshake &=~KConfigObeyCTS;
+			iConfig.iHandshake |=KConfigObeyRTS;
+			iRole = aRole;
+			break;
+		case ECommRoleDTE:
+			iConfig.iHandshake &=~KConfigObeyRTS;
+			iConfig.iHandshake |=KConfigObeyCTS;
+			iRole = aRole;
+			break;
+
+		default:
+			break;
+		}
+	return KErrNone;
+	}
+
+
+void CPort::FreeMemory()
+/**
+ * We do nothing
+ */
+	{
+	// we do nothing
+	}
+
+
+void CDummyPort::StartRead(const TAny *aClientBuffer,TInt aLength)
+/**
+ * Queue a read.  IPC is handled inside of C32 now.
+ */
+	{
+
+	//_LIT8(KTestLog,"KCSYLoggingName start reading....");
+	//__FLOG_STATIC0(KC32LoggingName, KCSYLoggingName, KTestLog);
+
+	#ifdef DUMMYCSY12
+
+		User::After(KDummy12ReadWait); // Added to block other csys
+
+	#endif
+
+	if(aLength==0)
+		{
+        iCompleteReadPtr->Complete(ECommRead,iDummyCompleteDelaySlow,KErrNone);
+		return;
+		}
+    else
+		iClientPtr=(TAny*)aClientBuffer;
+
+    if(aLength<0)
+        {
+        aLength = -aLength;
+        }
+
+    iClientLength=aLength;
+	iPtrDataIn.SetLength(aLength);
+	this->IPCWrite(aClientBuffer,iPtrDataIn,0);
+	iCompleteReadPtr->Complete(ECommRead,iDummyCompleteDelayFast,KErrNone);
+	//_LIT8(KTestLog1,"KCSYLoggingName end reading....");
+	//__FLOG_STATIC0(KC32LoggingName, KCSYLoggingName, KTestLog1);
+
+    }
+
+
+void CDummyPort::ReadCancel()
+/**
+ * cancel a pending read
+ */
+	{
+	iCompleteReadPtr->CancelComplete();
+    }
+
+
+TInt CDummyPort::QueryReceiveBuffer(TInt& aLength) const
+/**
+ * Get the size of the receive buffer from the real serial port
+ */
+	{
+    aLength=iLength;
+	return KErrNone;
+	}
+
+
+void CDummyPort::ResetBuffers(TUint /*aFlags*/)
+/**
+ * Flush the client buffers
+ */
+	{
+	iLength=0;
+	}
+
+
+void CDummyPort::StartWrite(const TAny* aClientBuffer, TInt aLength)
+/**
+ * Queue a write.
+ */
+	{
+//	LOG(Log::Printf(_L("	**CDummyPort::StartWrite** :\r\n")));
+
+	TInt offset = 0;
+    TInt result=this->IPCRead(aClientBuffer, iPtrDataOut,offset);
+	iPtrDataOut.SetLength(aLength);
+    if(result==KErrNone)
+        {
+		result = iPtrCompData.Match(iPtrDataOut);
+		if (result==0)
+			iCompleteWritePtr->Complete(ECommWrite,iDummyCompleteDelayFast,KErrNone);
+		else
+			iCompleteWritePtr->Complete(ECommWrite,iDummyCompleteDelayFast,KErrCommsLineFail);
+		}
+    else
+		iCompleteWritePtr->CancelComplete();
+
+	}
+
+
+void CDummyPort::WriteCancel()
+/**
+ * cancel a pending write
+ */
+	{
+    iCompleteWritePtr->CancelComplete();
+	}
+
+
+void CDummyPort::Break(TInt aTime)
+/**
+ * Queue a break
+ */
+	{
+	if (iBreakDelay!=aTime)
+		User::Panic(_L("Dummy"),E_ParametersCorrupted);
+	else
+		iCompleteSetBreakPtr->Complete(ECommBreak,aTime,KErrNone);
+	iBreakDelay*=100;
+	}
+
+
+void CDummyPort::BreakCancel()
+/**
+ * Cancel a pending break
+ */
+	{
+    iCompleteSetBreakPtr->CancelComplete();
+	}
+
+
+TInt CDummyPort::SetConfig(const TDesC8& aPackage)
+/**
+ * Set up the Comm LDD/PDD
+ */
+	{
+    // line characteristics should be set and the line states checked accordingly
+    TCommConfigV01 c;
+
+    Mem::FillZ(&c,sizeof(c));
+	TInt len=Min(aPackage.Length(),sizeof(c));
+	Mem::Copy(&c, aPackage.Ptr(),len);
+
+	if ((c.iStopBits!=EStop2))
+		User::Panic(_L("Dummy"),E_ParametersCorrupted); // Panic if parameter fails
+
+	if(c.iTerminatorCount>KConfigMaxTerminators)
+		{
+		return KErrNotSupported;
+		}
+	if (c.iSIREnable==ESIREnable)
+		{
+		return KErrNotSupported;
+		}
+
+	iConfig=c;
+
+//
+// Piggy back the "Start Server from CSY" test onto this request
+//
+
+	_LIT(KLibraryName,"TThread");
+	_LIT(KThreadName,"newserver");
+	const TInt kDefaultStackSize=0x2000;
+	const TInt kHeapSize=0x1000;
+	const TInt kMaxHeapSize=0x40000;
+
+		TInt res=RCommServ::CreateThreadInCommProc(KLibraryName,KThreadName,ServerThread,
+				kDefaultStackSize,kHeapSize,kMaxHeapSize);
+		 return res;
+
+	}
+
+
+TInt CDummyPort::GetConfig(TDes8& aPackage) const
+/**
+ * Pass a config request
+ */
+	{
+    // simple - copy back iConfig
+    TPckg<TCommConfigV01> cfg(iConfig);
+    aPackage.Copy(cfg);
+	return KErrNone;
+	}
+
+
+TInt CDummyPort::GetCaps(TDes8& aPackage)
+/**
+ * Read capabilities from the driver
+ */
+	{
+	TCommCapsV01 *c;
+	TCommCapsV02 *c2=0;
+
+	c = (TCommCapsV01*)aPackage.Ptr();
+
+	if (aPackage.Size()==sizeof(TCommCapsV02))
+		{
+		c2 = (TCommCapsV02*)aPackage.Ptr();
+	    aPackage.SetLength(sizeof(TCommCapsV02));
+		}
+	else
+		{
+		aPackage.SetLength(sizeof(TCommCapsV01));
+		}
+
+	c->iRate=
+    KCapsBps50 | KCapsBps75 | KCapsBps110 | KCapsBps134 | KCapsBps150 | KCapsBps300
+    | KCapsBps600 | KCapsBps1200 | KCapsBps1800 | KCapsBps2000 | KCapsBps2400 | KCapsBps3600
+    | KCapsBps4800 | KCapsBps7200 | KCapsBps9600 | KCapsBps19200 | KCapsBps38400
+    | KCapsBps57600 | KCapsBps115200 ;
+
+	c->iDataBits=0xf; // All data sizes
+	c->iStopBits=0x3; // 1 and 2 stop bits
+	c->iParity=0x7; // None, Even and Odd
+	c->iHandshake=0x1ff; // All handshakes
+	c->iSignals=0x3f; // All signals
+	c->iFifo=KCapsHasFifo;
+	c->iSIR=0;
+
+	// Version 02 extended capabilities
+	if (c2!=0)
+		{
+		c2->iNotificationCaps=
+			(KNotifySignalsChangeSupported		| KNotifyRateChangeSupported
+			| KNotifyDataFormatChangeSupported	| KNotifyHandshakeChangeSupported
+			| KNotifyBreakSupported				| KNotifyFlowControlChangeSupported);
+		c2->iRoleCaps=KCapsRoleSwitchSupported;
+		c2->iFlowControlCaps=KCapsFlowControlStatusSupported;
+		}
+
+	return KErrNone;
+	}
+
+
+TInt CDummyPort::SetServerConfig(const TDesC8& aDes)
+/**
+ *	set server configurations
+ */
+	{
+	TCommServerConfigV01 *c;
+	c = (TCommServerConfigV01*)aDes.Ptr();
+	if (aDes.Size()!=sizeof(TCommServerConfigV01))
+		return KErrGeneral;
+
+	if (!((c->iBufFlags&KCommBufferPartial) && (c->iBufSize&0x10)))
+		User::Panic(_L("Dummy"),E_ParametersCorrupted);
+
+	iBufFlags=c->iBufFlags;
+	iBufSize=c->iBufSize;
+	return KErrNone;
+	}
+
+
+TInt CDummyPort::GetServerConfig(TDes8& aDes)
+/**
+ *	get server configurations
+ */
+	{
+
+	TCommServerConfigV01 *c;
+	c = (TCommServerConfigV01*)aDes.Ptr();
+	if (aDes.Size()!=sizeof(TCommServerConfigV01))
+		return KErrGeneral;
+
+	c->iBufFlags = iBufFlags;
+	c->iBufSize = iBufSize;
+
+	return KErrNone;
+	}
+
+
+TInt CDummyPort::GetSignals(TUint& aSignals)
+/**
+ * get the status of the signal pins
+ */
+	{
+	if (iRole==ECommRoleDTE)
+		aSignals = (KSignalDTEInputs);
+	else
+		aSignals = (KSignalDCEInputs);
+
+
+	return KErrNone;
+	}
+
+
+TInt CDummyPort::SetSignalsToMark(TUint aSignals)
+/**
+ * set selected signals to high (logical 1)
+ *
+ * @param aSignals bitmask with the signals to be set
+ * @return KErrNone always
+ */
+	{
+
+	if (iRole==ECommRoleDTE)
+		{
+		if (aSignals!=KSignalDTEOutputs)
+			User::Panic(_L("Dummy"),E_ParametersCorrupted);
+		aSignals &= KSignalDTEOutputs;
+		}
+	else
+		{
+		if (aSignals!=KSignalDCEOutputs)
+			User::Panic(_L("Dummy"),E_ParametersCorrupted);
+		aSignals &= KSignalDCEOutputs;
+		}
+
+    if(aSignals)
+        {
+        iSignals |= aSignals;
+		}
+	return KErrNone;
+	}
+
+
+TInt CDummyPort::SetSignalsToSpace(TUint aSignals)
+/**
+ * set selected signals to low (logical 0)
+ *
+ * @param aSignals bitmask with the signals to be cleared
+ * @return KErrNone always
+ */
+	{
+
+
+	if (iRole==ECommRoleDTE)
+		{
+		if (aSignals!=KSignalDTEOutputs)
+			User::Panic(_L("Dummy"),E_ParametersCorrupted);
+	    aSignals &= KSignalDTEOutputs;
+		}
+	else
+		{
+		if (aSignals!=KSignalDCEOutputs)
+			User::Panic(_L("Dummy"),E_ParametersCorrupted);
+		aSignals &= KSignalDCEOutputs;
+		}
+
+    if(aSignals)
+        {
+        iSignals &= ~aSignals;
+        }
+	return KErrNone;
+	}
+
+
+TInt CDummyPort::GetReceiveBufferLength(TInt& aLength) const
+/**
+ * get size of Tx and Rx buffer
+ *
+ * @param aLength reference to where the length will be written to
+ * @return KErrNone always
+ */
+	{
+
+    aLength = iLength;
+	return KErrNone;
+	}
+
+
+TInt CDummyPort::SetReceiveBufferLength(TInt aLength)
+/**
+ * set the size of Tx and Rx buffer
+ *
+ * @param aLength new length of Tx and Rx buffer
+ * @return TInt error code
+ */
+	{
+	iLength	= aLength;
+    return KErrNone;
+	}
+
+
+void CDummyPort::NotifyDataAvailable()
+/**
+ * Set the flag on that we must notify C32 when there has appeared data into
+ * incoming buffer
+ */
+	{
+	iCompleteDataAvailablePtr->Complete(ECommNotifyDataAvailable,iDummyCompleteDelaySlow,KErrNone);
+	}
+
+
+void CDummyPort::NotifyDataAvailableCancel()
+/**
+ * Set the flag on that we must not notify C32 when there has appeared data
+ * into incoming buffer
+ */
+	{
+	iCompleteDataAvailablePtr->CancelComplete();
+	}
+
+
+void CDummyPort::NotifyOutputEmpty()
+/**
+ * Set the flag on that we must not notify C32 when outgoing buffer is empty
+ */
+	{
+	iCompleteOutputEmptyPtr->Complete(ECommNotifyOutputEmpty,iDummyCompleteDelaySlow,KErrNone);
+	}
+
+
+void CDummyPort::NotifyOutputEmptyCancel()
+/**
+ * Set the flag on that we must not notify C32 when outgoing buffer is empty
+ */
+	{
+	iCompleteOutputEmptyPtr->CancelComplete();
+	}
+
+
+void CDummyPort::Destruct()
+/**
+ * Called from Port manager to close us down - we must call delete this sometime
+ * soon (unless AcessCount goes positive again)
+ */
+	{
+	if(iCompleteClosePtr)
+		{
+		if (!iCompleteClosePtr->IsActive()) // Don't want two completes at once
+			iCompleteClosePtr->Complete(ECommClose,iDummyCompleteDelaySlow,KErrNone);
+
+		}
+	}
+
+
+
+//**********************************************************************
+//			            DUMMY DLL ENTRY POINT CODE
+//**********************************************************************
+
+
+extern "C"
+	{
+	IMPORT_C CSerial* LibEntry(); // Force export
+	}
+
+
+EXPORT_C CSerial * LibEntry()
+/**
+ * Lib main entry point
+ */
+	{
+#ifdef DUMMYCSY15
+	return NULL;   // returning NULL ptr here so that load fails
+#else
+	CDummyPortFactory *c=NULL;
+	TRAPD(ret,c=CDummyPortFactory::NewL());
+	if (ret!=KErrNone)
+		{
+		return NULL;
+		}
+	return c;
+#endif
+	}
+
+
+//
+// implementation of CDummyCompleter
+//
+
+
+CDummyCompleter::CDummyCompleter(CDummyPort& aPort)
+/**
+ * C'tor
+ */
+	:CActive(EPriorityStandard)
+	,iPort(aPort)
+	,iReason(KErrNone)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+
+void CDummyCompleter::Complete(TCommMess aMess,TTimeIntervalMicroSeconds32 anInterval, TInt aReason, TUint aValue)
+/**
+ * complete a request
+ */
+	{
+	iReason = aReason;
+	iMess = aMess;
+	iValue = aValue;
+	TInt ret=iTimer.CreateLocal();
+	if (ret!=KErrNone)
+		User::Panic(_L("Dummy"),E_ParametersCorrupted);
+	iTimer.After(iStatus,anInterval); // 2 seconds timeout
+	SetActive();
+	}
+
+
+void CDummyCompleter::Complete(TCommMess aMess,TTimeIntervalMicroSeconds32 anInterval, TInt aReason, const TDesC8& aDescriptor)
+/**
+ * complete a request
+ */
+	{
+	iReason = aReason;
+	iMess = aMess;
+	//iConfPtr = (TAny *)&aDescriptor;
+	Mem::FillZ(&iPeerConfig,sizeof(iPeerConfig));
+	TInt len=Min(aDescriptor.Length(),sizeof(iPeerConfig));
+	Mem::Copy(&iPeerConfig, aDescriptor.Ptr(),len);
+	TInt ret=iTimer.CreateLocal();
+	if (ret!=KErrNone)
+		User::Panic(_L("Dummy"),E_ParametersCorrupted);
+	iTimer.After(iStatus,anInterval); // 2 seconds timeout
+	SetActive();
+	}
+
+
+void CDummyCompleter::CancelComplete()
+/**
+ * cancel a complete
+ */
+	{
+	Cancel();
+	}
+
+
+CDummyCompleter::~CDummyCompleter()
+/**
+ * D'tor
+ */
+	{
+	CActive::Cancel();
+	}
+
+
+void CDummyCompleter::RunL()
+/**
+ * a completer request has completed
+ */
+	{
+	TInt ret = iStatus.Int();
+
+	if (ret!=KErrNone)
+		{
+		return;
+		}
+
+	switch(iMess)
+		{
+		case ECommNotifySignals:
+
+			iPort.SignalChangeCompleted(iValue,iReason);
+			break;
+		case ECommNotifyFlowControl:
+			iPort.FlowControlChangeCompleted((TFlowControl)iValue,iReason);
+			break;
+		case ECommNotifyConfigChange:
+			{
+			TPckg<TCommNotificationV01> cfg(iPeerConfig);
+			iPort.ConfigChangeCompleted(cfg,iReason);
+			}
+			break;
+		case ECommNotifyBreak:
+			iPort.BreakNotifyCompleted(iReason);
+			break;
+		case ECommBreak:
+			iPort.BreakCompleted(iReason);
+			break;
+		case ECommRead:
+			iPort.ReadCompleted(iReason);
+			break;
+		case ECommWrite:
+			iPort.WriteCompleted(iReason);
+			break;
+		case ECommNotifyDataAvailable:
+			iPort.NotifyDataAvailableCompleted(iReason);
+			break;
+		case ECommNotifyOutputEmpty:
+			iPort.NotifyOutputEmptyCompleted(iReason);
+			break;
+		case ECommClose:
+			if (iPort.AccessCount()==0)
+				delete &iPort; // will delete this also
+			break;
+		default:
+			break;
+
+		}
+
+	}
+
+
+void CDummyCompleter::DoCancel()
+/**
+ * called when a cancelling the request
+ */
+	{
+	iTimer.Cancel();
+	}
+
+// EOF - DUMMY.CPP
+