sl@0: // Copyright (c) 2004-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: // f32test\testusbcldd\src\descriptors.cpp sl@0: // Platform independent USB client controller layer (PIL): sl@0: // USB descriptor handling and management. sl@0: // sl@0: // sl@0: sl@0: #include "usbcdesc.h" sl@0: #include "dtestusblogdev.h" sl@0: sl@0: // --- TUsbcDescriptorBase sl@0: sl@0: TUsbcDescriptorBase::TUsbcDescriptorBase() sl@0: : sl@0: #ifdef USB_SUPPORTS_SET_DESCRIPTOR_REQUEST sl@0: iIndex(0), sl@0: #endif sl@0: iBufPtr(NULL, 0) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorBase::TUsbcDescriptorBase()"))); sl@0: } sl@0: sl@0: sl@0: TUsbcDescriptorBase::~TUsbcDescriptorBase() sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorBase::~TUsbcDescriptorBase()"))); sl@0: } sl@0: sl@0: sl@0: void TUsbcDescriptorBase::SetByte(TUint aPosition, TUint8 aValue) sl@0: { sl@0: iBufPtr[aPosition] = aValue; sl@0: } sl@0: sl@0: sl@0: void TUsbcDescriptorBase::SetWord(TUint aPosition, TUint16 aValue) sl@0: { sl@0: *reinterpret_cast(&iBufPtr[aPosition]) = SWAP_BYTES_16(aValue); sl@0: } sl@0: sl@0: sl@0: TUint8 TUsbcDescriptorBase::Byte(TUint aPosition) const sl@0: { sl@0: return iBufPtr[aPosition]; sl@0: } sl@0: sl@0: sl@0: TUint16 TUsbcDescriptorBase::Word(TUint aPosition) const sl@0: { sl@0: return SWAP_BYTES_16(*reinterpret_cast(&iBufPtr[aPosition])); sl@0: } sl@0: sl@0: sl@0: void TUsbcDescriptorBase::GetDescriptorData(TDes8& aBuffer) const sl@0: { sl@0: aBuffer = iBufPtr; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorBase::GetDescriptorData(TUint8* aBuffer) const sl@0: { sl@0: __MEMCPY(aBuffer, iBufPtr.Ptr(), Size()); sl@0: return Size(); sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorBase::GetDescriptorData(TUint8* aBuffer, TInt aMaxSize) const sl@0: { sl@0: if (aMaxSize < Size()) sl@0: { sl@0: // No use to copy only half a descriptor sl@0: return 0; sl@0: } sl@0: return GetDescriptorData(aBuffer); sl@0: } sl@0: sl@0: sl@0: const TDes8& TUsbcDescriptorBase::DescriptorData() const sl@0: { sl@0: return iBufPtr; sl@0: } sl@0: sl@0: sl@0: TDes8& TUsbcDescriptorBase::DescriptorData() sl@0: { sl@0: return iBufPtr; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorBase::Size() const sl@0: { sl@0: return iBufPtr.Size(); sl@0: } sl@0: sl@0: sl@0: TUint8 TUsbcDescriptorBase::Type() const sl@0: { sl@0: return iBufPtr[1]; sl@0: } sl@0: sl@0: sl@0: void TUsbcDescriptorBase::SetBufferPointer(const TDesC8& aDes) sl@0: { sl@0: iBufPtr.Set(const_cast(aDes.Ptr()), aDes.Size(), aDes.Size()); sl@0: } sl@0: sl@0: sl@0: // --- TUsbcDeviceDescriptor sl@0: sl@0: TUsbcDeviceDescriptor::TUsbcDeviceDescriptor() sl@0: : iBuf() sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDeviceDescriptor::TUsbcDeviceDescriptor()"))); sl@0: } sl@0: sl@0: sl@0: TUsbcDeviceDescriptor* TUsbcDeviceDescriptor::New(TUint8 aDeviceClass, TUint8 aDeviceSubClass, sl@0: TUint8 aDeviceProtocol, TUint8 aMaxPacketSize0, sl@0: TUint16 aVendorId, TUint16 aProductId, sl@0: TUint16 aDeviceRelease, TUint8 aNumConfigurations) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDeviceDescriptor::New()"))); sl@0: TUsbcDeviceDescriptor* self = new TUsbcDeviceDescriptor(); sl@0: if (self) sl@0: { sl@0: if (self->Construct(aDeviceClass, aDeviceSubClass, aDeviceProtocol, aMaxPacketSize0, aVendorId, sl@0: aProductId, aDeviceRelease, aNumConfigurations) != KErrNone) sl@0: { sl@0: delete self; sl@0: return NULL; sl@0: } sl@0: } sl@0: return self; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDeviceDescriptor::Construct(TUint8 aDeviceClass, TUint8 aDeviceSubClass, TUint8 aDeviceProtocol, sl@0: TUint8 aMaxPacketSize0, TUint16 aVendorId, TUint16 aProductId, sl@0: TUint16 aDeviceRelease, TUint8 aNumConfigurations) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDeviceDescriptor::Construct()"))); sl@0: iBuf.SetMax(); sl@0: SetBufferPointer(iBuf); sl@0: iBuf[0] = (TUint8)iBuf.Size(); // bLength sl@0: iBuf[1] = KUsbDescType_Device; // bDescriptorType sl@0: SetWord(2, KUsbcUsbVersion); // bcdUSB sl@0: iBuf[4] = aDeviceClass; // bDeviceClass sl@0: iBuf[5] = aDeviceSubClass; // bDeviceSubClass sl@0: iBuf[6] = aDeviceProtocol; // bDeviceProtocol sl@0: iBuf[7] = aMaxPacketSize0; // bMaxPacketSize0 sl@0: SetWord(8, aVendorId); // idVendor sl@0: SetWord(10, aProductId); // idProduct sl@0: SetWord(12, aDeviceRelease); // bcdDevice sl@0: iBuf[14] = 0; // iManufacturer sl@0: iBuf[15] = 0; // iProduct sl@0: iBuf[16] = 0; // iSerialNumber sl@0: iBuf[17] = aNumConfigurations; // bNumConfigurations sl@0: return KErrNone; sl@0: } sl@0: sl@0: // --- TUsbcConfigDescriptor sl@0: sl@0: TUsbcConfigDescriptor::TUsbcConfigDescriptor() sl@0: : iBuf() sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcConfigDescriptor::TUsbcConfigDescriptor()"))); sl@0: } sl@0: sl@0: sl@0: TUsbcConfigDescriptor* TUsbcConfigDescriptor::New(TUint8 aConfigurationValue, TBool aSelfPowered, sl@0: TBool aRemoteWakeup, TUint8 aMaxPower) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcConfigDescriptor::New()"))); sl@0: TUsbcConfigDescriptor* self = new TUsbcConfigDescriptor(); sl@0: if (self) sl@0: { sl@0: if (self->Construct(aConfigurationValue, aSelfPowered, aRemoteWakeup, aMaxPower) != KErrNone) sl@0: { sl@0: delete self; sl@0: return NULL; sl@0: } sl@0: } sl@0: return self; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcConfigDescriptor::Construct(TUint8 aConfigurationValue, TBool aSelfPowered, sl@0: TBool aRemoteWakeup, TUint8 aMaxPower) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcConfigDescriptor::Construct()"))); sl@0: iBuf.SetMax(); sl@0: SetBufferPointer(iBuf); sl@0: iBuf[0] = (TUint8)iBuf.Size(); // bLength sl@0: iBuf[1] = KUsbDescType_Config; // bDescriptorType sl@0: SetWord(2, KUsbDescSize_Config); // wTotalLength sl@0: iBuf[4] = 0; // bNumInterfaces sl@0: iBuf[5] = aConfigurationValue; // bConfigurationValue sl@0: iBuf[6] = 0; // iConfiguration sl@0: iBuf[7] = (TUint8)(0x80 | (aSelfPowered ? 0x40 : 0) | (aRemoteWakeup ? 0x20 : 0)); // bmAttributes (bit 7 always 1) sl@0: iBuf[8] = (TUint8)(aMaxPower / 2); // MaxPower (2mA units!) sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: // --- TUsbcInterfaceDescriptor sl@0: sl@0: TUsbcInterfaceDescriptor::TUsbcInterfaceDescriptor() sl@0: : iBuf() sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcInterfaceDescriptor::TUsbcInterfaceDescriptor()"))); sl@0: } sl@0: sl@0: sl@0: TUsbcInterfaceDescriptor* TUsbcInterfaceDescriptor::New(TUint8 aInterfaceNumber, TUint8 aAlternateSetting, sl@0: TInt aNumEndpoints, const TUsbcClassInfo& aClassInfo) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcInterfaceDescriptor::New()"))); sl@0: TUsbcInterfaceDescriptor* self = new TUsbcInterfaceDescriptor(); sl@0: if (self) sl@0: { sl@0: if (self->Construct(aInterfaceNumber, aAlternateSetting, aNumEndpoints, aClassInfo) != KErrNone) sl@0: { sl@0: delete self; sl@0: return NULL; sl@0: } sl@0: } sl@0: return self; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcInterfaceDescriptor::Construct(TUint8 aInterfaceNumber, TUint8 aAlternateSetting, sl@0: TInt aNumEndpoints, const TUsbcClassInfo& aClassInfo) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcInterfaceDescriptor::Construct()"))); sl@0: iBuf.SetMax(); sl@0: SetBufferPointer(iBuf); sl@0: iBuf[0] = (TUint8)iBuf.Size(); // bLength sl@0: iBuf[1] = KUsbDescType_Interface; // bDescriptorType sl@0: iBuf[2] = aInterfaceNumber; // bInterfaceNumber sl@0: iBuf[3] = aAlternateSetting; // bAlternateSetting sl@0: iBuf[4] = (TUint8)aNumEndpoints; // bNumEndpoints sl@0: iBuf[5] = (TUint8)aClassInfo.iClassNum; // bInterfaceClass sl@0: iBuf[6] = (TUint8)aClassInfo.iSubClassNum; // bInterfaceSubClass sl@0: iBuf[7] = (TUint8)aClassInfo.iProtocolNum; // bInterfaceProtocol sl@0: iBuf[8] = 0; // iInterface sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: // --- TUsbcEndpointDescriptor sl@0: sl@0: TUsbcEndpointDescriptor::TUsbcEndpointDescriptor() sl@0: : iBuf() sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcEndpointDescriptor::TUsbcEndpointDescriptor()"))); sl@0: } sl@0: sl@0: sl@0: TUsbcEndpointDescriptor* TUsbcEndpointDescriptor::New(TUint8 aEndpointAddress, sl@0: const TUsbcEndpointInfo& aEpInfo) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcEndpointDescriptor::New()"))); sl@0: TUsbcEndpointDescriptor* self = new TUsbcEndpointDescriptor(); sl@0: if (self) sl@0: { sl@0: if (self->Construct(aEndpointAddress, aEpInfo) != KErrNone) sl@0: { sl@0: delete self; sl@0: return NULL; sl@0: } sl@0: } sl@0: return self; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcEndpointDescriptor::Construct(TUint8 aEndpointAddress, const TUsbcEndpointInfo& aEpInfo) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcEndpointDescriptor::Construct()"))); sl@0: iBuf.SetMax(); sl@0: SetBufferPointer(iBuf); sl@0: iBuf[0] = (TUint8)iBuf.Size(); // bLength sl@0: iBuf[1] = KUsbDescType_Endpoint; // bDescriptorType sl@0: iBuf[2] = aEndpointAddress; // bEndpointAddress sl@0: iBuf[3] = (TUint8)EpTypeMask2Value(aEpInfo.iType); // bmAttributes sl@0: SetWord(4, (TUint8)aEpInfo.iSize); // wMaxPacketSize sl@0: iBuf[6] = (TUint8)aEpInfo.iInterval; // bInterval sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: // --- TUsbcAudioEndpointDescriptor sl@0: sl@0: TUsbcAudioEndpointDescriptor::TUsbcAudioEndpointDescriptor() sl@0: : iBuf() sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcAudioEndpointDescriptor::TUsbcAudioEndpointDescriptor()"))); sl@0: } sl@0: sl@0: sl@0: TUsbcAudioEndpointDescriptor* TUsbcAudioEndpointDescriptor::New(TUint8 aEndpointAddress, sl@0: const TUsbcEndpointInfo& aEpInfo) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcAudioEndpointDescriptor::New()"))); sl@0: TUsbcAudioEndpointDescriptor* self = new TUsbcAudioEndpointDescriptor(); sl@0: if (self) sl@0: { sl@0: if (self->Construct(aEndpointAddress, aEpInfo) != KErrNone) sl@0: { sl@0: delete self; sl@0: return NULL; sl@0: } sl@0: } sl@0: return self; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcAudioEndpointDescriptor::Construct(TUint8 aEndpointAddress, const TUsbcEndpointInfo& aEpInfo) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcAudioEndpointDescriptor::Construct()"))); sl@0: iBuf.SetMax(); sl@0: SetBufferPointer(iBuf); sl@0: iBuf[0] = (TUint8)iBuf.Size(); // bLength sl@0: iBuf[1] = KUsbDescType_Endpoint; // bDescriptorType sl@0: iBuf[2] = aEndpointAddress; // bEndpointAddress sl@0: iBuf[3] = (TUint8)EpTypeMask2Value(aEpInfo.iType); // bmAttributes sl@0: SetWord(4, (TUint8)aEpInfo.iSize); // wMaxPacketSize sl@0: iBuf[6] = (TUint8)aEpInfo.iInterval; // bInterval sl@0: iBuf[7] = 0; sl@0: iBuf[8] = 0; sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: // --- TUsbcClassSpecificDescriptor sl@0: sl@0: TUsbcClassSpecificDescriptor::TUsbcClassSpecificDescriptor() sl@0: : iBuf(NULL) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcClassSpecificDescriptor::TUsbcClassSpecificDescriptor()"))); sl@0: } sl@0: sl@0: sl@0: TUsbcClassSpecificDescriptor::~TUsbcClassSpecificDescriptor() sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcClassSpecificDescriptor::~TUsbcClassSpecificDescriptor()"))); sl@0: delete iBuf; sl@0: } sl@0: sl@0: sl@0: TUsbcClassSpecificDescriptor* TUsbcClassSpecificDescriptor::New(TUint8 aType, TInt aSize) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcClassSpecificDescriptor::New()"))); sl@0: TUsbcClassSpecificDescriptor* self = new TUsbcClassSpecificDescriptor(); sl@0: if (self) sl@0: { sl@0: if (self->Construct(aType, aSize) != KErrNone) sl@0: { sl@0: delete self; sl@0: return NULL; sl@0: } sl@0: } sl@0: return self; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcClassSpecificDescriptor::Construct(TUint8 aType, TInt aSize) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcClassSpecificDescriptor::Construct()"))); sl@0: __NEWPLATBUF(iBuf, aSize); sl@0: if (!iBuf) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: Allocation of CS desc buffer failed"))); sl@0: return KErrNoMemory; sl@0: } sl@0: SetBufferPointer(*iBuf); sl@0: SetByte(1, aType); // bDescriptorType sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: // --- TUsbcStringDescriptorBase sl@0: sl@0: TUsbcStringDescriptorBase::TUsbcStringDescriptorBase() sl@0: : /*iIndex(0),*/ iSBuf(0), iBufPtr(NULL, 0) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptorBase::TUsbcStringDescriptorBase()"))); sl@0: } sl@0: sl@0: sl@0: TUsbcStringDescriptorBase::~TUsbcStringDescriptorBase() sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptorBase::~TUsbcStringDescriptorBase()"))); sl@0: } sl@0: sl@0: sl@0: TUint16 TUsbcStringDescriptorBase::Word(TUint aPosition) const sl@0: { sl@0: if (aPosition <= 1) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("TUsbcStringDescriptorBase::Word: Error: Word(%d) in string descriptor!"), aPosition)); sl@0: return 0; sl@0: } sl@0: else sl@0: { sl@0: // since iBufPtr[0] is actually string descriptor byte index 2, sl@0: // we have to subtract 2 from the absolute position. sl@0: return SWAP_BYTES_16(*reinterpret_cast(&iBufPtr[aPosition - 2])); sl@0: } sl@0: } sl@0: sl@0: sl@0: TInt TUsbcStringDescriptorBase::GetDescriptorData(TUint8* aBuffer) const sl@0: { sl@0: aBuffer[0] = iSBuf[0]; sl@0: aBuffer[1] = iSBuf[1]; sl@0: __MEMCPY(&aBuffer[2], iBufPtr.Ptr(), iBufPtr.Size()); sl@0: return Size(); sl@0: } sl@0: sl@0: sl@0: TInt TUsbcStringDescriptorBase::GetDescriptorData(TUint8* aBuffer, TInt aMaxSize) const sl@0: { sl@0: if (aMaxSize < Size()) sl@0: { sl@0: // No use to copy only half a string sl@0: return 0; sl@0: } sl@0: return GetDescriptorData(aBuffer); sl@0: } sl@0: sl@0: sl@0: const TDes8& TUsbcStringDescriptorBase::StringData() const sl@0: { sl@0: return iBufPtr; sl@0: } sl@0: sl@0: sl@0: TDes8& TUsbcStringDescriptorBase::StringData() sl@0: { sl@0: return iBufPtr; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcStringDescriptorBase::Size() const sl@0: { sl@0: return iSBuf[0]; sl@0: } sl@0: sl@0: sl@0: void TUsbcStringDescriptorBase::SetBufferPointer(const TDesC8& aDes) sl@0: { sl@0: iBufPtr.Set(const_cast(aDes.Ptr()), aDes.Size(), aDes.Size()); sl@0: } sl@0: sl@0: sl@0: // --- TUsbcStringDescriptor sl@0: sl@0: TUsbcStringDescriptor::TUsbcStringDescriptor() sl@0: : iBuf(NULL) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptor::TUsbcStringDescriptor()"))); sl@0: } sl@0: sl@0: sl@0: TUsbcStringDescriptor::~TUsbcStringDescriptor() sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptor::~TUsbcStringDescriptor()"))); sl@0: delete iBuf; sl@0: } sl@0: sl@0: sl@0: TUsbcStringDescriptor* TUsbcStringDescriptor::New(const TDesC8& aString) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptor::New"))); sl@0: TUsbcStringDescriptor* self = new TUsbcStringDescriptor(); sl@0: if (self) sl@0: { sl@0: if (self->Construct(aString) != KErrNone) sl@0: { sl@0: delete self; sl@0: return NULL; sl@0: } sl@0: } sl@0: return self; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcStringDescriptor::Construct(const TDesC8& aString) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptor::Construct"))); sl@0: __NEWPLATBUF(iBuf, aString.Size()); sl@0: if (!iBuf) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: Allocation of string buffer failed"))); sl@0: return KErrNoMemory; sl@0: } sl@0: SetBufferPointer(*iBuf); sl@0: iBufPtr.Copy(aString); sl@0: iSBuf.SetMax(); sl@0: iSBuf[0] = (TUint8)(iBuf->Size() + 2); // Bytes sl@0: iSBuf[1] = KUsbDescType_String; sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: // --- TUsbcLangIdDescriptor sl@0: sl@0: TUsbcLangIdDescriptor::TUsbcLangIdDescriptor() sl@0: : iBuf(NULL) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcLangIdDescriptor::TUsbcLangIdDescriptor()"))); sl@0: } sl@0: sl@0: sl@0: TUsbcLangIdDescriptor::~TUsbcLangIdDescriptor() sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcLangIdDescriptor::~TUsbcLangIdDescriptor()"))); sl@0: } sl@0: sl@0: sl@0: TUsbcLangIdDescriptor* TUsbcLangIdDescriptor::New(TUint16 aLangId) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcLangIdDescriptor::New"))); sl@0: TUsbcLangIdDescriptor* self = new TUsbcLangIdDescriptor(); sl@0: if (self) sl@0: { sl@0: if (self->Construct(aLangId) != KErrNone) sl@0: { sl@0: delete self; sl@0: return NULL; sl@0: } sl@0: } sl@0: return self; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcLangIdDescriptor::Construct(TUint16 aLangId) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcLangIdDescriptor::Construct"))); sl@0: iBuf.SetMax(); sl@0: SetBufferPointer(iBuf); sl@0: iBufPtr[0] = LowByte(SWAP_BYTES_16(aLangId)); // Language ID value sl@0: iBufPtr[1] = HighByte(SWAP_BYTES_16(aLangId)); sl@0: iSBuf.SetMax(); sl@0: iSBuf[0] = (TUint8)(iBuf.Size() + 2); // Bytes sl@0: iSBuf[1] = KUsbDescType_String; sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: // --- TUsbcDescriptorPool sl@0: sl@0: TUsbcDescriptorPool::TUsbcDescriptorPool(TUint8* aEp0_TxBuf) sl@0: // sl@0: // The constructor for this class. sl@0: // sl@0: : iDescriptors(4), iStrings(4), iIfcIdx(0), iEp0_TxBuf(aEp0_TxBuf) // 4 = granularity sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::TUsbcDescriptorPool()"))); sl@0: } sl@0: sl@0: sl@0: TUsbcDescriptorPool::~TUsbcDescriptorPool() sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::~TUsbcDescriptorPool()"))); sl@0: // The destructor of each object is called before the objects themselves are destroyed. sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" iDescriptors.Count(): %d"), iDescriptors.Count())); sl@0: iDescriptors.ResetAndDestroy(); sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" iStrings.Count(): %d"), iStrings.Count())); sl@0: iStrings.ResetAndDestroy(); sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::Init(TUsbcDeviceDescriptor* aDeviceDesc, TUsbcConfigDescriptor* aConfigDesc, sl@0: TUsbcLangIdDescriptor* aLangId, TUsbcStringDescriptor* aManufacturer, sl@0: TUsbcStringDescriptor* aProduct, TUsbcStringDescriptor* aSerialNum, sl@0: TUsbcStringDescriptor* aConfig) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::Init()"))); sl@0: iDescriptors.Insert(aDeviceDesc, 0); sl@0: iDescriptors.Insert(aConfigDesc, 1); sl@0: if (!aLangId || !aManufacturer || !aProduct || !aSerialNum || !aConfig) sl@0: { sl@0: // USB spec p. 202 says: "A USB device may omit all string descriptors." sl@0: // So, either ALL string descriptors are supplied or none at all. sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: No string descriptor(s)"))); sl@0: return KErrArgument; sl@0: } sl@0: iStrings.Insert(aLangId, 0); sl@0: iStrings.Insert(aManufacturer, 1); sl@0: iStrings.Insert(aProduct, 2); sl@0: iStrings.Insert(aSerialNum, 3); sl@0: iStrings.Insert(aConfig, 4); sl@0: // set string indices sl@0: iDescriptors[0]->SetByte(14, 1); // Device.iManufacturer sl@0: iDescriptors[0]->SetByte(15, 2); // Device.iProduct sl@0: iDescriptors[0]->SetByte(16, 3); // Device.iSerialNumber sl@0: iDescriptors[1]->SetByte( 6, 4); // Config.iConfiguration sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::FindDescriptor(TUint8 aType, TUint8 aIndex, TUint16 aLangid, TInt& aSize) const sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::FindDescriptor()"))); sl@0: TInt result = KErrGeneral; sl@0: sl@0: switch(aType) sl@0: { sl@0: case KUsbDescType_Device: sl@0: if (aLangid != 0) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: bad langid: 0x%04x"), aLangid)); sl@0: result = KErrGeneral; // bad langid sl@0: } sl@0: else if (aIndex > 0) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: bad device index: %d"), aIndex)); sl@0: result = KErrGeneral; // we have only one device sl@0: } sl@0: else sl@0: { sl@0: aSize = GetDeviceDescriptor(); sl@0: result = KErrNone; sl@0: } sl@0: break; sl@0: case KUsbDescType_Config: sl@0: if (aLangid != 0) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: bad langid: 0x%04x"), aLangid)); sl@0: result = KErrGeneral; // bad langid sl@0: } sl@0: else if (aIndex > 0) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: bad config index: %d"), aIndex)); sl@0: result = KErrGeneral; // we have only one configuration sl@0: } sl@0: else sl@0: { sl@0: aSize = GetConfigDescriptor(); sl@0: result = KErrNone; sl@0: } sl@0: break; sl@0: case KUsbDescType_String: sl@0: if ((aLangid != 0) && // 0 addresses the LangId array sl@0: (aLangid != iStrings[0]->Word(2))) // we have just one (this) language sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: bad langid (0x%04x requested, 0x%04x supported)"), sl@0: aLangid, iStrings[0]->Word(2))); sl@0: result = KErrGeneral; // bad langid sl@0: } sl@0: else if (aIndex >= iStrings.Count()) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: bad string index: %d"), aIndex)); sl@0: result = KErrGeneral; sl@0: } sl@0: else sl@0: { sl@0: aSize = GetStringDescriptor(aIndex); sl@0: result = KErrNone; sl@0: } sl@0: break; sl@0: case KUsbDescType_CS_Interface: sl@0: /* fall through */ sl@0: case KUsbDescType_CS_Endpoint: sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Warning: finding of class specific descriptors not supported"))); sl@0: break; sl@0: default: sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: unknown descriptor type requested: %d"), aType)); sl@0: result = KErrGeneral; sl@0: break; sl@0: } sl@0: sl@0: return result; sl@0: } sl@0: sl@0: sl@0: void TUsbcDescriptorPool::InsertDescriptor(TUsbcDescriptorBase* aDesc) sl@0: { sl@0: switch (aDesc->Type()) sl@0: { sl@0: case KUsbDescType_Device: sl@0: InsertDevDesc(aDesc); sl@0: break; sl@0: case KUsbDescType_Config: sl@0: InsertConfigDesc(aDesc); sl@0: break; sl@0: case KUsbDescType_Interface: sl@0: InsertIfcDesc(aDesc); sl@0: break; sl@0: case KUsbDescType_Endpoint: sl@0: InsertEpDesc(aDesc); sl@0: break; sl@0: case KUsbDescType_CS_Interface: sl@0: /* fall through */ sl@0: case KUsbDescType_CS_Endpoint: sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Warning: inserting class specific descriptors not supported"))); sl@0: break; sl@0: default: sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertDescriptor: Error: invalid type"))); sl@0: break; sl@0: } sl@0: } sl@0: sl@0: sl@0: void TUsbcDescriptorPool::SetIfcStringDescriptor(TUsbcStringDescriptor* aDesc, TInt aNumber, TInt aSetting) sl@0: { sl@0: TInt i = FindIfcDescriptor(aNumber, aSetting); sl@0: if (i < 0) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::SetIfcStringDescriptor: error"))); sl@0: return; sl@0: } sl@0: // Set (append) string descriptor for specified interface sl@0: iStrings.Append(aDesc); sl@0: // Update this ifc descriptors' string index field sl@0: const TInt str_idx = iStrings.Count() - 1; sl@0: iDescriptors[i]->SetByte(8, (TUint8)str_idx); sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" String for ifc %d/%d (@ pos %d): \"%S\""), aNumber, aSetting, str_idx, sl@0: &iStrings[str_idx]->StringData())); sl@0: } sl@0: sl@0: sl@0: void TUsbcDescriptorPool::DeleteIfcDescriptor(TInt aNumber, TInt aSetting) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::DeleteIfcDescriptor(%d, %d)"), aNumber, aSetting)); sl@0: TInt i = FindIfcDescriptor(aNumber, aSetting); sl@0: if (i < 0) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" > Error: descriptor not found"))); sl@0: return; sl@0: } sl@0: // Delete (if necessary) specified interface's string descriptor sl@0: TInt si = iDescriptors[i]->Byte(8); sl@0: if (si != 0) sl@0: { sl@0: DeleteString(si); sl@0: } sl@0: // Delete specified ifc setting + all its cs descriptors + all its endpoints + all their cs descriptors: sl@0: // find position of the next interface descriptor: we need to delete everything in between sl@0: const TInt count = iDescriptors.Count(); sl@0: TInt j = i, n = 1; sl@0: while (++j < count && iDescriptors[j]->Type() != KUsbDescType_Interface) sl@0: ++n; sl@0: DeleteDescriptors(i, n); sl@0: // Update all the following interfaces' bInterfaceNumber field if required sl@0: // (because these descriptors might have moved down by one position) sl@0: UpdateIfcNumbers(aNumber); sl@0: // Update (if necessary) all interfaces' string index field sl@0: if (si != 0) sl@0: { sl@0: UpdateIfcStringIndexes(si); sl@0: } sl@0: iIfcIdx = 0; // ifc index no longer valid sl@0: } sl@0: sl@0: sl@0: // The TC in many of the following functions stands for 'ThreadCopy', sl@0: // because that's what's happening there. sl@0: sl@0: TInt TUsbcDescriptorPool::GetDeviceDescriptorTC(DThread* aThread, TDes8& aBuffer) const sl@0: { sl@0: return __THREADWRITE(aThread, &aBuffer, iDescriptors[0]->DescriptorData()); sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::SetDeviceDescriptorTC(DThread* aThread, const TDes8& aBuffer) sl@0: { sl@0: TBuf8 device; sl@0: TInt r = __THREADREAD(aThread, &aBuffer, device); sl@0: if (r != KErrNone) sl@0: { sl@0: return r; sl@0: } sl@0: iDescriptors[0]->SetByte(2, device[2]); // bcdUSB sl@0: iDescriptors[0]->SetByte(3, device[3]); // bcdUSB (part II) sl@0: iDescriptors[0]->SetByte(4, device[4]); // bDeviceClass sl@0: iDescriptors[0]->SetByte(5, device[5]); // bDeviceSubClass sl@0: iDescriptors[0]->SetByte(6, device[6]); // bDeviceProtocol sl@0: iDescriptors[0]->SetByte(8, device[8]); // idVendor sl@0: iDescriptors[0]->SetByte(9, device[9]); // idVendor (part II) sl@0: iDescriptors[0]->SetByte(10, device[10]); // idProduct sl@0: iDescriptors[0]->SetByte(11, device[11]); // idProduct (part II) sl@0: iDescriptors[0]->SetByte(12, device[12]); // bcdDevice sl@0: iDescriptors[0]->SetByte(13, device[13]); // bcdDevice (part II) sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::GetConfigurationDescriptorTC(DThread* aThread, TDes8& aBuffer) const sl@0: { sl@0: return __THREADWRITE(aThread, &aBuffer, iDescriptors[1]->DescriptorData()); sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::SetConfigurationDescriptorTC(DThread* aThread, const TDes8& aBuffer) sl@0: { sl@0: TBuf8 config; sl@0: TInt r = __THREADREAD(aThread, &aBuffer, config); sl@0: if (r != KErrNone) sl@0: { sl@0: return r; sl@0: } sl@0: iDescriptors[1]->SetByte(7, config[7]); // bmAttributes sl@0: iDescriptors[1]->SetByte(8, config[8]); // bMaxPower sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::GetInterfaceDescriptorTC(DThread* aThread, TDes8& aBuffer, sl@0: TInt aInterface, TInt aSetting) const sl@0: { sl@0: TInt i = FindIfcDescriptor(aInterface, aSetting); sl@0: if (i < 0) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such interface"))); sl@0: return KErrNotFound; sl@0: } sl@0: return __THREADWRITE(aThread, &aBuffer, iDescriptors[i]->DescriptorData()); sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::SetInterfaceDescriptor(const TDes8& aBuffer, TInt aInterface, TInt aSetting) sl@0: { sl@0: TInt i = FindIfcDescriptor(aInterface, aSetting); sl@0: if (i < 0) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such interface"))); sl@0: return KErrNotFound; sl@0: } sl@0: iDescriptors[i]->SetByte(2, aBuffer[2]); // bInterfaceNumber sl@0: iDescriptors[i]->SetByte(5, aBuffer[5]); // bInterfaceClass sl@0: iDescriptors[i]->SetByte(6, aBuffer[6]); // bInterfaceSubClass sl@0: iDescriptors[i]->SetByte(7, aBuffer[7]); // bInterfaceProtocol sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::GetEndpointDescriptorTC(DThread* aThread, TDes8& aBuffer, sl@0: TInt aInterface, TInt aSetting, TUint8 aEndpointAddress) const sl@0: { sl@0: TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress); sl@0: if (i < 0) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such endpoint"))); sl@0: return KErrNotFound; sl@0: } sl@0: return __THREADWRITE(aThread, &aBuffer, iDescriptors[i]->DescriptorData()); sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::SetEndpointDescriptorTC(DThread* aThread, const TDes8& aBuffer, sl@0: TInt aInterface, TInt aSetting, TUint8 aEndpointAddress) sl@0: { sl@0: TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress); sl@0: if (i < 0) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such endpoint"))); sl@0: return KErrNotFound; sl@0: } sl@0: TBuf8 ep; // it could be an audio endpoint sl@0: TInt r = __THREADREAD(aThread, &aBuffer, ep); sl@0: if (r != KErrNone) sl@0: { sl@0: return r; sl@0: } sl@0: iDescriptors[i]->SetByte(3, ep[3]); // bmAttributes sl@0: iDescriptors[i]->SetByte(6, ep[6]); // bInterval sl@0: if (static_cast(iDescriptors[i]->Size()) == KUsbDescSize_AudioEndpoint) sl@0: { sl@0: iDescriptors[i]->SetByte(7, ep[7]); // bRefresh sl@0: iDescriptors[i]->SetByte(8, ep[8]); // bSynchAddress sl@0: } sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::GetEndpointDescriptorSize(TInt aInterface, TInt aSetting, TUint8 aEndpointAddress, sl@0: TInt& aSize) const sl@0: { sl@0: TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress); sl@0: if (i < 0) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such endpoint"))); sl@0: return KErrNotFound; sl@0: } sl@0: aSize = iDescriptors[i]->Size(); sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::GetCSInterfaceDescriptorTC(DThread* aThread, TDes8& aBuffer, sl@0: TInt aInterface, TInt aSetting) const sl@0: { sl@0: // first find the interface sl@0: TInt i = FindIfcDescriptor(aInterface, aSetting); sl@0: if (i < 0) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such interface"))); sl@0: return KErrNotFound; sl@0: } sl@0: TInt r = KErrNotFound; sl@0: TInt offset = 0; sl@0: const TInt count = iDescriptors.Count(); sl@0: while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface) sl@0: { sl@0: r = __THREADWRITEOFFSET(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), offset); sl@0: if (r != KErrNone) sl@0: break; sl@0: offset += iDescriptors[i]->Size(); sl@0: } sl@0: return r; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::SetCSInterfaceDescriptorTC(DThread* aThread, const TDes8& aBuffer, sl@0: TInt aInterface, TInt aSetting, TInt aSize) sl@0: { sl@0: // first find the interface sl@0: TInt i = FindIfcDescriptor(aInterface, aSetting); sl@0: if (i < 0) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such interface"))); sl@0: return KErrNotFound; sl@0: } sl@0: // find a position where to insert the new class specific interface descriptor(s) sl@0: const TInt count = iDescriptors.Count(); sl@0: while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface) sl@0: ; sl@0: // create a new cs descriptor sl@0: TUsbcClassSpecificDescriptor* desc = TUsbcClassSpecificDescriptor::New(KUsbDescType_CS_Interface, aSize); sl@0: if (!desc) sl@0: { sl@0: return KErrNoMemory; sl@0: } sl@0: iDescriptors.Insert(desc, i); sl@0: if (iDescriptors[1]) sl@0: { sl@0: // if there's a config descriptor (and not a NULL pointer), we update its wTotalLength field sl@0: iDescriptors[1]->SetWord(2, (TUint8)(iDescriptors[1]->Word(2) + aSize)); sl@0: } sl@0: // copy contents from user side sl@0: return __THREADREAD(aThread, &aBuffer, iDescriptors[i]->DescriptorData()); sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::GetCSInterfaceDescriptorSize(TInt aInterface, TInt aSetting, TInt& aSize) const sl@0: { sl@0: // first find the interface sl@0: TInt i = FindIfcDescriptor(aInterface, aSetting); sl@0: if (i < 0) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such interface"))); sl@0: return KErrNotFound; sl@0: } sl@0: TInt r = KErrNotFound; sl@0: TInt size = 0; sl@0: const TInt count = iDescriptors.Count(); sl@0: while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface) sl@0: { sl@0: size += iDescriptors[i]->Size(); sl@0: r = KErrNone; sl@0: } sl@0: if (r == KErrNone) sl@0: aSize = size; sl@0: return r; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::GetCSEndpointDescriptorTC(DThread* aThread, TDes8& aBuffer, TInt aInterface, sl@0: TInt aSetting, TUint8 aEndpointAddress) const sl@0: { sl@0: // first find the endpoint sl@0: TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress); sl@0: if (i < 0) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such endpoint"))); sl@0: return KErrNotFound; sl@0: } sl@0: TInt r = KErrNotFound; sl@0: TInt offset = 0; sl@0: const TInt count = iDescriptors.Count(); sl@0: while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint) sl@0: { sl@0: __THREADWRITEOFFSET(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), offset); sl@0: if (r != KErrNone) sl@0: break; sl@0: offset += iDescriptors[i]->Size(); sl@0: } sl@0: return r; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::SetCSEndpointDescriptorTC(DThread* aThread, const TDes8& aBuffer, TInt aInterface, sl@0: TInt aSetting, TUint8 aEndpointAddress, TInt aSize) sl@0: { sl@0: // first find the endpoint sl@0: TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress); sl@0: if (i < 0) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such endpoint"))); sl@0: return KErrNotFound; sl@0: } sl@0: // find a position where to insert the new class specific endpoint descriptor(s) sl@0: const TInt count = iDescriptors.Count(); sl@0: while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint) sl@0: ; sl@0: // create a new cs descriptor sl@0: TUsbcClassSpecificDescriptor* desc = TUsbcClassSpecificDescriptor::New(KUsbDescType_CS_Endpoint, aSize); sl@0: if (!desc) sl@0: { sl@0: return KErrNoMemory; sl@0: } sl@0: iDescriptors.Insert(desc, i); sl@0: if (iDescriptors[1]) sl@0: { sl@0: // if there's a config descriptor (and not a NULL pointer), we update its wTotalLength field sl@0: iDescriptors[1]->SetWord(2, (TUint8)(iDescriptors[1]->Word(2) + aSize)); sl@0: } sl@0: // copy contents from user side sl@0: return __THREADREAD(aThread, &aBuffer, iDescriptors[i]->DescriptorData()); sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::GetCSEndpointDescriptorSize(TInt aInterface, TInt aSetting, sl@0: TUint8 aEndpointAddress, TInt& aSize) const sl@0: { sl@0: // first find the endpoint sl@0: TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress); sl@0: if (i < 0) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such endpoint"))); sl@0: return KErrNotFound; sl@0: } sl@0: TInt r = KErrNotFound; sl@0: TInt size = 0; sl@0: const TInt count = iDescriptors.Count(); sl@0: while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint) sl@0: { sl@0: size += iDescriptors[i]->Size(); sl@0: r = KErrNone; sl@0: } sl@0: if (r == KErrNone) sl@0: aSize = size; sl@0: return r; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::GetManufacturerStringDescriptorTC(DThread* aThread, TDes8& aString) const sl@0: { sl@0: return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Manufact); sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::SetManufacturerStringDescriptorTC(DThread* aThread, const TDes8& aString) sl@0: { sl@0: return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Manufact); sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::GetProductStringDescriptorTC(DThread* aThread, TDes8& aString) const sl@0: { sl@0: return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Product); sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::SetProductStringDescriptorTC(DThread* aThread, const TDes8& aString) sl@0: { sl@0: return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Product); sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::GetSerialNumberStringDescriptorTC(DThread* aThread, TDes8& aString) const sl@0: { sl@0: return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Serial); sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::SetSerialNumberStringDescriptorTC(DThread* aThread, const TDes8& aString) sl@0: { sl@0: return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Serial); sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::GetConfigurationStringDescriptorTC(DThread* aThread, TDes8& aString) const sl@0: { sl@0: TBuf8 config_desc; sl@0: iDescriptors[1]->GetDescriptorData(config_desc); sl@0: const TInt str_idx = config_desc[KUsbDescStringIndex_Config]; sl@0: if ((str_idx > 0) && iStrings[str_idx]) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" String @ pos %d (conf $): \"%S\""), sl@0: str_idx, &iStrings[str_idx]->StringData())); sl@0: return __THREADWRITE(aThread, &aString, iStrings[str_idx]->StringData()); sl@0: } sl@0: else sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no string descriptor @ pos %d!"), str_idx)); sl@0: return KErrNotFound; sl@0: } sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::SetConfigurationStringDescriptorTC(DThread* aThread, const TDes8& aString) sl@0: { sl@0: // we don't know the length of the string, so we have to allocate memory dynamically sl@0: TUint strlen = __THREADDESLEN(aThread, &aString); sl@0: if (strlen > KUsbStringDescStringMaxSize) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Warning: $ descriptor too long - string will be truncated"))); sl@0: strlen = KUsbStringDescStringMaxSize; sl@0: } sl@0: sl@0: HBuf8Plat* strbuf = NULL; sl@0: __NEWPLATBUF(strbuf, strlen); sl@0: if (!strbuf) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: Memory allocation for config $ desc string failed (1)"))); sl@0: return KErrNoMemory; sl@0: } sl@0: sl@0: TInt r; sl@0: __THREADREADPLATBUF(aThread, &aString, strbuf, r); sl@0: if (r != KErrNone) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: Thread read error"))); sl@0: delete strbuf; sl@0: return r; sl@0: } sl@0: TUsbcStringDescriptor* sd = TUsbcStringDescriptor::New(*strbuf); sl@0: if (!sd) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: Memory allocation for config $ desc failed (2)"))); sl@0: delete strbuf; sl@0: return KErrNoMemory; sl@0: } sl@0: TBuf8 config_desc; sl@0: config_desc.FillZ(config_desc.MaxLength()); sl@0: iDescriptors[1]->GetDescriptorData(config_desc); sl@0: ExchangeStringDescriptor(config_desc[KUsbDescStringIndex_Config], sd); sl@0: delete strbuf; sl@0: return r; sl@0: } sl@0: sl@0: sl@0: // --- private --- sl@0: sl@0: void TUsbcDescriptorPool::InsertDevDesc(TUsbcDescriptorBase* aDesc) sl@0: { sl@0: TInt count = iDescriptors.Count(); sl@0: if (count > 0) sl@0: { sl@0: DeleteDescriptors(0); // if there's already something at pos. 0, delete it sl@0: } sl@0: iDescriptors.Insert(aDesc, 0); // in any case: put the new descriptor at position 0 sl@0: } sl@0: sl@0: sl@0: void TUsbcDescriptorPool::InsertConfigDesc(TUsbcDescriptorBase* aDesc) sl@0: { sl@0: TInt count = iDescriptors.Count(); sl@0: if (count == 0) sl@0: { sl@0: TUsbcDescriptorBase* const iNullDesc = NULL; sl@0: iDescriptors.Append(iNullDesc); // if array's empty, put a dummy in position 0 sl@0: } sl@0: else if (count > 1) sl@0: { sl@0: DeleteDescriptors(1); // if there's already something at pos. 1, delete it sl@0: } sl@0: iDescriptors.Insert(aDesc, 1); // in any case: put the new descriptor at position 1 sl@0: // Currently this code assumes, that the config descriptor is inserted _before_ any interface sl@0: // or endpoint descriptors! sl@0: if (iDescriptors.Count() != 2) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertConfigDesc: config descriptor will be invalid!"))); sl@0: } sl@0: } sl@0: sl@0: sl@0: void TUsbcDescriptorPool::InsertIfcDesc(TUsbcDescriptorBase* aDesc) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertIfcDesc()"))); sl@0: TInt count = iDescriptors.Count(); sl@0: if (count < 2) sl@0: { sl@0: TUsbcDescriptorBase* const iNullDesc = NULL; sl@0: iDescriptors.Append(iNullDesc); // if array's too small, put some dummies in sl@0: iDescriptors.Append(iNullDesc); sl@0: } sl@0: TBool interface_exists = EFalse; // set to 'true' if we're adding an alternate sl@0: // setting to an already existing interface sl@0: TInt i = 2; sl@0: while (i < count) sl@0: { sl@0: if (iDescriptors[i]->Type() == KUsbDescType_Interface) sl@0: { sl@0: if (iDescriptors[i]->Byte(2) > aDesc->Byte(2)) sl@0: { sl@0: // our interface number is less than the one's just found => insert before it (= here) sl@0: break; sl@0: } sl@0: else if (iDescriptors[i]->Byte(2) == aDesc->Byte(2)) sl@0: { sl@0: interface_exists = ETrue; sl@0: // same interface number => look at settings number sl@0: if (iDescriptors[i]->Byte(3) > aDesc->Byte(3)) sl@0: { sl@0: // our setting number is less than the one's found => insert before (= here) sl@0: break; sl@0: } sl@0: else if (iDescriptors[i]->Byte(3) == aDesc->Byte(3)) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertIfcDesc: error: first delete old one!"))); sl@0: return; sl@0: } sl@0: } sl@0: } sl@0: ++i; sl@0: } sl@0: iDescriptors.Insert(aDesc, i); // in any case: put the new descriptor at position i sl@0: if (iDescriptors[1]) sl@0: { sl@0: // if there's a config descriptor (and not a NULL pointer), update its wTotalLength field... sl@0: iDescriptors[1]->SetWord(2, (TUint8)(iDescriptors[1]->Word(2) + KUsbDescSize_Interface)); sl@0: // and increment bNumInterfaces if this is the first setting for the interface sl@0: if (!interface_exists) sl@0: iDescriptors[1]->SetByte(4, (TUint8)(iDescriptors[1]->Byte(4) + 1)); sl@0: } sl@0: iIfcIdx = i; sl@0: } sl@0: sl@0: sl@0: void TUsbcDescriptorPool::InsertEpDesc(TUsbcDescriptorBase* aDesc) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertEpDesc()"))); sl@0: if (iIfcIdx == 0) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertEpDesc: error: only after interface"))); sl@0: return; sl@0: } sl@0: TInt count = iDescriptors.Count(); sl@0: TInt i = iIfcIdx + 1; sl@0: while (i < count) sl@0: { sl@0: if (iDescriptors[i]->Type() != KUsbDescType_Endpoint) sl@0: break; sl@0: ++i; sl@0: } sl@0: iDescriptors.Insert(aDesc, i); // put the new descriptor at position i sl@0: if (iDescriptors[1]) sl@0: { sl@0: // if there's a config descriptor (and not a NULL pointer), update its wTotalLength field sl@0: iDescriptors[1]->SetWord(2, (TUint8)(iDescriptors[1]->Word(2) + aDesc->Size())); sl@0: } sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::FindIfcDescriptor(TInt aIfcNumber, TInt aIfcSetting) const sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::FindIfcDescriptor(%d, %d)"), sl@0: aIfcNumber, aIfcSetting)); sl@0: TInt count = iDescriptors.Count(); sl@0: for (TInt i = 2; i < count; ++i) sl@0: { sl@0: if ((iDescriptors[i]->Type() == KUsbDescType_Interface) && sl@0: (iDescriptors[i]->Byte(2) == aIfcNumber) && sl@0: (iDescriptors[i]->Byte(3) == aIfcSetting)) sl@0: { sl@0: return i; sl@0: } sl@0: } sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such interface"))); sl@0: return -1; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::FindEpDescriptor(TInt aIfcNumber, TInt aIfcSetting, TUint8 aEpAddress) const sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::FindEpDescriptor(%d, %d, 0x%02x)"), sl@0: aIfcNumber, aIfcSetting, aEpAddress)); sl@0: // first find the interface sl@0: TInt ifc = FindIfcDescriptor(aIfcNumber, aIfcSetting); sl@0: if (ifc < 0) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such interface"))); sl@0: return ifc; sl@0: } sl@0: TInt count = iDescriptors.Count(); sl@0: // then, before the next interface, try to locate the endpoint sl@0: for (TInt i = ifc + 1; i < count; ++i) sl@0: { sl@0: if (iDescriptors[i]->Type() == KUsbDescType_Interface) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such endpoint before next interface"))); sl@0: return -1; sl@0: } sl@0: else if ((iDescriptors[i]->Type() == KUsbDescType_Endpoint) && sl@0: (iDescriptors[i]->Byte(2) == aEpAddress)) sl@0: { sl@0: return i; // found sl@0: } sl@0: } sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such endpoint"))); sl@0: return -1; sl@0: } sl@0: sl@0: sl@0: void TUsbcDescriptorPool::DeleteDescriptors(TInt aIndex, TInt aCount) sl@0: { sl@0: if (aCount <= 0) sl@0: { sl@0: return; sl@0: } sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" Removing descriptors at index %d:"), aIndex)); sl@0: while (aCount--) sl@0: { sl@0: // in this loop we don't decrement aIndex, because after deleting an element sl@0: // aIndex is already indexing the next one! sl@0: TUsbcDescriptorBase* ptr = iDescriptors[aIndex]; sl@0: if (iDescriptors[1]) sl@0: { sl@0: // if there's a config descriptor (and not a NULL pointer), sl@0: if (ptr->Type() == KUsbDescType_Interface) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" - an interface descriptor"))); sl@0: // if it's an interface descriptor: sl@0: // we update its wTotalLength field... sl@0: iDescriptors[1]->SetWord(2, (TUint8)(iDescriptors[1]->Word(2) - KUsbDescSize_Interface)); sl@0: } sl@0: else if (ptr->Type() == KUsbDescType_Endpoint) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" - an endpoint descriptor"))); sl@0: // if it's an endpoint descriptor: sl@0: // we only update its wTotalLength field sl@0: iDescriptors[1]->SetWord(2, (TUint8)(iDescriptors[1]->Word(2) - ptr->Size())); sl@0: } sl@0: else if (ptr->Type() == KUsbDescType_CS_Interface || ptr->Type() == KUsbDescType_CS_Endpoint) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" - a class specific descriptor"))); sl@0: // if it's an class specific descriptor: sl@0: // we only update its wTotalLength field sl@0: iDescriptors[1]->SetWord(2, (TUint8)(iDescriptors[1]->Word(2) - ptr->Size())); sl@0: } sl@0: } sl@0: iDescriptors.Remove(aIndex); sl@0: delete ptr; sl@0: } sl@0: } sl@0: sl@0: sl@0: void TUsbcDescriptorPool::DeleteString(TInt aIndex) sl@0: { sl@0: TUsbcStringDescriptorBase* ptr = iStrings[aIndex]; sl@0: iStrings.Remove(aIndex); sl@0: delete ptr; sl@0: } sl@0: sl@0: sl@0: void TUsbcDescriptorPool::UpdateIfcNumbers(TInt aNumber) sl@0: { sl@0: const TInt count = iDescriptors.Count(); sl@0: for (TInt i = 2; i < count; ++i) sl@0: { sl@0: if ((iDescriptors[i]->Type() == KUsbDescType_Interface) && sl@0: (iDescriptors[i]->Byte(2) == aNumber)) sl@0: { sl@0: // there's still an interface with 'number' so we don't need to update anything sl@0: return; sl@0: } sl@0: } sl@0: // if we haven't returned yet, we decrement bNumInterfaces sl@0: iDescriptors[1]->SetByte(4, (TUint8)(iDescriptors[1]->Byte(4) - 1)); sl@0: } sl@0: sl@0: sl@0: void TUsbcDescriptorPool::UpdateIfcStringIndexes(TInt aStringIndex) sl@0: { sl@0: // aStringIndex is the index value of the string descriptor that has just been removed. sl@0: // We update all ifc descriptors with a string index value that is greater than aStringIndex, sl@0: // because those strings moved all down by one position. sl@0: // sl@0: TInt count = iDescriptors.Count(); sl@0: for (TInt i = 2; i < count; ++i) sl@0: { sl@0: if ((iDescriptors[i]->Type() == KUsbDescType_Interface) && sl@0: (iDescriptors[i]->Byte(8) > aStringIndex)) sl@0: { sl@0: iDescriptors[i]->SetByte(8, (TUint8)(iDescriptors[i]->Byte(8) - 1)); sl@0: } sl@0: } sl@0: } sl@0: sl@0: sl@0: // sl@0: // Only used for Ep0 standard requests, so target buffer could be hard-wired. sl@0: // sl@0: TInt TUsbcDescriptorPool::GetDeviceDescriptor() const sl@0: { sl@0: return iDescriptors[0]->GetDescriptorData(iEp0_TxBuf, KUsbcBufSz_Ep0Tx); sl@0: } sl@0: sl@0: sl@0: // sl@0: // Only used for Ep0 standard requests, so target buffer could be hard-wired. sl@0: // sl@0: TInt TUsbcDescriptorPool::GetConfigDescriptor() const sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::GetConfigDescriptor()"))); sl@0: TInt copied = 0; sl@0: TInt count = iDescriptors.Count(); sl@0: TUint8* buf = iEp0_TxBuf; sl@0: for (TInt i = 1; i < count; ++i) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" > desc[%02d]: type = 0x%02x size = %d "), sl@0: i, iDescriptors[i]->Type(), iDescriptors[i]->Size())); sl@0: const TInt size = iDescriptors[i]->GetDescriptorData(buf, KUsbcBufSz_Ep0Tx - copied); sl@0: if (size == 0) sl@0: { sl@0: // There was no buffer space to copy the descriptor -> no use to proceed sl@0: break; sl@0: } sl@0: copied += size; sl@0: if (copied >= KUsbcBufSz_Ep0Tx) sl@0: { sl@0: // There's no buffer space left -> we need to stop copying here sl@0: break; sl@0: } sl@0: buf += size; sl@0: } sl@0: return copied; sl@0: } sl@0: sl@0: sl@0: // sl@0: // Only used for Ep0 standard requests, so target buffer could be hard-wired. sl@0: // sl@0: TInt TUsbcDescriptorPool::GetStringDescriptor(TInt aIndex) const sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::GetStringDescriptor()"))); sl@0: // I really would have liked to display here the descriptor contents, but without trailing zero sl@0: // we got a problem: how could we tell printf where the string ends? We would have to sl@0: // dynamically allocate memory (since we don't know the size in advance), copy the descriptor sl@0: // contents there, append a zero, and give this to printf. That's a bit too much effort... sl@0: if (iStrings[aIndex]) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" String @ pos %d"), aIndex)); sl@0: TInt size = iStrings[aIndex]->GetDescriptorData(iEp0_TxBuf, KUsbcBufSz_Ep0Tx); sl@0: return size; sl@0: } sl@0: else sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no descriptor @ pos %d!"), aIndex)); sl@0: return 0; sl@0: } sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::GetDeviceStringDescriptorTC(DThread* aThread, TDes8& aString, TInt aIndex) const sl@0: { sl@0: TBuf8 dev_desc; sl@0: iDescriptors[0]->GetDescriptorData(dev_desc); sl@0: const TInt str_idx = dev_desc[aIndex]; sl@0: if ((str_idx > 0) && iStrings[str_idx]) sl@0: { sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" String @ pos %d (device $): \"%S\""), sl@0: str_idx, &iStrings[str_idx]->StringData())); sl@0: return __THREADWRITE(aThread, &aString, iStrings[str_idx]->StringData()); sl@0: } sl@0: else sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no string descriptor @ pos %d!"), str_idx)); sl@0: return KErrNotFound; sl@0: } sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::SetDeviceStringDescriptorTC(DThread* aThread, const TDes8& aString, TInt aIndex) sl@0: { sl@0: // we don't know the length of the string, so we have to allocate memory dynamically sl@0: TUint strlen = __THREADDESLEN(aThread, &aString); sl@0: if (strlen > KUsbStringDescStringMaxSize) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Warning: $ descriptor too long - string will be truncated"))); sl@0: strlen = KUsbStringDescStringMaxSize; sl@0: } sl@0: sl@0: HBuf8Plat* strbuf = NULL; sl@0: __NEWPLATBUF(strbuf, strlen); sl@0: if (!strbuf) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: Memory allocation for dev $ desc string failed (1)"))); sl@0: return KErrNoMemory; sl@0: } sl@0: sl@0: TInt r; sl@0: __THREADREADPLATBUF(aThread, &aString, strbuf, r); sl@0: if (r != KErrNone) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: Thread read error"))); sl@0: delete strbuf; sl@0: return r; sl@0: } sl@0: TUsbcStringDescriptor* sd = TUsbcStringDescriptor::New(*strbuf); sl@0: if (!sd) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: Memory allocation for dev $ desc failed (2)"))); sl@0: delete strbuf; sl@0: return KErrNoMemory; sl@0: } sl@0: TBuf8 dev_desc; sl@0: dev_desc.FillZ(dev_desc.MaxLength()); sl@0: iDescriptors[0]->GetDescriptorData(dev_desc); sl@0: ExchangeStringDescriptor(dev_desc[aIndex], sd); sl@0: delete strbuf; sl@0: return r; sl@0: } sl@0: sl@0: sl@0: TInt TUsbcDescriptorPool::ExchangeStringDescriptor(TInt aIndex, const TUsbcStringDescriptor* aDesc) sl@0: { sl@0: if (aIndex <= 0) sl@0: { sl@0: __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: invalid string descriptor index: %d!"), aIndex)); sl@0: return KErrArgument; sl@0: } sl@0: __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" Exchanging string descriptor @ index %d"), aIndex)); sl@0: DeleteString(aIndex); sl@0: iStrings.Insert(aDesc, aIndex); sl@0: return KErrNone; sl@0: } sl@0: sl@0: sl@0: // -eof-