First public contribution.
1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of the License "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // f32test\testusbcldd\src\descriptors.cpp
15 // Platform independent USB client controller layer (PIL):
16 // USB descriptor handling and management.
21 #include "dtestusblogdev.h"
23 // --- TUsbcDescriptorBase
25 TUsbcDescriptorBase::TUsbcDescriptorBase()
27 #ifdef USB_SUPPORTS_SET_DESCRIPTOR_REQUEST
32 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorBase::TUsbcDescriptorBase()")));
36 TUsbcDescriptorBase::~TUsbcDescriptorBase()
38 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorBase::~TUsbcDescriptorBase()")));
42 void TUsbcDescriptorBase::SetByte(TUint aPosition, TUint8 aValue)
44 iBufPtr[aPosition] = aValue;
48 void TUsbcDescriptorBase::SetWord(TUint aPosition, TUint16 aValue)
50 *reinterpret_cast<TUint16*>(&iBufPtr[aPosition]) = SWAP_BYTES_16(aValue);
54 TUint8 TUsbcDescriptorBase::Byte(TUint aPosition) const
56 return iBufPtr[aPosition];
60 TUint16 TUsbcDescriptorBase::Word(TUint aPosition) const
62 return SWAP_BYTES_16(*reinterpret_cast<const TUint16*>(&iBufPtr[aPosition]));
66 void TUsbcDescriptorBase::GetDescriptorData(TDes8& aBuffer) const
72 TInt TUsbcDescriptorBase::GetDescriptorData(TUint8* aBuffer) const
74 __MEMCPY(aBuffer, iBufPtr.Ptr(), Size());
79 TInt TUsbcDescriptorBase::GetDescriptorData(TUint8* aBuffer, TInt aMaxSize) const
81 if (aMaxSize < Size())
83 // No use to copy only half a descriptor
86 return GetDescriptorData(aBuffer);
90 const TDes8& TUsbcDescriptorBase::DescriptorData() const
96 TDes8& TUsbcDescriptorBase::DescriptorData()
102 TInt TUsbcDescriptorBase::Size() const
104 return iBufPtr.Size();
108 TUint8 TUsbcDescriptorBase::Type() const
114 void TUsbcDescriptorBase::SetBufferPointer(const TDesC8& aDes)
116 iBufPtr.Set(const_cast<TUint8*>(aDes.Ptr()), aDes.Size(), aDes.Size());
120 // --- TUsbcDeviceDescriptor
122 TUsbcDeviceDescriptor::TUsbcDeviceDescriptor()
125 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDeviceDescriptor::TUsbcDeviceDescriptor()")));
129 TUsbcDeviceDescriptor* TUsbcDeviceDescriptor::New(TUint8 aDeviceClass, TUint8 aDeviceSubClass,
130 TUint8 aDeviceProtocol, TUint8 aMaxPacketSize0,
131 TUint16 aVendorId, TUint16 aProductId,
132 TUint16 aDeviceRelease, TUint8 aNumConfigurations)
134 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDeviceDescriptor::New()")));
135 TUsbcDeviceDescriptor* self = new TUsbcDeviceDescriptor();
138 if (self->Construct(aDeviceClass, aDeviceSubClass, aDeviceProtocol, aMaxPacketSize0, aVendorId,
139 aProductId, aDeviceRelease, aNumConfigurations) != KErrNone)
149 TInt TUsbcDeviceDescriptor::Construct(TUint8 aDeviceClass, TUint8 aDeviceSubClass, TUint8 aDeviceProtocol,
150 TUint8 aMaxPacketSize0, TUint16 aVendorId, TUint16 aProductId,
151 TUint16 aDeviceRelease, TUint8 aNumConfigurations)
153 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDeviceDescriptor::Construct()")));
155 SetBufferPointer(iBuf);
156 iBuf[0] = (TUint8)iBuf.Size(); // bLength
157 iBuf[1] = KUsbDescType_Device; // bDescriptorType
158 SetWord(2, KUsbcUsbVersion); // bcdUSB
159 iBuf[4] = aDeviceClass; // bDeviceClass
160 iBuf[5] = aDeviceSubClass; // bDeviceSubClass
161 iBuf[6] = aDeviceProtocol; // bDeviceProtocol
162 iBuf[7] = aMaxPacketSize0; // bMaxPacketSize0
163 SetWord(8, aVendorId); // idVendor
164 SetWord(10, aProductId); // idProduct
165 SetWord(12, aDeviceRelease); // bcdDevice
166 iBuf[14] = 0; // iManufacturer
167 iBuf[15] = 0; // iProduct
168 iBuf[16] = 0; // iSerialNumber
169 iBuf[17] = aNumConfigurations; // bNumConfigurations
173 // --- TUsbcConfigDescriptor
175 TUsbcConfigDescriptor::TUsbcConfigDescriptor()
178 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcConfigDescriptor::TUsbcConfigDescriptor()")));
182 TUsbcConfigDescriptor* TUsbcConfigDescriptor::New(TUint8 aConfigurationValue, TBool aSelfPowered,
183 TBool aRemoteWakeup, TUint8 aMaxPower)
185 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcConfigDescriptor::New()")));
186 TUsbcConfigDescriptor* self = new TUsbcConfigDescriptor();
189 if (self->Construct(aConfigurationValue, aSelfPowered, aRemoteWakeup, aMaxPower) != KErrNone)
199 TInt TUsbcConfigDescriptor::Construct(TUint8 aConfigurationValue, TBool aSelfPowered,
200 TBool aRemoteWakeup, TUint8 aMaxPower)
202 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcConfigDescriptor::Construct()")));
204 SetBufferPointer(iBuf);
205 iBuf[0] = (TUint8)iBuf.Size(); // bLength
206 iBuf[1] = KUsbDescType_Config; // bDescriptorType
207 SetWord(2, KUsbDescSize_Config); // wTotalLength
208 iBuf[4] = 0; // bNumInterfaces
209 iBuf[5] = aConfigurationValue; // bConfigurationValue
210 iBuf[6] = 0; // iConfiguration
211 iBuf[7] = (TUint8)(0x80 | (aSelfPowered ? 0x40 : 0) | (aRemoteWakeup ? 0x20 : 0)); // bmAttributes (bit 7 always 1)
212 iBuf[8] = (TUint8)(aMaxPower / 2); // MaxPower (2mA units!)
217 // --- TUsbcInterfaceDescriptor
219 TUsbcInterfaceDescriptor::TUsbcInterfaceDescriptor()
222 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcInterfaceDescriptor::TUsbcInterfaceDescriptor()")));
226 TUsbcInterfaceDescriptor* TUsbcInterfaceDescriptor::New(TUint8 aInterfaceNumber, TUint8 aAlternateSetting,
227 TInt aNumEndpoints, const TUsbcClassInfo& aClassInfo)
229 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcInterfaceDescriptor::New()")));
230 TUsbcInterfaceDescriptor* self = new TUsbcInterfaceDescriptor();
233 if (self->Construct(aInterfaceNumber, aAlternateSetting, aNumEndpoints, aClassInfo) != KErrNone)
243 TInt TUsbcInterfaceDescriptor::Construct(TUint8 aInterfaceNumber, TUint8 aAlternateSetting,
244 TInt aNumEndpoints, const TUsbcClassInfo& aClassInfo)
246 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcInterfaceDescriptor::Construct()")));
248 SetBufferPointer(iBuf);
249 iBuf[0] = (TUint8)iBuf.Size(); // bLength
250 iBuf[1] = KUsbDescType_Interface; // bDescriptorType
251 iBuf[2] = aInterfaceNumber; // bInterfaceNumber
252 iBuf[3] = aAlternateSetting; // bAlternateSetting
253 iBuf[4] = (TUint8)aNumEndpoints; // bNumEndpoints
254 iBuf[5] = (TUint8)aClassInfo.iClassNum; // bInterfaceClass
255 iBuf[6] = (TUint8)aClassInfo.iSubClassNum; // bInterfaceSubClass
256 iBuf[7] = (TUint8)aClassInfo.iProtocolNum; // bInterfaceProtocol
257 iBuf[8] = 0; // iInterface
262 // --- TUsbcEndpointDescriptor
264 TUsbcEndpointDescriptor::TUsbcEndpointDescriptor()
267 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcEndpointDescriptor::TUsbcEndpointDescriptor()")));
271 TUsbcEndpointDescriptor* TUsbcEndpointDescriptor::New(TUint8 aEndpointAddress,
272 const TUsbcEndpointInfo& aEpInfo)
274 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcEndpointDescriptor::New()")));
275 TUsbcEndpointDescriptor* self = new TUsbcEndpointDescriptor();
278 if (self->Construct(aEndpointAddress, aEpInfo) != KErrNone)
288 TInt TUsbcEndpointDescriptor::Construct(TUint8 aEndpointAddress, const TUsbcEndpointInfo& aEpInfo)
290 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcEndpointDescriptor::Construct()")));
292 SetBufferPointer(iBuf);
293 iBuf[0] = (TUint8)iBuf.Size(); // bLength
294 iBuf[1] = KUsbDescType_Endpoint; // bDescriptorType
295 iBuf[2] = aEndpointAddress; // bEndpointAddress
296 iBuf[3] = (TUint8)EpTypeMask2Value(aEpInfo.iType); // bmAttributes
297 SetWord(4, (TUint8)aEpInfo.iSize); // wMaxPacketSize
298 iBuf[6] = (TUint8)aEpInfo.iInterval; // bInterval
303 // --- TUsbcAudioEndpointDescriptor
305 TUsbcAudioEndpointDescriptor::TUsbcAudioEndpointDescriptor()
308 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcAudioEndpointDescriptor::TUsbcAudioEndpointDescriptor()")));
312 TUsbcAudioEndpointDescriptor* TUsbcAudioEndpointDescriptor::New(TUint8 aEndpointAddress,
313 const TUsbcEndpointInfo& aEpInfo)
315 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcAudioEndpointDescriptor::New()")));
316 TUsbcAudioEndpointDescriptor* self = new TUsbcAudioEndpointDescriptor();
319 if (self->Construct(aEndpointAddress, aEpInfo) != KErrNone)
329 TInt TUsbcAudioEndpointDescriptor::Construct(TUint8 aEndpointAddress, const TUsbcEndpointInfo& aEpInfo)
331 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcAudioEndpointDescriptor::Construct()")));
333 SetBufferPointer(iBuf);
334 iBuf[0] = (TUint8)iBuf.Size(); // bLength
335 iBuf[1] = KUsbDescType_Endpoint; // bDescriptorType
336 iBuf[2] = aEndpointAddress; // bEndpointAddress
337 iBuf[3] = (TUint8)EpTypeMask2Value(aEpInfo.iType); // bmAttributes
338 SetWord(4, (TUint8)aEpInfo.iSize); // wMaxPacketSize
339 iBuf[6] = (TUint8)aEpInfo.iInterval; // bInterval
346 // --- TUsbcClassSpecificDescriptor
348 TUsbcClassSpecificDescriptor::TUsbcClassSpecificDescriptor()
351 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcClassSpecificDescriptor::TUsbcClassSpecificDescriptor()")));
355 TUsbcClassSpecificDescriptor::~TUsbcClassSpecificDescriptor()
357 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcClassSpecificDescriptor::~TUsbcClassSpecificDescriptor()")));
362 TUsbcClassSpecificDescriptor* TUsbcClassSpecificDescriptor::New(TUint8 aType, TInt aSize)
364 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcClassSpecificDescriptor::New()")));
365 TUsbcClassSpecificDescriptor* self = new TUsbcClassSpecificDescriptor();
368 if (self->Construct(aType, aSize) != KErrNone)
378 TInt TUsbcClassSpecificDescriptor::Construct(TUint8 aType, TInt aSize)
380 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcClassSpecificDescriptor::Construct()")));
381 __NEWPLATBUF(iBuf, aSize);
384 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: Allocation of CS desc buffer failed")));
387 SetBufferPointer(*iBuf);
388 SetByte(1, aType); // bDescriptorType
393 // --- TUsbcStringDescriptorBase
395 TUsbcStringDescriptorBase::TUsbcStringDescriptorBase()
396 : /*iIndex(0),*/ iSBuf(0), iBufPtr(NULL, 0)
398 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptorBase::TUsbcStringDescriptorBase()")));
402 TUsbcStringDescriptorBase::~TUsbcStringDescriptorBase()
404 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptorBase::~TUsbcStringDescriptorBase()")));
408 TUint16 TUsbcStringDescriptorBase::Word(TUint aPosition) const
412 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("TUsbcStringDescriptorBase::Word: Error: Word(%d) in string descriptor!"), aPosition));
417 // since iBufPtr[0] is actually string descriptor byte index 2,
418 // we have to subtract 2 from the absolute position.
419 return SWAP_BYTES_16(*reinterpret_cast<const TUint16*>(&iBufPtr[aPosition - 2]));
424 TInt TUsbcStringDescriptorBase::GetDescriptorData(TUint8* aBuffer) const
426 aBuffer[0] = iSBuf[0];
427 aBuffer[1] = iSBuf[1];
428 __MEMCPY(&aBuffer[2], iBufPtr.Ptr(), iBufPtr.Size());
433 TInt TUsbcStringDescriptorBase::GetDescriptorData(TUint8* aBuffer, TInt aMaxSize) const
435 if (aMaxSize < Size())
437 // No use to copy only half a string
440 return GetDescriptorData(aBuffer);
444 const TDes8& TUsbcStringDescriptorBase::StringData() const
450 TDes8& TUsbcStringDescriptorBase::StringData()
456 TInt TUsbcStringDescriptorBase::Size() const
462 void TUsbcStringDescriptorBase::SetBufferPointer(const TDesC8& aDes)
464 iBufPtr.Set(const_cast<TUint8*>(aDes.Ptr()), aDes.Size(), aDes.Size());
468 // --- TUsbcStringDescriptor
470 TUsbcStringDescriptor::TUsbcStringDescriptor()
473 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptor::TUsbcStringDescriptor()")));
477 TUsbcStringDescriptor::~TUsbcStringDescriptor()
479 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptor::~TUsbcStringDescriptor()")));
484 TUsbcStringDescriptor* TUsbcStringDescriptor::New(const TDesC8& aString)
486 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptor::New")));
487 TUsbcStringDescriptor* self = new TUsbcStringDescriptor();
490 if (self->Construct(aString) != KErrNone)
500 TInt TUsbcStringDescriptor::Construct(const TDesC8& aString)
502 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptor::Construct")));
503 __NEWPLATBUF(iBuf, aString.Size());
506 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: Allocation of string buffer failed")));
509 SetBufferPointer(*iBuf);
510 iBufPtr.Copy(aString);
512 iSBuf[0] = (TUint8)(iBuf->Size() + 2); // Bytes
513 iSBuf[1] = KUsbDescType_String;
518 // --- TUsbcLangIdDescriptor
520 TUsbcLangIdDescriptor::TUsbcLangIdDescriptor()
523 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcLangIdDescriptor::TUsbcLangIdDescriptor()")));
527 TUsbcLangIdDescriptor::~TUsbcLangIdDescriptor()
529 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcLangIdDescriptor::~TUsbcLangIdDescriptor()")));
533 TUsbcLangIdDescriptor* TUsbcLangIdDescriptor::New(TUint16 aLangId)
535 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcLangIdDescriptor::New")));
536 TUsbcLangIdDescriptor* self = new TUsbcLangIdDescriptor();
539 if (self->Construct(aLangId) != KErrNone)
549 TInt TUsbcLangIdDescriptor::Construct(TUint16 aLangId)
551 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcLangIdDescriptor::Construct")));
553 SetBufferPointer(iBuf);
554 iBufPtr[0] = LowByte(SWAP_BYTES_16(aLangId)); // Language ID value
555 iBufPtr[1] = HighByte(SWAP_BYTES_16(aLangId));
557 iSBuf[0] = (TUint8)(iBuf.Size() + 2); // Bytes
558 iSBuf[1] = KUsbDescType_String;
563 // --- TUsbcDescriptorPool
565 TUsbcDescriptorPool::TUsbcDescriptorPool(TUint8* aEp0_TxBuf)
567 // The constructor for this class.
569 : iDescriptors(4), iStrings(4), iIfcIdx(0), iEp0_TxBuf(aEp0_TxBuf) // 4 = granularity
571 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::TUsbcDescriptorPool()")));
575 TUsbcDescriptorPool::~TUsbcDescriptorPool()
577 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::~TUsbcDescriptorPool()")));
578 // The destructor of each <class T> object is called before the objects themselves are destroyed.
579 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" iDescriptors.Count(): %d"), iDescriptors.Count()));
580 iDescriptors.ResetAndDestroy();
581 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" iStrings.Count(): %d"), iStrings.Count()));
582 iStrings.ResetAndDestroy();
586 TInt TUsbcDescriptorPool::Init(TUsbcDeviceDescriptor* aDeviceDesc, TUsbcConfigDescriptor* aConfigDesc,
587 TUsbcLangIdDescriptor* aLangId, TUsbcStringDescriptor* aManufacturer,
588 TUsbcStringDescriptor* aProduct, TUsbcStringDescriptor* aSerialNum,
589 TUsbcStringDescriptor* aConfig)
591 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::Init()")));
592 iDescriptors.Insert(aDeviceDesc, 0);
593 iDescriptors.Insert(aConfigDesc, 1);
594 if (!aLangId || !aManufacturer || !aProduct || !aSerialNum || !aConfig)
596 // USB spec p. 202 says: "A USB device may omit all string descriptors."
597 // So, either ALL string descriptors are supplied or none at all.
598 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: No string descriptor(s)")));
601 iStrings.Insert(aLangId, 0);
602 iStrings.Insert(aManufacturer, 1);
603 iStrings.Insert(aProduct, 2);
604 iStrings.Insert(aSerialNum, 3);
605 iStrings.Insert(aConfig, 4);
606 // set string indices
607 iDescriptors[0]->SetByte(14, 1); // Device.iManufacturer
608 iDescriptors[0]->SetByte(15, 2); // Device.iProduct
609 iDescriptors[0]->SetByte(16, 3); // Device.iSerialNumber
610 iDescriptors[1]->SetByte( 6, 4); // Config.iConfiguration
615 TInt TUsbcDescriptorPool::FindDescriptor(TUint8 aType, TUint8 aIndex, TUint16 aLangid, TInt& aSize) const
617 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::FindDescriptor()")));
618 TInt result = KErrGeneral;
622 case KUsbDescType_Device:
625 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: bad langid: 0x%04x"), aLangid));
626 result = KErrGeneral; // bad langid
630 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: bad device index: %d"), aIndex));
631 result = KErrGeneral; // we have only one device
635 aSize = GetDeviceDescriptor();
639 case KUsbDescType_Config:
642 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: bad langid: 0x%04x"), aLangid));
643 result = KErrGeneral; // bad langid
647 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: bad config index: %d"), aIndex));
648 result = KErrGeneral; // we have only one configuration
652 aSize = GetConfigDescriptor();
656 case KUsbDescType_String:
657 if ((aLangid != 0) && // 0 addresses the LangId array
658 (aLangid != iStrings[0]->Word(2))) // we have just one (this) language
660 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: bad langid (0x%04x requested, 0x%04x supported)"),
661 aLangid, iStrings[0]->Word(2)));
662 result = KErrGeneral; // bad langid
664 else if (aIndex >= iStrings.Count())
666 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: bad string index: %d"), aIndex));
667 result = KErrGeneral;
671 aSize = GetStringDescriptor(aIndex);
675 case KUsbDescType_CS_Interface:
677 case KUsbDescType_CS_Endpoint:
678 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Warning: finding of class specific descriptors not supported")));
681 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: unknown descriptor type requested: %d"), aType));
682 result = KErrGeneral;
690 void TUsbcDescriptorPool::InsertDescriptor(TUsbcDescriptorBase* aDesc)
692 switch (aDesc->Type())
694 case KUsbDescType_Device:
695 InsertDevDesc(aDesc);
697 case KUsbDescType_Config:
698 InsertConfigDesc(aDesc);
700 case KUsbDescType_Interface:
701 InsertIfcDesc(aDesc);
703 case KUsbDescType_Endpoint:
706 case KUsbDescType_CS_Interface:
708 case KUsbDescType_CS_Endpoint:
709 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Warning: inserting class specific descriptors not supported")));
712 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertDescriptor: Error: invalid type")));
718 void TUsbcDescriptorPool::SetIfcStringDescriptor(TUsbcStringDescriptor* aDesc, TInt aNumber, TInt aSetting)
720 TInt i = FindIfcDescriptor(aNumber, aSetting);
723 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::SetIfcStringDescriptor: error")));
726 // Set (append) string descriptor for specified interface
727 iStrings.Append(aDesc);
728 // Update this ifc descriptors' string index field
729 const TInt str_idx = iStrings.Count() - 1;
730 iDescriptors[i]->SetByte(8, (TUint8)str_idx);
731 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" String for ifc %d/%d (@ pos %d): \"%S\""), aNumber, aSetting, str_idx,
732 &iStrings[str_idx]->StringData()));
736 void TUsbcDescriptorPool::DeleteIfcDescriptor(TInt aNumber, TInt aSetting)
738 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::DeleteIfcDescriptor(%d, %d)"), aNumber, aSetting));
739 TInt i = FindIfcDescriptor(aNumber, aSetting);
742 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" > Error: descriptor not found")));
745 // Delete (if necessary) specified interface's string descriptor
746 TInt si = iDescriptors[i]->Byte(8);
751 // Delete specified ifc setting + all its cs descriptors + all its endpoints + all their cs descriptors:
752 // find position of the next interface descriptor: we need to delete everything in between
753 const TInt count = iDescriptors.Count();
755 while (++j < count && iDescriptors[j]->Type() != KUsbDescType_Interface)
757 DeleteDescriptors(i, n);
758 // Update all the following interfaces' bInterfaceNumber field if required
759 // (because these descriptors might have moved down by one position)
760 UpdateIfcNumbers(aNumber);
761 // Update (if necessary) all interfaces' string index field
764 UpdateIfcStringIndexes(si);
766 iIfcIdx = 0; // ifc index no longer valid
770 // The TC in many of the following functions stands for 'ThreadCopy',
771 // because that's what's happening there.
773 TInt TUsbcDescriptorPool::GetDeviceDescriptorTC(DThread* aThread, TDes8& aBuffer) const
775 return __THREADWRITE(aThread, &aBuffer, iDescriptors[0]->DescriptorData());
779 TInt TUsbcDescriptorPool::SetDeviceDescriptorTC(DThread* aThread, const TDes8& aBuffer)
781 TBuf8<KUsbDescSize_Device> device;
782 TInt r = __THREADREAD(aThread, &aBuffer, device);
787 iDescriptors[0]->SetByte(2, device[2]); // bcdUSB
788 iDescriptors[0]->SetByte(3, device[3]); // bcdUSB (part II)
789 iDescriptors[0]->SetByte(4, device[4]); // bDeviceClass
790 iDescriptors[0]->SetByte(5, device[5]); // bDeviceSubClass
791 iDescriptors[0]->SetByte(6, device[6]); // bDeviceProtocol
792 iDescriptors[0]->SetByte(8, device[8]); // idVendor
793 iDescriptors[0]->SetByte(9, device[9]); // idVendor (part II)
794 iDescriptors[0]->SetByte(10, device[10]); // idProduct
795 iDescriptors[0]->SetByte(11, device[11]); // idProduct (part II)
796 iDescriptors[0]->SetByte(12, device[12]); // bcdDevice
797 iDescriptors[0]->SetByte(13, device[13]); // bcdDevice (part II)
802 TInt TUsbcDescriptorPool::GetConfigurationDescriptorTC(DThread* aThread, TDes8& aBuffer) const
804 return __THREADWRITE(aThread, &aBuffer, iDescriptors[1]->DescriptorData());
808 TInt TUsbcDescriptorPool::SetConfigurationDescriptorTC(DThread* aThread, const TDes8& aBuffer)
810 TBuf8<KUsbDescSize_Config> config;
811 TInt r = __THREADREAD(aThread, &aBuffer, config);
816 iDescriptors[1]->SetByte(7, config[7]); // bmAttributes
817 iDescriptors[1]->SetByte(8, config[8]); // bMaxPower
822 TInt TUsbcDescriptorPool::GetInterfaceDescriptorTC(DThread* aThread, TDes8& aBuffer,
823 TInt aInterface, TInt aSetting) const
825 TInt i = FindIfcDescriptor(aInterface, aSetting);
828 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such interface")));
831 return __THREADWRITE(aThread, &aBuffer, iDescriptors[i]->DescriptorData());
835 TInt TUsbcDescriptorPool::SetInterfaceDescriptor(const TDes8& aBuffer, TInt aInterface, TInt aSetting)
837 TInt i = FindIfcDescriptor(aInterface, aSetting);
840 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such interface")));
843 iDescriptors[i]->SetByte(2, aBuffer[2]); // bInterfaceNumber
844 iDescriptors[i]->SetByte(5, aBuffer[5]); // bInterfaceClass
845 iDescriptors[i]->SetByte(6, aBuffer[6]); // bInterfaceSubClass
846 iDescriptors[i]->SetByte(7, aBuffer[7]); // bInterfaceProtocol
851 TInt TUsbcDescriptorPool::GetEndpointDescriptorTC(DThread* aThread, TDes8& aBuffer,
852 TInt aInterface, TInt aSetting, TUint8 aEndpointAddress) const
854 TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
857 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such endpoint")));
860 return __THREADWRITE(aThread, &aBuffer, iDescriptors[i]->DescriptorData());
864 TInt TUsbcDescriptorPool::SetEndpointDescriptorTC(DThread* aThread, const TDes8& aBuffer,
865 TInt aInterface, TInt aSetting, TUint8 aEndpointAddress)
867 TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
870 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such endpoint")));
873 TBuf8<KUsbDescSize_AudioEndpoint> ep; // it could be an audio endpoint
874 TInt r = __THREADREAD(aThread, &aBuffer, ep);
879 iDescriptors[i]->SetByte(3, ep[3]); // bmAttributes
880 iDescriptors[i]->SetByte(6, ep[6]); // bInterval
881 if (static_cast<TUint>(iDescriptors[i]->Size()) == KUsbDescSize_AudioEndpoint)
883 iDescriptors[i]->SetByte(7, ep[7]); // bRefresh
884 iDescriptors[i]->SetByte(8, ep[8]); // bSynchAddress
890 TInt TUsbcDescriptorPool::GetEndpointDescriptorSize(TInt aInterface, TInt aSetting, TUint8 aEndpointAddress,
893 TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
896 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such endpoint")));
899 aSize = iDescriptors[i]->Size();
904 TInt TUsbcDescriptorPool::GetCSInterfaceDescriptorTC(DThread* aThread, TDes8& aBuffer,
905 TInt aInterface, TInt aSetting) const
907 // first find the interface
908 TInt i = FindIfcDescriptor(aInterface, aSetting);
911 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such interface")));
914 TInt r = KErrNotFound;
916 const TInt count = iDescriptors.Count();
917 while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface)
919 r = __THREADWRITEOFFSET(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), offset);
922 offset += iDescriptors[i]->Size();
928 TInt TUsbcDescriptorPool::SetCSInterfaceDescriptorTC(DThread* aThread, const TDes8& aBuffer,
929 TInt aInterface, TInt aSetting, TInt aSize)
931 // first find the interface
932 TInt i = FindIfcDescriptor(aInterface, aSetting);
935 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such interface")));
938 // find a position where to insert the new class specific interface descriptor(s)
939 const TInt count = iDescriptors.Count();
940 while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface)
942 // create a new cs descriptor
943 TUsbcClassSpecificDescriptor* desc = TUsbcClassSpecificDescriptor::New(KUsbDescType_CS_Interface, aSize);
948 iDescriptors.Insert(desc, i);
951 // if there's a config descriptor (and not a NULL pointer), we update its wTotalLength field
952 iDescriptors[1]->SetWord(2, (TUint8)(iDescriptors[1]->Word(2) + aSize));
954 // copy contents from user side
955 return __THREADREAD(aThread, &aBuffer, iDescriptors[i]->DescriptorData());
959 TInt TUsbcDescriptorPool::GetCSInterfaceDescriptorSize(TInt aInterface, TInt aSetting, TInt& aSize) const
961 // first find the interface
962 TInt i = FindIfcDescriptor(aInterface, aSetting);
965 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such interface")));
968 TInt r = KErrNotFound;
970 const TInt count = iDescriptors.Count();
971 while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface)
973 size += iDescriptors[i]->Size();
982 TInt TUsbcDescriptorPool::GetCSEndpointDescriptorTC(DThread* aThread, TDes8& aBuffer, TInt aInterface,
983 TInt aSetting, TUint8 aEndpointAddress) const
985 // first find the endpoint
986 TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
989 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such endpoint")));
992 TInt r = KErrNotFound;
994 const TInt count = iDescriptors.Count();
995 while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint)
997 __THREADWRITEOFFSET(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), offset);
1000 offset += iDescriptors[i]->Size();
1006 TInt TUsbcDescriptorPool::SetCSEndpointDescriptorTC(DThread* aThread, const TDes8& aBuffer, TInt aInterface,
1007 TInt aSetting, TUint8 aEndpointAddress, TInt aSize)
1009 // first find the endpoint
1010 TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
1013 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such endpoint")));
1014 return KErrNotFound;
1016 // find a position where to insert the new class specific endpoint descriptor(s)
1017 const TInt count = iDescriptors.Count();
1018 while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint)
1020 // create a new cs descriptor
1021 TUsbcClassSpecificDescriptor* desc = TUsbcClassSpecificDescriptor::New(KUsbDescType_CS_Endpoint, aSize);
1024 return KErrNoMemory;
1026 iDescriptors.Insert(desc, i);
1027 if (iDescriptors[1])
1029 // if there's a config descriptor (and not a NULL pointer), we update its wTotalLength field
1030 iDescriptors[1]->SetWord(2, (TUint8)(iDescriptors[1]->Word(2) + aSize));
1032 // copy contents from user side
1033 return __THREADREAD(aThread, &aBuffer, iDescriptors[i]->DescriptorData());
1037 TInt TUsbcDescriptorPool::GetCSEndpointDescriptorSize(TInt aInterface, TInt aSetting,
1038 TUint8 aEndpointAddress, TInt& aSize) const
1040 // first find the endpoint
1041 TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
1044 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such endpoint")));
1045 return KErrNotFound;
1047 TInt r = KErrNotFound;
1049 const TInt count = iDescriptors.Count();
1050 while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint)
1052 size += iDescriptors[i]->Size();
1061 TInt TUsbcDescriptorPool::GetManufacturerStringDescriptorTC(DThread* aThread, TDes8& aString) const
1063 return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Manufact);
1067 TInt TUsbcDescriptorPool::SetManufacturerStringDescriptorTC(DThread* aThread, const TDes8& aString)
1069 return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Manufact);
1073 TInt TUsbcDescriptorPool::GetProductStringDescriptorTC(DThread* aThread, TDes8& aString) const
1075 return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Product);
1079 TInt TUsbcDescriptorPool::SetProductStringDescriptorTC(DThread* aThread, const TDes8& aString)
1081 return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Product);
1085 TInt TUsbcDescriptorPool::GetSerialNumberStringDescriptorTC(DThread* aThread, TDes8& aString) const
1087 return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Serial);
1091 TInt TUsbcDescriptorPool::SetSerialNumberStringDescriptorTC(DThread* aThread, const TDes8& aString)
1093 return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Serial);
1097 TInt TUsbcDescriptorPool::GetConfigurationStringDescriptorTC(DThread* aThread, TDes8& aString) const
1099 TBuf8<KUsbDescSize_Config> config_desc;
1100 iDescriptors[1]->GetDescriptorData(config_desc);
1101 const TInt str_idx = config_desc[KUsbDescStringIndex_Config];
1102 if ((str_idx > 0) && iStrings[str_idx])
1104 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" String @ pos %d (conf $): \"%S\""),
1105 str_idx, &iStrings[str_idx]->StringData()));
1106 return __THREADWRITE(aThread, &aString, iStrings[str_idx]->StringData());
1110 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no string descriptor @ pos %d!"), str_idx));
1111 return KErrNotFound;
1116 TInt TUsbcDescriptorPool::SetConfigurationStringDescriptorTC(DThread* aThread, const TDes8& aString)
1118 // we don't know the length of the string, so we have to allocate memory dynamically
1119 TUint strlen = __THREADDESLEN(aThread, &aString);
1120 if (strlen > KUsbStringDescStringMaxSize)
1122 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Warning: $ descriptor too long - string will be truncated")));
1123 strlen = KUsbStringDescStringMaxSize;
1126 HBuf8Plat* strbuf = NULL;
1127 __NEWPLATBUF(strbuf, strlen);
1130 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: Memory allocation for config $ desc string failed (1)")));
1131 return KErrNoMemory;
1135 __THREADREADPLATBUF(aThread, &aString, strbuf, r);
1138 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: Thread read error")));
1142 TUsbcStringDescriptor* sd = TUsbcStringDescriptor::New(*strbuf);
1145 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: Memory allocation for config $ desc failed (2)")));
1147 return KErrNoMemory;
1149 TBuf8<KUsbDescSize_Config> config_desc;
1150 config_desc.FillZ(config_desc.MaxLength());
1151 iDescriptors[1]->GetDescriptorData(config_desc);
1152 ExchangeStringDescriptor(config_desc[KUsbDescStringIndex_Config], sd);
1160 void TUsbcDescriptorPool::InsertDevDesc(TUsbcDescriptorBase* aDesc)
1162 TInt count = iDescriptors.Count();
1165 DeleteDescriptors(0); // if there's already something at pos. 0, delete it
1167 iDescriptors.Insert(aDesc, 0); // in any case: put the new descriptor at position 0
1171 void TUsbcDescriptorPool::InsertConfigDesc(TUsbcDescriptorBase* aDesc)
1173 TInt count = iDescriptors.Count();
1176 TUsbcDescriptorBase* const iNullDesc = NULL;
1177 iDescriptors.Append(iNullDesc); // if array's empty, put a dummy in position 0
1181 DeleteDescriptors(1); // if there's already something at pos. 1, delete it
1183 iDescriptors.Insert(aDesc, 1); // in any case: put the new descriptor at position 1
1184 // Currently this code assumes, that the config descriptor is inserted _before_ any interface
1185 // or endpoint descriptors!
1186 if (iDescriptors.Count() != 2)
1188 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertConfigDesc: config descriptor will be invalid!")));
1193 void TUsbcDescriptorPool::InsertIfcDesc(TUsbcDescriptorBase* aDesc)
1195 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertIfcDesc()")));
1196 TInt count = iDescriptors.Count();
1199 TUsbcDescriptorBase* const iNullDesc = NULL;
1200 iDescriptors.Append(iNullDesc); // if array's too small, put some dummies in
1201 iDescriptors.Append(iNullDesc);
1203 TBool interface_exists = EFalse; // set to 'true' if we're adding an alternate
1204 // setting to an already existing interface
1208 if (iDescriptors[i]->Type() == KUsbDescType_Interface)
1210 if (iDescriptors[i]->Byte(2) > aDesc->Byte(2))
1212 // our interface number is less than the one's just found => insert before it (= here)
1215 else if (iDescriptors[i]->Byte(2) == aDesc->Byte(2))
1217 interface_exists = ETrue;
1218 // same interface number => look at settings number
1219 if (iDescriptors[i]->Byte(3) > aDesc->Byte(3))
1221 // our setting number is less than the one's found => insert before (= here)
1224 else if (iDescriptors[i]->Byte(3) == aDesc->Byte(3))
1226 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertIfcDesc: error: first delete old one!")));
1233 iDescriptors.Insert(aDesc, i); // in any case: put the new descriptor at position i
1234 if (iDescriptors[1])
1236 // if there's a config descriptor (and not a NULL pointer), update its wTotalLength field...
1237 iDescriptors[1]->SetWord(2, (TUint8)(iDescriptors[1]->Word(2) + KUsbDescSize_Interface));
1238 // and increment bNumInterfaces if this is the first setting for the interface
1239 if (!interface_exists)
1240 iDescriptors[1]->SetByte(4, (TUint8)(iDescriptors[1]->Byte(4) + 1));
1246 void TUsbcDescriptorPool::InsertEpDesc(TUsbcDescriptorBase* aDesc)
1248 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertEpDesc()")));
1251 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertEpDesc: error: only after interface")));
1254 TInt count = iDescriptors.Count();
1255 TInt i = iIfcIdx + 1;
1258 if (iDescriptors[i]->Type() != KUsbDescType_Endpoint)
1262 iDescriptors.Insert(aDesc, i); // put the new descriptor at position i
1263 if (iDescriptors[1])
1265 // if there's a config descriptor (and not a NULL pointer), update its wTotalLength field
1266 iDescriptors[1]->SetWord(2, (TUint8)(iDescriptors[1]->Word(2) + aDesc->Size()));
1271 TInt TUsbcDescriptorPool::FindIfcDescriptor(TInt aIfcNumber, TInt aIfcSetting) const
1273 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::FindIfcDescriptor(%d, %d)"),
1274 aIfcNumber, aIfcSetting));
1275 TInt count = iDescriptors.Count();
1276 for (TInt i = 2; i < count; ++i)
1278 if ((iDescriptors[i]->Type() == KUsbDescType_Interface) &&
1279 (iDescriptors[i]->Byte(2) == aIfcNumber) &&
1280 (iDescriptors[i]->Byte(3) == aIfcSetting))
1285 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such interface")));
1290 TInt TUsbcDescriptorPool::FindEpDescriptor(TInt aIfcNumber, TInt aIfcSetting, TUint8 aEpAddress) const
1292 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::FindEpDescriptor(%d, %d, 0x%02x)"),
1293 aIfcNumber, aIfcSetting, aEpAddress));
1294 // first find the interface
1295 TInt ifc = FindIfcDescriptor(aIfcNumber, aIfcSetting);
1298 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such interface")));
1301 TInt count = iDescriptors.Count();
1302 // then, before the next interface, try to locate the endpoint
1303 for (TInt i = ifc + 1; i < count; ++i)
1305 if (iDescriptors[i]->Type() == KUsbDescType_Interface)
1307 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such endpoint before next interface")));
1310 else if ((iDescriptors[i]->Type() == KUsbDescType_Endpoint) &&
1311 (iDescriptors[i]->Byte(2) == aEpAddress))
1316 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no such endpoint")));
1321 void TUsbcDescriptorPool::DeleteDescriptors(TInt aIndex, TInt aCount)
1327 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" Removing descriptors at index %d:"), aIndex));
1330 // in this loop we don't decrement aIndex, because after deleting an element
1331 // aIndex is already indexing the next one!
1332 TUsbcDescriptorBase* ptr = iDescriptors[aIndex];
1333 if (iDescriptors[1])
1335 // if there's a config descriptor (and not a NULL pointer),
1336 if (ptr->Type() == KUsbDescType_Interface)
1338 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" - an interface descriptor")));
1339 // if it's an interface descriptor:
1340 // we update its wTotalLength field...
1341 iDescriptors[1]->SetWord(2, (TUint8)(iDescriptors[1]->Word(2) - KUsbDescSize_Interface));
1343 else if (ptr->Type() == KUsbDescType_Endpoint)
1345 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" - an endpoint descriptor")));
1346 // if it's an endpoint descriptor:
1347 // we only update its wTotalLength field
1348 iDescriptors[1]->SetWord(2, (TUint8)(iDescriptors[1]->Word(2) - ptr->Size()));
1350 else if (ptr->Type() == KUsbDescType_CS_Interface || ptr->Type() == KUsbDescType_CS_Endpoint)
1352 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" - a class specific descriptor")));
1353 // if it's an class specific descriptor:
1354 // we only update its wTotalLength field
1355 iDescriptors[1]->SetWord(2, (TUint8)(iDescriptors[1]->Word(2) - ptr->Size()));
1358 iDescriptors.Remove(aIndex);
1364 void TUsbcDescriptorPool::DeleteString(TInt aIndex)
1366 TUsbcStringDescriptorBase* ptr = iStrings[aIndex];
1367 iStrings.Remove(aIndex);
1372 void TUsbcDescriptorPool::UpdateIfcNumbers(TInt aNumber)
1374 const TInt count = iDescriptors.Count();
1375 for (TInt i = 2; i < count; ++i)
1377 if ((iDescriptors[i]->Type() == KUsbDescType_Interface) &&
1378 (iDescriptors[i]->Byte(2) == aNumber))
1380 // there's still an interface with 'number' so we don't need to update anything
1384 // if we haven't returned yet, we decrement bNumInterfaces
1385 iDescriptors[1]->SetByte(4, (TUint8)(iDescriptors[1]->Byte(4) - 1));
1389 void TUsbcDescriptorPool::UpdateIfcStringIndexes(TInt aStringIndex)
1391 // aStringIndex is the index value of the string descriptor that has just been removed.
1392 // We update all ifc descriptors with a string index value that is greater than aStringIndex,
1393 // because those strings moved all down by one position.
1395 TInt count = iDescriptors.Count();
1396 for (TInt i = 2; i < count; ++i)
1398 if ((iDescriptors[i]->Type() == KUsbDescType_Interface) &&
1399 (iDescriptors[i]->Byte(8) > aStringIndex))
1401 iDescriptors[i]->SetByte(8, (TUint8)(iDescriptors[i]->Byte(8) - 1));
1408 // Only used for Ep0 standard requests, so target buffer could be hard-wired.
1410 TInt TUsbcDescriptorPool::GetDeviceDescriptor() const
1412 return iDescriptors[0]->GetDescriptorData(iEp0_TxBuf, KUsbcBufSz_Ep0Tx);
1417 // Only used for Ep0 standard requests, so target buffer could be hard-wired.
1419 TInt TUsbcDescriptorPool::GetConfigDescriptor() const
1421 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::GetConfigDescriptor()")));
1423 TInt count = iDescriptors.Count();
1424 TUint8* buf = iEp0_TxBuf;
1425 for (TInt i = 1; i < count; ++i)
1427 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" > desc[%02d]: type = 0x%02x size = %d "),
1428 i, iDescriptors[i]->Type(), iDescriptors[i]->Size()));
1429 const TInt size = iDescriptors[i]->GetDescriptorData(buf, KUsbcBufSz_Ep0Tx - copied);
1432 // There was no buffer space to copy the descriptor -> no use to proceed
1436 if (copied >= KUsbcBufSz_Ep0Tx)
1438 // There's no buffer space left -> we need to stop copying here
1448 // Only used for Ep0 standard requests, so target buffer could be hard-wired.
1450 TInt TUsbcDescriptorPool::GetStringDescriptor(TInt aIndex) const
1452 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::GetStringDescriptor()")));
1453 // I really would have liked to display here the descriptor contents, but without trailing zero
1454 // we got a problem: how could we tell printf where the string ends? We would have to
1455 // dynamically allocate memory (since we don't know the size in advance), copy the descriptor
1456 // contents there, append a zero, and give this to printf. That's a bit too much effort...
1457 if (iStrings[aIndex])
1459 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" String @ pos %d"), aIndex));
1460 TInt size = iStrings[aIndex]->GetDescriptorData(iEp0_TxBuf, KUsbcBufSz_Ep0Tx);
1465 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no descriptor @ pos %d!"), aIndex));
1471 TInt TUsbcDescriptorPool::GetDeviceStringDescriptorTC(DThread* aThread, TDes8& aString, TInt aIndex) const
1473 TBuf8<KUsbDescSize_Device> dev_desc;
1474 iDescriptors[0]->GetDescriptorData(dev_desc);
1475 const TInt str_idx = dev_desc[aIndex];
1476 if ((str_idx > 0) && iStrings[str_idx])
1478 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" String @ pos %d (device $): \"%S\""),
1479 str_idx, &iStrings[str_idx]->StringData()));
1480 return __THREADWRITE(aThread, &aString, iStrings[str_idx]->StringData());
1484 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: no string descriptor @ pos %d!"), str_idx));
1485 return KErrNotFound;
1490 TInt TUsbcDescriptorPool::SetDeviceStringDescriptorTC(DThread* aThread, const TDes8& aString, TInt aIndex)
1492 // we don't know the length of the string, so we have to allocate memory dynamically
1493 TUint strlen = __THREADDESLEN(aThread, &aString);
1494 if (strlen > KUsbStringDescStringMaxSize)
1496 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Warning: $ descriptor too long - string will be truncated")));
1497 strlen = KUsbStringDescStringMaxSize;
1500 HBuf8Plat* strbuf = NULL;
1501 __NEWPLATBUF(strbuf, strlen);
1504 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: Memory allocation for dev $ desc string failed (1)")));
1505 return KErrNoMemory;
1509 __THREADREADPLATBUF(aThread, &aString, strbuf, r);
1512 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: Thread read error")));
1516 TUsbcStringDescriptor* sd = TUsbcStringDescriptor::New(*strbuf);
1519 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: Memory allocation for dev $ desc failed (2)")));
1521 return KErrNoMemory;
1523 TBuf8<KUsbDescSize_Device> dev_desc;
1524 dev_desc.FillZ(dev_desc.MaxLength());
1525 iDescriptors[0]->GetDescriptorData(dev_desc);
1526 ExchangeStringDescriptor(dev_desc[aIndex], sd);
1532 TInt TUsbcDescriptorPool::ExchangeStringDescriptor(TInt aIndex, const TUsbcStringDescriptor* aDesc)
1536 __KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" Error: invalid string descriptor index: %d!"), aIndex));
1537 return KErrArgument;
1539 __KTRACE_OPT(KUSB, Kern::Printf(__KSTRING(" Exchanging string descriptor @ index %d"), aIndex));
1540 DeleteString(aIndex);
1541 iStrings.Insert(aDesc, aIndex);