--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/kerneltest/e32test/usb/t_usb_device/src/apitests.cpp Mon Oct 19 15:55:17 2009 +0100
@@ -0,0 +1,1005 @@
+// Copyright (c) 2000-2009 Nokia Corporation and/or its subsidiary(-ies).
+// All rights reserved.
+// This component and the accompanying materials are made available
+// under the terms of the License "Eclipse Public License v1.0"
+// which accompanies this distribution, and is available
+// at the URL "http://www.eclipse.org/legal/epl-v10.html".
+//
+// Initial Contributors:
+// Nokia Corporation - initial contribution.
+//
+// Contributors:
+//
+// Description:
+// e32test/usb/t_usb_device/src/apitests.cpp
+// USB Test Program T_USB_DEVICE, functional part.
+// Device-side part, to work against T_USB_HOST running on the host.
+//
+//
+
+#include "general.h" // CActiveControl, CActiveRW
+#include "config.h"
+#include "usblib.h" // Helpers
+
+extern RTest test;
+extern TBool gVerbose;
+extern TBool gSkip;
+extern TBool gTempTest;
+
+_LIT16(KString_one, "Arbitrary String Descriptor Test String 1");
+_LIT16(KString_two, "Another Arbitrary String Descriptor Test String");
+
+void SetupDescriptors(LDDConfigPtr aLddPtr,RDEVCLIENT* aPort, TUint16 aPid = 0)
+ {
+ // === Device Descriptor
+ test.Start(_L("Set up descriptors"));
+
+ test.Next(_L("GetDeviceDescriptorSize"));
+ TInt deviceDescriptorSize = 0;
+ aPort->GetDeviceDescriptorSize(deviceDescriptorSize);
+ test_Equal(KUsbDescSize_Device,static_cast<TUint>(deviceDescriptorSize));
+
+ test.Next(_L("GetDeviceDescriptor"));
+ TBuf8<KUsbDescSize_Device> deviceDescriptor;
+ TInt r = aPort->GetDeviceDescriptor(deviceDescriptor);
+ test_KErrNone(r);
+
+ test.Next(_L("SetDeviceDescriptor"));
+ const TInt KUsbSpecOffset = 2;
+ const TInt KUsbDevClass = 4;
+ const TInt KUsbDevSubClass = 5;
+ const TInt KUsbDevProtocol = 6;
+ const TInt KUsbVendorIdOffset = 8;
+ const TInt KUsbProductIdOffset = 10;
+ const TInt KUsbDevReleaseOffset = 12;
+ // Change the USB spec number
+ deviceDescriptor[KUsbSpecOffset] = LoByte(aLddPtr->iSpec);
+ deviceDescriptor[KUsbSpecOffset+1] = HiByte(aLddPtr->iSpec);
+ // Change the Device Class, SubClass and Protocol to zero so that they are not device specific
+ // and diferent clases can used on different interfaces
+ deviceDescriptor[KUsbDevClass] = 0;
+ deviceDescriptor[KUsbDevSubClass] = 0;
+ deviceDescriptor[KUsbDevProtocol] = 0;
+ // Change the device vendor ID (VID)
+ deviceDescriptor[KUsbVendorIdOffset] = LoByte(aLddPtr->iVid); // little endian!
+ deviceDescriptor[KUsbVendorIdOffset+1] = HiByte(aLddPtr->iVid);
+ // Change the device product ID (PID)
+ if (aPid != 0)
+ {
+ deviceDescriptor[KUsbProductIdOffset] = LoByte(aPid); // little endian!
+ deviceDescriptor[KUsbProductIdOffset+1] = HiByte(aPid);
+ }
+ else
+ {
+ deviceDescriptor[KUsbProductIdOffset] = LoByte(aLddPtr->iPid); // little endian!
+ deviceDescriptor[KUsbProductIdOffset+1] = HiByte(aLddPtr->iPid);
+ }
+ // Change the device release number
+ deviceDescriptor[KUsbDevReleaseOffset] = LoByte(aLddPtr->iRelease); // little endian!
+ deviceDescriptor[KUsbDevReleaseOffset+1] = HiByte(aLddPtr->iRelease);
+ r = aPort->SetDeviceDescriptor(deviceDescriptor);
+ test_KErrNone(r);
+
+ if (!gSkip)
+ {
+ test.Next(_L("GetDeviceDescriptor()"));
+ TBuf8<KUsbDescSize_Device> descriptor2;
+ r = aPort->GetDeviceDescriptor(descriptor2);
+ test_KErrNone(r);
+
+ test.Next(_L("Compare device descriptor with value set"));
+ r = descriptor2.Compare(deviceDescriptor);
+ test_KErrNone(r);
+ }
+
+ // === Configuration Descriptor
+
+ test.Next(_L("GetConfigurationDescriptorSize"));
+ TInt configDescriptorSize = 0;
+ aPort->GetConfigurationDescriptorSize(configDescriptorSize);
+ test_Equal(KUsbDescSize_Config,static_cast<TUint>(configDescriptorSize));
+
+ test.Next(_L("GetConfigurationDescriptor"));
+ TBuf8<KUsbDescSize_Config> configDescriptor;
+ r = aPort->GetConfigurationDescriptor(configDescriptor);
+ test_KErrNone(r);
+
+ test.Next(_L("SetConfigurationDescriptor"));
+ // Change Self Power and Remote Wakeup
+ const TInt KUsbAttributesOffset = 7;
+ const TUint8 KUsbAttributeDefault = 0x80;
+ const TUint8 KUsbAttributeSelfPower = 0x40;
+ const TUint8 KUsbAttributeRemoteWakeup = 0x20;
+ configDescriptor[KUsbAttributesOffset] = KUsbAttributeDefault | (aLddPtr->iSelfPower ? KUsbAttributeSelfPower : 0)
+ | (aLddPtr->iRemoteWakeup ? KUsbAttributeRemoteWakeup : 0);
+ // Change the reported max power
+ // 100mA (= 2 * 0x32) is the highest value allowed for a bus-powered device.
+ const TInt KUsbMaxPowerOffset = 8;
+ configDescriptor[KUsbMaxPowerOffset] = aLddPtr->iMaxPower;
+ r = aPort->SetConfigurationDescriptor(configDescriptor);
+ test_KErrNone(r);
+
+ if (!gSkip)
+ {
+ test.Next(_L("GetConfigurationDescriptor()"));
+ TBuf8<KUsbDescSize_Config> descriptor2;
+ r = aPort->GetConfigurationDescriptor(descriptor2);
+ test_KErrNone(r);
+
+ test.Next(_L("Compare configuration desc with value set"));
+ r = descriptor2.Compare(configDescriptor);
+ test_KErrNone(r);
+ }
+
+ // === String Descriptors
+
+ test.Next(_L("SetStringDescriptor"));
+
+ // Set up any standard string descriptors that were defined in the xml config
+ if (aLddPtr->iManufacturer)
+ {
+ r = aPort->SetManufacturerStringDescriptor(* aLddPtr->iManufacturer);
+ test_KErrNone(r);
+ }
+
+ if (aLddPtr->iProduct)
+ {
+ r = aPort->SetProductStringDescriptor(* aLddPtr->iProduct);
+ test_KErrNone(r);
+ }
+
+ if (aLddPtr->iSerialNumber)
+ {
+ r = aPort->SetSerialNumberStringDescriptor(* aLddPtr->iSerialNumber);
+ test_KErrNone(r);
+ }
+
+ // Set up two arbitrary string descriptors, which can be queried
+ // manually from the host side for testing purposes
+
+ TBuf16<KUsbStringDescStringMaxSize / 2> wr_str(KString_one);
+ r = aPort->SetStringDescriptor(stridx1, wr_str);
+ test_KErrNone(r);
+
+ wr_str.FillZ(wr_str.MaxLength());
+ wr_str = KString_two;
+ r = aPort->SetStringDescriptor(stridx2, wr_str);
+ test_KErrNone(r);
+
+ test.End();
+
+ }
+
+static void TestDeviceQualifierDescriptor(RDEVCLIENT* aPort)
+ {
+ test.Start(_L("Device_Qualifier Descriptor Manipulation"));
+
+ test.Next(_L("GetDeviceQualifierDescriptor()"));
+ TBuf8<KUsbDescSize_DeviceQualifier> descriptor;
+ TInt r = aPort->GetDeviceQualifierDescriptor(descriptor);
+ test_KErrNone(r);
+
+ test.Next(_L("SetDeviceQualifierDescriptor()"));
+ // Change the USB spec number to 3.00
+ descriptor[KDevDesc_SpecOffset] = 0x00;
+ descriptor[KDevDesc_SpecOffset+1] = 0x03;
+ // Change the device class, subclass and protocol codes
+ descriptor[KDevDesc_DevClassOffset] = 0xA1;
+ descriptor[KDevDesc_DevSubClassOffset] = 0xB2;
+ descriptor[KDevDesc_DevProtocolOffset] = 0xC3;
+ r = aPort->SetDeviceQualifierDescriptor(descriptor);
+ test_KErrNone(r);
+
+ test.Next(_L("GetDeviceQualifierDescriptor()"));
+ TBuf8<KUsbDescSize_DeviceQualifier> descriptor2;
+ r = aPort->GetDeviceQualifierDescriptor(descriptor2);
+ test_KErrNone(r);
+
+ test.Next(_L("Compare Device_Qualifier desc with value set"));
+ r = descriptor2.Compare(descriptor);
+ test_Equal(0,r);
+
+ test.End();
+ }
+
+
+
+static void TestOtherSpeedConfigurationDescriptor(RDEVCLIENT* aPort)
+ {
+ test.Start(_L("Other_Speed_Configuration Desc Manipulation"));
+
+ test.Next(_L("GetOtherSpeedConfigurationDescriptor()"));
+ TBuf8<KUsbDescSize_OtherSpeedConfig> descriptor;
+ TInt r = aPort->GetOtherSpeedConfigurationDescriptor(descriptor);
+ test_KErrNone(r);
+
+ test.Next(_L("SetOtherSpeedConfigurationDescriptor()"));
+ // Invert Remote-Wakup support
+ descriptor[KConfDesc_AttribOffset] = (descriptor[KConfDesc_AttribOffset] ^ KUsbDevAttr_RemoteWakeup);
+ // Change the reported max power to 330mA (2 * 0xA5)
+ descriptor[KConfDesc_MaxPowerOffset] = 0xA5;
+ r = aPort->SetOtherSpeedConfigurationDescriptor(descriptor);
+ test_KErrNone(r);
+
+ test.Next(_L("GetOtherSpeedConfigurationDescriptor()"));
+ TBuf8<KUsbDescSize_OtherSpeedConfig> descriptor2;
+ r = aPort->GetOtherSpeedConfigurationDescriptor(descriptor2);
+ test_KErrNone(r);
+
+ test.Next(_L("Compare O_S_Config desc with value set"));
+ r = descriptor2.Compare(descriptor);
+ test_KErrNone(r);
+
+ test.End();
+ }
+
+
+static void TestInterfaceDescriptor(RDEVCLIENT* aPort, TInt aNumSettings)
+ {
+ test.Start(_L("Interface Descriptor Manipulation"));
+
+ // For all settings
+
+ TInt desc_size = 0;
+ TInt r = 0;
+ TBuf8<KUsbDescSize_Interface> descriptor;
+ TBuf8<KUsbDescSize_Interface> descriptor2;
+ for (TInt i =0; i < aNumSettings; i++)
+ {
+
+ test.Next(_L("GetInterfaceDescriptorSize()"));
+ r = aPort->GetInterfaceDescriptorSize(i, desc_size);
+ if (r != KErrNone)
+ {
+ RDebug::Printf ("Error %d in GetInterfaceDescriptorSize %d\n",r,i);
+ }
+ test_KErrNone(r);
+ test_Equal(KUsbDescSize_Interface,static_cast<TUint>(desc_size));
+
+ test.Next(_L("GetInterfaceDescriptor()"));
+ r = aPort->GetInterfaceDescriptor(i, descriptor);
+ test_KErrNone(r);
+
+ test.Next(_L("SetInterfaceDescriptor()"));
+ // Change the interface protocol to 0x78(+)
+ TUint8 prot = 0x78;
+ if (descriptor[KIfcDesc_ProtocolOffset] == prot)
+ prot++;
+ descriptor[KIfcDesc_ProtocolOffset] = prot;
+ r = aPort->SetInterfaceDescriptor(i, descriptor);
+ test_KErrNone(r);
+
+ test.Next(_L("GetInterfaceDescriptor()"));
+ r = aPort->GetInterfaceDescriptor(i, descriptor2);
+ test_KErrNone(r);
+
+ test.Next(_L("Compare interface descriptor with value set"));
+ r = descriptor2.Compare(descriptor);
+ test_KErrNone(r);
+ }
+
+ test.Next(_L("GetInterfaceDescriptor()"));
+ r = aPort->GetInterfaceDescriptor(aNumSettings, descriptor);
+ test_Equal(KErrNotFound,r);
+
+ test.Next(_L("SetInterfaceDescriptor()"));
+ r = aPort->SetInterfaceDescriptor(aNumSettings, descriptor);
+ test_Equal(KErrNotFound,r);
+
+ test.End();
+ }
+
+
+static void TestClassSpecificDescriptors(RDEVCLIENT* aPort)
+ {
+ test.Start(_L("Class-specific Descriptor Manipulation"));
+
+ // First a class-specific Interface descriptor
+
+ test.Next(_L("SetCSInterfaceDescriptorBlock()"));
+ // choose arbitrary new descriptor size
+ const TInt KUsbDescSize_CS_Interface = KUsbDescSize_Interface + 10;
+ TBuf8<KUsbDescSize_CS_Interface> cs_ifc_descriptor;
+ cs_ifc_descriptor.FillZ(cs_ifc_descriptor.MaxLength());
+ cs_ifc_descriptor[KUsbDesc_SizeOffset] = KUsbDescSize_CS_Interface;
+ cs_ifc_descriptor[KUsbDesc_TypeOffset] = KUsbDescType_CS_Interface;
+ TInt r = aPort->SetCSInterfaceDescriptorBlock(0, cs_ifc_descriptor);
+ test_KErrNone(r);
+
+ test.Next(_L("GetCSInterfaceDescriptorBlockSize()"));
+ TInt desc_size = 0;
+ r = aPort->GetCSInterfaceDescriptorBlockSize(0, desc_size);
+ test_KErrNone(r);
+ test_Equal(KUsbDescSize_CS_Interface,desc_size);
+
+ test.Next(_L("GetCSInterfaceDescriptorBlock()"));
+ TBuf8<KUsbDescSize_CS_Interface> descriptor;
+ r = aPort->GetCSInterfaceDescriptorBlock(0, descriptor);
+ test_KErrNone(r);
+
+ test.Next(_L("Compare CS ifc descriptor with value set"));
+ r = descriptor.Compare(cs_ifc_descriptor);
+ test_KErrNone(r);
+
+ // Next a class-specific Endpoint descriptor
+
+ test.Next(_L("SetCSEndpointDescriptorBlock()"));
+ // choose arbitrary new descriptor size
+ const TInt KUsbDescSize_CS_Endpoint = KUsbDescSize_Endpoint + 5;
+ TBuf8<KUsbDescSize_CS_Endpoint> cs_ep_descriptor;
+ cs_ep_descriptor.FillZ(cs_ep_descriptor.MaxLength());
+ cs_ep_descriptor[KUsbDesc_SizeOffset] = KUsbDescSize_CS_Endpoint;
+ cs_ep_descriptor[KUsbDesc_TypeOffset] = KUsbDescType_CS_Endpoint;
+ r = aPort->SetCSEndpointDescriptorBlock(0, 2, cs_ep_descriptor);
+ test_KErrNone(r);
+
+ test.Next(_L("GetCSEndpointDescriptorBlockSize()"));
+ r = aPort->GetCSEndpointDescriptorBlockSize(0, 2, desc_size);
+ test_KErrNone(r);
+ test_Equal(KUsbDescSize_CS_Endpoint,desc_size);
+
+ test.Next(_L("GetCSEndpointDescriptorBlock()"));
+ TBuf8<KUsbDescSize_CS_Endpoint> descriptor2;
+ r = aPort->GetCSEndpointDescriptorBlock(0, 2, descriptor2);
+ test_KErrNone(r);
+
+ test.Next(_L("Compare CS ep descriptor with value set"));
+ r = descriptor2.Compare(cs_ep_descriptor);
+ test_KErrNone(r);
+
+ test.End();
+ }
+
+
+void TestEndpointDescriptor(RDEVCLIENT* aPort,TInt aIfSetting, TInt aEpNumber,TUsbcEndpointInfo aEpInfo)
+ {
+ test.Start(_L("Endpoint Descriptor Manipulation"));
+
+ TBuf8<KUsbDescSize_AudioEndpoint> epDescriptor;
+ TInt desc_size;
+ TInt r = aPort->GetEndpointDescriptorSize(aIfSetting, aEpNumber, desc_size);
+ test_KErrNone(r);
+ test_Equal(KUsbDescSize_Endpoint + aEpInfo.iExtra,static_cast<TUint>(desc_size));
+
+ r = aPort->GetEndpointDescriptor(aIfSetting, aEpNumber, epDescriptor);
+ test_KErrNone(r);
+
+ test(((aEpInfo.iDir & KUsbEpDirIn) && (epDescriptor[KEpDesc_AddressOffset] & 0x80) ||
+ !(aEpInfo.iDir & KUsbEpDirIn) && !(epDescriptor[KEpDesc_AddressOffset] & 0x80)) &&
+ EpTypeMask2Value(aEpInfo.iType) == (TUint)(epDescriptor[KEpDesc_AttributesOffset] & 0x03) &&
+ aEpInfo.iInterval == epDescriptor[KEpDesc_IntervalOffset]);
+
+ // Change the endpoint poll interval
+ TUint8 ival = 0x66;
+ if (epDescriptor[KEpDesc_IntervalOffset] == ival)
+ ival++;
+
+
+ TUint8 saveAddr = 0; // save the address
+ if (aEpInfo.iExtra > 0)
+ {
+ saveAddr = epDescriptor[KEpDesc_SynchAddressOffset];
+ TUint8 addr = 0x85; // bogus address
+ if (epDescriptor[KEpDesc_SynchAddressOffset] == addr)
+ addr++;
+ epDescriptor[KEpDesc_SynchAddressOffset] = addr;
+ }
+
+ epDescriptor[KEpDesc_IntervalOffset] = ival;
+ r = aPort->SetEndpointDescriptor(aIfSetting, aEpNumber, epDescriptor);
+ test_KErrNone(r);
+
+ TBuf8<KUsbDescSize_AudioEndpoint> descriptor2;
+ r = aPort->GetEndpointDescriptor(aIfSetting, aEpNumber, descriptor2);
+ test_KErrNone(r);
+
+ r = descriptor2.Compare(epDescriptor);
+ test_KErrNone(r);
+
+ if (aEpInfo.iExtra > 0)
+ {
+ // Restore the endpoint synch address
+ epDescriptor[KEpDesc_SynchAddressOffset] = saveAddr;
+ }
+
+ // Restore the endpoint poll interval
+ epDescriptor[KEpDesc_IntervalOffset] = aEpInfo.iInterval;
+ r = aPort->SetEndpointDescriptor(aIfSetting, aEpNumber, epDescriptor);
+ test_KErrNone(r);
+
+ test.End();
+ }
+
+static void TestStandardStringDescriptors(RDEVCLIENT* aPort)
+ {
+ test.Start(_L("String Descriptor Manipulation"));
+
+ //
+ // --- LANGID code
+ //
+
+ test.Next(_L("GetStringDescriptorLangId()"));
+ TUint16 rd_langid_orig;
+ TInt r = aPort->GetStringDescriptorLangId(rd_langid_orig);
+ test_KErrNone(r);
+ test.Printf(_L("Original LANGID code: 0x%04X\n"), rd_langid_orig);
+
+ test.Next(_L("SetStringDescriptorLangId()"));
+ TUint16 wr_langid = 0x0809; // English (UK) Language ID
+ if (wr_langid == rd_langid_orig)
+ wr_langid = 0x0444; // Tatar Language ID
+ r = aPort->SetStringDescriptorLangId(wr_langid);
+ test_KErrNone(r);
+
+ test.Next(_L("GetStringDescriptorLangId()"));
+ TUint16 rd_langid;
+ r = aPort->GetStringDescriptorLangId(rd_langid);
+ test_KErrNone(r);
+ test.Printf(_L("New LANGID code: 0x%04X\n"), rd_langid);
+
+ test.Next(_L("Compare LANGID codes"));
+ test_Equal(wr_langid,rd_langid);
+
+ test.Next(_L("Restore original LANGID code"));
+ r = aPort->SetStringDescriptorLangId(rd_langid_orig);
+ test_KErrNone(r);
+ r = aPort->GetStringDescriptorLangId(rd_langid);
+ test_KErrNone(r);
+ test_Equal(rd_langid_orig,rd_langid);
+
+ //
+ // --- Manufacturer string
+ //
+
+ test.Next(_L("GetManufacturerStringDescriptor()"));
+ TBuf16<KUsbStringDescStringMaxSize / 2> rd_str_orig;
+ r = aPort->GetManufacturerStringDescriptor(rd_str_orig);
+ test(r == KErrNone || r == KErrNotFound);
+ TBool restore_string;
+ if (r == KErrNone)
+ {
+ test.Printf(_L("Original Manufacturer string: \"%lS\"\n"), &rd_str_orig);
+ restore_string = ETrue;
+ }
+ else
+ {
+ test.Printf(_L("No Manufacturer string set\n"));
+ restore_string = EFalse;
+ }
+
+ test.Next(_L("SetManufacturerStringDescriptor()"));
+ _LIT16(manufacturer, "Manufacturer Which Manufactures Devices");
+ TBuf16<KUsbStringDescStringMaxSize / 2> wr_str(manufacturer);
+ r = aPort->SetManufacturerStringDescriptor(wr_str);
+ test_KErrNone(r);
+
+ test.Next(_L("GetManufacturerStringDescriptor()"));
+ TBuf16<KUsbStringDescStringMaxSize / 2> rd_str;
+ r = aPort->GetManufacturerStringDescriptor(rd_str);
+ test_KErrNone(r);
+ test.Printf(_L("New Manufacturer string: \"%lS\"\n"), &rd_str);
+
+ test.Next(_L("Compare Manufacturer strings"));
+ r = rd_str.Compare(wr_str);
+ test_KErrNone(r);
+
+ test.Next(_L("SetManufacturerStringDescriptor()"));
+ _LIT16(manufacturer2, "Different Manufacturer Which Manufactures Different Devices");
+ wr_str.FillZ(wr_str.MaxLength());
+ wr_str = manufacturer2;
+ r = aPort->SetManufacturerStringDescriptor(wr_str);
+ test_KErrNone(r);
+
+ test.Next(_L("GetManufacturerStringDescriptor()"));
+ rd_str.FillZ(rd_str.MaxLength());
+ r = aPort->GetManufacturerStringDescriptor(rd_str);
+ test_KErrNone(r);
+ test.Printf(_L("New Manufacturer string: \"%lS\"\n"), &rd_str);
+
+ test.Next(_L("Compare Manufacturer strings"));
+ r = rd_str.Compare(wr_str);
+ test_KErrNone(r);
+
+ test.Next(_L("RemoveManufacturerStringDescriptor()"));
+ r = aPort->RemoveManufacturerStringDescriptor();
+ test_KErrNone(r);
+ r = aPort->GetManufacturerStringDescriptor(rd_str);
+ test_Equal(KErrNotFound,r);
+
+ if (restore_string)
+ {
+ test.Next(_L("Restore original string"));
+ r = aPort->SetManufacturerStringDescriptor(rd_str_orig);
+ test_KErrNone(r);
+ r = aPort->GetManufacturerStringDescriptor(rd_str);
+ test_KErrNone(r);
+ r = rd_str.Compare(rd_str_orig);
+ test_KErrNone(r);
+ }
+
+ //
+ // --- Product string
+ //
+
+ test.Next(_L("GetProductStringDescriptor()"));
+ rd_str_orig.FillZ(rd_str.MaxLength());
+ r = aPort->GetProductStringDescriptor(rd_str_orig);
+ test(r == KErrNone || r == KErrNotFound);
+ if (r == KErrNone)
+ {
+ test.Printf(_L("Old Product string: \"%lS\"\n"), &rd_str_orig);
+ restore_string = ETrue;
+ }
+ else
+ restore_string = EFalse;
+
+ test.Next(_L("SetProductStringDescriptor()"));
+ _LIT16(product, "Product That Was Produced By A Manufacturer");
+ wr_str.FillZ(wr_str.MaxLength());
+ wr_str = product;
+ r = aPort->SetProductStringDescriptor(wr_str);
+ test_KErrNone(r);
+
+ test.Next(_L("GetProductStringDescriptor()"));
+ rd_str.FillZ(rd_str.MaxLength());
+ r = aPort->GetProductStringDescriptor(rd_str);
+ test_KErrNone(r);
+ test.Printf(_L("New Product string: \"%lS\"\n"), &rd_str);
+
+ test.Next(_L("Compare Product strings"));
+ r = rd_str.Compare(wr_str);
+ test_KErrNone(r);
+
+ test.Next(_L("SetProductStringDescriptor()"));
+ _LIT16(product2, "Different Product That Was Produced By A Different Manufacturer");
+ wr_str.FillZ(wr_str.MaxLength());
+ wr_str = product2;
+ r = aPort->SetProductStringDescriptor(wr_str);
+ test_KErrNone(r);
+
+ test.Next(_L("GetProductStringDescriptor()"));
+ rd_str.FillZ(rd_str.MaxLength());
+ r = aPort->GetProductStringDescriptor(rd_str);
+ test_KErrNone(r);
+ test.Printf(_L("New Product string: \"%lS\"\n"), &rd_str);
+
+ test.Next(_L("Compare Product strings"));
+ r = rd_str.Compare(wr_str);
+ test_KErrNone(r);
+
+ test.Next(_L("RemoveProductStringDescriptor()"));
+ r = aPort->RemoveProductStringDescriptor();
+ test_KErrNone(r);
+ r = aPort->GetProductStringDescriptor(rd_str);
+ test_Equal(KErrNotFound,r);
+
+ if (restore_string)
+ {
+ test.Next(_L("Restore original string"));
+ r = aPort->SetProductStringDescriptor(rd_str_orig);
+ test_KErrNone(r);
+ r = aPort->GetProductStringDescriptor(rd_str);
+ test_KErrNone(r);
+ r = rd_str.Compare(rd_str_orig);
+ test_KErrNone(r);
+ }
+
+ //
+ // --- Serial Number string
+ //
+
+ test.Next(_L("GetSerialNumberStringDescriptor()"));
+ rd_str_orig.FillZ(rd_str.MaxLength());
+ r = aPort->GetSerialNumberStringDescriptor(rd_str_orig);
+ test(r == KErrNone || r == KErrNotFound);
+ if (r == KErrNone)
+ {
+ test.Printf(_L("Old Serial Number: \"%lS\"\n"), &rd_str_orig);
+ restore_string = ETrue;
+ }
+ else
+ restore_string = EFalse;
+
+ test.Next(_L("SetSerialNumberStringDescriptor()"));
+ _LIT16(serial, "000666000XYZ");
+ wr_str.FillZ(wr_str.MaxLength());
+ wr_str = serial;
+ r = aPort->SetSerialNumberStringDescriptor(wr_str);
+ test_KErrNone(r);
+
+ test.Next(_L("GetSerialNumberStringDescriptor()"));
+ rd_str.FillZ(rd_str.MaxLength());
+ r = aPort->GetSerialNumberStringDescriptor(rd_str);
+ test_KErrNone(r);
+ test.Printf(_L("New Serial Number: \"%lS\"\n"), &rd_str);
+
+ test.Next(_L("Compare Serial Number strings"));
+ r = rd_str.Compare(wr_str);
+ test_KErrNone(r);
+
+ test.Next(_L("SetSerialNumberStringDescriptor()"));
+ _LIT16(serial2, "Y11611193111711111Y");
+ wr_str.FillZ(wr_str.MaxLength());
+ wr_str = serial2;
+ r = aPort->SetSerialNumberStringDescriptor(wr_str);
+ test_KErrNone(r);
+
+ test.Next(_L("GetSerialNumberStringDescriptor()"));
+ rd_str.FillZ(rd_str.MaxLength());
+ r = aPort->GetSerialNumberStringDescriptor(rd_str);
+ test_KErrNone(r);
+ test.Printf(_L("New Serial Number: \"%lS\"\n"), &rd_str);
+
+ test.Next(_L("Compare Serial Number strings"));
+ r = rd_str.Compare(wr_str);
+ test_KErrNone(r);
+
+ test.Next(_L("RemoveSerialNumberStringDescriptor()"));
+ r = aPort->RemoveSerialNumberStringDescriptor();
+ test_KErrNone(r);
+ r = aPort->GetSerialNumberStringDescriptor(rd_str);
+ test_Equal(KErrNotFound,r);
+
+ if (restore_string)
+ {
+ test.Next(_L("Restore original string"));
+ r = aPort->SetSerialNumberStringDescriptor(rd_str_orig);
+ test_KErrNone(r);
+ r = aPort->GetSerialNumberStringDescriptor(rd_str);
+ test_KErrNone(r);
+ r = rd_str.Compare(rd_str_orig);
+ test_KErrNone(r);
+ }
+
+ //
+ // --- Configuration string
+ //
+
+ test.Next(_L("GetConfigurationStringDescriptor()"));
+ rd_str_orig.FillZ(rd_str.MaxLength());
+ r = aPort->GetConfigurationStringDescriptor(rd_str_orig);
+ test(r == KErrNone || r == KErrNotFound);
+ if (r == KErrNone)
+ {
+ test.Printf(_L("Old Configuration string: \"%lS\"\n"), &rd_str_orig);
+ restore_string = ETrue;
+ }
+ else
+ restore_string = EFalse;
+
+ test.Next(_L("SetConfigurationStringDescriptor()"));
+ _LIT16(config, "Relatively Simple Configuration That Is Still Useful");
+ wr_str.FillZ(wr_str.MaxLength());
+ wr_str = config;
+ r = aPort->SetConfigurationStringDescriptor(wr_str);
+ test_KErrNone(r);
+
+ test.Next(_L("GetConfigurationStringDescriptor()"));
+ rd_str.FillZ(rd_str.MaxLength());
+ r = aPort->GetConfigurationStringDescriptor(rd_str);
+ test_KErrNone(r);
+ test.Printf(_L("New Configuration string: \"%lS\"\n"), &rd_str);
+
+ test.Next(_L("Compare Configuration strings"));
+ r = rd_str.Compare(wr_str);
+ test_KErrNone(r);
+
+ test.Next(_L("SetConfigurationStringDescriptor()"));
+ _LIT16(config2, "Convenient Configuration That Can Be Very Confusing");
+ wr_str.FillZ(wr_str.MaxLength());
+ wr_str = config2;
+ r = aPort->SetConfigurationStringDescriptor(wr_str);
+ test_KErrNone(r);
+
+ test.Next(_L("GetConfigurationStringDescriptor()"));
+ rd_str.FillZ(rd_str.MaxLength());
+ r = aPort->GetConfigurationStringDescriptor(rd_str);
+ test_KErrNone(r);
+ test.Printf(_L("New Configuration string: \"%lS\"\n"), &rd_str);
+
+ test.Next(_L("Compare Configuration strings"));
+ r = rd_str.Compare(wr_str);
+ test_KErrNone(r);
+
+ test.Next(_L("RemoveConfigurationStringDescriptor()"));
+ r = aPort->RemoveConfigurationStringDescriptor();
+ test_KErrNone(r);
+ r = aPort->GetConfigurationStringDescriptor(rd_str);
+ test_Equal(KErrNotFound,r);
+
+ if (restore_string)
+ {
+ test.Next(_L("Restore original string"));
+ r = aPort->SetConfigurationStringDescriptor(rd_str_orig);
+ test_KErrNone(r);
+ r = aPort->GetConfigurationStringDescriptor(rd_str);
+ test_KErrNone(r);
+ r = rd_str.Compare(rd_str_orig);
+ test_KErrNone(r);
+ }
+
+ test.End();
+ }
+
+
+static void TestArbitraryStringDescriptors(RDEVCLIENT* aPort,TInt aNumSettings)
+ {
+ test.Start(_L("Arbitrary String Descriptor Manipulation"));
+
+ // First test string
+
+ test.Next(_L("GetStringDescriptor() 1"));
+ TBuf16<KUsbStringDescStringMaxSize / 2> rd_str;
+ TInt r = aPort->GetStringDescriptor(stridx1, rd_str);
+ test_KErrNone(r);
+
+ TBuf16<KUsbStringDescStringMaxSize / 2> wr_str(KString_one);
+ r = rd_str.Compare(wr_str);
+ test_KErrNone(r);
+
+ // Second test string
+
+ test.Next(_L("GetStringDescriptor() 2"));
+ rd_str.FillZ(rd_str.MaxLength());
+ r = aPort->GetStringDescriptor(stridx2, rd_str);
+ test_KErrNone(r);
+
+ wr_str = KString_two;
+ r = rd_str.Compare(wr_str);
+ test_KErrNone(r);
+
+ // Third test string
+
+ test.Next(_L("GetStringDescriptor() 3"));
+ rd_str.FillZ(rd_str.MaxLength());
+ r = aPort->GetStringDescriptor(stridx3, rd_str);
+ test_Equal(KErrNotFound,r);
+
+ test.Next(_L("SetStringDescriptor() 3"));
+ _LIT16(string_three, "Arbitrary String Descriptor Test String 3");
+ wr_str.FillZ(wr_str.MaxLength());
+ wr_str = string_three;
+ r = aPort->SetStringDescriptor(stridx3, wr_str);
+ test_KErrNone(r);
+
+ // In between we create another interface setting to see what happens
+ // to the existing string descriptor indices.
+ // (We don't have to test this on every platform -
+ // besides, those that don't support alt settings
+ // are by now very rare.)
+ if (SupportsAlternateInterfaces())
+ {
+ #ifdef USB_SC
+ TUsbcScInterfaceInfoBuf ifc;
+ #else
+ TUsbcInterfaceInfoBuf ifc;
+ #endif
+ _LIT16(string, "T_USB_DEVICE Bogus Test Interface (Next Setting)");
+ ifc().iString = const_cast<TDesC16*>(&string);
+ ifc().iTotalEndpointsUsed = 0;
+ TInt r = aPort->SetInterface(aNumSettings, ifc);
+ test_KErrNone(r);
+ }
+
+ test.Next(_L("GetStringDescriptor() 3"));
+ r = aPort->GetStringDescriptor(stridx3, rd_str);
+ test_KErrNone(r);
+ test.Printf(_L("New test string @ idx %d: \"%lS\"\n"), stridx3, &rd_str);
+
+ test.Next(_L("Compare test strings 3"));
+ r = rd_str.Compare(wr_str);
+ test_KErrNone(r);
+
+ // Remove string descriptors 3 and 4
+
+ test.Next(_L("RemoveStringDescriptor() 4"));
+ r = aPort->RemoveStringDescriptor(stridx4);
+ test_Equal(KErrNotFound,r);
+
+ test.Next(_L("RemoveStringDescriptor() 3"));
+ r = aPort->RemoveStringDescriptor(stridx3);
+ test_KErrNone(r);
+
+ r = aPort->GetStringDescriptor(stridx3, rd_str);
+ test_Equal(KErrNotFound,r);
+
+ if (SupportsAlternateInterfaces())
+ {
+ TInt r = aPort->ReleaseInterface(aNumSettings);
+ test_KErrNone(r);
+ }
+
+ test.End();
+ }
+
+void TestInvalidSetInterface (RDEVCLIENT* aPort,TInt aNumSettings)
+ {
+ #ifdef USB_SC
+ TUsbcScInterfaceInfoBuf ifc;
+ #else
+ TUsbcInterfaceInfoBuf ifc;
+ #endif
+ _LIT16(string, "T_USB_DEVICE Invalid Interface");
+ ifc().iString = const_cast<TDesC16*>(&string);
+ ifc().iTotalEndpointsUsed = 0;
+
+ test.Start(_L("Test Invalid Interface Setting"));
+
+ if (SupportsAlternateInterfaces())
+ {
+ TInt r = aPort->SetInterface(aNumSettings+1, ifc);
+ test_Compare(r,!=,KErrNone);
+ }
+
+ if (aNumSettings > 1)
+ {
+ TInt r = aPort->SetInterface(aNumSettings-1, ifc);
+ test_Compare(r,!=,KErrNone);
+ }
+
+ TInt r = aPort->SetInterface(0, ifc);
+ test_Compare(r,!=,KErrNone);
+
+ test.End();
+ }
+
+void TestInvalidReleaseInterface (RDEVCLIENT* aPort,TInt aNumSettings)
+ {
+ test.Start(_L("Test Invalid Interface Release"));
+
+ if (aNumSettings > 2)
+ {
+ TInt r = aPort->ReleaseInterface(aNumSettings-3);
+ test_Compare(r,!=,KErrNone);
+ }
+
+ if (aNumSettings > 1)
+ {
+ TInt r = aPort->ReleaseInterface(aNumSettings-2);
+ test_Compare(r,!=,KErrNone);
+ }
+
+ test.End();
+ }
+
+void TestDescriptorManipulation(TBool aHighSpeed, RDEVCLIENT* aPort, TInt aNumSettings)
+ {
+ test.Start(_L("Test USB Descriptor Manipulation"));
+
+ if (aHighSpeed)
+ {
+ TestDeviceQualifierDescriptor(aPort);
+
+ TestOtherSpeedConfigurationDescriptor(aPort);
+ }
+
+ TestInterfaceDescriptor(aPort,aNumSettings);
+
+ TestClassSpecificDescriptors(aPort);
+
+ TestStandardStringDescriptors(aPort);
+
+ TestArbitraryStringDescriptors(aPort,aNumSettings);
+
+ test.End();
+ }
+
+
+void TestOtgExtensions(RDEVCLIENT* aPort)
+ {
+ test.Start(_L("Test Some OTG API Extensions"));
+
+ // Test OTG descriptor manipulation
+ test.Next(_L("Get OTG Descriptor Size"));
+ TInt size;
+ aPort->GetOtgDescriptorSize(size);
+ test_Equal(KUsbDescSize_Otg,static_cast<TUint>(size));
+
+ test.Next(_L("Get OTG Descriptor"));
+ TBuf8<KUsbDescSize_Otg> otgDesc;
+ TInt r = aPort->GetOtgDescriptor(otgDesc);
+ test(r == KErrNotSupported || r == KErrNone);
+
+ test.Next(_L("Set OTG Descriptor"));
+ TBool supportOtg = EFalse;
+ if (r == KErrNotSupported)
+ {
+ r = aPort->SetOtgDescriptor(otgDesc);
+ test_Equal(KErrNotSupported,r);
+ }
+ else
+ {
+ supportOtg = ETrue;
+ otgDesc[0] = KUsbDescSize_Otg;
+ otgDesc[1] = KUsbDescType_Otg;
+ otgDesc[2] = KUsbOtgAttr_SrpSupp;
+ r = aPort->SetOtgDescriptor(otgDesc);
+ test_KErrNone(r);
+ TBuf8<KUsbDescSize_Otg> desc;
+ r = aPort->GetOtgDescriptor(desc);
+ test_KErrNone(r);
+ test_Equal(0,desc.Compare(otgDesc));
+ }
+
+ // Test get/set OTG feature
+ test.Next(_L("Get OTG Features"));
+ TUint8 features;
+ r = aPort->GetOtgFeatures(features);
+ if (supportOtg)
+ {
+ test_KErrNone(r);
+ TBool b_HnpEnable = (features & KUsbOtgAttr_B_HnpEnable) ? ETrue : EFalse;
+ TBool a_HnpSupport = (features & KUsbOtgAttr_A_HnpSupport) ? ETrue : EFalse;
+ TBool a_AltHnpSupport = (features & KUsbOtgAttr_A_AltHnpSupport) ? ETrue : EFalse;
+ test.Printf(_L("### OTG Features:\nB_HnpEnable(%d)\nA_HnpSupport(%d)\nA_Alt_HnpSupport(%d)\n"),
+ b_HnpEnable, a_HnpSupport, a_AltHnpSupport);
+ }
+ else
+ {
+ test_Equal(KErrNotSupported,r);
+ test.Printf(_L("GetOtgFeatures() not supported\n"));
+ }
+
+ test.End();
+}
+
+
+void TestEndpoint0MaxPacketSizes(RDEVCLIENT* aPort)
+ {
+ test.Start(_L("Test Endpoint0 MaxPacketSizes"));
+
+ TUint32 sizes = aPort->EndpointZeroMaxPacketSizes();
+ TInt r = KErrNone;
+ TBool good;
+ TInt mpsize = 0;
+ for (TInt i = 0; i < 32; i++)
+ {
+ TUint bit = sizes & (1 << i);
+ if (bit != 0)
+ {
+ switch (bit)
+ {
+ case KUsbEpSizeCont:
+ good = EFalse;
+ break;
+ case KUsbEpSize8:
+ mpsize = 8;
+ good = ETrue;
+ break;
+ case KUsbEpSize16:
+ mpsize = 16;
+ good = ETrue;
+ break;
+ case KUsbEpSize32:
+ mpsize = 32;
+ good = ETrue;
+ break;
+ case KUsbEpSize64:
+ mpsize = 64;
+ good = ETrue;
+ break;
+ case KUsbEpSize128:
+ case KUsbEpSize256:
+ case KUsbEpSize512:
+ case KUsbEpSize1023:
+ default:
+ good = EFalse;
+ break;
+ }
+ if (good)
+ {
+ test.Printf(_L("Ep0 supports %d bytes MaxPacketSize\n"), mpsize);
+ }
+ else
+ {
+ test.Printf(_L("Bad Ep0 size: 0x%08x, failure will occur\n"), bit);
+ r = KErrGeneral;
+ }
+ }
+ }
+ test_KErrNone(r);
+
+ test.End();
+ }
+
+