serialserver/c32serialserver/Test/TE_C32/d_comm.cpp
changeset 0 dfb7c4ff071f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/serialserver/c32serialserver/Test/TE_C32/d_comm.cpp	Thu Dec 17 09:22:25 2009 +0200
@@ -0,0 +1,319 @@
+// Copyright (c) 1995-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:
+//
+
+#include <e32std.h>
+#include <e32base.h>
+
+#define __KERNEL_MODE__
+#include <kernel.h>
+#undef  __KERNEL_MODE__
+
+#include <d32comm.h>
+#include <e32ver.h>
+
+#include "d_comm.h"
+#include <e32hal.h>
+#include "DParams.h"
+
+const TUint KXoffSignal=0x80000000;
+//
+const TInt KInputHeldFree=(-1);
+const TInt KInputHeld=(-2);
+//
+const TUint KTransmitting=0x01;
+const TUint KBreaking=0x02;
+const TUint KBreakPending=0x04;
+//
+enum TPanic
+	{
+	ESetConfigWhileRequestPending,
+	ESetSignalsSetAndClear,
+	EResetBuffers,
+	ESetReceiveBufferLength,
+//	EDoubleTxBufFill,
+	};
+
+EXPORT_C DLogicalDevice *CreateLogicalDevice()
+//
+// Create a new device
+//
+	{
+	return(new DDeviceComm);
+	}
+
+DDeviceComm::DDeviceComm()
+//
+// Constructor
+//
+	{
+	//iParseMask=KDeviceAllowAll;
+	iParseMask=KDeviceAllowUnit|KDeviceAllowInfo;
+	iUnitsMask=0xffffffff; // Leave units decision to the driver
+	iVersion=TVersion(KCommsMajorVersionNumber,KCommsMinorVersionNumber,KCommsBuildVersionNumber);
+	}
+
+TInt DDeviceComm::Install()
+//
+// Install the device driver.
+//
+	{
+    TPtrC name=_L("CommDCE");
+	return(SetName(&name));
+	}
+
+void DDeviceComm::GetCaps(TDes8 &aDes) const
+//
+// Return the Comm capabilities.
+//
+	{
+
+	TCapsDevCommV01 b;
+	b.version=iVersion;
+	aDes.FillZ(aDes.MaxLength());
+	aDes.Copy((TUint8 *)&b,Min(aDes.MaxLength(),sizeof(b)));
+	}
+
+DLogicalChannel *DDeviceComm::CreateL()
+//
+// Create a channel on the device.
+//
+	{
+
+	return(new(ELeave) DChannelComm(this));
+	}
+
+
+#pragma warning( disable : 4705 )	// statement has no effect
+#pragma warning( disable : 4355 )	// this used in intializer list
+DChannelComm::DChannelComm(DLogicalDevice *aDevice)
+//
+// Constructor
+//
+: DLogicalChannel(aDevice)
+	{
+
+	SetBehaviour(RBusDevComm::ERequestReadCancel|
+		RBusDevComm::ERequestWriteCancel|
+		RBusDevComm::ERequestBreakCancel|
+		RBusDevCommDCE::ERequestNotifySignalChangeCancel|
+		RBusDevCommDCE::ERequestNotifyFlowControlChangeCancel|
+		RBusDevCommDCE::ERequestNotifyConfigChangeCancel);
+//
+// Setup the default config
+//
+	iConfig.iRate=DUMMYCONFIGRATE;
+	iConfig.iDataBits=DUMMYDATABITS;
+	iConfig.iStopBits=DUMMYSTOPBITS;
+	iConfig.iHandshake=DUMMYHANDSHAKE;
+	}
+#pragma warning( default : 4705 )
+#pragma warning( disable : 4355 )
+
+DChannelComm::~DChannelComm()
+//
+// Destructor
+//
+	{
+	CompleteAll(KErrAbort);
+	delete iDriver;
+	}
+
+void DChannelComm::DoCreateL(TInt /*aUnit*/,CBase *aDriver,const TDesC * /*anInfo*/,const TVersion &aVer)
+//
+// Create the channel from the passed info.
+//
+	{
+	iDriver=(DComm *)aDriver; // Must do this to ensure the driver is destroyed by the destructor
+	if (!User::QueryVersionSupported(TVersion(KCommsMajorVersionNumber,KCommsMinorVersionNumber,KCommsBuildVersionNumber),aVer))
+		User::Leave(KErrNotSupported);
+
+//	((DComm *)aDriver)->SetComm(this); // Rog
+	}
+
+void DChannelComm::DoCancel(TInt aReqNo)
+//
+// Cancel an outstanding request.
+//
+	{
+
+	switch (aReqNo)
+		{
+	case RBusDevComm::ERequestRead:
+		iRxDataAvailablePending=EFalse;
+		break;
+	case RBusDevCommDCE::ERequestNotifySignalChange:
+		iSignalCount++;
+		iSignalNotifyPending=EFalse;
+		break;
+	case RBusDevCommDCE::ERequestNotifyFlowControlChange:
+		iFlowControlChangePending=EFalse;
+		break;
+	case RBusDevCommDCE::ERequestNotifyConfigChange:
+		iConfigChangePending=EFalse;
+		break;
+	default:
+		__ASSERT_ALWAYS(0,User::Invariant());
+		}
+	}
+
+void DChannelComm::DoRequest(TInt aReqNo,TAny *a1,TAny *a2)
+//
+// Async requests.
+//
+	{
+	aReqNo &= (~KDataAvailableNotifyFlag);
+	switch (aReqNo)
+		{
+	case RBusDevCommDCE::ERequestWrite:
+		{
+		__ASSERT_ALWAYS(iWritePending==EFalse,User::Invariant());
+		iWritePending=ETrue;
+		iQueuedWrite.OneShotInMicroSeconds(KDummyTimeOut,DChannelComm::WriteCompleted,this);
+		}
+		break;
+	case RBusDevCommDCE::ERequestRead:	// this is the RxDataAvailable notification. Base have chosen
+									// to use the enum for both this and Read().
+		{
+		__ASSERT_ALWAYS(iRxDataAvailablePending==EFalse,User::Invariant());
+		iRxDataAvailablePending=ETrue;
+		iQueuedRxDataAvailable.OneShotInMicroSeconds(KDummyTimeOut,DChannelComm::RxDataAvailableCompleted,this);
+		}
+		break;
+	case RBusDevCommDCE::ERequestNotifySignalChange:
+		{
+		__ASSERT_ALWAYS(iSignalNotifyPending==EFalse,User::Invariant());
+		iSignalNotifyPending=ETrue;
+		switch (iSignalCount)
+			{
+		case 0:
+		case 2:
+			__ASSERT_ALWAYS(*((TUint*)a2) == (DUMMYSIGNALMASK),User::Invariant());	// and wait for cancel
+			break;
+		case 1:
+			__ASSERT_ALWAYS(*((TUint*)a2) == (DUMMYSIGNALMASK|KSignalBreak),User::Invariant());// and wait for cancel
+			break;
+		case 3:
+		case 4:
+			{
+			iSignals=(TUint*)a1;
+			iSignalMask=*((TUint*)a2);
+			iQueuedSignalNotify.OneShotInMicroSeconds(KDummyTimeOut,DChannelComm::SignalChangeCompleted,this);
+			break;
+			}
+		default:
+			__ASSERT_ALWAYS(0,User::Invariant());
+			}
+		break;
+	case RBusDevCommDCE::ERequestNotifyFlowControlChange:
+		{
+		__ASSERT_ALWAYS(iFlowControlChangePending==EFalse,User::Invariant());
+		iFlowControlChangePending=ETrue;
+		iQueuedFlowControl.OneShotInMicroSeconds(KDummyTimeOut,DChannelComm::FlowControlChangeCompleted,this);
+		}
+		break;
+	case RBusDevCommDCE::ERequestNotifyConfigChange:
+		{
+		__ASSERT_ALWAYS(iConfigChangePending==EFalse,User::Invariant());
+		iConfigChangePending=ETrue;
+		iConfigPointer = (TCommNotificationPckg*)a1;
+
+		iQueuedConfigChange.OneShotInMicroSeconds(KDummyTimeOut,DChannelComm::ConfigChangeCompleted,this);
+		}
+		break;
+	default:
+		Complete(aReqNo,KErrNotSupported);
+		}
+		}
+	}
+
+TInt DChannelComm::DoControl(TInt aFunction,TAny *a1,TAny* /*a2*/)
+//
+// Sync requests.
+//
+	{
+	TInt r=KErrNone;
+	switch (aFunction)
+		{
+	case RBusDevCommDCE::EControlFlowControlStatus:
+		{
+		iFlowControl=DUMMYFLOWCONTROLSTATUS;
+		*((TFlowControl*)a1) = iFlowControl;
+		}
+		break;
+	case RBusDevCommDCE::EControlSetConfig:
+		break;
+	default:
+		r=KErrNotSupported;
+		}
+	return(r);
+	}
+
+
+void DChannelComm::SignalChangeCompleted(TAny* aChannel,TInt)
+	{
+	DChannelComm* dc = (DChannelComm*)aChannel;
+	dc->SetSignals();
+	dc->CompleteReq(RBusDevCommDCE::ERequestNotifySignalChange);
+	}
+void DChannelComm::ConfigChangeCompleted(TAny* aChannel,TInt)
+	{
+	DChannelComm* dc = (DChannelComm*)aChannel;
+	dc->ChangeConfig();
+	dc->CompleteReq(RBusDevCommDCE::ERequestNotifyConfigChange);
+	}
+void DChannelComm::RxDataAvailableCompleted(TAny* aChannel,TInt)
+	{
+	((DChannelComm*)aChannel)->CompleteReq(RBusDevCommDCE::ERequestRead);
+	}
+void DChannelComm::FlowControlChangeCompleted(TAny* aChannel,TInt)
+	{
+	((DChannelComm*)aChannel)->CompleteReq(RBusDevCommDCE::ERequestNotifyFlowControlChange);
+	}
+void DChannelComm::WriteCompleted(TAny* aChannel,TInt)
+	{
+	((DChannelComm*)aChannel)->CompleteReq(RBusDevCommDCE::ERequestWrite);
+	}
+
+void DChannelComm::CompleteReq(TInt aReqNo)
+	{
+
+	Complete(aReqNo);
+	}
+
+void DChannelComm::SetSignals()
+	{
+	switch(iSignalCount++)
+		{
+	case 3:
+		(*iSignals)=DUMMYSIGNALS;
+		break;
+	case 4:
+		(*iSignals)=(KSignalBreak|KBreakChanged);
+		break;
+	default:
+		__ASSERT_ALWAYS(0,User::Invariant());
+		};
+	iSignalNotifyPending=EFalse;
+	}
+
+void DChannelComm::ChangeConfig()
+	{
+	iConfig.iChangedMembers = DUMMYCHANGED;
+	iConfigPointer->FillZ(iConfigPointer->MaxLength());
+	TInt len=Min(iConfigPointer->MaxLength(),sizeof(iConfig));
+	iConfigPointer->Copy((TUint8 *)&iConfig,len);
+	}
+
+