Mercurial > hg > ucis.core
diff USBLib/Descriptor/UsbDescriptor.cs @ 21:dcfec2be27c9
Added USBLib
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Mon, 15 Apr 2013 01:04:59 +0200 |
parents | |
children | 5b14fed54a89 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/USBLib/Descriptor/UsbDescriptor.cs Mon Apr 15 01:04:59 2013 +0200 @@ -0,0 +1,194 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Runtime.InteropServices; +using UCIS.USBLib.Communication; + +namespace UCIS.USBLib.Descriptor { + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct UsbDescriptor { + byte bmLength; + byte bType; + public Byte Length { get { return bmLength; } } + public UsbDescriptorType Type { get { return (UsbDescriptorType)bType; } } + internal static short FromLittleEndian(short value) { + if (BitConverter.IsLittleEndian) return value; + return (short)(((value & 0xFF) << 8) | ((value >> 8) & 0xFF)); + } + public unsafe static UsbDescriptor FromByteArray(Byte[] buffer, int offset, int length) { + if (length < Marshal.SizeOf(typeof(UsbDescriptor))) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); + if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); + fixed (Byte* ptr = buffer) return *(UsbDescriptor*)(ptr + offset); + } + } + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct UsbStringDescriptor { + public static String GetString(Byte[] buffer, int offset, int length) { + if (length < 2) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); + if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); + if (buffer[offset + 1] != (Byte)UsbDescriptorType.String) throw new InvalidOperationException("The descriptor is not a string descriptor"); + int slen = buffer[offset]; + if (slen > length) throw new InvalidOperationException("The string has been truncated"); + return Encoding.Unicode.GetString(buffer, offset + 2, slen - 2); + } + } + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct UsbDeviceDescriptor { + byte bmLength; + byte bType; + short bcdUSB; + byte bDeviceClass; + byte bDeviceSubClass; + byte bDeviceProtocol; + byte bMaxControlPacketSize; + short idVendor; + short idProduct; + short bcdDevice; + byte iManufacturer; + byte iProduct; + byte iSerialNumber; + byte numConfigurations; + public Byte Length { get { return bmLength; } } + public UsbDescriptorType Type { get { return (UsbDescriptorType)bType; }} + public short USBVersion { get { return UsbDescriptor.FromLittleEndian(bcdUSB); } } + public Byte DeviceClass { get { return bDeviceClass; } } + public Byte DeviceSubClass { get { return bDeviceSubClass; } } + public Byte DeviceProtocol { get { return bDeviceProtocol; } } + public short DeviceVersion { get { return UsbDescriptor.FromLittleEndian(bcdDevice); } } + public Byte MaxControlPacketSize { get { return bMaxControlPacketSize; } } + public short VendorID { get { return UsbDescriptor.FromLittleEndian(idVendor); } } + public short ProductID { get { return UsbDescriptor.FromLittleEndian(idProduct); } } + public Byte ManufacturerStringID { get { return iManufacturer; } } + public Byte ProductStringID { get { return iProduct; } } + public Byte SerialNumberStringID { get { return iSerialNumber; } } + public Byte NumConfigurations { get { return numConfigurations; } } + public unsafe static UsbDeviceDescriptor FromByteArray(Byte[] buffer, int offset, int length) { + if (length < Size) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); + if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); + fixed (Byte* ptr = buffer) return *(UsbDeviceDescriptor*)(ptr + offset); + } + public static unsafe int Size { get { return sizeof(UsbDeviceDescriptor); } } + } + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct UsbConfigurationDescriptor { + byte bmLength; + byte bType; + short wTotalLength; + byte bNumInterfaces; + byte bConfigurationValue; + byte bConfigurationStringID; + byte bmAttributes; + byte bMaxPower; + public Byte Length { get { return bmLength; } } + public UsbDescriptorType Type { get { return (UsbDescriptorType)bType; } } + public short TotalLength { get { return UsbDescriptor.FromLittleEndian(wTotalLength); } } + public Byte NumInterfaces { get { return bNumInterfaces; } } + public Byte ConfigurationValue { get { return bConfigurationValue; } } + public Byte ConfigurationStringID { get { return bConfigurationStringID; } } + public Boolean SelfPowered { get { return 0 != (bmAttributes & (1 << 6)); } } + public Boolean RemoteWakeup { get { return 0 != (bmAttributes & (1 << 5)); } } + public int MaxPowerMA { get { return bMaxPower * 2; } } + public unsafe static UsbConfigurationDescriptor FromByteArray(Byte[] buffer, int offset, int length) { + if (length < Size) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); + if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); + fixed (Byte* ptr = buffer) return *(UsbConfigurationDescriptor*)(ptr + offset); + } + public static unsafe int Size { get { return sizeof(UsbConfigurationDescriptor); } } + } + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct UsbInterfaceDescriptor { + byte bmLength; + byte bType; + byte bInterfaceNumber; + byte bAlternateSetting; + byte bNumEndpoints; + byte bInterfaceClass; + byte bInterfaceSubClass; + byte bInterfaceProtocol; + byte bInterfaceStringID; + public Byte Length { get { return bmLength; } } + public UsbDescriptorType Type { get { return (UsbDescriptorType)bType; } } + public Byte InterfaceNumber { get { return bInterfaceNumber; } } + public Byte AlternateSetting { get { return bAlternateSetting; } } + public Byte NumEndpoints { get { return bNumEndpoints; } } + public Byte InterfaceClass { get { return bInterfaceClass; } } + public Byte InterfaceSubClass { get { return bInterfaceSubClass; } } + public Byte InterfaceProtocol { get { return bInterfaceProtocol; } } + public Byte InterfaceStringID { get { return bInterfaceStringID; } } + public unsafe static UsbInterfaceDescriptor FromByteArray(Byte[] buffer, int offset, int length) { + if (length < Size) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); + if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); + fixed (Byte* ptr = buffer) return *(UsbInterfaceDescriptor*)(ptr + offset); + } + public static unsafe int Size { get { return sizeof(UsbInterfaceDescriptor); } } + } + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct UsbEndpointDescriptor { + byte bmLength; + byte bType; + byte bEndpointAddress; + Byte bmAttributes; + short wMaxPacketSize; + byte bInterval; + public Byte Length { get { return bmLength; } } + public UsbDescriptorType Type { get { return (UsbDescriptorType)bType; } } + public Byte EndpointAddress { get { return bEndpointAddress; } } + public Boolean IsInput { get { return 0 != (EndpointAddress & (1 << 7)); } } + public int EndpointNumber { get { return EndpointAddress & 0xF; } } + public int TransferType { get { return bmAttributes & 3; } } + public Boolean IsControl { get { return TransferType == 0; } } + public Boolean IsIsochronous { get { return TransferType == 1; } } + public Boolean IsBulk { get { return TransferType == 2; } } + public Boolean IsInterrupt { get { return TransferType == 3; } } + public int MaxPacketSize { get { return UsbDescriptor.FromLittleEndian(wMaxPacketSize) & 0x7FF; } } + public Byte Interval { get { return bInterval; } } + public unsafe static UsbEndpointDescriptor FromByteArray(Byte[] buffer, int offset, int length) { + if (length < Size) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); + if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); + fixed (Byte* ptr = buffer) return *(UsbEndpointDescriptor*)(ptr + offset); + } + public static unsafe int Size { get { return sizeof(UsbEndpointDescriptor); } } + } + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct UsbHIDDescriptor { + byte bmLength; + byte bType; + short bcdHID; + byte bCountryCode; + byte bNumDescriptors; + byte bDescriptorType; + short wDescriptorLength; + public Byte Length { get { return bmLength; } } + public UsbDescriptorType Type { get { return (UsbDescriptorType)bType; } } + public short HIDVersion { get { return UsbDescriptor.FromLittleEndian(bcdHID); } } + public Byte CountryCode { get { return bCountryCode; } } + public Byte NumDescriptors { get { return bNumDescriptors; } } + public UsbDescriptorType DescriptorType { get { return (UsbDescriptorType)bDescriptorType; } } + public short DescriptorLength { get { return UsbDescriptor.FromLittleEndian(wDescriptorLength); } } + public unsafe static UsbHIDDescriptor FromByteArray(Byte[] buffer, int offset, int length) { + if (length < Size) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); + if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); + fixed (Byte* ptr = buffer) return *(UsbHIDDescriptor*)(ptr + offset); + } + public static unsafe int Size { get { return sizeof(UsbHIDDescriptor); } } + } + [StructLayout(LayoutKind.Sequential, Pack = 1)] + public struct UsbHubDescriptor { + byte bmLength; + byte bType; + byte bNumPorts; + short wHubCharacteristics; + byte bPwrOn2PwrGood; //2ms intervals + byte bHubControllerCurrent; + public Byte Length { get { return bmLength; } } + public UsbDescriptorType Type { get { return (UsbDescriptorType)bType; } } + public Byte NumPorts { get { return bNumPorts; } } + public Boolean IsCompoundDevice { get { return 0 != (wHubCharacteristics & (1 << 2)); } } + public Byte HubControllerCurrent { get { return bHubControllerCurrent; } } + public unsafe static UsbHubDescriptor FromByteArray(Byte[] buffer, int offset, int length) { + if (length < Marshal.SizeOf(typeof(UsbHubDescriptor))) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); + if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); + fixed (Byte* ptr = buffer) return *(UsbHubDescriptor*)(ptr + offset); + } + } +}