kerneltest/e32test/pccd/d_medch.cpp
changeset 0 a41df078684a
child 31 56f325a607ea
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/pccd/d_medch.cpp	Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,289 @@
+// 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 the License "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:
+// e32test\pccd\d_medch.cpp
+// This LDD allow simulation of media change on a peripheral bus controller.
+// 
+//
+
+#include <kernel/kernel.h>
+#include <drivers/pbus.h>
+#include "d_medch.h"
+
+const TInt KMajorVersionNumber=1;
+const TInt KMinorVersionNumber=0;
+const TInt KBuildVersionNumber=1;
+
+class DLddFactoryMedCh : public DLogicalDevice
+	{
+public:
+	DLddFactoryMedCh();
+	virtual TInt Install();
+	virtual void GetCaps(TDes8 &aDes) const;
+	virtual TInt Create(DLogicalChannelBase*& aChannel);
+	};
+
+class DLddMedCh : public DLogicalChannel
+	{
+public:
+	 DLddMedCh();
+	~DLddMedCh();
+protected:
+	virtual TInt DoCreate(TInt aUnit, const TDesC8* anInfo, const TVersion& aVer);
+	virtual void HandleMsg(class TMessageBase *);
+private:
+	TInt DoRequest(TInt aReqNo,TAny *a1,TAny *a2);
+	TInt DoControl(TInt aFunction,TAny *a1,TAny *a2);
+private:
+	static void MsCBFunc(TAny* aPtr);
+private:	
+	DPBusSocket* iSocketP;
+	DThread* iClient;
+	TRequestStatus* iReqStat;
+	
+	NTimer iMsCallBack;
+	TInt iMsInterval;
+
+	DPBusSocket::TPBusSimulateMediaState iDelayedOperation;
+	};
+
+DECLARE_STANDARD_LDD()
+	{
+	return new DLddFactoryMedCh;
+	}
+
+DLddFactoryMedCh::DLddFactoryMedCh()
+/**
+ * Constructor
+ */
+	{
+
+    iParseMask=KDeviceAllowUnit;
+	iUnitsMask=0xffffffff;
+	iVersion = TVersion(KMajorVersionNumber, KMinorVersionNumber, KBuildVersionNumber);
+	}
+
+TInt DLddFactoryMedCh::Install()
+/**
+ * Install the device driver.
+ */
+	{
+
+    TPtrC name = _L("MedCh");
+	return(SetName(&name));
+	}
+
+void DLddFactoryMedCh::GetCaps(TDes8 &aDes) const
+/**
+ * Return the media change LDD capabilities.
+ */
+	{
+
+	TCapsMediaChangeV01 caps;
+	caps.version = TVersion(KMajorVersionNumber, KMinorVersionNumber, KBuildVersionNumber);
+    Kern::InfoCopy(aDes,(TUint8*)&caps,sizeof(caps));
+	}
+
+TInt DLddFactoryMedCh::Create(DLogicalChannelBase*& aChannel)
+/**
+ * Create a channel on the device.
+ */
+	{
+
+	aChannel = new DLddMedCh;
+	return aChannel ? KErrNone : KErrNoMemory;
+	}
+
+DLddMedCh::DLddMedCh()
+/**
+ * Constructor
+ */
+	: iMsCallBack(MsCBFunc, this)
+	{
+
+	iClient = &Kern::CurrentThread();
+	((DObject*)iClient)->Open();
+	}
+
+DLddMedCh::~DLddMedCh()
+/**
+ * Destructor
+ */
+	{ 
+	if(iSocketP)
+		(void)iSocketP->ControlIO(DPBusSocket::EControlMediaState, (TAny*)DPBusSocket::EPeriphBusMediaNormal, NULL);
+
+	Kern::SafeClose((DObject*&)iClient, NULL);
+	}
+
+TInt DLddMedCh::DoCreate(TInt aUnit, const TDesC8* /*aInfo*/, const TVersion& aVer)
+/**
+ * Create channel.
+ */
+	{
+
+	if (!Kern::QueryVersionSupported(TVersion(KMajorVersionNumber, KMinorVersionNumber, KBuildVersionNumber), aVer))
+		return(KErrNotSupported);
+
+	//
+	// Obtain the requested socket (as specified by the opened logical unit)
+	//
+	iSocketP = DPBusSocket::SocketFromId(aUnit);
+	if(iSocketP == NULL)
+		return(KErrNoMemory);
+
+	SetDfcQ(Kern::DfcQue0());
+	iMsgQ.Receive();
+	
+    return KErrNone;
+	}
+
+void DLddMedCh::HandleMsg(TMessageBase* aMsg)
+/**
+ * Message Handler
+ */
+    {
+
+    TThreadMessage& m=*(TThreadMessage*)aMsg;
+    TInt id=m.iValue;
+    
+	if (id == (TInt)ECloseMsg)
+		{
+		iMsCallBack.Cancel();
+		(void)iSocketP->ControlIO(DPBusSocket::EControlMediaState, (TAny*)DPBusSocket::EPeriphBusMediaNormal, NULL);
+		m.Complete(KErrNone, EFalse);
+		return;
+		}
+    else if (id == KMaxTInt)
+		{
+		// DoCancel
+		m.Complete(KErrNone, ETrue);
+		return;
+		}
+
+    if (id < 0)
+		{
+		// DoRequest
+		TRequestStatus* pS = (TRequestStatus*)m.Ptr0();
+		iReqStat = pS;
+		TInt r = DoRequest(~id, m.Ptr1(), m.Ptr2());
+		if (r != KErrNone)
+	    	Kern::RequestComplete(iClient, pS, r);
+		m.Complete(KErrNone, ETrue);
+		}
+    else
+		{
+		// DoControl
+		TInt r = DoControl(id, m.Ptr0(), m.Ptr1());
+		if(r != KErrCompletion)
+			{
+			m.Complete(r, ETrue);
+			}
+		}
+	}
+
+TInt DLddMedCh::DoRequest(TInt aFunction, TAny* a1, TAny* a2)
+/**
+ * Asynchronous requests
+ */
+	{
+
+	TInt err = KErrNotSupported;
+	
+	switch (aFunction)
+		{
+		case RMedCh::EDelayedDoorOpen:
+			{
+			const TInt KMsInterval = (TInt)a1;
+			iDelayedOperation = DPBusSocket::EPeriphBusDoorOpen;
+			err = iMsCallBack.OneShot(NKern::TimerTicks(KMsInterval), ETrue);
+			break;
+			}
+		
+		case RMedCh::EDelayedDoorClose:
+			{
+			const TInt KMsInterval = (TInt)a1;
+			const TBool KMediaPresent = (TBool)a2;
+			iDelayedOperation = KMediaPresent ? DPBusSocket::EPeriphBusMediaPresent : DPBusSocket::EPeriphBusMediaRemoved;
+			err = iMsCallBack.OneShot(NKern::TimerTicks(KMsInterval), ETrue);
+			break;
+			}
+				
+		default:
+			{
+			err = KErrNotSupported;
+			break;
+			}
+		}
+	
+	return err;
+	}
+
+TInt DLddMedCh::DoControl(TInt aFunction,TAny* a1, TAny* /*a2*/)
+/**
+ * Synchronous requests
+ */
+	{
+
+	TInt err = KErrNotSupported;
+	
+	switch (aFunction)
+		{
+		case RMedCh::EDoorOpen:
+			{
+			err = iSocketP->ControlIO(DPBusSocket::EControlMediaState, (TAny*)DPBusSocket::EPeriphBusDoorOpen, NULL);
+			break;
+			}
+
+		case RMedCh::EDoorClose:
+			{
+			const TBool KMediaPresent = (TBool)a1;
+
+			err = iSocketP->ControlIO(DPBusSocket::EControlMediaState, 
+									  (TAny*)(KMediaPresent ? DPBusSocket::EPeriphBusMediaPresent : DPBusSocket::EPeriphBusMediaRemoved),
+									  NULL);
+			break;
+			}
+
+		case RMedCh::EDoorNormal:
+			{
+			err = iSocketP->ControlIO(DPBusSocket::EControlMediaState, (TAny*)DPBusSocket::EPeriphBusMediaNormal, NULL);
+			break;
+			}
+
+		case RMedCh::EDoubleDoorOpen:
+			{
+			err = iSocketP->ControlIO(DPBusSocket::EControlMediaState, (TAny*)DPBusSocket::EPeriphBusMediaDoubleDoorOpen, NULL);
+			break;
+			}
+
+		default:
+			{
+			err = KErrNotSupported;
+			break;
+			}
+		}
+	
+	return err;
+	}
+
+void DLddMedCh::MsCBFunc(TAny* aPtr)
+/**
+ * Delayed Open/Close timer callback
+ */
+	{
+	DLddMedCh& mcldd=*(DLddMedCh*)aPtr;
+	TInt err = mcldd.iSocketP->ControlIO(DPBusSocket::EControlMediaState, (TAny*)mcldd.iDelayedOperation, NULL);
+   	Kern::RequestComplete(mcldd.iClient, mcldd.iReqStat, err);
+	}
+