DecodeBOSDescriptor.m [plain text]
/*
* Copyright © 2012 Apple Inc. All rights reserved.
*
* @APPLE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
* compliance with the License. Please obtain a copy of the License at
* http://www.opensource.apple.com/apsl/ and read it before using this
* file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
* INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
* Please see the License for the specific language governing rights and
* limitations under the License.
*
* @APPLE_LICENSE_HEADER_END@
*/
#import "DescriptorDecoder.h"
#import "DecodeBOSDescriptor.h"
@implementation DecodeBOSDescriptor
+ (void)decodeBytes:(IOUSBBOSDescriptor *)bosDescriptor forDevice:(BusProbeDevice *)thisDevice deviceInterface:(IOUSBDeviceRef)deviceIntf {
char buf[128];
UInt8 numCaps = bosDescriptor->bNumDeviceCaps;
Byte *bosBuf;
Byte *p;
IOReturn ret = kIOReturnSuccess;
int i;
[thisDevice addProperty:"BOS Descriptor" withValue:"" atDepth:BOS_DESCRIPTOR_LEVEL-1];
if ( bosDescriptor->wTotalLength != 0 )
{
// We have device capabilities, so let's get the full descriptor
Swap16(&bosDescriptor->wTotalLength);
bosBuf = malloc(bosDescriptor->wTotalLength*sizeof(Byte));
ret = GetDescriptor(deviceIntf, kUSBBOSDescriptor, 0, bosBuf, bosDescriptor->wTotalLength, nil);
if ( ret != kIOReturnSuccess )
{
fprintf(stderr,"Failed to get full BOS descriptor: 0x return;
}
sprintf(buf, " [thisDevice addProperty:"Length (and contents):" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL];
[DescriptorDecoder dumpRawBOSDescriptor:(IOUSBBOSDescriptor *)bosBuf forDevice:thisDevice atDepth:BOS_DESCRIPTOR_LEVEL+1];
sprintf(buf, " [thisDevice addProperty:"Number of Capability Descriptors:" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL];
// point to the start of the caps
//
p = &bosBuf[5];
for ( i = 0 ; i < numCaps; i++)
{
IOUSBDeviceCapabilityDescriptorHeader *header = (IOUSBDeviceCapabilityDescriptorHeader *)p;
sprintf(buf, "
switch (header->bDevCapabilityType)
{
case kUSBDeviceCapabilityWirelessUSB:
{
[thisDevice addProperty:"Wireless USB:" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL+1];
}
break;
case kUSBDeviceCapabilityUSB20Extension:
{
IOUSBDeviceCapabilityUSB2Extension * usb2Cap = (IOUSBDeviceCapabilityUSB2Extension*)p;
UInt32 attributes = USBToHostLong(usb2Cap->bmAttributes);
[thisDevice addProperty:"USB 2.0 Extension:" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL+1];
sprintf(buf, "0x [thisDevice addProperty:"bmAttributes:" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL+2];
if ( attributes &( 1 << kUSB20ExtensionLPMSupported) )
[thisDevice addProperty:"" withValue:"Bit 1: Link Power Management supported" atDepth:BOS_DESCRIPTOR_LEVEL+2];
}
break;
case kUSBDeviceCapabilitySuperSpeedUSB:
{
IOUSBDeviceCapabilitySuperSpeedUSB * sspeedCap = (IOUSBDeviceCapabilitySuperSpeedUSB*)p;
UInt8 attributes = (sspeedCap->bmAttributes);
UInt16 speedsSupported = USBToHostWord(sspeedCap->wSpeedsSupported);
UInt8 speedFunctionalitySupport = sspeedCap->bFunctionalitySupport;
UInt8 u1ExitLatency = sspeedCap->bU1DevExitLat;
UInt16 u2ExitLatency = USBToHostWord(sspeedCap->wU2DevExitLat);
[thisDevice addProperty:"SuperSpeed USB Device:" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL+1];
sprintf(buf, "0x [thisDevice addProperty:"bmAttributes:" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL+2];
if ( attributes &( 1 << kUSBSuperSpeedLTMCapable) )
[thisDevice addProperty:"" withValue:"Bit 1: Latency Tolerance Messages supported" atDepth:BOS_DESCRIPTOR_LEVEL+2];
sprintf(buf, "0x [thisDevice addProperty:"wSpeedsSupported:" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL+2];
if ( speedsSupported & (1<<kUSBSuperSpeedSupportsLS) )
[thisDevice addProperty:"" withValue:"Bit 0: Low Speed supported" atDepth:BOS_DESCRIPTOR_LEVEL+2];
if ( speedsSupported & (1<<kUSBSuperSpeedSupportsFS) )
[thisDevice addProperty:"" withValue:"Bit 1: Full Speed supported" atDepth:BOS_DESCRIPTOR_LEVEL+2];
if ( speedsSupported & (1<<kUSBSuperSpeedSupportsHS) )
[thisDevice addProperty:"" withValue:"Bit 2: High Speed supported" atDepth:BOS_DESCRIPTOR_LEVEL+2];
if ( speedsSupported & (1<<kUSBSuperSpeedSupportsSS) )
[thisDevice addProperty:"" withValue:"Bit 3: Super Speed (5Gbps) supported" atDepth:BOS_DESCRIPTOR_LEVEL+2];
if ( speedFunctionalitySupport & (1<<kUSBSuperSpeedSupportsLS) )
sprintf(buf, "0x if ( speedFunctionalitySupport & (1<<kUSBSuperSpeedSupportsFS) )
sprintf(buf, "0x if ( speedFunctionalitySupport & (1<<kUSBSuperSpeedSupportsHS) )
sprintf(buf, "0x if ( speedFunctionalitySupport & (1<<kUSBSuperSpeedSupportsSS) )
sprintf(buf, "0x [thisDevice addProperty:"bFunctionalitySupport:" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL+2];
if (u1ExitLatency == 0 )
{
[thisDevice addProperty:"bU1ExitLat:" withValue:"Zero" atDepth:BOS_DESCRIPTOR_LEVEL+2];
}
else if (u1ExitLatency < 0xB )
{
sprintf(buf, "Less than [thisDevice addProperty:"bU1ExitLat:" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL+2];
}
else
{
sprintf(buf, "Illegal value of [thisDevice addProperty:"wU2ExitLat:" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL+2];
}
if (u2ExitLatency == 0 )
{
[thisDevice addProperty:"wU2ExitLat:" withValue:"Zero" atDepth:BOS_DESCRIPTOR_LEVEL+2];
}
else if (u2ExitLatency < 0x800 )
{
sprintf(buf, "Less than [thisDevice addProperty:"wU2ExitLat:" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL+2];
}
else
{
sprintf(buf, "Illegal value of [thisDevice addProperty:"wU2ExitLat:" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL+2];
}
}
break;
case kUSBDeviceCapabilityContainerID:
{
uint64_t uuidLO;
uint32_t data1;
uint16_t data2, data3;
IOUSBDeviceCapabilityContainerID * container = (IOUSBDeviceCapabilityContainerID*)p;
data1 = USBToHostLong(* (uint32_t *) &container->containerID[0]);
data2 = USBToHostWord(* (uint16_t *) &container->containerID[4]);
data3 = USBToHostWord(* (uint16_t *) &container->containerID[6]);
uuidLO = OSSwapBigToHostInt64(* (uint64_t *) &container->containerID[8]);
sprintf((char *)buf, " (uint32_t) ( (uuidLO & 0xffff000000000000ULL)>>48), (uuidLO & 0x0000FFFFFFFFFFFFULL) );
[thisDevice addProperty:"ContainerID:" withValue:buf atDepth:BOS_DESCRIPTOR_LEVEL+1];
}
break;
}
// Look at the next cap
p = p + header->bLength;
}
}
// [thisDevice addNumberProperty:"Number of Ports:" value: hubDescriptor.numPorts size:sizeof(hubDescriptor.numPorts) atDepth:HUB_DESCRIPTOR_LEVEL usingStyle:kHexOutputStyle];
}
@end