kerneltest/e32test/device/t_usbapi.cpp
changeset 0 a41df078684a
child 19 4a8fed1c0ef6
equal deleted inserted replaced
-1:000000000000 0:a41df078684a
       
     1 // Copyright (c) 2003-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/device/t_usbapi.cpp
       
    15 // Overview:
       
    16 // USB API Test Program (a standalone USB test program).
       
    17 // API Information:
       
    18 // Details:
       
    19 // - Query whether the platform is operating HS (or it is connected to a HS host) or not,
       
    20 // and executes the appropiate tests in each case (see RunTests() for the actual code,
       
    21 // state machine enclosed for clarity):
       
    22 // - Load and open an EUSBC device driver (logical device)
       
    23 // - Setup the USB interface: query device capabilities, setup interface.
       
    24 // - Test allocating DMA and double buffering resources with
       
    25 // AllocateEndpointResource results in their use being correctly reported by
       
    26 // QueryEndpointResourceUse
       
    27 // - Test descriptor manipulation: validate the device, configuration,
       
    28 // interface, alternate interface, endpoint and string descriptor
       
    29 // manipulation.
       
    30 // HS: device_qualifier and other_speed_configuation descriptors.
       
    31 // - Check and validate the EndpointZeroMaxPacketSizes.
       
    32 // - Quick test that calling the following APIs doesn't generate errors: device
       
    33 // control, AlternateDeviceStatusNotify, EndpointStatusNotify
       
    34 // - Test HaltEndpoint and ClearHaltEndpoint correctly result in endpoint
       
    35 // status being reported as stalled/not stalled.
       
    36 // - Test OTG extensions: OTG descriptor manipulations; set/get OTG feature
       
    37 // - Close and free the logical device.
       
    38 // Platforms/Drives/Compatibility:
       
    39 // All.
       
    40 // Assumptions/Requirement/Pre-requisites:
       
    41 // Failures and causes:
       
    42 // Base Port information:
       
    43 // 
       
    44 //
       
    45 
       
    46 
       
    47 #include <e32test.h>
       
    48 #include <e32debug.h>
       
    49 #include <hal.h>
       
    50 #include <d32usbc.h>
       
    51 #include <d32otgdi.h>
       
    52 
       
    53 #include "t_usblib.h"
       
    54 
       
    55 
       
    56 // --- Local Top Level Variables
       
    57 
       
    58 static RTest test(_L("T_USBAPI"));
       
    59 static RDevUsbcClient gPort;
       
    60 static RUsbOtgDriver gOTG;
       
    61 static TBool gSupportsOtg;
       
    62 static TBool gSupportsHighSpeed;
       
    63 static TBool gUsingHighSpeed;
       
    64 static TBool gSoak;
       
    65 static TChar gKeychar = 'a';
       
    66 
       
    67 // Store the actual endpoint number(s) of our alternate interface
       
    68 static TInt INT_IN_ep = -1;
       
    69 
       
    70 _LIT(KUsbLddFilename, "eusbc");
       
    71 _LIT(KOtgdiLddFilename, "otgdi");
       
    72 _LIT(KUsbDeviceName, "Usbc");
       
    73 
       
    74 
       
    75 // --- Local Constants
       
    76 
       
    77 static const TInt KUsbDesc_SizeOffset = 0;
       
    78 static const TInt KUsbDesc_TypeOffset = 1;
       
    79 
       
    80 static const TInt KDevDesc_SpecOffset = 2;
       
    81 static const TInt KDevDesc_DevClassOffset = 4;
       
    82 static const TInt KDevDesc_DevSubClassOffset = 5;
       
    83 static const TInt KDevDesc_DevProtocolOffset = 6;
       
    84 static const TInt KDevDesc_Ep0SizeOffset = 7;
       
    85 static const TInt KDevDesc_VendorIdOffset = 8;
       
    86 static const TInt KDevDesc_ProductIdOffset = 10;
       
    87 static const TInt KDevDesc_DevReleaseOffset = 12;
       
    88 
       
    89 static const TInt KConfDesc_AttribOffset = 7;
       
    90 static const TInt KConfDesc_MaxPowerOffset = 8;
       
    91 
       
    92 static const TInt KIfcDesc_SettingOffset = 2;
       
    93 static const TInt KIfcDesc_ProtocolOffset = 7;
       
    94 
       
    95 static const TInt KEpDesc_PacketSizeOffset = 4;
       
    96 static const TInt KEpDesc_IntervalOffset = 6;
       
    97 static const TInt KEpDesc_SynchAddressOffset = 8;
       
    98 
       
    99 
       
   100 //
       
   101 // Helper.
       
   102 //
       
   103 static TEndpointState QueryEndpointState(TEndpointNumber aEndpoint)
       
   104 	{
       
   105 	TEndpointState ep_state = EEndpointStateUnknown;
       
   106 	TInt r = gPort.EndpointStatus(aEndpoint, ep_state);
       
   107 	test(r == KErrNone);
       
   108 	test.Printf(_L("Endpoint %d state: %s\n"), aEndpoint,
       
   109 				(ep_state == EEndpointStateNotStalled) ? _S("Not stalled") :
       
   110 				((ep_state == EEndpointStateStalled) ? _S("Stalled") :
       
   111 				 _S("Unknown...")));
       
   112 	return ep_state;
       
   113 	}
       
   114 
       
   115 
       
   116 // --- Class CActiveKeypressNotifier
       
   117 
       
   118 class CActiveKeypressNotifier : public CActive
       
   119 	{
       
   120 public:
       
   121 	static CActiveKeypressNotifier* NewL(CConsoleBase* aConsole);
       
   122 	~CActiveKeypressNotifier();
       
   123 	void RequestCharacter();
       
   124 	void ProcessKeyPressL(TChar aChar);
       
   125 private:
       
   126 	virtual void DoCancel();
       
   127 	virtual void RunL();
       
   128 	CActiveKeypressNotifier(CConsoleBase* aConsole);
       
   129 	void ConstructL() {};
       
   130 private:
       
   131 	CConsoleBase* iConsole;
       
   132 	};
       
   133 
       
   134 
       
   135 CActiveKeypressNotifier* CActiveKeypressNotifier::NewL(CConsoleBase* aConsole)
       
   136 	{
       
   137 	CActiveKeypressNotifier* self = new (ELeave) CActiveKeypressNotifier(aConsole);
       
   138 	CleanupStack::PushL(self);
       
   139 	self->ConstructL();
       
   140 	CActiveScheduler::Add(self);
       
   141 	CleanupStack::Pop();
       
   142 	return self;
       
   143 	}
       
   144 
       
   145 
       
   146 CActiveKeypressNotifier::CActiveKeypressNotifier(CConsoleBase* aConsole)
       
   147 	: CActive(EPriorityNormal), iConsole(aConsole)
       
   148 	{}
       
   149 
       
   150 
       
   151 CActiveKeypressNotifier::~CActiveKeypressNotifier()
       
   152 	{
       
   153 	Cancel();												// base class cancel -> calls our DoCancel
       
   154 	}
       
   155 
       
   156 
       
   157 void CActiveKeypressNotifier::RunL()
       
   158 	{
       
   159 	gKeychar = (static_cast<TChar>(iConsole->KeyCode()));
       
   160 	RequestCharacter();
       
   161 	}
       
   162 
       
   163 
       
   164 void CActiveKeypressNotifier::DoCancel()
       
   165 	{
       
   166 	iConsole->ReadCancel();
       
   167 	}
       
   168 
       
   169 
       
   170 void CActiveKeypressNotifier::RequestCharacter()
       
   171 	{
       
   172 	// A request is issued to the CConsoleBase to accept a character from the keyboard.
       
   173 	if (IsActive())
       
   174 		{
       
   175 		return;
       
   176 		}
       
   177 	iConsole->Read(iStatus);
       
   178 	SetActive();
       
   179 	}
       
   180 
       
   181 
       
   182 // --- Actual Test Functions
       
   183 
       
   184 // 2nd Thread helper function
       
   185 static TInt TestThreadFunction(TAny* aPtr)
       
   186 	{
       
   187 	RThread* other = static_cast<RThread*>(aPtr);
       
   188 	RDevUsbcClient port = gPort;
       
   189 	// Now try to duplicate the USB channel handle
       
   190 	TInt r = port.Duplicate(*other);
       
   191  	// Wait for 1 second
       
   192  	User::After(1000000);
       
   193 	return r;
       
   194 	}
       
   195 
       
   196 
       
   197 static void OpenChannel()
       
   198 	{
       
   199 	test.Start(_L("Open Channel"));
       
   200 
       
   201 	test.Next(_L("Load USB LDD"));
       
   202 	TInt r = User::LoadLogicalDevice(KUsbLddFilename);
       
   203 	test(r == KErrNone || r == KErrAlreadyExists);
       
   204 
       
   205 	RDevUsbcClient port1;
       
   206 	test.Next(_L("Open local USB channel 1"));
       
   207 	r = port1.Open(0);
       
   208 	test(r == KErrNone);
       
   209 
       
   210 	test.Next(_L("Open global USB channel"));
       
   211 	r = gPort.Open(0);
       
   212 	test(r == KErrNone);
       
   213 
       
   214 	RDevUsbcClient port2;
       
   215 	test.Next(_L("Open local USB channel 2"));
       
   216 	r = port2.Open(0);
       
   217 	test(r == KErrNone);
       
   218 
       
   219 	test.Next(_L("Close USB channel 1"));
       
   220 	port1.Close();
       
   221 
       
   222 	RDevUsbcClient port3;
       
   223 	test.Next(_L("Open local USB channel 3"));
       
   224 	r = port3.Open(0);
       
   225 	test(r == KErrNone);
       
   226 
       
   227 	test.Next(_L("Close USB channel 2"));
       
   228 	port2.Close();
       
   229 
       
   230 	test.Next(_L("Close USB channel 3"));
       
   231 	port3.Close();
       
   232 
       
   233 	// Check for OTG support
       
   234 	TBuf8<KUsbDescSize_Otg> otg_desc;
       
   235 	r = gPort.GetOtgDescriptor(otg_desc);
       
   236 	test(r == KErrNotSupported || r == KErrNone);
       
   237 	gSupportsOtg = (r != KErrNotSupported) ? ETrue : EFalse;
       
   238 
       
   239 	// On an OTG device we have to start the OTG driver, otherwise the Client
       
   240 	// stack will remain disabled forever.
       
   241 	if (gSupportsOtg)
       
   242 		{
       
   243 		test.Printf(_L("Running on OTG device: loading OTG driver\n"));
       
   244 		test.Next(_L("Load OTG LDD"));
       
   245 		r = User::LoadLogicalDevice(KOtgdiLddFilename);
       
   246 		test((r == KErrNone) || (r == KErrAlreadyExists));
       
   247 
       
   248 		test.Next(_L("Open OTG channel"));
       
   249 		r = gOTG.Open();
       
   250 		test(r == KErrNone);
       
   251 
       
   252 		test.Next(_L("Start OTG stack"));
       
   253 		r = gOTG.StartStacks();
       
   254 		test(r == KErrNone);
       
   255 		}
       
   256 
       
   257 	// Try duplicating channel handle in a second thread
       
   258 	// (which should not work because we don't support it)
       
   259 
       
   260 	test.Next(_L("Create 2nd Thread"));
       
   261 	RThread me;
       
   262  	TThreadId me_id = me.Id();
       
   263 	// We need to open the RThread object, otherwise we'll only get the
       
   264 	// 'special' handle 0xFFFF8001.
       
   265 	test(me.Open(me_id) == KErrNone);
       
   266 	RThread test_thread;
       
   267 	TBuf<17> name = _L("tusbapitestthread");
       
   268 	test(test_thread.Create(name, TestThreadFunction, 0x1000, NULL, &me) == KErrNone);
       
   269 	test.Next(_L("Logon to 2nd Thread"));
       
   270 	TRequestStatus stat;
       
   271 	test_thread.Logon(stat);
       
   272 	test(stat == KRequestPending);
       
   273 	test_thread.Resume();
       
   274 	test.Next(_L("Wait for 2nd Thread to exit"));
       
   275 	User::WaitForRequest(stat);
       
   276 	// Check correct return value of RDevUsbcClient::Duplicate()
       
   277 	test(stat == KErrAccessDenied);
       
   278 	test.Next(_L("Close 2nd Thread"));
       
   279 	test_thread.Close();
       
   280 
       
   281 	test.End();
       
   282 	}
       
   283 
       
   284 
       
   285 static void TestResourceAllocation()
       
   286 	{
       
   287 	test.Start(_L("Test Endpoint Resource Allocation"));
       
   288 
       
   289 	test.Next(_L("Request DMA resource"));
       
   290 	const TInt dma = gPort.AllocateEndpointResource(EEndpoint1, EUsbcEndpointResourceDMA);
       
   291 	TBool res = gPort.QueryEndpointResourceUse(EEndpoint1, EUsbcEndpointResourceDMA);
       
   292 	test.Printf(_L("DMA on endpoint 1 %s\n"),
       
   293 				res ? _S("now allocated") : _S("not allocated"));
       
   294 	if (dma == KErrNone)
       
   295 		// Only if DMA resource was successfully allocated should we expect truth here:
       
   296 		test(res);
       
   297 	else
       
   298 		test(!res);
       
   299 
       
   300 	test.Next(_L("Request Double Buffering resource"));
       
   301 	const TInt db = gPort.AllocateEndpointResource(EEndpoint1, EUsbcEndpointResourceDoubleBuffering);
       
   302 	res = gPort.QueryEndpointResourceUse(EEndpoint1, EUsbcEndpointResourceDoubleBuffering);
       
   303 	test.Printf(_L("Double Buffering on endpoint 1 %s\n"),
       
   304 				res ? _S("now allocated") : _S("not allocated"));
       
   305 	if (db == KErrNone)
       
   306 		// Only if DB resource was successfully allocated should we expect truth here:
       
   307 		test(res);
       
   308 	else
       
   309 		test(!res);
       
   310 
       
   311 	test.Next(_L("Deallocate Double Buffering resource"));
       
   312 	TInt r = gPort.DeAllocateEndpointResource(EEndpoint1, EUsbcEndpointResourceDoubleBuffering);
       
   313 	// Whether DB is dynamic or permanent - deallocation (if supported) should always return success:
       
   314 	if (db == KErrNone)
       
   315 		test(r == KErrNone);
       
   316 	else
       
   317 		test(r != KErrNone);
       
   318 	res = gPort.QueryEndpointResourceUse(EEndpoint1, EUsbcEndpointResourceDoubleBuffering);
       
   319 	test.Printf(_L("Double Buffering on endpoint 1 %s\n"),
       
   320 				res ? _S("still allocated") : _S("not (longer) allocated"));
       
   321 
       
   322 	test.Next(_L("Deallocate DMA resource"));
       
   323 	r = gPort.DeAllocateEndpointResource(EEndpoint1, EUsbcEndpointResourceDMA);
       
   324 	// Whether DMA is dynamic or permanent - deallocation (if supported) should always return success:
       
   325 	if (dma == KErrNone)
       
   326 		test(r == KErrNone);
       
   327 	else
       
   328 		test(r != KErrNone);
       
   329 	res = gPort.QueryEndpointResourceUse(EEndpoint1, EUsbcEndpointResourceDMA);
       
   330 	test.Printf(_L("DMA on endpoint 1 %s\n"),
       
   331 				res ? _S("still allocated") : _S("not (longer) allocated"));
       
   332 
       
   333 	test.End();
       
   334 	}
       
   335 
       
   336 
       
   337 static void SetupInterface()
       
   338 	{
       
   339 	test.Start(_L("Query USB device caps and set up interface"));
       
   340 
       
   341 	// Device caps
       
   342 	test.Next(_L("Query USB device caps"));
       
   343 	TUsbDeviceCaps d_caps;
       
   344 	TInt r = gPort.DeviceCaps(d_caps);
       
   345 	test(r == KErrNone);
       
   346 	TInt n = d_caps().iTotalEndpoints;
       
   347 
       
   348 	// Global variable - we'll need this value later
       
   349 	gSupportsHighSpeed = d_caps().iHighSpeed;
       
   350 
       
   351 	test.Printf(_L("### USB device capabilities:\n"));
       
   352 	test.Printf(_L("Number of endpoints:                        %d\n"), n);
       
   353 	test.Printf(_L("Supports Software-Connect:                  %s\n"),
       
   354 				d_caps().iConnect ? _S("yes") : _S("no"));
       
   355 	test.Printf(_L("Device is Self-Powered:                     %s\n"),
       
   356 				d_caps().iSelfPowered ? _S("yes") : _S("no"));
       
   357 	test.Printf(_L("Supports Remote-Wakeup:                     %s\n"),
       
   358 				d_caps().iRemoteWakeup ? _S("yes") : _S("no"));
       
   359 	test.Printf(_L("Supports High-speed:                        %s\n"),
       
   360 				gSupportsHighSpeed ? _S("yes") : _S("no"));
       
   361 	test.Printf(_L("Supports OTG:                               %s\n"),
       
   362 				gSupportsOtg ? _S("yes") : _S("no"));
       
   363 	test.Printf(_L("Supports unpowered cable detection:         %s\n"),
       
   364 				(d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_CableDetectWithoutPower) ?
       
   365 				_S("yes") : _S("no"));
       
   366 	test.Printf(_L("Supports endpoint resource alloc scheme V2: %s\n"),
       
   367 				(d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_EndpointResourceAllocV2) ?
       
   368 				_S("yes") : _S("no"));
       
   369 
       
   370 	test(n >= 2);
       
   371 	test.Printf(_L("(Device has sufficient endpoints.)\n"));
       
   372 
       
   373 	// Endpoint caps
       
   374 	test.Next(_L("Query USB endpoint caps"));
       
   375 	TUsbcEndpointData data[KUsbcMaxEndpoints];
       
   376 	TPtr8 dataptr(reinterpret_cast<TUint8*>(data), sizeof(data), sizeof(data));
       
   377 	r = gPort.EndpointCaps(dataptr);
       
   378 	test(r == KErrNone);
       
   379 
       
   380 	test.Printf(_L("### USB device endpoint capabilities:\n"));
       
   381 	for (TInt i = 0; i < n; i++)
       
   382 		{
       
   383 		const TUsbcEndpointCaps* caps = &data[i].iCaps;
       
   384 		test.Printf(_L("Endpoint: SizeMask = 0x%08x TypeDirMask = 0x%08x\n"),
       
   385 					caps->iSizes, caps->iTypesAndDir);
       
   386 		if (caps->iHighBandwidth)
       
   387 			{
       
   388 			test.Printf(_L("  (high-speed, high bandwidth endpoint)\n"));
       
   389 			// Must be HS Int or Iso ep
       
   390 			test(gSupportsHighSpeed);
       
   391 			test(caps->iTypesAndDir & (KUsbEpTypeIsochronous | KUsbEpTypeInterrupt));
       
   392 			}
       
   393 		}
       
   394 
       
   395 	test.Next(_L("Looking for suitable endpoints"));
       
   396 	// Set the active interface
       
   397 	TUsbcInterfaceInfoBuf ifc;
       
   398 	TInt ep_found = 0;
       
   399 	TBool foundBulkIN = EFalse;
       
   400 	TBool foundBulkOUT = EFalse;
       
   401 	for (TInt i = 0; i < n; i++)
       
   402 		{
       
   403 		const TUsbcEndpointCaps* caps = &data[i].iCaps;
       
   404 		const TInt mps = caps->MaxPacketSize();
       
   405 		if (!foundBulkIN &&
       
   406 			(caps->iTypesAndDir & (KUsbEpTypeBulk | KUsbEpDirIn)) ==
       
   407 			(KUsbEpTypeBulk | KUsbEpDirIn))
       
   408 			{
       
   409 			// EEndpoint1 is going to be our TX (IN, write) endpoint
       
   410 			ifc().iEndpointData[0].iType = KUsbEpTypeBulk;
       
   411 			ifc().iEndpointData[0].iDir  = KUsbEpDirIn;
       
   412 			ifc().iEndpointData[0].iSize = mps;
       
   413 			foundBulkIN = ETrue;
       
   414 			if (++ep_found == 2)
       
   415 				break;
       
   416 			}
       
   417 		else if (!foundBulkOUT &&
       
   418 			(caps->iTypesAndDir & (KUsbEpTypeBulk | KUsbEpDirOut)) ==
       
   419 				 (KUsbEpTypeBulk | KUsbEpDirOut))
       
   420 			{
       
   421 			// EEndpoint2 is going to be our RX (OUT, read) endpoint
       
   422 			ifc().iEndpointData[1].iType = KUsbEpTypeBulk;
       
   423 			ifc().iEndpointData[1].iDir  = KUsbEpDirOut;
       
   424 			ifc().iEndpointData[1].iSize = mps;
       
   425 			foundBulkOUT = ETrue;
       
   426 			if (++ep_found == 2)
       
   427 				break;
       
   428 			}
       
   429 		}
       
   430 	test(ep_found == 2);
       
   431 
       
   432 	test.Next(_L("Setting up main interface"));
       
   433 	_LIT16(string, "T_USBAPI Test Interface (Setting 0)");
       
   434 	ifc().iString = const_cast<TDesC16*>(&string);
       
   435 	ifc().iTotalEndpointsUsed = 2;
       
   436 	ifc().iClass.iClassNum	  = 0xff;
       
   437 	ifc().iClass.iSubClassNum = 0xff;
       
   438 	ifc().iClass.iProtocolNum = 0xff;
       
   439 	// Set up the interface.
       
   440 	r = gPort.SetInterface(0, ifc);
       
   441 	test(r == KErrNone);
       
   442 
       
   443 	TInt ifc_no = -1;
       
   444 	r = gPort.GetAlternateSetting(ifc_no);
       
   445 	test(r == KErrUsbDeviceNotConfigured);
       
   446 
       
   447 	// Some UDCs won't allow endpoint resource manipulation once the hardware has been
       
   448 	// configured and turned on. So we do it here & now:
       
   449 	TestResourceAllocation();
       
   450 
       
   451 	// On the other hand, since some UDCs won't let us test many features which require
       
   452 	// register access until the USB hardware is powered up (and because it might start
       
   453 	// out unpowered), we should turn it on here explicitly.
       
   454 	// (It will be turned off automatically by the PIL after all tests have been run,
       
   455 	// when the interface gets deleted.)
       
   456 	test.Next(_L("Powering up UDC (1)"));
       
   457 	r = gPort.PowerUpUdc();
       
   458 	if (!gSupportsOtg)
       
   459 		{
       
   460 		test(r == KErrNone);
       
   461 		}
       
   462 	else
       
   463 		{
       
   464 		test((r == KErrNone) || (r == KErrNotReady));
       
   465 		}
       
   466 	if (gSupportsOtg && (r == KErrNotReady))
       
   467 		{
       
   468 		test.Printf(_L("OTG device but not connected to Host, stopping subtest here.\n"));
       
   469 		test.End();
       
   470 		return;
       
   471 		}
       
   472 	// The board might be attached to a PC with HS controller, thus enabling us
       
   473 	// to test some HS-specific features. For that to work we have to connect
       
   474 	// the board to the PC. The "Found new device" box that may pop up on the PC
       
   475 	// in response to this can be ignored (i.e. just closed).
       
   476 	test.Next(_L("Connecting to Host (1)"));
       
   477 	r = gPort.DeviceConnectToHost();
       
   478 	test(r == KErrNone);
       
   479  	// Suspend thread to let things get stable on the bus.
       
   480 	test.Printf(_L("Waiting a short moment..."));
       
   481 	User::After(2000000);
       
   482 	test.Printf(_L(" done.\n"));
       
   483 
       
   484 	// Check the speed of the physical connection (if any).
       
   485 	gUsingHighSpeed = gPort.CurrentlyUsingHighSpeed();
       
   486 	if (gUsingHighSpeed)
       
   487 		{
       
   488 		test(gSupportsHighSpeed);							// sane?
       
   489 		test.Printf(_L("---> USB High-speed Testing\n"));
       
   490 		}
       
   491 	else
       
   492 		{
       
   493 		test.Printf(_L("---> USB Full-speed Testing\n"));
       
   494 		}
       
   495 
       
   496 	// By pulling down the interface/connection and bringing them up again we
       
   497 	// simulate a starting/stopping of the USB service by a control app.
       
   498 
       
   499 	test.Next(_L("Disconnecting from Host"));
       
   500 	r = gPort.DeviceDisconnectFromHost();
       
   501 	test(r == KErrNone);
       
   502 
       
   503 	test.Next(_L("Releasing interface"));
       
   504 	r = gPort.ReleaseInterface(0);
       
   505 	test(r == KErrNone);
       
   506 
       
   507 	test.Next(_L("Setting interface"));
       
   508 	r = gPort.SetInterface(0, ifc);
       
   509 	test(r == KErrNone);
       
   510 
       
   511  	// Suspend thread before connecting again.
       
   512 	test.Printf(_L("Waiting a short moment..."));
       
   513 	User::After(1000000);
       
   514 	test.Printf(_L(" done.\n"));
       
   515 
       
   516 	test.Next(_L("Powering up UDC (2)"));
       
   517 	r = gPort.PowerUpUdc();
       
   518 	if (!gSupportsOtg)
       
   519 		{
       
   520 		test(r == KErrNone);
       
   521 		}
       
   522 	else
       
   523 		{
       
   524 		test((r == KErrNone) || (r == KErrNotReady));
       
   525 		}
       
   526 	if (gSupportsOtg && (r == KErrNotReady))
       
   527 		{
       
   528 		test.Printf(_L("OTG device but not connected to Host, stopping subtest here.\n"));
       
   529 		test.End();
       
   530 		return;
       
   531 		}
       
   532 
       
   533 	test.Next(_L("Connecting to Host (2)"));
       
   534 	r = gPort.DeviceConnectToHost();
       
   535 	test(r == KErrNone);
       
   536 	// Suspend thread to let things get stable on the bus.
       
   537 	User::After(2000000);
       
   538 
       
   539 	test.End();
       
   540 	}
       
   541 
       
   542 
       
   543 static void TestDeviceDescriptor()
       
   544 	{
       
   545 	test.Start(_L("Device Descriptor Manipulation"));
       
   546 
       
   547 	test.Next(_L("GetDeviceDescriptorSize()"));
       
   548 	TInt desc_size = 0;
       
   549 	gPort.GetDeviceDescriptorSize(desc_size);
       
   550 	test(static_cast<TUint>(desc_size) == KUsbDescSize_Device);
       
   551 
       
   552 	test.Next(_L("GetDeviceDescriptor()"));
       
   553 	TBuf8<KUsbDescSize_Device> descriptor;
       
   554 	TInt r = gPort.GetDeviceDescriptor(descriptor);
       
   555 	test(r == KErrNone);
       
   556 
       
   557 	test.Next(_L("SetDeviceDescriptor()"));
       
   558 	// Change the USB spec number to 2.30
       
   559 	descriptor[KDevDesc_SpecOffset]   = 0x30;
       
   560 	descriptor[KDevDesc_SpecOffset+1] = 0x02;
       
   561 	// Change the device vendor ID (VID) to 0x1234
       
   562 	descriptor[KDevDesc_VendorIdOffset]   = 0x34;			// little endian
       
   563 	descriptor[KDevDesc_VendorIdOffset+1] = 0x12;
       
   564 	// Change the device product ID (PID) to 0x1111
       
   565 	descriptor[KDevDesc_ProductIdOffset]   = 0x11;
       
   566 	descriptor[KDevDesc_ProductIdOffset+1] = 0x11;
       
   567 	// Change the device release number to 3.05
       
   568 	descriptor[KDevDesc_DevReleaseOffset]   = 0x05;
       
   569 	descriptor[KDevDesc_DevReleaseOffset+1] = 0x03;
       
   570 	r = gPort.SetDeviceDescriptor(descriptor);
       
   571 	test(r == KErrNone);
       
   572 
       
   573 	test.Next(_L("GetDeviceDescriptor()"));
       
   574 	TBuf8<KUsbDescSize_Device> descriptor2;
       
   575 	r = gPort.GetDeviceDescriptor(descriptor2);
       
   576 	test(r == KErrNone);
       
   577 
       
   578 	test.Next(_L("Compare device descriptor with value set"));
       
   579 	r = descriptor2.Compare(descriptor);
       
   580 	test(r == KErrNone);
       
   581 
       
   582 	if (gUsingHighSpeed)
       
   583 		{
       
   584 		// HS only allows one possible packet size.
       
   585 		test(descriptor[KDevDesc_Ep0SizeOffset] == 64);
       
   586 		}
       
   587 
       
   588 	test.End();
       
   589 	}
       
   590 
       
   591 
       
   592 static void	TestDeviceQualifierDescriptor()
       
   593 	{
       
   594 	test.Start(_L("Device_Qualifier Descriptor Manipulation"));
       
   595 
       
   596 	if (!gSupportsHighSpeed)
       
   597 		{
       
   598 		test.Printf(_L("*** Not supported - skipping Device_Qualifier descriptor tests\n"));
       
   599 		test.End();
       
   600 		return;
       
   601 		}
       
   602 
       
   603 	test.Next(_L("GetDeviceQualifierDescriptor()"));
       
   604 	TBuf8<KUsbDescSize_DeviceQualifier> descriptor;
       
   605 	TInt r = gPort.GetDeviceQualifierDescriptor(descriptor);
       
   606 	test(r == KErrNone);
       
   607 
       
   608 	test.Next(_L("SetDeviceQualifierDescriptor()"));
       
   609 	// Change the USB spec number to 3.00
       
   610 	descriptor[KDevDesc_SpecOffset]   = 0x00;
       
   611 	descriptor[KDevDesc_SpecOffset+1] = 0x03;
       
   612 	// Change the device class, subclass and protocol codes
       
   613 	descriptor[KDevDesc_DevClassOffset]    = 0xA1;
       
   614 	descriptor[KDevDesc_DevSubClassOffset] = 0xB2;
       
   615 	descriptor[KDevDesc_DevProtocolOffset] = 0xC3;
       
   616 	r = gPort.SetDeviceQualifierDescriptor(descriptor);
       
   617 	test(r == KErrNone);
       
   618 
       
   619 	test.Next(_L("GetDeviceQualifierDescriptor()"));
       
   620 	TBuf8<KUsbDescSize_DeviceQualifier> descriptor2;
       
   621 	r = gPort.GetDeviceQualifierDescriptor(descriptor2);
       
   622 	test(r == KErrNone);
       
   623 
       
   624 	test.Next(_L("Compare Device_Qualifier desc with value set"));
       
   625 	r = descriptor2.Compare(descriptor);
       
   626 	test(r == 0);
       
   627 
       
   628 	if (!gUsingHighSpeed)
       
   629 		{
       
   630 		// HS only allows one possible packet size.
       
   631 		test(descriptor[KDevDesc_Ep0SizeOffset] == 64);
       
   632 		}
       
   633 
       
   634 	test.End();
       
   635 	}
       
   636 
       
   637 
       
   638 static void TestConfigurationDescriptor()
       
   639 	{
       
   640 	test.Start(_L("Configuration Descriptor Manipulation"));
       
   641 
       
   642 	test.Next(_L("GetConfigurationDescriptorSize()"));
       
   643 	TInt desc_size = 0;
       
   644 	gPort.GetConfigurationDescriptorSize(desc_size);
       
   645 	test(static_cast<TUint>(desc_size) == KUsbDescSize_Config);
       
   646 
       
   647 	test.Next(_L("GetConfigurationDescriptor()"));
       
   648 	TBuf8<KUsbDescSize_Config> descriptor;
       
   649 	TInt r = gPort.GetConfigurationDescriptor(descriptor);
       
   650 	test(r == KErrNone);
       
   651 
       
   652 	test.Next(_L("SetConfigurationDescriptor()"));
       
   653 	// Invert Remote-Wakup support
       
   654 	descriptor[KConfDesc_AttribOffset] = (descriptor[KConfDesc_AttribOffset] ^ KUsbDevAttr_RemoteWakeup);
       
   655 	// Change the reported max power to 200mA (2 * 0x64)
       
   656 	descriptor[KConfDesc_MaxPowerOffset] = 0x64;
       
   657 	r = gPort.SetConfigurationDescriptor(descriptor);
       
   658 	test(r == KErrNone);
       
   659 
       
   660 	test.Next(_L("GetConfigurationDescriptor()"));
       
   661 	TBuf8<KUsbDescSize_Config> descriptor2;
       
   662 	r = gPort.GetConfigurationDescriptor(descriptor2);
       
   663 	test(r == KErrNone);
       
   664 
       
   665 	test.Next(_L("Compare configuration desc with value set"));
       
   666 	r = descriptor2.Compare(descriptor);
       
   667 	test(r == KErrNone);
       
   668 
       
   669 	test.End();
       
   670 	}
       
   671 
       
   672 
       
   673 static void	TestOtherSpeedConfigurationDescriptor()
       
   674 	{
       
   675 	test.Start(_L("Other_Speed_Configuration Desc Manipulation"));
       
   676 
       
   677 	if (!gSupportsHighSpeed)
       
   678 		{
       
   679 		test.Printf(_L("*** Not supported - skipping Other_Speed_Configuration desc tests\n"));
       
   680 		test.End();
       
   681 		return;
       
   682 		}
       
   683 
       
   684 	test.Next(_L("GetOtherSpeedConfigurationDescriptor()"));
       
   685 	TBuf8<KUsbDescSize_OtherSpeedConfig> descriptor;
       
   686 	TInt r = gPort.GetOtherSpeedConfigurationDescriptor(descriptor);
       
   687 	test(r == KErrNone);
       
   688 
       
   689 	test.Next(_L("SetOtherSpeedConfigurationDescriptor()"));
       
   690 	// Invert Remote-Wakup support
       
   691 	descriptor[KConfDesc_AttribOffset] = (descriptor[KConfDesc_AttribOffset] ^ KUsbDevAttr_RemoteWakeup);
       
   692 	// Change the reported max power to 330mA (2 * 0xA5)
       
   693 	descriptor[KConfDesc_MaxPowerOffset] = 0xA5;
       
   694 	r = gPort.SetOtherSpeedConfigurationDescriptor(descriptor);
       
   695 	test(r == KErrNone);
       
   696 
       
   697 	test.Next(_L("GetOtherSpeedConfigurationDescriptor()"));
       
   698 	TBuf8<KUsbDescSize_OtherSpeedConfig> descriptor2;
       
   699 	r = gPort.GetOtherSpeedConfigurationDescriptor(descriptor2);
       
   700 	test(r == KErrNone);
       
   701 
       
   702 	test.Next(_L("Compare O_S_Config desc with value set"));
       
   703 	r = descriptor2.Compare(descriptor);
       
   704 	test(r == KErrNone);
       
   705 
       
   706 	test.End();
       
   707 	}
       
   708 
       
   709 
       
   710 static void TestInterfaceDescriptor()
       
   711 	{
       
   712 	test.Start(_L("Interface Descriptor Manipulation"));
       
   713 
       
   714 	// First the standard Interface descriptor
       
   715 
       
   716 	test.Next(_L("GetInterfaceDescriptorSize()"));
       
   717 	TInt desc_size = 0;
       
   718 	TInt r = gPort.GetInterfaceDescriptorSize(0, desc_size);
       
   719 	test(r == KErrNone);
       
   720 	test(static_cast<TUint>(desc_size) == KUsbDescSize_Interface);
       
   721 
       
   722 	test.Next(_L("GetInterfaceDescriptor()"));
       
   723 	TBuf8<KUsbDescSize_Interface> descriptor;
       
   724 	r = gPort.GetInterfaceDescriptor(0, descriptor);
       
   725 	test(r == KErrNone);
       
   726 
       
   727 	test.Next(_L("SetInterfaceDescriptor()"));
       
   728 	// Change the interface protocol to 0x78(+)
       
   729 	TUint8 prot = 0x78;
       
   730 	if (descriptor[KIfcDesc_ProtocolOffset] == prot)
       
   731 		prot++;
       
   732 	descriptor[KIfcDesc_ProtocolOffset] = prot;
       
   733 	r = gPort.SetInterfaceDescriptor(0, descriptor);
       
   734 	test(r == KErrNone);
       
   735 
       
   736 	test.Next(_L("GetInterfaceDescriptor()"));
       
   737 	TBuf8<KUsbDescSize_Interface> descriptor2;
       
   738 	r = gPort.GetInterfaceDescriptor(0, descriptor2);
       
   739 	test(r == KErrNone);
       
   740 
       
   741 	test.Next(_L("Compare interface descriptor with value set"));
       
   742 	r = descriptor2.Compare(descriptor);
       
   743 	test(r == KErrNone);
       
   744 
       
   745 	test.End();
       
   746 	}
       
   747 
       
   748 
       
   749 static void TestClassSpecificDescriptors()
       
   750 	{
       
   751 	test.Start(_L("Class-specific Descriptor Manipulation"));
       
   752 
       
   753 	// First a class-specific Interface descriptor
       
   754 
       
   755 	test.Next(_L("SetCSInterfaceDescriptorBlock()"));
       
   756 	// choose arbitrary new descriptor size
       
   757 	const TInt KUsbDescSize_CS_Interface = KUsbDescSize_Interface + 10;
       
   758 	TBuf8<KUsbDescSize_CS_Interface> cs_ifc_descriptor;
       
   759 	cs_ifc_descriptor.FillZ(cs_ifc_descriptor.MaxLength());
       
   760 	cs_ifc_descriptor[KUsbDesc_SizeOffset] = KUsbDescSize_CS_Interface;
       
   761 	cs_ifc_descriptor[KUsbDesc_TypeOffset] = KUsbDescType_CS_Interface;
       
   762 	TInt r = gPort.SetCSInterfaceDescriptorBlock(0, cs_ifc_descriptor);
       
   763 	test(r == KErrNone);
       
   764 
       
   765 	test.Next(_L("GetCSInterfaceDescriptorBlockSize()"));
       
   766 	TInt desc_size = 0;
       
   767 	r = gPort.GetCSInterfaceDescriptorBlockSize(0, desc_size);
       
   768 	test(r == KErrNone);
       
   769 	test(desc_size == KUsbDescSize_CS_Interface);
       
   770 
       
   771 	test.Next(_L("GetCSInterfaceDescriptorBlock()"));
       
   772 	TBuf8<KUsbDescSize_CS_Interface> descriptor;
       
   773 	r = gPort.GetCSInterfaceDescriptorBlock(0, descriptor);
       
   774 	test(r == KErrNone);
       
   775 
       
   776 	test.Next(_L("Compare CS ifc descriptor with value set"));
       
   777 	r = descriptor.Compare(cs_ifc_descriptor);
       
   778 	test(r == KErrNone);
       
   779 
       
   780 	// Next a class-specific Endpoint descriptor
       
   781 
       
   782 	test.Next(_L("SetCSEndpointDescriptorBlock()"));
       
   783 	// choose arbitrary new descriptor size
       
   784 	const TInt KUsbDescSize_CS_Endpoint = KUsbDescSize_Endpoint + 5;
       
   785 	TBuf8<KUsbDescSize_CS_Endpoint> cs_ep_descriptor;
       
   786 	cs_ep_descriptor.FillZ(cs_ep_descriptor.MaxLength());
       
   787 	cs_ep_descriptor[KUsbDesc_SizeOffset] = KUsbDescSize_CS_Endpoint;
       
   788 	cs_ep_descriptor[KUsbDesc_TypeOffset] = KUsbDescType_CS_Endpoint;
       
   789 	r = gPort.SetCSEndpointDescriptorBlock(0, 2, cs_ep_descriptor);
       
   790 	test(r == KErrNone);
       
   791 
       
   792 	test.Next(_L("GetCSEndpointDescriptorBlockSize()"));
       
   793 	r = gPort.GetCSEndpointDescriptorBlockSize(0, 2, desc_size);
       
   794 	test(r == KErrNone);
       
   795 	test(desc_size == KUsbDescSize_CS_Endpoint);
       
   796 
       
   797 	test.Next(_L("GetCSEndpointDescriptorBlock()"));
       
   798 	TBuf8<KUsbDescSize_CS_Endpoint> descriptor2;
       
   799 	r = gPort.GetCSEndpointDescriptorBlock(0, 2, descriptor2);
       
   800 	test(r == KErrNone);
       
   801 
       
   802 	test.Next(_L("Compare CS ep descriptor with value set"));
       
   803 	r = descriptor2.Compare(cs_ep_descriptor);
       
   804 	test(r == KErrNone);
       
   805 
       
   806 	test.End();
       
   807 	}
       
   808 
       
   809 
       
   810 static void TestAlternateInterfaceManipulation()
       
   811 	{
       
   812 	test.Start(_L("Alternate Interface Setting Manipulation"));
       
   813 
       
   814 	if (!SupportsAlternateInterfaces())
       
   815 		{
       
   816 		test.Printf(_L("*** Not supported - skipping alternate interface settings tests\n"));
       
   817 		test.End();
       
   818 		return;
       
   819 		}
       
   820 
       
   821 	// Fetch endpoint data (again)
       
   822 	test.Next(_L("Get endpoint capabilities"));
       
   823 	TUsbDeviceCaps d_caps;
       
   824 	TInt r = gPort.DeviceCaps(d_caps);
       
   825 	test(r == KErrNone);
       
   826 	const TInt n = d_caps().iTotalEndpoints;
       
   827 	TUsbcEndpointData data[KUsbcMaxEndpoints];
       
   828 	TPtr8 dataptr(reinterpret_cast<TUint8*>(data), sizeof(data), sizeof(data));
       
   829 	r = gPort.EndpointCaps(dataptr);
       
   830 	test(r == KErrNone);
       
   831 
       
   832 	// Find ep's for alternate ifc setting
       
   833 	test.Next(_L("Find suitable endpoints"));
       
   834 	TInt ep_found = 0;
       
   835 	TBool foundIsoIN  = EFalse;
       
   836 	TBool foundIsoOUT = EFalse;
       
   837 	TBool foundIntIN  = EFalse;
       
   838 	TUsbcInterfaceInfoBuf ifc;
       
   839 
       
   840 	// NB! We cannot assume that any specific device has any given set of
       
   841 	// capabilities, so whilst we try and set an assortment of endpoint types
       
   842 	// we may not get what we want.
       
   843 
       
   844 	// Also, note that the endpoint[] array in the interface descriptor
       
   845 	// must be filled from ep[0]...ep[n-1].
       
   846 
       
   847 	for (TInt i = 0; i < n; i++)
       
   848 		{
       
   849 		const TUsbcEndpointCaps* const caps = &data[i].iCaps;
       
   850 		const TInt mps = caps->MaxPacketSize();
       
   851 		if (!foundIsoIN &&
       
   852 			(caps->iTypesAndDir & (KUsbEpTypeIsochronous | KUsbEpDirIn)) ==
       
   853 			(KUsbEpTypeIsochronous | KUsbEpDirIn))
       
   854 			{
       
   855 			// This is going to be our Iso TX (IN) endpoint
       
   856 			ifc().iEndpointData[ep_found].iType = KUsbEpTypeIsochronous;
       
   857 			ifc().iEndpointData[ep_found].iDir  = KUsbEpDirIn;
       
   858 			ifc().iEndpointData[ep_found].iSize = mps;
       
   859 			ifc().iEndpointData[ep_found].iInterval = 0x01;	// 2^(bInterval-1)ms, bInterval must be [1..16]
       
   860 			ifc().iEndpointData[ep_found].iInterval_Hs = 0x01; // same as for FS
       
   861 			test.Printf(_L("ISO  IN  size = %4d (ep %d)\n"), mps, ep_found + 1);
       
   862 			foundIsoIN = ETrue;
       
   863 			if (++ep_found == 3)
       
   864 				break;
       
   865 			}
       
   866 		else if (!foundIsoOUT &&
       
   867 				 (caps->iTypesAndDir & (KUsbEpTypeIsochronous | KUsbEpDirOut)) ==
       
   868 				 (KUsbEpTypeIsochronous | KUsbEpDirOut))
       
   869 			{
       
   870 			// This is going to be our Iso RX (OUT) endpoint
       
   871 			ifc().iEndpointData[ep_found].iType = KUsbEpTypeIsochronous;
       
   872 			ifc().iEndpointData[ep_found].iDir  = KUsbEpDirOut;
       
   873 			ifc().iEndpointData[ep_found].iSize = mps;
       
   874 			ifc().iEndpointData[ep_found].iInterval = 0x01;	// 2^(bInterval-1)ms, bInterval must be [1..16]
       
   875 			test.Printf(_L("ISO  OUT size = %4d (ep %d)\n"), mps, ep_found + 1);
       
   876 			foundIsoOUT = ETrue;
       
   877 			if (++ep_found == 3)
       
   878 				break;
       
   879 			}
       
   880 		else if (!foundIntIN &&
       
   881 				 (caps->iTypesAndDir & (KUsbEpTypeInterrupt | KUsbEpDirIn)) ==
       
   882 				 (KUsbEpTypeInterrupt | KUsbEpDirIn))
       
   883 			{
       
   884 			// This is going to be our Interrupt TX (IN) endpoint
       
   885 			ifc().iEndpointData[ep_found].iType  = KUsbEpTypeInterrupt;
       
   886 			ifc().iEndpointData[ep_found].iDir   = KUsbEpDirIn;
       
   887 			ifc().iEndpointData[ep_found].iSize  = mps;
       
   888 			ifc().iEndpointData[ep_found].iInterval = 10;	// interval = 10ms, valid range [1..255]
       
   889 			ifc().iEndpointData[ep_found].iInterval_Hs = 4;	// interval = 2^(bInterval-1)ms = 8ms
       
   890 			ifc().iEndpointData[ep_found].iExtra    = 2;	// 2 extra bytes for Audio Class EP descriptor
       
   891 			test.Printf(_L("INT  IN  size = %4d (ep %d)\n"), mps, ep_found + 1);
       
   892 			foundIntIN = ETrue;
       
   893 			INT_IN_ep = ep_found + 1;
       
   894 			if (++ep_found == 3)
       
   895 				break;
       
   896 			}
       
   897 		}
       
   898 
       
   899 	// Let's try to add some more Bulk endpoints up to the max # of 5.
       
   900 	for (TInt i = 0; i < n; i++)
       
   901 		{
       
   902 		TUsbcEndpointCaps& caps = data[i].iCaps;
       
   903 		const TUint mps = caps.MaxPacketSize();
       
   904 		if (caps.iTypesAndDir & KUsbEpTypeBulk)
       
   905 			{
       
   906 			const TUint dir = (caps.iTypesAndDir & KUsbEpDirIn) ? KUsbEpDirIn : KUsbEpDirOut;
       
   907 			ifc().iEndpointData[ep_found].iType = KUsbEpTypeBulk;
       
   908 			ifc().iEndpointData[ep_found].iDir = dir;
       
   909 			if (gUsingHighSpeed)
       
   910 				{
       
   911 				test.Printf(_L("Checking if correct Bulk packet size is reported in HS case\n"));
       
   912 				test(mps == KUsbEpSize512);					// sane?
       
   913 				}
       
   914 			// The PSL should in any case also offer the 'legacy' FS size:
       
   915 			test(caps.iSizes & KUsbEpSize64);
       
   916 			ifc().iEndpointData[ep_found].iSize = mps;
       
   917 			test.Printf(_L("BULK %s size = %4d (ep %d)\n"),
       
   918 						dir == KUsbEpDirIn ? _S("IN ") : _S("OUT"), mps, ep_found + 1);
       
   919 			if (++ep_found == 5)
       
   920 				break;
       
   921 			}
       
   922 		}
       
   923 
       
   924 	test.Printf(_L("Total: %d endpoints found for the alt. ifc setting\n"), ep_found);
       
   925 	if (ep_found < 3)
       
   926 		{
       
   927 		test.Printf(_L("(3 endpoints are at least required. Skipping test...)\n"));
       
   928 		test.End();
       
   929 		return;
       
   930 		}
       
   931 
       
   932 	if (!foundIsoIN && !foundIsoOUT)
       
   933 		{
       
   934 		test.Printf(_L("(No Isochronous endpoints found)\n"));
       
   935 		}
       
   936 
       
   937 	if (!foundIntIN)
       
   938 		{
       
   939 		test.Printf(_L("(No Interrupt endpoint found)\n"));
       
   940 		test.Printf(_L("Adjusting endpoint size for later test\n"));
       
   941 		// We want to make sure that at least one descriptor has the 2 extra bytes.
       
   942 		// It doesn't matter that this ep could be a Bulk one, or that the 2 Iso ep's might be missing -
       
   943 		// we just want to test some functionality and we're not going to use this interface in earnest.
       
   944 		ifc().iEndpointData[2].iExtra = 2;					// 2 extra bytes for Audio Class Ep descriptor
       
   945 		INT_IN_ep = 3;										// pretend it's an INT ep
       
   946 		}
       
   947 
       
   948 	test.Next(_L("Create alternate interface setting"));
       
   949 	_LIT16(string, "T_USBAPI Test Interface (Setting 1: Audio)");
       
   950 	ifc().iString = const_cast<TDesC16*>(&string);
       
   951 	ifc().iTotalEndpointsUsed = ep_found;
       
   952 	ifc().iClass.iClassNum	  = KUsbAudioInterfaceClassCode;
       
   953 	ifc().iClass.iSubClassNum = KUsbAudioInterfaceSubclassCode_Audiostreaming;
       
   954 	ifc().iClass.iProtocolNum = KUsbAudioInterfaceProtocolCode_Pr_Protocol_Undefined;
       
   955 	r = gPort.SetInterface(1, ifc);
       
   956 	test(r == KErrNone);
       
   957 
       
   958 	test.Next(_L("Set alternate setting number to 8"));
       
   959 	TBuf8<KUsbDescSize_Interface> descriptor;
       
   960 	r = gPort.GetInterfaceDescriptor(1, descriptor);
       
   961 	test(r == KErrNone);
       
   962 	descriptor[KIfcDesc_SettingOffset] = 8;
       
   963 	r = gPort.SetInterfaceDescriptor(1, descriptor);
       
   964 	test(r != KErrNone);
       
   965 
       
   966 	test.Next(_L("Change ifc # in def setting whith alt ifcs"));
       
   967 	r = gPort.GetInterfaceDescriptor(0, descriptor);
       
   968 	test(r == KErrNone);
       
   969 	descriptor[KIfcDesc_SettingOffset] = 8;
       
   970 	r = gPort.SetInterfaceDescriptor(0, descriptor);
       
   971 	test(r != KErrNone);
       
   972 
       
   973 	test.Next(_L("Change the ifc # in default setting to 8"));
       
   974 	r = gPort.ReleaseInterface(1);
       
   975 	test(r == KErrNone);
       
   976 	r = gPort.SetInterfaceDescriptor(0, descriptor);
       
   977 	test(r == KErrNone);
       
   978 
       
   979 	test.Next(_L("Create new setting - this should also get #8"));
       
   980 	r = gPort.SetInterface(1, ifc);
       
   981 	test(r == KErrNone);
       
   982 	r = gPort.GetInterfaceDescriptor(1, descriptor);
       
   983 	test(r == KErrNone);
       
   984 	test(descriptor[KIfcDesc_SettingOffset] == 8);
       
   985 
       
   986 	test.Next(_L("Change the ifc # in default setting to 0"));
       
   987 	r = gPort.ReleaseInterface(1);
       
   988 	test(r == KErrNone);
       
   989 	r = gPort.GetInterfaceDescriptor(0, descriptor);
       
   990 	test(r == KErrNone);
       
   991 	descriptor[KIfcDesc_SettingOffset] = 0;
       
   992 	r = gPort.SetInterfaceDescriptor(0, descriptor);
       
   993 	test(r == KErrNone);
       
   994 
       
   995 	test.Next(_L("Create new setting - this should also get #0"));
       
   996 	r = gPort.SetInterface(1, ifc);
       
   997 	test(r == KErrNone);
       
   998 	r = gPort.GetInterfaceDescriptor(1, descriptor);
       
   999 	test(r == KErrNone);
       
  1000 	test(descriptor[KIfcDesc_SettingOffset] == 0);
       
  1001 
       
  1002 	test.End();
       
  1003 	}
       
  1004 
       
  1005 
       
  1006 static void TestEndpointDescriptor()
       
  1007 	{
       
  1008 	test.Start(_L("Endpoint Descriptor Manipulation"));
       
  1009 
       
  1010 	test.Next(_L("GetEndpointDescriptorSize(1)"));
       
  1011 	TInt epNumber = 1;
       
  1012 	TInt desc_size = 0;
       
  1013 	TInt r = gPort.GetEndpointDescriptorSize(0, epNumber, desc_size);
       
  1014 	test(r == KErrNone);
       
  1015 	test(static_cast<TUint>(desc_size) == KUsbDescSize_Endpoint);
       
  1016 
       
  1017 	test.Next(_L("GetEndpointDescriptor(1)"));
       
  1018 	TBuf8<KUsbDescSize_Endpoint> descriptor;
       
  1019 	r = gPort.GetEndpointDescriptor(0, epNumber, descriptor);
       
  1020 	test(r == KErrNone);
       
  1021 
       
  1022 	test.Next(_L("SetEndpointDescriptor(1)"));
       
  1023 	// Change the endpoint poll interval
       
  1024 	TUint8 ival = 0x66;
       
  1025 	if (descriptor[KEpDesc_IntervalOffset] == ival)
       
  1026 		ival++;
       
  1027 	descriptor[KEpDesc_IntervalOffset] = ival;
       
  1028 	r = gPort.SetEndpointDescriptor(0, epNumber, descriptor);
       
  1029 	test(r == KErrNone);
       
  1030 
       
  1031 	test.Next(_L("GetEndpointDescriptor(1)"));
       
  1032 	TBuf8<KUsbDescSize_Endpoint> descriptor2;
       
  1033 	r = gPort.GetEndpointDescriptor(0, epNumber, descriptor2);
       
  1034 	test(r == KErrNone);
       
  1035 
       
  1036 	test.Next(_L("Compare endpoint descriptor with value set"));
       
  1037 	r = descriptor2.Compare(descriptor);
       
  1038 	test(r == KErrNone);
       
  1039 
       
  1040 	test.Next(_L("Check endpoint max packet size"));
       
  1041 	const TUint16 ep_size = EpSize(descriptor[KEpDesc_PacketSizeOffset],
       
  1042 								   descriptor[KEpDesc_PacketSizeOffset+1]);
       
  1043 	test.Printf(_L(" Size: %d\n"), ep_size);
       
  1044 	if (gUsingHighSpeed)
       
  1045 		{
       
  1046 		// HS Bulk ep can only have one possible packet size.
       
  1047 		test(ep_size == 512);
       
  1048 		}
       
  1049 	else
       
  1050 		{
       
  1051 		// FS Bulk ep cannot be larger than 64 bytes.
       
  1052 		test(ep_size <= 64);
       
  1053 		}
       
  1054 
       
  1055 	test.End();
       
  1056 	}
       
  1057 
       
  1058 
       
  1059 static void TestExtendedEndpointDescriptor()
       
  1060 	{
       
  1061 	test.Start(_L("Extended Endpoint Descriptor Manipulation"));
       
  1062 
       
  1063 	if (!SupportsAlternateInterfaces())
       
  1064 		{
       
  1065 		test.Printf(_L("*** Not supported - skipping Extended Endpoint descriptor tests\n"));
       
  1066 		test.End();
       
  1067 		return;
       
  1068 		}
       
  1069 
       
  1070 	// Extended Endpoint Descriptor manipulation (Audio class endpoint)
       
  1071 
       
  1072 	test.Next(_L("GetEndpointDescriptorSize()"));
       
  1073 	TInt epNumber = INT_IN_ep;
       
  1074 	TInt desc_size = 0;
       
  1075 	TInt r = gPort.GetEndpointDescriptorSize(1, epNumber, desc_size);
       
  1076 	test(r == KErrNone);
       
  1077 	test(static_cast<TUint>(desc_size) == KUsbDescSize_AudioEndpoint);
       
  1078 
       
  1079 	test.Next(_L("GetEndpointDescriptor()"));
       
  1080 	TBuf8<KUsbDescSize_AudioEndpoint> descriptor;
       
  1081 	r = gPort.GetEndpointDescriptor(1, epNumber, descriptor);
       
  1082 	test(r == KErrNone);
       
  1083 
       
  1084 	test.Next(_L("SetEndpointDescriptor()"));
       
  1085 	// Change the Audio Endpoint bSynchAddress field
       
  1086 	TUint8 addr = 0x85;										// bogus address
       
  1087 	if (descriptor[KEpDesc_SynchAddressOffset] == addr)
       
  1088 		addr++;
       
  1089 	descriptor[KEpDesc_SynchAddressOffset] = addr;
       
  1090 	r = gPort.SetEndpointDescriptor(1, epNumber, descriptor);
       
  1091 	test(r == KErrNone);
       
  1092 
       
  1093 	test.Next(_L("GetEndpointDescriptor()"));
       
  1094 	TBuf8<KUsbDescSize_AudioEndpoint> descriptor2;
       
  1095 	r = gPort.GetEndpointDescriptor(1, epNumber, descriptor2);
       
  1096 	test(r == KErrNone);
       
  1097 
       
  1098 	test.Next(_L("Compare endpoint descriptor with value set"));
       
  1099 	r = descriptor2.Compare(descriptor);
       
  1100 	test(r == KErrNone);
       
  1101 
       
  1102 	test.Next(_L("Check endpoint max packet size"));
       
  1103 	const TUint16 ep_size = EpSize(descriptor[KEpDesc_PacketSizeOffset],
       
  1104 								   descriptor[KEpDesc_PacketSizeOffset+1]);
       
  1105 	if (gUsingHighSpeed)
       
  1106 		{
       
  1107 		// HS Interrupt ep.
       
  1108 		test(ep_size <= 1024);
       
  1109 		}
       
  1110 	else
       
  1111 		{
       
  1112 		// FS Interrupt ep cannot be larger than 64 bytes.
       
  1113 		test(ep_size <= 64);
       
  1114 		}
       
  1115 
       
  1116 	test.End();
       
  1117 	}
       
  1118 
       
  1119 
       
  1120 static void TestStandardStringDescriptors()
       
  1121 	{
       
  1122 	test.Start(_L("String Descriptor Manipulation"));
       
  1123 
       
  1124 	//
       
  1125 	// --- LANGID code
       
  1126 	//
       
  1127 
       
  1128 	test.Next(_L("GetStringDescriptorLangId()"));
       
  1129 	TUint16 rd_langid_orig;
       
  1130 	TInt r = gPort.GetStringDescriptorLangId(rd_langid_orig);
       
  1131 	test(r == KErrNone);
       
  1132 	test.Printf(_L("Original LANGID code: 0x%04X\n"), rd_langid_orig);
       
  1133 
       
  1134 	test.Next(_L("SetStringDescriptorLangId()"));
       
  1135 	TUint16 wr_langid = 0x0809;								// English (UK) Language ID
       
  1136 	if (wr_langid == rd_langid_orig)
       
  1137 		wr_langid = 0x0444;									// Tatar Language ID
       
  1138 	r = gPort.SetStringDescriptorLangId(wr_langid);
       
  1139 	test(r == KErrNone);
       
  1140 
       
  1141 	test.Next(_L("GetStringDescriptorLangId()"));
       
  1142 	TUint16 rd_langid;
       
  1143 	r = gPort.GetStringDescriptorLangId(rd_langid);
       
  1144 	test(r == KErrNone);
       
  1145 	test.Printf(_L("New LANGID code: 0x%04X\n"), rd_langid);
       
  1146 
       
  1147 	test.Next(_L("Compare LANGID codes"));
       
  1148 	test(rd_langid == wr_langid);
       
  1149 
       
  1150 	test.Next(_L("Restore original LANGID code"));
       
  1151 	r = gPort.SetStringDescriptorLangId(rd_langid_orig);
       
  1152 	test(r == KErrNone);
       
  1153 	r = gPort.GetStringDescriptorLangId(rd_langid);
       
  1154 	test(r == KErrNone);
       
  1155 	test(rd_langid == rd_langid_orig);
       
  1156 
       
  1157 	//
       
  1158 	// --- Manufacturer string
       
  1159 	//
       
  1160 
       
  1161 	test.Next(_L("GetManufacturerStringDescriptor()"));
       
  1162 	TBuf16<KUsbStringDescStringMaxSize / 2> rd_str_orig;
       
  1163 	r = gPort.GetManufacturerStringDescriptor(rd_str_orig);
       
  1164 	test(r == KErrNone || r == KErrNotFound);
       
  1165 	TBool restore_string;
       
  1166 	if (r == KErrNone)
       
  1167 		{
       
  1168 		test.Printf(_L("Original Manufacturer string: \"%lS\"\n"), &rd_str_orig);
       
  1169 		restore_string = ETrue;
       
  1170 		}
       
  1171 	else
       
  1172 		{
       
  1173 		test.Printf(_L("No Manufacturer string set\n"));
       
  1174 		restore_string = EFalse;
       
  1175 		}
       
  1176 
       
  1177 	test.Next(_L("SetManufacturerStringDescriptor()"));
       
  1178 	_LIT16(manufacturer, "Manufacturer Which Manufactures Devices");
       
  1179 	TBuf16<KUsbStringDescStringMaxSize / 2> wr_str(manufacturer);
       
  1180 	r = gPort.SetManufacturerStringDescriptor(wr_str);
       
  1181 	test(r == KErrNone);
       
  1182 
       
  1183 	test.Next(_L("GetManufacturerStringDescriptor()"));
       
  1184 	TBuf16<KUsbStringDescStringMaxSize / 2> rd_str;
       
  1185 	r = gPort.GetManufacturerStringDescriptor(rd_str);
       
  1186 	test(r == KErrNone);
       
  1187 	test.Printf(_L("New Manufacturer string: \"%lS\"\n"), &rd_str);
       
  1188 
       
  1189 	test.Next(_L("Compare Manufacturer strings"));
       
  1190 	r = rd_str.Compare(wr_str);
       
  1191 	test(r == KErrNone);
       
  1192 
       
  1193 	test.Next(_L("SetManufacturerStringDescriptor()"));
       
  1194 	_LIT16(manufacturer2, "Different Manufacturer Which Manufactures Different Devices");
       
  1195 	wr_str.FillZ(wr_str.MaxLength());
       
  1196 	wr_str = manufacturer2;
       
  1197 	r = gPort.SetManufacturerStringDescriptor(wr_str);
       
  1198 	test(r == KErrNone);
       
  1199 
       
  1200 	test.Next(_L("GetManufacturerStringDescriptor()"));
       
  1201 	rd_str.FillZ(rd_str.MaxLength());
       
  1202 	r = gPort.GetManufacturerStringDescriptor(rd_str);
       
  1203 	test(r == KErrNone);
       
  1204 	test.Printf(_L("New Manufacturer string: \"%lS\"\n"), &rd_str);
       
  1205 
       
  1206 	test.Next(_L("Compare Manufacturer strings"));
       
  1207 	r = rd_str.Compare(wr_str);
       
  1208 	test(r == KErrNone);
       
  1209 
       
  1210 	test.Next(_L("RemoveManufacturerStringDescriptor()"));
       
  1211 	r = gPort.RemoveManufacturerStringDescriptor();
       
  1212 	test(r == KErrNone);
       
  1213 	r = gPort.GetManufacturerStringDescriptor(rd_str);
       
  1214 	test(r == KErrNotFound);
       
  1215 
       
  1216 	if (restore_string)
       
  1217 		{
       
  1218 		test.Next(_L("Restore original string"));
       
  1219 		r = gPort.SetManufacturerStringDescriptor(rd_str_orig);
       
  1220 		test(r == KErrNone);
       
  1221 		r = gPort.GetManufacturerStringDescriptor(rd_str);
       
  1222 		test(r == KErrNone);
       
  1223 		r = rd_str.Compare(rd_str_orig);
       
  1224 		test(r == KErrNone);
       
  1225 		}
       
  1226 
       
  1227 	//
       
  1228 	// --- Product string
       
  1229 	//
       
  1230 
       
  1231 	test.Next(_L("GetProductStringDescriptor()"));
       
  1232 	rd_str_orig.FillZ(rd_str.MaxLength());
       
  1233 	r = gPort.GetProductStringDescriptor(rd_str_orig);
       
  1234 	test(r == KErrNone || r == KErrNotFound);
       
  1235 	if (r == KErrNone)
       
  1236 		{
       
  1237 		test.Printf(_L("Old Product string: \"%lS\"\n"), &rd_str_orig);
       
  1238 		restore_string = ETrue;
       
  1239 		}
       
  1240 	else
       
  1241 		restore_string = EFalse;
       
  1242 
       
  1243 	test.Next(_L("SetProductStringDescriptor()"));
       
  1244 	_LIT16(product, "Product That Was Produced By A Manufacturer");
       
  1245 	wr_str.FillZ(wr_str.MaxLength());
       
  1246 	wr_str = product;
       
  1247 	r = gPort.SetProductStringDescriptor(wr_str);
       
  1248 	test(r == KErrNone);
       
  1249 
       
  1250 	test.Next(_L("GetProductStringDescriptor()"));
       
  1251 	rd_str.FillZ(rd_str.MaxLength());
       
  1252 	r = gPort.GetProductStringDescriptor(rd_str);
       
  1253 	test(r == KErrNone);
       
  1254 	test.Printf(_L("New Product string: \"%lS\"\n"), &rd_str);
       
  1255 
       
  1256 	test.Next(_L("Compare Product strings"));
       
  1257 	r = rd_str.Compare(wr_str);
       
  1258 	test(r == KErrNone);
       
  1259 
       
  1260 	test.Next(_L("SetProductStringDescriptor()"));
       
  1261 	_LIT16(product2, "Different Product That Was Produced By A Different Manufacturer");
       
  1262 	wr_str.FillZ(wr_str.MaxLength());
       
  1263 	wr_str = product2;
       
  1264 	r = gPort.SetProductStringDescriptor(wr_str);
       
  1265 	test(r == KErrNone);
       
  1266 
       
  1267 	test.Next(_L("GetProductStringDescriptor()"));
       
  1268 	rd_str.FillZ(rd_str.MaxLength());
       
  1269 	r = gPort.GetProductStringDescriptor(rd_str);
       
  1270 	test(r == KErrNone);
       
  1271 	test.Printf(_L("New Product string: \"%lS\"\n"), &rd_str);
       
  1272 
       
  1273 	test.Next(_L("Compare Product strings"));
       
  1274 	r = rd_str.Compare(wr_str);
       
  1275 	test(r == KErrNone);
       
  1276 
       
  1277 	test.Next(_L("RemoveProductStringDescriptor()"));
       
  1278 	r = gPort.RemoveProductStringDescriptor();
       
  1279 	test(r == KErrNone);
       
  1280 	r = gPort.GetProductStringDescriptor(rd_str);
       
  1281 	test(r == KErrNotFound);
       
  1282 
       
  1283 	if (restore_string)
       
  1284 		{
       
  1285 		test.Next(_L("Restore original string"));
       
  1286 		r = gPort.SetProductStringDescriptor(rd_str_orig);
       
  1287 		test(r == KErrNone);
       
  1288 		r = gPort.GetProductStringDescriptor(rd_str);
       
  1289 		test(r == KErrNone);
       
  1290 		r = rd_str.Compare(rd_str_orig);
       
  1291 		test(r == KErrNone);
       
  1292 		}
       
  1293 
       
  1294 	//
       
  1295 	// --- Serial Number string
       
  1296 	//
       
  1297 
       
  1298 	test.Next(_L("GetSerialNumberStringDescriptor()"));
       
  1299 	rd_str_orig.FillZ(rd_str.MaxLength());
       
  1300 	r = gPort.GetSerialNumberStringDescriptor(rd_str_orig);
       
  1301 	test(r == KErrNone || r == KErrNotFound);
       
  1302 	if (r == KErrNone)
       
  1303 		{
       
  1304 		test.Printf(_L("Old Serial Number: \"%lS\"\n"), &rd_str_orig);
       
  1305 		restore_string = ETrue;
       
  1306 		}
       
  1307 	else
       
  1308 		restore_string = EFalse;
       
  1309 
       
  1310 	test.Next(_L("SetSerialNumberStringDescriptor()"));
       
  1311 	_LIT16(serial, "000666000XYZ");
       
  1312 	wr_str.FillZ(wr_str.MaxLength());
       
  1313 	wr_str = serial;
       
  1314 	r = gPort.SetSerialNumberStringDescriptor(wr_str);
       
  1315 	test(r == KErrNone);
       
  1316 
       
  1317 	test.Next(_L("GetSerialNumberStringDescriptor()"));
       
  1318 	rd_str.FillZ(rd_str.MaxLength());
       
  1319 	r = gPort.GetSerialNumberStringDescriptor(rd_str);
       
  1320 	test(r == KErrNone);
       
  1321 	test.Printf(_L("New Serial Number: \"%lS\"\n"), &rd_str);
       
  1322 
       
  1323 	test.Next(_L("Compare Serial Number strings"));
       
  1324 	r = rd_str.Compare(wr_str);
       
  1325 	test(r == KErrNone);
       
  1326 
       
  1327 	test.Next(_L("SetSerialNumberStringDescriptor()"));
       
  1328 	_LIT16(serial2, "Y11611193111711111Y");
       
  1329 	wr_str.FillZ(wr_str.MaxLength());
       
  1330 	wr_str = serial2;
       
  1331 	r = gPort.SetSerialNumberStringDescriptor(wr_str);
       
  1332 	test(r == KErrNone);
       
  1333 
       
  1334 	test.Next(_L("GetSerialNumberStringDescriptor()"));
       
  1335 	rd_str.FillZ(rd_str.MaxLength());
       
  1336 	r = gPort.GetSerialNumberStringDescriptor(rd_str);
       
  1337 	test(r == KErrNone);
       
  1338 	test.Printf(_L("New Serial Number: \"%lS\"\n"), &rd_str);
       
  1339 
       
  1340 	test.Next(_L("Compare Serial Number strings"));
       
  1341 	r = rd_str.Compare(wr_str);
       
  1342 	test(r == KErrNone);
       
  1343 
       
  1344 	test.Next(_L("RemoveSerialNumberStringDescriptor()"));
       
  1345 	r = gPort.RemoveSerialNumberStringDescriptor();
       
  1346 	test(r == KErrNone);
       
  1347 	r = gPort.GetSerialNumberStringDescriptor(rd_str);
       
  1348 	test(r == KErrNotFound);
       
  1349 
       
  1350 	if (restore_string)
       
  1351 		{
       
  1352 		test.Next(_L("Restore original string"));
       
  1353 		r = gPort.SetSerialNumberStringDescriptor(rd_str_orig);
       
  1354 		test(r == KErrNone);
       
  1355 		r = gPort.GetSerialNumberStringDescriptor(rd_str);
       
  1356 		test(r == KErrNone);
       
  1357 		r = rd_str.Compare(rd_str_orig);
       
  1358 		test(r == KErrNone);
       
  1359 		}
       
  1360 
       
  1361 	//
       
  1362 	// --- Configuration string
       
  1363 	//
       
  1364 
       
  1365 	test.Next(_L("GetConfigurationStringDescriptor()"));
       
  1366 	rd_str_orig.FillZ(rd_str.MaxLength());
       
  1367 	r = gPort.GetConfigurationStringDescriptor(rd_str_orig);
       
  1368 	test(r == KErrNone || r == KErrNotFound);
       
  1369 	if (r == KErrNone)
       
  1370 		{
       
  1371 		test.Printf(_L("Old Configuration string: \"%lS\"\n"), &rd_str_orig);
       
  1372 		restore_string = ETrue;
       
  1373 		}
       
  1374 	else
       
  1375 		restore_string = EFalse;
       
  1376 
       
  1377 	test.Next(_L("SetConfigurationStringDescriptor()"));
       
  1378 	_LIT16(config, "Relatively Simple Configuration That Is Still Useful");
       
  1379 	wr_str.FillZ(wr_str.MaxLength());
       
  1380 	wr_str = config;
       
  1381 	r = gPort.SetConfigurationStringDescriptor(wr_str);
       
  1382 	test(r == KErrNone);
       
  1383 
       
  1384 	test.Next(_L("GetConfigurationStringDescriptor()"));
       
  1385 	rd_str.FillZ(rd_str.MaxLength());
       
  1386 	r = gPort.GetConfigurationStringDescriptor(rd_str);
       
  1387 	test(r == KErrNone);
       
  1388 	test.Printf(_L("New Configuration string: \"%lS\"\n"), &rd_str);
       
  1389 
       
  1390 	test.Next(_L("Compare Configuration strings"));
       
  1391 	r = rd_str.Compare(wr_str);
       
  1392 	test(r == KErrNone);
       
  1393 
       
  1394 	test.Next(_L("SetConfigurationStringDescriptor()"));
       
  1395 	_LIT16(config2, "Convenient Configuration That Can Be Very Confusing");
       
  1396 	wr_str.FillZ(wr_str.MaxLength());
       
  1397 	wr_str = config2;
       
  1398 	r = gPort.SetConfigurationStringDescriptor(wr_str);
       
  1399 	test(r == KErrNone);
       
  1400 
       
  1401 	test.Next(_L("GetConfigurationStringDescriptor()"));
       
  1402 	rd_str.FillZ(rd_str.MaxLength());
       
  1403 	r = gPort.GetConfigurationStringDescriptor(rd_str);
       
  1404 	test(r == KErrNone);
       
  1405 	test.Printf(_L("New Configuration string: \"%lS\"\n"), &rd_str);
       
  1406 
       
  1407 	test.Next(_L("Compare Configuration strings"));
       
  1408 	r = rd_str.Compare(wr_str);
       
  1409 	test(r == KErrNone);
       
  1410 
       
  1411 	test.Next(_L("RemoveConfigurationStringDescriptor()"));
       
  1412 	r = gPort.RemoveConfigurationStringDescriptor();
       
  1413 	test(r == KErrNone);
       
  1414 	r = gPort.GetConfigurationStringDescriptor(rd_str);
       
  1415 	test(r == KErrNotFound);
       
  1416 
       
  1417 	if (restore_string)
       
  1418 		{
       
  1419 		test.Next(_L("Restore original string"));
       
  1420 		r = gPort.SetConfigurationStringDescriptor(rd_str_orig);
       
  1421 		test(r == KErrNone);
       
  1422 		r = gPort.GetConfigurationStringDescriptor(rd_str);
       
  1423 		test(r == KErrNone);
       
  1424 		r = rd_str.Compare(rd_str_orig);
       
  1425 		test(r == KErrNone);
       
  1426 		}
       
  1427 
       
  1428 	test.End();
       
  1429 	}
       
  1430 
       
  1431 
       
  1432 //---------------------------------------------
       
  1433 //! @SYMTestCaseID KBASE-T_USBAPI-0041
       
  1434 //! @SYMTestType UT
       
  1435 //! @SYMREQ REQ5662
       
  1436 //! @SYMTestCaseDesc USB Device Driver API extension to support setting of a string descriptor at a specific index
       
  1437 //! @SYMTestActions Tests GetStringDescriptor(), SetStringDescriptor() and RemoveStringDescriptor() to verify
       
  1438 //! the right values are retrieved, set and deleted at specific positions
       
  1439 //! @SYMTestExpectedResults KErrNone in positive testing and KErrNotFound in negative one
       
  1440 //! @SYMTestPriority High
       
  1441 //! @SYMTestStatus Implemented
       
  1442 //---------------------------------------------
       
  1443 static void TestArbitraryStringDescriptors()
       
  1444 	{
       
  1445 	test.Start(_L("Arbitrary String Descriptor Manipulation"));
       
  1446 
       
  1447 	const TUint8 stridx1 = 0xEE;
       
  1448 	const TUint8 stridx2 = 0xCC;
       
  1449 	const TUint8 stridx3 = 0xDD;
       
  1450 	const TUint8 stridx4 = 0xFF;
       
  1451 
       
  1452 	// First test string
       
  1453 
       
  1454 	test.Next(_L("GetStringDescriptor() 1"));
       
  1455 	TBuf16<KUsbStringDescStringMaxSize / 2> rd_str;
       
  1456 	TInt r = gPort.GetStringDescriptor(stridx1, rd_str);
       
  1457 	test(r == KErrNotFound);
       
  1458 
       
  1459 	test.Next(_L("SetStringDescriptor() 1"));
       
  1460 	_LIT16(string_one, "Arbitrary String Descriptor Test String 1");
       
  1461 	TBuf16<KUsbStringDescStringMaxSize / 2> wr_str(string_one);
       
  1462 	r = gPort.SetStringDescriptor(stridx1, wr_str);
       
  1463 	test(r == KErrNone);
       
  1464 
       
  1465 	test.Next(_L("GetStringDescriptor() 1"));
       
  1466 	r = gPort.GetStringDescriptor(stridx1, rd_str);
       
  1467 	test(r == KErrNone);
       
  1468 	test.Printf(_L("New test string @ idx %d: \"%lS\"\n"), stridx1, &rd_str);
       
  1469 
       
  1470 	test.Next(_L("Compare test strings 1"));
       
  1471 	r = rd_str.Compare(wr_str);
       
  1472 	test(r == KErrNone);
       
  1473 
       
  1474 	// Second test string
       
  1475 
       
  1476 	test.Next(_L("GetStringDescriptor() 2"));
       
  1477 	rd_str.FillZ(rd_str.MaxLength());
       
  1478 	r = gPort.GetStringDescriptor(stridx2, rd_str);
       
  1479 	test(r == KErrNotFound);
       
  1480 
       
  1481 	test.Next(_L("SetStringDescriptor() 2"));
       
  1482 	_LIT16(string_two, "Arbitrary String Descriptor Test String 2");
       
  1483 	wr_str.FillZ(wr_str.MaxLength());
       
  1484 	wr_str = string_two;
       
  1485 	r = gPort.SetStringDescriptor(stridx2, wr_str);
       
  1486 	test(r == KErrNone);
       
  1487 
       
  1488 	// In between we create another interface setting to see what happens
       
  1489 	// to the existing string descriptor indices.
       
  1490 	// (We don't have to test this on every platform -
       
  1491 	// besides, those that don't support alt settings
       
  1492 	// are by now very rare.)
       
  1493 	if (SupportsAlternateInterfaces())
       
  1494 		{
       
  1495 		TUsbcInterfaceInfoBuf ifc;
       
  1496 		_LIT16(string, "T_USBAPI Bogus Test Interface (Setting 2)");
       
  1497 		ifc().iString = const_cast<TDesC16*>(&string);
       
  1498 		ifc().iTotalEndpointsUsed = 0;
       
  1499 		TInt r = gPort.SetInterface(2, ifc);
       
  1500 		test(r == KErrNone);
       
  1501 		}
       
  1502 
       
  1503 	test.Next(_L("GetStringDescriptor() 2"));
       
  1504 	r = gPort.GetStringDescriptor(stridx2, rd_str);
       
  1505 	test(r == KErrNone);
       
  1506 	test.Printf(_L("New test string @ idx %d: \"%lS\"\n"), stridx2, &rd_str);
       
  1507 
       
  1508 	test.Next(_L("Compare test strings 2"));
       
  1509 	r = rd_str.Compare(wr_str);
       
  1510 	test(r == KErrNone);
       
  1511 
       
  1512 	// Third test string
       
  1513 
       
  1514 	test.Next(_L("GetStringDescriptor() 3"));
       
  1515 	rd_str.FillZ(rd_str.MaxLength());
       
  1516 	r = gPort.GetStringDescriptor(stridx3, rd_str);
       
  1517 	test(r == KErrNotFound);
       
  1518 
       
  1519 	test.Next(_L("SetStringDescriptor() 3"));
       
  1520 	_LIT16(string_three, "Arbitrary String Descriptor Test String 3");
       
  1521 	wr_str.FillZ(wr_str.MaxLength());
       
  1522 	wr_str = string_three;
       
  1523 	r = gPort.SetStringDescriptor(stridx3, wr_str);
       
  1524 	test(r == KErrNone);
       
  1525 
       
  1526 	test.Next(_L("GetStringDescriptor() 3"));
       
  1527 	r = gPort.GetStringDescriptor(stridx3, rd_str);
       
  1528 	test(r == KErrNone);
       
  1529 	test.Printf(_L("New test string @ idx %d: \"%lS\"\n"), stridx3, &rd_str);
       
  1530 
       
  1531 	test.Next(_L("Compare test strings 3"));
       
  1532 	r = rd_str.Compare(wr_str);
       
  1533 	test(r == KErrNone);
       
  1534 
       
  1535 	// Remove string descriptors
       
  1536 
       
  1537 	test.Next(_L("RemoveStringDescriptor() 4"));
       
  1538 	r = gPort.RemoveStringDescriptor(stridx4);
       
  1539 	test(r == KErrNotFound);
       
  1540 
       
  1541 	test.Next(_L("RemoveStringDescriptor() 3"));
       
  1542 	r = gPort.RemoveStringDescriptor(stridx3);
       
  1543 	test(r == KErrNone);
       
  1544 	r = gPort.GetStringDescriptor(stridx3, rd_str);
       
  1545 	test(r == KErrNotFound);
       
  1546 
       
  1547 	test.Next(_L("RemoveStringDescriptor() 2"));
       
  1548 	r = gPort.RemoveStringDescriptor(stridx2);
       
  1549 	test(r == KErrNone);
       
  1550 	r = gPort.GetStringDescriptor(stridx2, rd_str);
       
  1551 	test(r == KErrNotFound);
       
  1552 
       
  1553 	test.Next(_L("RemoveStringDescriptor() 1"));
       
  1554 	r = gPort.RemoveStringDescriptor(stridx1);
       
  1555 	test(r == KErrNone);
       
  1556 	r = gPort.GetStringDescriptor(stridx1, rd_str);
       
  1557 	test(r == KErrNotFound);
       
  1558 
       
  1559 	test.End();
       
  1560 	}
       
  1561 
       
  1562 
       
  1563 static void TestDescriptorManipulation()
       
  1564 	{
       
  1565 	test.Start(_L("Test USB Descriptor Manipulation"));
       
  1566 
       
  1567 	TestDeviceDescriptor();
       
  1568 
       
  1569 	TestDeviceQualifierDescriptor();
       
  1570 
       
  1571 	TestConfigurationDescriptor();
       
  1572 
       
  1573 	TestOtherSpeedConfigurationDescriptor();
       
  1574 
       
  1575 	TestInterfaceDescriptor();
       
  1576 
       
  1577 	TestClassSpecificDescriptors();
       
  1578 
       
  1579 	TestAlternateInterfaceManipulation();
       
  1580 
       
  1581 	TestEndpointDescriptor();
       
  1582 
       
  1583 	TestExtendedEndpointDescriptor();
       
  1584 
       
  1585 	TestStandardStringDescriptors();
       
  1586 
       
  1587 	TestArbitraryStringDescriptors();
       
  1588 
       
  1589 	test.End();
       
  1590 	}
       
  1591 
       
  1592 
       
  1593 //---------------------------------------------
       
  1594 //! @SYMTestCaseID KBASE-T_USBAPI-0040
       
  1595 //! @SYMTestType UT
       
  1596 //! @SYMTestCaseDesc Test OTG extensions
       
  1597 //! @SYMTestExpectedResults All APIs behave as expected
       
  1598 //! @SYMTestPriority Medium
       
  1599 //! @SYMTestStatus Implemented
       
  1600 //---------------------------------------------
       
  1601 static void TestOtgExtensions()
       
  1602 	{
       
  1603 	test.Start(_L("Test Some OTG API Extensions"));
       
  1604 
       
  1605 	// Test OTG descriptor manipulation
       
  1606 	test.Next(_L("Get OTG Descriptor Size"));
       
  1607 	TInt size;
       
  1608 	gPort.GetOtgDescriptorSize(size);
       
  1609 	test(static_cast<TUint>(size) == KUsbDescSize_Otg);
       
  1610 
       
  1611 	test.Next(_L("Get OTG Descriptor"));
       
  1612 	TBuf8<KUsbDescSize_Otg> otgDesc;
       
  1613 	TInt r = gPort.GetOtgDescriptor(otgDesc);
       
  1614 	test(r == KErrNotSupported || r == KErrNone);
       
  1615 
       
  1616 	test.Next(_L("Set OTG Descriptor"));
       
  1617 	if (r == KErrNotSupported)
       
  1618 		{
       
  1619 		r = gPort.SetOtgDescriptor(otgDesc);
       
  1620 		test(r == KErrNotSupported);
       
  1621 		}
       
  1622 	else
       
  1623 		{
       
  1624 		otgDesc[0] = KUsbDescSize_Otg;
       
  1625 		otgDesc[1] = KUsbDescType_Otg;
       
  1626 		// The next step is likely to reset KUsbOtgAttr_HnpSupp
       
  1627 		otgDesc[2] = KUsbOtgAttr_SrpSupp;
       
  1628 		r = gPort.SetOtgDescriptor(otgDesc);
       
  1629 		test(r == KErrNone);
       
  1630 		TBuf8<KUsbDescSize_Otg> desc;
       
  1631 		r = gPort.GetOtgDescriptor(desc);
       
  1632 		test(r == KErrNone);
       
  1633 		test(desc.Compare(otgDesc) == 0);
       
  1634 		}
       
  1635 
       
  1636 	// Test get OTG features
       
  1637 	test.Next(_L("Get OTG Features"));
       
  1638 	TUint8 features;
       
  1639 	r = gPort.GetOtgFeatures(features);
       
  1640 	if (gSupportsOtg)
       
  1641 		{
       
  1642 		test(r == KErrNone);
       
  1643 		TBool b_HnpEnable = (features & KUsbOtgAttr_B_HnpEnable) ? ETrue : EFalse;
       
  1644 		TBool a_HnpSupport = (features & KUsbOtgAttr_A_HnpSupport) ? ETrue : EFalse;
       
  1645 		TBool a_AltHnpSupport = (features & KUsbOtgAttr_A_AltHnpSupport) ? ETrue : EFalse;
       
  1646 		test.Printf(_L("### OTG Features:\nB_HnpEnable(%d)\nA_HnpSupport(%d)\nA_Alt_HnpSupport(%d)\n"),
       
  1647 					b_HnpEnable, a_HnpSupport, a_AltHnpSupport);
       
  1648 		}
       
  1649 	else
       
  1650 		{
       
  1651 		test(r == KErrNotSupported);
       
  1652 		test.Printf(_L("GetOtgFeatures() not supported\n"));
       
  1653 		}
       
  1654 
       
  1655 	test.End();
       
  1656 }
       
  1657 
       
  1658 
       
  1659 static void TestEndpoint0MaxPacketSizes()
       
  1660 	{
       
  1661 	test.Start(_L("Test Endpoint0 MaxPacketSizes"));
       
  1662 
       
  1663 	TUint32 sizes = gPort.EndpointZeroMaxPacketSizes();
       
  1664 	TInt r = KErrNone;
       
  1665 	TBool good;
       
  1666 	TInt mpsize = 0;
       
  1667 	for (TInt i = 0; i < 32; i++)
       
  1668 		{
       
  1669 		TUint bit = sizes & (1 << i);
       
  1670 		if (bit != 0)
       
  1671 			{
       
  1672 			switch (bit)
       
  1673 				{
       
  1674 			case KUsbEpSizeCont:
       
  1675 				good = EFalse;
       
  1676 				break;
       
  1677 			case KUsbEpSize8:
       
  1678 				mpsize = 8;
       
  1679 				good = ETrue;
       
  1680 				break;
       
  1681 			case KUsbEpSize16:
       
  1682 				mpsize = 16;
       
  1683 				good = ETrue;
       
  1684 				break;
       
  1685 			case KUsbEpSize32:
       
  1686 				mpsize = 32;
       
  1687 				good = ETrue;
       
  1688 				break;
       
  1689 			case KUsbEpSize64:
       
  1690 				mpsize = 64;
       
  1691 				good = ETrue;
       
  1692 				break;
       
  1693 			case KUsbEpSize128:
       
  1694 			case KUsbEpSize256:
       
  1695 			case KUsbEpSize512:
       
  1696 			case KUsbEpSize1023:
       
  1697 			default:
       
  1698 				good = EFalse;
       
  1699 				break;
       
  1700 				}
       
  1701 			if (good)
       
  1702 				{
       
  1703 				test.Printf(_L("Ep0 supports %d bytes MaxPacketSize\n"), mpsize);
       
  1704 				}
       
  1705 			else
       
  1706 				{
       
  1707 				test.Printf(_L("Bad Ep0 size: 0x%08x, failure will occur\n"), bit);
       
  1708 				r = KErrGeneral;
       
  1709 				}
       
  1710 			}
       
  1711 		}
       
  1712 	test(r == KErrNone);
       
  1713 
       
  1714     test.End();
       
  1715 	}
       
  1716 
       
  1717 
       
  1718 static void TestDeviceControl()
       
  1719 	{
       
  1720 	test.Start(_L("Test Device Control"));
       
  1721 
       
  1722 	// This is a quick and crude test, to make sure that we don't get a steaming heap
       
  1723 	// as a result of calling the device control API's.
       
  1724 	test.Next(_L("SetDeviceControl()"));
       
  1725 	TInt r = gPort.SetDeviceControl();
       
  1726 	test(r == KErrNone);
       
  1727 	test.Next(_L("ReleaseDeviceControl()"));
       
  1728 	r = gPort.ReleaseDeviceControl();
       
  1729 	test(r == KErrNone);
       
  1730 
       
  1731 	test.End();
       
  1732 	}
       
  1733 
       
  1734 
       
  1735 static void TestAlternateDeviceStatusNotify()
       
  1736 	{
       
  1737 	test.Start(_L("Test Alternate Device Status Notification"));
       
  1738 
       
  1739 	TRequestStatus dev_status;
       
  1740 	TUint deviceState = 0xffffffff;						// put in a nonsense value
       
  1741 	test.Next(_L("AlternateDeviceStatusNotify()"));
       
  1742 	gPort.AlternateDeviceStatusNotify(dev_status, deviceState);
       
  1743 	test.Next(_L("AlternateDeviceStatusNotifyCancel()"));
       
  1744 	gPort.AlternateDeviceStatusNotifyCancel();
       
  1745 	User::WaitForRequest(dev_status);
       
  1746 	test(dev_status == KErrCancel || dev_status == KErrNone);
       
  1747 	if (deviceState & KUsbAlternateSetting)
       
  1748 		{
       
  1749 		TUint setting = (deviceState & ~KUsbAlternateSetting);
       
  1750 		test.Printf(_L("Alternate setting change to setting %d - unexpected"), setting);
       
  1751 		test(EFalse);
       
  1752 		}
       
  1753 	else
       
  1754 		{
       
  1755 		switch (deviceState)
       
  1756 			{
       
  1757 		case EUsbcDeviceStateUndefined:
       
  1758 			test.Printf(_L("TestAlternateDeviceStatusNotify: Undefined state\n"));
       
  1759 			break;
       
  1760 		case EUsbcDeviceStateAttached:
       
  1761 			test.Printf(_L("TestAlternateDeviceStatusNotify: Attached state\n"));
       
  1762 			break;
       
  1763 		case EUsbcDeviceStatePowered:
       
  1764 			test.Printf(_L("TestAlternateDeviceStatusNotify: Powered state\n"));
       
  1765 			break;
       
  1766 		case EUsbcDeviceStateDefault:
       
  1767 			test.Printf(_L("TestAlternateDeviceStatusNotify: Default state\n"));
       
  1768 			break;
       
  1769 		case EUsbcDeviceStateAddress:
       
  1770 			test.Printf(_L("TestAlternateDeviceStatusNotify: Address state\n"));
       
  1771 			break;
       
  1772 		case EUsbcDeviceStateConfigured:
       
  1773 			test.Printf(_L("TestAlternateDeviceStatusNotify: Configured state\n"));
       
  1774 			break;
       
  1775 		case EUsbcDeviceStateSuspended:
       
  1776 			test.Printf(_L("TestAlternateDeviceStatusNotify: Suspended state\n"));
       
  1777 			break;
       
  1778 		case EUsbcNoState:
       
  1779 			test.Printf(_L("TestAlternateDeviceStatusNotify: State buffering error\n"));
       
  1780 			test(EFalse);
       
  1781 			break;
       
  1782 		default:
       
  1783 			test.Printf(_L("TestAlternateDeviceStatusNotify: Unknown state\n"));
       
  1784 			test(EFalse);
       
  1785 			}
       
  1786 		}
       
  1787 
       
  1788 	test.End();
       
  1789 	}
       
  1790 
       
  1791 
       
  1792 static void TestEndpointStatusNotify()
       
  1793 	{
       
  1794 	test.Start(_L("Test Endpoint Status Notification"));
       
  1795 
       
  1796 	TRequestStatus ep_status;
       
  1797 	TUint epStateBitmap = 0xffffffff;						// put in a nonsense value
       
  1798 	test.Next(_L("EndpointStatusNotify()"));
       
  1799 	gPort.EndpointStatusNotify(ep_status, epStateBitmap);
       
  1800 	test.Next(_L("EndpointStatusNotifyCancel()"));
       
  1801 	gPort.EndpointStatusNotifyCancel();
       
  1802 	User::WaitForRequest(ep_status);
       
  1803 	test(ep_status.Int() == KErrCancel);
       
  1804 	test.Next(_L("Check endpoint state bitmap returned"));
       
  1805 	// Our ifc only uses 2 eps + ep0 is automatically granted:
       
  1806 	const TUint usedEpBitmap = (1 << EEndpoint0 | 1 << EEndpoint1 | 1 << EEndpoint2);
       
  1807 	// Must not return info about non existent Eps:
       
  1808 	test((epStateBitmap & ~usedEpBitmap) == 0);
       
  1809 	for (TInt i = 0; i <= 2; i++)
       
  1810 		{
       
  1811 		if ((epStateBitmap & (1 << i)) == EEndpointStateNotStalled)
       
  1812 			{
       
  1813 			test.Printf(_L("EndpointStatusNotify: Ep %d NOT STALLED\n"), i);
       
  1814 			}
       
  1815 		else
       
  1816 			{
       
  1817 			test.Printf(_L("EndpointStatusNotify: Ep %d STALLED\n"), i);
       
  1818 			}
       
  1819 		}
       
  1820 
       
  1821 	test.End();
       
  1822 	}
       
  1823 
       
  1824 
       
  1825 static void TestEndpointStallStatus()
       
  1826 	{
       
  1827 	test.Start(_L("Test Endpoint Stall Status"));
       
  1828 
       
  1829 	if (!SupportsEndpointStall())
       
  1830 		{
       
  1831 		test.Printf(_L("*** Not supported - skipping endpoint stall status tests\n"));
       
  1832 		test.End();
       
  1833 		return;
       
  1834 		}
       
  1835 
       
  1836 	test.Next(_L("Endpoint stall status"));
       
  1837 	TEndpointState epState = EEndpointStateUnknown;
       
  1838 	QueryEndpointState(EEndpoint1);
       
  1839 	QueryEndpointState(EEndpoint2);
       
  1840 
       
  1841 	test.Next(_L("Stall Ep1"));
       
  1842 	gPort.HaltEndpoint(EEndpoint1);
       
  1843 	epState = QueryEndpointState(EEndpoint1);
       
  1844 	test(epState == EEndpointStateStalled);
       
  1845 
       
  1846 	test.Next(_L("Clear Stall Ep1"));
       
  1847 	gPort.ClearHaltEndpoint(EEndpoint1);
       
  1848 	epState = QueryEndpointState(EEndpoint1);
       
  1849 	test(epState == EEndpointStateNotStalled);
       
  1850 
       
  1851 	test.Next(_L("Stall Ep2"));
       
  1852 	gPort.HaltEndpoint(EEndpoint2);
       
  1853 	epState = QueryEndpointState(EEndpoint2);
       
  1854 	test(epState == EEndpointStateStalled);
       
  1855 
       
  1856 	test.Next(_L("Clear Stall Ep2"));
       
  1857 	gPort.ClearHaltEndpoint(EEndpoint2);
       
  1858 	epState = QueryEndpointState(EEndpoint2);
       
  1859 	test(epState == EEndpointStateNotStalled);
       
  1860 
       
  1861 	test.End();
       
  1862 	}
       
  1863 
       
  1864 
       
  1865 static void CloseChannel()
       
  1866 	{
       
  1867 	test.Start(_L("Close Channel"));
       
  1868 
       
  1869 	test.Next(_L("Disconnect Device from Host"));
       
  1870 	TInt r = gPort.DeviceDisconnectFromHost();
       
  1871 	test(r != KErrGeneral);
       
  1872 
       
  1873 	if (gSupportsOtg)
       
  1874 		{
       
  1875 		test.Next(_L("Stop OTG stack"));
       
  1876 		gOTG.StopStacks();
       
  1877 		test.Next(_L("Close OTG Channel"));
       
  1878 		gOTG.Close();
       
  1879 		test.Next(_L("Free OTG LDD"));
       
  1880 		r = User::FreeLogicalDevice(RUsbOtgDriver::Name());
       
  1881 		test(r == KErrNone);
       
  1882 		}
       
  1883 
       
  1884 	test.Next(_L("Close USB Channel"));
       
  1885 	gPort.Close();
       
  1886 	test.Next(_L("Free USB LDD"));
       
  1887 	r = User::FreeLogicalDevice(KUsbDeviceName);
       
  1888 	test(r == KErrNone);
       
  1889 
       
  1890 	test.End();
       
  1891 	}
       
  1892 
       
  1893 
       
  1894 static const TInt KPrologue = 0;
       
  1895 static const TInt KMain     = 1;
       
  1896 static const TInt KEpilogue = 2;
       
  1897 
       
  1898 static TInt RunTests(void* /*aArg*/)
       
  1899 	{
       
  1900 	static TInt step = KPrologue;
       
  1901 	static TReal loops = 0;
       
  1902 
       
  1903 	switch (step)
       
  1904 		{
       
  1905 	case KPrologue:
       
  1906 		test.Title();
       
  1907 		// outermost test begin
       
  1908 		test.Start(_L("Test of USB APIs not requiring a host connection\n"));
       
  1909 		if (SupportsUsb())
       
  1910 			{
       
  1911 			step = KMain;
       
  1912 			}
       
  1913 		else
       
  1914 			{
       
  1915 			step = KEpilogue;
       
  1916 			test.Printf(_L("*** Test platform does not support USB - skipping all tests\n"));
       
  1917 			}
       
  1918 		return ETrue;
       
  1919 	case KMain:
       
  1920 		OpenChannel();
       
  1921 		SetupInterface();
       
  1922 		TestDescriptorManipulation();
       
  1923 		TestOtgExtensions();
       
  1924 		TestEndpoint0MaxPacketSizes();
       
  1925 		TestDeviceControl();
       
  1926 		TestAlternateDeviceStatusNotify();
       
  1927 		TestEndpointStatusNotify();
       
  1928 		TestEndpointStallStatus();
       
  1929 		CloseChannel();
       
  1930 		loops++;
       
  1931 		if (gSoak && (gKeychar != EKeyEscape))
       
  1932 			{
       
  1933 			step = KMain;
       
  1934 			}
       
  1935 		else
       
  1936 			{
       
  1937 			step = KEpilogue;
       
  1938 			}
       
  1939 		return ETrue;
       
  1940 	case KEpilogue:
       
  1941 		test.Printf(_L("USBAPI tests were run %.0f time(s)\n"), loops);
       
  1942 		// outermost test end
       
  1943 		test.End();
       
  1944 		CActiveScheduler::Stop();
       
  1945 		return EFalse;
       
  1946 		}
       
  1947 	return EFalse;
       
  1948 	}
       
  1949 
       
  1950 
       
  1951 static void RunAppL()
       
  1952 	{
       
  1953 	// Create the active scheduler
       
  1954 	CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
       
  1955 	// Push active scheduler onto the cleanup stack
       
  1956 	CleanupStack::PushL(scheduler);
       
  1957 	// Install as the active scheduler
       
  1958 	CActiveScheduler::Install(scheduler);
       
  1959 
       
  1960 	// Create console handler
       
  1961 	CConsoleBase* console =
       
  1962 		Console::NewL(_L("T_USBAPI - USB Client Test Program"), TSize(KConsFullScreen, KConsFullScreen));
       
  1963 	CleanupStack::PushL(console);
       
  1964 	// Make this one also RTest's console
       
  1965 	test.SetConsole(console);
       
  1966 
       
  1967 	// Create keypress notifier active object
       
  1968 	CActiveKeypressNotifier* keypress_notifier = CActiveKeypressNotifier::NewL(console);
       
  1969 	test(keypress_notifier != NULL);
       
  1970 	CleanupStack::PushL(keypress_notifier);
       
  1971 	keypress_notifier->RequestCharacter();
       
  1972 
       
  1973 	// Create long-running test task active object
       
  1974 	CIdle* active_test = CIdle::NewL(CActive::EPriorityIdle);
       
  1975 	test(active_test != NULL);
       
  1976 	CleanupStack::PushL(active_test);
       
  1977 	active_test->Start(TCallBack(RunTests));
       
  1978 
       
  1979 	// Start active scheduler
       
  1980 	CActiveScheduler::Start();
       
  1981 
       
  1982 	// Suspend thread for a short while
       
  1983 	User::After(1000000);
       
  1984 
       
  1985 	// active_test, keypress_notifier, console, scheduler
       
  1986 	CleanupStack::PopAndDestroy(4);
       
  1987 
       
  1988 	return;
       
  1989 	}
       
  1990 
       
  1991 
       
  1992 GLDEF_C TInt E32Main()
       
  1993 	{
       
  1994 
       
  1995 	CTrapCleanup* cleanup = CTrapCleanup::New();			// get clean-up stack
       
  1996 
       
  1997 	__UHEAP_MARK;
       
  1998 
       
  1999 	_LIT(KArg, "soak");
       
  2000 	TBuf<64> c;
       
  2001 	User::CommandLine(c);
       
  2002 	if (c.CompareF(KArg) == 0)
       
  2003 		gSoak = ETrue;
       
  2004 	else
       
  2005 		gSoak = EFalse;
       
  2006 	TRAPD(r, RunAppL());
       
  2007 	__ASSERT_ALWAYS(!r, User::Panic(_L("E32EX"), r));
       
  2008 
       
  2009 	__UHEAP_MARKEND;
       
  2010 
       
  2011 	delete cleanup;											// destroy clean-up stack
       
  2012 	return KErrNone;
       
  2013 	}