21
|
1 ???using System; |
22
|
2 using System.Runtime.InteropServices; |
21
|
3 using System.Text; |
|
4 using UCIS.USBLib.Communication; |
|
5 |
|
6 namespace UCIS.USBLib.Descriptor { |
|
7 [StructLayout(LayoutKind.Sequential, Pack = 1)] |
|
8 public struct UsbDescriptor { |
|
9 byte bmLength; |
|
10 byte bType; |
|
11 public Byte Length { get { return bmLength; } } |
|
12 public UsbDescriptorType Type { get { return (UsbDescriptorType)bType; } } |
|
13 internal static short FromLittleEndian(short value) { |
|
14 if (BitConverter.IsLittleEndian) return value; |
|
15 return (short)(((value & 0xFF) << 8) | ((value >> 8) & 0xFF)); |
|
16 } |
|
17 public unsafe static UsbDescriptor FromByteArray(Byte[] buffer, int offset, int length) { |
|
18 if (length < Marshal.SizeOf(typeof(UsbDescriptor))) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); |
|
19 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); |
|
20 fixed (Byte* ptr = buffer) return *(UsbDescriptor*)(ptr + offset); |
|
21 } |
|
22 } |
|
23 [StructLayout(LayoutKind.Sequential, Pack = 1)] |
|
24 public struct UsbStringDescriptor { |
|
25 public static String GetString(Byte[] buffer, int offset, int length) { |
|
26 if (length < 2) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); |
|
27 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); |
|
28 if (buffer[offset + 1] != (Byte)UsbDescriptorType.String) throw new InvalidOperationException("The descriptor is not a string descriptor"); |
|
29 int slen = buffer[offset]; |
|
30 if (slen > length) throw new InvalidOperationException("The string has been truncated"); |
|
31 return Encoding.Unicode.GetString(buffer, offset + 2, slen - 2); |
|
32 } |
|
33 } |
|
34 [StructLayout(LayoutKind.Sequential, Pack = 1)] |
|
35 public struct UsbDeviceDescriptor { |
|
36 byte bmLength; |
|
37 byte bType; |
|
38 short bcdUSB; |
|
39 byte bDeviceClass; |
|
40 byte bDeviceSubClass; |
|
41 byte bDeviceProtocol; |
|
42 byte bMaxControlPacketSize; |
|
43 short idVendor; |
|
44 short idProduct; |
|
45 short bcdDevice; |
|
46 byte iManufacturer; |
|
47 byte iProduct; |
|
48 byte iSerialNumber; |
|
49 byte numConfigurations; |
|
50 public Byte Length { get { return bmLength; } } |
|
51 public UsbDescriptorType Type { get { return (UsbDescriptorType)bType; }} |
|
52 public short USBVersion { get { return UsbDescriptor.FromLittleEndian(bcdUSB); } } |
|
53 public Byte DeviceClass { get { return bDeviceClass; } } |
|
54 public Byte DeviceSubClass { get { return bDeviceSubClass; } } |
|
55 public Byte DeviceProtocol { get { return bDeviceProtocol; } } |
|
56 public short DeviceVersion { get { return UsbDescriptor.FromLittleEndian(bcdDevice); } } |
|
57 public Byte MaxControlPacketSize { get { return bMaxControlPacketSize; } } |
|
58 public short VendorID { get { return UsbDescriptor.FromLittleEndian(idVendor); } } |
|
59 public short ProductID { get { return UsbDescriptor.FromLittleEndian(idProduct); } } |
|
60 public Byte ManufacturerStringID { get { return iManufacturer; } } |
|
61 public Byte ProductStringID { get { return iProduct; } } |
|
62 public Byte SerialNumberStringID { get { return iSerialNumber; } } |
|
63 public Byte NumConfigurations { get { return numConfigurations; } } |
|
64 public unsafe static UsbDeviceDescriptor FromByteArray(Byte[] buffer, int offset, int length) { |
|
65 if (length < Size) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); |
|
66 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); |
|
67 fixed (Byte* ptr = buffer) return *(UsbDeviceDescriptor*)(ptr + offset); |
|
68 } |
|
69 public static unsafe int Size { get { return sizeof(UsbDeviceDescriptor); } } |
|
70 } |
|
71 [StructLayout(LayoutKind.Sequential, Pack = 1)] |
|
72 public struct UsbConfigurationDescriptor { |
|
73 byte bmLength; |
|
74 byte bType; |
|
75 short wTotalLength; |
|
76 byte bNumInterfaces; |
|
77 byte bConfigurationValue; |
|
78 byte bConfigurationStringID; |
|
79 byte bmAttributes; |
|
80 byte bMaxPower; |
|
81 public Byte Length { get { return bmLength; } } |
|
82 public UsbDescriptorType Type { get { return (UsbDescriptorType)bType; } } |
|
83 public short TotalLength { get { return UsbDescriptor.FromLittleEndian(wTotalLength); } } |
|
84 public Byte NumInterfaces { get { return bNumInterfaces; } } |
|
85 public Byte ConfigurationValue { get { return bConfigurationValue; } } |
|
86 public Byte ConfigurationStringID { get { return bConfigurationStringID; } } |
|
87 public Boolean SelfPowered { get { return 0 != (bmAttributes & (1 << 6)); } } |
|
88 public Boolean RemoteWakeup { get { return 0 != (bmAttributes & (1 << 5)); } } |
|
89 public int MaxPowerMA { get { return bMaxPower * 2; } } |
|
90 public unsafe static UsbConfigurationDescriptor FromByteArray(Byte[] buffer, int offset, int length) { |
|
91 if (length < Size) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); |
|
92 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); |
|
93 fixed (Byte* ptr = buffer) return *(UsbConfigurationDescriptor*)(ptr + offset); |
|
94 } |
|
95 public static unsafe int Size { get { return sizeof(UsbConfigurationDescriptor); } } |
|
96 } |
|
97 [StructLayout(LayoutKind.Sequential, Pack = 1)] |
|
98 public struct UsbInterfaceDescriptor { |
|
99 byte bmLength; |
|
100 byte bType; |
|
101 byte bInterfaceNumber; |
|
102 byte bAlternateSetting; |
|
103 byte bNumEndpoints; |
|
104 byte bInterfaceClass; |
|
105 byte bInterfaceSubClass; |
|
106 byte bInterfaceProtocol; |
|
107 byte bInterfaceStringID; |
|
108 public Byte Length { get { return bmLength; } } |
|
109 public UsbDescriptorType Type { get { return (UsbDescriptorType)bType; } } |
|
110 public Byte InterfaceNumber { get { return bInterfaceNumber; } } |
|
111 public Byte AlternateSetting { get { return bAlternateSetting; } } |
|
112 public Byte NumEndpoints { get { return bNumEndpoints; } } |
|
113 public Byte InterfaceClass { get { return bInterfaceClass; } } |
|
114 public Byte InterfaceSubClass { get { return bInterfaceSubClass; } } |
|
115 public Byte InterfaceProtocol { get { return bInterfaceProtocol; } } |
|
116 public Byte InterfaceStringID { get { return bInterfaceStringID; } } |
|
117 public unsafe static UsbInterfaceDescriptor FromByteArray(Byte[] buffer, int offset, int length) { |
|
118 if (length < Size) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); |
|
119 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); |
|
120 fixed (Byte* ptr = buffer) return *(UsbInterfaceDescriptor*)(ptr + offset); |
|
121 } |
|
122 public static unsafe int Size { get { return sizeof(UsbInterfaceDescriptor); } } |
|
123 } |
|
124 [StructLayout(LayoutKind.Sequential, Pack = 1)] |
|
125 public struct UsbEndpointDescriptor { |
|
126 byte bmLength; |
|
127 byte bType; |
|
128 byte bEndpointAddress; |
|
129 Byte bmAttributes; |
|
130 short wMaxPacketSize; |
|
131 byte bInterval; |
|
132 public Byte Length { get { return bmLength; } } |
|
133 public UsbDescriptorType Type { get { return (UsbDescriptorType)bType; } } |
|
134 public Byte EndpointAddress { get { return bEndpointAddress; } } |
|
135 public Boolean IsInput { get { return 0 != (EndpointAddress & (1 << 7)); } } |
|
136 public int EndpointNumber { get { return EndpointAddress & 0xF; } } |
|
137 public int TransferType { get { return bmAttributes & 3; } } |
|
138 public Boolean IsControl { get { return TransferType == 0; } } |
|
139 public Boolean IsIsochronous { get { return TransferType == 1; } } |
|
140 public Boolean IsBulk { get { return TransferType == 2; } } |
|
141 public Boolean IsInterrupt { get { return TransferType == 3; } } |
|
142 public int MaxPacketSize { get { return UsbDescriptor.FromLittleEndian(wMaxPacketSize) & 0x7FF; } } |
|
143 public Byte Interval { get { return bInterval; } } |
|
144 public unsafe static UsbEndpointDescriptor FromByteArray(Byte[] buffer, int offset, int length) { |
|
145 if (length < Size) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); |
|
146 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); |
|
147 fixed (Byte* ptr = buffer) return *(UsbEndpointDescriptor*)(ptr + offset); |
|
148 } |
|
149 public static unsafe int Size { get { return sizeof(UsbEndpointDescriptor); } } |
|
150 } |
|
151 [StructLayout(LayoutKind.Sequential, Pack = 1)] |
|
152 public struct UsbHIDDescriptor { |
|
153 byte bmLength; |
|
154 byte bType; |
|
155 short bcdHID; |
|
156 byte bCountryCode; |
|
157 byte bNumDescriptors; |
|
158 byte bDescriptorType; |
|
159 short wDescriptorLength; |
|
160 public Byte Length { get { return bmLength; } } |
|
161 public UsbDescriptorType Type { get { return (UsbDescriptorType)bType; } } |
|
162 public short HIDVersion { get { return UsbDescriptor.FromLittleEndian(bcdHID); } } |
|
163 public Byte CountryCode { get { return bCountryCode; } } |
|
164 public Byte NumDescriptors { get { return bNumDescriptors; } } |
|
165 public UsbDescriptorType DescriptorType { get { return (UsbDescriptorType)bDescriptorType; } } |
|
166 public short DescriptorLength { get { return UsbDescriptor.FromLittleEndian(wDescriptorLength); } } |
|
167 public unsafe static UsbHIDDescriptor FromByteArray(Byte[] buffer, int offset, int length) { |
|
168 if (length < Size) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); |
|
169 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); |
|
170 fixed (Byte* ptr = buffer) return *(UsbHIDDescriptor*)(ptr + offset); |
|
171 } |
|
172 public static unsafe int Size { get { return sizeof(UsbHIDDescriptor); } } |
|
173 } |
|
174 [StructLayout(LayoutKind.Sequential, Pack = 1)] |
|
175 public struct UsbHubDescriptor { |
|
176 byte bmLength; |
|
177 byte bType; |
|
178 byte bNumPorts; |
|
179 short wHubCharacteristics; |
|
180 byte bPwrOn2PwrGood; //2ms intervals |
|
181 byte bHubControllerCurrent; |
|
182 public Byte Length { get { return bmLength; } } |
|
183 public UsbDescriptorType Type { get { return (UsbDescriptorType)bType; } } |
|
184 public Byte NumPorts { get { return bNumPorts; } } |
|
185 public Boolean IsCompoundDevice { get { return 0 != (wHubCharacteristics & (1 << 2)); } } |
|
186 public Byte HubControllerCurrent { get { return bHubControllerCurrent; } } |
|
187 public unsafe static UsbHubDescriptor FromByteArray(Byte[] buffer, int offset, int length) { |
|
188 if (length < Marshal.SizeOf(typeof(UsbHubDescriptor))) throw new ArgumentOutOfRangeException("length", "The data length is smaller than the descriptor length"); |
|
189 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer dimensions"); |
|
190 fixed (Byte* ptr = buffer) return *(UsbHubDescriptor*)(ptr + offset); |
|
191 } |
|
192 } |
|
193 } |