kernel/eka/drivers/usbho/usbdescriptors/usbdescriptors.cpp
branchRCL_3
changeset 23 1df514389a47
equal deleted inserted replaced
22:2f92ad2dc5db 23:1df514389a47
       
     1 // Copyright (c) 2007-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 // Description:
       
    12 // Symbian USBDI Descriptors Parsing Routines.
       
    13 // 
       
    14 //
       
    15 
       
    16 /**
       
    17  @file
       
    18  @publishedPartner
       
    19 */
       
    20 
       
    21 #include <d32usbdescriptors.h>
       
    22 #include "usbdescutils.h"
       
    23 
       
    24 
       
    25 // ----------------
       
    26 // TUsbGenericDescriptor
       
    27 // ----------------
       
    28 
       
    29 EXPORT_C TUsbGenericDescriptor::TUsbGenericDescriptor()
       
    30 	: iRecognisedAndParsed(EUnrecognised)
       
    31 	, iNextPeer(NULL)
       
    32 	, iFirstChild(NULL)
       
    33 	, iParent(NULL)
       
    34 	{
       
    35 	}
       
    36 
       
    37 /**
       
    38 Deletes all child and peer descriptors.  Does not delete this descriptor, the caller is responsible for
       
    39 doing this separately.
       
    40 */
       
    41 EXPORT_C void TUsbGenericDescriptor::DestroyTree()
       
    42 	{
       
    43 	// Store the tree pointers
       
    44 	TUsbGenericDescriptor* child = this->iFirstChild;
       
    45 	TUsbGenericDescriptor* peer = this->iNextPeer;
       
    46 
       
    47 	// Now we chop off the tree from the root node, by doing this
       
    48 	// we don't need to NULL pointers as we go down (which makes
       
    49 	// the iterative algorithm more efficient).
       
    50 	this->iFirstChild = NULL;
       
    51 	this->iNextPeer = NULL;
       
    52 
       
    53 	// Now we walk and destroy the tree from the two pointers
       
    54 	// we have
       
    55 	WalkAndDelete(child);
       
    56 	WalkAndDelete(peer);
       
    57 	}
       
    58 	
       
    59 void TUsbGenericDescriptor::WalkAndDelete(TUsbGenericDescriptor* aDesc)
       
    60 	{
       
    61 	if(!aDesc)
       
    62 		{
       
    63 		return;
       
    64 		}
       
    65 
       
    66 	TUsbGenericDescriptor* topLevel = aDesc->iParent;
       
    67 	do
       
    68 		{
       
    69 		if(aDesc->iFirstChild)
       
    70 			{
       
    71 			// walk down the tree depth first.
       
    72 			aDesc = aDesc->iFirstChild;
       
    73 			}
       
    74 		else if(aDesc->iNextPeer)
       
    75 			{
       
    76 			// Walk along each peer at the "bottom"
       
    77 			TUsbGenericDescriptor* peer = aDesc->iNextPeer;
       
    78 			delete aDesc;
       
    79 			aDesc = peer;
       
    80 			}
       
    81 		else
       
    82 			{
       
    83 			// End of bottom tier, so we go back up to the parent
       
    84 			// and null the first child pointer so we don't go back
       
    85 			// down again.
       
    86 			TUsbGenericDescriptor* parent = aDesc->iParent;
       
    87 			delete aDesc;
       
    88 			aDesc = parent;
       
    89 			if(aDesc)
       
    90 				{
       
    91 				aDesc->iFirstChild = NULL;
       
    92 				}
       
    93 			
       
    94 			// if we have gone up to the top level for destruction then we don't
       
    95 			// do anymore.
       
    96 			if(aDesc == topLevel)
       
    97 				{
       
    98 				break;
       
    99 				}
       
   100 			}
       
   101 		}
       
   102 	while(aDesc);
       
   103 	}
       
   104 
       
   105 /**
       
   106 Utility method to retrieve a TUint8 value from a given offset in the descriptor.
       
   107 @param aOffset The offset in the binary blob at which to retrieve the value.
       
   108 @return The value from the descriptor.
       
   109 */
       
   110 EXPORT_C TUint8 TUsbGenericDescriptor::TUint8At(TInt aOffset) const
       
   111 	{
       
   112 	return ParseTUint8(iBlob, aOffset);
       
   113 	}
       
   114 
       
   115 /**
       
   116 Utility method to retrieve a TUint16 value from a given offset in the descriptor.
       
   117 @param aOffset The offset in the binary blob at which to retrieve the value.
       
   118 @return The value from the descriptor.
       
   119 */
       
   120 EXPORT_C TUint16 TUsbGenericDescriptor::TUint16At(TInt aOffset) const
       
   121 	{
       
   122 	return ParseTUint16(iBlob, aOffset);
       
   123 	}
       
   124 
       
   125 /**
       
   126 Utility method to retrieve a TUint32 value from a given offset in the descriptor.
       
   127 @param aOffset The offset in the binary blob at which to retrieve the value.
       
   128 @return The value from the descriptor.
       
   129 */
       
   130 EXPORT_C TUint32 TUsbGenericDescriptor::TUint32At(TInt aOffset) const
       
   131 	{
       
   132 	return ParseTUint32(iBlob, aOffset);
       
   133 	}
       
   134 
       
   135 /**
       
   136 Assignment operator to fill in the TUsbGenericDescriptor fields from a TUsbGenericDescriptor.
       
   137 Note that if a TUsbGenericDescriptor derived class has additional member fields then
       
   138 they should define a specialised assignment overload for that type.
       
   139 */
       
   140 EXPORT_C TUsbGenericDescriptor& TUsbGenericDescriptor::operator=(const TUsbGenericDescriptor& aDescriptor)
       
   141 	{
       
   142 	ibLength = aDescriptor.ibLength;
       
   143 	ibDescriptorType = aDescriptor.ibDescriptorType;
       
   144 	iRecognisedAndParsed = aDescriptor.iRecognisedAndParsed;
       
   145 	iNextPeer = aDescriptor.iNextPeer;
       
   146 	iFirstChild = aDescriptor.iFirstChild;
       
   147 	iParent = aDescriptor.iParent;
       
   148 	iBlob.Set(aDescriptor.iBlob);
       
   149 	return *this;
       
   150 	}
       
   151 
       
   152 /**
       
   153 This function determines whether the given USB descriptor is a parent
       
   154 of the descriptor the method is called on.  The implementation may be
       
   155 specialised for each type of descriptor to ensure the tree is correctly
       
   156 built up.
       
   157 @param aPotentialRelative The USB descriptor that is being queried to see if it is a parent or peer.
       
   158 @return TBool Efalse if the given USB descriptor is a parent of this USB descriptor, ETrue if a peer of this descriptor
       
   159 */
       
   160 /*virtual*/ TBool TUsbGenericDescriptor::IsParent(TUsbGenericDescriptor& aPotentialParent)
       
   161 	{
       
   162 	// As generic descriptors we consider all other "unknown" descriptors as peers, and
       
   163 	// all "known" descriptors as parents of the descriptor.
       
   164 	switch(aPotentialParent.ibDescriptorType)
       
   165 		{
       
   166 	case EDevice:
       
   167 	case EConfiguration:
       
   168 	case EString:
       
   169 	case EInterface:
       
   170 	case EEndpoint:
       
   171 	case EDeviceQualifier:
       
   172 	case EOtherSpeedConfiguration:
       
   173 	case EInterfacePower:
       
   174 	case EOTG:
       
   175 	case EDebug:
       
   176 	case EInterfaceAssociation:
       
   177 		return ETrue;
       
   178 	default:
       
   179 		return EFalse;
       
   180 		}
       
   181 	}
       
   182 
       
   183 /**
       
   184 This function determines whether the given USB descriptor is a peer
       
   185 of the descriptor the method is called on.  The implementation may be
       
   186 specialised for each type of descriptor to ensure the tree is correctly
       
   187 built up.
       
   188 @param aPotentialPeer The USB descriptor that is being queried to see if it is a peer.
       
   189 @return TBool EFalse if the given USB descriptor is a parent of this USB descriptor, ETrue if a peer of this descriptor
       
   190 */
       
   191 /*virtual*/ TBool TUsbGenericDescriptor::IsPeer(TUsbGenericDescriptor& /*aPotentialPeer*/)
       
   192 	{
       
   193 	// As generic descriptors we are very permissive in binding peers.
       
   194 	return ETrue;
       
   195 	}
       
   196 
       
   197 /**
       
   198 This function determines whether the given USB descriptor is a child
       
   199 of the descriptor the method is called on.  The implementation may be
       
   200 specialised for each type of descriptor to ensure the tree is correctly
       
   201 built up.
       
   202 @param aPotentialChild The USB descriptor that is being queried to see if it is a child.
       
   203 @return TBool ETrue if the given USB descriptor is a child of this USB descriptor, ETrue if a peer of this descriptor
       
   204 */
       
   205 /*virtual*/ TBool TUsbGenericDescriptor::IsChild(TUsbGenericDescriptor& /*aPotentialChild*/)
       
   206 	{
       
   207 	// We just use the logic in the IsParent.
       
   208 	return EFalse;
       
   209 	}
       
   210 
       
   211 /**
       
   212 Ensures no memory is leaked if an owned TUsbGenericDescriptor is no longer needed.
       
   213 @param aPtr The TUsbGenericDescriptor that is to be cleaned up.
       
   214 @internalComponent
       
   215 */
       
   216 EXPORT_C /*static*/ void TUsbGenericDescriptor::Cleanup(TAny* aPtr)
       
   217 	{
       
   218 	TUsbGenericDescriptor* ptr = static_cast<TUsbGenericDescriptor*>(aPtr);
       
   219 	ptr->DestroyTree(); // belt and braces really.
       
   220 	delete ptr;
       
   221 	}
       
   222 
       
   223 
       
   224 // ----------------------
       
   225 // TUsbDeviceDescriptor
       
   226 // See section 9.6.1 of the USB 2.0 specification.
       
   227 // ----------------------
       
   228 
       
   229 EXPORT_C TUsbDeviceDescriptor::TUsbDeviceDescriptor()
       
   230 	{
       
   231 	}
       
   232 
       
   233 EXPORT_C /*static*/ TUsbDeviceDescriptor* TUsbDeviceDescriptor::Cast(TUsbGenericDescriptor* aOriginal)
       
   234 	{
       
   235 	TUsbDeviceDescriptor* ret = NULL;
       
   236 	// Only cast if correctly indentified as device descriptor
       
   237 	if(	aOriginal &&
       
   238 		aOriginal->ibDescriptorType == EDevice &&
       
   239 		aOriginal->ibLength == TUsbDeviceDescriptor::KSizeInOctets &&
       
   240 		aOriginal->iRecognisedAndParsed == ERecognised)
       
   241 		{
       
   242 		ret = static_cast<TUsbDeviceDescriptor*>(aOriginal);
       
   243 		}
       
   244 	return ret;
       
   245 	}
       
   246 
       
   247 EXPORT_C TUint16 TUsbDeviceDescriptor::USBBcd() const
       
   248 	{
       
   249     return ParseTUint16(iBlob, EbcdUSB);
       
   250 	}
       
   251 	
       
   252 EXPORT_C TUint8 TUsbDeviceDescriptor::DeviceClass() const
       
   253 	{
       
   254 	return ParseTUint8(iBlob, EbDeviceClass);
       
   255 	}
       
   256 
       
   257 EXPORT_C TUint8 TUsbDeviceDescriptor::DeviceSubClass() const
       
   258 	{
       
   259 	return ParseTUint8(iBlob, EbDeviceSubClass);
       
   260 	}
       
   261 
       
   262 EXPORT_C TUint8 TUsbDeviceDescriptor::DeviceProtocol() const
       
   263 	{
       
   264 	return ParseTUint8(iBlob, EbDeviceProtocol);
       
   265 	}
       
   266 
       
   267 EXPORT_C TUint8 TUsbDeviceDescriptor::MaxPacketSize0() const
       
   268 	{
       
   269 	return ParseTUint8(iBlob, EbMaxPacketSize0);
       
   270 	}
       
   271 
       
   272 EXPORT_C TUint16 TUsbDeviceDescriptor::VendorId() const
       
   273 	{
       
   274 	return ParseTUint16(iBlob, EidVendor);
       
   275 	}
       
   276 
       
   277 EXPORT_C TUint16 TUsbDeviceDescriptor::ProductId() const
       
   278 	{
       
   279 	return ParseTUint16(iBlob, EidProduct);
       
   280 	}
       
   281 
       
   282 EXPORT_C TUint16 TUsbDeviceDescriptor::DeviceBcd() const
       
   283 	{
       
   284 	return ParseTUint16(iBlob, EbcdDevice);
       
   285 	}
       
   286 
       
   287 EXPORT_C TUint8 TUsbDeviceDescriptor::ManufacturerIndex() const
       
   288 	{
       
   289 	return ParseTUint8(iBlob, EiManufacturer);
       
   290 	}
       
   291 
       
   292 EXPORT_C TUint8 TUsbDeviceDescriptor::ProductIndex() const
       
   293 	{
       
   294 	return ParseTUint8(iBlob, EiProduct);
       
   295 	}
       
   296 
       
   297 EXPORT_C TUint8 TUsbDeviceDescriptor::SerialNumberIndex() const
       
   298 	{
       
   299 	return ParseTUint8(iBlob, EiSerialNumber);
       
   300 	}
       
   301 
       
   302 EXPORT_C TUint8 TUsbDeviceDescriptor::NumConfigurations() const
       
   303 	{
       
   304 	return ParseTUint8(iBlob, EbNumConfigurations);
       
   305 	}
       
   306 
       
   307 /**
       
   308 The parsing routine for device descriptors.
       
   309 Here the previous descriptor parameter is ignored - because logically a device descriptor can be neither a peer
       
   310 nor a child.
       
   311 
       
   312 @internalComponent
       
   313 */
       
   314 /*static*/ TUsbDeviceDescriptor* TUsbDeviceDescriptor::ParseL(TPtrC8& aUsbDes, TUsbGenericDescriptor* aPreviousDesc)
       
   315 	{
       
   316 	TUsbDeviceDescriptor* devDes = NULL;
       
   317 
       
   318 	const TInt KMinDeviceDesDecisionLength = 2;
       
   319 	if(	aUsbDes.Length() >= KMinDeviceDesDecisionLength &&
       
   320 		aUsbDes[KbDescriptorTypeOffset] == EDevice &&
       
   321 		aUsbDes[KbLengthOffset] == TUsbDeviceDescriptor::KSizeInOctets)
       
   322 		{
       
   323 		// Robustness check - check the length field is valid, and that we have enough data.
       
   324 		if(aUsbDes.Length() < TUsbDeviceDescriptor::KSizeInOctets)
       
   325 			{
       
   326 			User::Leave(KErrCorrupt);
       
   327 			}
       
   328 			
       
   329 		// Robustness check - check that the device descriptor is the first to be parsed.
       
   330 		if(aPreviousDesc)
       
   331 			{
       
   332 			User::Leave(KErrCorrupt);
       
   333 			}
       
   334 
       
   335 		// Looks ok to be a device descriptor.
       
   336 		devDes = new(ELeave) TUsbDeviceDescriptor;
       
   337 		// Set the standard fields
       
   338 		devDes->ibLength = TUsbDeviceDescriptor::KSizeInOctets;
       
   339 		devDes->ibDescriptorType = EDevice;
       
   340 		// Set the blob appropriately
       
   341 		devDes->iBlob.Set(aUsbDes.Left(TUsbDeviceDescriptor::KSizeInOctets));
       
   342 		
       
   343 		devDes->iRecognisedAndParsed = ERecognised;
       
   344 
       
   345 		// Update the data-left-to-parse Symbian descriptor
       
   346 		aUsbDes.Set(aUsbDes.Mid(TUsbDeviceDescriptor::KSizeInOctets));
       
   347 		}
       
   348 
       
   349 	return devDes;
       
   350 	}
       
   351 
       
   352 /**
       
   353 @internalComponent
       
   354 */
       
   355 /*virtual*/ TBool TUsbDeviceDescriptor::IsParent(TUsbGenericDescriptor& /*aPotentialParent*/)
       
   356 	{
       
   357 	// The device descriptor should only come by itself in a bundle, so must be top-level.
       
   358 	return EFalse;
       
   359 	}
       
   360 
       
   361 /**
       
   362 @internalComponent
       
   363 */
       
   364 /*virtual*/ TBool TUsbDeviceDescriptor::IsPeer(TUsbGenericDescriptor& /*aPotentialPeer*/)
       
   365 	{
       
   366 	// The device descriptor should only come by itself in a bundle, so no other peers.
       
   367 	return EFalse;
       
   368 	}
       
   369 
       
   370 
       
   371 // ------------------------------
       
   372 // TUsbDeviceQualifierDescriptor
       
   373 // See section 9.6.2 of the USB 2.0 specification.
       
   374 // ------------------------------
       
   375 
       
   376 EXPORT_C TUsbDeviceQualifierDescriptor::TUsbDeviceQualifierDescriptor()
       
   377 	{
       
   378 	}
       
   379 	
       
   380 EXPORT_C /*static*/ TUsbDeviceQualifierDescriptor* TUsbDeviceQualifierDescriptor::Cast(TUsbGenericDescriptor* aOriginal)
       
   381 	{
       
   382 	TUsbDeviceQualifierDescriptor* ret = NULL;
       
   383 	// Only cast if correctly indentified as device qualifier descriptor
       
   384 	if(	aOriginal &&
       
   385 		aOriginal->ibDescriptorType == EDeviceQualifier &&
       
   386 		aOriginal->ibLength == TUsbDeviceQualifierDescriptor::KSizeInOctets &&
       
   387 		aOriginal->iRecognisedAndParsed == ERecognised)
       
   388 		{
       
   389 		ret = static_cast<TUsbDeviceQualifierDescriptor*>(aOriginal);
       
   390 		}
       
   391 	return ret;
       
   392 	}
       
   393 
       
   394 EXPORT_C TUint16 TUsbDeviceQualifierDescriptor::USBBcd() const
       
   395 	{
       
   396 	return ParseTUint16(iBlob, EbcdUSB);
       
   397 	}
       
   398 
       
   399 EXPORT_C TUint8 TUsbDeviceQualifierDescriptor::DeviceClass() const
       
   400 	{
       
   401 	return ParseTUint8(iBlob, EbDeviceClass);
       
   402 	}
       
   403 
       
   404 EXPORT_C TUint8 TUsbDeviceQualifierDescriptor::DeviceSubClass() const
       
   405 	{
       
   406 	return ParseTUint8(iBlob, EbDeviceSubClass);
       
   407 	}
       
   408 
       
   409 EXPORT_C TUint8 TUsbDeviceQualifierDescriptor::DeviceProtocol() const
       
   410 	{
       
   411 	return ParseTUint8(iBlob, EbDeviceProtocol);
       
   412 	}
       
   413 
       
   414 EXPORT_C TUint8 TUsbDeviceQualifierDescriptor::MaxPacketSize0() const
       
   415 	{
       
   416 	return ParseTUint8(iBlob, EbMaxPacketSize0);
       
   417 	}
       
   418 
       
   419 EXPORT_C TUint8 TUsbDeviceQualifierDescriptor::NumConfigurations() const
       
   420 	{
       
   421 	return ParseTUint8(iBlob, EbNumConfigurations);
       
   422 	}
       
   423 
       
   424 EXPORT_C TUint8 TUsbDeviceQualifierDescriptor::Reserved() const
       
   425 	{
       
   426 	return ParseTUint8(iBlob, EbReserved);
       
   427 	}
       
   428 	
       
   429 /**
       
   430 The parsing routine for device qualifier descriptors.
       
   431 
       
   432 @internalComponent
       
   433 */
       
   434 /*static*/ TUsbDeviceQualifierDescriptor* TUsbDeviceQualifierDescriptor::ParseL(TPtrC8& aUsbDes, TUsbGenericDescriptor* /*aPreviousDesc*/)
       
   435 	{
       
   436 	TUsbDeviceQualifierDescriptor* devQualDes = NULL;
       
   437 
       
   438 	const TInt KMinDevQualDesDecisionLength = 2;
       
   439 	if(	aUsbDes.Length() >= KMinDevQualDesDecisionLength &&
       
   440 		aUsbDes[KbDescriptorTypeOffset] == EDeviceQualifier &&
       
   441 		aUsbDes[KbLengthOffset] == TUsbDeviceQualifierDescriptor::KSizeInOctets)
       
   442 		{
       
   443 		// Robustness check - check the length field is valid, and that we have enough data.
       
   444 		if(aUsbDes.Length() < TUsbDeviceQualifierDescriptor::KSizeInOctets)
       
   445 			{
       
   446 			User::Leave(KErrCorrupt);
       
   447 			}
       
   448 
       
   449 		// Looks ok to be a device quialifier descriptor.
       
   450 		devQualDes = new(ELeave) TUsbDeviceQualifierDescriptor;
       
   451 		// Set the standard fields
       
   452 		devQualDes->ibLength = TUsbDeviceQualifierDescriptor::KSizeInOctets;
       
   453 		devQualDes->ibDescriptorType = EDeviceQualifier;
       
   454 		// Set the blob appropriately
       
   455 		devQualDes->iBlob.Set(aUsbDes.Left(TUsbDeviceQualifierDescriptor::KSizeInOctets));
       
   456 
       
   457 		devQualDes->iRecognisedAndParsed = ERecognised;
       
   458 
       
   459 		// Update the data-left-to-parse Symbian descriptor
       
   460 		aUsbDes.Set(aUsbDes.Mid(TUsbDeviceQualifierDescriptor::KSizeInOctets));
       
   461 		}
       
   462 
       
   463 	return devQualDes;
       
   464 	}
       
   465 
       
   466 /**
       
   467 @internalComponent
       
   468 */
       
   469 /*virtual*/ TBool TUsbDeviceQualifierDescriptor::IsParent(TUsbGenericDescriptor& /*aPotentialParent*/)
       
   470 	{
       
   471 	// Like a device descriptor, they should be top-level.
       
   472 	return EFalse;
       
   473 	}
       
   474 
       
   475 /**
       
   476 @internalComponent
       
   477 */
       
   478 /*virtual*/ TBool TUsbDeviceQualifierDescriptor::IsPeer(TUsbGenericDescriptor& /*aPotentialPeer*/)
       
   479 	{
       
   480 	// Like a device descriptor, they should come by themselves.
       
   481 	return EFalse;
       
   482 	}
       
   483 
       
   484 
       
   485 // ----------------------------
       
   486 // TUsbConfigurationDescriptor
       
   487 // See section 9.6.3 of the USB 2.0 specification.
       
   488 // ----------------------------
       
   489 
       
   490 EXPORT_C TUsbConfigurationDescriptor::TUsbConfigurationDescriptor()
       
   491 	{
       
   492 	}
       
   493 	
       
   494 EXPORT_C /*static*/ TUsbConfigurationDescriptor* TUsbConfigurationDescriptor::Cast(TUsbGenericDescriptor* aOriginal)
       
   495 	{
       
   496 	TUsbConfigurationDescriptor* ret = NULL;
       
   497 	// Only cast if correctly indentified as configuration descriptor
       
   498 	if(	aOriginal &&
       
   499 		aOriginal->ibDescriptorType == EConfiguration &&
       
   500 		aOriginal->ibLength == TUsbConfigurationDescriptor::KSizeInOctets &&
       
   501 		aOriginal->iRecognisedAndParsed == ERecognised)
       
   502 		{
       
   503 		ret = static_cast<TUsbConfigurationDescriptor*>(aOriginal);
       
   504 		}
       
   505 	return ret;
       
   506 	}
       
   507 
       
   508 EXPORT_C TUint16 TUsbConfigurationDescriptor::TotalLength() const
       
   509 	{
       
   510 	return ParseTUint16(iBlob, EwTotalLength);
       
   511 	}
       
   512 
       
   513 EXPORT_C TUint8 TUsbConfigurationDescriptor::NumInterfaces() const
       
   514 	{
       
   515 	return ParseTUint8(iBlob, EbNumInterfaces);
       
   516 	}
       
   517 
       
   518 EXPORT_C TUint8 TUsbConfigurationDescriptor::ConfigurationValue() const
       
   519 	{
       
   520 	return ParseTUint8(iBlob, EbConfigurationValue);
       
   521 	}
       
   522 
       
   523 EXPORT_C TUint8 TUsbConfigurationDescriptor::ConfigurationIndex() const
       
   524 	{
       
   525 	return ParseTUint8(iBlob, EiConfiguration);
       
   526 	}
       
   527 
       
   528 EXPORT_C TUint8 TUsbConfigurationDescriptor::Attributes() const
       
   529 	{
       
   530 	return ParseTUint8(iBlob, EbmAttributes);
       
   531 	}
       
   532 
       
   533 EXPORT_C TUint8 TUsbConfigurationDescriptor::MaxPower() const
       
   534 	{
       
   535 	return ParseTUint8(iBlob, EbMaxPower);
       
   536 	}
       
   537 
       
   538 /**
       
   539 The parsing routine for configuration descriptors.
       
   540 
       
   541 @internalComponent
       
   542 */
       
   543 /*static*/ TUsbConfigurationDescriptor* TUsbConfigurationDescriptor::ParseL(TPtrC8& aUsbDes, TUsbGenericDescriptor* /*aPreviousDesc*/)
       
   544 	{
       
   545 	TUsbConfigurationDescriptor* configDes = NULL;
       
   546 
       
   547 	const TInt KMinConfigDesDecisionLength = 2;
       
   548 	if(	aUsbDes.Length() >= KMinConfigDesDecisionLength &&
       
   549 		aUsbDes[KbDescriptorTypeOffset] == EConfiguration &&
       
   550 		aUsbDes[KbLengthOffset] == TUsbConfigurationDescriptor::KSizeInOctets)
       
   551 		{
       
   552 		// Robustness check - check the length field is valid, and that we have enough data.
       
   553 		if(aUsbDes.Length() < TUsbConfigurationDescriptor::KSizeInOctets)
       
   554 			{
       
   555 			User::Leave(KErrCorrupt);
       
   556 			}
       
   557 			
       
   558 		// Robustness check - check that there is sufficient data for whole bundle (wTotalLength)
       
   559 		const TInt KwTotalLengthOffset = 2;
       
   560 		if(aUsbDes.Length() < ParseTUint16(aUsbDes, KwTotalLengthOffset))
       
   561 			{
       
   562 			User::Leave(KErrCorrupt);
       
   563 			}
       
   564 
       
   565 		// Looks ok to be a configuration descriptor.
       
   566 		configDes = new(ELeave) TUsbConfigurationDescriptor;
       
   567 		// Set the standard fields
       
   568 		configDes->ibLength = TUsbConfigurationDescriptor::KSizeInOctets;
       
   569 		configDes->ibDescriptorType = EConfiguration;
       
   570 		// Set the blob appropriately
       
   571 		configDes->iBlob.Set(aUsbDes.Left(TUsbConfigurationDescriptor::KSizeInOctets));
       
   572 
       
   573 		configDes->iRecognisedAndParsed = ERecognised;
       
   574 
       
   575 		// Update the data-left-to-parse Symbian descriptor
       
   576 		aUsbDes.Set(aUsbDes.Mid(TUsbConfigurationDescriptor::KSizeInOctets));
       
   577 		}
       
   578 
       
   579 	return configDes;
       
   580 	}
       
   581 
       
   582 /**
       
   583 @internalComponent
       
   584 */
       
   585 /*virtual*/ TBool TUsbConfigurationDescriptor::IsParent(TUsbGenericDescriptor& /*aPotentialParent*/)
       
   586 	{
       
   587 	// A configuration descriptor should always be the top-level descriptor in a configuration
       
   588 	// bundle.
       
   589 	return EFalse;
       
   590 	}
       
   591 
       
   592 /**
       
   593 @internalComponent
       
   594 */
       
   595 /*virtual*/ TBool TUsbConfigurationDescriptor::IsPeer(TUsbGenericDescriptor& /*aPotentialPeer*/)
       
   596 	{
       
   597 	// There should only ever be one configuration descriptor in a bundle.
       
   598 	return EFalse;
       
   599 	}
       
   600 
       
   601 
       
   602 // --------------------------
       
   603 // TUsbOtherSpeedDescriptor
       
   604 // See section 9.6.4 of the USB 2.0 specification.
       
   605 // --------------------------
       
   606 
       
   607 EXPORT_C TUsbOtherSpeedDescriptor::TUsbOtherSpeedDescriptor()
       
   608 	{
       
   609 	}
       
   610 	
       
   611 EXPORT_C /*static*/ TUsbOtherSpeedDescriptor* TUsbOtherSpeedDescriptor::Cast(TUsbGenericDescriptor* aOriginal)
       
   612 	{
       
   613 	TUsbOtherSpeedDescriptor* ret = NULL;
       
   614 	// Only cast if correctly indentified as other speed descriptor
       
   615 	if(	aOriginal &&
       
   616 		aOriginal->ibDescriptorType == EOtherSpeedConfiguration &&
       
   617 		aOriginal->ibLength == TUsbOtherSpeedDescriptor::KSizeInOctets &&
       
   618 		aOriginal->iRecognisedAndParsed == ERecognised)
       
   619 		{
       
   620 		ret = static_cast<TUsbOtherSpeedDescriptor*>(aOriginal);
       
   621 		}
       
   622 	return ret;
       
   623 	}
       
   624 
       
   625 EXPORT_C TUint16 TUsbOtherSpeedDescriptor::TotalLength() const
       
   626 	{
       
   627 	return ParseTUint16(iBlob, EwTotalLength);
       
   628 	}
       
   629 
       
   630 EXPORT_C TUint8 TUsbOtherSpeedDescriptor::NumInterfaces() const
       
   631 	{
       
   632 	return ParseTUint8(iBlob, EbNumInterfaces);
       
   633 	}
       
   634 
       
   635 EXPORT_C TUint8 TUsbOtherSpeedDescriptor::ConfigurationValue() const
       
   636 	{
       
   637 	return ParseTUint8(iBlob, EbConfigurationValue);
       
   638 	}
       
   639 
       
   640 EXPORT_C TUint8 TUsbOtherSpeedDescriptor::ConfigurationIndex() const
       
   641 	{
       
   642 	return ParseTUint8(iBlob, EiConfiguration);
       
   643 	}
       
   644 
       
   645 EXPORT_C TUint8 TUsbOtherSpeedDescriptor::Attributes() const
       
   646 	{
       
   647 	return ParseTUint8(iBlob, EbmAttributes);
       
   648 	}
       
   649 
       
   650 EXPORT_C TUint8 TUsbOtherSpeedDescriptor::MaxPower() const
       
   651 	{
       
   652 	return ParseTUint8(iBlob, EbMaxPower);
       
   653 	}
       
   654 	
       
   655 /**
       
   656 The parsing routine for other speed descriptors.
       
   657 
       
   658 @internalComponent
       
   659 */
       
   660 /*static*/ TUsbOtherSpeedDescriptor* TUsbOtherSpeedDescriptor::ParseL(TPtrC8& aUsbDes, TUsbGenericDescriptor* /*aPreviousDesc*/)
       
   661 	{
       
   662 	TUsbOtherSpeedDescriptor* oSpeedDes = NULL;
       
   663 
       
   664 	const TInt KMinOtherSpeedDesDecisionLength = 2;
       
   665 	if(	aUsbDes.Length() >= KMinOtherSpeedDesDecisionLength &&
       
   666 		aUsbDes[KbDescriptorTypeOffset] == EOtherSpeedConfiguration &&
       
   667 		aUsbDes[KbLengthOffset] == TUsbOtherSpeedDescriptor::KSizeInOctets)
       
   668 		{
       
   669 		// Robustness check - check the length field is valid, and that we have enough data.
       
   670 		if(aUsbDes.Length() < TUsbOtherSpeedDescriptor::KSizeInOctets)
       
   671 			{
       
   672 			User::Leave(KErrCorrupt);
       
   673 			}
       
   674 	
       
   675 		// Robustness check - check that there is sufficient data for whole bundle (wTotalLength)
       
   676 		const TInt KwTotalLengthOffset = 2;
       
   677 		if(aUsbDes.Length() < ParseTUint16(aUsbDes, KwTotalLengthOffset))
       
   678 			{
       
   679 			User::Leave(KErrCorrupt);
       
   680 			}
       
   681 
       
   682 		// Looks ok to be an other speed descriptor.
       
   683 		oSpeedDes = new(ELeave) TUsbOtherSpeedDescriptor;
       
   684 		// Set the standard fields
       
   685 		oSpeedDes->ibLength = TUsbOtherSpeedDescriptor::KSizeInOctets;
       
   686 		oSpeedDes->ibDescriptorType = EOtherSpeedConfiguration;
       
   687 		// Set the blob appropriately
       
   688 		oSpeedDes->iBlob.Set(aUsbDes.Left(TUsbOtherSpeedDescriptor::KSizeInOctets));
       
   689 
       
   690 		oSpeedDes->iRecognisedAndParsed = ERecognised;
       
   691 
       
   692 		// Update the data-left-to-parse Symbian descriptor
       
   693 		aUsbDes.Set(aUsbDes.Mid(TUsbOtherSpeedDescriptor::KSizeInOctets));
       
   694 		}
       
   695 
       
   696 	return oSpeedDes;
       
   697 	}
       
   698 
       
   699 /**
       
   700 @internalComponent
       
   701 */
       
   702 /*virtual*/ TBool TUsbOtherSpeedDescriptor::IsParent(TUsbGenericDescriptor& /*aPotentialParent*/)
       
   703 	{
       
   704 	// Other speed descriptor is like a configuration descriptor, in that it should
       
   705 	// not have any parents in a bundle.
       
   706 	return EFalse;
       
   707 	}
       
   708 
       
   709 /**
       
   710 @internalComponent
       
   711 */
       
   712 /*virtual*/ TBool TUsbOtherSpeedDescriptor::IsPeer(TUsbGenericDescriptor& /*aPotentialPeer*/)
       
   713 	{
       
   714 	// There should only ever be one other speed descriptor in a bundle.
       
   715 	return EFalse;
       
   716 	}
       
   717 
       
   718 
       
   719 // ------------------------------------
       
   720 // TUsbInterfaceAssociationDescriptor
       
   721 // See the USB IAD ECN.
       
   722 // ------------------------------------
       
   723 
       
   724 EXPORT_C TUsbInterfaceAssociationDescriptor::TUsbInterfaceAssociationDescriptor()
       
   725 	{
       
   726 	}
       
   727 	
       
   728 EXPORT_C /*static*/ TUsbInterfaceAssociationDescriptor* TUsbInterfaceAssociationDescriptor::Cast(TUsbGenericDescriptor* aOriginal)
       
   729 	{
       
   730 	TUsbInterfaceAssociationDescriptor* ret = NULL;
       
   731 	// Only cast if correctly indentified as interface association descriptor
       
   732 	if(	aOriginal &&
       
   733 		aOriginal->ibDescriptorType == EInterfaceAssociation &&
       
   734 		aOriginal->ibLength == TUsbInterfaceAssociationDescriptor::KSizeInOctets &&
       
   735 		aOriginal->iRecognisedAndParsed == ERecognised)
       
   736 		{
       
   737 		ret = static_cast<TUsbInterfaceAssociationDescriptor*>(aOriginal);
       
   738 		}
       
   739 	return ret;
       
   740 	}
       
   741 
       
   742 EXPORT_C TUint8 TUsbInterfaceAssociationDescriptor::FirstInterface() const
       
   743 	{
       
   744 	return ParseTUint8(iBlob, EbFirstInterface);
       
   745 	}
       
   746 
       
   747 EXPORT_C TUint8 TUsbInterfaceAssociationDescriptor::InterfaceCount() const
       
   748 	{
       
   749 	return ParseTUint8(iBlob, EbInterfaceCount);
       
   750 	}
       
   751 
       
   752 EXPORT_C TUint8 TUsbInterfaceAssociationDescriptor::FunctionClass() const
       
   753 	{
       
   754 	return ParseTUint8(iBlob, EbFunctionClass);
       
   755 	}
       
   756 
       
   757 EXPORT_C TUint8 TUsbInterfaceAssociationDescriptor::FunctionSubClass() const
       
   758 	{
       
   759 	return ParseTUint8(iBlob, EbFunctionSubClass);
       
   760 	}
       
   761 
       
   762 EXPORT_C TUint8 TUsbInterfaceAssociationDescriptor::FunctionProtocol() const
       
   763 	{
       
   764 	return ParseTUint8(iBlob, EbFunctionProtocol);
       
   765 	}
       
   766 
       
   767 EXPORT_C TUint8 TUsbInterfaceAssociationDescriptor::FunctionIndex() const
       
   768 	{
       
   769 	return ParseTUint8(iBlob, EiFunction);
       
   770 	}
       
   771 	
       
   772 /*static*/ TUsbInterfaceAssociationDescriptor* TUsbInterfaceAssociationDescriptor::ParseL(TPtrC8& aUsbDes, TUsbGenericDescriptor* /*aPreviousDesc*/)
       
   773 	{
       
   774 	TUsbInterfaceAssociationDescriptor* intAssocDes = NULL;
       
   775 
       
   776 	const TInt KMinIntAssocDesDecisionLength = 2;
       
   777 	if(	aUsbDes.Length() >= KMinIntAssocDesDecisionLength &&
       
   778 		aUsbDes[KbDescriptorTypeOffset] == EInterfaceAssociation &&
       
   779 		aUsbDes[KbLengthOffset] == TUsbInterfaceAssociationDescriptor::KSizeInOctets)
       
   780 		{
       
   781 		// Robustness check - check the length field is valid, and that we have enough data.
       
   782 		if(aUsbDes.Length() < TUsbInterfaceAssociationDescriptor::KSizeInOctets)
       
   783 			{
       
   784 			User::Leave(KErrCorrupt);
       
   785 			}
       
   786 
       
   787 		// Looks ok to be a interface association descriptor.
       
   788 		intAssocDes = new(ELeave) TUsbInterfaceAssociationDescriptor;
       
   789 		// Set the standard fields
       
   790 		intAssocDes->ibLength = TUsbInterfaceAssociationDescriptor::KSizeInOctets;
       
   791 		intAssocDes->ibDescriptorType = EInterfaceAssociation;
       
   792 		// Set the blob appropriately
       
   793 		intAssocDes->iBlob.Set(aUsbDes.Left(TUsbInterfaceAssociationDescriptor::KSizeInOctets));
       
   794 	
       
   795 		intAssocDes->iRecognisedAndParsed = ERecognised;
       
   796 
       
   797 		// Update the data-left-to-parse Symbian descriptor
       
   798 		aUsbDes.Set(aUsbDes.Mid(TUsbInterfaceAssociationDescriptor::KSizeInOctets));
       
   799 		}
       
   800 
       
   801 	return intAssocDes;
       
   802 	}
       
   803 
       
   804 /**
       
   805 @internalComponent
       
   806 */
       
   807 /*virtual*/ TBool TUsbInterfaceAssociationDescriptor::IsParent(TUsbGenericDescriptor& aPotentialParent)
       
   808 	{
       
   809 	switch(aPotentialParent.ibDescriptorType)
       
   810 		{
       
   811 	case EConfiguration:
       
   812 		return ETrue;
       
   813 	case EOtherSpeedConfiguration:
       
   814 		return ETrue;	// I think this should be EFalse by my reading of the USB spec - however
       
   815 						// it is not explicitly clear, so play it safe.
       
   816 	default:
       
   817 		return EFalse;
       
   818 		}
       
   819 	}
       
   820 
       
   821 /**
       
   822 @internalComponent
       
   823 */
       
   824 /*virtual*/ TBool TUsbInterfaceAssociationDescriptor::IsPeer(TUsbGenericDescriptor& aPotentialPeer)
       
   825 	{
       
   826 	switch(aPotentialPeer.ibDescriptorType)
       
   827 		{
       
   828 	case EInterfaceAssociation:
       
   829 		return ETrue;
       
   830 	case EInterface:
       
   831 		// Only interfaces are peers of IADs.
       
   832 			{
       
   833 			TUsbInterfaceDescriptor* intDesc = TUsbInterfaceDescriptor::Cast(&aPotentialPeer);
       
   834 			if(intDesc)
       
   835 				{
       
   836 				TInt intNum = intDesc->InterfaceNumber();
       
   837 				intNum -= FirstInterface();
       
   838 				if(intNum < 0 || intNum >= InterfaceCount())
       
   839 					{
       
   840 					// The interface number is outside the IAD region.
       
   841 					return ETrue;
       
   842 					}
       
   843 				}
       
   844 			return EFalse;
       
   845 			}
       
   846 	default:
       
   847 		return EFalse;
       
   848 		}
       
   849 	}
       
   850 	
       
   851 /*virtual*/ TBool TUsbInterfaceAssociationDescriptor::IsChild(TUsbGenericDescriptor& aPotentialChild)
       
   852 	{
       
   853 	switch(aPotentialChild.ibDescriptorType)
       
   854 		{
       
   855 	case EInterface:
       
   856 		// Only interfaces are children of IADs. And only if they are special.
       
   857 			{
       
   858 			TUsbInterfaceDescriptor* intDesc = TUsbInterfaceDescriptor::Cast(&aPotentialChild);
       
   859 			if(intDesc)
       
   860 				{
       
   861 				TInt intNum = intDesc->InterfaceNumber();
       
   862 				intNum -= FirstInterface();
       
   863 				if(intNum >= 0 && intNum < InterfaceCount())
       
   864 					{
       
   865 					// The interface number is within the IAD region required.
       
   866 					return ETrue;
       
   867 					}
       
   868 				}
       
   869 			return EFalse;
       
   870 			}
       
   871 	default:
       
   872 		return EFalse;
       
   873 		}
       
   874 	}
       
   875 
       
   876 
       
   877 // -------------------------
       
   878 // TUsbInterfaceDescriptor
       
   879 // See section 9.6.5 of the USB 2.0 specification.
       
   880 // -------------------------
       
   881 
       
   882 EXPORT_C TUsbInterfaceDescriptor::TUsbInterfaceDescriptor()
       
   883 	{
       
   884 	}
       
   885 
       
   886 EXPORT_C /*static*/ TUsbInterfaceDescriptor* TUsbInterfaceDescriptor::Cast(TUsbGenericDescriptor* aOriginal)
       
   887 	{
       
   888 	TUsbInterfaceDescriptor* ret = NULL;
       
   889 	// Only cast if correctly indentified as interface descriptor
       
   890 	if(	aOriginal &&
       
   891 		aOriginal->ibDescriptorType == EInterface &&
       
   892 		aOriginal->ibLength == TUsbInterfaceDescriptor::KSizeInOctets &&
       
   893 		aOriginal->iRecognisedAndParsed == ERecognised)
       
   894 		{
       
   895 		ret = static_cast<TUsbInterfaceDescriptor*>(aOriginal);
       
   896 		}
       
   897 	return ret;
       
   898 	}
       
   899 
       
   900 EXPORT_C TUint8 TUsbInterfaceDescriptor::InterfaceNumber() const
       
   901 	{
       
   902 	return ParseTUint8(iBlob, EbInterfaceNumber);
       
   903 	}
       
   904 
       
   905 EXPORT_C TUint8 TUsbInterfaceDescriptor::AlternateSetting() const
       
   906 	{
       
   907 	return ParseTUint8(iBlob, EbAlternateSetting);
       
   908 	}
       
   909 
       
   910 EXPORT_C TUint8 TUsbInterfaceDescriptor::NumEndpoints() const
       
   911 	{
       
   912 	return ParseTUint8(iBlob, EbNumEndpoints);
       
   913 	}
       
   914 
       
   915 EXPORT_C TUint8 TUsbInterfaceDescriptor::InterfaceClass() const
       
   916 	{
       
   917 	return ParseTUint8(iBlob, EbInterfaceClass);
       
   918 	}
       
   919 
       
   920 EXPORT_C TUint8 TUsbInterfaceDescriptor::InterfaceSubClass() const
       
   921 	{
       
   922 	return ParseTUint8(iBlob, EbInterfaceSubClass);
       
   923 	}
       
   924 
       
   925 EXPORT_C TUint8 TUsbInterfaceDescriptor::InterfaceProtocol() const
       
   926 	{
       
   927 	return ParseTUint8(iBlob, EbInterfaceProtocol);
       
   928 	}
       
   929 
       
   930 EXPORT_C TUint8 TUsbInterfaceDescriptor::Interface() const
       
   931 	{
       
   932 	return ParseTUint8(iBlob, EiInterface);
       
   933 	}
       
   934 	
       
   935 /**
       
   936 The parsing routine for interface descriptors.
       
   937 
       
   938 @internalComponent
       
   939 */
       
   940 /*static*/ TUsbInterfaceDescriptor* TUsbInterfaceDescriptor::ParseL(TPtrC8& aUsbDes, TUsbGenericDescriptor* /*aPreviousDesc*/)
       
   941 	{
       
   942 	TUsbInterfaceDescriptor* intDes = NULL;
       
   943 
       
   944 	const TInt KMinInterfaceDesDecisionLength = 2;
       
   945 	if(	aUsbDes.Length() >= KMinInterfaceDesDecisionLength &&
       
   946 		aUsbDes[KbDescriptorTypeOffset] == EInterface &&
       
   947 		aUsbDes[KbLengthOffset] == TUsbInterfaceDescriptor::KSizeInOctets)
       
   948 		{
       
   949 		// Robustness check - check the length field is valid, and that we have enough data.
       
   950 		if(aUsbDes.Length() < TUsbInterfaceDescriptor::KSizeInOctets)
       
   951 			{
       
   952 			User::Leave(KErrCorrupt);
       
   953 			}
       
   954 
       
   955 		// Looks ok to be an interface descriptor.
       
   956 		intDes = new(ELeave) TUsbInterfaceDescriptor;
       
   957 		// Set the standard fields
       
   958 		intDes->ibLength = TUsbInterfaceDescriptor::KSizeInOctets;
       
   959 		intDes->ibDescriptorType = EInterface;
       
   960 		// Set the blob appropriately
       
   961 		intDes->iBlob.Set(aUsbDes.Left(TUsbInterfaceDescriptor::KSizeInOctets));
       
   962 
       
   963 		intDes->iRecognisedAndParsed = ERecognised;
       
   964 
       
   965 		// Update the data-left-to-parse Symbian descriptor
       
   966 		aUsbDes.Set(aUsbDes.Mid(TUsbInterfaceDescriptor::KSizeInOctets));
       
   967 		}
       
   968 
       
   969 	return intDes;
       
   970 	}
       
   971 
       
   972 /**
       
   973 @internalComponent
       
   974 */
       
   975 /*virtual*/ TBool TUsbInterfaceDescriptor::IsParent(TUsbGenericDescriptor& aPotentialParent)
       
   976 	{
       
   977 	switch(aPotentialParent.ibDescriptorType)
       
   978 		{
       
   979 	case EConfiguration:
       
   980 		return ETrue;
       
   981 	case EOtherSpeedConfiguration:
       
   982 		return ETrue;	// I think this should be EFalse by my reading of the USB spec - however
       
   983 						// it is not explicitly clear, so play it safe.
       
   984 	// case EInterfaceAssociation:
       
   985 	// 		We let the IAD descriptor handle the logic of how we bind to it.
       
   986 	default:
       
   987 		return EFalse;
       
   988 		}
       
   989 	}
       
   990 
       
   991 /**
       
   992 @internalComponent
       
   993 */
       
   994 /*virtual*/ TBool TUsbInterfaceDescriptor::IsPeer(TUsbGenericDescriptor& aPotentialPeer)
       
   995 	{
       
   996 	switch(aPotentialPeer.ibDescriptorType)
       
   997 		{
       
   998 	//case EInterfaceAssociation:
       
   999 	//		We let the IAD descriptor handle the logic of how we bind to it.
       
  1000 	case EInterface:
       
  1001 		// If another interface descriptor then it is a peer not child.
       
  1002 		return ETrue;
       
  1003 	default:
       
  1004 		// Any other descriptors are ignored.
       
  1005 		return EFalse;
       
  1006 		}
       
  1007 	}
       
  1008 
       
  1009 
       
  1010 // ------------------------
       
  1011 // TUsbEndpointDescriptor
       
  1012 // See section 9.6.6 of the USB 2.0 specification.
       
  1013 // ------------------------
       
  1014 
       
  1015 EXPORT_C TUsbEndpointDescriptor::TUsbEndpointDescriptor()
       
  1016 	{
       
  1017 	}
       
  1018 	
       
  1019 EXPORT_C /*static*/ TUsbEndpointDescriptor* TUsbEndpointDescriptor::Cast(TUsbGenericDescriptor* aOriginal)
       
  1020 	{
       
  1021 	TUsbEndpointDescriptor* ret = NULL;
       
  1022 	// Only cast if correctly indentified as endpoint descriptor
       
  1023 	if(	aOriginal &&
       
  1024 		aOriginal->ibDescriptorType == EEndpoint &&
       
  1025 		aOriginal->ibLength == TUsbEndpointDescriptor::KSizeInOctets &&
       
  1026 		aOriginal->iRecognisedAndParsed == ERecognised)
       
  1027 		{
       
  1028 		ret = static_cast<TUsbEndpointDescriptor*>(aOriginal);
       
  1029 		}
       
  1030 	return ret;
       
  1031 	}
       
  1032 
       
  1033 EXPORT_C TUint8 TUsbEndpointDescriptor::EndpointAddress() const
       
  1034 	{
       
  1035 	return ParseTUint8(iBlob, EbEndpointAddress);
       
  1036 	}
       
  1037 
       
  1038 EXPORT_C TUint8 TUsbEndpointDescriptor::Attributes() const
       
  1039 	{
       
  1040 	return ParseTUint8(iBlob, EbmAttributes);
       
  1041 	}
       
  1042 
       
  1043 EXPORT_C TUint16 TUsbEndpointDescriptor::MaxPacketSize() const
       
  1044 	{
       
  1045 	return ParseTUint16(iBlob, EwMaxPacketSize);
       
  1046 	}
       
  1047 
       
  1048 EXPORT_C TUint8 TUsbEndpointDescriptor::Interval() const
       
  1049 	{
       
  1050 	return ParseTUint8(iBlob, EbInterval);
       
  1051 	}
       
  1052 	
       
  1053 /**
       
  1054 The parsing routine for endpoint descriptors.
       
  1055 
       
  1056 @internalComponent
       
  1057 */
       
  1058 /*static*/ TUsbEndpointDescriptor* TUsbEndpointDescriptor::ParseL(TPtrC8& aUsbDes, TUsbGenericDescriptor* /*aPreviousDesc*/)
       
  1059 	{
       
  1060 	TUsbEndpointDescriptor* endDes = NULL;
       
  1061 
       
  1062 	const TInt KMinEndpointDesDecisionLength = 2;
       
  1063 	if(	aUsbDes.Length() >= KMinEndpointDesDecisionLength &&
       
  1064 		aUsbDes[KbDescriptorTypeOffset] == EEndpoint &&
       
  1065 		aUsbDes[KbLengthOffset] == TUsbEndpointDescriptor::KSizeInOctets)
       
  1066 		{
       
  1067 		// Robustness check - check the length field is valid, and that we have enough data.
       
  1068 		if(aUsbDes.Length() < TUsbEndpointDescriptor::KSizeInOctets)
       
  1069 			{
       
  1070 			User::Leave(KErrCorrupt);
       
  1071 			}
       
  1072 
       
  1073 		// Looks ok to be an endpoint descriptor.
       
  1074 		endDes = new(ELeave) TUsbEndpointDescriptor;
       
  1075 		// Set the standard fields
       
  1076 		endDes->ibLength = TUsbEndpointDescriptor::KSizeInOctets;
       
  1077 		endDes->ibDescriptorType = EEndpoint;
       
  1078 		// Set the blob appropriately
       
  1079 		endDes->iBlob.Set(aUsbDes.Left(TUsbEndpointDescriptor::KSizeInOctets));
       
  1080 
       
  1081 		endDes->iRecognisedAndParsed = ERecognised;
       
  1082 
       
  1083 		// Update the data-left-to-parse Symbian descriptor
       
  1084 		aUsbDes.Set(aUsbDes.Mid(TUsbEndpointDescriptor::KSizeInOctets));
       
  1085 		}
       
  1086 
       
  1087 	return endDes;
       
  1088 	}
       
  1089 
       
  1090 /**
       
  1091 @internalComponent
       
  1092 */
       
  1093 /*virtual*/ TBool TUsbEndpointDescriptor::IsParent(TUsbGenericDescriptor& aPotentialParent)
       
  1094 	{
       
  1095 	switch(aPotentialParent.ibDescriptorType)
       
  1096 		{
       
  1097 	case EInterface:
       
  1098 		return ETrue;
       
  1099 	default:
       
  1100 		return EFalse;
       
  1101 		}
       
  1102 	}
       
  1103 
       
  1104 /**
       
  1105 @internalComponent
       
  1106 */
       
  1107 /*virtual*/ TBool TUsbEndpointDescriptor::IsPeer(TUsbGenericDescriptor& aPotentialPeer)
       
  1108 	{
       
  1109 	switch(aPotentialPeer.ibDescriptorType)
       
  1110 		{
       
  1111 	case EEndpoint:
       
  1112 		return ETrue;
       
  1113 	default:
       
  1114 		return EFalse;
       
  1115 		}
       
  1116 	}
       
  1117 
       
  1118 // ------------------------
       
  1119 // TUsbOTGDescriptor
       
  1120 // See section 6.4 of the USB 2.0 On-The-Go Supplement Revision 1.3
       
  1121 // ------------------------
       
  1122 
       
  1123 EXPORT_C TUsbOTGDescriptor::TUsbOTGDescriptor()
       
  1124 	{
       
  1125 	}
       
  1126 	
       
  1127 EXPORT_C /*static*/ TUsbOTGDescriptor* TUsbOTGDescriptor::Cast(TUsbGenericDescriptor* aOriginal)
       
  1128 	{
       
  1129 	TUsbOTGDescriptor* ret = NULL;
       
  1130 	// Only cast if correctly indentified as otg descriptor
       
  1131 	if(	aOriginal &&
       
  1132 		aOriginal->ibDescriptorType == EOTG &&
       
  1133 		aOriginal->ibLength == TUsbOTGDescriptor::KSizeInOctets &&
       
  1134 		aOriginal->iRecognisedAndParsed == ERecognised)
       
  1135 		{
       
  1136 		ret = static_cast<TUsbOTGDescriptor*>(aOriginal);
       
  1137 		}
       
  1138 	return ret;
       
  1139 	}
       
  1140 
       
  1141 EXPORT_C TUint8 TUsbOTGDescriptor::Attributes() const
       
  1142 	{
       
  1143 	return ParseTUint8(iBlob, EbmAttributes);
       
  1144 	}
       
  1145 
       
  1146 EXPORT_C TBool TUsbOTGDescriptor::HNPSupported() const
       
  1147     {
       
  1148     return (ParseTUint8(iBlob, EbmAttributes) & 0x02) == 0x02;
       
  1149     }
       
  1150 
       
  1151 EXPORT_C TBool TUsbOTGDescriptor::SRPSupported() const
       
  1152     {
       
  1153     // Note: an illegal device (see 6.4.2 of the OTG specification) could
       
  1154     // incorrectly return False for SRP and True for HNP
       
  1155     // However this function just extracts the bit rather than attempting to
       
  1156     // fix up a broken device.  Devices broken in this way wouldn't be expected on
       
  1157     // the TPL.
       
  1158     return (ParseTUint8(iBlob, EbmAttributes) & 0x01) == 0x01;
       
  1159     }
       
  1160 	
       
  1161 /**
       
  1162 The parsing routine for OTG descriptors.
       
  1163 
       
  1164 @internalComponent
       
  1165 */
       
  1166 /*static*/ TUsbOTGDescriptor* TUsbOTGDescriptor::ParseL(TPtrC8& aUsbDes, TUsbGenericDescriptor* /*aPreviousDesc*/)
       
  1167 	{
       
  1168 	TUsbOTGDescriptor* endDes = NULL;
       
  1169 
       
  1170 	const TInt KMinOTGDesDecisionLength = 2;
       
  1171 	if(	aUsbDes.Length() >= KMinOTGDesDecisionLength &&
       
  1172 		aUsbDes[KbDescriptorTypeOffset] == EOTG &&
       
  1173 		aUsbDes[KbLengthOffset] == TUsbOTGDescriptor::KSizeInOctets)
       
  1174 		{
       
  1175 		// Robustness check - check the length field is valid, and that we have enough data.
       
  1176 		if(aUsbDes.Length() < TUsbOTGDescriptor::KSizeInOctets)
       
  1177 			{
       
  1178 			User::Leave(KErrCorrupt);
       
  1179 			}
       
  1180 
       
  1181 		// Looks ok to be an OTG descriptor.
       
  1182 		endDes = new(ELeave) TUsbOTGDescriptor;
       
  1183 		// Set the standard fields
       
  1184 		endDes->ibLength = TUsbOTGDescriptor::KSizeInOctets;
       
  1185 		endDes->ibDescriptorType = EOTG;
       
  1186 		// Set the blob appropriately
       
  1187 		endDes->iBlob.Set(aUsbDes.Left(TUsbOTGDescriptor::KSizeInOctets));
       
  1188 
       
  1189 		// Null the pointers
       
  1190 		endDes->iFirstChild = NULL;
       
  1191 		endDes->iNextPeer = NULL;
       
  1192 		endDes->iParent = NULL;
       
  1193 		
       
  1194 		endDes->iRecognisedAndParsed = ERecognised;
       
  1195 
       
  1196 		// Update the data-left-to-parse Symbian descriptor
       
  1197 		aUsbDes.Set(aUsbDes.Mid(TUsbOTGDescriptor::KSizeInOctets));
       
  1198 		}
       
  1199 
       
  1200 	return endDes;
       
  1201 	}
       
  1202 
       
  1203 /**
       
  1204 @internalComponent
       
  1205 */
       
  1206 /*virtual*/ TBool TUsbOTGDescriptor::IsParent(TUsbGenericDescriptor& aPotentialParent)
       
  1207 	{
       
  1208 	switch(aPotentialParent.ibDescriptorType)
       
  1209 		{
       
  1210 	case EConfiguration:    // we are part of a configuration descriptor, or standalone
       
  1211 		return ETrue;
       
  1212 	default:
       
  1213 		return EFalse;
       
  1214 		}
       
  1215 	}
       
  1216 
       
  1217 /**
       
  1218 @internalComponent
       
  1219 */
       
  1220 /*virtual*/ TBool TUsbOTGDescriptor::IsPeer(TUsbGenericDescriptor& aPotentialPeer)
       
  1221 	{
       
  1222     switch(aPotentialPeer.ibDescriptorType)
       
  1223 		{
       
  1224 	//case EInterfaceAssociation:
       
  1225 	//		We let the IAD descriptor handle the logic of how we bind to it.
       
  1226 	case EInterface:
       
  1227 		// If another interface descriptor then it is a peer not child.
       
  1228 		return ETrue;
       
  1229 	default:
       
  1230 		// Any other descriptors are ignored.
       
  1231 		return EFalse;
       
  1232 		}
       
  1233 	}
       
  1234 
       
  1235 
       
  1236 // ----------------------
       
  1237 // TUsbStringDescriptor
       
  1238 // See section 9.6.7 of the USB 2.0 specification.
       
  1239 // ----------------------
       
  1240 
       
  1241 // The length of the header in a string descriptor (i.e. the same as every other standard USB descriptor).
       
  1242 static const TInt KStringDescriptorHeaderFieldLength = 2;
       
  1243 
       
  1244 EXPORT_C TUsbStringDescriptor::TUsbStringDescriptor()
       
  1245 	{
       
  1246 	}
       
  1247 	
       
  1248 EXPORT_C /*static*/ TUsbStringDescriptor* TUsbStringDescriptor::Cast(TUsbGenericDescriptor* aOriginal)
       
  1249 	{
       
  1250 	TUsbStringDescriptor* ret = NULL;
       
  1251 	// Only cast if correctly indentified as string descriptor
       
  1252 	if(	aOriginal &&
       
  1253 		aOriginal->ibDescriptorType == EString &&
       
  1254 		aOriginal->ibLength >= KStringDescriptorHeaderFieldLength &&
       
  1255 		aOriginal->iRecognisedAndParsed == ERecognised)
       
  1256 		{
       
  1257 		ret = static_cast<TUsbStringDescriptor*>(aOriginal);
       
  1258 		}
       
  1259 	return ret;
       
  1260 	}
       
  1261 
       
  1262 /**
       
  1263 For string descriptor zero, this function allows a means to iterate through the list of supported languages
       
  1264 for strings on this device.
       
  1265 
       
  1266 @param aIndex Index into language ID table.
       
  1267 @return The language ID at the requested index, or KErrNotFound if the end of the list has been reached.
       
  1268 Note that the language IDs are unsigned 16-bit numbers, while the return from this function is signed 32-bit.
       
  1269 */
       
  1270 EXPORT_C TInt TUsbStringDescriptor::GetLangId(TInt aIndex) const
       
  1271 	{
       
  1272 	__ASSERT_ALWAYS(aIndex >= 0, UsbDescPanic(UsbdiPanics::EUsbDescNegativeIndexToLangId));
       
  1273 	const TUint8 KSizeOfLangIdField = 2;
       
  1274 
       
  1275 	TInt offset = KStringDescriptorHeaderFieldLength + KSizeOfLangIdField * aIndex;
       
  1276 	if(offset >= ibLength)
       
  1277 		{
       
  1278 		return KErrNotFound;
       
  1279 		}
       
  1280 	return ParseTUint16(iBlob, offset);
       
  1281 	}
       
  1282 
       
  1283 /**
       
  1284 Writes the string data into a Symbian descriptor of sufficient size.
       
  1285 
       
  1286 @param aString The Symbian descriptor that will have the string data written into it.
       
  1287 */
       
  1288 EXPORT_C void TUsbStringDescriptor::StringData(TDes16& aString) const
       
  1289 	{
       
  1290 	const TUint8 KUnicodeCharacterWidth = 2;
       
  1291 	aString.Zero();
       
  1292 
       
  1293 	TInt index = KStringDescriptorHeaderFieldLength;
       
  1294 	while(index+KUnicodeCharacterWidth <= ibLength)
       
  1295 		{
       
  1296 		aString.Append(ParseTUint16(iBlob, index));
       
  1297 		index += KUnicodeCharacterWidth;
       
  1298 		}
       
  1299 	}
       
  1300 
       
  1301 
       
  1302 /*static*/ TUsbStringDescriptor* TUsbStringDescriptor::ParseL(TPtrC8& aUsbDes, TUsbGenericDescriptor* /*aPreviousDesc*/)
       
  1303 	{
       
  1304 	TUsbStringDescriptor* stringDes = NULL;
       
  1305 
       
  1306 	if(	aUsbDes.Length() >= KStringDescriptorHeaderFieldLength &&
       
  1307 		aUsbDes[KbDescriptorTypeOffset] == EString)
       
  1308 		{
       
  1309 		TUint8 stringDesLen = aUsbDes[KbLengthOffset];
       
  1310 
       
  1311 		// Robustness check - check the length field is valid
       
  1312 		if(aUsbDes.Length() < stringDesLen || stringDesLen < KStringDescriptorHeaderFieldLength)
       
  1313 			{
       
  1314 			User::Leave(KErrCorrupt);
       
  1315 			}
       
  1316 		// Robustness check - check the length is a multiple of two.
       
  1317 		if(stringDesLen % 2 != 0)
       
  1318 			{
       
  1319 			User::Leave(KErrCorrupt);
       
  1320 			}
       
  1321 
       
  1322 		// Looks ok to be a string descriptor.
       
  1323 		stringDes = new(ELeave) TUsbStringDescriptor;
       
  1324 		// Set the standard fields
       
  1325 		stringDes->ibLength = stringDesLen;
       
  1326 		stringDes->ibDescriptorType = EString;
       
  1327 		// Set the blob appropriately
       
  1328 		stringDes->iBlob.Set(aUsbDes.Left(stringDesLen));
       
  1329 
       
  1330 		stringDes->iRecognisedAndParsed = ERecognised;
       
  1331 
       
  1332 		// Update the data-left-to-parse Symbian descriptor
       
  1333 		aUsbDes.Set(aUsbDes.Mid(stringDesLen));
       
  1334 		}
       
  1335 
       
  1336 	return stringDes;
       
  1337 	}
       
  1338 
       
  1339 /**
       
  1340 @internalComponent
       
  1341 */
       
  1342 /*virtual*/ TBool TUsbStringDescriptor::IsParent(TUsbGenericDescriptor& /*aPotentialParent*/)
       
  1343 	{
       
  1344 	// String descriptors have no parents - they are standalone.
       
  1345 	return EFalse;
       
  1346 	}
       
  1347 
       
  1348 /**
       
  1349 @internalComponent
       
  1350 */
       
  1351 /*virtual*/ TBool TUsbStringDescriptor::IsPeer(TUsbGenericDescriptor& /*aPotentialPeer*/)
       
  1352 	{
       
  1353 	// String descriptors have no peers - they are standalone.
       
  1354 	return EFalse;
       
  1355 	}
       
  1356