kerneltest/e32utils/testusbcldd/src/descriptors.cpp
changeset 43 96e5fb8b040d
equal deleted inserted replaced
-1:000000000000 43:96e5fb8b040d
       
     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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // f32test\testusbcldd\src\descriptors.cpp
       
    15 // Platform independent USB client controller layer (PIL):
       
    16 // USB descriptor handling and management.
       
    17 // 
       
    18 //
       
    19 
       
    20 #include "usbcdesc.h"
       
    21 #include "dtestusblogdev.h"
       
    22 
       
    23 // --- TUsbcDescriptorBase
       
    24 
       
    25 TUsbcDescriptorBase::TUsbcDescriptorBase()
       
    26 	:
       
    27 #ifdef USB_SUPPORTS_SET_DESCRIPTOR_REQUEST
       
    28 	iIndex(0),
       
    29 #endif
       
    30 	iBufPtr(NULL, 0)
       
    31   	{
       
    32 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorBase::TUsbcDescriptorBase()")));
       
    33 	}
       
    34 
       
    35 
       
    36 TUsbcDescriptorBase::~TUsbcDescriptorBase()
       
    37 	{
       
    38 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorBase::~TUsbcDescriptorBase()")));
       
    39 	}
       
    40 
       
    41 
       
    42 void TUsbcDescriptorBase::SetByte(TUint aPosition, TUint8 aValue)
       
    43 	{
       
    44 	iBufPtr[aPosition] = aValue;
       
    45 	}
       
    46 
       
    47 
       
    48 void TUsbcDescriptorBase::SetWord(TUint aPosition, TUint16 aValue)
       
    49 	{
       
    50 	*reinterpret_cast<TUint16*>(&iBufPtr[aPosition]) = SWAP_BYTES_16(aValue);
       
    51 	}
       
    52 
       
    53 
       
    54 TUint8 TUsbcDescriptorBase::Byte(TUint aPosition) const
       
    55 	{
       
    56 	return iBufPtr[aPosition];
       
    57 	}
       
    58 
       
    59 
       
    60 TUint16 TUsbcDescriptorBase::Word(TUint aPosition) const
       
    61 	{
       
    62 	return SWAP_BYTES_16(*reinterpret_cast<const TUint16*>(&iBufPtr[aPosition]));
       
    63 	}
       
    64 
       
    65 
       
    66 void TUsbcDescriptorBase::GetDescriptorData(TDes8& aBuffer) const
       
    67 	{
       
    68 	aBuffer = iBufPtr;
       
    69 	}
       
    70 
       
    71 
       
    72 TInt TUsbcDescriptorBase::GetDescriptorData(TUint8* aBuffer) const
       
    73 	{
       
    74 	__MEMCPY(aBuffer, iBufPtr.Ptr(), Size());
       
    75 	return Size();
       
    76 	}
       
    77 
       
    78 
       
    79 TInt TUsbcDescriptorBase::GetDescriptorData(TUint8* aBuffer, TInt aMaxSize) const
       
    80 	{
       
    81 	if (aMaxSize < Size())
       
    82 		{
       
    83 		// No use to copy only half a descriptor
       
    84 		return 0;
       
    85 		}
       
    86 	return GetDescriptorData(aBuffer);
       
    87 	}
       
    88 
       
    89 
       
    90 const TDes8& TUsbcDescriptorBase::DescriptorData() const
       
    91 	{
       
    92 	return iBufPtr;
       
    93 	}
       
    94 
       
    95 
       
    96 TDes8& TUsbcDescriptorBase::DescriptorData()
       
    97 	{
       
    98 	return iBufPtr;
       
    99 	}
       
   100 
       
   101 
       
   102 TInt TUsbcDescriptorBase::Size() const
       
   103 	{
       
   104 	return iBufPtr.Size();
       
   105 	}
       
   106 
       
   107 
       
   108 TUint8 TUsbcDescriptorBase::Type() const
       
   109 	{
       
   110 	return iBufPtr[1];
       
   111 	}
       
   112 
       
   113 
       
   114 void TUsbcDescriptorBase::SetBufferPointer(const TDesC8& aDes)
       
   115 	{
       
   116 	iBufPtr.Set(const_cast<TUint8*>(aDes.Ptr()), aDes.Size(), aDes.Size());
       
   117 	}
       
   118 
       
   119 
       
   120 // --- TUsbcDeviceDescriptor
       
   121 
       
   122 TUsbcDeviceDescriptor::TUsbcDeviceDescriptor()
       
   123 	: iBuf()
       
   124   	{
       
   125 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDeviceDescriptor::TUsbcDeviceDescriptor()")));
       
   126 	}
       
   127 
       
   128 
       
   129 TUsbcDeviceDescriptor* TUsbcDeviceDescriptor::New(TUint8 aDeviceClass, TUint8 aDeviceSubClass,
       
   130 												  TUint8 aDeviceProtocol, TUint8 aMaxPacketSize0,
       
   131 												  TUint16 aVendorId, TUint16 aProductId,
       
   132 												  TUint16 aDeviceRelease, TUint8 aNumConfigurations)
       
   133 	{
       
   134 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDeviceDescriptor::New()")));
       
   135 	TUsbcDeviceDescriptor* self = new TUsbcDeviceDescriptor();
       
   136 	if (self)
       
   137 		{
       
   138 		if (self->Construct(aDeviceClass, aDeviceSubClass, aDeviceProtocol, aMaxPacketSize0, aVendorId,
       
   139 							aProductId, aDeviceRelease, aNumConfigurations) != KErrNone)
       
   140 			{
       
   141 			delete self;
       
   142 			return NULL;
       
   143 			}
       
   144 		}
       
   145 	return self;
       
   146 	}
       
   147 
       
   148 
       
   149 TInt TUsbcDeviceDescriptor::Construct(TUint8 aDeviceClass, TUint8 aDeviceSubClass, TUint8 aDeviceProtocol,
       
   150 									  TUint8 aMaxPacketSize0, TUint16 aVendorId, TUint16 aProductId,
       
   151 									  TUint16 aDeviceRelease, TUint8 aNumConfigurations)
       
   152 	{
       
   153 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDeviceDescriptor::Construct()")));
       
   154 	iBuf.SetMax();
       
   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
       
   170 	return KErrNone;
       
   171 	}
       
   172 
       
   173 // --- TUsbcConfigDescriptor
       
   174 
       
   175 TUsbcConfigDescriptor::TUsbcConfigDescriptor()
       
   176 	: iBuf()
       
   177   	{
       
   178 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcConfigDescriptor::TUsbcConfigDescriptor()")));
       
   179 	}
       
   180 
       
   181 
       
   182 TUsbcConfigDescriptor* TUsbcConfigDescriptor::New(TUint8 aConfigurationValue, TBool aSelfPowered,
       
   183 												  TBool aRemoteWakeup, TUint8 aMaxPower)
       
   184 	{
       
   185 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcConfigDescriptor::New()")));
       
   186 	TUsbcConfigDescriptor* self = new TUsbcConfigDescriptor();
       
   187 	if (self)
       
   188 		{
       
   189 		if (self->Construct(aConfigurationValue, aSelfPowered, aRemoteWakeup, aMaxPower) != KErrNone)
       
   190 			{
       
   191 			delete self;
       
   192 			return NULL;
       
   193 			}
       
   194 		}
       
   195 	return self;
       
   196 	}
       
   197 
       
   198 
       
   199 TInt TUsbcConfigDescriptor::Construct(TUint8 aConfigurationValue, TBool aSelfPowered,
       
   200 									   TBool aRemoteWakeup, TUint8 aMaxPower)
       
   201 	{
       
   202 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcConfigDescriptor::Construct()")));
       
   203 	iBuf.SetMax();
       
   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!)
       
   213 	return KErrNone;
       
   214 	}
       
   215 
       
   216 
       
   217 // --- TUsbcInterfaceDescriptor
       
   218 
       
   219 TUsbcInterfaceDescriptor::TUsbcInterfaceDescriptor()
       
   220 	: iBuf()
       
   221   	{
       
   222  	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcInterfaceDescriptor::TUsbcInterfaceDescriptor()")));
       
   223 	}
       
   224 
       
   225 
       
   226 TUsbcInterfaceDescriptor* TUsbcInterfaceDescriptor::New(TUint8 aInterfaceNumber, TUint8 aAlternateSetting,
       
   227 														TInt aNumEndpoints, const TUsbcClassInfo& aClassInfo)
       
   228 	{
       
   229 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcInterfaceDescriptor::New()")));
       
   230 	TUsbcInterfaceDescriptor* self = new TUsbcInterfaceDescriptor();
       
   231 	if (self)
       
   232 		{
       
   233 		if (self->Construct(aInterfaceNumber, aAlternateSetting, aNumEndpoints, aClassInfo) != KErrNone)
       
   234 			{
       
   235 			delete self;
       
   236 			return NULL;
       
   237 			}
       
   238 		}
       
   239 	return self;
       
   240 	}
       
   241 
       
   242 
       
   243 TInt TUsbcInterfaceDescriptor::Construct(TUint8 aInterfaceNumber, TUint8 aAlternateSetting,
       
   244 										 TInt aNumEndpoints, const TUsbcClassInfo& aClassInfo)
       
   245 	{
       
   246 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcInterfaceDescriptor::Construct()")));
       
   247 	iBuf.SetMax();
       
   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
       
   258 	return KErrNone;
       
   259 	}
       
   260 
       
   261 
       
   262 // --- TUsbcEndpointDescriptor
       
   263 
       
   264 TUsbcEndpointDescriptor::TUsbcEndpointDescriptor()
       
   265 	: iBuf()
       
   266   	{
       
   267  	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcEndpointDescriptor::TUsbcEndpointDescriptor()")));
       
   268 	}
       
   269 
       
   270 
       
   271 TUsbcEndpointDescriptor* TUsbcEndpointDescriptor::New(TUint8 aEndpointAddress,
       
   272 													  const TUsbcEndpointInfo& aEpInfo)
       
   273 	{
       
   274 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcEndpointDescriptor::New()")));
       
   275 	TUsbcEndpointDescriptor* self = new TUsbcEndpointDescriptor();
       
   276 	if (self)
       
   277 		{
       
   278 		if (self->Construct(aEndpointAddress, aEpInfo) != KErrNone)
       
   279 			{
       
   280 			delete self;
       
   281 			return NULL;
       
   282 			}
       
   283 		}
       
   284 	return self;
       
   285 	}
       
   286 
       
   287 
       
   288 TInt TUsbcEndpointDescriptor::Construct(TUint8 aEndpointAddress, const TUsbcEndpointInfo& aEpInfo)
       
   289 	{
       
   290 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcEndpointDescriptor::Construct()")));
       
   291 	iBuf.SetMax();
       
   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
       
   299 	return KErrNone;
       
   300 	}
       
   301 
       
   302 
       
   303 // --- TUsbcAudioEndpointDescriptor
       
   304 
       
   305 TUsbcAudioEndpointDescriptor::TUsbcAudioEndpointDescriptor()
       
   306 	: iBuf()
       
   307   	{
       
   308  	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcAudioEndpointDescriptor::TUsbcAudioEndpointDescriptor()")));
       
   309 	}
       
   310 
       
   311 
       
   312 TUsbcAudioEndpointDescriptor* TUsbcAudioEndpointDescriptor::New(TUint8 aEndpointAddress,
       
   313 																const TUsbcEndpointInfo& aEpInfo)
       
   314 	{
       
   315 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcAudioEndpointDescriptor::New()")));
       
   316 	TUsbcAudioEndpointDescriptor* self = new TUsbcAudioEndpointDescriptor();
       
   317 	if (self)
       
   318 		{
       
   319 		if (self->Construct(aEndpointAddress, aEpInfo) != KErrNone)
       
   320 			{
       
   321 			delete self;
       
   322 			return NULL;
       
   323 			}
       
   324 		}
       
   325 	return self;
       
   326 	}
       
   327 
       
   328 
       
   329 TInt TUsbcAudioEndpointDescriptor::Construct(TUint8 aEndpointAddress, const TUsbcEndpointInfo& aEpInfo)
       
   330 	{
       
   331 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcAudioEndpointDescriptor::Construct()")));
       
   332 	iBuf.SetMax();
       
   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
       
   340 	iBuf[7] = 0;
       
   341 	iBuf[8] = 0;
       
   342 	return KErrNone;
       
   343 	}
       
   344 
       
   345 
       
   346 // --- TUsbcClassSpecificDescriptor
       
   347 
       
   348 TUsbcClassSpecificDescriptor::TUsbcClassSpecificDescriptor()
       
   349 	: iBuf(NULL)
       
   350   	{
       
   351  	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcClassSpecificDescriptor::TUsbcClassSpecificDescriptor()")));
       
   352 	}
       
   353 
       
   354 
       
   355 TUsbcClassSpecificDescriptor::~TUsbcClassSpecificDescriptor()
       
   356 	{
       
   357 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcClassSpecificDescriptor::~TUsbcClassSpecificDescriptor()")));
       
   358 	delete iBuf;
       
   359 	}
       
   360 
       
   361 
       
   362 TUsbcClassSpecificDescriptor* TUsbcClassSpecificDescriptor::New(TUint8 aType, TInt aSize)
       
   363 	{
       
   364 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcClassSpecificDescriptor::New()")));
       
   365 	TUsbcClassSpecificDescriptor* self = new TUsbcClassSpecificDescriptor();
       
   366 	if (self)
       
   367 		{
       
   368 		if (self->Construct(aType, aSize) != KErrNone)
       
   369 			{
       
   370 			delete self;
       
   371 			return NULL;
       
   372 			}
       
   373 		}
       
   374 	return self;
       
   375 	}
       
   376 
       
   377 
       
   378 TInt TUsbcClassSpecificDescriptor::Construct(TUint8 aType, TInt aSize)
       
   379 	{
       
   380 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcClassSpecificDescriptor::Construct()")));
       
   381 	__NEWPLATBUF(iBuf, aSize);
       
   382 	if (!iBuf)
       
   383 		{
       
   384 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: Allocation of CS desc buffer failed")));
       
   385 		return KErrNoMemory;
       
   386 		}
       
   387 	SetBufferPointer(*iBuf);
       
   388 	SetByte(1, aType);										// bDescriptorType
       
   389 	return KErrNone;
       
   390 	}
       
   391 
       
   392 
       
   393 // --- TUsbcStringDescriptorBase
       
   394 
       
   395 TUsbcStringDescriptorBase::TUsbcStringDescriptorBase()
       
   396 	: /*iIndex(0),*/ iSBuf(0), iBufPtr(NULL, 0)
       
   397 	{
       
   398 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptorBase::TUsbcStringDescriptorBase()")));
       
   399 	}
       
   400 
       
   401 
       
   402 TUsbcStringDescriptorBase::~TUsbcStringDescriptorBase()
       
   403 	{
       
   404 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptorBase::~TUsbcStringDescriptorBase()")));
       
   405 	}
       
   406 
       
   407 
       
   408 TUint16 TUsbcStringDescriptorBase::Word(TUint aPosition) const
       
   409 	{
       
   410 	if (aPosition <= 1)
       
   411 		{
       
   412 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("TUsbcStringDescriptorBase::Word: Error: Word(%d) in string descriptor!"), aPosition));
       
   413 		return 0;
       
   414 		}
       
   415 	else
       
   416 		{
       
   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]));
       
   420 		}
       
   421 	}
       
   422 
       
   423 
       
   424 TInt TUsbcStringDescriptorBase::GetDescriptorData(TUint8* aBuffer) const
       
   425 	{
       
   426 	aBuffer[0] = iSBuf[0];
       
   427 	aBuffer[1] = iSBuf[1];
       
   428 	__MEMCPY(&aBuffer[2], iBufPtr.Ptr(), iBufPtr.Size());
       
   429 	return Size();
       
   430 	}
       
   431 
       
   432 
       
   433 TInt TUsbcStringDescriptorBase::GetDescriptorData(TUint8* aBuffer, TInt aMaxSize) const
       
   434 	{
       
   435 	if (aMaxSize < Size())
       
   436 		{
       
   437 		// No use to copy only half a string
       
   438 		return 0;
       
   439 		}
       
   440 	return GetDescriptorData(aBuffer);
       
   441 	}
       
   442 
       
   443 
       
   444 const TDes8& TUsbcStringDescriptorBase::StringData() const
       
   445 	{
       
   446 	return iBufPtr;
       
   447 	}
       
   448 
       
   449 
       
   450 TDes8& TUsbcStringDescriptorBase::StringData()
       
   451 	{
       
   452 	return iBufPtr;
       
   453 	}
       
   454 
       
   455 
       
   456 TInt TUsbcStringDescriptorBase::Size() const
       
   457 	{
       
   458 	return iSBuf[0];
       
   459 	}
       
   460 
       
   461 
       
   462 void TUsbcStringDescriptorBase::SetBufferPointer(const TDesC8& aDes)
       
   463 	{
       
   464 	iBufPtr.Set(const_cast<TUint8*>(aDes.Ptr()), aDes.Size(), aDes.Size());
       
   465 	}
       
   466 
       
   467 
       
   468 // --- TUsbcStringDescriptor
       
   469 
       
   470 TUsbcStringDescriptor::TUsbcStringDescriptor()
       
   471 	: iBuf(NULL)
       
   472 	{
       
   473 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptor::TUsbcStringDescriptor()")));
       
   474 	}
       
   475 
       
   476 
       
   477 TUsbcStringDescriptor::~TUsbcStringDescriptor()
       
   478 	{
       
   479 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptor::~TUsbcStringDescriptor()")));
       
   480 	delete iBuf;
       
   481 	}
       
   482 
       
   483 
       
   484 TUsbcStringDescriptor* TUsbcStringDescriptor::New(const TDesC8& aString)
       
   485 	{
       
   486 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptor::New")));
       
   487 	TUsbcStringDescriptor* self = new TUsbcStringDescriptor();
       
   488 	if (self)
       
   489 		{
       
   490 		if (self->Construct(aString) != KErrNone)
       
   491 			{
       
   492 			delete self;
       
   493 			return NULL;
       
   494 			}
       
   495 		}
       
   496 	return self;
       
   497 	}
       
   498 
       
   499 
       
   500 TInt TUsbcStringDescriptor::Construct(const TDesC8& aString)
       
   501 	{
       
   502 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcStringDescriptor::Construct")));
       
   503 	__NEWPLATBUF(iBuf, aString.Size());
       
   504 	if (!iBuf)
       
   505 		{
       
   506 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: Allocation of string buffer failed")));
       
   507 		return KErrNoMemory;
       
   508 		}
       
   509 	SetBufferPointer(*iBuf);
       
   510 	iBufPtr.Copy(aString);
       
   511 	iSBuf.SetMax();
       
   512 	iSBuf[0] = (TUint8)(iBuf->Size() + 2); // Bytes
       
   513 	iSBuf[1] = KUsbDescType_String;
       
   514 	return KErrNone;
       
   515 	}
       
   516 
       
   517 
       
   518 // --- TUsbcLangIdDescriptor
       
   519 
       
   520 TUsbcLangIdDescriptor::TUsbcLangIdDescriptor()
       
   521 	: iBuf(NULL)
       
   522 	{
       
   523 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcLangIdDescriptor::TUsbcLangIdDescriptor()")));
       
   524 	}
       
   525 
       
   526 
       
   527 TUsbcLangIdDescriptor::~TUsbcLangIdDescriptor()
       
   528 	{
       
   529 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcLangIdDescriptor::~TUsbcLangIdDescriptor()")));
       
   530 	}
       
   531 
       
   532 
       
   533 TUsbcLangIdDescriptor* TUsbcLangIdDescriptor::New(TUint16 aLangId)
       
   534 	{
       
   535 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcLangIdDescriptor::New")));
       
   536 	TUsbcLangIdDescriptor* self = new TUsbcLangIdDescriptor();
       
   537 	if (self)
       
   538 		{
       
   539 		if (self->Construct(aLangId) != KErrNone)
       
   540 			{
       
   541 			delete self;
       
   542 			return NULL;
       
   543 			}
       
   544 		}
       
   545 	return self;
       
   546 	}
       
   547 
       
   548 
       
   549 TInt TUsbcLangIdDescriptor::Construct(TUint16 aLangId)
       
   550 	{
       
   551 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcLangIdDescriptor::Construct")));
       
   552 	iBuf.SetMax();
       
   553 	SetBufferPointer(iBuf);
       
   554 	iBufPtr[0] = LowByte(SWAP_BYTES_16(aLangId));			// Language ID value
       
   555 	iBufPtr[1] = HighByte(SWAP_BYTES_16(aLangId));
       
   556 	iSBuf.SetMax();
       
   557 	iSBuf[0] = (TUint8)(iBuf.Size() + 2);								// Bytes
       
   558 	iSBuf[1] = KUsbDescType_String;
       
   559 	return KErrNone;
       
   560 	}
       
   561 
       
   562 
       
   563 // --- TUsbcDescriptorPool
       
   564 
       
   565 TUsbcDescriptorPool::TUsbcDescriptorPool(TUint8* aEp0_TxBuf)
       
   566 //
       
   567 //  The constructor for this class.
       
   568 //
       
   569 	: iDescriptors(4), iStrings(4),	iIfcIdx(0), iEp0_TxBuf(aEp0_TxBuf) // 4 = granularity
       
   570 	{
       
   571 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::TUsbcDescriptorPool()")));
       
   572 	}
       
   573 
       
   574 
       
   575 TUsbcDescriptorPool::~TUsbcDescriptorPool()
       
   576 	{
       
   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();
       
   583 	}
       
   584 
       
   585 
       
   586 TInt TUsbcDescriptorPool::Init(TUsbcDeviceDescriptor* aDeviceDesc, TUsbcConfigDescriptor* aConfigDesc,
       
   587 							   TUsbcLangIdDescriptor* aLangId, TUsbcStringDescriptor* aManufacturer,
       
   588 							   TUsbcStringDescriptor* aProduct, TUsbcStringDescriptor* aSerialNum,
       
   589 							   TUsbcStringDescriptor* aConfig)
       
   590 	{
       
   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)
       
   595 		{
       
   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)")));
       
   599 		return KErrArgument;
       
   600 		}
       
   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
       
   611 	return KErrNone;
       
   612 	}
       
   613 
       
   614 
       
   615 TInt TUsbcDescriptorPool::FindDescriptor(TUint8 aType, TUint8 aIndex, TUint16 aLangid, TInt& aSize) const
       
   616 	{
       
   617 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::FindDescriptor()")));
       
   618 	TInt result = KErrGeneral;
       
   619 
       
   620 	switch(aType)
       
   621 		{
       
   622 	case KUsbDescType_Device:
       
   623 		if (aLangid != 0)
       
   624 			{
       
   625 			__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: bad langid: 0x%04x"), aLangid));
       
   626 			result = KErrGeneral;							// bad langid
       
   627 			}
       
   628 		else if (aIndex > 0)
       
   629 			{
       
   630 			__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: bad device index: %d"), aIndex));
       
   631 			result = KErrGeneral;							// we have only one device
       
   632 			}
       
   633 		else
       
   634 			{
       
   635 			aSize = GetDeviceDescriptor();
       
   636 			result = KErrNone;
       
   637 			}
       
   638 		break;
       
   639 	case KUsbDescType_Config:
       
   640 		if (aLangid != 0)
       
   641 			{
       
   642 			__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: bad langid: 0x%04x"), aLangid));
       
   643 			result = KErrGeneral;							// bad langid
       
   644 			}
       
   645 		else if (aIndex > 0)
       
   646 			{
       
   647 			__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: bad config index: %d"), aIndex));
       
   648 			result = KErrGeneral;							// we have only one configuration
       
   649 			}
       
   650 		else
       
   651 			{
       
   652 			aSize = GetConfigDescriptor();
       
   653 			result = KErrNone;
       
   654 			}
       
   655 		break;
       
   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
       
   659 			{
       
   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
       
   663 			}
       
   664 		else if (aIndex >= iStrings.Count())
       
   665 			{
       
   666 			__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: bad string index: %d"), aIndex));
       
   667 			result = KErrGeneral;
       
   668 			}
       
   669 		else
       
   670 			{
       
   671 			aSize = GetStringDescriptor(aIndex);
       
   672 			result = KErrNone;
       
   673 			}
       
   674 		break;
       
   675 	case KUsbDescType_CS_Interface:
       
   676 		/* fall through */
       
   677 	case KUsbDescType_CS_Endpoint:
       
   678 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Warning: finding of class specific descriptors not supported")));
       
   679 		break;
       
   680 	default:
       
   681 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: unknown descriptor type requested: %d"), aType));
       
   682 		result = KErrGeneral;
       
   683 		break;
       
   684 		}
       
   685 
       
   686 	return result;
       
   687 	}
       
   688 
       
   689 
       
   690 void TUsbcDescriptorPool::InsertDescriptor(TUsbcDescriptorBase* aDesc)
       
   691 	{
       
   692 	switch (aDesc->Type())
       
   693 		{
       
   694 	case KUsbDescType_Device:
       
   695 		InsertDevDesc(aDesc);
       
   696 		break;
       
   697 	case KUsbDescType_Config:
       
   698 		InsertConfigDesc(aDesc);
       
   699 		break;
       
   700 	case KUsbDescType_Interface:
       
   701 		InsertIfcDesc(aDesc);
       
   702 		break;
       
   703 	case KUsbDescType_Endpoint:
       
   704 		InsertEpDesc(aDesc);
       
   705 		break;
       
   706 	case KUsbDescType_CS_Interface:
       
   707 		/* fall through */
       
   708 	case KUsbDescType_CS_Endpoint:
       
   709 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Warning: inserting class specific descriptors not supported")));
       
   710 		break;
       
   711 	default:
       
   712 		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertDescriptor: Error: invalid type")));
       
   713 		break;
       
   714 		}
       
   715 	}
       
   716 
       
   717 
       
   718 void TUsbcDescriptorPool::SetIfcStringDescriptor(TUsbcStringDescriptor* aDesc, TInt aNumber, TInt aSetting)
       
   719 	{
       
   720 	TInt i = FindIfcDescriptor(aNumber, aSetting);
       
   721 	if (i < 0)
       
   722 		{
       
   723 		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::SetIfcStringDescriptor: error")));
       
   724 		return;
       
   725 		}
       
   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()));
       
   733 	}
       
   734 
       
   735 
       
   736 void TUsbcDescriptorPool::DeleteIfcDescriptor(TInt aNumber, TInt aSetting)
       
   737 	{
       
   738 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::DeleteIfcDescriptor(%d, %d)"), aNumber, aSetting));
       
   739 	TInt i = FindIfcDescriptor(aNumber, aSetting);
       
   740 	if (i < 0)
       
   741 		{
       
   742 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING(" > Error: descriptor not found")));
       
   743 		return;
       
   744 		}
       
   745 	// Delete (if necessary) specified interface's string descriptor
       
   746 	TInt si = iDescriptors[i]->Byte(8);
       
   747 	if (si != 0)
       
   748 		{
       
   749 		DeleteString(si);
       
   750 		}
       
   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();
       
   754 	TInt j = i, n = 1;
       
   755 	while (++j < count && iDescriptors[j]->Type() != KUsbDescType_Interface)
       
   756 		++n;
       
   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
       
   762 	if (si != 0)
       
   763 		{
       
   764 		UpdateIfcStringIndexes(si);
       
   765 		}
       
   766 	iIfcIdx = 0;											// ifc index no longer valid
       
   767 	}
       
   768 
       
   769 
       
   770 // The TC in many of the following functions stands for 'ThreadCopy',
       
   771 // because that's what's happening there.
       
   772 
       
   773 TInt TUsbcDescriptorPool::GetDeviceDescriptorTC(DThread* aThread, TDes8& aBuffer) const
       
   774 	{
       
   775 	return __THREADWRITE(aThread, &aBuffer, iDescriptors[0]->DescriptorData());
       
   776 	}
       
   777 
       
   778 
       
   779 TInt TUsbcDescriptorPool::SetDeviceDescriptorTC(DThread* aThread, const TDes8& aBuffer)
       
   780 	{
       
   781 	TBuf8<KUsbDescSize_Device> device;
       
   782 	TInt r = __THREADREAD(aThread, &aBuffer, device);
       
   783 	if (r != KErrNone)
       
   784 		{
       
   785 		return r;
       
   786 		}
       
   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)
       
   798 	return KErrNone;
       
   799 	}
       
   800 
       
   801 
       
   802 TInt TUsbcDescriptorPool::GetConfigurationDescriptorTC(DThread* aThread, TDes8& aBuffer) const
       
   803 	{
       
   804 	return __THREADWRITE(aThread, &aBuffer, iDescriptors[1]->DescriptorData());
       
   805 	}
       
   806 
       
   807 
       
   808 TInt TUsbcDescriptorPool::SetConfigurationDescriptorTC(DThread* aThread, const TDes8& aBuffer)
       
   809 	{
       
   810 	TBuf8<KUsbDescSize_Config> config;
       
   811 	TInt r = __THREADREAD(aThread, &aBuffer, config);
       
   812 	if (r != KErrNone)
       
   813 		{
       
   814 		return r;
       
   815 		}
       
   816 	iDescriptors[1]->SetByte(7, config[7]);					// bmAttributes
       
   817 	iDescriptors[1]->SetByte(8, config[8]);					// bMaxPower
       
   818 	return KErrNone;
       
   819 	}
       
   820 
       
   821 
       
   822 TInt TUsbcDescriptorPool::GetInterfaceDescriptorTC(DThread* aThread, TDes8& aBuffer,
       
   823 												   TInt aInterface, TInt aSetting) const
       
   824 	{
       
   825 	TInt i = FindIfcDescriptor(aInterface, aSetting);
       
   826 	if (i < 0)
       
   827 		{
       
   828 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such interface")));
       
   829 		return KErrNotFound;
       
   830 		}
       
   831 	return __THREADWRITE(aThread, &aBuffer, iDescriptors[i]->DescriptorData());
       
   832 	}
       
   833 
       
   834 
       
   835 TInt TUsbcDescriptorPool::SetInterfaceDescriptor(const TDes8& aBuffer, TInt aInterface, TInt aSetting)
       
   836 	{
       
   837 	TInt i = FindIfcDescriptor(aInterface, aSetting);
       
   838 	if (i < 0)
       
   839 		{
       
   840 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such interface")));
       
   841 		return KErrNotFound;
       
   842 		}
       
   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
       
   847 	return KErrNone;
       
   848 	}
       
   849 
       
   850 
       
   851 TInt TUsbcDescriptorPool::GetEndpointDescriptorTC(DThread* aThread, TDes8& aBuffer,
       
   852 												  TInt aInterface, TInt aSetting, TUint8 aEndpointAddress) const
       
   853 	{
       
   854 	TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
       
   855 	if (i < 0)
       
   856 		{
       
   857 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such endpoint")));
       
   858 		return KErrNotFound;
       
   859 		}
       
   860 	return __THREADWRITE(aThread, &aBuffer, iDescriptors[i]->DescriptorData());
       
   861 	}
       
   862 
       
   863 
       
   864 TInt TUsbcDescriptorPool::SetEndpointDescriptorTC(DThread* aThread, const TDes8& aBuffer,
       
   865 												  TInt aInterface, TInt aSetting, TUint8 aEndpointAddress)
       
   866 	{
       
   867 	TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
       
   868 	if (i < 0)
       
   869 		{
       
   870 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such endpoint")));
       
   871 		return KErrNotFound;
       
   872 		}
       
   873 	TBuf8<KUsbDescSize_AudioEndpoint> ep;					// it could be an audio endpoint
       
   874 	TInt r = __THREADREAD(aThread, &aBuffer, ep);
       
   875 	if (r != KErrNone)
       
   876 		{
       
   877 		return r;
       
   878 		}
       
   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)
       
   882 		{
       
   883 		iDescriptors[i]->SetByte(7, ep[7]);					// bRefresh
       
   884 		iDescriptors[i]->SetByte(8, ep[8]);					// bSynchAddress
       
   885 		}
       
   886 	return KErrNone;
       
   887 	}
       
   888 
       
   889 
       
   890 TInt TUsbcDescriptorPool::GetEndpointDescriptorSize(TInt aInterface, TInt aSetting, TUint8 aEndpointAddress,
       
   891 													TInt& aSize) const
       
   892 	{
       
   893 	TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
       
   894 	if (i < 0)
       
   895 		{
       
   896 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such endpoint")));
       
   897 		return KErrNotFound;
       
   898 		}
       
   899 	aSize = iDescriptors[i]->Size();
       
   900 	return KErrNone;
       
   901 	}
       
   902 
       
   903 
       
   904 TInt TUsbcDescriptorPool::GetCSInterfaceDescriptorTC(DThread* aThread, TDes8& aBuffer,
       
   905 													 TInt aInterface, TInt aSetting) const
       
   906 	{
       
   907 	// first find the interface
       
   908 	TInt i = FindIfcDescriptor(aInterface, aSetting);
       
   909 	if (i < 0)
       
   910 		{
       
   911 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such interface")));
       
   912 		return KErrNotFound;
       
   913 		}
       
   914 	TInt r = KErrNotFound;
       
   915 	TInt offset = 0;
       
   916 	const TInt count = iDescriptors.Count();
       
   917 	while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface)
       
   918 		{
       
   919 		r = __THREADWRITEOFFSET(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), offset);
       
   920 		if (r != KErrNone)
       
   921 			break;
       
   922 		offset += iDescriptors[i]->Size();
       
   923 		}
       
   924 	return r;
       
   925 	}
       
   926 
       
   927 
       
   928 TInt TUsbcDescriptorPool::SetCSInterfaceDescriptorTC(DThread* aThread, const TDes8& aBuffer,
       
   929 													 TInt aInterface, TInt aSetting, TInt aSize)
       
   930 	{
       
   931 	// first find the interface
       
   932 	TInt i = FindIfcDescriptor(aInterface, aSetting);
       
   933 	if (i < 0)
       
   934 		{
       
   935 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such interface")));
       
   936 		return KErrNotFound;
       
   937 		}
       
   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)
       
   941 		;
       
   942 	// create a new cs descriptor
       
   943 	TUsbcClassSpecificDescriptor* desc = TUsbcClassSpecificDescriptor::New(KUsbDescType_CS_Interface, aSize);
       
   944 	if (!desc)
       
   945 		{
       
   946 		return KErrNoMemory;
       
   947 		}
       
   948 	iDescriptors.Insert(desc, i);
       
   949 	if (iDescriptors[1])
       
   950 		{
       
   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));
       
   953 		}
       
   954 	// copy contents from user side
       
   955 	return __THREADREAD(aThread, &aBuffer, iDescriptors[i]->DescriptorData());
       
   956 	}
       
   957 
       
   958 
       
   959 TInt TUsbcDescriptorPool::GetCSInterfaceDescriptorSize(TInt aInterface, TInt aSetting, TInt& aSize) const
       
   960 	{
       
   961 	// first find the interface
       
   962 	TInt i = FindIfcDescriptor(aInterface, aSetting);
       
   963 	if (i < 0)
       
   964 		{
       
   965 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such interface")));
       
   966 		return KErrNotFound;
       
   967 		}
       
   968 	TInt r = KErrNotFound;
       
   969 	TInt size = 0;
       
   970 	const TInt count = iDescriptors.Count();
       
   971 	while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Interface)
       
   972 		{
       
   973 		size += iDescriptors[i]->Size();
       
   974 		r = KErrNone;
       
   975 		}
       
   976 	if (r == KErrNone)
       
   977 		aSize = size;
       
   978 	return r;
       
   979 	}
       
   980 
       
   981 
       
   982 TInt TUsbcDescriptorPool::GetCSEndpointDescriptorTC(DThread* aThread, TDes8& aBuffer, TInt aInterface,
       
   983 													TInt aSetting, TUint8 aEndpointAddress) const
       
   984 	{
       
   985 	// first find the endpoint
       
   986 	TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
       
   987 	if (i < 0)
       
   988 		{
       
   989 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such endpoint")));
       
   990 		return KErrNotFound;
       
   991 		}
       
   992 	TInt r = KErrNotFound;
       
   993 	TInt offset = 0;
       
   994 	const TInt count = iDescriptors.Count();
       
   995 	while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint)
       
   996 		{
       
   997 		__THREADWRITEOFFSET(aThread, &aBuffer, iDescriptors[i]->DescriptorData(), offset);
       
   998 		if (r != KErrNone)
       
   999 			break;
       
  1000 		offset += iDescriptors[i]->Size();
       
  1001 		}
       
  1002 	return r;
       
  1003 	}
       
  1004 
       
  1005 
       
  1006 TInt TUsbcDescriptorPool::SetCSEndpointDescriptorTC(DThread* aThread, const TDes8& aBuffer, TInt aInterface,
       
  1007 													TInt aSetting, TUint8 aEndpointAddress, TInt aSize)
       
  1008 	{
       
  1009 	// first find the endpoint
       
  1010 	TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
       
  1011 	if (i < 0)
       
  1012 		{
       
  1013 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such endpoint")));
       
  1014 		return KErrNotFound;
       
  1015 		}
       
  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)
       
  1019 		;
       
  1020 	// create a new cs descriptor
       
  1021 	TUsbcClassSpecificDescriptor* desc = TUsbcClassSpecificDescriptor::New(KUsbDescType_CS_Endpoint, aSize);
       
  1022 	if (!desc)
       
  1023 		{
       
  1024 		return KErrNoMemory;
       
  1025 		}
       
  1026 	iDescriptors.Insert(desc, i);
       
  1027 	if (iDescriptors[1])
       
  1028 		{
       
  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));
       
  1031 		}
       
  1032 	// copy contents from user side
       
  1033 	return __THREADREAD(aThread, &aBuffer, iDescriptors[i]->DescriptorData());
       
  1034 	}
       
  1035 
       
  1036 
       
  1037 TInt TUsbcDescriptorPool::GetCSEndpointDescriptorSize(TInt aInterface, TInt aSetting,
       
  1038 													  TUint8 aEndpointAddress, TInt& aSize) const
       
  1039 	{
       
  1040 	// first find the endpoint
       
  1041 	TInt i = FindEpDescriptor(aInterface, aSetting, aEndpointAddress);
       
  1042 	if (i < 0)
       
  1043 		{
       
  1044 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such endpoint")));
       
  1045 		return KErrNotFound;
       
  1046 		}
       
  1047 	TInt r = KErrNotFound;
       
  1048 	TInt size = 0;
       
  1049 	const TInt count = iDescriptors.Count();
       
  1050 	while (++i < count && iDescriptors[i]->Type() == KUsbDescType_CS_Endpoint)
       
  1051 		{
       
  1052 		size += iDescriptors[i]->Size();
       
  1053 		r = KErrNone;
       
  1054 		}
       
  1055 	if (r == KErrNone)
       
  1056 		aSize = size;
       
  1057 	return r;
       
  1058 	}
       
  1059 
       
  1060 
       
  1061 TInt TUsbcDescriptorPool::GetManufacturerStringDescriptorTC(DThread* aThread, TDes8& aString) const
       
  1062 	{
       
  1063 	return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Manufact);
       
  1064 	}
       
  1065 
       
  1066 
       
  1067 TInt TUsbcDescriptorPool::SetManufacturerStringDescriptorTC(DThread* aThread, const TDes8& aString)
       
  1068 	{
       
  1069 	return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Manufact);
       
  1070 	}
       
  1071 
       
  1072 
       
  1073 TInt TUsbcDescriptorPool::GetProductStringDescriptorTC(DThread* aThread, TDes8& aString) const
       
  1074 	{
       
  1075 	return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Product);
       
  1076 	}
       
  1077 
       
  1078 
       
  1079 TInt TUsbcDescriptorPool::SetProductStringDescriptorTC(DThread* aThread, const TDes8& aString)
       
  1080 	{
       
  1081 	return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Product);
       
  1082 	}
       
  1083 
       
  1084 
       
  1085 TInt TUsbcDescriptorPool::GetSerialNumberStringDescriptorTC(DThread* aThread, TDes8& aString) const
       
  1086 	{
       
  1087 	return GetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Serial);
       
  1088 	}
       
  1089 
       
  1090 
       
  1091 TInt TUsbcDescriptorPool::SetSerialNumberStringDescriptorTC(DThread* aThread, const TDes8& aString)
       
  1092 	{
       
  1093 	return SetDeviceStringDescriptorTC(aThread, aString, KUsbDescStringIndex_Serial);
       
  1094 	}
       
  1095 
       
  1096 
       
  1097 TInt TUsbcDescriptorPool::GetConfigurationStringDescriptorTC(DThread* aThread, TDes8& aString) const
       
  1098 	{
       
  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])
       
  1103 		{
       
  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());
       
  1107 		}
       
  1108 	else
       
  1109 		{
       
  1110 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no string descriptor @ pos %d!"), str_idx));
       
  1111 		return KErrNotFound;
       
  1112 		}
       
  1113 	}
       
  1114 
       
  1115 
       
  1116 TInt TUsbcDescriptorPool::SetConfigurationStringDescriptorTC(DThread* aThread, const TDes8& aString)
       
  1117 	{
       
  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)
       
  1121 		{
       
  1122 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Warning: $ descriptor too long - string will be truncated")));
       
  1123 		strlen = KUsbStringDescStringMaxSize;
       
  1124 		}
       
  1125 
       
  1126 	HBuf8Plat* strbuf = NULL;
       
  1127 	__NEWPLATBUF(strbuf, strlen);
       
  1128 	if (!strbuf)
       
  1129 		{
       
  1130 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: Memory allocation for config $ desc string failed (1)")));
       
  1131 		return KErrNoMemory;
       
  1132 		}
       
  1133 
       
  1134 	TInt r;	
       
  1135 	__THREADREADPLATBUF(aThread, &aString, strbuf, r);
       
  1136 	if (r != KErrNone)
       
  1137 		{
       
  1138 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: Thread read error")));
       
  1139 		delete strbuf;
       
  1140 		return r;
       
  1141 		}
       
  1142 	TUsbcStringDescriptor* sd = TUsbcStringDescriptor::New(*strbuf);
       
  1143 	if (!sd)
       
  1144 		{
       
  1145 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: Memory allocation for config $ desc failed (2)")));
       
  1146 		delete strbuf;
       
  1147 		return KErrNoMemory;
       
  1148 		}
       
  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);
       
  1153 	delete strbuf;
       
  1154 	return r;
       
  1155 	}
       
  1156 
       
  1157 
       
  1158 // --- private ---
       
  1159 
       
  1160 void TUsbcDescriptorPool::InsertDevDesc(TUsbcDescriptorBase* aDesc)
       
  1161 	{
       
  1162 	TInt count = iDescriptors.Count();
       
  1163 	if (count > 0)
       
  1164 		{
       
  1165 		DeleteDescriptors(0);								// if there's already something at pos. 0, delete it
       
  1166 		}
       
  1167 	iDescriptors.Insert(aDesc, 0);							// in any case: put the new descriptor at position 0
       
  1168 	}
       
  1169 
       
  1170 
       
  1171 void TUsbcDescriptorPool::InsertConfigDesc(TUsbcDescriptorBase* aDesc)
       
  1172 	{
       
  1173 	TInt count = iDescriptors.Count();
       
  1174 	if (count == 0)
       
  1175 		{
       
  1176 		TUsbcDescriptorBase* const iNullDesc = NULL;
       
  1177 		iDescriptors.Append(iNullDesc);						// if array's empty, put a dummy in position 0
       
  1178 		}
       
  1179 	else if (count > 1)
       
  1180 		{
       
  1181 		DeleteDescriptors(1);								// if there's already something at pos. 1, delete it
       
  1182 		}
       
  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)
       
  1187 		{
       
  1188 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertConfigDesc: config descriptor will be invalid!")));
       
  1189 		}
       
  1190 	}
       
  1191 
       
  1192 
       
  1193 void TUsbcDescriptorPool::InsertIfcDesc(TUsbcDescriptorBase* aDesc)
       
  1194 	{
       
  1195 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertIfcDesc()")));
       
  1196 	TInt count = iDescriptors.Count();
       
  1197 	if (count < 2)
       
  1198 		{
       
  1199 		TUsbcDescriptorBase* const iNullDesc = NULL;
       
  1200 		iDescriptors.Append(iNullDesc);						// if array's too small, put some dummies in
       
  1201 		iDescriptors.Append(iNullDesc);
       
  1202 		}
       
  1203 	TBool interface_exists = EFalse;						// set to 'true' if we're adding an alternate
       
  1204 															// setting to an already existing interface
       
  1205 	TInt i = 2;
       
  1206 	while (i < count)
       
  1207 		{
       
  1208 		if (iDescriptors[i]->Type() == KUsbDescType_Interface)
       
  1209 			{
       
  1210 			if (iDescriptors[i]->Byte(2) > aDesc->Byte(2))
       
  1211 				{
       
  1212 				// our interface number is less than the one's just found => insert before it (= here)
       
  1213 				break;
       
  1214 				}
       
  1215 			else if (iDescriptors[i]->Byte(2) == aDesc->Byte(2))
       
  1216 				{
       
  1217 				interface_exists = ETrue;
       
  1218 				// same interface number => look at settings number
       
  1219 				if (iDescriptors[i]->Byte(3) > aDesc->Byte(3))
       
  1220 					{
       
  1221 					// our setting number is less than the one's found => insert before (= here)
       
  1222 					break;
       
  1223 					}
       
  1224 				else if (iDescriptors[i]->Byte(3) == aDesc->Byte(3))
       
  1225 					{
       
  1226 					__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertIfcDesc: error: first delete old one!")));
       
  1227 					return;
       
  1228 					}
       
  1229 				}
       
  1230 			}
       
  1231 		++i;
       
  1232 		}
       
  1233 	iDescriptors.Insert(aDesc, i);							// in any case: put the new descriptor at position i
       
  1234 	if (iDescriptors[1])
       
  1235 		{
       
  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));
       
  1241 		}
       
  1242 	iIfcIdx = i;
       
  1243 	}
       
  1244 
       
  1245 
       
  1246 void TUsbcDescriptorPool::InsertEpDesc(TUsbcDescriptorBase* aDesc)
       
  1247 	{
       
  1248 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertEpDesc()")));
       
  1249 	if (iIfcIdx == 0)
       
  1250 		{
       
  1251 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("TUsbcDescriptorPool::InsertEpDesc: error: only after interface")));
       
  1252 		return;
       
  1253 		}
       
  1254 	TInt count = iDescriptors.Count();
       
  1255 	TInt i = iIfcIdx + 1;
       
  1256 	while (i < count)
       
  1257 		{
       
  1258 		if (iDescriptors[i]->Type() != KUsbDescType_Endpoint)
       
  1259 			break;
       
  1260 		++i;
       
  1261 		}
       
  1262 	iDescriptors.Insert(aDesc, i);							// put the new descriptor at position i
       
  1263 	if (iDescriptors[1])
       
  1264 		{
       
  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()));
       
  1267 		}
       
  1268 	}
       
  1269 
       
  1270 
       
  1271 TInt TUsbcDescriptorPool::FindIfcDescriptor(TInt aIfcNumber, TInt aIfcSetting) const
       
  1272 	{
       
  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)
       
  1277 		{
       
  1278 		if ((iDescriptors[i]->Type() == KUsbDescType_Interface) &&
       
  1279 			(iDescriptors[i]->Byte(2) == aIfcNumber) &&
       
  1280 			(iDescriptors[i]->Byte(3) == aIfcSetting))
       
  1281 			{
       
  1282 			return i;
       
  1283 			}
       
  1284 		}
       
  1285 	__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such interface")));
       
  1286 	return -1;
       
  1287 	}
       
  1288 
       
  1289 
       
  1290 TInt TUsbcDescriptorPool::FindEpDescriptor(TInt aIfcNumber, TInt aIfcSetting, TUint8 aEpAddress) const
       
  1291 	{
       
  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);
       
  1296 	if (ifc < 0)
       
  1297 		{
       
  1298 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such interface")));
       
  1299 		return ifc;
       
  1300 		}
       
  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)
       
  1304 		{
       
  1305 		if (iDescriptors[i]->Type() == KUsbDescType_Interface)
       
  1306 			{
       
  1307 			__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such endpoint before next interface")));
       
  1308 			return -1;
       
  1309 			}
       
  1310 		else if ((iDescriptors[i]->Type() == KUsbDescType_Endpoint) &&
       
  1311 				 (iDescriptors[i]->Byte(2) == aEpAddress))
       
  1312 			{
       
  1313 			return i;										// found
       
  1314 			}
       
  1315 		}
       
  1316 	__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no such endpoint")));
       
  1317 	return -1;
       
  1318 	}
       
  1319 
       
  1320 
       
  1321 void TUsbcDescriptorPool::DeleteDescriptors(TInt aIndex, TInt aCount)
       
  1322 	{
       
  1323 	if (aCount <= 0)
       
  1324 		{
       
  1325 		return;
       
  1326 		}
       
  1327 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("  Removing descriptors at index %d:"), aIndex));
       
  1328 	while (aCount--)
       
  1329 		{
       
  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])
       
  1334 			{
       
  1335 			// if there's a config descriptor (and not a NULL pointer),
       
  1336 			if (ptr->Type() == KUsbDescType_Interface)
       
  1337 				{
       
  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));
       
  1342 				}
       
  1343 			else if (ptr->Type() == KUsbDescType_Endpoint)
       
  1344 				{
       
  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()));
       
  1349 				}
       
  1350 			else if (ptr->Type() == KUsbDescType_CS_Interface || ptr->Type() == KUsbDescType_CS_Endpoint)
       
  1351 				{
       
  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()));
       
  1356 				}
       
  1357 			}
       
  1358 		iDescriptors.Remove(aIndex);
       
  1359 		delete ptr;
       
  1360 		}
       
  1361 	}
       
  1362 
       
  1363 
       
  1364 void TUsbcDescriptorPool::DeleteString(TInt aIndex)
       
  1365 	{
       
  1366 	TUsbcStringDescriptorBase* ptr = iStrings[aIndex];
       
  1367 	iStrings.Remove(aIndex);
       
  1368 	delete ptr;
       
  1369 	}
       
  1370 
       
  1371 
       
  1372 void TUsbcDescriptorPool::UpdateIfcNumbers(TInt aNumber)
       
  1373 	{
       
  1374 	const TInt count = iDescriptors.Count();
       
  1375 	for (TInt i = 2; i < count; ++i)
       
  1376 		{
       
  1377 		if ((iDescriptors[i]->Type() == KUsbDescType_Interface) &&
       
  1378 			(iDescriptors[i]->Byte(2) == aNumber))
       
  1379 			{
       
  1380 			// there's still an interface with 'number' so we don't need to update anything
       
  1381 			return;
       
  1382 			}
       
  1383 		}
       
  1384 	// if we haven't returned yet, we decrement bNumInterfaces
       
  1385 	iDescriptors[1]->SetByte(4, (TUint8)(iDescriptors[1]->Byte(4) - 1));
       
  1386 	}
       
  1387 
       
  1388 
       
  1389 void TUsbcDescriptorPool::UpdateIfcStringIndexes(TInt aStringIndex)
       
  1390 	{
       
  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.
       
  1394 	//
       
  1395 	TInt count = iDescriptors.Count();
       
  1396 	for (TInt i = 2; i < count; ++i)
       
  1397 		{
       
  1398 		if ((iDescriptors[i]->Type() == KUsbDescType_Interface) &&
       
  1399 			(iDescriptors[i]->Byte(8) > aStringIndex))
       
  1400 			{
       
  1401 			iDescriptors[i]->SetByte(8, (TUint8)(iDescriptors[i]->Byte(8) - 1));
       
  1402 			}
       
  1403 		}
       
  1404 	}
       
  1405 
       
  1406 
       
  1407 //
       
  1408 // Only used for Ep0 standard requests, so target buffer could be hard-wired.
       
  1409 //
       
  1410 TInt TUsbcDescriptorPool::GetDeviceDescriptor() const
       
  1411 	{
       
  1412 	return iDescriptors[0]->GetDescriptorData(iEp0_TxBuf, KUsbcBufSz_Ep0Tx);
       
  1413 	}
       
  1414 
       
  1415 
       
  1416 //
       
  1417 // Only used for Ep0 standard requests, so target buffer could be hard-wired.
       
  1418 //
       
  1419 TInt TUsbcDescriptorPool::GetConfigDescriptor() const
       
  1420 	{
       
  1421 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("TUsbcDescriptorPool::GetConfigDescriptor()")));
       
  1422 	TInt copied = 0;
       
  1423 	TInt count = iDescriptors.Count();
       
  1424 	TUint8* buf = iEp0_TxBuf;
       
  1425 	for (TInt i = 1; i < count; ++i)
       
  1426 		{
       
  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);
       
  1430 		if (size == 0)
       
  1431 			{
       
  1432 			// There was no buffer space to copy the descriptor -> no use to proceed
       
  1433 			break;
       
  1434 			}
       
  1435 		copied += size;
       
  1436 		if (copied >= KUsbcBufSz_Ep0Tx)
       
  1437 			{
       
  1438 			// There's no buffer space left -> we need to stop copying here
       
  1439 			break;
       
  1440 			}
       
  1441 		buf += size;
       
  1442 		}
       
  1443 	return copied;
       
  1444 	}
       
  1445 
       
  1446 
       
  1447 //
       
  1448 // Only used for Ep0 standard requests, so target buffer could be hard-wired.
       
  1449 //
       
  1450 TInt TUsbcDescriptorPool::GetStringDescriptor(TInt aIndex) const
       
  1451 	{
       
  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])
       
  1458 		{
       
  1459 		__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("  String @ pos %d"), aIndex));
       
  1460 		TInt size = iStrings[aIndex]->GetDescriptorData(iEp0_TxBuf, KUsbcBufSz_Ep0Tx);
       
  1461 		return size;
       
  1462 		}
       
  1463 	else
       
  1464 		{
       
  1465 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no descriptor @ pos %d!"), aIndex));
       
  1466 		return 0;
       
  1467 		}
       
  1468 	}
       
  1469 
       
  1470 
       
  1471 TInt TUsbcDescriptorPool::GetDeviceStringDescriptorTC(DThread* aThread, TDes8& aString, TInt aIndex) const
       
  1472 	{
       
  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])
       
  1477 		{
       
  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());
       
  1481 		}
       
  1482 	else
       
  1483 		{
       
  1484 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: no string descriptor @ pos %d!"), str_idx));
       
  1485 		return KErrNotFound;
       
  1486 		}
       
  1487 	}
       
  1488 
       
  1489 
       
  1490 TInt TUsbcDescriptorPool::SetDeviceStringDescriptorTC(DThread* aThread, const TDes8& aString, TInt aIndex)
       
  1491 	{
       
  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)
       
  1495 		{
       
  1496 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Warning: $ descriptor too long - string will be truncated")));
       
  1497 		strlen = KUsbStringDescStringMaxSize;
       
  1498 		}
       
  1499 	
       
  1500 	HBuf8Plat* strbuf = NULL;
       
  1501 	__NEWPLATBUF(strbuf, strlen);
       
  1502 	if (!strbuf)
       
  1503 		{
       
  1504 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: Memory allocation for dev $ desc string failed (1)")));
       
  1505 		return KErrNoMemory;
       
  1506 		}
       
  1507 
       
  1508 	TInt r;	
       
  1509 	__THREADREADPLATBUF(aThread, &aString, strbuf, r);
       
  1510 	if (r != KErrNone)
       
  1511 		{
       
  1512 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: Thread read error")));
       
  1513 		delete strbuf;
       
  1514 		return r;
       
  1515 		}
       
  1516 	TUsbcStringDescriptor* sd = TUsbcStringDescriptor::New(*strbuf);
       
  1517 	if (!sd)
       
  1518 		{
       
  1519 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: Memory allocation for dev $ desc failed (2)")));
       
  1520 		delete strbuf;
       
  1521 		return KErrNoMemory;
       
  1522 		}
       
  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);
       
  1527 	delete strbuf;
       
  1528 	return r;
       
  1529 	}
       
  1530 
       
  1531 
       
  1532 TInt TUsbcDescriptorPool::ExchangeStringDescriptor(TInt aIndex, const TUsbcStringDescriptor* aDesc)
       
  1533 	{
       
  1534 	if (aIndex <= 0)
       
  1535 		{
       
  1536 		__KTRACE_OPT(KPANIC, Kern::Printf(__KSTRING("  Error: invalid string descriptor index: %d!"), aIndex));
       
  1537 		return KErrArgument;
       
  1538 		}
       
  1539 	__KTRACE_OPT(KUSB, Kern::Printf(__KSTRING("  Exchanging string descriptor @ index %d"), aIndex));
       
  1540 	DeleteString(aIndex);
       
  1541 	iStrings.Insert(aDesc, aIndex);
       
  1542 	return KErrNone;
       
  1543 	}
       
  1544 
       
  1545 
       
  1546 // -eof-