kerneltest/e32test/usb/t_usb_device/src/transferserver.cpp
changeset 247 d8d70de2bd36
child 253 d37db4dcc88d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/usb/t_usb_device/src/transferserver.cpp	Wed Aug 18 11:08:29 2010 +0300
@@ -0,0 +1,486 @@
+/*
+* 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:
+*
+*
+*/
+
+/**
+ @file
+*/
+
+#include <e32svr.h>
+#include "transferserver.h"
+#include "transfersession.h"
+#include "transfersrv.h"
+#include "transferserversecuritypolicy.h"
+#include "transferhandle.h"
+#include "tranhandlesrv.h"
+
+
+
+TBool gVerbose = ETrue;
+extern RTest test;
+
+
+CTransferServer* CTransferServer::NewLC()
+	{
+	RDebug::Printf("CTransferServer::NewLC");
+	CTransferServer* self = new(ELeave) CTransferServer;
+	CleanupStack::PushL(self);
+	self->StartL(KTransferServerName);
+	self->ConstructL();
+	return self;
+	}
+
+CTransferServer::~CTransferServer()
+	{
+	RDebug::Printf("CTransferServer::~CTransferServer");
+	while (iLddPtr->iIFPtr)
+	{
+	IFConfigPtr* ifPtrPtr = & iLddPtr->iIFPtr;
+	while ((*ifPtrPtr)->iPtrNext)
+		{
+		ifPtrPtr = &(*ifPtrPtr)->iPtrNext;
+		}
+	delete (*ifPtrPtr)->iInfoPtr->iString;
+	delete (*ifPtrPtr)->iInfoPtr;
+	delete (*ifPtrPtr);
+	* ifPtrPtr = NULL;
+	}
+
+	while (iLddPtr)
+		{
+		LDDConfigPtr* lddPtrPtr = &iLddPtr;	
+		while ((*lddPtrPtr)->iPtrNext)
+			{
+			lddPtrPtr = &(*lddPtrPtr)->iPtrNext;
+			}
+		delete (*lddPtrPtr)->iManufacturer;
+		delete (*lddPtrPtr)->iProduct;
+		delete (*lddPtrPtr)->iSerialNumber;
+		delete (*lddPtrPtr);
+		* lddPtrPtr = NULL;
+		}
+
+	delete iShutdownTimer;	
+	delete iTransferHandle;	
+	RDebug::Printf("<<<CTransferServer::~CTransferServer");
+	}
+
+
+CTransferServer::CTransferServer()
+     : CPolicyServer(EPriorityHigh,KTransferServerPolicy)
+	{
+	}
+
+void CTransferServer::ConstructL()
+	{
+	iShutdownTimer = new(ELeave) CShutdownTimer;
+	iShutdownTimer->ConstructL(); 
+	
+	iTransferHandle = CTransferHandle::NewL(*this);
+	RDebug::Printf("CTransferServer::ConstructL");
+	}
+
+
+CSession2* CTransferServer::NewSessionL(const TVersion &aVersion, const RMessage2& aMessage) const
+	{
+	(void)aMessage;//Remove compiler warning
+	(void)aVersion;//Remove compiler warning
+	
+	CTransferServer* ncThis = const_cast<CTransferServer*>(this);
+	
+	CTransferSession* sess = CTransferSession::NewL(ncThis);
+		
+	return sess;
+	}
+
+
+void CTransferServer::Error(TInt aError)
+	{
+	RDebug::Printf("CTransferServer::Error");
+	Message().Complete(aError);
+	ReStart();
+	}
+
+void CTransferServer::IncrementSessionCount()
+	{
+	RDebug::Printf("CTransferServer::IncrementSessionCount");
+	
+	++iSessionCount;
+	iShutdownTimer->Cancel();
+
+	}
+
+void CTransferServer::DecrementSessionCount()
+	{
+	--iSessionCount;	
+	RDebug::Printf("CTransferServer::DecrementSessionCount");	
+	if (iSessionCount == 0)
+		{
+		iShutdownTimer->After(KShutdownDelay);
+		RDebug::Printf("CTransferServer::DecrementSessionCount1");
+		}
+	}
+
+void CTransferServer::LaunchShutdownTimerIfNoSessions()
+	{
+	if (iSessionCount == 0)
+		iShutdownTimer->After(KShutdownDelay);
+	}
+
+CTransferServer::CShutdownTimer::CShutdownTimer()
+:	CTimer(EPriorityStandard)
+	{
+	CActiveScheduler::Add(this);
+	}
+
+
+void CTransferServer::CShutdownTimer::ConstructL()
+	{
+	RDebug::Printf("CTransferServer::CShutdownTimer::ConstructL");
+	CTimer::ConstructL();
+	}
+
+
+void CTransferServer::CShutdownTimer::RunL()
+	{
+	RDebug::Printf("CShutdownTimer::RunL");
+	CActiveScheduler::Stop();
+	}
+
+
+void CTransferServer::TransferHandleL()
+	{
+	RTranHandleSrv aServer;
+	RChunk* commChunk = NULL;
+	User::LeaveIfError(aServer.Connect());
+	User::LeaveIfError(iPort[0].GetDataTransferChunk(commChunk));
+	User::LeaveIfError(aServer.TransferHandle(iPort[0], *commChunk));	
+	aServer.Close();
+	commChunk->Close();
+	iPort[0].Close();
+	}
+
+void CTransferServer::FillEndpointsResourceAllocation(IFConfigPtr aIfCfg)
+	{
+	
+#ifdef USB_SC
+		TUsbcScInterfaceInfo* iInfoPtr = aIfCfg->iInfoPtr;
+#else
+		TUsbcInterfaceInfo* iInfoPtr = aIfCfg->iInfoPtr;
+#endif
+	
+	//	fill resource allocation info in the endpoint info with resource allocation v2
+	for (TUint8 i = 1; i <= iInfoPtr->iTotalEndpointsUsed; i++)
+		{
+		if (aIfCfg->iEpDMA[i-1])
+			{
+			iInfoPtr->iEndpointData[i-1].iFeatureWord1 |= KUsbcEndpointInfoFeatureWord1_DMA;
+			}
+		else
+			{
+			iInfoPtr->iEndpointData[i-1].iFeatureWord1 &= (~KUsbcEndpointInfoFeatureWord1_DMA);
+			}
+	#ifndef USB_SC
+		if (aIfCfg->iEpDoubleBuff[i-1])
+			{
+			iInfoPtr->iEndpointData[i-1].iFeatureWord1 |= KUsbcEndpointInfoFeatureWord1_DoubleBuffering;
+			}
+		else
+			{
+			iInfoPtr->iEndpointData[i-1].iFeatureWord1 &= (~KUsbcEndpointInfoFeatureWord1_DoubleBuffering);
+			}
+	#endif
+		}	
+	}
+
+
+void CTransferServer::PopulateInterfaceResourceAllocation(IFConfigPtr aFirstIfCfg, TInt aPortNumber)
+	{
+	FillEndpointsResourceAllocation(aFirstIfCfg);
+	
+	IFConfigPtr ifCfgPtr = aFirstIfCfg->iPtrNext;
+	while (ifCfgPtr != NULL)
+		{
+		if (ifCfgPtr->iAlternateSetting)
+			{
+			FillEndpointsResourceAllocation(ifCfgPtr);
+			ifCfgPtr = ifCfgPtr->iPtrNext;
+			}
+		else
+			{
+			ifCfgPtr = NULL;
+			}
+		}
+	}
+
+void CTransferServer::SetupInterface(IFConfigPtr* aIfPtr, TInt aPortNumber)
+	{
+	test.Start (_L("Setup Interface"));
+	
+	// first of all set the default interface	
+	TUSB_PRINT2 ("Set Default Interface with %d endpoints bandwidth 0x%x",(*aIfPtr)->iInfoPtr->iTotalEndpointsUsed,(*aIfPtr)->iBandwidthIn | (*aIfPtr)->iBandwidthOut);
+#ifdef USB_SC
+	TUsbcScInterfaceInfoBuf ifc = *((*aIfPtr)->iInfoPtr);
+	TInt r = iPort[aPortNumber].SetInterface(0, ifc);
+#else
+	TUsbcInterfaceInfoBuf ifc = *((*aIfPtr)->iInfoPtr);
+	TInt r = iPort[aPortNumber].SetInterface(0, ifc, (*aIfPtr)->iBandwidthIn | (*aIfPtr)->iBandwidthOut);
+#endif
+	test_KErrNone(r);
+
+	TBuf8<KUsbDescSize_Interface> ifDescriptor;
+	r = iPort[aPortNumber].GetInterfaceDescriptor(0, ifDescriptor);
+	test_KErrNone(r);
+
+	// Check the interface descriptor
+	test(ifDescriptor[KIfcDesc_SettingOffset] == 0 && ifDescriptor[KIfcDesc_NumEndpointsOffset] == (*aIfPtr)->iInfoPtr->iTotalEndpointsUsed &&
+		ifDescriptor[KIfcDesc_ClassOffset] == (*aIfPtr)->iInfoPtr->iClass.iClassNum &&
+		ifDescriptor[KIfcDesc_SubClassOffset] == (*aIfPtr)->iInfoPtr->iClass.iSubClassNum &&
+		ifDescriptor[KIfcDesc_ProtocolOffset] == (*aIfPtr)->iInfoPtr->iClass.iProtocolNum);
+
+	if ((*aIfPtr)->iNumber != 0 && ifDescriptor[KIfcDesc_NumberOffset] != (*aIfPtr)->iNumber)
+		{
+		ifDescriptor[KIfcDesc_NumberOffset] = (*aIfPtr)->iNumber;
+		r = iPort[aPortNumber].SetInterfaceDescriptor(0, ifDescriptor); 
+		test_KErrNone(r);
+		}
+	else
+		{
+		(*aIfPtr)->iNumber = ifDescriptor[KIfcDesc_NumberOffset];	
+		}
+	TUint8 interfaceNumber = (*aIfPtr)->iNumber;
+	TUSB_PRINT1 ("Interface Number %d",interfaceNumber);
+	test.End();
+	}
+
+
+TInt CTransferServer::SetupLdds(TDes& aFileName)
+	{
+	TInt r;
+	User::LeaveIfError(iFs.Connect());
+
+	RDebug::Printf ("Configuration");
+	
+	RDebug::Printf ("Open configuration file");
+	// set the session path to use the ROM if no drive specified
+	r=iFs.SetSessionPath(_L("Z:\\test\\"));
+	test_KErrNone(r);
+
+	r = iConfigFile.Open(iFs, aFileName, EFileShareReadersOnly | EFileStreamText | EFileRead);
+	test_KErrNone(r);
+	RDebug::Printf("Configuration file %s Opened successfully", aFileName.PtrZ());
+
+	RDebug::Printf ("Process configuration file");
+	test(ProcessConfigFile (iConfigFile,NULL,&iLddPtr));
+	
+	iConfigFile.Close();
+	iFs.Close();
+
+	RDebug::Printf ("LDD in configuration file");
+	test_NotNull(iLddPtr);
+		
+	LDDConfigPtr lddPtr = iLddPtr;
+	TInt nextPort = 0;
+	while (lddPtr != NULL)
+		{
+		// Load logical driver (LDD)
+		// (There's no physical driver (PDD) with USB: it's a kernel extension DLL which
+		//	was already loaded at boot time.)
+		RDebug::Printf ("Loading USB LDD");
+		TUSB_PRINT1("Loading USB LDD ",lddPtr->iName.PtrZ());
+		r = User::LoadLogicalDevice(lddPtr->iName);
+		test(r == KErrNone || r == KErrAlreadyExists);
+	
+		IFConfigPtr ifPtr = lddPtr->iIFPtr;
+		
+		RDebug::Printf ("Opening Channels");
+		for (TInt portNumber = nextPort; portNumber < nextPort+lddPtr->iNumChannels; portNumber++)
+			{
+			test_Compare(lddPtr->iNumChannels,>,0);
+			test_Compare(lddPtr->iNumChannels,==,1);
+
+			// Open USB channel
+			r = iPort[portNumber].Open(0);
+			test_KErrNone(r);
+			TUSB_PRINT("Successfully opened USB port");
+
+			// Query the USB device/Setup the USB interface
+			if (portNumber == nextPort)
+				{
+				// Change some descriptors to contain suitable values
+				//SetupDescriptors(lddPtr, &iPort[portNumber]);
+				}
+				
+
+			test_NotNull(ifPtr);
+			
+			if (iSupportResourceAllocationV2)
+				{
+				PopulateInterfaceResourceAllocation(ifPtr, portNumber);
+				}
+				
+			SetupInterface(&ifPtr,portNumber);
+					
+	#ifdef USB_SC
+//			RChunk *tChunk = &gChunk;
+			test_KErrNone(iPort[portNumber].FinalizeInterface());
+	#endif
+
+			}
+	
+		iTotalChannels += lddPtr->iNumChannels;
+		nextPort += lddPtr->iNumChannels;	
+		lddPtr = lddPtr->iPtrNext;	
+		}
+		
+	TUSB_PRINT("All Interfaces and Alternate Settings successfully set up");
+	
+	iTransferHandle->StartTimer();
+
+	return KErrNone;
+	}
+
+void CTransferServer::QueryUsbClientL(LDDConfigPtr aLddPtr, RDEVCLIENT* aPort)
+	{
+	test.Start(_L("Query device and Endpoint Capabilities"));
+
+
+	TUsbDeviceCaps d_caps;
+	TInt r = aPort->DeviceCaps(d_caps);
+	test_KErrNone(r);
+
+	const TInt n = d_caps().iTotalEndpoints;
+
+	TUSB_PRINT("###  USB device capabilities:");
+	TUSB_PRINT1("Number of endpoints:				 %d", n);
+	TUSB_PRINT1("Supports Software-Connect: 		 %s",
+				d_caps().iConnect ? _S("yes") : _S("no"));
+	TUSB_PRINT1("Device is Self-Powered:			 %s",
+				d_caps().iSelfPowered ? _S("yes") : _S("no"));
+	TUSB_PRINT1("Supports Remote-Wakeup:			 %s",
+				d_caps().iRemoteWakeup ? _S("yes") : _S("no"));
+	TUSB_PRINT1("Supports High-speed:				 %s",
+				d_caps().iHighSpeed ? _S("yes") : _S("no"));
+	TUSB_PRINT1("Supports unpowered cable detection: %s\n",
+				(d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_CableDetectWithoutPower) ?
+				_S("yes") : _S("no"));
+	TUSB_PRINT1("Supports endpoint resource allocation v2 scheme: %s\n",
+				(d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_EndpointResourceAllocV2) ?
+				_S("yes") : _S("no"));					
+	TUSB_PRINT("");
+
+	iSoftwareConnect = d_caps().iConnect;					// we need to remember this
+	test_Equal(aLddPtr->iSoftConnect,iSoftwareConnect);
+
+	iSupportResourceAllocationV2 = ((d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_EndpointResourceAllocV2) != 0);
+	
+	// only check capabilities if set; therefore allowing them to be disabled
+	if (aLddPtr->iSelfPower)
+		{
+		test(d_caps().iSelfPowered);	
+		}
+	
+	// only check capabilities if set; therefore allowing them to be disabled
+	if (aLddPtr->iRemoteWakeup)
+		{
+		test(d_caps().iRemoteWakeup);		
+		}
+
+	test_Equal(d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_CableDetectWithoutPower,aLddPtr->iFeatures);
+
+	// only check capability if set; therefore allowing it to be disabled
+	if (aLddPtr->iHighSpeed)
+		{
+		test(d_caps().iHighSpeed);		
+		}
+	
+	test_Equal(aLddPtr->iNumEndpoints,n);
+
+	// Endpoints
+	TUsbcEndpointData data[KUsbcMaxEndpoints];
+	TPtr8 dataptr(reinterpret_cast<TUint8*>(data), sizeof(data), sizeof(data));
+	r = aPort->EndpointCaps(dataptr);
+	test_KErrNone(r);
+
+	TUSB_PRINT("### USB device endpoint capabilities:");
+	for (TInt i = 0; i < n; i++)
+		{
+		const TUsbcEndpointCaps* caps = &data[i].iCaps;
+		
+		
+		TBuf<40> sizeStr(_S("unknown"));
+		if (caps->iSizes == KUsbEpNotAvailable)
+			{
+			sizeStr = _S("Not Available");	
+			}		
+		else
+			{
+			sizeStr.SetLength(0);
+			if (caps->iSizes & KUsbEpSizeCont)
+				sizeStr.Append(_S(" Continuous"),11);
+			if (caps->iSizes & KUsbEpSize8)
+				sizeStr.Append(_S(" 8"),2);
+			if (caps->iSizes & KUsbEpSize16)
+				sizeStr.Append(_S(" 16"),3);
+			if (caps->iSizes & KUsbEpSize32)
+				sizeStr.Append(_S(" 32"),3);
+			if (caps->iSizes & KUsbEpSize64)
+				sizeStr.Append(_S(" 64"),3);
+			if (caps->iSizes & KUsbEpSize128)
+				sizeStr.Append(_S(" 128"),4);
+			if (caps->iSizes & KUsbEpSize256)
+				sizeStr.Append(_S(" 256"),4);
+			if (caps->iSizes & KUsbEpSize512)
+				sizeStr.Append(_S(" 512"),4);
+			if (caps->iSizes & KUsbEpSize1023)
+				sizeStr.Append(_S(" 1023"),5);
+			if (caps->iSizes & KUsbEpSize1024)
+				sizeStr.Append(_S(" 1024"),5);
+			}
+
+		TBuf<40> typeStr(_S("unknown"));
+		if (caps->iTypesAndDir == KUsbEpNotAvailable)
+			typeStr = _S("Not Available");
+		if (caps->iTypesAndDir & (KUsbEpTypeControl | KUsbEpTypeBulk | KUsbEpTypeInterrupt | KUsbEpTypeIsochronous))
+			{
+			typeStr.SetLength(0);
+			if (caps->iTypesAndDir & KUsbEpTypeBulk)
+				typeStr.Append(_S("Control "),8);
+			if (caps->iTypesAndDir & KUsbEpTypeBulk)
+				typeStr.Append(_S("Bulk "),5);
+			if (caps->iTypesAndDir & KUsbEpTypeInterrupt)
+				typeStr.Append(_S("Interrupt "),10);
+			if (caps->iTypesAndDir & KUsbEpTypeIsochronous)
+				typeStr.Append(_S("Isochronous"),11);			
+			}
+			
+		TBuf<20> directionStr(_S("unknown"));
+		
+		if (caps->iTypesAndDir & KUsbEpDirIn)
+			directionStr = _S("In");
+		if (caps->iTypesAndDir & KUsbEpDirOut)
+			directionStr = _S("Out");
+		if (caps->iTypesAndDir & KUsbEpDirBidirect)
+			directionStr = _S("Both");
+				
+		TUSB_PRINT4("Endpoint:%d Sizes =%s Type = %s - %s",
+					i+1,sizeStr.PtrZ(), typeStr.PtrZ(), directionStr.PtrZ());
+		}
+	TUSB_PRINT("");
+
+	test.End();
+			
+	}
+