comparison USBLib/Communication/LibUsb0/LibUsbDevice.cs @ 67:2d16447eff12

Simplified USB communication code, added functions to abort pipe transfers
author Ivo Smits <Ivo@UCIS.nl>
date Wed, 16 Oct 2013 01:11:49 +0200
parents 053cc617af54
children d467cd38b34e
comparison
equal deleted inserted replaced
66:b7bc27c6734e 67:2d16447eff12
5 using Microsoft.Win32.SafeHandles; 5 using Microsoft.Win32.SafeHandles;
6 using UCIS.USBLib.Internal.Windows; 6 using UCIS.USBLib.Internal.Windows;
7 7
8 namespace UCIS.USBLib.Communication.LibUsb { 8 namespace UCIS.USBLib.Communication.LibUsb {
9 public class LibUsb0Device : UsbInterface, IUsbDevice { 9 public class LibUsb0Device : UsbInterface, IUsbDevice {
10 //private readonly List<int> mClaimedInterfaces = new List<int>();
11 public string DeviceFilename { get; private set; } 10 public string DeviceFilename { get; private set; }
12 public IUsbDeviceRegistry Registry { get; private set; } 11 public IUsbDeviceRegistry Registry { get; private set; }
13 private SafeFileHandle DeviceHandle; 12 private SafeFileHandle DeviceHandle;
14 13
15 public LibUsb0Device(String path, LibUsb0Registry registry) { 14 public LibUsb0Device(String path, LibUsb0Registry registry) {
79 fixed (Byte* b = buffer) { 78 fixed (Byte* b = buffer) {
80 DeviceIoControl(DeviceHandle, LibUsbIoCtl.GET_DESCRIPTOR, ref req, LibUsbRequest.Size, (IntPtr)(b + offset), length, out ret); 79 DeviceIoControl(DeviceHandle, LibUsbIoCtl.GET_DESCRIPTOR, ref req, LibUsbRequest.Size, (IntPtr)(b + offset), length, out ret);
81 } 80 }
82 return ret; 81 return ret;
83 } 82 }
84 public override int BulkRead(byte endpoint, byte[] buffer, int offset, int length) { 83 public override int ControlTransfer(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) {
85 return PipeTransfer(endpoint, false, false, buffer, offset, length, 0); 84 if ((requestType & UsbControlRequestType.EndpointMask) == UsbControlRequestType.EndpointIn)
86 } 85 return ControlRead(requestType, request, value, index, buffer, offset, length);
87 public override int BulkWrite(byte endpoint, byte[] buffer, int offset, int length) { 86 else
88 return PipeTransfer(endpoint, true, false, buffer, offset, length, 0); 87 return ControlWrite(requestType, request, value, index, buffer, offset, length);
89 } 88 }
90 public override void BulkReset(byte endpoint) { 89 public unsafe int ControlRead(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) {
91 PipeReset(endpoint);
92 }
93 public override int InterruptRead(byte endpoint, byte[] buffer, int offset, int length) {
94 return PipeTransfer(endpoint, false, false, buffer, offset, length, 0);
95 }
96 public override int InterruptWrite(byte endpoint, byte[] buffer, int offset, int length) {
97 return PipeTransfer(endpoint, true, false, buffer, offset, length, 0);
98 }
99 public override void InterruptReset(byte endpoint) {
100 PipeReset(endpoint);
101 }
102 public unsafe override int ControlRead(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) {
103 if (buffer == null) buffer = new Byte[0]; 90 if (buffer == null) buffer = new Byte[0];
104 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length"); 91 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length");
105 int code; 92 int code;
106 LibUsbRequest req = new LibUsbRequest(); 93 LibUsbRequest req = new LibUsbRequest();
107 PrepareControlTransfer(requestType, request, value, index, length, ref req, out code); 94 PrepareControlTransfer(requestType, request, value, index, length, ref req, out code);
109 fixed (Byte* b = buffer) { 96 fixed (Byte* b = buffer) {
110 DeviceIoControl(DeviceHandle, code, ref req, LibUsbRequest.Size, (IntPtr)(b + offset), length, out ret); 97 DeviceIoControl(DeviceHandle, code, ref req, LibUsbRequest.Size, (IntPtr)(b + offset), length, out ret);
111 } 98 }
112 return ret; 99 return ret;
113 } 100 }
114 public unsafe override int ControlWrite(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { 101 public unsafe int ControlWrite(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) {
115 Byte[] inbuffer = new Byte[length + LibUsbRequest.Size]; 102 Byte[] inbuffer = new Byte[length + LibUsbRequest.Size];
116 if (length > 0) Buffer.BlockCopy(buffer, offset, inbuffer, LibUsbRequest.Size, length); 103 if (length > 0) Buffer.BlockCopy(buffer, offset, inbuffer, LibUsbRequest.Size, length);
117 int code; 104 int code;
118 fixed (Byte* inbufferp = inbuffer) 105 fixed (Byte* inbufferp = inbuffer)
119 PrepareControlTransfer(requestType, request, value, index, length, ref *((LibUsbRequest*)inbufferp), out code); 106 PrepareControlTransfer(requestType, request, value, index, length, ref *((LibUsbRequest*)inbufferp), out code);
197 break; 184 break;
198 case UsbControlRequestType.TypeReserved: 185 case UsbControlRequestType.TypeReserved:
199 default: 186 default:
200 throw new ArgumentException(String.Format("Invalid or unsupported request type: 0x{0:X8}", requestType)); 187 throw new ArgumentException(String.Format("Invalid or unsupported request type: 0x{0:X8}", requestType));
201 } 188 }
189 }
190
191 public override int PipeTransfer(Byte epnum, Byte[] buffer, int offset, int length) {
192 return PipeTransfer(epnum, (epnum & (Byte)UsbControlRequestType.EndpointMask) == (Byte)UsbControlRequestType.EndpointOut, false, buffer, offset, length, 0);
202 } 193 }
203 194
204 unsafe int PipeTransfer(Byte epnum, Boolean write, Boolean isochronous, Byte[] buffer, int offset, int length, int packetsize) { 195 unsafe int PipeTransfer(Byte epnum, Boolean write, Boolean isochronous, Byte[] buffer, int offset, int length, int packetsize) {
205 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length"); 196 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length");
206 LibUsbRequest req = new LibUsbRequest(); 197 LibUsbRequest req = new LibUsbRequest();
226 DeviceIoControl(DeviceHandle, cltCode, ref req, LibUsbRequest.Size, (IntPtr)(b + offset), Math.Min(UInt16.MaxValue, length), out ret); 217 DeviceIoControl(DeviceHandle, cltCode, ref req, LibUsbRequest.Size, (IntPtr)(b + offset), Math.Min(UInt16.MaxValue, length), out ret);
227 return ret; 218 return ret;
228 } 219 }
229 } 220 }
230 } 221 }
231 public void PipeReset(byte pipeID) { 222 public override void PipeReset(byte pipeID) {
232 LibUsbRequest req = new LibUsbRequest(); 223 LibUsbRequest req = new LibUsbRequest();
233 req.Endpoint.ID = pipeID; 224 req.Endpoint.ID = pipeID;
234 req.Timeout = UsbConstants.DEFAULT_TIMEOUT; 225 req.Timeout = UsbConstants.DEFAULT_TIMEOUT;
235 int ret; 226 int ret;
236 DeviceIoControl(DeviceHandle, LibUsbIoCtl.RESET_ENDPOINT, ref req, LibUsbRequest.Size, null, 0, out ret); 227 DeviceIoControl(DeviceHandle, LibUsbIoCtl.RESET_ENDPOINT, ref req, LibUsbRequest.Size, null, 0, out ret);
228 }
229 public override void PipeAbort(byte pipeID) {
230 LibUsbRequest req = new LibUsbRequest();
231 req.Endpoint.ID = pipeID;
232 req.Timeout = UsbConstants.DEFAULT_TIMEOUT;
233 int ret;
234 DeviceIoControl(DeviceHandle, LibUsbIoCtl.ABORT_ENDPOINT, ref req, LibUsbRequest.Size, null, 0, out ret);
237 } 235 }
238 236
239 private unsafe void DeviceIoControl(SafeHandle hDevice, int IoControlCode, [In] ref LibUsbRequest InBuffer, int nInBufferSize, Byte[] OutBuffer, int nOutBufferSize, out int pBytesReturned) { 237 private unsafe void DeviceIoControl(SafeHandle hDevice, int IoControlCode, [In] ref LibUsbRequest InBuffer, int nInBufferSize, Byte[] OutBuffer, int nOutBufferSize, out int pBytesReturned) {
240 fixed (LibUsbRequest* InBufferPtr = &InBuffer) { 238 fixed (LibUsbRequest* InBufferPtr = &InBuffer) {
241 fixed (Byte* OutBufferPtr = OutBuffer) { 239 fixed (Byte* OutBufferPtr = OutBuffer) {