os/kernelhwsrv/kerneltest/e32test/usb/t_usb_device/src/activecontrol.cpp
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
     1 // Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     4 // under the terms of the License "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     7 //
     8 // Initial Contributors:
     9 // Nokia Corporation - initial contribution.
    10 //
    11 // Contributors:
    12 //
    13 // Description:
    14 // e32test/usb/t_usb_device/src/activecontrol.cpp
    15 // USB Test Program T_USB_DEVICE, functional part.
    16 // Device-side part, to work against T_USB_HOST running on the host.
    17 // 
    18 //
    19 
    20 
    21 #include "general.h"									
    22 #include "usblib.h"											// Helpers
    23 #include "config.h"
    24 #include "activecontrol.h"
    25 #include "apitests.h"
    26 #include "activerw.h"
    27 
    28 void StartMassStorage(RDEVCLIENT* aPort);
    29 void StopMassStorage(RDEVCLIENT* aPort);
    30 
    31 enum Ep0Requests
    32 	{
    33 	EStop = 0x1,
    34 	EVersion = 0x10,
    35 	ETestParam = 0x20,
    36 	ETestResult = 0x30,
    37 	ETestFail = 0x40,
    38 	ETestConnect = 0x50,
    39 	ETestDisconnect = 0x60,
    40 	ETestMassStorage = 0x70,
    41 	ETestIdleCounter = 0x80,
    42 	};
    43 
    44 extern RTest test;
    45 extern TBool gVerbose;
    46 extern TBool gSkip;
    47 extern TBool gTempTest;
    48 extern TBool gStopOnFail;
    49 extern TBool gAltSettingOnNotify;
    50 extern TInt gSoakCount;
    51 extern CActiveRW* gRW[KMaxConcurrentTests];				// the USB read/write active object
    52 extern IFConfigPtr gInterfaceConfig [128] [KMaxInterfaceSettings];
    53 extern TInt gActiveTestCount;
    54 #ifdef USB_SC
    55 extern RChunk gChunk;
    56 #endif
    57 
    58 TInt firstBulkOutEndpoint = -1;
    59 
    60 _LIT(KTestIdleCounterChunkName, "TestIdleCounter");
    61 _LIT(KTestIdleCounterPanic, "IdleCounter");
    62 
    63 enum TTestIdleCounterPanic
    64 	{
    65 	ETestIdleCounterWrongCommand
    66 	};
    67 
    68 enum TTestIdleCounterCommand
    69 	{
    70 	ETestIdleCounterDoNothing,
    71 	ETestIdleCounterReset,
    72 	ETestIdleCounterClose
    73 	};
    74 
    75 struct TTestIdleCounter
    76 	{
    77 	volatile TInt64 iCounter;
    78 	volatile TTestIdleCounterCommand iCommand;
    79 	};
    80 
    81 TInt IdleCounterThread(TAny*)
    82 	{
    83 	TInt r;
    84 	//
    85 	RThread().SetPriority(EPriorityAbsoluteVeryLow);
    86 	//
    87 	RChunk chunk;
    88 	r = chunk.CreateGlobal(KTestIdleCounterChunkName,
    89 			sizeof(struct TTestIdleCounter),
    90 			sizeof(struct TTestIdleCounter) + 1);
    91 	if (r == KErrNone)
    92 		{
    93 		struct TTestIdleCounter* counter = (struct TTestIdleCounter*) chunk.Base();
    94 		counter->iCounter = 0;
    95 		counter->iCommand = ETestIdleCounterDoNothing;
    96 		//
    97 		FOREVER
    98 			{
    99 			TInt command = counter->iCommand;
   100 			if (command == ETestIdleCounterReset)
   101 				{
   102 				counter->iCounter = 0;
   103 				counter->iCommand = ETestIdleCounterDoNothing;
   104 				}
   105 			else if (command == ETestIdleCounterClose)
   106 				{
   107 				break;
   108 				}
   109 			else if (command != ETestIdleCounterDoNothing)
   110 				{
   111 				RThread().Panic(KTestIdleCounterPanic, ETestIdleCounterWrongCommand);
   112 				}
   113 			//
   114 			counter->iCounter++;
   115 			}
   116 		//
   117 		chunk.Close();
   118 		}
   119 	return r;
   120 	}
   121 
   122 //
   123 // --- class CActiveControl ---------------------------------------------------------
   124 //
   125 
   126 CActiveControl::CActiveControl(CConsoleBase* aConsole, TDes * aConfigFile, TDes * aScriptFile)
   127 	: CActive(EPriorityNormal),
   128 	  iConsole(aConsole),
   129 	  iSoftwareConnect(EFalse),
   130 	  iHighSpeed(EFalse),
   131 	  iConfigFileName(aConfigFile),
   132 	  iScriptFileName(aScriptFile),
   133 	  iEp0PacketSize(0)
   134 	{}
   135 
   136 
   137 CActiveControl* CActiveControl::NewLC(CConsoleBase* aConsole, TDes * aConfigFile, TDes * aScriptFile)
   138 	{
   139 	CActiveControl* self = new (ELeave) CActiveControl(aConsole, aConfigFile, aScriptFile);
   140 	CleanupStack::PushL(self);
   141 	self->ConstructL();
   142 	return self;
   143 	}
   144 
   145 
   146 CActiveControl* CActiveControl::NewL(CConsoleBase* aConsole, TDes * aConfigFile, TDes * aScriptFile)
   147 	{
   148 	CActiveControl* self = NewLC(aConsole, aConfigFile, aScriptFile);
   149 	CleanupStack::Pop();
   150 	return self;
   151 	}
   152 
   153 
   154 void CActiveControl::ConstructL()
   155 	{
   156 	CActiveScheduler::Add(this);
   157 	TInt r;
   158 	
   159 	User::LeaveIfError(iFs.Connect());
   160 
   161 	test.Start (_L("Configuration"));
   162 	
   163 	test_Compare(iConfigFileName->Length(),!=,0);
   164 		
   165 	iTimer.CreateLocal();
   166 	iPending = EPendingNone;
   167 	
   168 	test.Next (_L("Open configuration file"));
   169 	// set the session path to use the ROM if no drive specified
   170 	r=iFs.SetSessionPath(_L("Z:\\test\\"));
   171 	test_KErrNone(r);
   172 
   173 	r = iConfigFile.Open(iFs, * iConfigFileName, EFileShareReadersOnly | EFileStreamText | EFileRead);
   174 	test_KErrNone(r);
   175 	TUSB_VERBOSE_PRINT1("Configuration file %s Opened successfully", iConfigFileName->PtrZ());
   176 
   177 	test.Next (_L("Process configuration file"));
   178 	test(ProcessConfigFile (iConfigFile,iConsole,&iLddPtr));
   179 	
   180 	iConfigFile.Close();
   181 
   182 	test.Next (_L("LDD in configuration file"));
   183 	test_NotNull(iLddPtr);
   184 		
   185 	LDDConfigPtr lddPtr = iLddPtr;
   186 	TInt nextPort = 0;
   187 	while (lddPtr != NULL)
   188 		{
   189 		// Load logical driver (LDD)
   190 		// (There's no physical driver (PDD) with USB: it's a kernel extension DLL which
   191 		//  was already loaded at boot time.)
   192 		test.Next (_L("Loading USB LDD"));
   193 		TUSB_VERBOSE_PRINT1("Loading USB LDD ",lddPtr->iName.PtrZ());
   194 		r = User::LoadLogicalDevice(lddPtr->iName);
   195 		test(r == KErrNone || r == KErrAlreadyExists);
   196 	
   197 		IFConfigPtr ifPtr = lddPtr->iIFPtr;
   198 		
   199 		test.Next (_L("Opening Channels"));
   200 		for (TInt portNumber = nextPort; portNumber < nextPort+lddPtr->iNumChannels; portNumber++)
   201 			{
   202 			test_Compare(lddPtr->iNumChannels,>,0);
   203 
   204 			// Open USB channel
   205 			r = iPort[portNumber].Open(0);
   206 			test_KErrNone(r);
   207 			TUSB_VERBOSE_PRINT("Successfully opened USB port");
   208 
   209 			// Query the USB device/Setup the USB interface
   210 			if (portNumber == nextPort)
   211 				{
   212 				// Change some descriptors to contain suitable values
   213 				SetupDescriptors(lddPtr, &iPort[portNumber]);
   214 				}
   215 				
   216 			if (portNumber == 0)
   217 				{
   218 				QueryUsbClientL(lddPtr, &iPort[portNumber]);
   219 				}
   220 
   221 			test_NotNull(ifPtr);
   222 
   223 			IFConfigPtr defaultIfPtr = ifPtr;
   224 			SetupInterface(&ifPtr,portNumber);
   225 					
   226 			#ifdef USB_SC
   227 			RChunk *tChunk = &gChunk;
   228 			test_KErrNone(iPort[portNumber].FinalizeInterface(tChunk));
   229 			#endif
   230 
   231 			// 	allocate endpoint DMA and double buffering for all endpoints on default interface
   232 			for (TUint8 i = 1; i <= defaultIfPtr->iInfoPtr->iTotalEndpointsUsed; i++)
   233 				{
   234 				defaultIfPtr->iEpDMA[i-1] ? AllocateEndpointDMA(&iPort[portNumber],(TENDPOINTNUMBER)i) : DeAllocateEndpointDMA(&iPort[portNumber],(TENDPOINTNUMBER)i);
   235 				#ifndef USB_SC
   236 				defaultIfPtr->iEpDoubleBuff[i-1] ? AllocateDoubleBuffering(&iPort[portNumber],(TENDPOINTNUMBER)i) : DeAllocateDoubleBuffering(&iPort[portNumber],(TENDPOINTNUMBER)i);
   237 				#endif
   238 				}				
   239 
   240 			}
   241 	
   242 		iTotalChannels += lddPtr->iNumChannels;
   243 		nextPort += lddPtr->iNumChannels;	
   244 		lddPtr = lddPtr->iPtrNext;	
   245 		}
   246 		
   247 	TUSB_VERBOSE_PRINT("All Interfaces and Alternate Settings successfully set up");
   248 	
   249 	test.Next (_L("Start Idle Counter Thread"));
   250 	r = iIdleCounterThread.Create(_L("IdleCounter"), IdleCounterThread, KDefaultStackSize, KMinHeapSize, KMinHeapSize, NULL);
   251 	test_KErrNone(r);
   252 	iIdleCounterThread.Resume();
   253 	// Allow some time for low-priority counter process
   254 	User::After(100000); // 0.1 second
   255 	r = iIdleCounterChunk.OpenGlobal(KTestIdleCounterChunkName, EFalse);
   256 	test_KErrNone(r);
   257 	iIdleCounter = (struct TTestIdleCounter*) iIdleCounterChunk.Base();
   258 	test_NotNull(iIdleCounter);
   259 	// Allow some time for low-priority counter process
   260 	User::After(100000); // 0.1 second
   261 	TInt64 val1 = iIdleCounter->iCounter;
   262 	User::After(1000000); // 1 second
   263 	TInt64 val2 = iIdleCounter->iCounter;
   264 	TUSB_PRINT1("Idle Counter when test inactive: %Ldinc/ms", (val2 - val1) / 1000);
   265 
   266 	test.Next (_L("Enumeration..."));
   267 	r = ReEnumerate();
   268 	test_KErrNone(r);
   269 		
   270 	TUSB_VERBOSE_PRINT("Device successfully re-enumerated\n");
   271 
   272 
   273 	if (iLddPtr->iHighSpeed && !gSkip)
   274 		{
   275 		test.Next (_L("High Speed"));
   276 		test(iHighSpeed);	
   277 		}
   278 			
   279 	test.Next (_L("Create Notifiers"));
   280 	for (TInt portNumber = 0; portNumber < iTotalChannels; portNumber++)
   281 		{
   282 
   283 		// Create device state active object
   284 		iDeviceStateNotifier[portNumber] = CActiveDeviceStateNotifier::NewL(iConsole, &iPort[portNumber], portNumber);
   285 		test_NotNull(iDeviceStateNotifier[portNumber]);
   286 		iDeviceStateNotifier[portNumber]->Activate();
   287 		TUSB_VERBOSE_PRINT("Created device state notifier");
   288 
   289 		// Create endpoint stall status active object
   290 		iStallNotifier[portNumber] = CActiveStallNotifier::NewL(iConsole, &iPort[portNumber]);
   291 		test_NotNull(iStallNotifier[portNumber]);
   292 		iStallNotifier[portNumber]->Activate();
   293 		TUSB_VERBOSE_PRINT("Created stall notifier");
   294 			
   295 		TestInvalidSetInterface (&iPort[portNumber],iNumInterfaceSettings[portNumber]);			
   296 		TestInvalidReleaseInterface (&iPort[portNumber],iNumInterfaceSettings[portNumber]);
   297 			
   298 		}
   299 		
   300 	test.Next (_L("Endpoint Zero Max Packet Sizes"));
   301 	TUint ep0Size = iPort[0].EndpointZeroMaxPacketSizes();
   302 	switch (ep0Size)
   303 		{
   304 		case KUsbEpSize8 :
   305 			iEp0PacketSize = 8;
   306 			break;
   307 					
   308 		case KUsbEpSize16 :
   309 			iEp0PacketSize = 16;
   310 			break;
   311 
   312 		case KUsbEpSize32 :
   313 			iEp0PacketSize = 32;
   314 			break;
   315 
   316 		case KUsbEpSize64 :
   317 			iEp0PacketSize = 64;
   318 			break;
   319 					
   320 		default:
   321 			iEp0PacketSize = 0;
   322 			break;		
   323 		}
   324 	test_Compare(iEp0PacketSize,>,0);
   325 
   326 	test.Next (_L("Set Device Control"));
   327 	r = iPort[0].SetDeviceControl();
   328 	test_KErrNone(r);
   329 
   330 	#ifdef USB_SC
   331 	r = iPort[0].OpenEndpoint(iEp0Buf,0);
   332 	test_KErrNone(r);
   333 	#endif
   334 	
   335 	test.End();
   336 	
   337 	}
   338 
   339 void CActiveControl::ReConnect()
   340 	{
   341 	TInt r;
   342 
   343 	test.Start (_L("Reconnecting USB"));
   344 	LDDConfigPtr lddPtr = iLddPtr;
   345 	TInt nextPort = 0;
   346 	while (lddPtr != NULL)
   347 		{
   348 		IFConfigPtr ifPtr = lddPtr->iIFPtr;
   349 		
   350 		test.Next (_L("Opening Channels"));
   351 		for (TInt portNumber = nextPort; portNumber < nextPort+lddPtr->iNumChannels; portNumber++)
   352 			{
   353 			// Open USB channel
   354 			r = iPort[portNumber].Open(0);
   355 			test_KErrNone(r);
   356 			TUSB_VERBOSE_PRINT("Successfully opened USB port");
   357 
   358 			// Query the USB device/Setup the USB interface
   359 			if (portNumber == nextPort)
   360 				{
   361 				// Change some descriptors to contain suitable values
   362 				SetupDescriptors(lddPtr, &iPort[portNumber]);
   363 				}
   364 				
   365 			IFConfigPtr defaultIfPtr = ifPtr;
   366 			SetupInterface(&ifPtr,portNumber);
   367 					
   368 			#ifdef USB_SC
   369 			RChunk *tChunk = &gChunk;
   370 			test_KErrNone(iPort[portNumber].FinalizeInterface(tChunk));
   371 			#endif
   372 
   373 			// 	allocate endpoint DMA and double buffering for all endpoints on default interface
   374 			for (TUint8 i = 1; i <= defaultIfPtr->iInfoPtr->iTotalEndpointsUsed; i++)
   375 				{
   376 				defaultIfPtr->iEpDMA[i-1] ? AllocateEndpointDMA(&iPort[portNumber],(TENDPOINTNUMBER)i) : DeAllocateEndpointDMA(&iPort[portNumber],(TENDPOINTNUMBER)i);
   377 				#ifndef USB_SC
   378 				defaultIfPtr->iEpDoubleBuff[i-1] ? AllocateDoubleBuffering(&iPort[portNumber],(TENDPOINTNUMBER)i) : DeAllocateDoubleBuffering(&iPort[portNumber],(TENDPOINTNUMBER)i);
   379 				#endif
   380 				}				
   381 			}
   382 	
   383 		nextPort += lddPtr->iNumChannels;	
   384 		lddPtr = lddPtr->iPtrNext;	
   385 		}
   386 		
   387 	TUSB_VERBOSE_PRINT("All Interfaces and Alternate Settings successfully set up");
   388 
   389 	test.Next (_L("Enumeration..."));
   390 	r = ReEnumerate();
   391 	test_KErrNone(r);
   392 		
   393 	TUSB_VERBOSE_PRINT("Device successfully re-enumerated\n");
   394 	
   395 	for (TInt portNumber = 0; portNumber < iTotalChannels; portNumber++)
   396 		{
   397 		// Create device state active object
   398 		iDeviceStateNotifier[portNumber] = CActiveDeviceStateNotifier::NewL(iConsole, &iPort[portNumber], portNumber);
   399 		test_NotNull(iDeviceStateNotifier[portNumber]);
   400 		iDeviceStateNotifier[portNumber]->Activate();
   401 		TUSB_VERBOSE_PRINT("Created device state notifier");
   402 
   403 		// Create endpoint stall status active object
   404 		iStallNotifier[portNumber] = CActiveStallNotifier::NewL(iConsole, &iPort[portNumber]);
   405 		test_NotNull(iStallNotifier[portNumber]);
   406 		iStallNotifier[portNumber]->Activate();
   407 		TUSB_VERBOSE_PRINT("Created stall notifier");
   408 
   409 		if (portNumber == 0)
   410 			{
   411 			test.Next (_L("Set Device Control"));
   412 			r = iPort[portNumber].SetDeviceControl();
   413 			test_KErrNone(r);
   414 
   415 			#ifdef USB_SC
   416 			r = iPort[portNumber].OpenEndpoint(iEp0Buf,0);
   417 			test_KErrNone(r);
   418 			#endif
   419 			
   420 			}
   421 		}
   422 	
   423 	test.End();
   424 	}
   425 	
   426 void CActiveControl::SetupInterface(IFConfigPtr* aIfPtr, TInt aPortNumber)
   427 	{
   428 	test.Start (_L("Setup Interface"));
   429 	
   430 	// first of all set the default interface	
   431 	TUSB_PRINT2 ("Set Default Interface with %d endpoints bandwidth 0x%x",(*aIfPtr)->iInfoPtr->iTotalEndpointsUsed,(*aIfPtr)->iBandwidthIn | (*aIfPtr)->iBandwidthOut);
   432 	#ifdef USB_SC
   433 	TUsbcScInterfaceInfoBuf ifc = *((*aIfPtr)->iInfoPtr);
   434 	TInt r = iPort[aPortNumber].SetInterface(0, ifc);
   435 	#else
   436 	TUsbcInterfaceInfoBuf ifc = *((*aIfPtr)->iInfoPtr);
   437 	TInt r = iPort[aPortNumber].SetInterface(0, ifc, (*aIfPtr)->iBandwidthIn | (*aIfPtr)->iBandwidthOut);
   438 	#endif
   439 	test_KErrNone(r);
   440 
   441 	TBuf8<KUsbDescSize_Interface> ifDescriptor;
   442 	r = iPort[aPortNumber].GetInterfaceDescriptor(0, ifDescriptor);
   443 	test_KErrNone(r);
   444 
   445 	// Check the interface descriptor
   446 	test(ifDescriptor[KIfcDesc_SettingOffset] == 0 && ifDescriptor[KIfcDesc_NumEndpointsOffset] == (*aIfPtr)->iInfoPtr->iTotalEndpointsUsed &&
   447 	    ifDescriptor[KIfcDesc_ClassOffset] == (*aIfPtr)->iInfoPtr->iClass.iClassNum &&
   448 	    ifDescriptor[KIfcDesc_SubClassOffset] == (*aIfPtr)->iInfoPtr->iClass.iSubClassNum &&
   449 	    ifDescriptor[KIfcDesc_ProtocolOffset] == (*aIfPtr)->iInfoPtr->iClass.iProtocolNum);
   450 
   451 	if ((*aIfPtr)->iNumber != 0 && ifDescriptor[KIfcDesc_NumberOffset] != (*aIfPtr)->iNumber)
   452 		{
   453 		ifDescriptor[KIfcDesc_NumberOffset] = (*aIfPtr)->iNumber;
   454 		r = iPort[aPortNumber].SetInterfaceDescriptor(0, ifDescriptor);	
   455 		test_KErrNone(r);
   456 		}
   457 	else
   458 		{
   459 		(*aIfPtr)->iNumber = ifDescriptor[KIfcDesc_NumberOffset];	
   460 		}
   461 	TUint8 interfaceNumber = (*aIfPtr)->iNumber;
   462 	TUSB_PRINT1 ("Interface Number %d",interfaceNumber);
   463 		
   464 	// Check all endpoint descriptors
   465 	TBuf8<KUsbDescSize_AudioEndpoint> epDescriptor;
   466 	for (TUint i = 0; i < (*aIfPtr)->iInfoPtr->iTotalEndpointsUsed; i++)
   467 		{
   468 		if (!gSkip)
   469 			{
   470 			TestEndpointDescriptor (&iPort[aPortNumber],0,i+1,(*aIfPtr)->iInfoPtr->iEndpointData[i]);	
   471 
   472 			}
   473 
   474 		if (firstBulkOutEndpoint < 0 && ((*aIfPtr)->iInfoPtr->iEndpointData[i].iDir & KUsbEpDirOut) &&
   475 			(*aIfPtr)->iInfoPtr->iEndpointData[i].iType == KUsbEpTypeBulk)
   476 			{
   477 			firstBulkOutEndpoint = i+1;	
   478 			}
   479 		}
   480 
   481 	TUSB_PRINT1 ("Interface number is %d",interfaceNumber);
   482 	(*aIfPtr)->iPortNumber = aPortNumber;
   483 	gInterfaceConfig [interfaceNumber] [0] = *aIfPtr;
   484 
   485 	TInt alternateNumber = 1;
   486 	// check for any alternatate interfaces and set any that are found
   487 	* aIfPtr = (*aIfPtr)->iPtrNext;
   488 	if (* aIfPtr != NULL)
   489 		{
   490 		test(SupportsAlternateInterfaces());
   491 
   492 		IFConfigPtr ifPtr = *aIfPtr;
   493 		while (ifPtr != NULL)
   494 			{
   495 			if (ifPtr->iAlternateSetting)
   496 				{
   497 				ifc = *(ifPtr->iInfoPtr);
   498 				#ifdef USB_SC
   499 				TUSB_PRINT2 ("Set Alternate Interface Setting %d with %d endpoints",alternateNumber,ifPtr->iInfoPtr->iTotalEndpointsUsed);
   500 				r = iPort[aPortNumber].SetInterface(alternateNumber, ifc);
   501 				#else
   502 				TUSB_PRINT3 ("Set Alternate Interface Setting %d with %d endpoints bandwidth 0x%x",alternateNumber,ifPtr->iInfoPtr->iTotalEndpointsUsed,ifPtr->iBandwidthIn | iLddPtr->iIFPtr->iBandwidthOut);
   503 				r = iPort[aPortNumber].SetInterface(alternateNumber, ifc, ifPtr->iBandwidthIn | iLddPtr->iIFPtr->iBandwidthOut);
   504 				#endif
   505 				test_KErrNone(r);
   506 					
   507 				r = iPort[aPortNumber].GetInterfaceDescriptor(alternateNumber, ifDescriptor);
   508 				test_KErrNone(r);
   509 
   510 				// Check the interface descriptor
   511 				test(ifDescriptor[KIfcDesc_SettingOffset] == alternateNumber && ifDescriptor[KIfcDesc_NumEndpointsOffset] == (*aIfPtr)->iInfoPtr->iTotalEndpointsUsed &&
   512 				    ifDescriptor[KIfcDesc_ClassOffset] == (*aIfPtr)->iInfoPtr->iClass.iClassNum &&
   513 				    ifDescriptor[KIfcDesc_SubClassOffset] == (*aIfPtr)->iInfoPtr->iClass.iSubClassNum &&
   514 				    ifDescriptor[KIfcDesc_ProtocolOffset] == (*aIfPtr)->iInfoPtr->iClass.iProtocolNum);
   515 
   516 				// Check all endpoint descriptors
   517 				for (TUint i = 0; i < ifPtr->iInfoPtr->iTotalEndpointsUsed; i++)
   518 					{
   519 					TInt desc_size;
   520 					r = iPort[aPortNumber].GetEndpointDescriptorSize(alternateNumber, i+1, desc_size);
   521 					test_KErrNone(r);
   522 					test_Equal(KUsbDescSize_Endpoint + (*aIfPtr)->iInfoPtr->iEndpointData[i].iExtra,static_cast<TUint>(desc_size));
   523 
   524 					r = iPort[aPortNumber].GetEndpointDescriptor(alternateNumber, i+1, epDescriptor);
   525 					test_KErrNone(r);
   526 					
   527 					test((((*aIfPtr)->iInfoPtr->iEndpointData[i].iDir & KUsbEpDirIn) && (epDescriptor[KEpDesc_AddressOffset] & 0x80) ||
   528 						!((*aIfPtr)->iInfoPtr->iEndpointData[i].iDir & KUsbEpDirIn) && !(epDescriptor[KEpDesc_AddressOffset] & 0x80)) &&
   529 						EpTypeMask2Value((*aIfPtr)->iInfoPtr->iEndpointData[i].iType) == (TUint)(epDescriptor[KEpDesc_AttributesOffset] & 0x03) &&
   530 						(*aIfPtr)->iInfoPtr->iEndpointData[i].iInterval == epDescriptor[KEpDesc_IntervalOffset]);
   531 
   532 
   533 					if (!gSkip && (*aIfPtr)->iInfoPtr->iEndpointData[i].iExtra)
   534 						{
   535 						test.Next(_L("Extended Endpoint Descriptor Manipulation"));
   536 						TUint8 addr = 0x85;										// bogus address
   537 						if (epDescriptor[KEpDesc_SynchAddressOffset] == addr)
   538 							addr++;
   539 						epDescriptor[KEpDesc_SynchAddressOffset] = addr;
   540 						r = iPort[aPortNumber].SetEndpointDescriptor(alternateNumber, i+1, epDescriptor);
   541 						test_KErrNone(r);
   542 
   543 						TBuf8<KUsbDescSize_AudioEndpoint> descriptor2;
   544 						r = iPort[aPortNumber].GetEndpointDescriptor(alternateNumber, i+1, descriptor2);
   545 						test_KErrNone(r);
   546 
   547 						test.Next(_L("Compare endpoint descriptor with value set"));
   548 						r = descriptor2.Compare(epDescriptor);
   549 						test_KErrNone(r);						
   550 						}
   551 					}
   552 				
   553 					
   554 				// if no error move on to the next interface
   555 				ifPtr->iPortNumber = aPortNumber;
   556 				ifPtr->iNumber = interfaceNumber;
   557 				gInterfaceConfig [interfaceNumber] [alternateNumber] = ifPtr;
   558 
   559 				alternateNumber++;
   560 				ifPtr = ifPtr->iPtrNext;
   561 				* aIfPtr = ifPtr;
   562 				}
   563 			else
   564 				{
   565 				ifPtr = NULL;
   566 				}
   567 			}
   568 		}
   569 	iNumInterfaceSettings[aPortNumber] = alternateNumber;
   570 	if (!gSkip)
   571 		{
   572 		TestInvalidSetInterface (&iPort[aPortNumber],iNumInterfaceSettings[aPortNumber]);			
   573 		TestInvalidReleaseInterface (&iPort[aPortNumber],iNumInterfaceSettings[aPortNumber]);
   574 
   575 		TestDescriptorManipulation(iLddPtr->iHighSpeed,&iPort[aPortNumber],alternateNumber);
   576 		TestOtgExtensions(&iPort[aPortNumber]);
   577 		TestEndpoint0MaxPacketSizes(&iPort[aPortNumber]);
   578 		}
   579 		
   580 	test.End();
   581 	}
   582 
   583 
   584 CActiveControl::~CActiveControl()
   585 	{
   586 	TUSB_PRINT("CActiveControl::~CActiveControl()");
   587 
   588 	Cancel();
   589 	
   590 	iTimer.Close();
   591 	
   592 	// delete interfaces		
   593 	while (iLddPtr->iIFPtr)
   594 		{
   595 		IFConfigPtr* ifPtrPtr = & iLddPtr->iIFPtr;
   596 		while ((*ifPtrPtr)->iPtrNext)
   597 			{
   598 			ifPtrPtr = &(*ifPtrPtr)->iPtrNext;
   599 			}
   600 		delete (*ifPtrPtr)->iInfoPtr->iString;
   601 		delete (*ifPtrPtr)->iInfoPtr;
   602 		delete (*ifPtrPtr);
   603 		* ifPtrPtr = NULL;
   604 		}
   605 
   606 	while (iLddPtr)
   607 		{
   608 		LDDConfigPtr* lddPtrPtr = &iLddPtr;	
   609 		while ((*lddPtrPtr)->iPtrNext)
   610 			{
   611 			lddPtrPtr = &(*lddPtrPtr)->iPtrNext;
   612 			}
   613 		delete (*lddPtrPtr)->iManufacturer;
   614 		delete (*lddPtrPtr)->iProduct;
   615 		delete (*lddPtrPtr)->iSerialNumber;
   616 		delete (*lddPtrPtr);
   617 		* lddPtrPtr = NULL;
   618 		}
   619 
   620 	iFs.Close();
   621 	}
   622 
   623 void CActiveControl::DoCancel()
   624 	{
   625 	TUSB_VERBOSE_PRINT("CActiveControl::DoCancel()");
   626 	iConsole->ReadCancel();
   627 	}
   628 
   629 void CActiveControl::SetMSFinished(TBool aState)
   630 	{
   631 	if (aState)
   632 		{
   633 		if (iPending != EPendingEject)
   634 			{
   635 			iPending = EPendingEject;
   636 			iTimer.After(iStatus,KMSFinishedDelay);
   637 			if (!IsActive())
   638 				{
   639 				SetActive();
   640 				}		
   641 			}
   642 		}
   643 	else
   644 		{
   645 		if (iPending == EPendingEject)
   646 			{
   647 			iPending = EPendingCancel;
   648 			iTimer.Cancel();
   649 			}
   650 		}
   651 	}
   652 	
   653 void CActiveControl::RequestEp0ControlPacket()
   654 	{
   655 	TUSB_VERBOSE_PRINT("CActiveControl::RequestEp0ControlPacket()");
   656 	// A request is issued to read a packet for endpoint 0
   657 	__ASSERT_ALWAYS(!IsActive(), User::Panic(KActivePanic, 660));
   658 	#ifdef	USB_SC
   659 	TInt r = 0;
   660 	do
   661 		{
   662 		r = iEp0Buf.GetBuffer (iEp0Packet,iEp0Size,iEp0Zlp,iStatus);
   663 		TUSB_VERBOSE_PRINT4("Get Buffer Return code %d Status %d PacketPtr 0x%x Size %d", r, iStatus.Int(),iEp0Packet,iEp0Size);	
   664 		test_Value(r, (r == KErrNone) || (r == KErrCompletion) || (r == TEndpointBuffer::KStateChange) || (r == KErrAlternateSettingChanged));  
   665 		if (r == KErrCompletion)
   666 			{
   667 			// ignore anything except a setup packet
   668 			if ((TInt)iEp0Size == KSetupPacketSize)
   669 				{
   670 				iEp0SetUpPacket.Copy((TUint8 *)iEp0Packet,iEp0Size);
   671 				r = ProcessEp0ControlPacket();
   672 				}
   673 			}
   674 		else
   675 			{
   676 			if (r == KErrNone)
   677 				{
   678 				iPending = EPendingEp0Read;
   679 				SetActive();
   680 				}
   681 			}
   682 		}
   683 	while ((r == KErrCompletion) || (r == TEndpointBuffer::KStateChange) || (r == KErrAlternateSettingChanged));
   684 	#else
   685 	iPort[0].ReadPacket(iStatus,EEndpoint0, iEp0SetUpPacket,KSetupPacketSize);
   686 	iPending = EPendingEp0Read;
   687 	SetActive();
   688 	#endif
   689 	}
   690 
   691 void CActiveControl::RunL()
   692 	{
   693 	TInt r = KErrNone;
   694 	
   695 	TUSB_VERBOSE_PRINT("CActiveControl::RunL()");
   696 	
   697 	switch (iPending)
   698 		{
   699 		case EPendingNone :
   700 			break;
   701 			
   702 		case EPendingEp0Read :
   703 			iPending = EPendingNone;
   704 			if (iStatus != KErrNone)
   705 				{
   706 				TUSB_PRINT1("ActiveControl::Error %d in Ep0 Read Packet", iStatus.Int());
   707 				test(EFalse);
   708 				}
   709 			#ifdef USB_SC
   710 			// for shared chunks this means that data is available in the buffer
   711 			// but the data has yet to be transferred to a local buffer
   712 			RequestEp0ControlPacket();
   713 			#else
   714 			if (ProcessEp0ControlPacket() == KErrCompletion)
   715 				RequestEp0ControlPacket();
   716 			#endif		
   717 			break;		
   718 
   719 		case EPendingTimer :
   720 			iPending = EPendingNone;
   721 			if (iStatus != KErrNone)
   722 				{
   723 				TUSB_PRINT1("ActiveControl::Error %d in Connection Timer Delay", iStatus.Int());
   724 				test(EFalse);
   725 				}
   726 			r = iPort[0].DeviceConnectToHost();
   727 			test_KErrNone (r);
   728 		
   729 			test.End();
   730 		
   731 			RequestEp0ControlPacket();
   732 			break;
   733 			
   734 		case EPendingEject :
   735 			iPending = EPendingNone;
   736 			if (iStatus != KErrNone)
   737 				{
   738 				TUSB_PRINT1("ActiveControl::Error %d in Eject Timer Delay", iStatus.Int());
   739 				test(EFalse);
   740 				}
   741 			StopMassStorage(&iPort[0]);
   742 			#ifdef USB_SC
   743 				iEp0Buf.Close();
   744 			#endif
   745 			ReConnect();
   746 							
   747 			RequestEp0ControlPacket();
   748 			break;
   749 					
   750 		case EPendingCancel :
   751 			iPending = EPendingNone;
   752 			if (iStatus != KErrNone && iStatus != KErrCancel)
   753 				{
   754 				TUSB_PRINT1("ActiveControl::Error %d in Eject Timer Delay", iStatus.Int());
   755 				test(EFalse);
   756 				}
   757 		}
   758 	
   759 	}
   760 
   761 TInt CActiveControl::ProcessEp0ControlPacket()
   762 	{
   763 	TUint16 value = *reinterpret_cast<TUint16*>(&iEp0SetUpPacket[KUsb_Ep0wValueOffset]);
   764 	TUint16 index = *reinterpret_cast<TUint16*>(&iEp0SetUpPacket[KUsb_Ep0wIndexOffset]);
   765 	TUint16 length= *reinterpret_cast<TUint16*>(&iEp0SetUpPacket[KUsb_Ep0wLengthOffset]);
   766 	TUSB_VERBOSE_PRINT3("ProcessEp0ControlPacket length 0x%x value 0x%x index 0x%x",length,value,index);
   767 	TRequestStatus ep0Status;
   768 	TUint8 host_ver_major;
   769 	TUint8 host_ver_minor;
   770 	TUint8 host_ver_micro;
   771 	TUint8 usbio_ver_major;
   772 	TUint8 usbio_ver_minor;
   773 	#ifndef USB_SC
   774 	TBuf8<KMaxControlPacketSize> ep0DataPacket;
   775 	#endif
   776 	TestParamPtr tpPtr;
   777 	TBool firstSettingThread = (index & KFirstSettingThreadMask) ? ETrue : EFalse;
   778 	TBool lastSettingThread = (index & KLastSettingThreadMask) ? ETrue : EFalse;
   779 	index &= ~(KFirstSettingThreadMask | KLastSettingThreadMask);
   780     CActiveRW* pActiveRW;
   781 	TInt r;
   782 	TBool sendStatus;
   783 
   784 	if (((iEp0SetUpPacket[KUsb_Ep0RequestTypeOffset] & KUsbRequestType_DestMask) == KUsbRequestType_DestDevice) &&
   785 		((iEp0SetUpPacket[KUsb_Ep0RequestTypeOffset] & KUsbRequestType_TypeMask) == KUsbRequestType_TypeClass))
   786 		{
   787 		TUSB_VERBOSE_PRINT("Received Device Directed setup packet");
   788 		if ((iEp0SetUpPacket[KUsb_Ep0RequestTypeOffset] & KUsbRequestType_DirMask) == KUsbRequestType_DirToDev)
   789 			{
   790 			iEp0DataBuffer.SetLength(0);
   791 			while (iEp0DataBuffer.Length() < length)
   792 				{
   793 				TUSB_VERBOSE_PRINT("Reading Ep0 data packet");
   794 				#ifdef USB_SC
   795 				r = iEp0Buf.GetBuffer (iEp0Packet,iEp0Size,iEp0Zlp,ep0Status);
   796 				test_Value(r, r == KErrNone || r == KErrCompletion || (r == KErrAlternateSettingChanged));
   797 				while (r == KErrNone)  
   798 					{
   799 					TUSB_VERBOSE_PRINT("Waiting for Ep0 data packet");
   800 					User::WaitForRequest(ep0Status);
   801 					test_KErrNone(ep0Status.Int());
   802 					r = iEp0Buf.GetBuffer (iEp0Packet,iEp0Size,iEp0Zlp,ep0Status);
   803 					test_Value(r, r == KErrNone || r == KErrCompletion || (r == KErrAlternateSettingChanged));
   804 					}
   805 				TUSB_VERBOSE_PRINT1("Ep0 data packet - size %d",iEp0Size);
   806 				iEp0DataBuffer.Append((TUint8 *)iEp0Packet,iEp0Size);								
   807 				#else
   808 				TUint16 packetLength = Min(length-iEp0DataBuffer.Length(),iEp0PacketSize);
   809 				iPort[0].ReadPacket(ep0Status, EEndpoint0, ep0DataPacket, packetLength);
   810 				User::WaitForRequest(ep0Status);
   811 				if (ep0Status == KErrNone)
   812 					{
   813 					iEp0DataBuffer.Append(ep0DataPacket);				
   814 					}
   815 				else
   816 					{
   817 					TUSB_PRINT1("ActiveControl::Error %d in Ep0 Read Data Packet", ep0Status.Int());
   818 					test(EFalse);
   819 					return KErrNone;						
   820 					}
   821 				#endif
   822 				}
   823 			TUSB_VERBOSE_PRINT4("Setup ToDevice Type %d length %d value %d index %d",iEp0SetUpPacket[KUsb_Ep0RequestOffset],length,value,index);
   824 			sendStatus = ETrue;
   825 			switch (iEp0SetUpPacket[KUsb_Ep0RequestOffset])	
   826 				{
   827 				case EStop :
   828 					// send this now as the port will be disconnected
   829 					sendStatus = EFalse;
   830 					r = iPort[0].SendEp0StatusPacket();					
   831 					test_KErrNone(r);
   832 		
   833 					if (value && firstBulkOutEndpoint > 0)
   834 						{
   835 						PrintHostLog();
   836 						}
   837 						
   838 					for (TInt portNumber = 0; portNumber < iTotalChannels; portNumber++)
   839 						{
   840 						// base class cancel -> calls our DoCancel
   841 						delete iDeviceStateNotifier[portNumber];
   842 						delete iStallNotifier[portNumber];
   843 						if (portNumber == 0)
   844 							{
   845 							r = iPort[portNumber].RemoveStringDescriptor(stridx1);
   846 							if (r != KErrNone)
   847 								{
   848 								TUSB_PRINT1("Error %d on string removal", r);
   849 								}
   850 							r = iPort[portNumber].RemoveStringDescriptor(stridx2);
   851 							if (r != KErrNone)
   852 								{
   853 								TUSB_PRINT1("Error %d on string removal", r);
   854 								}	
   855 							}
   856 						TUSB_VERBOSE_PRINT1 ("Closing USB channel number %d",portNumber);
   857 						iPort[portNumber].Close();											// close USB channel
   858 						}
   859 					TUSB_VERBOSE_PRINT("Closing Idle Counter Thread");
   860 					iIdleCounter->iCommand = ETestIdleCounterClose;
   861 					iIdleCounterChunk.Close();
   862 					// Allow time for low-priority thread to close
   863 					User::After(100000);
   864 					iIdleCounterThread.Close();
   865 					
   866 					CActiveScheduler::Stop();
   867 					break;
   868 					
   869 				case EVersion :
   870 					TUSB_PRINT("Receiving t_usb_host version");
   871 					host_ver_major = iEp0DataBuffer[0];
   872 					host_ver_minor = iEp0DataBuffer[1];
   873 					host_ver_micro = iEp0DataBuffer[2];
   874 					usbio_ver_major = iEp0DataBuffer[3];
   875 					usbio_ver_minor = iEp0DataBuffer[4];
   876 					TUSB_PRINT5("Host-side: t_usb_host v%d.%d.%d  USBIO v%d.%d\n",
   877 						host_ver_major, host_ver_minor, host_ver_micro,
   878 						usbio_ver_major, usbio_ver_minor);
   879 					if (host_ver_major < KHostVersionMajor)
   880 						{
   881 						TUSB_PRINT1("t_usb_host version not sufficient (need at least v%d.x.x)\n",KHostVersionMajor);
   882 						User::Leave(-1);
   883 						return KErrNone;
   884 						}
   885 					// Just using '<' instead of the seemingly absurd '<= && !==' doesn't work without
   886 					// GCC compiler warning because Kxxx can also be zero (in which case there's no '<').
   887 					else if ((host_ver_minor <= KHostVersionMinor) &&
   888 			 				!(host_ver_minor == KHostVersionMinor))
   889 						{
   890 						TUSB_PRINT2("t_usb_host version not sufficient (need at least v%d.%d.x)\n",
   891 							KHostVersionMajor, KHostVersionMinor);
   892 						test(EFalse);
   893 						return KErrNone;
   894 						}
   895 					// Just using '<' instead of the seemingly absurd '<= && !==' doesn't work without
   896 					// GCC compiler warning because Kxxx can also be zero (in which case there's no '<').
   897 					else if ((host_ver_micro <= KHostVersionMicro) &&
   898 			 				!(host_ver_micro == KHostVersionMicro))
   899 						{
   900 						TUSB_PRINT3("USBRFLCT version not sufficient (need at least v%d.%d.%d)\n",
   901 									KHostVersionMajor, KHostVersionMinor, KHostVersionMicro);
   902 						test(EFalse);
   903 						return KErrNone;
   904 						}
   905 					break;
   906 					
   907 				case ETestParam :
   908 					tpPtr = (TestParamPtr)(&iEp0DataBuffer[0]);
   909 					TUSB_VERBOSE_PRINT4("Test Params - interface %d repeat %d settingRepeat %d beforeIndex %d",tpPtr->interfaceNumber,tpPtr->repeat,tpPtr->settingRepeat,tpPtr->beforeIndex);
   910 					if (index >= KMaxConcurrentTests)
   911 						{
   912 						TUSB_PRINT2("Test index %d is greater than maximum allowed (%d) concurrent tests",index,KMaxConcurrentTests);
   913 						test(EFalse);
   914 						return KErrNone;
   915 						}
   916 					// Create Reader/Writer active object
   917 					pActiveRW = CActiveRW::NewL(iConsole, &iPort[gInterfaceConfig[tpPtr->interfaceNumber][tpPtr->alternateSetting]->iPortNumber], iFs, index, lastSettingThread);
   918 					if (!pActiveRW)
   919 						{
   920 						TUSB_PRINT("Failed to create reader/writer");
   921 						test(EFalse);
   922 						return KErrNone;
   923 						}
   924 					TUSB_VERBOSE_PRINT("Created reader/writer");
   925 					pActiveRW->SetTestParams(tpPtr);
   926 					switch (value)
   927 						{
   928 					case 'X' :
   929 						test.Start (_L("Xml"));
   930 						break;
   931 							
   932 					case 'L' :
   933 						test.Start (_L("Loop"));
   934 						pActiveRW->SetTransferMode(ELoop);
   935 						gAltSettingOnNotify = ETrue;
   936 						if (tpPtr->settingRepeat && !firstSettingThread)
   937 							{
   938 							pActiveRW->Suspend(ESuspend);	
   939 							}
   940 						else
   941 							{
   942 							pActiveRW->StartOrSuspend();						
   943 							}
   944 						break;
   945 							
   946 					case 'C' :
   947 						test.Start (_L("Compare"));
   948 						pActiveRW->SetTransferMode(ELoopComp);
   949 						gAltSettingOnNotify = ETrue;
   950 						if (tpPtr->settingRepeat && !firstSettingThread)
   951 							{
   952 							pActiveRW->Suspend(ESuspend);	
   953 							}
   954 						else
   955 							{
   956 							pActiveRW->StartOrSuspend();						
   957 							}
   958 						break;
   959 							
   960 					case 'S' :
   961 						test.Start (_L("Stream"));
   962 						if (tpPtr->outPipe > KMaxEndpointsPerClient)
   963 							{
   964 							pActiveRW->SetTransferMode(ETransmitOnly);						
   965 							gAltSettingOnNotify = ETrue;
   966 							if (tpPtr->settingRepeat && !firstSettingThread)
   967 								{
   968 								pActiveRW->Suspend(ESuspend);	
   969 								}
   970 							else
   971 								{
   972 								pActiveRW->StartOrSuspend();						
   973 								}
   974 							}
   975 						else
   976 							{
   977 							pActiveRW->SetTransferMode(EReceiveOnly);						
   978 							gAltSettingOnNotify = ETrue;
   979 							if (tpPtr->settingRepeat && !firstSettingThread)
   980 								{
   981 								pActiveRW->Suspend(ESuspend);	
   982 								}
   983 							else
   984 								{
   985 								pActiveRW->StartOrSuspend();						
   986 								}
   987 							}					
   988 						break;
   989 							
   990 					case 'F' :
   991 						test.Start (_L("File"));
   992 						// send this now as the file setup takes a long time
   993 						sendStatus = EFalse;
   994 						r = iPort[0].SendEp0StatusPacket();					
   995 						test_KErrNone(r);
   996 						if (tpPtr->outPipe > KMaxEndpointsPerClient)
   997 							{
   998 							pActiveRW->SetTransferMode(ETransmitOnly);
   999 							TInt maxFileSize = tpPtr->maxSize * tpPtr->repeat;						
  1000 							pActiveRW->ReadFromDisk((TChar)tpPtr->minSize,maxFileSize);
  1001 							gAltSettingOnNotify = ETrue;
  1002 							if (tpPtr->settingRepeat && !firstSettingThread)
  1003 								{
  1004 								pActiveRW->Suspend(ESuspend);	
  1005 								}
  1006 							else
  1007 								{
  1008 								pActiveRW->StartOrSuspend();						
  1009 								}
  1010 							}
  1011 						else
  1012 							{
  1013 							pActiveRW->SetTransferMode(EReceiveOnly);						
  1014 							pActiveRW->WriteToDisk((TChar)tpPtr->minSize);
  1015 							gAltSettingOnNotify = ETrue;
  1016 							if (tpPtr->settingRepeat && !firstSettingThread)
  1017 								{
  1018 								pActiveRW->Suspend(ESuspend);	
  1019 								}
  1020 							else
  1021 								{
  1022 								pActiveRW->StartOrSuspend();						
  1023 								}
  1024 							}					
  1025 						break;
  1026 						
  1027 					default :
  1028 						TUSB_PRINT1("Invalid test value %X",value);
  1029 						test(EFalse);
  1030 						}
  1031 						
  1032 					gRW[index] = pActiveRW;
  1033 					break;
  1034 					
  1035 				case ETestResult :
  1036 					TUSB_VERBOSE_PRINT2 ("Test index %d complete - value %d",index,value);
  1037 					// if failure, send this first to prevent panic corrupting EP0 
  1038 					if (!value)
  1039 						{
  1040 						sendStatus = EFalse;
  1041 						r = iPort[0].SendEp0StatusPacket();					
  1042 						}
  1043 					if (index < KMaxConcurrentTests)
  1044 						{
  1045 						if (gRW[index] != NULL)
  1046 							{
  1047 							gRW[index]->TestComplete (value);
  1048 							break;
  1049 							}
  1050 						}
  1051 					if (index == KHostErrorIndex)
  1052 						{
  1053 						if (!value)
  1054 							{
  1055 							TUSB_PRINT("Host Test Fail");							
  1056 							}
  1057 						}
  1058 					else
  1059 						{
  1060 						TUSB_PRINT2("Invalid test index %d for result %d",index,value);
  1061 						}
  1062 					if (!value)
  1063 						{
  1064 						test(EFalse);
  1065 						}
  1066 					break;
  1067 
  1068 				case ETestFail :
  1069 					User::Leave(-1);
  1070 					break;
  1071 
  1072 				case ETestConnect :
  1073 					test.Start (_L("Connect"));
  1074 					sendStatus = EFalse;
  1075 					r = iPort[0].SendEp0StatusPacket();					
  1076 					if (iSoftwareConnect)
  1077 						{
  1078 						r = iPort[0].DeviceDisconnectFromHost();
  1079 						test_KErrNone (r);
  1080 						
  1081 						TUint32 waitTime = (TUint32)value * 1000;
  1082 						if (waitTime == 0)
  1083 							{
  1084 							waitTime = 5000;		// default to 5 milliseconds
  1085 							}
  1086 						iTimer.After(iStatus,waitTime);
  1087 						iPending = EPendingTimer;
  1088 						
  1089 						SetActive();
  1090 						}
  1091 					else
  1092 						{
  1093 						iConsole->Printf(_L("This device does not support software\n"));
  1094 						iConsole->Printf(_L("disconnect/reconnect\n"));
  1095 						iConsole->Printf(_L("Please physically unplug and replug\n"));
  1096 						iConsole->Printf(_L("the USB cable NOW... "));
  1097 						test.End ();
  1098 						}				
  1099 					break;
  1100 
  1101 				case ETestDisconnect :
  1102 					test.Start (_L("Disconnect"));
  1103 					// send this now as the port will be disconnected
  1104 					sendStatus = EFalse;
  1105 					r = iPort[0].SendEp0StatusPacket();					
  1106 					if (iSoftwareConnect)
  1107 						{
  1108 						r = iPort[0].DeviceDisconnectFromHost();
  1109 						test_KErrNone (r);
  1110 						}
  1111 					else
  1112 						{
  1113 						iConsole->Printf(_L("This device does not support software\n"));
  1114 						iConsole->Printf(_L("disconnect/reconnect\n"));
  1115 						iConsole->Printf(_L("Please physically unplug and replug\n"));
  1116 						iConsole->Printf(_L("the USB cable NOW... "));
  1117 						}				
  1118 
  1119 					test.End ();
  1120 					break;
  1121 
  1122 				case ETestMassStorage :
  1123 					test.Start (_L("Select Mass Storage"));
  1124 				
  1125 					// send this now as the port will be disconnected
  1126 					sendStatus = EFalse;
  1127 					r = iPort[0].SendEp0StatusPacket();					
  1128 					test_KErrNone(r);
  1129 			
  1130 					for (TInt portNumber = 0; portNumber < iTotalChannels; portNumber++)
  1131 						{
  1132 						delete iDeviceStateNotifier[portNumber];
  1133 						delete iStallNotifier[portNumber];
  1134 						if (portNumber == 0)
  1135 							{
  1136 							r = iPort[portNumber].RemoveStringDescriptor(stridx1);
  1137 							if (r != KErrNone)
  1138 								{
  1139 								TUSB_PRINT1("Error %d on string removal", r);
  1140 								}
  1141 							r = iPort[portNumber].RemoveStringDescriptor(stridx2);
  1142 							if (r != KErrNone)
  1143 								{
  1144 								TUSB_PRINT1("Error %d on string removal", r);
  1145 								}	
  1146 							}
  1147 						TUSB_VERBOSE_PRINT1 ("Closing USB channel number %d",portNumber);
  1148 						iPort[portNumber].Close();											// close USB channel
  1149 						}
  1150 		
  1151 					r = iPort[0].Open(0);
  1152 					test_KErrNone(r);
  1153 					TUSB_VERBOSE_PRINT("Successfully opened USB port");
  1154 
  1155 					SetupDescriptors(iLddPtr, &iPort[0],value);
  1156 					StartMassStorage(&iPort[0]);
  1157 		
  1158 					test.Next (_L("Enumeration..."));
  1159 					r = ReEnumerate();				
  1160 					test_KErrNone(r);
  1161 
  1162 
  1163 					test.End ();
  1164 					break;
  1165 				}
  1166 			if (sendStatus)
  1167 				{
  1168 				r = iPort[0].SendEp0StatusPacket();
  1169 				if (r != KErrNone)
  1170 					{
  1171 					TUSB_PRINT1("ActiveControl::Error %d in Ep0 Send Status Packet", r);
  1172 					test(EFalse);
  1173 					return KErrNone;						
  1174 					}				
  1175 				}
  1176 			}
  1177 		else
  1178 			{
  1179 			if ((iEp0SetUpPacket[KUsb_Ep0RequestOffset] == EVersion) && length > 0)
  1180 				{
  1181 				TUSB_PRINT4("Sending t_usb_device version: %d.%d.%d length %d \n", KDeviceVersionMajor, KDeviceVersionMinor, KDeviceVersionMicro, length);
  1182 				#ifdef	USB_SC
  1183 				TUint8 *ep0Buffer;
  1184 				TUint8 *ep0BufPtr;
  1185 				TUint ep0Length;
  1186 				iEp0Buf.GetInBufferRange(((TAny*&)ep0Buffer),ep0Length);
  1187 				
  1188 				ep0BufPtr = ep0Buffer;
  1189 				*(ep0Buffer++) = KDeviceVersionMajor;
  1190 				*(ep0Buffer++) = KDeviceVersionMinor;
  1191 				*(ep0Buffer++) = KDeviceVersionMicro;
  1192 				TUint8 i=3;
  1193 				if (iConfigFileName->Length())
  1194 					{
  1195 					for(TUint8 j=0; j < iConfigFileName->Length() && i < length; j++)
  1196 						{
  1197 						i++;
  1198 						*(ep0Buffer++) = (*iConfigFileName)[j];
  1199 						}
  1200 					}
  1201 				if (iScriptFileName->Length())
  1202 					{
  1203 					for(TUint8 j=0; j < iScriptFileName->Length() && i < length; j++)
  1204 						{
  1205 						i++;
  1206 						*(ep0Buffer++) = (*iScriptFileName)[j];
  1207 						}
  1208 					}
  1209 				*(ep0Buffer++) = 0;
  1210 				r = iEp0Buf.WriteBuffer(ep0BufPtr,length,FALSE,ep0Status);
  1211 				test_KErrNone(r);
  1212 				#else				
  1213 				iEp0DataBuffer.FillZ(length);
  1214 				iEp0DataBuffer[0] = KDeviceVersionMajor;
  1215 				iEp0DataBuffer[1] = KDeviceVersionMinor;
  1216 				iEp0DataBuffer[2] = KDeviceVersionMicro;
  1217 				iEp0DataBuffer.SetLength(3);
  1218 				iEp0DataBuffer.Append (*iConfigFileName);
  1219 				iEp0DataBuffer.Append (*iScriptFileName);
  1220 				iEp0DataBuffer.SetLength(length);				
  1221 				iPort[0].Write(ep0Status, EEndpoint0, iEp0DataBuffer, length);
  1222 				#endif
  1223 				User::WaitForRequest(ep0Status);
  1224 				test_KErrNone(ep0Status.Int());
  1225 				}
  1226 			else if ((iEp0SetUpPacket[KUsb_Ep0RequestOffset] == ETestIdleCounter) && length >= sizeof(TInt64))
  1227 				{
  1228 				// for a non zero request value if any tests still active send zero otherwise the counter value
  1229 				TInt64 val = (value == 0 || gActiveTestCount == 0) ? iIdleCounter->iCounter : 0;
  1230 
  1231 				TUSB_PRINT1("Sending counter value %Ld\n", val);
  1232 				#ifdef	USB_SC
  1233 
  1234 				TUint8 *ep0Buffer;
  1235 				TUint ep0Length;
  1236 				iEp0Buf.GetInBufferRange(((TAny*&)ep0Buffer),ep0Length);
  1237 				
  1238 				*((TInt64*) ep0Buffer) = val;
  1239 				
  1240 				r = iEp0Buf.WriteBuffer(ep0Buffer,length,FALSE,ep0Status);
  1241 				test_KErrNone(r);
  1242 				#else				
  1243 
  1244 				iEp0DataBuffer.FillZ(length);
  1245 				*((TInt64*) iEp0DataBuffer.Ptr()) = val;
  1246 				iEp0DataBuffer.SetLength(sizeof(TInt64));
  1247 				iPort[0].Write(ep0Status, EEndpoint0, iEp0DataBuffer, length);
  1248 				#endif
  1249 
  1250 				User::WaitForRequest(ep0Status);
  1251 				test_KErrNone(ep0Status.Int());
  1252 				}
  1253 			}
  1254 		if (iEp0SetUpPacket[KUsb_Ep0RequestOffset] != EStop && iEp0SetUpPacket[KUsb_Ep0RequestOffset] != ETestConnect &&
  1255 			iEp0SetUpPacket[KUsb_Ep0RequestOffset] != ETestMassStorage)
  1256 			{
  1257 			return KErrCompletion;		
  1258 			}				
  1259 		}
  1260 	else
  1261 		{
  1262 		TUSB_PRINT1("Error : Incorrect SetUp Packet Request Type %X", iEp0SetUpPacket[0]);			
  1263 		test(EFalse);
  1264 		return KErrNone;
  1265 		}
  1266 	
  1267 	return KErrNone;
  1268 	}
  1269 	
  1270 void CActiveControl::PrintHostLog()
  1271 	{
  1272 	TRequestStatus status = 0;
  1273 	wchar_t lineBuf[128];
  1274 	TUint j = 0;
  1275 	
  1276 	TUSB_VERBOSE_PRINT("Reading Host log file\n");
  1277 
  1278 	#ifdef USB_SC
  1279 	TInt r = 0;
  1280 	TEndpointBuffer scReadBuf;
  1281 	TAny * scReadData;
  1282 	TUint8 * scCharPtr;
  1283 	TUint readSize;
  1284 	TBool readZlp = EFalse;
  1285 
  1286 	r = iPort->OpenEndpoint(scReadBuf,firstBulkOutEndpoint);
  1287 	test_KErrNone(r);
  1288 	do
  1289 		{
  1290 		r = scReadBuf.GetBuffer (scReadData,readSize,readZlp,status);
  1291 		// The following line can be reinstated once the shared chunk failure is fixed
  1292 		// that prevents the readZlp flag from being set
  1293 		// test_Value(r, (r == KErrNone) || (r == KErrCompletion) || (r == KErrEof));
  1294 		if (r == KErrCompletion)
  1295 			{
  1296 			TUSB_VERBOSE_PRINT1("Host log file %d bytes read\n",readSize);
  1297 			scCharPtr = (TUint8 *)scReadData;
  1298 			// Print the host log file
  1299 			for (TUint i = 0; i < readSize; i++)
  1300 				{
  1301 				if (* scCharPtr == '\r')
  1302 					{
  1303 					lineBuf[j++] = '\0';
  1304 					RDebug::Print (_L("%s"),lineBuf);
  1305 					j = 0;	
  1306 					}
  1307 				else
  1308 					{
  1309 					if (* scCharPtr != '\n')
  1310 						{
  1311 						lineBuf[j++] = * scCharPtr;				
  1312 						}
  1313 					}
  1314 				scCharPtr++;
  1315 				}
  1316 			}
  1317 		if (r == KErrNone)
  1318 			{
  1319 			User::WaitForRequest(status);
  1320 			test_KErrNone(status.Int());	
  1321 			}
  1322 		}
  1323 	while (r >= KErrNone && !readZlp);
  1324 	#else
  1325 	TPtr8 readBuf((TUint8 *)User::Alloc(KHostLogFileSize),KHostLogFileSize,KHostLogFileSize);
  1326 	iPort[0].ReadUntilShort(status, (TEndpointNumber)firstBulkOutEndpoint, readBuf);
  1327 	User::WaitForRequest(status);
  1328 	test_KErrNone(status.Int());
  1329 	TUSB_VERBOSE_PRINT1("Host log file %d bytes read\n",readBuf.Length());
  1330 	for (TUint i = 0; i < readBuf.Length(); i++)
  1331 		{
  1332 		if (readBuf[i] == '\r')
  1333 			{
  1334 			lineBuf[j++] = '\0';
  1335 			RDebug::Print (_L("%s"),lineBuf);
  1336 			j = 0;	
  1337 			}
  1338 		else
  1339 			{
  1340 			if (readBuf[i] != '\n')
  1341 				{
  1342 				lineBuf[j++] = readBuf[i];				
  1343 				}
  1344 			}
  1345 		}
  1346 	User::Free ((TAny *)readBuf.Ptr());
  1347 	#endif
  1348 	}
  1349 	
  1350 void CActiveControl::QueryUsbClientL(LDDConfigPtr aLddPtr, RDEVCLIENT* aPort)
  1351 	{
  1352 	// Get device/endpoint capabilities
  1353 	//
  1354 	// A TPckg, or TPckBuf was not used in the following, because
  1355 	//
  1356 	//	 TPckgBuf<TUsbcEndpointData[KUsbcMaxEndpoints]> databuf;
  1357 	//
  1358 	// doesn't work. Also,
  1359 	//
  1360 	//	 TUsbcEndpointData data[KUsbcMaxEndpoints];
  1361 	//	 TPckgBuf<TUsbcEndpointData[KUsbcMaxEndpoints]> databuf(data);
  1362 	//
  1363 	// doesn't work. Also,
  1364 	//
  1365 	//	 TUsbcEndpointData data[KUsbcMaxEndpoints];
  1366 	//	 TPckgBuf<TUsbcEndpointData[]> databuf(data);
  1367 	//
  1368 	// doesn't work.
  1369 	// So we seem to have to stick to the ugly cast below.
  1370 	//
  1371 	//	 TUsbcEndpointData data[KUsbcMaxEndpoints];
  1372 	//	 TPtr8 databuf(reinterpret_cast<TUint8*>(data), sizeof(data), sizeof(data));
  1373 	//
  1374 
  1375 	// Device
  1376 	// === Device Descriptor
  1377 	
  1378 	test.Start(_L("Query device and Endpoint Capabilities"));
  1379 
  1380 
  1381 	TUsbDeviceCaps d_caps;
  1382 	TInt r = aPort->DeviceCaps(d_caps);
  1383 	test_KErrNone(r);
  1384 
  1385 	const TInt n = d_caps().iTotalEndpoints;
  1386 
  1387 	TUSB_PRINT("###  USB device capabilities:");
  1388 	TUSB_PRINT1("Number of endpoints:                %d", n);
  1389 	TUSB_PRINT1("Supports Software-Connect:          %s",
  1390 				d_caps().iConnect ? _S("yes") : _S("no"));
  1391 	TUSB_PRINT1("Device is Self-Powered:             %s",
  1392 				d_caps().iSelfPowered ? _S("yes") : _S("no"));
  1393 	TUSB_PRINT1("Supports Remote-Wakeup:             %s",
  1394 				d_caps().iRemoteWakeup ? _S("yes") : _S("no"));
  1395 	TUSB_PRINT1("Supports High-speed:                %s",
  1396 				d_caps().iHighSpeed ? _S("yes") : _S("no"));
  1397 	TUSB_PRINT1("Supports unpowered cable detection: %s\n",
  1398 				(d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_CableDetectWithoutPower) ?
  1399 				_S("yes") : _S("no"));
  1400 	TUSB_PRINT("");
  1401 
  1402 	iSoftwareConnect = d_caps().iConnect;					// we need to remember this
  1403 	test_Equal(aLddPtr->iSoftConnect,iSoftwareConnect);
  1404 
  1405 	// only check capabilities if set; therefore allowing them to be disabled
  1406 	if (aLddPtr->iSelfPower)
  1407 		{
  1408 		test(d_caps().iSelfPowered);	
  1409 		}
  1410 	
  1411 	// only check capabilities if set; therefore allowing them to be disabled
  1412 	if (aLddPtr->iRemoteWakeup)
  1413 		{
  1414 		test(d_caps().iRemoteWakeup);		
  1415 		}
  1416 
  1417 	test_Equal(d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_CableDetectWithoutPower,aLddPtr->iFeatures);
  1418 
  1419 	// only check capability if set; therefore allowing it to be disabled
  1420 	if (aLddPtr->iHighSpeed)
  1421 		{
  1422 		test(d_caps().iHighSpeed);		
  1423 		}
  1424 	
  1425 	test_Equal(aLddPtr->iNumEndpoints,n);
  1426 
  1427 	// Endpoints
  1428 	TUsbcEndpointData data[KUsbcMaxEndpoints];
  1429 	TPtr8 dataptr(reinterpret_cast<TUint8*>(data), sizeof(data), sizeof(data));
  1430 	r = aPort->EndpointCaps(dataptr);
  1431 	test_KErrNone(r);
  1432 
  1433 	TUSB_PRINT("### USB device endpoint capabilities:");
  1434 	for (TInt i = 0; i < n; i++)
  1435 		{
  1436 		const TUsbcEndpointCaps* caps = &data[i].iCaps;
  1437 		
  1438 		
  1439 		TBuf<40> sizeStr(_S("unknown"));
  1440 		if (caps->iSizes == KUsbEpNotAvailable)
  1441 			{
  1442 			sizeStr = _S("Not Available");	
  1443 			}		
  1444 		else
  1445 			{
  1446 			sizeStr.SetLength(0);
  1447 			if (caps->iSizes & KUsbEpSizeCont)
  1448 				sizeStr.Append(_S(" Continuous"),11);
  1449 			if (caps->iSizes & KUsbEpSize8)
  1450 				sizeStr.Append(_S(" 8"),2);
  1451 			if (caps->iSizes & KUsbEpSize16)
  1452 				sizeStr.Append(_S(" 16"),3);
  1453 			if (caps->iSizes & KUsbEpSize32)
  1454 				sizeStr.Append(_S(" 32"),3);
  1455 			if (caps->iSizes & KUsbEpSize64)
  1456 				sizeStr.Append(_S(" 64"),3);
  1457 			if (caps->iSizes & KUsbEpSize128)
  1458 				sizeStr.Append(_S(" 128"),4);
  1459 			if (caps->iSizes & KUsbEpSize256)
  1460 				sizeStr.Append(_S(" 256"),4);
  1461 			if (caps->iSizes & KUsbEpSize512)
  1462 				sizeStr.Append(_S(" 512"),4);
  1463 			if (caps->iSizes & KUsbEpSize1023)
  1464 				sizeStr.Append(_S(" 1023"),5);
  1465 			if (caps->iSizes & KUsbEpSize1024)
  1466 				sizeStr.Append(_S(" 1024"),5);
  1467 			}
  1468 
  1469 		TBuf<40> typeStr(_S("unknown"));
  1470 		if (caps->iTypesAndDir == KUsbEpNotAvailable)
  1471 			typeStr = _S("Not Available");
  1472 		if (caps->iTypesAndDir & (KUsbEpTypeControl | KUsbEpTypeBulk | KUsbEpTypeInterrupt | KUsbEpTypeIsochronous))
  1473 			{
  1474 			typeStr.SetLength(0);
  1475 			if (caps->iTypesAndDir & KUsbEpTypeBulk)
  1476 				typeStr.Append(_S("Control "),8);
  1477 			if (caps->iTypesAndDir & KUsbEpTypeBulk)
  1478 				typeStr.Append(_S("Bulk "),5);
  1479 			if (caps->iTypesAndDir & KUsbEpTypeInterrupt)
  1480 				typeStr.Append(_S("Interrupt "),10);
  1481 			if (caps->iTypesAndDir & KUsbEpTypeIsochronous)
  1482 				typeStr.Append(_S("Isochronous"),11);			
  1483 			}
  1484 			
  1485 		TBuf<20> directionStr(_S("unknown"));
  1486 		
  1487 		if (caps->iTypesAndDir & KUsbEpDirIn)
  1488 			directionStr = _S("In");
  1489 		if (caps->iTypesAndDir & KUsbEpDirOut)
  1490 			directionStr = _S("Out");
  1491 		if (caps->iTypesAndDir & KUsbEpDirBidirect)
  1492 			directionStr = _S("Both");
  1493 				
  1494 		TUSB_PRINT4("Endpoint:%d Sizes =%s Type = %s - %s",
  1495 					i+1,sizeStr.PtrZ(), typeStr.PtrZ(), directionStr.PtrZ());
  1496 		}
  1497 	TUSB_PRINT("");
  1498 
  1499 	test.End();
  1500 			
  1501 	}
  1502 
  1503 
  1504 void CActiveControl::AllocateEndpointDMA(RDEVCLIENT* aPort,TENDPOINTNUMBER aEndpoint)
  1505 	{
  1506 	TBool res = EFalse;
  1507 	
  1508 	TInt r = aPort->AllocateEndpointResource(aEndpoint, EUsbcEndpointResourceDMA);
  1509 	if (r == KErrNone)
  1510 		RDebug::Print(_L("DMA allocation on endpoint %d: KErrNone"), aEndpoint);
  1511 	else if (r == KErrInUse)
  1512 		RDebug::Print(_L("DMA allocation on endpoint %d: KErrInUse"), aEndpoint);
  1513 	else if (r == KErrNotSupported)
  1514 		RDebug::Print(_L("DMA allocation on endpoint %d: KErrNotSupported"), aEndpoint);
  1515 	else
  1516 		RDebug::Print(_L("DMA allocation on endpoint %d: unexpected return value %d"),
  1517 					  aEndpoint, r);
  1518 	#ifdef	USB_SC
  1519 	res = aPort->QueryEndpointResourceUse(aEndpoint, EUsbcEndpointResourceDMA);
  1520 	#else
  1521 	res = aPort->QueryEndpointResourceUse(aEndpoint, EUsbcEndpointResourceDMA);
  1522 	#endif
  1523 	
  1524 	TUSB_PRINT2("DMA on endpoint %d %s\n",
  1525 				aEndpoint, res ? _S("allocated") : _S("not allocated"));
  1526 
  1527 	if ((r == KErrNone) && !res)
  1528 		RDebug::Print(_L("(Allocation success but negative query result: contradiction!)\n"));
  1529 	else if ((r != KErrNone) && res)
  1530 		RDebug::Print(_L("(Allocation failure but positive query result: contradiction!)\n"));
  1531 	}
  1532 
  1533 
  1534 void CActiveControl::DeAllocateEndpointDMA(RDEVCLIENT* aPort,TENDPOINTNUMBER aEndpoint)
  1535 	{
  1536 	TBool res = FALSE;	
  1537 	TInt r = aPort->DeAllocateEndpointResource(aEndpoint, EUsbcEndpointResourceDMA);
  1538 	if (r == KErrNone)
  1539 		RDebug::Print(_L("DMA deallocation on endpoint %d: KErrNone"), aEndpoint);
  1540 	else if (r == KErrNotSupported)
  1541 		RDebug::Print(_L("DMA deallocation on endpoint %d: KErrNotSupported"), aEndpoint);
  1542 	else
  1543 		RDebug::Print(_L("DMA deallocation on endpoint %d: unexpected return value %d"),
  1544 					  aEndpoint, r);
  1545 	#ifdef	USB_SC
  1546 	res = aPort->QueryEndpointResourceUse(aEndpoint, EUsbcEndpointResourceDMA);
  1547 	#else
  1548 	res = aPort->QueryEndpointResourceUse(aEndpoint, EUsbcEndpointResourceDMA);
  1549 	#endif
  1550 	
  1551 	TUSB_PRINT2("DMA on endpoint %d %s\n",
  1552 				aEndpoint, res ? _S("allocated") : _S("not allocated"));
  1553 	}
  1554 
  1555 #ifndef USB_SC
  1556 void CActiveControl::AllocateDoubleBuffering(RDEVCLIENT* aPort,TENDPOINTNUMBER aEndpoint)
  1557 	{
  1558 	TBool res = FALSE;
  1559 	TInt r = aPort->AllocateEndpointResource(aEndpoint, EUsbcEndpointResourceDoubleBuffering);
  1560 	if (r == KErrNone)
  1561 		RDebug::Print(_L("Double Buffering allocation on endpoint %d: KErrNone"), aEndpoint);
  1562 	else if (r == KErrInUse)
  1563 		RDebug::Print(_L("Double Buffering allocation on endpoint %d: KErrInUse"), aEndpoint);
  1564 	else if (r == KErrNotSupported)
  1565 		RDebug::Print(_L("Double Buffering allocation on endpoint %d: KErrNotSupported"), aEndpoint);
  1566 	else
  1567 		RDebug::Print(_L("Double Buffering allocation on endpoint %d: unexpected return value %d"),
  1568 					  aEndpoint, r);
  1569 	res = aPort->QueryEndpointResourceUse(aEndpoint, EUsbcEndpointResourceDoubleBuffering);
  1570 	TUSB_PRINT2("Double Buffering on endpoint %d %s\n",
  1571 				aEndpoint, res ? _S("allocated") : _S("not allocated"));
  1572 
  1573 	if ((r == KErrNone) && !res)
  1574 		RDebug::Print(_L("(Allocation success but negative query result: contradiction!)\n"));
  1575 	else if ((r != KErrNone) && res)
  1576 		RDebug::Print(_L("(Allocation failure but positive query result: contradiction!)\n"));
  1577 	}
  1578 
  1579 
  1580 void CActiveControl::DeAllocateDoubleBuffering(RDEVCLIENT* aPort,TENDPOINTNUMBER aEndpoint)
  1581 	{
  1582 	TInt r = aPort->DeAllocateEndpointResource(aEndpoint, EUsbcEndpointResourceDoubleBuffering);
  1583 	if (r == KErrNone)
  1584 		RDebug::Print(_L("Double Buffering deallocation on endpoint %d: KErrNone"), aEndpoint);
  1585 	else if (r == KErrNotSupported)
  1586 		RDebug::Print(_L("Double Buffering deallocation on endpoint %d: KErrNotSupported"), aEndpoint);
  1587 	else
  1588 		RDebug::Print(_L("Double Buffering deallocation on endpoint %d: unexpected return value %d"),
  1589 					  aEndpoint, r);
  1590 	TBool res = aPort->QueryEndpointResourceUse(aEndpoint, EUsbcEndpointResourceDoubleBuffering);
  1591 	TUSB_PRINT2("Double Buffering on endpoint %d %s\n",
  1592 				aEndpoint, res ? _S("allocated") : _S("not allocated"));
  1593 	}
  1594 
  1595 #endif
  1596 
  1597 TInt CActiveControl::ReEnumerate()
  1598 	{
  1599 	TRequestStatus enum_status;
  1600 	iPort[0].ReEnumerate(enum_status);
  1601 	if (!iSoftwareConnect)
  1602 		{
  1603 		iConsole->Printf(_L("This device does not support software\n"));
  1604 		iConsole->Printf(_L("disconnect/reconnect\n"));
  1605 		iConsole->Printf(_L("Please physically unplug and replug\n"));
  1606 		iConsole->Printf(_L("the USB cable NOW... "));
  1607 		}
  1608 	iConsole->Printf(_L("\n>>> Start the t_usb_win program on the host <<<\n"));
  1609 	User::WaitForRequest(enum_status);
  1610 	if (enum_status != KErrNone)
  1611 		{
  1612 		TUSB_PRINT1("Error: Re-enumeration status = %d", enum_status.Int());
  1613 		return KErrGeneral;
  1614 		}
  1615 	TUsbcDeviceState device_state =	EUsbcDeviceStateUndefined;
  1616 	TInt r = iPort[0].DeviceStatus(device_state);
  1617 	if (r != KErrNone)
  1618 		{
  1619 		TUSB_PRINT1("Error %d on querying device state", r);
  1620 		}
  1621 	else
  1622 		{
  1623 		TUSB_PRINT1("Current device state: %s",
  1624 					(device_state == EUsbcDeviceStateUndefined) ? _S("Undefined") :
  1625 					((device_state == EUsbcDeviceStateAttached) ? _S("Attached") :
  1626 					 ((device_state == EUsbcDeviceStatePowered) ? _S("Powered") :
  1627 					  ((device_state == EUsbcDeviceStateDefault) ? _S("Default") :
  1628 					   ((device_state == EUsbcDeviceStateAddress) ? _S("Address") :
  1629 						((device_state == EUsbcDeviceStateConfigured) ? _S("Configured") :
  1630 						 ((device_state == EUsbcDeviceStateSuspended) ? _S("Suspended") :
  1631 						  _S("Unknown"))))))));
  1632 		}
  1633 
  1634 	// Check the speed of the established physical USB connection
  1635 	iHighSpeed = iPort[0].CurrentlyUsingHighSpeed();
  1636 	if (iHighSpeed)
  1637 		{
  1638 		TUSB_PRINT("---> USB High-speed Testing\n");
  1639 		}
  1640 	else
  1641 		{
  1642 		TUSB_PRINT("---> USB Full-speed Testing\n");
  1643 		}
  1644 
  1645 	return KErrNone;
  1646 	}
  1647 
  1648 // -eof-