diff -r 000000000000 -r a41df078684a kerneltest/e32test/pccd/d_medch.cpp --- /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 +#include +#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); + } +