annotate USBLib/Communication/LibUsb0/LibUsbDevice.cs @ 46:053cc617af54

USBLib: added functions to clear USB endpoint halt state
author Ivo Smits <Ivo@UCIS.nl>
date Sun, 30 Jun 2013 16:28:36 +0200
parents dcfec2be27c9
children 2d16447eff12
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
21
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1 using System;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
2 using System.ComponentModel;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
3 using System.Runtime.InteropServices;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
4 using System.Threading;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
5 using Microsoft.Win32.SafeHandles;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
6 using UCIS.USBLib.Internal.Windows;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
7
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
8 namespace UCIS.USBLib.Communication.LibUsb {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
9 public class LibUsb0Device : UsbInterface, IUsbDevice {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
10 //private readonly List<int> mClaimedInterfaces = new List<int>();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
11 public string DeviceFilename { get; private set; }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
12 public IUsbDeviceRegistry Registry { get; private set; }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
13 private SafeFileHandle DeviceHandle;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
14
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
15 public LibUsb0Device(String path, LibUsb0Registry registry) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
16 DeviceFilename = path;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
17 this.Registry = registry;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
18 DeviceHandle = Kernel32.CreateFile(DeviceFilename,
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
19 NativeFileAccess.SPECIAL,
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
20 NativeFileShare.NONE,
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
21 IntPtr.Zero,
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
22 NativeFileMode.OPEN_EXISTING,
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
23 NativeFileFlag.FILE_FLAG_OVERLAPPED,
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
24 IntPtr.Zero);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
25 if (DeviceHandle.IsInvalid || DeviceHandle.IsClosed) throw new Win32Exception(Marshal.GetLastWin32Error(), "Could not open device");
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
26 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
27 public override void Close() {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
28 if (DeviceHandle != null) DeviceHandle.Close();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
29 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
30
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
31 public override Byte Configuration {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
32 get { return base.Configuration; }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
33 set {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
34 ControlWrite(
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
35 UsbControlRequestType.EndpointOut | UsbControlRequestType.TypeStandard | UsbControlRequestType.RecipDevice,
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
36 (byte)UsbStandardRequest.SetConfiguration,
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
37 value,
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
38 0, null, 0, 0);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
39 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
40 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
41
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
42 public void ClaimInterface(int interfaceID) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
43 LibUsbRequest req = new LibUsbRequest();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
44 req.Iface.ID = interfaceID;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
45 req.Timeout = UsbConstants.DEFAULT_TIMEOUT;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
46 int ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
47 DeviceIoControl(DeviceHandle, LibUsbIoCtl.CLAIM_INTERFACE, ref req, LibUsbRequest.Size, null, 0, out ret);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
48 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
49 public void ReleaseInterface(int interfaceID) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
50 LibUsbRequest req = new LibUsbRequest();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
51 req.Iface.ID = interfaceID;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
52 req.Timeout = UsbConstants.DEFAULT_TIMEOUT;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
53 int ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
54 DeviceIoControl(DeviceHandle, LibUsbIoCtl.RELEASE_INTERFACE, ref req, LibUsbRequest.Size, null, 0, out ret);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
55 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
56 public void SetAltInterface(int interfaceID, int alternateID) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
57 LibUsbRequest req = new LibUsbRequest();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
58 req.Iface.ID = interfaceID;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
59 req.Iface.AlternateID = alternateID;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
60 req.Timeout = UsbConstants.DEFAULT_TIMEOUT;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
61 int ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
62 DeviceIoControl(DeviceHandle, LibUsbIoCtl.SET_INTERFACE, ref req, LibUsbRequest.Size, null, 0, out ret);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
63 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
64 public void ResetDevice() {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
65 LibUsbRequest req = new LibUsbRequest();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
66 req.Timeout = UsbConstants.DEFAULT_TIMEOUT;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
67 int ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
68 DeviceIoControl(DeviceHandle, LibUsbIoCtl.RESET_DEVICE, ref req, LibUsbRequest.Size, null, 0, out ret);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
69 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
70 public unsafe override int GetDescriptor(byte descriptorType, byte index, short langId, byte[] buffer, int offset, int length) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
71 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length");
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
72 LibUsbRequest req = new LibUsbRequest();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
73 req.Descriptor.Index = index;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
74 req.Descriptor.LangID = langId;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
75 req.Descriptor.Recipient = (byte)UsbEndpointDirection.EndpointIn & 0x1F;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
76 req.Descriptor.Type = descriptorType;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
77 req.Timeout = UsbConstants.DEFAULT_TIMEOUT;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
78 int ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
79 fixed (Byte* b = buffer) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
80 DeviceIoControl(DeviceHandle, LibUsbIoCtl.GET_DESCRIPTOR, ref req, LibUsbRequest.Size, (IntPtr)(b + offset), length, out ret);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
81 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
82 return ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
83 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
84 public override int BulkRead(byte endpoint, byte[] buffer, int offset, int length) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
85 return PipeTransfer(endpoint, false, false, buffer, offset, length, 0);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
86 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
87 public override int BulkWrite(byte endpoint, byte[] buffer, int offset, int length) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
88 return PipeTransfer(endpoint, true, false, buffer, offset, length, 0);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
89 }
46
053cc617af54 USBLib: added functions to clear USB endpoint halt state
Ivo Smits <Ivo@UCIS.nl>
parents: 21
diff changeset
90 public override void BulkReset(byte endpoint) {
053cc617af54 USBLib: added functions to clear USB endpoint halt state
Ivo Smits <Ivo@UCIS.nl>
parents: 21
diff changeset
91 PipeReset(endpoint);
053cc617af54 USBLib: added functions to clear USB endpoint halt state
Ivo Smits <Ivo@UCIS.nl>
parents: 21
diff changeset
92 }
21
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
93 public override int InterruptRead(byte endpoint, byte[] buffer, int offset, int length) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
94 return PipeTransfer(endpoint, false, false, buffer, offset, length, 0);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
95 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
96 public override int InterruptWrite(byte endpoint, byte[] buffer, int offset, int length) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
97 return PipeTransfer(endpoint, true, false, buffer, offset, length, 0);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
98 }
46
053cc617af54 USBLib: added functions to clear USB endpoint halt state
Ivo Smits <Ivo@UCIS.nl>
parents: 21
diff changeset
99 public override void InterruptReset(byte endpoint) {
053cc617af54 USBLib: added functions to clear USB endpoint halt state
Ivo Smits <Ivo@UCIS.nl>
parents: 21
diff changeset
100 PipeReset(endpoint);
053cc617af54 USBLib: added functions to clear USB endpoint halt state
Ivo Smits <Ivo@UCIS.nl>
parents: 21
diff changeset
101 }
21
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
102 public unsafe override int ControlRead(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
103 if (buffer == null) buffer = new Byte[0];
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
104 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length");
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
105 int code;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
106 LibUsbRequest req = new LibUsbRequest();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
107 PrepareControlTransfer(requestType, request, value, index, length, ref req, out code);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
108 int ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
109 fixed (Byte* b = buffer) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
110 DeviceIoControl(DeviceHandle, code, ref req, LibUsbRequest.Size, (IntPtr)(b + offset), length, out ret);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
111 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
112 return ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
113 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
114 public unsafe override int ControlWrite(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
115 Byte[] inbuffer = new Byte[length + LibUsbRequest.Size];
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
116 if (length > 0) Buffer.BlockCopy(buffer, offset, inbuffer, LibUsbRequest.Size, length);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
117 int code;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
118 fixed (Byte* inbufferp = inbuffer)
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
119 PrepareControlTransfer(requestType, request, value, index, length, ref *((LibUsbRequest*)inbufferp), out code);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
120 int ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
121 DeviceIoControl(DeviceHandle, code, inbuffer, length + LibUsbRequest.Size, null, 0, out ret);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
122 return length;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
123 //ret -= LibUsbRequest.Size;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
124 //if (ret <= 0) return 0;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
125 //return ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
126 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
127 void PrepareControlTransfer(UsbControlRequestType requestType, byte request, short value, short index, int length, ref LibUsbRequest req, out int code) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
128 code = LibUsbIoCtl.CONTROL_TRANSFER;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
129 req.Timeout = UsbConstants.DEFAULT_TIMEOUT;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
130 req.Control.RequestType = (Byte)requestType;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
131 req.Control.Request = request;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
132 req.Control.Value = (ushort)value;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
133 req.Control.Index = (ushort)index;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
134 req.Control.Length = (ushort)length;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
135 switch ((UsbControlRequestType)((int)requestType & (0x03 << 5))) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
136 case UsbControlRequestType.TypeStandard:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
137 switch ((UsbStandardRequest)request) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
138 case UsbStandardRequest.GetStatus:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
139 req.Status.Recipient = (int)requestType & 0x1F;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
140 req.Status.Index = index;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
141 code = LibUsbIoCtl.GET_STATUS;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
142 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
143 case UsbStandardRequest.ClearFeature:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
144 req.Feature.Recipient = (int)requestType & 0x1F;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
145 req.Feature.ID = value;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
146 req.Feature.Index = index;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
147 code = LibUsbIoCtl.CLEAR_FEATURE;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
148 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
149 case UsbStandardRequest.SetFeature:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
150 req.Feature.Recipient = (int)requestType & 0x1F;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
151 req.Feature.ID = value;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
152 req.Feature.Index = index;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
153 code = LibUsbIoCtl.SET_FEATURE;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
154 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
155 case UsbStandardRequest.GetDescriptor:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
156 req.Descriptor.Recipient = (int)requestType & 0x1F;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
157 req.Descriptor.Type = (value >> 8) & 0xFF;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
158 req.Descriptor.Index = value & 0xFF;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
159 req.Descriptor.LangID = index;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
160 code = LibUsbIoCtl.GET_DESCRIPTOR;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
161 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
162 case UsbStandardRequest.SetDescriptor:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
163 req.Descriptor.Recipient = (int)requestType & 0x1F;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
164 req.Descriptor.Type = (value >> 8) & 0xFF;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
165 req.Descriptor.Index = value & 0xFF;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
166 req.Descriptor.LangID = index;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
167 code = LibUsbIoCtl.SET_DESCRIPTOR;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
168 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
169 case UsbStandardRequest.GetConfiguration:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
170 code = LibUsbIoCtl.GET_CONFIGURATION;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
171 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
172 case UsbStandardRequest.SetConfiguration:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
173 req.Config.ID = value;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
174 code = LibUsbIoCtl.SET_CONFIGURATION;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
175 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
176 case UsbStandardRequest.GetInterface:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
177 req.Iface.ID = index;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
178 code = LibUsbIoCtl.GET_INTERFACE;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
179 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
180 case UsbStandardRequest.SetInterface:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
181 req.Iface.ID = index;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
182 req.Iface.AlternateID = value;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
183 code = LibUsbIoCtl.SET_INTERFACE;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
184 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
185 default:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
186 throw new ArgumentException(String.Format("Invalid request: 0x{0:X8}", request));
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
187 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
188 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
189 case UsbControlRequestType.TypeVendor:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
190 case UsbControlRequestType.TypeClass:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
191 req.Vendor.Type = ((byte)requestType >> 5) & 0x03;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
192 req.Vendor.Recipient = (int)requestType & 0x1F;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
193 req.Vendor.Request = (int)request;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
194 req.Vendor.ID = value;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
195 req.Vendor.Index = index;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
196 code = ((byte)requestType & 0x80) != 0 ? LibUsbIoCtl.VENDOR_READ : LibUsbIoCtl.VENDOR_WRITE;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
197 break;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
198 case UsbControlRequestType.TypeReserved:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
199 default:
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
200 throw new ArgumentException(String.Format("Invalid or unsupported request type: 0x{0:X8}", requestType));
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
201 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
202 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
203
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
204 unsafe int PipeTransfer(Byte epnum, Boolean write, Boolean isochronous, Byte[] buffer, int offset, int length, int packetsize) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
205 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length");
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
206 LibUsbRequest req = new LibUsbRequest();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
207 req.Endpoint.ID = epnum;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
208 req.Endpoint.PacketSize = packetsize;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
209 req.Timeout = UsbConstants.DEFAULT_TIMEOUT;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
210 fixed (Byte* b = buffer) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
211 if (write) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
212 int cltCode = isochronous ? LibUsbIoCtl.ISOCHRONOUS_WRITE : LibUsbIoCtl.INTERRUPT_OR_BULK_WRITE;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
213 int transfered = 0;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
214 while (length > 0) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
215 int ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
216 DeviceIoControl(DeviceHandle, cltCode, ref req, LibUsbRequest.Size, (IntPtr)(b + offset), Math.Min(Int16.MaxValue, length), out ret);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
217 if (ret <= 0) throw new System.IO.EndOfStreamException();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
218 length -= ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
219 offset += ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
220 transfered += ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
221 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
222 return transfered;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
223 } else {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
224 int cltCode = isochronous ? LibUsbIoCtl.ISOCHRONOUS_READ : LibUsbIoCtl.INTERRUPT_OR_BULK_READ;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
225 int ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
226 DeviceIoControl(DeviceHandle, cltCode, ref req, LibUsbRequest.Size, (IntPtr)(b + offset), Math.Min(UInt16.MaxValue, length), out ret);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
227 return ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
228 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
229 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
230 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
231 public void PipeReset(byte pipeID) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
232 LibUsbRequest req = new LibUsbRequest();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
233 req.Endpoint.ID = pipeID;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
234 req.Timeout = UsbConstants.DEFAULT_TIMEOUT;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
235 int ret;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
236 DeviceIoControl(DeviceHandle, LibUsbIoCtl.RESET_ENDPOINT, ref req, LibUsbRequest.Size, null, 0, out ret);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
237 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
238
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
239 private unsafe void DeviceIoControl(SafeHandle hDevice, int IoControlCode, [In] ref LibUsbRequest InBuffer, int nInBufferSize, Byte[] OutBuffer, int nOutBufferSize, out int pBytesReturned) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
240 fixed (LibUsbRequest* InBufferPtr = &InBuffer) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
241 fixed (Byte* OutBufferPtr = OutBuffer) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
242 DeviceIoControl(hDevice, IoControlCode, (IntPtr)InBufferPtr, nInBufferSize, (IntPtr)OutBufferPtr, nOutBufferSize, out pBytesReturned);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
243 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
244 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
245 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
246 private unsafe void DeviceIoControl(SafeHandle hDevice, int IoControlCode, Byte[] InBuffer, int nInBufferSize, Byte[] OutBuffer, int nOutBufferSize, out int pBytesReturned) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
247 fixed (Byte* InBufferPtr = InBuffer, OutBufferPtr = OutBuffer) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
248 DeviceIoControl(hDevice, IoControlCode, (IntPtr)InBufferPtr, nInBufferSize, (IntPtr)OutBufferPtr, nOutBufferSize, out pBytesReturned);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
249 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
250 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
251 private unsafe void DeviceIoControl(SafeHandle hDevice, int IoControlCode, [In] ref LibUsbRequest InBuffer, int nInBufferSize, IntPtr OutBuffer, int nOutBufferSize, out int pBytesReturned) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
252 fixed (LibUsbRequest* InBufferPtr = &InBuffer) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
253 DeviceIoControl(hDevice, IoControlCode, (IntPtr)InBufferPtr, nInBufferSize, OutBuffer, nOutBufferSize, out pBytesReturned);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
254 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
255 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
256 private unsafe void DeviceIoControl(SafeHandle hDevice, int IoControlCode, IntPtr InBuffer, int nInBufferSize, IntPtr OutBuffer, int nOutBufferSize, out int pBytesReturned) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
257 using (ManualResetEvent evt = new ManualResetEvent(false)) {
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
258 NativeOverlapped overlapped = new NativeOverlapped();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
259 overlapped.EventHandle = evt.SafeWaitHandle.DangerousGetHandle();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
260 if (Kernel32.DeviceIoControl(hDevice, IoControlCode, InBuffer, nInBufferSize, OutBuffer, nOutBufferSize, out pBytesReturned, &overlapped))
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
261 return;
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
262 int err = Marshal.GetLastWin32Error();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
263 if (err != 997) throw new Win32Exception(err);
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
264 evt.WaitOne();
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
265 if (!Kernel32.GetOverlappedResult(hDevice, &overlapped, out pBytesReturned, false))
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
266 throw new Win32Exception(Marshal.GetLastWin32Error());
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
267 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
268 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
269 }
dcfec2be27c9 Added USBLib
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
270 }