21
|
1 ???using System; |
|
2 |
|
3 namespace UCIS.USBLib.Communication.LibUsb1 { |
|
4 public unsafe class LibUsb1Device : UsbInterface, IUsbDevice { |
|
5 libusb_device Device; |
|
6 libusb_device_handle Handle; |
|
7 //Boolean KernelDriverWasAttached = false; |
|
8 public IUsbDeviceRegistry Registry { get; private set; } |
|
9 internal LibUsb1Device(libusb_device device, LibUsb1Registry registry) { |
|
10 this.Device = device; |
|
11 this.Registry = registry; |
|
12 int ret = libusb1.libusb_open(Device, out Handle); |
|
13 if (ret != 0) throw new Exception("libusb_open returned " + ret.ToString()); |
|
14 } |
|
15 |
|
16 public override void Close() { |
|
17 if (Handle != null) Handle.Close(); |
|
18 } |
|
19 |
|
20 public override int BulkWrite(byte endpoint, byte[] buffer, int offset, int length) { |
|
21 return BulkTransfer(endpoint, buffer, offset, length); |
|
22 } |
|
23 public override int BulkRead(byte endpoint, byte[] buffer, int offset, int length) { |
|
24 return BulkTransfer(endpoint, buffer, offset, length); |
|
25 } |
|
26 private int BulkTransfer(byte endpoint, byte[] buffer, int offset, int length) { |
|
27 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length"); |
|
28 if (length == 0) return 0; |
|
29 fixed (Byte* b = buffer) { |
|
30 int ret = libusb1.libusb_bulk_transfer(Handle, endpoint, b + offset, length, out length, 0); |
|
31 if (ret < 0) throw new Exception("libusb_bulk_transfer returned " + ret.ToString()); |
|
32 } |
|
33 return length; |
|
34 } |
|
35 |
|
36 public override int InterruptWrite(byte endpoint, byte[] buffer, int offset, int length) { |
|
37 return InterruptTransfer(endpoint, buffer, offset, length); |
|
38 } |
|
39 public override int InterruptRead(byte endpoint, byte[] buffer, int offset, int length) { |
|
40 return InterruptTransfer(endpoint, buffer, offset, length); |
|
41 } |
|
42 private int InterruptTransfer(byte endpoint, byte[] buffer, int offset, int length) { |
|
43 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length"); |
|
44 if (length == 0) return 0; |
|
45 fixed (Byte* b = buffer) { |
|
46 int ret = libusb1.libusb_interrupt_transfer(Handle, endpoint, b + offset, length, out length, 0); |
|
47 if (ret < 0) throw new Exception("libusb_interrupt_transfer returned " + ret.ToString()); |
|
48 } |
|
49 return length; |
|
50 } |
|
51 |
|
52 public override int ControlWrite(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { |
|
53 return ControlTransfer(requestType, request, value, index, buffer, offset, length); |
|
54 } |
|
55 public override int ControlRead(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { |
|
56 return ControlTransfer(requestType, request, value, index, buffer, offset, length); |
|
57 } |
|
58 private int ControlTransfer(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) { |
|
59 if (buffer == null) buffer = new Byte[0]; |
|
60 if (offset < 0 || length < 0 || length > ushort.MaxValue || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length"); |
|
61 fixed (Byte* b = buffer) { |
|
62 int ret = libusb1.libusb_control_transfer(Handle, (Byte)requestType, request, (ushort)value, (ushort)index, b + offset, (ushort)length, 0); |
|
63 if (ret < 0) throw new Exception("libusb_control_transfer returned " + ret.ToString()); |
|
64 return ret; |
|
65 } |
|
66 } |
|
67 |
|
68 public override byte Configuration { |
|
69 get { return base.Configuration; } |
|
70 set { |
|
71 if (value == base.Configuration) return; |
|
72 for (int i = 0; i < 16; i++) libusb1.libusb_detach_kernel_driver(Handle, i); |
|
73 int ret = libusb1.libusb_set_configuration(Handle, value); |
|
74 if (ret != 0) throw new Exception("libusb_set_configuration returned " + ret.ToString()); |
|
75 } |
|
76 } |
|
77 public void ClaimInterface(int interfaceID) { |
|
78 int ret = libusb1.libusb_detach_kernel_driver(Handle, interfaceID); |
|
79 ret = libusb1.libusb_claim_interface(Handle, interfaceID); |
|
80 if (ret != 0) throw new Exception("libusb_claim_interface returned " + ret.ToString()); |
|
81 } |
|
82 public void ReleaseInterface(int interfaceID) { |
|
83 int ret = libusb1.libusb_release_interface(Handle, interfaceID); |
|
84 if (ret != 0) throw new Exception("libusb_release_interface returned " + ret.ToString()); |
|
85 ret = libusb1.libusb_attach_kernel_driver(Handle, interfaceID); |
|
86 } |
|
87 public void ResetDevice() { |
|
88 int ret = libusb1.libusb_reset_device(Handle); |
|
89 if (ret != 0) throw new Exception("libusb_reset_device returned " + ret.ToString()); |
|
90 } |
|
91 } |
|
92 } |