Mercurial > hg > ucis.core
annotate USBLib/Communication/LibUsbDotNet.cs @ 65:abe0d55a2201
Removed some redundant USB communication code
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Tue, 15 Oct 2013 16:19:45 +0200 |
parents | 2b24666cd759 |
children | 2d16447eff12 |
rev | line source |
---|---|
21 | 1 ???using System; |
22 | 2 using System.Collections.Generic; |
21 | 3 using System.Collections.ObjectModel; |
22 | 4 using System.IO; |
21 | 5 using System.Runtime.InteropServices; |
22 | 6 using System.Text; |
21 | 7 using System.Threading; |
22 | 8 using LibUsbDotNet.Descriptors; |
9 using LibUsbDotNet.Info; | |
21 | 10 using LibUsbDotNet.Main; |
11 using UCIS.USBLib.Communication; | |
65
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
12 using UCIS.USBLib.Descriptor; |
21 | 13 using LibUsb0Registry = UCIS.USBLib.Communication.LibUsb.LibUsb0Registry; |
14 using LibUsb1Registry = UCIS.USBLib.Communication.LibUsb1.LibUsb1Registry; | |
15 using nIUsbDevice = UCIS.USBLib.Communication.IUsbDevice; | |
16 using nIUsbInterface = UCIS.USBLib.Communication.IUsbInterface; | |
17 using WinUsbRegistry = UCIS.USBLib.Communication.WinUsb.WinUsbRegistry; | |
35
6fcedb1030bf
USBLib: Added support for USBIO driver
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
18 using USBIORegistry = UCIS.USBLib.Communication.USBIO.USBIORegistry; |
21 | 19 |
20 namespace LibUsbDotNet { | |
65
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
21 public class UsbDevice { |
21 | 22 public nIUsbInterface Device { get; private set; } |
23 public UsbDevice(nIUsbInterface dev) { | |
60
3424fa5a12c9
Updated Windows USB enumeration classes and VBoxUSB backend
Ivo Smits <Ivo@UCIS.nl>
parents:
38
diff
changeset
|
24 if (dev == null) throw new ArgumentNullException("dev"); |
21 | 25 Device = dev; |
26 } | |
27 public bool GetDescriptor(byte descriptorType, byte index, short langId, Byte[] buffer, int bufferLength, out int transferLength) { | |
28 try { | |
29 transferLength = Device.GetDescriptor(descriptorType, index, langId, buffer, 0, bufferLength); | |
30 return true; | |
31 } catch { | |
32 transferLength = 0; | |
33 return false; | |
34 } | |
35 } | |
36 public bool ControlTransfer(ref UsbSetupPacket setupPacket, Byte[] buffer, int bufferLength, out int lengthTransferred) { | |
37 if ((setupPacket.RequestType & 128) != 0) { | |
38 lengthTransferred = Device.ControlRead((UsbControlRequestType)setupPacket.RequestType, setupPacket.Request, setupPacket.Value, setupPacket.Index, buffer, 0, bufferLength); | |
39 } else { | |
40 lengthTransferred = Device.ControlWrite((UsbControlRequestType)setupPacket.RequestType, setupPacket.Request, setupPacket.Value, setupPacket.Index, buffer, 0, bufferLength); | |
41 } | |
42 return true; | |
43 } | |
44 public UsbEndpointReader OpenEndpointReader(ReadEndpointID readEndpointID, int buffersize, EndpointType endpointType) { | |
45 UsbEndpointReader reader = new UsbEndpointReader(Device, (Byte)readEndpointID, endpointType); | |
46 reader.ReadBufferSize = buffersize; | |
47 return reader; | |
48 } | |
49 public void Close() { | |
50 Device.Dispose(); | |
51 } | |
52 public UsbDeviceInfo Info { get { return new UsbDeviceInfo(this); } } | |
53 public static IList<UsbRegistry> AllDevices { | |
54 get { | |
55 List<UsbRegistry> list = new List<UsbRegistry>(); | |
56 if (Environment.OSVersion.Platform == PlatformID.Win32NT) { | |
57 foreach (IUsbDeviceRegistry reg in WinUsbRegistry.DeviceList) list.Add(new UsbRegistry(reg)); | |
58 foreach (IUsbDeviceRegistry reg in LibUsb0Registry.DeviceList) list.Add(new UsbRegistry(reg)); | |
35
6fcedb1030bf
USBLib: Added support for USBIO driver
Ivo Smits <Ivo@UCIS.nl>
parents:
22
diff
changeset
|
59 foreach (IUsbDeviceRegistry reg in USBIORegistry.DeviceList) list.Add(new UsbRegistry(reg)); |
21 | 60 } else { |
61 foreach (IUsbDeviceRegistry reg in LibUsb1Registry.DeviceList) list.Add(new UsbRegistry(reg)); | |
62 } | |
63 return list; | |
64 } | |
65 } | |
66 public bool SetConfiguration(byte config) { | |
67 nIUsbDevice dev = Device as nIUsbDevice; | |
68 if (dev == null) return false; | |
69 try { | |
70 dev.Configuration = config; | |
71 return true; | |
72 } catch { | |
73 return false; | |
74 } | |
75 } | |
76 public bool ClaimInterface(int interfaceID) { | |
77 nIUsbDevice dev = Device as nIUsbDevice; | |
78 if (dev == null) return false; | |
79 try { | |
60
3424fa5a12c9
Updated Windows USB enumeration classes and VBoxUSB backend
Ivo Smits <Ivo@UCIS.nl>
parents:
38
diff
changeset
|
80 if (dev.Configuration == 0) dev.Configuration = 1; |
21 | 81 dev.ClaimInterface(interfaceID); |
82 return true; | |
83 } catch { | |
84 return false; | |
85 } | |
86 } | |
87 public bool ReleaseInterface(int interfaceID) { | |
88 nIUsbDevice dev = Device as nIUsbDevice; | |
89 if (dev == null) return false; | |
90 try { | |
91 dev.ReleaseInterface(interfaceID); | |
92 return true; | |
93 } catch { | |
94 return false; | |
95 } | |
96 } | |
97 public IList<UsbConfigInfo> Configs { | |
98 get { | |
99 List<UsbConfigInfo> rtnConfigs = new List<UsbConfigInfo>(); | |
65
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
100 int iConfigs = Info.Descriptor.NumConfigurations; |
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
101 for (Byte iConfig = 0; iConfig < iConfigs; iConfig++) { |
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
102 UsbConfigurationDescriptor configDescriptor = UsbConfigurationDescriptor.FromDevice(Device, iConfig); |
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
103 if (configDescriptor.Length < UsbConfigurationDescriptor.Size || configDescriptor.Type != UsbDescriptorType.Configuration) |
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
104 throw new Exception("GetDeviceConfigs: USB config descriptor is invalid."); |
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
105 Byte[] cfgBuffer = new Byte[configDescriptor.TotalLength]; |
21 | 106 int iBytesTransmitted; |
38
a9c4fed19e99
USBLib: fixes in USBIO driver and LibUsbDotNet compatibility code
Ivo Smits <Ivo@UCIS.nl>
parents:
35
diff
changeset
|
107 if (!GetDescriptor((byte)UsbDescriptorType.Configuration, (byte)iConfig, 0, cfgBuffer, cfgBuffer.Length, out iBytesTransmitted)) |
21 | 108 throw new Exception("Could not read configuration descriptor"); |
65
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
109 configDescriptor = UsbConfigurationDescriptor.FromByteArray(cfgBuffer, 0, iBytesTransmitted); |
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
110 if (configDescriptor.Length < UsbConfigurationDescriptor.Size || configDescriptor.Type != UsbDescriptorType.Configuration) |
21 | 111 throw new Exception("GetDeviceConfigs: USB config descriptor is invalid."); |
112 if (configDescriptor.TotalLength != iBytesTransmitted) throw new Exception("GetDeviceConfigs: USB config descriptor length doesn't match the length received."); | |
113 List<byte[]> rawDescriptorList = new List<byte[]>(); | |
114 int iRawLengthPosition = configDescriptor.Length; | |
115 while (iRawLengthPosition < configDescriptor.TotalLength) { | |
116 byte[] rawDescriptor = new byte[cfgBuffer[iRawLengthPosition]]; | |
117 if (iRawLengthPosition + rawDescriptor.Length > iBytesTransmitted) throw new Exception("Descriptor length is out of range."); | |
118 Array.Copy(cfgBuffer, iRawLengthPosition, rawDescriptor, 0, rawDescriptor.Length); | |
119 rawDescriptorList.Add(rawDescriptor); | |
120 iRawLengthPosition += rawDescriptor.Length; | |
121 } | |
65
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
122 rtnConfigs.Add(new UsbConfigInfo(this, configDescriptor, rawDescriptorList)); |
21 | 123 } |
124 return rtnConfigs; | |
125 } | |
126 } | |
127 } | |
128 public class UsbEndpointReader : IDisposable { | |
129 public nIUsbInterface Device { get; private set; } | |
130 public Byte EndpointID { get; private set; } | |
131 public EndpointType EndpointType { get; private set; } | |
132 public Byte EpNum { get { return EndpointID; } } | |
133 public int ReadBufferSize { get; set; } | |
134 | |
135 public UsbEndpointReader(nIUsbInterface dev, byte epid, EndpointType eptype) { | |
136 Device = dev; | |
137 EndpointID = epid; | |
138 EndpointType = eptype; | |
139 ReadBufferSize = 4096; | |
140 } | |
141 public ErrorCode Read(byte[] buffer, int offset, int count, int timeout, out int transferLength) { | |
142 switch (EndpointType) { | |
143 case EndpointType.Bulk: transferLength = Device.BulkRead(EndpointID, buffer, offset, count); break; | |
144 case EndpointType.Interrupt: transferLength = Device.InterruptRead(EndpointID, buffer, offset, count); break; | |
145 default: transferLength = 0; return ErrorCode.Error; | |
146 } | |
147 return ErrorCode.Ok; | |
148 } | |
149 public void Dispose() { DataReceivedEnabled = false; } | |
150 | |
151 private bool mDataReceivedEnabled; | |
152 private Thread mReadThread; | |
153 | |
154 public virtual bool DataReceivedEnabled { | |
155 get { return mDataReceivedEnabled; } | |
156 set { | |
157 if (value != mDataReceivedEnabled) { | |
158 if (mDataReceivedEnabled) { | |
159 mReadThread.Abort(); | |
160 } else { | |
161 mDataReceivedEnabled = true; | |
162 mReadThread = new Thread(ReadDataProcess); | |
163 mReadThread.Start(); | |
164 } | |
165 } | |
166 } | |
167 } | |
168 | |
169 private void ReadDataProcess(object state) { | |
170 byte[] buffer = new byte[ReadBufferSize]; | |
171 try { | |
172 while (mDataReceivedEnabled) { | |
173 int transferLength; | |
174 Read(buffer, 0, buffer.Length, -1, out transferLength); | |
175 EventHandler<EndpointDataEventArgs> eh = DataReceived; | |
176 if (!ReferenceEquals(eh, null)) eh(this, new EndpointDataEventArgs(buffer, transferLength)); | |
177 } | |
178 } catch (Exception ex) { | |
179 if (ReadError != null) ReadError(this, new ErrorEventArgs(ex)); | |
180 } finally { | |
181 mDataReceivedEnabled = false; | |
182 } | |
183 } | |
184 | |
185 public event EventHandler<EndpointDataEventArgs> DataReceived; | |
186 public event ErrorEventHandler ReadError; | |
187 } | |
188 } | |
189 namespace LibUsbDotNet.Main { | |
190 public class EndpointDataEventArgs : EventArgs { | |
191 internal EndpointDataEventArgs(byte[] bytes, int size) { | |
192 Buffer = bytes; | |
193 Count = size; | |
194 } | |
195 public byte[] Buffer { get; private set; } | |
196 public int Count { get; private set; } | |
197 } | |
198 [StructLayout(LayoutKind.Sequential, Pack = 1)] | |
199 public struct UsbSetupPacket { | |
200 public byte RequestType; | |
201 public byte Request; | |
202 public short Value; | |
203 public short Index; | |
204 public short Length; | |
205 public UsbSetupPacket(byte requestType, byte request, short value, short index, short length) { | |
206 RequestType = requestType; | |
207 Request = request; | |
208 Value = value; | |
209 Index = index; | |
210 Length = length; | |
211 } | |
212 } | |
213 public enum UsbEndpointDirection : byte { | |
214 EndpointIn = 0x80, | |
215 EndpointOut = 0x00, | |
216 } | |
217 public enum UsbRequestType : byte { | |
218 TypeClass = (0x01 << 5), | |
219 TypeReserved = (0x03 << 5), | |
220 TypeStandard = (0x00 << 5), | |
221 TypeVendor = (0x02 << 5), | |
222 } | |
223 public enum ReadEndpointID : byte { | |
224 Ep01 = 0x81, | |
225 Ep02 = 0x82, | |
226 Ep03 = 0x83, | |
227 Ep04 = 0x84, | |
228 Ep05 = 0x85, | |
229 Ep06 = 0x86, | |
230 Ep07 = 0x87, | |
231 Ep08 = 0x88, | |
232 Ep09 = 0x89, | |
233 Ep10 = 0x8A, | |
234 Ep11 = 0x8B, | |
235 Ep12 = 0x8C, | |
236 Ep13 = 0x8D, | |
237 Ep14 = 0x8E, | |
238 Ep15 = 0x8F, | |
239 } | |
240 public enum UsbRequestRecipient : byte { | |
241 RecipDevice = 0x00, | |
242 RecipInterface = 0x01, | |
243 RecipEndpoint = 0x02, | |
244 RecipOther = 0x03, | |
245 } | |
246 public enum EndpointType : byte { | |
247 Control, | |
248 Isochronous, | |
249 Bulk, | |
250 Interrupt | |
251 } | |
252 public enum ErrorCode { | |
253 Ok = 0, | |
254 Error = 1, | |
255 } | |
256 public class UsbRegistry { | |
257 public IUsbDeviceRegistry Registry { get; private set; } | |
258 public UsbRegistry(IUsbDeviceRegistry reg) { | |
259 Registry = reg; | |
260 } | |
261 public int Vid { get { return Registry.Vid; } } | |
262 public int Pid { get { return Registry.Pid; } } | |
263 public int Rev { get { return 0; } } | |
264 public Boolean IsAlive { get { return true; } } | |
265 public Boolean Open(out UsbDevice hand) { | |
266 hand = new UsbDevice(Registry.Open()); | |
267 return true; | |
268 } | |
269 public IDictionary<String, Object> DeviceProperties { get { return Registry.DeviceProperties; } } | |
270 public String FullName { get { return Registry.FullName; } } | |
271 public String Name { get { return Registry.Name; } } | |
272 public String SymbolicName { get { return Registry.SymbolicName; } } | |
273 } | |
274 } | |
275 namespace LibUsbDotNet.Info { | |
276 public class UsbDeviceInfo { | |
277 private readonly UsbDeviceDescriptor mDeviceDescriptor; | |
278 internal UsbDevice mUsbDevice; | |
279 internal UsbDeviceInfo(UsbDevice usbDevice) { | |
280 mUsbDevice = usbDevice; | |
65
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
281 mDeviceDescriptor = UsbDeviceDescriptor.FromDevice(usbDevice.Device); |
21 | 282 } |
283 public UsbDeviceDescriptor Descriptor { get { return mDeviceDescriptor; } } | |
284 public String ManufacturerString { | |
285 get { | |
65
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
286 if (Descriptor.ManufacturerStringID == 0) return null; |
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
287 return UsbStringDescriptor.GetStringFromDevice(mUsbDevice.Device, Descriptor.ManufacturerStringID, 0); |
21 | 288 } |
289 } | |
290 public String ProductString { | |
291 get { | |
65
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
292 if (Descriptor.ProductStringID == 0) return null; |
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
293 return UsbStringDescriptor.GetStringFromDevice(mUsbDevice.Device, Descriptor.ProductStringID, 0); |
21 | 294 } |
295 } | |
296 public String SerialString { | |
297 get { | |
65
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
298 if (Descriptor.SerialNumberStringID == 0) return null; |
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
299 return UsbStringDescriptor.GetStringFromDevice(mUsbDevice.Device, Descriptor.SerialNumberStringID, 0); |
21 | 300 } |
301 } | |
302 } | |
303 public class UsbConfigInfo { | |
304 private readonly List<UsbInterfaceInfo> mInterfaceList = new List<UsbInterfaceInfo>(); | |
65
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
305 internal readonly UsbConfigurationDescriptor mUsbConfigDescriptor; |
21 | 306 internal UsbDevice mUsbDevice; |
65
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
307 internal UsbConfigInfo(UsbDevice usbDevice, UsbConfigurationDescriptor descriptor, IEnumerable<byte[]> rawDescriptors) { |
21 | 308 mUsbDevice = usbDevice; |
309 mUsbConfigDescriptor = descriptor; | |
310 UsbInterfaceInfo currentInterface = null; | |
65
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
311 foreach (Byte[] bytesRawDescriptor in rawDescriptors) { |
21 | 312 switch (bytesRawDescriptor[1]) { |
313 case (byte)UsbDescriptorType.Interface: | |
314 currentInterface = new UsbInterfaceInfo(usbDevice, bytesRawDescriptor); | |
315 mInterfaceList.Add(currentInterface); | |
316 break; | |
317 case (byte)UsbDescriptorType.Endpoint: | |
318 if (currentInterface == null) throw new Exception("Recieved and endpoint descriptor before receiving an interface descriptor."); | |
319 currentInterface.mEndpointInfo.Add(new UsbEndpointInfo(bytesRawDescriptor)); | |
320 break; | |
321 } | |
322 } | |
323 } | |
65
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
324 public UsbConfigurationDescriptor Descriptor { get { return mUsbConfigDescriptor; } } |
21 | 325 public ReadOnlyCollection<UsbInterfaceInfo> InterfaceInfoList { get { return mInterfaceList.AsReadOnly(); } } |
326 } | |
327 public class UsbInterfaceInfo { | |
328 internal readonly UsbInterfaceDescriptor mUsbInterfaceDescriptor; | |
329 internal UsbDevice mUsbDevice; | |
330 internal List<UsbEndpointInfo> mEndpointInfo = new List<UsbEndpointInfo>(); | |
331 internal UsbInterfaceInfo(UsbDevice usbDevice, byte[] descriptor) { | |
332 mUsbDevice = usbDevice; | |
65
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
333 mUsbInterfaceDescriptor = UsbInterfaceDescriptor.FromByteArray(descriptor, 0, descriptor.Length); |
21 | 334 } |
335 public UsbInterfaceDescriptor Descriptor { get { return mUsbInterfaceDescriptor; } } | |
336 public ReadOnlyCollection<UsbEndpointInfo> EndpointInfoList { get { return mEndpointInfo.AsReadOnly(); } } | |
337 } | |
338 public class UsbEndpointInfo { | |
339 internal UsbEndpointDescriptor mUsbEndpointDescriptor; | |
340 internal UsbEndpointInfo(byte[] descriptor) { | |
65
abe0d55a2201
Removed some redundant USB communication code
Ivo Smits <Ivo@UCIS.nl>
parents:
61
diff
changeset
|
341 mUsbEndpointDescriptor = UsbEndpointDescriptor.FromByteArray(descriptor, 0, descriptor.Length); |
21 | 342 } |
343 public UsbEndpointDescriptor Descriptor { | |
344 get { return mUsbEndpointDescriptor; } | |
345 } | |
346 } | |
347 } | |
348 namespace LibUsbDotNet.Descriptors { | |
349 public enum ClassCodeType : byte { | |
350 PerInterface = 0, | |
351 Audio = 1, | |
352 Comm = 2, | |
353 Hid = 3, | |
354 Printer = 7, | |
355 Ptp = 6, | |
356 MassStorage = 8, | |
357 Hub = 9, | |
358 Data = 10, | |
359 VendorSpec = 0xff | |
360 } | |
361 } |