comparison USBLib/Communication/LibUsb0/Support.cs @ 21:dcfec2be27c9

Added USBLib
author Ivo Smits <Ivo@UCIS.nl>
date Mon, 15 Apr 2013 01:04:59 +0200
parents
children 5b14fed54a89
comparison
equal deleted inserted replaced
20:c873e3dd73fe 21:dcfec2be27c9
1 using System;
2 using System.Runtime.InteropServices;
3
4 namespace UCIS.USBLib.Communication.LibUsb {
5 /// <summary> Transfers data to the main control endpoint (Endpoint 0).
6 /// </summary>
7 /// <remarks> All USB devices respond to requests from the host on the device’s Default Control Pipe. These requests are made using control transfers. The request and the request’s parameters are sent to the device in the Setup packet. The host is responsible for establishing the values passed in the fields. Every Setup packet has eight bytes.
8 /// </remarks>
9 [StructLayout(LayoutKind.Sequential, Pack = 1)]
10 struct UsbSetupPacket {
11 /// <summary>
12 /// This bitmapped field identifies the characteristics of the specific request. In particular, this field identifies the direction of data transfer in the second phase of the control transfer. The state of the Direction bit is ignored if the wLength field is zero, signifying there is no Data stage.
13 /// The USB Specification defines a series of standard requests that all devices must support. In addition, a device class may define additional requests. A device vendor may also define requests supported by the device.
14 /// Requests may be directed to the device, an interface on the device, or a specific endpoint on a device. This field also specifies the intended recipient of the request. When an interface or endpoint is specified, the wIndex field identifies the interface or endpoint.
15 /// </summary>
16 /// <remarks>
17 /// <ul>Characteristics of request:
18 /// <li>D7: Data transfer direction</li>
19 /// <li>0 = Host-to-device</li>
20 /// <li>1 = Device-to-host</li>
21 /// <li>D6...5: Type</li>
22 /// <li>0 = Standard</li>
23 /// <li>1 = Class</li>
24 /// <li>2 = Vendor</li>
25 /// <li>3 = Reserved</li>
26 /// <li>D4...0: Recipient</li>
27 /// <li>0 = Device</li>
28 /// <li>1 = Interface</li>
29 /// <li>2 = Endpoint</li>
30 /// <li>3 = Other</li>
31 /// <li>4...31 = Reserved</li>
32 /// </ul>
33 /// </remarks>
34 public byte RequestType;
35
36 /// <summary>
37 /// This field specifies the particular request. The Type bits in the bmRequestType field modify the meaning of this field. This specification defines values for the bRequest field only when the bits are reset to zero, indicating a standard request.
38 /// </summary>
39 public byte Request;
40
41 /// <summary>
42 /// The contents of this field vary according to the request. It is used to pass a parameter to the device, specific to the request.
43 /// </summary>
44 public short Value;
45
46 /// <summary>
47 /// The contents of this field vary according to the request. It is used to pass a parameter to the device, specific to the request.
48 /// </summary>
49 public short Index;
50
51 /// <summary>
52 /// This field specifies the length of the data transferred during the second phase of the control transfer. The direction of data transfer (host-to-device or device-to-host) is indicated by the Direction bit of the <see cref="RequestType"/> field. If this field is zero, there is no data transfer phase. On an input request, a device must never return more data than is indicated by the wLength value; it may return less. On an output request, wLength will always indicate the exact amount of data to be sent by the host. Device behavior is undefined if the host should send more data than is specified in wLength.
53 /// </summary>
54 public short Length;
55
56 /// <summary>
57 /// Creates a new instance of a <see cref="UsbSetupPacket"/> and initializes all the fields with the following parameters.
58 /// </summary>
59 /// <param name="requestType">See <see cref="UsbSetupPacket.RequestType"/>.</param>
60 /// <param name="request">See <see cref="UsbSetupPacket.Request"/>.</param>
61 /// <param name="value">See <see cref="UsbSetupPacket.Value"/>.</param>
62 /// <param name="index">See <see cref="UsbSetupPacket.Index"/>.</param>
63 /// <param name="length">See <see cref="UsbSetupPacket.Length"/>.</param>
64 public UsbSetupPacket(byte requestType, byte request, short value, short index, short length) {
65 RequestType = requestType;
66 Request = request;
67 Value = value;
68 Index = index;
69 Length = length;
70 }
71 }
72 /// <summary> Standard Windows registry properties for USB devices and other hardware.
73 /// </summary>
74 /// DeviceRegistryProperty or DEVICE_REGISTRY_PROPERTY on MSDN
75 enum DevicePropertyType {
76 /// <summary>
77 /// Requests a string describing the device, such as "Microsoft PS/2 Port Mouse", typically defined by the manufacturer.
78 /// </summary>
79 DeviceDesc = 0,
80 /// <summary>
81 /// Requests the hardware IDs provided by the device that identify the device.
82 /// </summary>
83 HardwareId = 1,
84 /// <summary>
85 /// Requests the compatible IDs reported by the device.
86 /// </summary>
87 CompatibleIds = 2,
88 /// <summary>
89 /// Requests the name of the device's setup class, in text format.
90 /// </summary>
91 Class = 5,
92 /// <summary>
93 /// Requests the GUID for the device's setup class.
94 /// </summary>
95 ClassGuid = 6,
96 /// <summary>
97 /// Requests the name of the driver-specific registry key.
98 /// </summary>
99 Driver = 7,
100 /// <summary>
101 /// Requests a string identifying the manufacturer of the device.
102 /// </summary>
103 Mfg = 8,
104 /// <summary>
105 /// Requests a string that can be used to distinguish between two similar devices, typically defined by the class installer.
106 /// </summary>
107 FriendlyName = 9,
108 /// <summary>
109 /// Requests information about the device's location on the bus; the interpretation of this information is bus-specific.
110 /// </summary>
111 LocationInformation = 10,
112 /// <summary>
113 /// Requests the name of the PDO for this device.
114 /// </summary>
115 PhysicalDeviceObjectName = 11,
116 /// <summary>
117 /// Requests the GUID for the bus that the device is connected to.
118 /// </summary>
119 BusTypeGuid = 12,
120 /// <summary>
121 /// Requests the bus type, such as PCIBus or PCMCIABus.
122 /// </summary>
123 LegacyBusType = 13,
124 /// <summary>
125 /// Requests the legacy bus number of the bus the device is connected to.
126 /// </summary>
127 BusNumber = 14,
128 /// <summary>
129 /// Requests the name of the enumerator for the device, such as "USB".
130 /// </summary>
131 EnumeratorName = 15,
132 /// <summary>
133 /// Requests the address of the device on the bus.
134 /// </summary>
135 Address = 16,
136 /// <summary>
137 /// Requests a number associated with the device that can be displayed in the user interface.
138 /// </summary>
139 UiNumber = 17,
140 /// <summary>
141 /// Windows XP and later.) Requests the device's installation state.
142 /// </summary>
143 InstallState = 18,
144 /// <summary>
145 /// (Windows XP and later.) Requests the device's current removal policy. The operating system uses this value as a hint to determine how the device is normally removed.
146 /// </summary>
147 RemovalPolicy = 19
148 }
149 /// <summary> Various USB constants.
150 /// </summary>
151 static class UsbConstants {
152 /// <summary>
153 /// Default timeout for all USB IO operations.
154 /// </summary>
155 public const int DEFAULT_TIMEOUT = 1000;
156
157 /// <summary>
158 /// Maximum size of a config descriptor.
159 /// </summary>
160 public const int MAX_CONFIG_SIZE = 4096;
161
162 /// <summary>
163 /// Maximum number of USB devices.
164 /// </summary>
165 public const int MAX_DEVICES = 128;
166
167 /// <summary>
168 /// Maximum number of endpoints per device.
169 /// </summary>
170 public const int MAX_ENDPOINTS = 32;
171
172 /// <summary>
173 /// Endpoint direction mask.
174 /// </summary>
175 public const byte ENDPOINT_DIR_MASK = 0x80;
176
177 /// <summary>
178 /// Endpoint number mask.
179 /// </summary>
180 public const byte ENDPOINT_NUMBER_MASK = 0xf;
181
182 }
183 ///<summary>Endpoint direction.</summary>
184 /// <seealso cref="UsbCtrlFlags"/>
185 [Flags]
186 enum UsbEndpointDirection : byte {
187 /// <summary>
188 /// In Direction
189 /// </summary>
190 EndpointIn = 0x80,
191 /// <summary>
192 /// Out Direction
193 /// </summary>
194 EndpointOut = 0x00,
195 }
196 ///<summary>
197 /// Contains version information for the LibUsb Sys driver.
198 ///</summary>
199 /// <remarks>
200 /// This version is not related to LibUsbDotNet. TO get the LibUsbDotNet version use .NET reflections.
201 /// </remarks>
202 [StructLayout(LayoutKind.Sequential, Pack = 1)]
203 struct UsbKernelVersion {
204 /// <summary>
205 /// True if Major == 0 and Minor == 0 and Micro == 0 and Nano == 0.
206 /// </summary>
207 public bool IsEmpty {
208 get {
209 if (Major == 0 && Minor == 0 && Micro == 0 && Nano == 0) return true;
210 return false;
211 }
212 }
213
214 internal UsbKernelVersion(int major, int minor, int micro, int nano, int bcdLibUsbDotNetKernelMod) {
215 Major = major;
216 Minor = minor;
217 Micro = micro;
218 Nano = nano;
219 BcdLibUsbDotNetKernelMod = bcdLibUsbDotNetKernelMod;
220 }
221
222 /// <summary>
223 /// LibUsb-Win32 Major version
224 /// </summary>
225 public readonly int Major;
226
227 /// <summary>
228 /// LibUsb-Win32 Minor version
229 /// </summary>
230 public readonly int Minor;
231
232 /// <summary>
233 /// LibUsb-Win32 Micro version
234 /// </summary>
235 public readonly int Micro;
236
237 /// <summary>
238 /// LibUsb-Win32 Nano version
239 /// </summary>
240 public readonly int Nano;
241
242 /// <summary>
243 /// The LibUsbDotNet - LibUsb-Win32 binary mod code. if not running the LibUsbDotNet LibUsb-Win32 modified kernel driver, this value is 0.
244 /// </summary>
245 public readonly int BcdLibUsbDotNetKernelMod;
246
247 ///<summary>
248 ///The full LibUsb-Win32 kernel driver version (libusb0.sys).
249 ///</summary>
250 ///
251 ///<returns>
252 ///A <see cref="System.String"/> containing the full LibUsb-Win32 version.
253 ///</returns>
254 public override string ToString() { return string.Format("{0}.{1}.{2}.{3}", Major, Minor, Micro, Nano); }
255 }
256 [StructLayout(LayoutKind.Explicit, Pack = 1, Size = sizeof(int) * 6)]
257 struct LibUsbRequest {
258 public static int Size = Marshal.SizeOf(typeof(LibUsbRequest));
259 [FieldOffset(0)]
260 public int Timeout; // = UsbConstants.DEFAULT_TIMEOUT;
261
262 #region Union Struct
263
264 [FieldOffset(sizeof(int))]
265 public Control Control;
266
267 [FieldOffset(sizeof(int))]
268 public Config Config;
269
270 [FieldOffset(sizeof(int))]
271 public Debug Debug;
272
273 [FieldOffset(sizeof(int))]
274 public Descriptor Descriptor;
275
276 [FieldOffset(sizeof(int))]
277 public Endpoint Endpoint;
278
279 [FieldOffset(sizeof(int))]
280 public Feature Feature;
281
282 [FieldOffset(sizeof(int))]
283 public Iface Iface;
284
285 [FieldOffset(sizeof(int))]
286 public Status Status;
287
288 [FieldOffset(sizeof(int))]
289 public Vendor Vendor;
290
291 [FieldOffset(sizeof(int))]
292 public UsbKernelVersion Version;
293
294 [FieldOffset(sizeof(int))]
295 public DeviceProperty DeviceProperty;
296
297 [FieldOffset(sizeof(int))]
298 public DeviceRegKey DeviceRegKey;
299
300 [FieldOffset(sizeof(int))]
301 public BusQueryID BusQueryID;
302 #endregion
303
304 public Byte[] Bytes {
305 get {
306 Byte[] rtn = new byte[Size];
307
308 for (int i = 0; i < Size; i++)
309 rtn[i] = Marshal.ReadByte(this, i);
310
311 return rtn;
312 }
313 }
314
315
316 public void RequestConfigDescriptor(int index) {
317 Timeout = UsbConstants.DEFAULT_TIMEOUT;
318
319 int value = ((int)UsbDescriptorType.Configuration << 8) + index;
320
321 Descriptor.Recipient = (byte)UsbEndpointDirection.EndpointIn & 0x1F;
322 Descriptor.Type = (value >> 8) & 0xFF;
323 Descriptor.Index = value & 0xFF;
324 Descriptor.LangID = 0;
325 }
326
327 public void RequestStringDescriptor(int index, short langid) {
328 Timeout = UsbConstants.DEFAULT_TIMEOUT;
329
330 int value = ((int)UsbDescriptorType.String << 8) + index;
331
332 Descriptor.Recipient = (byte)UsbEndpointDirection.EndpointIn & 0x1F;
333 Descriptor.Type = value >> 8 & 0xFF;
334 Descriptor.Index = value & 0xFF;
335 Descriptor.LangID = langid;
336 }
337 }
338 [StructLayout(LayoutKind.Sequential, Pack = 1)]
339 struct Descriptor {
340 public int Type;
341 public int Index;
342 public int LangID;
343 public int Recipient;
344 }
345 [StructLayout(LayoutKind.Sequential, Pack = 1)]
346 struct Config {
347 public int ID;
348 }
349 [StructLayout(LayoutKind.Sequential, Pack = 1)]
350 struct Control {
351 public byte RequestType;
352 public byte Request;
353 public ushort Value;
354 public ushort Index;
355 public ushort Length;
356 }
357 [StructLayout(LayoutKind.Sequential, Pack = 1)]
358 struct DeviceProperty {
359 public int ID;
360 }
361 [StructLayout(LayoutKind.Sequential, Pack = 1)]
362 struct Iface {
363 public int ID;
364 public int AlternateID;
365 }
366 [StructLayout(LayoutKind.Sequential, Pack = 1)]
367 struct Endpoint {
368 public int ID;
369 public int PacketSize;
370 }
371 [StructLayout(LayoutKind.Sequential, Pack = 1)]
372 struct Vendor {
373 public int Type;
374 public int Recipient;
375 public int Request;
376 public int ID;
377 public int Index;
378 }
379 [StructLayout(LayoutKind.Sequential, Pack = 1)]
380 struct Feature {
381 public int Recipient;
382 public int ID;
383 public int Index;
384 }
385 [StructLayout(LayoutKind.Sequential, Pack = 1)]
386 struct Status {
387 public int Recipient;
388 public int Index;
389 public int ID;
390 }
391 [StructLayout(LayoutKind.Sequential, Pack = 1)]
392 struct Debug {
393 public int Level;
394 }
395 [StructLayout(LayoutKind.Sequential, Pack = 1)]
396 struct DeviceRegKey {
397 public int KeyType;
398 public int NameOffset;
399 public int ValueOffset;
400 public int ValueLength;
401 }
402 [StructLayout(LayoutKind.Sequential, Pack = 1)]
403 struct BusQueryID {
404 public ushort IDType;
405 }
406 static class LibUsbIoCtl {
407 private const int FILE_ANY_ACCESS = 0;
408 private const int FILE_DEVICE_UNKNOWN = 0x00000022;
409
410 private const int METHOD_BUFFERED = 0;
411 private const int METHOD_IN_DIRECT = 1;
412 private const int METHOD_OUT_DIRECT = 2;
413 private const int METHOD_NEITHER = 3;
414
415 public static readonly int ABORT_ENDPOINT = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80F, METHOD_BUFFERED, FILE_ANY_ACCESS);
416 public static readonly int CLAIM_INTERFACE = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x815, METHOD_BUFFERED, FILE_ANY_ACCESS);
417 public static readonly int CLEAR_FEATURE = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS);
418 public static readonly int CONTROL_TRANSFER = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x903, METHOD_BUFFERED, FILE_ANY_ACCESS);
419
420 public static readonly int GET_CONFIGURATION = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS);
421 public static readonly int GET_CUSTOM_REG_PROPERTY = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x901, METHOD_BUFFERED, FILE_ANY_ACCESS);
422 public static readonly int GET_DESCRIPTOR = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x809, METHOD_BUFFERED, FILE_ANY_ACCESS);
423 public static readonly int GET_INTERFACE = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS);
424 public static readonly int GET_STATUS = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807, METHOD_BUFFERED, FILE_ANY_ACCESS);
425 public static readonly int GET_VERSION = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x812, METHOD_BUFFERED, FILE_ANY_ACCESS);
426 public static readonly int GET_REG_PROPERTY = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x900, METHOD_BUFFERED, FILE_ANY_ACCESS);
427 public static readonly int INTERRUPT_OR_BULK_READ = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80B, METHOD_OUT_DIRECT, FILE_ANY_ACCESS);
428 public static readonly int INTERRUPT_OR_BULK_WRITE = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80A, METHOD_IN_DIRECT, FILE_ANY_ACCESS);
429 public static readonly int ISOCHRONOUS_READ = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x814, METHOD_OUT_DIRECT, FILE_ANY_ACCESS);
430 public static readonly int ISOCHRONOUS_WRITE = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x813, METHOD_IN_DIRECT, FILE_ANY_ACCESS);
431 public static readonly int RELEASE_INTERFACE = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x816, METHOD_BUFFERED, FILE_ANY_ACCESS);
432 public static readonly int RESET_DEVICE = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x810, METHOD_BUFFERED, FILE_ANY_ACCESS);
433 public static readonly int RESET_ENDPOINT = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80E, METHOD_BUFFERED, FILE_ANY_ACCESS);
434 public static readonly int SET_CONFIGURATION = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS);
435 public static readonly int SET_DEBUG_LEVEL = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x811, METHOD_BUFFERED, FILE_ANY_ACCESS);
436 public static readonly int SET_DESCRIPTOR = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x808, METHOD_BUFFERED, FILE_ANY_ACCESS);
437 public static readonly int SET_FEATURE = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS);
438 public static readonly int SET_INTERFACE = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS);
439 public static readonly int VENDOR_READ = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80D, METHOD_BUFFERED, FILE_ANY_ACCESS);
440 public static readonly int VENDOR_WRITE = CTL_CODE(FILE_DEVICE_UNKNOWN, 0x80C, METHOD_BUFFERED, FILE_ANY_ACCESS);
441
442 private static int CTL_CODE(int DeviceType, int Function, int Method, int Access) { return ((DeviceType) << 16) | ((Access) << 14) | ((Function) << 2) | (Method); }
443 }
444 }