os/kernelhwsrv/kerneltest/e32test/device/t_usbapi.cpp
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/kernelhwsrv/kerneltest/e32test/device/t_usbapi.cpp	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,2013 @@
     1.4 +// Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of the License "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// e32test/device/t_usbapi.cpp
    1.18 +// Overview:
    1.19 +// USB API Test Program (a standalone USB test program).
    1.20 +// API Information:
    1.21 +// Details:
    1.22 +// - Query whether the platform is operating HS (or it is connected to a HS host) or not,
    1.23 +// and executes the appropiate tests in each case (see RunTests() for the actual code,
    1.24 +// state machine enclosed for clarity):
    1.25 +// - Load and open an EUSBC device driver (logical device)
    1.26 +// - Setup the USB interface: query device capabilities, setup interface.
    1.27 +// - Test allocating DMA and double buffering resources with
    1.28 +// AllocateEndpointResource results in their use being correctly reported by
    1.29 +// QueryEndpointResourceUse
    1.30 +// - Test descriptor manipulation: validate the device, configuration,
    1.31 +// interface, alternate interface, endpoint and string descriptor
    1.32 +// manipulation.
    1.33 +// HS: device_qualifier and other_speed_configuation descriptors.
    1.34 +// - Check and validate the EndpointZeroMaxPacketSizes.
    1.35 +// - Quick test that calling the following APIs doesn't generate errors: device
    1.36 +// control, AlternateDeviceStatusNotify, EndpointStatusNotify
    1.37 +// - Test HaltEndpoint and ClearHaltEndpoint correctly result in endpoint
    1.38 +// status being reported as stalled/not stalled.
    1.39 +// - Test OTG extensions: OTG descriptor manipulations; set/get OTG feature
    1.40 +// - Close and free the logical device.
    1.41 +// Platforms/Drives/Compatibility:
    1.42 +// All.
    1.43 +// Assumptions/Requirement/Pre-requisites:
    1.44 +// Failures and causes:
    1.45 +// Base Port information:
    1.46 +// 
    1.47 +//
    1.48 +
    1.49 +
    1.50 +#include <e32test.h>
    1.51 +#include <e32debug.h>
    1.52 +#include <hal.h>
    1.53 +#include <d32usbc.h>
    1.54 +#include <d32otgdi.h>
    1.55 +
    1.56 +#include "t_usblib.h"
    1.57 +
    1.58 +
    1.59 +// --- Local Top Level Variables
    1.60 +
    1.61 +static RTest test(_L("T_USBAPI"));
    1.62 +static RDevUsbcClient gPort;
    1.63 +static RUsbOtgDriver gOTG;
    1.64 +static TBool gSupportsOtg;
    1.65 +static TBool gSupportsHighSpeed;
    1.66 +static TBool gUsingHighSpeed;
    1.67 +static TBool gSoak;
    1.68 +static TChar gKeychar = 'a';
    1.69 +
    1.70 +// Store the actual endpoint number(s) of our alternate interface
    1.71 +static TInt INT_IN_ep = -1;
    1.72 +
    1.73 +_LIT(KUsbLddFilename, "eusbc");
    1.74 +_LIT(KOtgdiLddFilename, "otgdi");
    1.75 +_LIT(KUsbDeviceName, "Usbc");
    1.76 +
    1.77 +
    1.78 +// --- Local Constants
    1.79 +
    1.80 +static const TInt KUsbDesc_SizeOffset = 0;
    1.81 +static const TInt KUsbDesc_TypeOffset = 1;
    1.82 +
    1.83 +static const TInt KDevDesc_SpecOffset = 2;
    1.84 +static const TInt KDevDesc_DevClassOffset = 4;
    1.85 +static const TInt KDevDesc_DevSubClassOffset = 5;
    1.86 +static const TInt KDevDesc_DevProtocolOffset = 6;
    1.87 +static const TInt KDevDesc_Ep0SizeOffset = 7;
    1.88 +static const TInt KDevDesc_VendorIdOffset = 8;
    1.89 +static const TInt KDevDesc_ProductIdOffset = 10;
    1.90 +static const TInt KDevDesc_DevReleaseOffset = 12;
    1.91 +
    1.92 +static const TInt KConfDesc_AttribOffset = 7;
    1.93 +static const TInt KConfDesc_MaxPowerOffset = 8;
    1.94 +
    1.95 +static const TInt KIfcDesc_SettingOffset = 2;
    1.96 +static const TInt KIfcDesc_ProtocolOffset = 7;
    1.97 +
    1.98 +static const TInt KEpDesc_PacketSizeOffset = 4;
    1.99 +static const TInt KEpDesc_IntervalOffset = 6;
   1.100 +static const TInt KEpDesc_SynchAddressOffset = 8;
   1.101 +
   1.102 +
   1.103 +//
   1.104 +// Helper.
   1.105 +//
   1.106 +static TEndpointState QueryEndpointState(TEndpointNumber aEndpoint)
   1.107 +	{
   1.108 +	TEndpointState ep_state = EEndpointStateUnknown;
   1.109 +	TInt r = gPort.EndpointStatus(aEndpoint, ep_state);
   1.110 +	test(r == KErrNone);
   1.111 +	test.Printf(_L("Endpoint %d state: %s\n"), aEndpoint,
   1.112 +				(ep_state == EEndpointStateNotStalled) ? _S("Not stalled") :
   1.113 +				((ep_state == EEndpointStateStalled) ? _S("Stalled") :
   1.114 +				 _S("Unknown...")));
   1.115 +	return ep_state;
   1.116 +	}
   1.117 +
   1.118 +
   1.119 +// --- Class CActiveKeypressNotifier
   1.120 +
   1.121 +class CActiveKeypressNotifier : public CActive
   1.122 +	{
   1.123 +public:
   1.124 +	static CActiveKeypressNotifier* NewL(CConsoleBase* aConsole);
   1.125 +	~CActiveKeypressNotifier();
   1.126 +	void RequestCharacter();
   1.127 +	void ProcessKeyPressL(TChar aChar);
   1.128 +private:
   1.129 +	virtual void DoCancel();
   1.130 +	virtual void RunL();
   1.131 +	CActiveKeypressNotifier(CConsoleBase* aConsole);
   1.132 +	void ConstructL() {};
   1.133 +private:
   1.134 +	CConsoleBase* iConsole;
   1.135 +	};
   1.136 +
   1.137 +
   1.138 +CActiveKeypressNotifier* CActiveKeypressNotifier::NewL(CConsoleBase* aConsole)
   1.139 +	{
   1.140 +	CActiveKeypressNotifier* self = new (ELeave) CActiveKeypressNotifier(aConsole);
   1.141 +	CleanupStack::PushL(self);
   1.142 +	self->ConstructL();
   1.143 +	CActiveScheduler::Add(self);
   1.144 +	CleanupStack::Pop();
   1.145 +	return self;
   1.146 +	}
   1.147 +
   1.148 +
   1.149 +CActiveKeypressNotifier::CActiveKeypressNotifier(CConsoleBase* aConsole)
   1.150 +	: CActive(EPriorityNormal), iConsole(aConsole)
   1.151 +	{}
   1.152 +
   1.153 +
   1.154 +CActiveKeypressNotifier::~CActiveKeypressNotifier()
   1.155 +	{
   1.156 +	Cancel();												// base class cancel -> calls our DoCancel
   1.157 +	}
   1.158 +
   1.159 +
   1.160 +void CActiveKeypressNotifier::RunL()
   1.161 +	{
   1.162 +	gKeychar = (static_cast<TChar>(iConsole->KeyCode()));
   1.163 +	RequestCharacter();
   1.164 +	}
   1.165 +
   1.166 +
   1.167 +void CActiveKeypressNotifier::DoCancel()
   1.168 +	{
   1.169 +	iConsole->ReadCancel();
   1.170 +	}
   1.171 +
   1.172 +
   1.173 +void CActiveKeypressNotifier::RequestCharacter()
   1.174 +	{
   1.175 +	// A request is issued to the CConsoleBase to accept a character from the keyboard.
   1.176 +	if (IsActive())
   1.177 +		{
   1.178 +		return;
   1.179 +		}
   1.180 +	iConsole->Read(iStatus);
   1.181 +	SetActive();
   1.182 +	}
   1.183 +
   1.184 +
   1.185 +// --- Actual Test Functions
   1.186 +
   1.187 +// 2nd Thread helper function
   1.188 +static TInt TestThreadFunction(TAny* aPtr)
   1.189 +	{
   1.190 +	RThread* other = static_cast<RThread*>(aPtr);
   1.191 +	RDevUsbcClient port = gPort;
   1.192 +	// Now try to duplicate the USB channel handle
   1.193 +	TInt r = port.Duplicate(*other);
   1.194 + 	// Wait for 1 second
   1.195 + 	User::After(1000000);
   1.196 +	return r;
   1.197 +	}
   1.198 +
   1.199 +
   1.200 +static void OpenChannel()
   1.201 +	{
   1.202 +	test.Start(_L("Open Channel"));
   1.203 +
   1.204 +	test.Next(_L("Load USB LDD"));
   1.205 +	TInt r = User::LoadLogicalDevice(KUsbLddFilename);
   1.206 +	test(r == KErrNone || r == KErrAlreadyExists);
   1.207 +
   1.208 +	RDevUsbcClient port1;
   1.209 +	test.Next(_L("Open local USB channel 1"));
   1.210 +	r = port1.Open(0);
   1.211 +	test(r == KErrNone);
   1.212 +
   1.213 +	test.Next(_L("Open global USB channel"));
   1.214 +	r = gPort.Open(0);
   1.215 +	test(r == KErrNone);
   1.216 +
   1.217 +	RDevUsbcClient port2;
   1.218 +	test.Next(_L("Open local USB channel 2"));
   1.219 +	r = port2.Open(0);
   1.220 +	test(r == KErrNone);
   1.221 +
   1.222 +	test.Next(_L("Close USB channel 1"));
   1.223 +	port1.Close();
   1.224 +
   1.225 +	RDevUsbcClient port3;
   1.226 +	test.Next(_L("Open local USB channel 3"));
   1.227 +	r = port3.Open(0);
   1.228 +	test(r == KErrNone);
   1.229 +
   1.230 +	test.Next(_L("Close USB channel 2"));
   1.231 +	port2.Close();
   1.232 +
   1.233 +	test.Next(_L("Close USB channel 3"));
   1.234 +	port3.Close();
   1.235 +
   1.236 +	// Check for OTG support
   1.237 +	TBuf8<KUsbDescSize_Otg> otg_desc;
   1.238 +	r = gPort.GetOtgDescriptor(otg_desc);
   1.239 +	test(r == KErrNotSupported || r == KErrNone);
   1.240 +	gSupportsOtg = (r != KErrNotSupported) ? ETrue : EFalse;
   1.241 +
   1.242 +	// On an OTG device we have to start the OTG driver, otherwise the Client
   1.243 +	// stack will remain disabled forever.
   1.244 +	if (gSupportsOtg)
   1.245 +		{
   1.246 +		test.Printf(_L("Running on OTG device: loading OTG driver\n"));
   1.247 +		test.Next(_L("Load OTG LDD"));
   1.248 +		r = User::LoadLogicalDevice(KOtgdiLddFilename);
   1.249 +		test((r == KErrNone) || (r == KErrAlreadyExists));
   1.250 +
   1.251 +		test.Next(_L("Open OTG channel"));
   1.252 +		r = gOTG.Open();
   1.253 +		test(r == KErrNone);
   1.254 +
   1.255 +		test.Next(_L("Start OTG stack"));
   1.256 +		r = gOTG.StartStacks();
   1.257 +		test(r == KErrNone);
   1.258 +		}
   1.259 +
   1.260 +	// Try duplicating channel handle in a second thread
   1.261 +	// (which should not work because we don't support it)
   1.262 +
   1.263 +	test.Next(_L("Create 2nd Thread"));
   1.264 +	RThread me;
   1.265 + 	TThreadId me_id = me.Id();
   1.266 +	// We need to open the RThread object, otherwise we'll only get the
   1.267 +	// 'special' handle 0xFFFF8001.
   1.268 +	test(me.Open(me_id) == KErrNone);
   1.269 +	RThread test_thread;
   1.270 +	TBuf<17> name = _L("tusbapitestthread");
   1.271 +	test(test_thread.Create(name, TestThreadFunction, 0x1000, NULL, &me) == KErrNone);
   1.272 +	test.Next(_L("Logon to 2nd Thread"));
   1.273 +	TRequestStatus stat;
   1.274 +	test_thread.Logon(stat);
   1.275 +	test(stat == KRequestPending);
   1.276 +	test_thread.Resume();
   1.277 +	test.Next(_L("Wait for 2nd Thread to exit"));
   1.278 +	User::WaitForRequest(stat);
   1.279 +	// Check correct return value of RDevUsbcClient::Duplicate()
   1.280 +	test(stat == KErrAccessDenied);
   1.281 +	test.Next(_L("Close 2nd Thread"));
   1.282 +	test_thread.Close();
   1.283 +
   1.284 +	test.End();
   1.285 +	}
   1.286 +
   1.287 +
   1.288 +static void TestResourceAllocation()
   1.289 +	{
   1.290 +	test.Start(_L("Test Endpoint Resource Allocation"));
   1.291 +
   1.292 +	test.Next(_L("Request DMA resource"));
   1.293 +	const TInt dma = gPort.AllocateEndpointResource(EEndpoint1, EUsbcEndpointResourceDMA);
   1.294 +	TBool res = gPort.QueryEndpointResourceUse(EEndpoint1, EUsbcEndpointResourceDMA);
   1.295 +	test.Printf(_L("DMA on endpoint 1 %s\n"),
   1.296 +				res ? _S("now allocated") : _S("not allocated"));
   1.297 +	if (dma == KErrNone)
   1.298 +		// Only if DMA resource was successfully allocated should we expect truth here:
   1.299 +		test(res);
   1.300 +	else
   1.301 +		test(!res);
   1.302 +
   1.303 +	test.Next(_L("Request Double Buffering resource"));
   1.304 +	const TInt db = gPort.AllocateEndpointResource(EEndpoint1, EUsbcEndpointResourceDoubleBuffering);
   1.305 +	res = gPort.QueryEndpointResourceUse(EEndpoint1, EUsbcEndpointResourceDoubleBuffering);
   1.306 +	test.Printf(_L("Double Buffering on endpoint 1 %s\n"),
   1.307 +				res ? _S("now allocated") : _S("not allocated"));
   1.308 +	if (db == KErrNone)
   1.309 +		// Only if DB resource was successfully allocated should we expect truth here:
   1.310 +		test(res);
   1.311 +	else
   1.312 +		test(!res);
   1.313 +
   1.314 +	test.Next(_L("Deallocate Double Buffering resource"));
   1.315 +	TInt r = gPort.DeAllocateEndpointResource(EEndpoint1, EUsbcEndpointResourceDoubleBuffering);
   1.316 +	// Whether DB is dynamic or permanent - deallocation (if supported) should always return success:
   1.317 +	if (db == KErrNone)
   1.318 +		test(r == KErrNone);
   1.319 +	else
   1.320 +		test(r != KErrNone);
   1.321 +	res = gPort.QueryEndpointResourceUse(EEndpoint1, EUsbcEndpointResourceDoubleBuffering);
   1.322 +	test.Printf(_L("Double Buffering on endpoint 1 %s\n"),
   1.323 +				res ? _S("still allocated") : _S("not (longer) allocated"));
   1.324 +
   1.325 +	test.Next(_L("Deallocate DMA resource"));
   1.326 +	r = gPort.DeAllocateEndpointResource(EEndpoint1, EUsbcEndpointResourceDMA);
   1.327 +	// Whether DMA is dynamic or permanent - deallocation (if supported) should always return success:
   1.328 +	if (dma == KErrNone)
   1.329 +		test(r == KErrNone);
   1.330 +	else
   1.331 +		test(r != KErrNone);
   1.332 +	res = gPort.QueryEndpointResourceUse(EEndpoint1, EUsbcEndpointResourceDMA);
   1.333 +	test.Printf(_L("DMA on endpoint 1 %s\n"),
   1.334 +				res ? _S("still allocated") : _S("not (longer) allocated"));
   1.335 +
   1.336 +	test.End();
   1.337 +	}
   1.338 +
   1.339 +
   1.340 +static void SetupInterface()
   1.341 +	{
   1.342 +	test.Start(_L("Query USB device caps and set up interface"));
   1.343 +
   1.344 +	// Device caps
   1.345 +	test.Next(_L("Query USB device caps"));
   1.346 +	TUsbDeviceCaps d_caps;
   1.347 +	TInt r = gPort.DeviceCaps(d_caps);
   1.348 +	test(r == KErrNone);
   1.349 +	TInt n = d_caps().iTotalEndpoints;
   1.350 +
   1.351 +	// Global variable - we'll need this value later
   1.352 +	gSupportsHighSpeed = d_caps().iHighSpeed;
   1.353 +
   1.354 +	test.Printf(_L("### USB device capabilities:\n"));
   1.355 +	test.Printf(_L("Number of endpoints:                        %d\n"), n);
   1.356 +	test.Printf(_L("Supports Software-Connect:                  %s\n"),
   1.357 +				d_caps().iConnect ? _S("yes") : _S("no"));
   1.358 +	test.Printf(_L("Device is Self-Powered:                     %s\n"),
   1.359 +				d_caps().iSelfPowered ? _S("yes") : _S("no"));
   1.360 +	test.Printf(_L("Supports Remote-Wakeup:                     %s\n"),
   1.361 +				d_caps().iRemoteWakeup ? _S("yes") : _S("no"));
   1.362 +	test.Printf(_L("Supports High-speed:                        %s\n"),
   1.363 +				gSupportsHighSpeed ? _S("yes") : _S("no"));
   1.364 +	test.Printf(_L("Supports OTG:                               %s\n"),
   1.365 +				gSupportsOtg ? _S("yes") : _S("no"));
   1.366 +	test.Printf(_L("Supports unpowered cable detection:         %s\n"),
   1.367 +				(d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_CableDetectWithoutPower) ?
   1.368 +				_S("yes") : _S("no"));
   1.369 +	test.Printf(_L("Supports endpoint resource alloc scheme V2: %s\n"),
   1.370 +				(d_caps().iFeatureWord1 & KUsbDevCapsFeatureWord1_EndpointResourceAllocV2) ?
   1.371 +				_S("yes") : _S("no"));
   1.372 +
   1.373 +	test(n >= 2);
   1.374 +	test.Printf(_L("(Device has sufficient endpoints.)\n"));
   1.375 +
   1.376 +	// Endpoint caps
   1.377 +	test.Next(_L("Query USB endpoint caps"));
   1.378 +	TUsbcEndpointData data[KUsbcMaxEndpoints];
   1.379 +	TPtr8 dataptr(reinterpret_cast<TUint8*>(data), sizeof(data), sizeof(data));
   1.380 +	r = gPort.EndpointCaps(dataptr);
   1.381 +	test(r == KErrNone);
   1.382 +
   1.383 +	test.Printf(_L("### USB device endpoint capabilities:\n"));
   1.384 +	for (TInt i = 0; i < n; i++)
   1.385 +		{
   1.386 +		const TUsbcEndpointCaps* caps = &data[i].iCaps;
   1.387 +		test.Printf(_L("Endpoint: SizeMask = 0x%08x TypeDirMask = 0x%08x\n"),
   1.388 +					caps->iSizes, caps->iTypesAndDir);
   1.389 +		if (caps->iHighBandwidth)
   1.390 +			{
   1.391 +			test.Printf(_L("  (high-speed, high bandwidth endpoint)\n"));
   1.392 +			// Must be HS Int or Iso ep
   1.393 +			test(gSupportsHighSpeed);
   1.394 +			test(caps->iTypesAndDir & (KUsbEpTypeIsochronous | KUsbEpTypeInterrupt));
   1.395 +			}
   1.396 +		}
   1.397 +
   1.398 +	test.Next(_L("Looking for suitable endpoints"));
   1.399 +	// Set the active interface
   1.400 +	TUsbcInterfaceInfoBuf ifc;
   1.401 +	TInt ep_found = 0;
   1.402 +	TBool foundBulkIN = EFalse;
   1.403 +	TBool foundBulkOUT = EFalse;
   1.404 +	for (TInt i = 0; i < n; i++)
   1.405 +		{
   1.406 +		const TUsbcEndpointCaps* caps = &data[i].iCaps;
   1.407 +		const TInt mps = caps->MaxPacketSize();
   1.408 +		if (!foundBulkIN &&
   1.409 +			(caps->iTypesAndDir & (KUsbEpTypeBulk | KUsbEpDirIn)) ==
   1.410 +			(KUsbEpTypeBulk | KUsbEpDirIn))
   1.411 +			{
   1.412 +			// EEndpoint1 is going to be our TX (IN, write) endpoint
   1.413 +			ifc().iEndpointData[0].iType = KUsbEpTypeBulk;
   1.414 +			ifc().iEndpointData[0].iDir  = KUsbEpDirIn;
   1.415 +			ifc().iEndpointData[0].iSize = mps;
   1.416 +			foundBulkIN = ETrue;
   1.417 +			if (++ep_found == 2)
   1.418 +				break;
   1.419 +			}
   1.420 +		else if (!foundBulkOUT &&
   1.421 +			(caps->iTypesAndDir & (KUsbEpTypeBulk | KUsbEpDirOut)) ==
   1.422 +				 (KUsbEpTypeBulk | KUsbEpDirOut))
   1.423 +			{
   1.424 +			// EEndpoint2 is going to be our RX (OUT, read) endpoint
   1.425 +			ifc().iEndpointData[1].iType = KUsbEpTypeBulk;
   1.426 +			ifc().iEndpointData[1].iDir  = KUsbEpDirOut;
   1.427 +			ifc().iEndpointData[1].iSize = mps;
   1.428 +			foundBulkOUT = ETrue;
   1.429 +			if (++ep_found == 2)
   1.430 +				break;
   1.431 +			}
   1.432 +		}
   1.433 +	test(ep_found == 2);
   1.434 +
   1.435 +	test.Next(_L("Setting up main interface"));
   1.436 +	_LIT16(string, "T_USBAPI Test Interface (Setting 0)");
   1.437 +	ifc().iString = const_cast<TDesC16*>(&string);
   1.438 +	ifc().iTotalEndpointsUsed = 2;
   1.439 +	ifc().iClass.iClassNum	  = 0xff;
   1.440 +	ifc().iClass.iSubClassNum = 0xff;
   1.441 +	ifc().iClass.iProtocolNum = 0xff;
   1.442 +	// Set up the interface.
   1.443 +	r = gPort.SetInterface(0, ifc);
   1.444 +	test(r == KErrNone);
   1.445 +
   1.446 +	TInt ifc_no = -1;
   1.447 +	r = gPort.GetAlternateSetting(ifc_no);
   1.448 +	test(r == KErrUsbDeviceNotConfigured);
   1.449 +
   1.450 +	// Some UDCs won't allow endpoint resource manipulation once the hardware has been
   1.451 +	// configured and turned on. So we do it here & now:
   1.452 +	TestResourceAllocation();
   1.453 +
   1.454 +	// On the other hand, since some UDCs won't let us test many features which require
   1.455 +	// register access until the USB hardware is powered up (and because it might start
   1.456 +	// out unpowered), we should turn it on here explicitly.
   1.457 +	// (It will be turned off automatically by the PIL after all tests have been run,
   1.458 +	// when the interface gets deleted.)
   1.459 +	test.Next(_L("Powering up UDC (1)"));
   1.460 +	r = gPort.PowerUpUdc();
   1.461 +	if (!gSupportsOtg)
   1.462 +		{
   1.463 +		test(r == KErrNone);
   1.464 +		}
   1.465 +	else
   1.466 +		{
   1.467 +		test((r == KErrNone) || (r == KErrNotReady));
   1.468 +		}
   1.469 +	if (gSupportsOtg && (r == KErrNotReady))
   1.470 +		{
   1.471 +		test.Printf(_L("OTG device but not connected to Host, stopping subtest here.\n"));
   1.472 +		test.End();
   1.473 +		return;
   1.474 +		}
   1.475 +	// The board might be attached to a PC with HS controller, thus enabling us
   1.476 +	// to test some HS-specific features. For that to work we have to connect
   1.477 +	// the board to the PC. The "Found new device" box that may pop up on the PC
   1.478 +	// in response to this can be ignored (i.e. just closed).
   1.479 +	test.Next(_L("Connecting to Host (1)"));
   1.480 +	r = gPort.DeviceConnectToHost();
   1.481 +	test(r == KErrNone);
   1.482 + 	// Suspend thread to let things get stable on the bus.
   1.483 +	test.Printf(_L("Waiting a short moment..."));
   1.484 +	User::After(2000000);
   1.485 +	test.Printf(_L(" done.\n"));
   1.486 +
   1.487 +	// Check the speed of the physical connection (if any).
   1.488 +	gUsingHighSpeed = gPort.CurrentlyUsingHighSpeed();
   1.489 +	if (gUsingHighSpeed)
   1.490 +		{
   1.491 +		test(gSupportsHighSpeed);							// sane?
   1.492 +		test.Printf(_L("---> USB High-speed Testing\n"));
   1.493 +		}
   1.494 +	else
   1.495 +		{
   1.496 +		test.Printf(_L("---> USB Full-speed Testing\n"));
   1.497 +		}
   1.498 +
   1.499 +	// By pulling down the interface/connection and bringing them up again we
   1.500 +	// simulate a starting/stopping of the USB service by a control app.
   1.501 +
   1.502 +	test.Next(_L("Disconnecting from Host"));
   1.503 +	r = gPort.DeviceDisconnectFromHost();
   1.504 +	test(r == KErrNone);
   1.505 +
   1.506 +	test.Next(_L("Releasing interface"));
   1.507 +	r = gPort.ReleaseInterface(0);
   1.508 +	test(r == KErrNone);
   1.509 +
   1.510 +	test.Next(_L("Setting interface"));
   1.511 +	r = gPort.SetInterface(0, ifc);
   1.512 +	test(r == KErrNone);
   1.513 +
   1.514 + 	// Suspend thread before connecting again.
   1.515 +	test.Printf(_L("Waiting a short moment..."));
   1.516 +	User::After(1000000);
   1.517 +	test.Printf(_L(" done.\n"));
   1.518 +
   1.519 +	test.Next(_L("Powering up UDC (2)"));
   1.520 +	r = gPort.PowerUpUdc();
   1.521 +	if (!gSupportsOtg)
   1.522 +		{
   1.523 +		test(r == KErrNone);
   1.524 +		}
   1.525 +	else
   1.526 +		{
   1.527 +		test((r == KErrNone) || (r == KErrNotReady));
   1.528 +		}
   1.529 +	if (gSupportsOtg && (r == KErrNotReady))
   1.530 +		{
   1.531 +		test.Printf(_L("OTG device but not connected to Host, stopping subtest here.\n"));
   1.532 +		test.End();
   1.533 +		return;
   1.534 +		}
   1.535 +
   1.536 +	test.Next(_L("Connecting to Host (2)"));
   1.537 +	r = gPort.DeviceConnectToHost();
   1.538 +	test(r == KErrNone);
   1.539 +	// Suspend thread to let things get stable on the bus.
   1.540 +	User::After(2000000);
   1.541 +
   1.542 +	test.End();
   1.543 +	}
   1.544 +
   1.545 +
   1.546 +static void TestDeviceDescriptor()
   1.547 +	{
   1.548 +	test.Start(_L("Device Descriptor Manipulation"));
   1.549 +
   1.550 +	test.Next(_L("GetDeviceDescriptorSize()"));
   1.551 +	TInt desc_size = 0;
   1.552 +	gPort.GetDeviceDescriptorSize(desc_size);
   1.553 +	test(static_cast<TUint>(desc_size) == KUsbDescSize_Device);
   1.554 +
   1.555 +	test.Next(_L("GetDeviceDescriptor()"));
   1.556 +	TBuf8<KUsbDescSize_Device> descriptor;
   1.557 +	TInt r = gPort.GetDeviceDescriptor(descriptor);
   1.558 +	test(r == KErrNone);
   1.559 +
   1.560 +	test.Next(_L("SetDeviceDescriptor()"));
   1.561 +	// Change the USB spec number to 2.30
   1.562 +	descriptor[KDevDesc_SpecOffset]   = 0x30;
   1.563 +	descriptor[KDevDesc_SpecOffset+1] = 0x02;
   1.564 +	// Change the device vendor ID (VID) to 0x1234
   1.565 +	descriptor[KDevDesc_VendorIdOffset]   = 0x34;			// little endian
   1.566 +	descriptor[KDevDesc_VendorIdOffset+1] = 0x12;
   1.567 +	// Change the device product ID (PID) to 0x1111
   1.568 +	descriptor[KDevDesc_ProductIdOffset]   = 0x11;
   1.569 +	descriptor[KDevDesc_ProductIdOffset+1] = 0x11;
   1.570 +	// Change the device release number to 3.05
   1.571 +	descriptor[KDevDesc_DevReleaseOffset]   = 0x05;
   1.572 +	descriptor[KDevDesc_DevReleaseOffset+1] = 0x03;
   1.573 +	r = gPort.SetDeviceDescriptor(descriptor);
   1.574 +	test(r == KErrNone);
   1.575 +
   1.576 +	test.Next(_L("GetDeviceDescriptor()"));
   1.577 +	TBuf8<KUsbDescSize_Device> descriptor2;
   1.578 +	r = gPort.GetDeviceDescriptor(descriptor2);
   1.579 +	test(r == KErrNone);
   1.580 +
   1.581 +	test.Next(_L("Compare device descriptor with value set"));
   1.582 +	r = descriptor2.Compare(descriptor);
   1.583 +	test(r == KErrNone);
   1.584 +
   1.585 +	if (gUsingHighSpeed)
   1.586 +		{
   1.587 +		// HS only allows one possible packet size.
   1.588 +		test(descriptor[KDevDesc_Ep0SizeOffset] == 64);
   1.589 +		}
   1.590 +
   1.591 +	test.End();
   1.592 +	}
   1.593 +
   1.594 +
   1.595 +static void	TestDeviceQualifierDescriptor()
   1.596 +	{
   1.597 +	test.Start(_L("Device_Qualifier Descriptor Manipulation"));
   1.598 +
   1.599 +	if (!gSupportsHighSpeed)
   1.600 +		{
   1.601 +		test.Printf(_L("*** Not supported - skipping Device_Qualifier descriptor tests\n"));
   1.602 +		test.End();
   1.603 +		return;
   1.604 +		}
   1.605 +
   1.606 +	test.Next(_L("GetDeviceQualifierDescriptor()"));
   1.607 +	TBuf8<KUsbDescSize_DeviceQualifier> descriptor;
   1.608 +	TInt r = gPort.GetDeviceQualifierDescriptor(descriptor);
   1.609 +	test(r == KErrNone);
   1.610 +
   1.611 +	test.Next(_L("SetDeviceQualifierDescriptor()"));
   1.612 +	// Change the USB spec number to 3.00
   1.613 +	descriptor[KDevDesc_SpecOffset]   = 0x00;
   1.614 +	descriptor[KDevDesc_SpecOffset+1] = 0x03;
   1.615 +	// Change the device class, subclass and protocol codes
   1.616 +	descriptor[KDevDesc_DevClassOffset]    = 0xA1;
   1.617 +	descriptor[KDevDesc_DevSubClassOffset] = 0xB2;
   1.618 +	descriptor[KDevDesc_DevProtocolOffset] = 0xC3;
   1.619 +	r = gPort.SetDeviceQualifierDescriptor(descriptor);
   1.620 +	test(r == KErrNone);
   1.621 +
   1.622 +	test.Next(_L("GetDeviceQualifierDescriptor()"));
   1.623 +	TBuf8<KUsbDescSize_DeviceQualifier> descriptor2;
   1.624 +	r = gPort.GetDeviceQualifierDescriptor(descriptor2);
   1.625 +	test(r == KErrNone);
   1.626 +
   1.627 +	test.Next(_L("Compare Device_Qualifier desc with value set"));
   1.628 +	r = descriptor2.Compare(descriptor);
   1.629 +	test(r == 0);
   1.630 +
   1.631 +	if (!gUsingHighSpeed)
   1.632 +		{
   1.633 +		// HS only allows one possible packet size.
   1.634 +		test(descriptor[KDevDesc_Ep0SizeOffset] == 64);
   1.635 +		}
   1.636 +
   1.637 +	test.End();
   1.638 +	}
   1.639 +
   1.640 +
   1.641 +static void TestConfigurationDescriptor()
   1.642 +	{
   1.643 +	test.Start(_L("Configuration Descriptor Manipulation"));
   1.644 +
   1.645 +	test.Next(_L("GetConfigurationDescriptorSize()"));
   1.646 +	TInt desc_size = 0;
   1.647 +	gPort.GetConfigurationDescriptorSize(desc_size);
   1.648 +	test(static_cast<TUint>(desc_size) == KUsbDescSize_Config);
   1.649 +
   1.650 +	test.Next(_L("GetConfigurationDescriptor()"));
   1.651 +	TBuf8<KUsbDescSize_Config> descriptor;
   1.652 +	TInt r = gPort.GetConfigurationDescriptor(descriptor);
   1.653 +	test(r == KErrNone);
   1.654 +
   1.655 +	test.Next(_L("SetConfigurationDescriptor()"));
   1.656 +	// Invert Remote-Wakup support
   1.657 +	descriptor[KConfDesc_AttribOffset] = (descriptor[KConfDesc_AttribOffset] ^ KUsbDevAttr_RemoteWakeup);
   1.658 +	// Change the reported max power to 200mA (2 * 0x64)
   1.659 +	descriptor[KConfDesc_MaxPowerOffset] = 0x64;
   1.660 +	r = gPort.SetConfigurationDescriptor(descriptor);
   1.661 +	test(r == KErrNone);
   1.662 +
   1.663 +	test.Next(_L("GetConfigurationDescriptor()"));
   1.664 +	TBuf8<KUsbDescSize_Config> descriptor2;
   1.665 +	r = gPort.GetConfigurationDescriptor(descriptor2);
   1.666 +	test(r == KErrNone);
   1.667 +
   1.668 +	test.Next(_L("Compare configuration desc with value set"));
   1.669 +	r = descriptor2.Compare(descriptor);
   1.670 +	test(r == KErrNone);
   1.671 +
   1.672 +	test.End();
   1.673 +	}
   1.674 +
   1.675 +
   1.676 +static void	TestOtherSpeedConfigurationDescriptor()
   1.677 +	{
   1.678 +	test.Start(_L("Other_Speed_Configuration Desc Manipulation"));
   1.679 +
   1.680 +	if (!gSupportsHighSpeed)
   1.681 +		{
   1.682 +		test.Printf(_L("*** Not supported - skipping Other_Speed_Configuration desc tests\n"));
   1.683 +		test.End();
   1.684 +		return;
   1.685 +		}
   1.686 +
   1.687 +	test.Next(_L("GetOtherSpeedConfigurationDescriptor()"));
   1.688 +	TBuf8<KUsbDescSize_OtherSpeedConfig> descriptor;
   1.689 +	TInt r = gPort.GetOtherSpeedConfigurationDescriptor(descriptor);
   1.690 +	test(r == KErrNone);
   1.691 +
   1.692 +	test.Next(_L("SetOtherSpeedConfigurationDescriptor()"));
   1.693 +	// Invert Remote-Wakup support
   1.694 +	descriptor[KConfDesc_AttribOffset] = (descriptor[KConfDesc_AttribOffset] ^ KUsbDevAttr_RemoteWakeup);
   1.695 +	// Change the reported max power to 330mA (2 * 0xA5)
   1.696 +	descriptor[KConfDesc_MaxPowerOffset] = 0xA5;
   1.697 +	r = gPort.SetOtherSpeedConfigurationDescriptor(descriptor);
   1.698 +	test(r == KErrNone);
   1.699 +
   1.700 +	test.Next(_L("GetOtherSpeedConfigurationDescriptor()"));
   1.701 +	TBuf8<KUsbDescSize_OtherSpeedConfig> descriptor2;
   1.702 +	r = gPort.GetOtherSpeedConfigurationDescriptor(descriptor2);
   1.703 +	test(r == KErrNone);
   1.704 +
   1.705 +	test.Next(_L("Compare O_S_Config desc with value set"));
   1.706 +	r = descriptor2.Compare(descriptor);
   1.707 +	test(r == KErrNone);
   1.708 +
   1.709 +	test.End();
   1.710 +	}
   1.711 +
   1.712 +
   1.713 +static void TestInterfaceDescriptor()
   1.714 +	{
   1.715 +	test.Start(_L("Interface Descriptor Manipulation"));
   1.716 +
   1.717 +	// First the standard Interface descriptor
   1.718 +
   1.719 +	test.Next(_L("GetInterfaceDescriptorSize()"));
   1.720 +	TInt desc_size = 0;
   1.721 +	TInt r = gPort.GetInterfaceDescriptorSize(0, desc_size);
   1.722 +	test(r == KErrNone);
   1.723 +	test(static_cast<TUint>(desc_size) == KUsbDescSize_Interface);
   1.724 +
   1.725 +	test.Next(_L("GetInterfaceDescriptor()"));
   1.726 +	TBuf8<KUsbDescSize_Interface> descriptor;
   1.727 +	r = gPort.GetInterfaceDescriptor(0, descriptor);
   1.728 +	test(r == KErrNone);
   1.729 +
   1.730 +	test.Next(_L("SetInterfaceDescriptor()"));
   1.731 +	// Change the interface protocol to 0x78(+)
   1.732 +	TUint8 prot = 0x78;
   1.733 +	if (descriptor[KIfcDesc_ProtocolOffset] == prot)
   1.734 +		prot++;
   1.735 +	descriptor[KIfcDesc_ProtocolOffset] = prot;
   1.736 +	r = gPort.SetInterfaceDescriptor(0, descriptor);
   1.737 +	test(r == KErrNone);
   1.738 +
   1.739 +	test.Next(_L("GetInterfaceDescriptor()"));
   1.740 +	TBuf8<KUsbDescSize_Interface> descriptor2;
   1.741 +	r = gPort.GetInterfaceDescriptor(0, descriptor2);
   1.742 +	test(r == KErrNone);
   1.743 +
   1.744 +	test.Next(_L("Compare interface descriptor with value set"));
   1.745 +	r = descriptor2.Compare(descriptor);
   1.746 +	test(r == KErrNone);
   1.747 +
   1.748 +	test.End();
   1.749 +	}
   1.750 +
   1.751 +
   1.752 +static void TestClassSpecificDescriptors()
   1.753 +	{
   1.754 +	test.Start(_L("Class-specific Descriptor Manipulation"));
   1.755 +
   1.756 +	// First a class-specific Interface descriptor
   1.757 +
   1.758 +	test.Next(_L("SetCSInterfaceDescriptorBlock()"));
   1.759 +	// choose arbitrary new descriptor size
   1.760 +	const TInt KUsbDescSize_CS_Interface = KUsbDescSize_Interface + 10;
   1.761 +	TBuf8<KUsbDescSize_CS_Interface> cs_ifc_descriptor;
   1.762 +	cs_ifc_descriptor.FillZ(cs_ifc_descriptor.MaxLength());
   1.763 +	cs_ifc_descriptor[KUsbDesc_SizeOffset] = KUsbDescSize_CS_Interface;
   1.764 +	cs_ifc_descriptor[KUsbDesc_TypeOffset] = KUsbDescType_CS_Interface;
   1.765 +	TInt r = gPort.SetCSInterfaceDescriptorBlock(0, cs_ifc_descriptor);
   1.766 +	test(r == KErrNone);
   1.767 +
   1.768 +	test.Next(_L("GetCSInterfaceDescriptorBlockSize()"));
   1.769 +	TInt desc_size = 0;
   1.770 +	r = gPort.GetCSInterfaceDescriptorBlockSize(0, desc_size);
   1.771 +	test(r == KErrNone);
   1.772 +	test(desc_size == KUsbDescSize_CS_Interface);
   1.773 +
   1.774 +	test.Next(_L("GetCSInterfaceDescriptorBlock()"));
   1.775 +	TBuf8<KUsbDescSize_CS_Interface> descriptor;
   1.776 +	r = gPort.GetCSInterfaceDescriptorBlock(0, descriptor);
   1.777 +	test(r == KErrNone);
   1.778 +
   1.779 +	test.Next(_L("Compare CS ifc descriptor with value set"));
   1.780 +	r = descriptor.Compare(cs_ifc_descriptor);
   1.781 +	test(r == KErrNone);
   1.782 +
   1.783 +	// Next a class-specific Endpoint descriptor
   1.784 +
   1.785 +	test.Next(_L("SetCSEndpointDescriptorBlock()"));
   1.786 +	// choose arbitrary new descriptor size
   1.787 +	const TInt KUsbDescSize_CS_Endpoint = KUsbDescSize_Endpoint + 5;
   1.788 +	TBuf8<KUsbDescSize_CS_Endpoint> cs_ep_descriptor;
   1.789 +	cs_ep_descriptor.FillZ(cs_ep_descriptor.MaxLength());
   1.790 +	cs_ep_descriptor[KUsbDesc_SizeOffset] = KUsbDescSize_CS_Endpoint;
   1.791 +	cs_ep_descriptor[KUsbDesc_TypeOffset] = KUsbDescType_CS_Endpoint;
   1.792 +	r = gPort.SetCSEndpointDescriptorBlock(0, 2, cs_ep_descriptor);
   1.793 +	test(r == KErrNone);
   1.794 +
   1.795 +	test.Next(_L("GetCSEndpointDescriptorBlockSize()"));
   1.796 +	r = gPort.GetCSEndpointDescriptorBlockSize(0, 2, desc_size);
   1.797 +	test(r == KErrNone);
   1.798 +	test(desc_size == KUsbDescSize_CS_Endpoint);
   1.799 +
   1.800 +	test.Next(_L("GetCSEndpointDescriptorBlock()"));
   1.801 +	TBuf8<KUsbDescSize_CS_Endpoint> descriptor2;
   1.802 +	r = gPort.GetCSEndpointDescriptorBlock(0, 2, descriptor2);
   1.803 +	test(r == KErrNone);
   1.804 +
   1.805 +	test.Next(_L("Compare CS ep descriptor with value set"));
   1.806 +	r = descriptor2.Compare(cs_ep_descriptor);
   1.807 +	test(r == KErrNone);
   1.808 +
   1.809 +	test.End();
   1.810 +	}
   1.811 +
   1.812 +
   1.813 +static void TestAlternateInterfaceManipulation()
   1.814 +	{
   1.815 +	test.Start(_L("Alternate Interface Setting Manipulation"));
   1.816 +
   1.817 +	if (!SupportsAlternateInterfaces())
   1.818 +		{
   1.819 +		test.Printf(_L("*** Not supported - skipping alternate interface settings tests\n"));
   1.820 +		test.End();
   1.821 +		return;
   1.822 +		}
   1.823 +
   1.824 +	// Fetch endpoint data (again)
   1.825 +	test.Next(_L("Get endpoint capabilities"));
   1.826 +	TUsbDeviceCaps d_caps;
   1.827 +	TInt r = gPort.DeviceCaps(d_caps);
   1.828 +	test(r == KErrNone);
   1.829 +	const TInt n = d_caps().iTotalEndpoints;
   1.830 +	TUsbcEndpointData data[KUsbcMaxEndpoints];
   1.831 +	TPtr8 dataptr(reinterpret_cast<TUint8*>(data), sizeof(data), sizeof(data));
   1.832 +	r = gPort.EndpointCaps(dataptr);
   1.833 +	test(r == KErrNone);
   1.834 +
   1.835 +	// Find ep's for alternate ifc setting
   1.836 +	test.Next(_L("Find suitable endpoints"));
   1.837 +	TInt ep_found = 0;
   1.838 +	TBool foundIsoIN  = EFalse;
   1.839 +	TBool foundIsoOUT = EFalse;
   1.840 +	TBool foundIntIN  = EFalse;
   1.841 +	TUsbcInterfaceInfoBuf ifc;
   1.842 +
   1.843 +	// NB! We cannot assume that any specific device has any given set of
   1.844 +	// capabilities, so whilst we try and set an assortment of endpoint types
   1.845 +	// we may not get what we want.
   1.846 +
   1.847 +	// Also, note that the endpoint[] array in the interface descriptor
   1.848 +	// must be filled from ep[0]...ep[n-1].
   1.849 +
   1.850 +	for (TInt i = 0; i < n; i++)
   1.851 +		{
   1.852 +		const TUsbcEndpointCaps* const caps = &data[i].iCaps;
   1.853 +		const TInt mps = caps->MaxPacketSize();
   1.854 +		if (!foundIsoIN &&
   1.855 +			(caps->iTypesAndDir & (KUsbEpTypeIsochronous | KUsbEpDirIn)) ==
   1.856 +			(KUsbEpTypeIsochronous | KUsbEpDirIn))
   1.857 +			{
   1.858 +			// This is going to be our Iso TX (IN) endpoint
   1.859 +			ifc().iEndpointData[ep_found].iType = KUsbEpTypeIsochronous;
   1.860 +			ifc().iEndpointData[ep_found].iDir  = KUsbEpDirIn;
   1.861 +			ifc().iEndpointData[ep_found].iSize = mps;
   1.862 +			ifc().iEndpointData[ep_found].iInterval = 0x01;	// 2^(bInterval-1)ms, bInterval must be [1..16]
   1.863 +			ifc().iEndpointData[ep_found].iInterval_Hs = 0x01; // same as for FS
   1.864 +			test.Printf(_L("ISO  IN  size = %4d (ep %d)\n"), mps, ep_found + 1);
   1.865 +			foundIsoIN = ETrue;
   1.866 +			if (++ep_found == 3)
   1.867 +				break;
   1.868 +			}
   1.869 +		else if (!foundIsoOUT &&
   1.870 +				 (caps->iTypesAndDir & (KUsbEpTypeIsochronous | KUsbEpDirOut)) ==
   1.871 +				 (KUsbEpTypeIsochronous | KUsbEpDirOut))
   1.872 +			{
   1.873 +			// This is going to be our Iso RX (OUT) endpoint
   1.874 +			ifc().iEndpointData[ep_found].iType = KUsbEpTypeIsochronous;
   1.875 +			ifc().iEndpointData[ep_found].iDir  = KUsbEpDirOut;
   1.876 +			ifc().iEndpointData[ep_found].iSize = mps;
   1.877 +			ifc().iEndpointData[ep_found].iInterval = 0x01;	// 2^(bInterval-1)ms, bInterval must be [1..16]
   1.878 +			test.Printf(_L("ISO  OUT size = %4d (ep %d)\n"), mps, ep_found + 1);
   1.879 +			foundIsoOUT = ETrue;
   1.880 +			if (++ep_found == 3)
   1.881 +				break;
   1.882 +			}
   1.883 +		else if (!foundIntIN &&
   1.884 +				 (caps->iTypesAndDir & (KUsbEpTypeInterrupt | KUsbEpDirIn)) ==
   1.885 +				 (KUsbEpTypeInterrupt | KUsbEpDirIn))
   1.886 +			{
   1.887 +			// This is going to be our Interrupt TX (IN) endpoint
   1.888 +			ifc().iEndpointData[ep_found].iType  = KUsbEpTypeInterrupt;
   1.889 +			ifc().iEndpointData[ep_found].iDir   = KUsbEpDirIn;
   1.890 +			ifc().iEndpointData[ep_found].iSize  = mps;
   1.891 +			ifc().iEndpointData[ep_found].iInterval = 10;	// interval = 10ms, valid range [1..255]
   1.892 +			ifc().iEndpointData[ep_found].iInterval_Hs = 4;	// interval = 2^(bInterval-1)ms = 8ms
   1.893 +			ifc().iEndpointData[ep_found].iExtra    = 2;	// 2 extra bytes for Audio Class EP descriptor
   1.894 +			test.Printf(_L("INT  IN  size = %4d (ep %d)\n"), mps, ep_found + 1);
   1.895 +			foundIntIN = ETrue;
   1.896 +			INT_IN_ep = ep_found + 1;
   1.897 +			if (++ep_found == 3)
   1.898 +				break;
   1.899 +			}
   1.900 +		}
   1.901 +
   1.902 +	// Let's try to add some more Bulk endpoints up to the max # of 5.
   1.903 +	for (TInt i = 0; i < n; i++)
   1.904 +		{
   1.905 +		TUsbcEndpointCaps& caps = data[i].iCaps;
   1.906 +		const TUint mps = caps.MaxPacketSize();
   1.907 +		if (caps.iTypesAndDir & KUsbEpTypeBulk)
   1.908 +			{
   1.909 +			const TUint dir = (caps.iTypesAndDir & KUsbEpDirIn) ? KUsbEpDirIn : KUsbEpDirOut;
   1.910 +			ifc().iEndpointData[ep_found].iType = KUsbEpTypeBulk;
   1.911 +			ifc().iEndpointData[ep_found].iDir = dir;
   1.912 +			if (gUsingHighSpeed)
   1.913 +				{
   1.914 +				test.Printf(_L("Checking if correct Bulk packet size is reported in HS case\n"));
   1.915 +				test(mps == KUsbEpSize512);					// sane?
   1.916 +				}
   1.917 +			// The PSL should in any case also offer the 'legacy' FS size:
   1.918 +			test(caps.iSizes & KUsbEpSize64);
   1.919 +			ifc().iEndpointData[ep_found].iSize = mps;
   1.920 +			test.Printf(_L("BULK %s size = %4d (ep %d)\n"),
   1.921 +						dir == KUsbEpDirIn ? _S("IN ") : _S("OUT"), mps, ep_found + 1);
   1.922 +			if (++ep_found == 5)
   1.923 +				break;
   1.924 +			}
   1.925 +		}
   1.926 +
   1.927 +	test.Printf(_L("Total: %d endpoints found for the alt. ifc setting\n"), ep_found);
   1.928 +	if (ep_found < 3)
   1.929 +		{
   1.930 +		test.Printf(_L("(3 endpoints are at least required. Skipping test...)\n"));
   1.931 +		test.End();
   1.932 +		return;
   1.933 +		}
   1.934 +
   1.935 +	if (!foundIsoIN && !foundIsoOUT)
   1.936 +		{
   1.937 +		test.Printf(_L("(No Isochronous endpoints found)\n"));
   1.938 +		}
   1.939 +
   1.940 +	if (!foundIntIN)
   1.941 +		{
   1.942 +		test.Printf(_L("(No Interrupt endpoint found)\n"));
   1.943 +		test.Printf(_L("Adjusting endpoint size for later test\n"));
   1.944 +		// We want to make sure that at least one descriptor has the 2 extra bytes.
   1.945 +		// It doesn't matter that this ep could be a Bulk one, or that the 2 Iso ep's might be missing -
   1.946 +		// we just want to test some functionality and we're not going to use this interface in earnest.
   1.947 +		ifc().iEndpointData[2].iExtra = 2;					// 2 extra bytes for Audio Class Ep descriptor
   1.948 +		INT_IN_ep = 3;										// pretend it's an INT ep
   1.949 +		}
   1.950 +
   1.951 +	test.Next(_L("Create alternate interface setting"));
   1.952 +	_LIT16(string, "T_USBAPI Test Interface (Setting 1: Audio)");
   1.953 +	ifc().iString = const_cast<TDesC16*>(&string);
   1.954 +	ifc().iTotalEndpointsUsed = ep_found;
   1.955 +	ifc().iClass.iClassNum	  = KUsbAudioInterfaceClassCode;
   1.956 +	ifc().iClass.iSubClassNum = KUsbAudioInterfaceSubclassCode_Audiostreaming;
   1.957 +	ifc().iClass.iProtocolNum = KUsbAudioInterfaceProtocolCode_Pr_Protocol_Undefined;
   1.958 +	r = gPort.SetInterface(1, ifc);
   1.959 +	test(r == KErrNone);
   1.960 +
   1.961 +	test.Next(_L("Set alternate setting number to 8"));
   1.962 +	TBuf8<KUsbDescSize_Interface> descriptor;
   1.963 +	r = gPort.GetInterfaceDescriptor(1, descriptor);
   1.964 +	test(r == KErrNone);
   1.965 +	descriptor[KIfcDesc_SettingOffset] = 8;
   1.966 +	r = gPort.SetInterfaceDescriptor(1, descriptor);
   1.967 +	test(r != KErrNone);
   1.968 +
   1.969 +	test.Next(_L("Change ifc # in def setting whith alt ifcs"));
   1.970 +	r = gPort.GetInterfaceDescriptor(0, descriptor);
   1.971 +	test(r == KErrNone);
   1.972 +	descriptor[KIfcDesc_SettingOffset] = 8;
   1.973 +	r = gPort.SetInterfaceDescriptor(0, descriptor);
   1.974 +	test(r != KErrNone);
   1.975 +
   1.976 +	test.Next(_L("Change the ifc # in default setting to 8"));
   1.977 +	r = gPort.ReleaseInterface(1);
   1.978 +	test(r == KErrNone);
   1.979 +	r = gPort.SetInterfaceDescriptor(0, descriptor);
   1.980 +	test(r == KErrNone);
   1.981 +
   1.982 +	test.Next(_L("Create new setting - this should also get #8"));
   1.983 +	r = gPort.SetInterface(1, ifc);
   1.984 +	test(r == KErrNone);
   1.985 +	r = gPort.GetInterfaceDescriptor(1, descriptor);
   1.986 +	test(r == KErrNone);
   1.987 +	test(descriptor[KIfcDesc_SettingOffset] == 8);
   1.988 +
   1.989 +	test.Next(_L("Change the ifc # in default setting to 0"));
   1.990 +	r = gPort.ReleaseInterface(1);
   1.991 +	test(r == KErrNone);
   1.992 +	r = gPort.GetInterfaceDescriptor(0, descriptor);
   1.993 +	test(r == KErrNone);
   1.994 +	descriptor[KIfcDesc_SettingOffset] = 0;
   1.995 +	r = gPort.SetInterfaceDescriptor(0, descriptor);
   1.996 +	test(r == KErrNone);
   1.997 +
   1.998 +	test.Next(_L("Create new setting - this should also get #0"));
   1.999 +	r = gPort.SetInterface(1, ifc);
  1.1000 +	test(r == KErrNone);
  1.1001 +	r = gPort.GetInterfaceDescriptor(1, descriptor);
  1.1002 +	test(r == KErrNone);
  1.1003 +	test(descriptor[KIfcDesc_SettingOffset] == 0);
  1.1004 +
  1.1005 +	test.End();
  1.1006 +	}
  1.1007 +
  1.1008 +
  1.1009 +static void TestEndpointDescriptor()
  1.1010 +	{
  1.1011 +	test.Start(_L("Endpoint Descriptor Manipulation"));
  1.1012 +
  1.1013 +	test.Next(_L("GetEndpointDescriptorSize(1)"));
  1.1014 +	TInt epNumber = 1;
  1.1015 +	TInt desc_size = 0;
  1.1016 +	TInt r = gPort.GetEndpointDescriptorSize(0, epNumber, desc_size);
  1.1017 +	test(r == KErrNone);
  1.1018 +	test(static_cast<TUint>(desc_size) == KUsbDescSize_Endpoint);
  1.1019 +
  1.1020 +	test.Next(_L("GetEndpointDescriptor(1)"));
  1.1021 +	TBuf8<KUsbDescSize_Endpoint> descriptor;
  1.1022 +	r = gPort.GetEndpointDescriptor(0, epNumber, descriptor);
  1.1023 +	test(r == KErrNone);
  1.1024 +
  1.1025 +	test.Next(_L("SetEndpointDescriptor(1)"));
  1.1026 +	// Change the endpoint poll interval
  1.1027 +	TUint8 ival = 0x66;
  1.1028 +	if (descriptor[KEpDesc_IntervalOffset] == ival)
  1.1029 +		ival++;
  1.1030 +	descriptor[KEpDesc_IntervalOffset] = ival;
  1.1031 +	r = gPort.SetEndpointDescriptor(0, epNumber, descriptor);
  1.1032 +	test(r == KErrNone);
  1.1033 +
  1.1034 +	test.Next(_L("GetEndpointDescriptor(1)"));
  1.1035 +	TBuf8<KUsbDescSize_Endpoint> descriptor2;
  1.1036 +	r = gPort.GetEndpointDescriptor(0, epNumber, descriptor2);
  1.1037 +	test(r == KErrNone);
  1.1038 +
  1.1039 +	test.Next(_L("Compare endpoint descriptor with value set"));
  1.1040 +	r = descriptor2.Compare(descriptor);
  1.1041 +	test(r == KErrNone);
  1.1042 +
  1.1043 +	test.Next(_L("Check endpoint max packet size"));
  1.1044 +	const TUint16 ep_size = EpSize(descriptor[KEpDesc_PacketSizeOffset],
  1.1045 +								   descriptor[KEpDesc_PacketSizeOffset+1]);
  1.1046 +	test.Printf(_L(" Size: %d\n"), ep_size);
  1.1047 +	if (gUsingHighSpeed)
  1.1048 +		{
  1.1049 +		// HS Bulk ep can only have one possible packet size.
  1.1050 +		test(ep_size == 512);
  1.1051 +		}
  1.1052 +	else
  1.1053 +		{
  1.1054 +		// FS Bulk ep cannot be larger than 64 bytes.
  1.1055 +		test(ep_size <= 64);
  1.1056 +		}
  1.1057 +
  1.1058 +	test.End();
  1.1059 +	}
  1.1060 +
  1.1061 +
  1.1062 +static void TestExtendedEndpointDescriptor()
  1.1063 +	{
  1.1064 +	test.Start(_L("Extended Endpoint Descriptor Manipulation"));
  1.1065 +
  1.1066 +	if (!SupportsAlternateInterfaces())
  1.1067 +		{
  1.1068 +		test.Printf(_L("*** Not supported - skipping Extended Endpoint descriptor tests\n"));
  1.1069 +		test.End();
  1.1070 +		return;
  1.1071 +		}
  1.1072 +
  1.1073 +	// Extended Endpoint Descriptor manipulation (Audio class endpoint)
  1.1074 +
  1.1075 +	test.Next(_L("GetEndpointDescriptorSize()"));
  1.1076 +	TInt epNumber = INT_IN_ep;
  1.1077 +	TInt desc_size = 0;
  1.1078 +	TInt r = gPort.GetEndpointDescriptorSize(1, epNumber, desc_size);
  1.1079 +	test(r == KErrNone);
  1.1080 +	test(static_cast<TUint>(desc_size) == KUsbDescSize_AudioEndpoint);
  1.1081 +
  1.1082 +	test.Next(_L("GetEndpointDescriptor()"));
  1.1083 +	TBuf8<KUsbDescSize_AudioEndpoint> descriptor;
  1.1084 +	r = gPort.GetEndpointDescriptor(1, epNumber, descriptor);
  1.1085 +	test(r == KErrNone);
  1.1086 +
  1.1087 +	test.Next(_L("SetEndpointDescriptor()"));
  1.1088 +	// Change the Audio Endpoint bSynchAddress field
  1.1089 +	TUint8 addr = 0x85;										// bogus address
  1.1090 +	if (descriptor[KEpDesc_SynchAddressOffset] == addr)
  1.1091 +		addr++;
  1.1092 +	descriptor[KEpDesc_SynchAddressOffset] = addr;
  1.1093 +	r = gPort.SetEndpointDescriptor(1, epNumber, descriptor);
  1.1094 +	test(r == KErrNone);
  1.1095 +
  1.1096 +	test.Next(_L("GetEndpointDescriptor()"));
  1.1097 +	TBuf8<KUsbDescSize_AudioEndpoint> descriptor2;
  1.1098 +	r = gPort.GetEndpointDescriptor(1, epNumber, descriptor2);
  1.1099 +	test(r == KErrNone);
  1.1100 +
  1.1101 +	test.Next(_L("Compare endpoint descriptor with value set"));
  1.1102 +	r = descriptor2.Compare(descriptor);
  1.1103 +	test(r == KErrNone);
  1.1104 +
  1.1105 +	test.Next(_L("Check endpoint max packet size"));
  1.1106 +	const TUint16 ep_size = EpSize(descriptor[KEpDesc_PacketSizeOffset],
  1.1107 +								   descriptor[KEpDesc_PacketSizeOffset+1]);
  1.1108 +	if (gUsingHighSpeed)
  1.1109 +		{
  1.1110 +		// HS Interrupt ep.
  1.1111 +		test(ep_size <= 1024);
  1.1112 +		}
  1.1113 +	else
  1.1114 +		{
  1.1115 +		// FS Interrupt ep cannot be larger than 64 bytes.
  1.1116 +		test(ep_size <= 64);
  1.1117 +		}
  1.1118 +
  1.1119 +	test.End();
  1.1120 +	}
  1.1121 +
  1.1122 +
  1.1123 +static void TestStandardStringDescriptors()
  1.1124 +	{
  1.1125 +	test.Start(_L("String Descriptor Manipulation"));
  1.1126 +
  1.1127 +	//
  1.1128 +	// --- LANGID code
  1.1129 +	//
  1.1130 +
  1.1131 +	test.Next(_L("GetStringDescriptorLangId()"));
  1.1132 +	TUint16 rd_langid_orig;
  1.1133 +	TInt r = gPort.GetStringDescriptorLangId(rd_langid_orig);
  1.1134 +	test(r == KErrNone);
  1.1135 +	test.Printf(_L("Original LANGID code: 0x%04X\n"), rd_langid_orig);
  1.1136 +
  1.1137 +	test.Next(_L("SetStringDescriptorLangId()"));
  1.1138 +	TUint16 wr_langid = 0x0809;								// English (UK) Language ID
  1.1139 +	if (wr_langid == rd_langid_orig)
  1.1140 +		wr_langid = 0x0444;									// Tatar Language ID
  1.1141 +	r = gPort.SetStringDescriptorLangId(wr_langid);
  1.1142 +	test(r == KErrNone);
  1.1143 +
  1.1144 +	test.Next(_L("GetStringDescriptorLangId()"));
  1.1145 +	TUint16 rd_langid;
  1.1146 +	r = gPort.GetStringDescriptorLangId(rd_langid);
  1.1147 +	test(r == KErrNone);
  1.1148 +	test.Printf(_L("New LANGID code: 0x%04X\n"), rd_langid);
  1.1149 +
  1.1150 +	test.Next(_L("Compare LANGID codes"));
  1.1151 +	test(rd_langid == wr_langid);
  1.1152 +
  1.1153 +	test.Next(_L("Restore original LANGID code"));
  1.1154 +	r = gPort.SetStringDescriptorLangId(rd_langid_orig);
  1.1155 +	test(r == KErrNone);
  1.1156 +	r = gPort.GetStringDescriptorLangId(rd_langid);
  1.1157 +	test(r == KErrNone);
  1.1158 +	test(rd_langid == rd_langid_orig);
  1.1159 +
  1.1160 +	//
  1.1161 +	// --- Manufacturer string
  1.1162 +	//
  1.1163 +
  1.1164 +	test.Next(_L("GetManufacturerStringDescriptor()"));
  1.1165 +	TBuf16<KUsbStringDescStringMaxSize / 2> rd_str_orig;
  1.1166 +	r = gPort.GetManufacturerStringDescriptor(rd_str_orig);
  1.1167 +	test(r == KErrNone || r == KErrNotFound);
  1.1168 +	TBool restore_string;
  1.1169 +	if (r == KErrNone)
  1.1170 +		{
  1.1171 +		test.Printf(_L("Original Manufacturer string: \"%lS\"\n"), &rd_str_orig);
  1.1172 +		restore_string = ETrue;
  1.1173 +		}
  1.1174 +	else
  1.1175 +		{
  1.1176 +		test.Printf(_L("No Manufacturer string set\n"));
  1.1177 +		restore_string = EFalse;
  1.1178 +		}
  1.1179 +
  1.1180 +	test.Next(_L("SetManufacturerStringDescriptor()"));
  1.1181 +	_LIT16(manufacturer, "Manufacturer Which Manufactures Devices");
  1.1182 +	TBuf16<KUsbStringDescStringMaxSize / 2> wr_str(manufacturer);
  1.1183 +	r = gPort.SetManufacturerStringDescriptor(wr_str);
  1.1184 +	test(r == KErrNone);
  1.1185 +
  1.1186 +	test.Next(_L("GetManufacturerStringDescriptor()"));
  1.1187 +	TBuf16<KUsbStringDescStringMaxSize / 2> rd_str;
  1.1188 +	r = gPort.GetManufacturerStringDescriptor(rd_str);
  1.1189 +	test(r == KErrNone);
  1.1190 +	test.Printf(_L("New Manufacturer string: \"%lS\"\n"), &rd_str);
  1.1191 +
  1.1192 +	test.Next(_L("Compare Manufacturer strings"));
  1.1193 +	r = rd_str.Compare(wr_str);
  1.1194 +	test(r == KErrNone);
  1.1195 +
  1.1196 +	test.Next(_L("SetManufacturerStringDescriptor()"));
  1.1197 +	_LIT16(manufacturer2, "Different Manufacturer Which Manufactures Different Devices");
  1.1198 +	wr_str.FillZ(wr_str.MaxLength());
  1.1199 +	wr_str = manufacturer2;
  1.1200 +	r = gPort.SetManufacturerStringDescriptor(wr_str);
  1.1201 +	test(r == KErrNone);
  1.1202 +
  1.1203 +	test.Next(_L("GetManufacturerStringDescriptor()"));
  1.1204 +	rd_str.FillZ(rd_str.MaxLength());
  1.1205 +	r = gPort.GetManufacturerStringDescriptor(rd_str);
  1.1206 +	test(r == KErrNone);
  1.1207 +	test.Printf(_L("New Manufacturer string: \"%lS\"\n"), &rd_str);
  1.1208 +
  1.1209 +	test.Next(_L("Compare Manufacturer strings"));
  1.1210 +	r = rd_str.Compare(wr_str);
  1.1211 +	test(r == KErrNone);
  1.1212 +
  1.1213 +	test.Next(_L("RemoveManufacturerStringDescriptor()"));
  1.1214 +	r = gPort.RemoveManufacturerStringDescriptor();
  1.1215 +	test(r == KErrNone);
  1.1216 +	r = gPort.GetManufacturerStringDescriptor(rd_str);
  1.1217 +	test(r == KErrNotFound);
  1.1218 +
  1.1219 +	if (restore_string)
  1.1220 +		{
  1.1221 +		test.Next(_L("Restore original string"));
  1.1222 +		r = gPort.SetManufacturerStringDescriptor(rd_str_orig);
  1.1223 +		test(r == KErrNone);
  1.1224 +		r = gPort.GetManufacturerStringDescriptor(rd_str);
  1.1225 +		test(r == KErrNone);
  1.1226 +		r = rd_str.Compare(rd_str_orig);
  1.1227 +		test(r == KErrNone);
  1.1228 +		}
  1.1229 +
  1.1230 +	//
  1.1231 +	// --- Product string
  1.1232 +	//
  1.1233 +
  1.1234 +	test.Next(_L("GetProductStringDescriptor()"));
  1.1235 +	rd_str_orig.FillZ(rd_str.MaxLength());
  1.1236 +	r = gPort.GetProductStringDescriptor(rd_str_orig);
  1.1237 +	test(r == KErrNone || r == KErrNotFound);
  1.1238 +	if (r == KErrNone)
  1.1239 +		{
  1.1240 +		test.Printf(_L("Old Product string: \"%lS\"\n"), &rd_str_orig);
  1.1241 +		restore_string = ETrue;
  1.1242 +		}
  1.1243 +	else
  1.1244 +		restore_string = EFalse;
  1.1245 +
  1.1246 +	test.Next(_L("SetProductStringDescriptor()"));
  1.1247 +	_LIT16(product, "Product That Was Produced By A Manufacturer");
  1.1248 +	wr_str.FillZ(wr_str.MaxLength());
  1.1249 +	wr_str = product;
  1.1250 +	r = gPort.SetProductStringDescriptor(wr_str);
  1.1251 +	test(r == KErrNone);
  1.1252 +
  1.1253 +	test.Next(_L("GetProductStringDescriptor()"));
  1.1254 +	rd_str.FillZ(rd_str.MaxLength());
  1.1255 +	r = gPort.GetProductStringDescriptor(rd_str);
  1.1256 +	test(r == KErrNone);
  1.1257 +	test.Printf(_L("New Product string: \"%lS\"\n"), &rd_str);
  1.1258 +
  1.1259 +	test.Next(_L("Compare Product strings"));
  1.1260 +	r = rd_str.Compare(wr_str);
  1.1261 +	test(r == KErrNone);
  1.1262 +
  1.1263 +	test.Next(_L("SetProductStringDescriptor()"));
  1.1264 +	_LIT16(product2, "Different Product That Was Produced By A Different Manufacturer");
  1.1265 +	wr_str.FillZ(wr_str.MaxLength());
  1.1266 +	wr_str = product2;
  1.1267 +	r = gPort.SetProductStringDescriptor(wr_str);
  1.1268 +	test(r == KErrNone);
  1.1269 +
  1.1270 +	test.Next(_L("GetProductStringDescriptor()"));
  1.1271 +	rd_str.FillZ(rd_str.MaxLength());
  1.1272 +	r = gPort.GetProductStringDescriptor(rd_str);
  1.1273 +	test(r == KErrNone);
  1.1274 +	test.Printf(_L("New Product string: \"%lS\"\n"), &rd_str);
  1.1275 +
  1.1276 +	test.Next(_L("Compare Product strings"));
  1.1277 +	r = rd_str.Compare(wr_str);
  1.1278 +	test(r == KErrNone);
  1.1279 +
  1.1280 +	test.Next(_L("RemoveProductStringDescriptor()"));
  1.1281 +	r = gPort.RemoveProductStringDescriptor();
  1.1282 +	test(r == KErrNone);
  1.1283 +	r = gPort.GetProductStringDescriptor(rd_str);
  1.1284 +	test(r == KErrNotFound);
  1.1285 +
  1.1286 +	if (restore_string)
  1.1287 +		{
  1.1288 +		test.Next(_L("Restore original string"));
  1.1289 +		r = gPort.SetProductStringDescriptor(rd_str_orig);
  1.1290 +		test(r == KErrNone);
  1.1291 +		r = gPort.GetProductStringDescriptor(rd_str);
  1.1292 +		test(r == KErrNone);
  1.1293 +		r = rd_str.Compare(rd_str_orig);
  1.1294 +		test(r == KErrNone);
  1.1295 +		}
  1.1296 +
  1.1297 +	//
  1.1298 +	// --- Serial Number string
  1.1299 +	//
  1.1300 +
  1.1301 +	test.Next(_L("GetSerialNumberStringDescriptor()"));
  1.1302 +	rd_str_orig.FillZ(rd_str.MaxLength());
  1.1303 +	r = gPort.GetSerialNumberStringDescriptor(rd_str_orig);
  1.1304 +	test(r == KErrNone || r == KErrNotFound);
  1.1305 +	if (r == KErrNone)
  1.1306 +		{
  1.1307 +		test.Printf(_L("Old Serial Number: \"%lS\"\n"), &rd_str_orig);
  1.1308 +		restore_string = ETrue;
  1.1309 +		}
  1.1310 +	else
  1.1311 +		restore_string = EFalse;
  1.1312 +
  1.1313 +	test.Next(_L("SetSerialNumberStringDescriptor()"));
  1.1314 +	_LIT16(serial, "000666000XYZ");
  1.1315 +	wr_str.FillZ(wr_str.MaxLength());
  1.1316 +	wr_str = serial;
  1.1317 +	r = gPort.SetSerialNumberStringDescriptor(wr_str);
  1.1318 +	test(r == KErrNone);
  1.1319 +
  1.1320 +	test.Next(_L("GetSerialNumberStringDescriptor()"));
  1.1321 +	rd_str.FillZ(rd_str.MaxLength());
  1.1322 +	r = gPort.GetSerialNumberStringDescriptor(rd_str);
  1.1323 +	test(r == KErrNone);
  1.1324 +	test.Printf(_L("New Serial Number: \"%lS\"\n"), &rd_str);
  1.1325 +
  1.1326 +	test.Next(_L("Compare Serial Number strings"));
  1.1327 +	r = rd_str.Compare(wr_str);
  1.1328 +	test(r == KErrNone);
  1.1329 +
  1.1330 +	test.Next(_L("SetSerialNumberStringDescriptor()"));
  1.1331 +	_LIT16(serial2, "Y11611193111711111Y");
  1.1332 +	wr_str.FillZ(wr_str.MaxLength());
  1.1333 +	wr_str = serial2;
  1.1334 +	r = gPort.SetSerialNumberStringDescriptor(wr_str);
  1.1335 +	test(r == KErrNone);
  1.1336 +
  1.1337 +	test.Next(_L("GetSerialNumberStringDescriptor()"));
  1.1338 +	rd_str.FillZ(rd_str.MaxLength());
  1.1339 +	r = gPort.GetSerialNumberStringDescriptor(rd_str);
  1.1340 +	test(r == KErrNone);
  1.1341 +	test.Printf(_L("New Serial Number: \"%lS\"\n"), &rd_str);
  1.1342 +
  1.1343 +	test.Next(_L("Compare Serial Number strings"));
  1.1344 +	r = rd_str.Compare(wr_str);
  1.1345 +	test(r == KErrNone);
  1.1346 +
  1.1347 +	test.Next(_L("RemoveSerialNumberStringDescriptor()"));
  1.1348 +	r = gPort.RemoveSerialNumberStringDescriptor();
  1.1349 +	test(r == KErrNone);
  1.1350 +	r = gPort.GetSerialNumberStringDescriptor(rd_str);
  1.1351 +	test(r == KErrNotFound);
  1.1352 +
  1.1353 +	if (restore_string)
  1.1354 +		{
  1.1355 +		test.Next(_L("Restore original string"));
  1.1356 +		r = gPort.SetSerialNumberStringDescriptor(rd_str_orig);
  1.1357 +		test(r == KErrNone);
  1.1358 +		r = gPort.GetSerialNumberStringDescriptor(rd_str);
  1.1359 +		test(r == KErrNone);
  1.1360 +		r = rd_str.Compare(rd_str_orig);
  1.1361 +		test(r == KErrNone);
  1.1362 +		}
  1.1363 +
  1.1364 +	//
  1.1365 +	// --- Configuration string
  1.1366 +	//
  1.1367 +
  1.1368 +	test.Next(_L("GetConfigurationStringDescriptor()"));
  1.1369 +	rd_str_orig.FillZ(rd_str.MaxLength());
  1.1370 +	r = gPort.GetConfigurationStringDescriptor(rd_str_orig);
  1.1371 +	test(r == KErrNone || r == KErrNotFound);
  1.1372 +	if (r == KErrNone)
  1.1373 +		{
  1.1374 +		test.Printf(_L("Old Configuration string: \"%lS\"\n"), &rd_str_orig);
  1.1375 +		restore_string = ETrue;
  1.1376 +		}
  1.1377 +	else
  1.1378 +		restore_string = EFalse;
  1.1379 +
  1.1380 +	test.Next(_L("SetConfigurationStringDescriptor()"));
  1.1381 +	_LIT16(config, "Relatively Simple Configuration That Is Still Useful");
  1.1382 +	wr_str.FillZ(wr_str.MaxLength());
  1.1383 +	wr_str = config;
  1.1384 +	r = gPort.SetConfigurationStringDescriptor(wr_str);
  1.1385 +	test(r == KErrNone);
  1.1386 +
  1.1387 +	test.Next(_L("GetConfigurationStringDescriptor()"));
  1.1388 +	rd_str.FillZ(rd_str.MaxLength());
  1.1389 +	r = gPort.GetConfigurationStringDescriptor(rd_str);
  1.1390 +	test(r == KErrNone);
  1.1391 +	test.Printf(_L("New Configuration string: \"%lS\"\n"), &rd_str);
  1.1392 +
  1.1393 +	test.Next(_L("Compare Configuration strings"));
  1.1394 +	r = rd_str.Compare(wr_str);
  1.1395 +	test(r == KErrNone);
  1.1396 +
  1.1397 +	test.Next(_L("SetConfigurationStringDescriptor()"));
  1.1398 +	_LIT16(config2, "Convenient Configuration That Can Be Very Confusing");
  1.1399 +	wr_str.FillZ(wr_str.MaxLength());
  1.1400 +	wr_str = config2;
  1.1401 +	r = gPort.SetConfigurationStringDescriptor(wr_str);
  1.1402 +	test(r == KErrNone);
  1.1403 +
  1.1404 +	test.Next(_L("GetConfigurationStringDescriptor()"));
  1.1405 +	rd_str.FillZ(rd_str.MaxLength());
  1.1406 +	r = gPort.GetConfigurationStringDescriptor(rd_str);
  1.1407 +	test(r == KErrNone);
  1.1408 +	test.Printf(_L("New Configuration string: \"%lS\"\n"), &rd_str);
  1.1409 +
  1.1410 +	test.Next(_L("Compare Configuration strings"));
  1.1411 +	r = rd_str.Compare(wr_str);
  1.1412 +	test(r == KErrNone);
  1.1413 +
  1.1414 +	test.Next(_L("RemoveConfigurationStringDescriptor()"));
  1.1415 +	r = gPort.RemoveConfigurationStringDescriptor();
  1.1416 +	test(r == KErrNone);
  1.1417 +	r = gPort.GetConfigurationStringDescriptor(rd_str);
  1.1418 +	test(r == KErrNotFound);
  1.1419 +
  1.1420 +	if (restore_string)
  1.1421 +		{
  1.1422 +		test.Next(_L("Restore original string"));
  1.1423 +		r = gPort.SetConfigurationStringDescriptor(rd_str_orig);
  1.1424 +		test(r == KErrNone);
  1.1425 +		r = gPort.GetConfigurationStringDescriptor(rd_str);
  1.1426 +		test(r == KErrNone);
  1.1427 +		r = rd_str.Compare(rd_str_orig);
  1.1428 +		test(r == KErrNone);
  1.1429 +		}
  1.1430 +
  1.1431 +	test.End();
  1.1432 +	}
  1.1433 +
  1.1434 +
  1.1435 +//---------------------------------------------
  1.1436 +//! @SYMTestCaseID KBASE-T_USBAPI-0041
  1.1437 +//! @SYMTestType UT
  1.1438 +//! @SYMREQ REQ5662
  1.1439 +//! @SYMTestCaseDesc USB Device Driver API extension to support setting of a string descriptor at a specific index
  1.1440 +//! @SYMTestActions Tests GetStringDescriptor(), SetStringDescriptor() and RemoveStringDescriptor() to verify
  1.1441 +//! the right values are retrieved, set and deleted at specific positions
  1.1442 +//! @SYMTestExpectedResults KErrNone in positive testing and KErrNotFound in negative one
  1.1443 +//! @SYMTestPriority High
  1.1444 +//! @SYMTestStatus Implemented
  1.1445 +//---------------------------------------------
  1.1446 +static void TestArbitraryStringDescriptors()
  1.1447 +	{
  1.1448 +	test.Start(_L("Arbitrary String Descriptor Manipulation"));
  1.1449 +
  1.1450 +	const TUint8 stridx1 = 0xEE;
  1.1451 +	const TUint8 stridx2 = 0xCC;
  1.1452 +	const TUint8 stridx3 = 0xDD;
  1.1453 +	const TUint8 stridx4 = 0xFF;
  1.1454 +
  1.1455 +	// First test string
  1.1456 +
  1.1457 +	test.Next(_L("GetStringDescriptor() 1"));
  1.1458 +	TBuf16<KUsbStringDescStringMaxSize / 2> rd_str;
  1.1459 +	TInt r = gPort.GetStringDescriptor(stridx1, rd_str);
  1.1460 +	test(r == KErrNotFound);
  1.1461 +
  1.1462 +	test.Next(_L("SetStringDescriptor() 1"));
  1.1463 +	_LIT16(string_one, "Arbitrary String Descriptor Test String 1");
  1.1464 +	TBuf16<KUsbStringDescStringMaxSize / 2> wr_str(string_one);
  1.1465 +	r = gPort.SetStringDescriptor(stridx1, wr_str);
  1.1466 +	test(r == KErrNone);
  1.1467 +
  1.1468 +	test.Next(_L("GetStringDescriptor() 1"));
  1.1469 +	r = gPort.GetStringDescriptor(stridx1, rd_str);
  1.1470 +	test(r == KErrNone);
  1.1471 +	test.Printf(_L("New test string @ idx %d: \"%lS\"\n"), stridx1, &rd_str);
  1.1472 +
  1.1473 +	test.Next(_L("Compare test strings 1"));
  1.1474 +	r = rd_str.Compare(wr_str);
  1.1475 +	test(r == KErrNone);
  1.1476 +
  1.1477 +	// Second test string
  1.1478 +
  1.1479 +	test.Next(_L("GetStringDescriptor() 2"));
  1.1480 +	rd_str.FillZ(rd_str.MaxLength());
  1.1481 +	r = gPort.GetStringDescriptor(stridx2, rd_str);
  1.1482 +	test(r == KErrNotFound);
  1.1483 +
  1.1484 +	test.Next(_L("SetStringDescriptor() 2"));
  1.1485 +	_LIT16(string_two, "Arbitrary String Descriptor Test String 2");
  1.1486 +	wr_str.FillZ(wr_str.MaxLength());
  1.1487 +	wr_str = string_two;
  1.1488 +	r = gPort.SetStringDescriptor(stridx2, wr_str);
  1.1489 +	test(r == KErrNone);
  1.1490 +
  1.1491 +	// In between we create another interface setting to see what happens
  1.1492 +	// to the existing string descriptor indices.
  1.1493 +	// (We don't have to test this on every platform -
  1.1494 +	// besides, those that don't support alt settings
  1.1495 +	// are by now very rare.)
  1.1496 +	if (SupportsAlternateInterfaces())
  1.1497 +		{
  1.1498 +		TUsbcInterfaceInfoBuf ifc;
  1.1499 +		_LIT16(string, "T_USBAPI Bogus Test Interface (Setting 2)");
  1.1500 +		ifc().iString = const_cast<TDesC16*>(&string);
  1.1501 +		ifc().iTotalEndpointsUsed = 0;
  1.1502 +		TInt r = gPort.SetInterface(2, ifc);
  1.1503 +		test(r == KErrNone);
  1.1504 +		}
  1.1505 +
  1.1506 +	test.Next(_L("GetStringDescriptor() 2"));
  1.1507 +	r = gPort.GetStringDescriptor(stridx2, rd_str);
  1.1508 +	test(r == KErrNone);
  1.1509 +	test.Printf(_L("New test string @ idx %d: \"%lS\"\n"), stridx2, &rd_str);
  1.1510 +
  1.1511 +	test.Next(_L("Compare test strings 2"));
  1.1512 +	r = rd_str.Compare(wr_str);
  1.1513 +	test(r == KErrNone);
  1.1514 +
  1.1515 +	// Third test string
  1.1516 +
  1.1517 +	test.Next(_L("GetStringDescriptor() 3"));
  1.1518 +	rd_str.FillZ(rd_str.MaxLength());
  1.1519 +	r = gPort.GetStringDescriptor(stridx3, rd_str);
  1.1520 +	test(r == KErrNotFound);
  1.1521 +
  1.1522 +	test.Next(_L("SetStringDescriptor() 3"));
  1.1523 +	_LIT16(string_three, "Arbitrary String Descriptor Test String 3");
  1.1524 +	wr_str.FillZ(wr_str.MaxLength());
  1.1525 +	wr_str = string_three;
  1.1526 +	r = gPort.SetStringDescriptor(stridx3, wr_str);
  1.1527 +	test(r == KErrNone);
  1.1528 +
  1.1529 +	test.Next(_L("GetStringDescriptor() 3"));
  1.1530 +	r = gPort.GetStringDescriptor(stridx3, rd_str);
  1.1531 +	test(r == KErrNone);
  1.1532 +	test.Printf(_L("New test string @ idx %d: \"%lS\"\n"), stridx3, &rd_str);
  1.1533 +
  1.1534 +	test.Next(_L("Compare test strings 3"));
  1.1535 +	r = rd_str.Compare(wr_str);
  1.1536 +	test(r == KErrNone);
  1.1537 +
  1.1538 +	// Remove string descriptors
  1.1539 +
  1.1540 +	test.Next(_L("RemoveStringDescriptor() 4"));
  1.1541 +	r = gPort.RemoveStringDescriptor(stridx4);
  1.1542 +	test(r == KErrNotFound);
  1.1543 +
  1.1544 +	test.Next(_L("RemoveStringDescriptor() 3"));
  1.1545 +	r = gPort.RemoveStringDescriptor(stridx3);
  1.1546 +	test(r == KErrNone);
  1.1547 +	r = gPort.GetStringDescriptor(stridx3, rd_str);
  1.1548 +	test(r == KErrNotFound);
  1.1549 +
  1.1550 +	test.Next(_L("RemoveStringDescriptor() 2"));
  1.1551 +	r = gPort.RemoveStringDescriptor(stridx2);
  1.1552 +	test(r == KErrNone);
  1.1553 +	r = gPort.GetStringDescriptor(stridx2, rd_str);
  1.1554 +	test(r == KErrNotFound);
  1.1555 +
  1.1556 +	test.Next(_L("RemoveStringDescriptor() 1"));
  1.1557 +	r = gPort.RemoveStringDescriptor(stridx1);
  1.1558 +	test(r == KErrNone);
  1.1559 +	r = gPort.GetStringDescriptor(stridx1, rd_str);
  1.1560 +	test(r == KErrNotFound);
  1.1561 +
  1.1562 +	test.End();
  1.1563 +	}
  1.1564 +
  1.1565 +
  1.1566 +static void TestDescriptorManipulation()
  1.1567 +	{
  1.1568 +	test.Start(_L("Test USB Descriptor Manipulation"));
  1.1569 +
  1.1570 +	TestDeviceDescriptor();
  1.1571 +
  1.1572 +	TestDeviceQualifierDescriptor();
  1.1573 +
  1.1574 +	TestConfigurationDescriptor();
  1.1575 +
  1.1576 +	TestOtherSpeedConfigurationDescriptor();
  1.1577 +
  1.1578 +	TestInterfaceDescriptor();
  1.1579 +
  1.1580 +	TestClassSpecificDescriptors();
  1.1581 +
  1.1582 +	TestAlternateInterfaceManipulation();
  1.1583 +
  1.1584 +	TestEndpointDescriptor();
  1.1585 +
  1.1586 +	TestExtendedEndpointDescriptor();
  1.1587 +
  1.1588 +	TestStandardStringDescriptors();
  1.1589 +
  1.1590 +	TestArbitraryStringDescriptors();
  1.1591 +
  1.1592 +	test.End();
  1.1593 +	}
  1.1594 +
  1.1595 +
  1.1596 +//---------------------------------------------
  1.1597 +//! @SYMTestCaseID KBASE-T_USBAPI-0040
  1.1598 +//! @SYMTestType UT
  1.1599 +//! @SYMTestCaseDesc Test OTG extensions
  1.1600 +//! @SYMTestExpectedResults All APIs behave as expected
  1.1601 +//! @SYMTestPriority Medium
  1.1602 +//! @SYMTestStatus Implemented
  1.1603 +//---------------------------------------------
  1.1604 +static void TestOtgExtensions()
  1.1605 +	{
  1.1606 +	test.Start(_L("Test Some OTG API Extensions"));
  1.1607 +
  1.1608 +	// Test OTG descriptor manipulation
  1.1609 +	test.Next(_L("Get OTG Descriptor Size"));
  1.1610 +	TInt size;
  1.1611 +	gPort.GetOtgDescriptorSize(size);
  1.1612 +	test(static_cast<TUint>(size) == KUsbDescSize_Otg);
  1.1613 +
  1.1614 +	test.Next(_L("Get OTG Descriptor"));
  1.1615 +	TBuf8<KUsbDescSize_Otg> otgDesc;
  1.1616 +	TInt r = gPort.GetOtgDescriptor(otgDesc);
  1.1617 +	test(r == KErrNotSupported || r == KErrNone);
  1.1618 +
  1.1619 +	test.Next(_L("Set OTG Descriptor"));
  1.1620 +	if (r == KErrNotSupported)
  1.1621 +		{
  1.1622 +		r = gPort.SetOtgDescriptor(otgDesc);
  1.1623 +		test(r == KErrNotSupported);
  1.1624 +		}
  1.1625 +	else
  1.1626 +		{
  1.1627 +		otgDesc[0] = KUsbDescSize_Otg;
  1.1628 +		otgDesc[1] = KUsbDescType_Otg;
  1.1629 +		// The next step is likely to reset KUsbOtgAttr_HnpSupp
  1.1630 +		otgDesc[2] = KUsbOtgAttr_SrpSupp;
  1.1631 +		r = gPort.SetOtgDescriptor(otgDesc);
  1.1632 +		test(r == KErrNone);
  1.1633 +		TBuf8<KUsbDescSize_Otg> desc;
  1.1634 +		r = gPort.GetOtgDescriptor(desc);
  1.1635 +		test(r == KErrNone);
  1.1636 +		test(desc.Compare(otgDesc) == 0);
  1.1637 +		}
  1.1638 +
  1.1639 +	// Test get OTG features
  1.1640 +	test.Next(_L("Get OTG Features"));
  1.1641 +	TUint8 features;
  1.1642 +	r = gPort.GetOtgFeatures(features);
  1.1643 +	if (gSupportsOtg)
  1.1644 +		{
  1.1645 +		test(r == KErrNone);
  1.1646 +		TBool b_HnpEnable = (features & KUsbOtgAttr_B_HnpEnable) ? ETrue : EFalse;
  1.1647 +		TBool a_HnpSupport = (features & KUsbOtgAttr_A_HnpSupport) ? ETrue : EFalse;
  1.1648 +		TBool a_AltHnpSupport = (features & KUsbOtgAttr_A_AltHnpSupport) ? ETrue : EFalse;
  1.1649 +		test.Printf(_L("### OTG Features:\nB_HnpEnable(%d)\nA_HnpSupport(%d)\nA_Alt_HnpSupport(%d)\n"),
  1.1650 +					b_HnpEnable, a_HnpSupport, a_AltHnpSupport);
  1.1651 +		}
  1.1652 +	else
  1.1653 +		{
  1.1654 +		test(r == KErrNotSupported);
  1.1655 +		test.Printf(_L("GetOtgFeatures() not supported\n"));
  1.1656 +		}
  1.1657 +
  1.1658 +	test.End();
  1.1659 +}
  1.1660 +
  1.1661 +
  1.1662 +static void TestEndpoint0MaxPacketSizes()
  1.1663 +	{
  1.1664 +	test.Start(_L("Test Endpoint0 MaxPacketSizes"));
  1.1665 +
  1.1666 +	TUint32 sizes = gPort.EndpointZeroMaxPacketSizes();
  1.1667 +	TInt r = KErrNone;
  1.1668 +	TBool good;
  1.1669 +	TInt mpsize = 0;
  1.1670 +	for (TInt i = 0; i < 32; i++)
  1.1671 +		{
  1.1672 +		TUint bit = sizes & (1 << i);
  1.1673 +		if (bit != 0)
  1.1674 +			{
  1.1675 +			switch (bit)
  1.1676 +				{
  1.1677 +			case KUsbEpSizeCont:
  1.1678 +				good = EFalse;
  1.1679 +				break;
  1.1680 +			case KUsbEpSize8:
  1.1681 +				mpsize = 8;
  1.1682 +				good = ETrue;
  1.1683 +				break;
  1.1684 +			case KUsbEpSize16:
  1.1685 +				mpsize = 16;
  1.1686 +				good = ETrue;
  1.1687 +				break;
  1.1688 +			case KUsbEpSize32:
  1.1689 +				mpsize = 32;
  1.1690 +				good = ETrue;
  1.1691 +				break;
  1.1692 +			case KUsbEpSize64:
  1.1693 +				mpsize = 64;
  1.1694 +				good = ETrue;
  1.1695 +				break;
  1.1696 +			case KUsbEpSize128:
  1.1697 +			case KUsbEpSize256:
  1.1698 +			case KUsbEpSize512:
  1.1699 +			case KUsbEpSize1023:
  1.1700 +			default:
  1.1701 +				good = EFalse;
  1.1702 +				break;
  1.1703 +				}
  1.1704 +			if (good)
  1.1705 +				{
  1.1706 +				test.Printf(_L("Ep0 supports %d bytes MaxPacketSize\n"), mpsize);
  1.1707 +				}
  1.1708 +			else
  1.1709 +				{
  1.1710 +				test.Printf(_L("Bad Ep0 size: 0x%08x, failure will occur\n"), bit);
  1.1711 +				r = KErrGeneral;
  1.1712 +				}
  1.1713 +			}
  1.1714 +		}
  1.1715 +	test(r == KErrNone);
  1.1716 +
  1.1717 +    test.End();
  1.1718 +	}
  1.1719 +
  1.1720 +
  1.1721 +static void TestDeviceControl()
  1.1722 +	{
  1.1723 +	test.Start(_L("Test Device Control"));
  1.1724 +
  1.1725 +	// This is a quick and crude test, to make sure that we don't get a steaming heap
  1.1726 +	// as a result of calling the device control API's.
  1.1727 +	test.Next(_L("SetDeviceControl()"));
  1.1728 +	TInt r = gPort.SetDeviceControl();
  1.1729 +	test(r == KErrNone);
  1.1730 +	test.Next(_L("ReleaseDeviceControl()"));
  1.1731 +	r = gPort.ReleaseDeviceControl();
  1.1732 +	test(r == KErrNone);
  1.1733 +
  1.1734 +	test.End();
  1.1735 +	}
  1.1736 +
  1.1737 +
  1.1738 +static void TestAlternateDeviceStatusNotify()
  1.1739 +	{
  1.1740 +	test.Start(_L("Test Alternate Device Status Notification"));
  1.1741 +
  1.1742 +	TRequestStatus dev_status;
  1.1743 +	TUint deviceState = 0xffffffff;						// put in a nonsense value
  1.1744 +	test.Next(_L("AlternateDeviceStatusNotify()"));
  1.1745 +	gPort.AlternateDeviceStatusNotify(dev_status, deviceState);
  1.1746 +	test.Next(_L("AlternateDeviceStatusNotifyCancel()"));
  1.1747 +	gPort.AlternateDeviceStatusNotifyCancel();
  1.1748 +	User::WaitForRequest(dev_status);
  1.1749 +	test(dev_status == KErrCancel || dev_status == KErrNone);
  1.1750 +	if (deviceState & KUsbAlternateSetting)
  1.1751 +		{
  1.1752 +		TUint setting = (deviceState & ~KUsbAlternateSetting);
  1.1753 +		test.Printf(_L("Alternate setting change to setting %d - unexpected"), setting);
  1.1754 +		test(EFalse);
  1.1755 +		}
  1.1756 +	else
  1.1757 +		{
  1.1758 +		switch (deviceState)
  1.1759 +			{
  1.1760 +		case EUsbcDeviceStateUndefined:
  1.1761 +			test.Printf(_L("TestAlternateDeviceStatusNotify: Undefined state\n"));
  1.1762 +			break;
  1.1763 +		case EUsbcDeviceStateAttached:
  1.1764 +			test.Printf(_L("TestAlternateDeviceStatusNotify: Attached state\n"));
  1.1765 +			break;
  1.1766 +		case EUsbcDeviceStatePowered:
  1.1767 +			test.Printf(_L("TestAlternateDeviceStatusNotify: Powered state\n"));
  1.1768 +			break;
  1.1769 +		case EUsbcDeviceStateDefault:
  1.1770 +			test.Printf(_L("TestAlternateDeviceStatusNotify: Default state\n"));
  1.1771 +			break;
  1.1772 +		case EUsbcDeviceStateAddress:
  1.1773 +			test.Printf(_L("TestAlternateDeviceStatusNotify: Address state\n"));
  1.1774 +			break;
  1.1775 +		case EUsbcDeviceStateConfigured:
  1.1776 +			test.Printf(_L("TestAlternateDeviceStatusNotify: Configured state\n"));
  1.1777 +			break;
  1.1778 +		case EUsbcDeviceStateSuspended:
  1.1779 +			test.Printf(_L("TestAlternateDeviceStatusNotify: Suspended state\n"));
  1.1780 +			break;
  1.1781 +		case EUsbcNoState:
  1.1782 +			test.Printf(_L("TestAlternateDeviceStatusNotify: State buffering error\n"));
  1.1783 +			test(EFalse);
  1.1784 +			break;
  1.1785 +		default:
  1.1786 +			test.Printf(_L("TestAlternateDeviceStatusNotify: Unknown state\n"));
  1.1787 +			test(EFalse);
  1.1788 +			}
  1.1789 +		}
  1.1790 +
  1.1791 +	test.End();
  1.1792 +	}
  1.1793 +
  1.1794 +
  1.1795 +static void TestEndpointStatusNotify()
  1.1796 +	{
  1.1797 +	test.Start(_L("Test Endpoint Status Notification"));
  1.1798 +
  1.1799 +	TRequestStatus ep_status;
  1.1800 +	TUint epStateBitmap = 0xffffffff;						// put in a nonsense value
  1.1801 +	test.Next(_L("EndpointStatusNotify()"));
  1.1802 +	gPort.EndpointStatusNotify(ep_status, epStateBitmap);
  1.1803 +	test.Next(_L("EndpointStatusNotifyCancel()"));
  1.1804 +	gPort.EndpointStatusNotifyCancel();
  1.1805 +	User::WaitForRequest(ep_status);
  1.1806 +	test(ep_status.Int() == KErrCancel);
  1.1807 +	test.Next(_L("Check endpoint state bitmap returned"));
  1.1808 +	// Our ifc only uses 2 eps + ep0 is automatically granted:
  1.1809 +	const TUint usedEpBitmap = (1 << EEndpoint0 | 1 << EEndpoint1 | 1 << EEndpoint2);
  1.1810 +	// Must not return info about non existent Eps:
  1.1811 +	test((epStateBitmap & ~usedEpBitmap) == 0);
  1.1812 +	for (TInt i = 0; i <= 2; i++)
  1.1813 +		{
  1.1814 +		if ((epStateBitmap & (1 << i)) == EEndpointStateNotStalled)
  1.1815 +			{
  1.1816 +			test.Printf(_L("EndpointStatusNotify: Ep %d NOT STALLED\n"), i);
  1.1817 +			}
  1.1818 +		else
  1.1819 +			{
  1.1820 +			test.Printf(_L("EndpointStatusNotify: Ep %d STALLED\n"), i);
  1.1821 +			}
  1.1822 +		}
  1.1823 +
  1.1824 +	test.End();
  1.1825 +	}
  1.1826 +
  1.1827 +
  1.1828 +static void TestEndpointStallStatus()
  1.1829 +	{
  1.1830 +	test.Start(_L("Test Endpoint Stall Status"));
  1.1831 +
  1.1832 +	if (!SupportsEndpointStall())
  1.1833 +		{
  1.1834 +		test.Printf(_L("*** Not supported - skipping endpoint stall status tests\n"));
  1.1835 +		test.End();
  1.1836 +		return;
  1.1837 +		}
  1.1838 +
  1.1839 +	test.Next(_L("Endpoint stall status"));
  1.1840 +	TEndpointState epState = EEndpointStateUnknown;
  1.1841 +	QueryEndpointState(EEndpoint1);
  1.1842 +	QueryEndpointState(EEndpoint2);
  1.1843 +
  1.1844 +	test.Next(_L("Stall Ep1"));
  1.1845 +	gPort.HaltEndpoint(EEndpoint1);
  1.1846 +	epState = QueryEndpointState(EEndpoint1);
  1.1847 +	test(epState == EEndpointStateStalled);
  1.1848 +
  1.1849 +	test.Next(_L("Clear Stall Ep1"));
  1.1850 +	gPort.ClearHaltEndpoint(EEndpoint1);
  1.1851 +	epState = QueryEndpointState(EEndpoint1);
  1.1852 +	test(epState == EEndpointStateNotStalled);
  1.1853 +
  1.1854 +	test.Next(_L("Stall Ep2"));
  1.1855 +	gPort.HaltEndpoint(EEndpoint2);
  1.1856 +	epState = QueryEndpointState(EEndpoint2);
  1.1857 +	test(epState == EEndpointStateStalled);
  1.1858 +
  1.1859 +	test.Next(_L("Clear Stall Ep2"));
  1.1860 +	gPort.ClearHaltEndpoint(EEndpoint2);
  1.1861 +	epState = QueryEndpointState(EEndpoint2);
  1.1862 +	test(epState == EEndpointStateNotStalled);
  1.1863 +
  1.1864 +	test.End();
  1.1865 +	}
  1.1866 +
  1.1867 +
  1.1868 +static void CloseChannel()
  1.1869 +	{
  1.1870 +	test.Start(_L("Close Channel"));
  1.1871 +
  1.1872 +	test.Next(_L("Disconnect Device from Host"));
  1.1873 +	TInt r = gPort.DeviceDisconnectFromHost();
  1.1874 +	test(r != KErrGeneral);
  1.1875 +
  1.1876 +	if (gSupportsOtg)
  1.1877 +		{
  1.1878 +		test.Next(_L("Stop OTG stack"));
  1.1879 +		gOTG.StopStacks();
  1.1880 +		test.Next(_L("Close OTG Channel"));
  1.1881 +		gOTG.Close();
  1.1882 +		test.Next(_L("Free OTG LDD"));
  1.1883 +		r = User::FreeLogicalDevice(RUsbOtgDriver::Name());
  1.1884 +		test(r == KErrNone);
  1.1885 +		}
  1.1886 +
  1.1887 +	test.Next(_L("Close USB Channel"));
  1.1888 +	gPort.Close();
  1.1889 +	test.Next(_L("Free USB LDD"));
  1.1890 +	r = User::FreeLogicalDevice(KUsbDeviceName);
  1.1891 +	test(r == KErrNone);
  1.1892 +
  1.1893 +	test.End();
  1.1894 +	}
  1.1895 +
  1.1896 +
  1.1897 +static const TInt KPrologue = 0;
  1.1898 +static const TInt KMain     = 1;
  1.1899 +static const TInt KEpilogue = 2;
  1.1900 +
  1.1901 +static TInt RunTests(void* /*aArg*/)
  1.1902 +	{
  1.1903 +	static TInt step = KPrologue;
  1.1904 +	static TReal loops = 0;
  1.1905 +
  1.1906 +	switch (step)
  1.1907 +		{
  1.1908 +	case KPrologue:
  1.1909 +		test.Title();
  1.1910 +		// outermost test begin
  1.1911 +		test.Start(_L("Test of USB APIs not requiring a host connection\n"));
  1.1912 +		if (SupportsUsb())
  1.1913 +			{
  1.1914 +			step = KMain;
  1.1915 +			}
  1.1916 +		else
  1.1917 +			{
  1.1918 +			step = KEpilogue;
  1.1919 +			test.Printf(_L("*** Test platform does not support USB - skipping all tests\n"));
  1.1920 +			}
  1.1921 +		return ETrue;
  1.1922 +	case KMain:
  1.1923 +		OpenChannel();
  1.1924 +		SetupInterface();
  1.1925 +		TestDescriptorManipulation();
  1.1926 +		TestOtgExtensions();
  1.1927 +		TestEndpoint0MaxPacketSizes();
  1.1928 +		TestDeviceControl();
  1.1929 +		TestAlternateDeviceStatusNotify();
  1.1930 +		TestEndpointStatusNotify();
  1.1931 +		TestEndpointStallStatus();
  1.1932 +		CloseChannel();
  1.1933 +		loops++;
  1.1934 +		if (gSoak && (gKeychar != EKeyEscape))
  1.1935 +			{
  1.1936 +			step = KMain;
  1.1937 +			}
  1.1938 +		else
  1.1939 +			{
  1.1940 +			step = KEpilogue;
  1.1941 +			}
  1.1942 +		return ETrue;
  1.1943 +	case KEpilogue:
  1.1944 +		test.Printf(_L("USBAPI tests were run %.0f time(s)\n"), loops);
  1.1945 +		// outermost test end
  1.1946 +		test.End();
  1.1947 +		CActiveScheduler::Stop();
  1.1948 +		return EFalse;
  1.1949 +		}
  1.1950 +	return EFalse;
  1.1951 +	}
  1.1952 +
  1.1953 +
  1.1954 +static void RunAppL()
  1.1955 +	{
  1.1956 +	// Create the active scheduler
  1.1957 +	CActiveScheduler* scheduler = new (ELeave) CActiveScheduler();
  1.1958 +	// Push active scheduler onto the cleanup stack
  1.1959 +	CleanupStack::PushL(scheduler);
  1.1960 +	// Install as the active scheduler
  1.1961 +	CActiveScheduler::Install(scheduler);
  1.1962 +
  1.1963 +	// Create console handler
  1.1964 +	CConsoleBase* console =
  1.1965 +		Console::NewL(_L("T_USBAPI - USB Client Test Program"), TSize(KConsFullScreen, KConsFullScreen));
  1.1966 +	CleanupStack::PushL(console);
  1.1967 +	// Make this one also RTest's console
  1.1968 +	test.SetConsole(console);
  1.1969 +
  1.1970 +	// Create keypress notifier active object
  1.1971 +	CActiveKeypressNotifier* keypress_notifier = CActiveKeypressNotifier::NewL(console);
  1.1972 +	test(keypress_notifier != NULL);
  1.1973 +	CleanupStack::PushL(keypress_notifier);
  1.1974 +	keypress_notifier->RequestCharacter();
  1.1975 +
  1.1976 +	// Create long-running test task active object
  1.1977 +	CIdle* active_test = CIdle::NewL(CActive::EPriorityIdle);
  1.1978 +	test(active_test != NULL);
  1.1979 +	CleanupStack::PushL(active_test);
  1.1980 +	active_test->Start(TCallBack(RunTests));
  1.1981 +
  1.1982 +	// Start active scheduler
  1.1983 +	CActiveScheduler::Start();
  1.1984 +
  1.1985 +	// Suspend thread for a short while
  1.1986 +	User::After(1000000);
  1.1987 +
  1.1988 +	// active_test, keypress_notifier, console, scheduler
  1.1989 +	CleanupStack::PopAndDestroy(4);
  1.1990 +
  1.1991 +	return;
  1.1992 +	}
  1.1993 +
  1.1994 +
  1.1995 +GLDEF_C TInt E32Main()
  1.1996 +	{
  1.1997 +
  1.1998 +	CTrapCleanup* cleanup = CTrapCleanup::New();			// get clean-up stack
  1.1999 +
  1.2000 +	__UHEAP_MARK;
  1.2001 +
  1.2002 +	_LIT(KArg, "soak");
  1.2003 +	TBuf<64> c;
  1.2004 +	User::CommandLine(c);
  1.2005 +	if (c.CompareF(KArg) == 0)
  1.2006 +		gSoak = ETrue;
  1.2007 +	else
  1.2008 +		gSoak = EFalse;
  1.2009 +	TRAPD(r, RunAppL());
  1.2010 +	__ASSERT_ALWAYS(!r, User::Panic(_L("E32EX"), r));
  1.2011 +
  1.2012 +	__UHEAP_MARKEND;
  1.2013 +
  1.2014 +	delete cleanup;											// destroy clean-up stack
  1.2015 +	return KErrNone;
  1.2016 +	}