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