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