os/kernelhwsrv/kerneltest/e32test/device/t_usbapi.cpp
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     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 	}