comparison USBLib/Communication/USBIO/USBIODevice.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 abe0d55a2201
children e811297f5aa4
comparison
equal deleted inserted replaced
66:b7bc27c6734e 67:2d16447eff12
26 static readonly int IOCTL_USBIO_CLASS_OR_VENDOR_IN_REQUEST = _USBIO_IOCTL_CODE(12, METHOD_OUT_DIRECT); 26 static readonly int IOCTL_USBIO_CLASS_OR_VENDOR_IN_REQUEST = _USBIO_IOCTL_CODE(12, METHOD_OUT_DIRECT);
27 static readonly int IOCTL_USBIO_CLASS_OR_VENDOR_OUT_REQUEST = _USBIO_IOCTL_CODE(13, METHOD_IN_DIRECT); 27 static readonly int IOCTL_USBIO_CLASS_OR_VENDOR_OUT_REQUEST = _USBIO_IOCTL_CODE(13, METHOD_IN_DIRECT);
28 static readonly int IOCTL_USBIO_RESET_DEVICE = _USBIO_IOCTL_CODE(21, METHOD_BUFFERED); 28 static readonly int IOCTL_USBIO_RESET_DEVICE = _USBIO_IOCTL_CODE(21, METHOD_BUFFERED);
29 static readonly int IOCTL_USBIO_BIND_PIPE = _USBIO_IOCTL_CODE(30, METHOD_BUFFERED); 29 static readonly int IOCTL_USBIO_BIND_PIPE = _USBIO_IOCTL_CODE(30, METHOD_BUFFERED);
30 static readonly int IOCTL_USBIO_RESET_PIPE = _USBIO_IOCTL_CODE(32, METHOD_BUFFERED); 30 static readonly int IOCTL_USBIO_RESET_PIPE = _USBIO_IOCTL_CODE(32, METHOD_BUFFERED);
31 static readonly int IOCTL_USBIO_ABORT_PIPE = _USBIO_IOCTL_CODE(33, METHOD_BUFFERED);
31 32
32 [DllImport("kernel32.dll", SetLastError = true)] 33 [DllImport("kernel32.dll", SetLastError = true)]
33 static unsafe extern bool ReadFile(SafeFileHandle hFile, byte* lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped); 34 static unsafe extern bool ReadFile(SafeFileHandle hFile, byte* lpBuffer, uint nNumberOfBytesToRead, out uint lpNumberOfBytesRead, IntPtr lpOverlapped);
34 [DllImport("kernel32.dll", SetLastError = true)] 35 [DllImport("kernel32.dll", SetLastError = true)]
35 static unsafe extern bool WriteFile(SafeFileHandle hFile, byte* lpBuffer, uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten, IntPtr lpOverlapped); 36 static unsafe extern bool WriteFile(SafeFileHandle hFile, byte* lpBuffer, uint nNumberOfBytesToWrite, out uint lpNumberOfBytesWritten, IntPtr lpOverlapped);
148 USBIO_DESCRIPTOR_REQUEST req = new USBIO_DESCRIPTOR_REQUEST() { DescriptorType = descriptorType, DescriptorIndex = index, LanguageId = langId, Recipient = USBIO_REQUEST_RECIPIENT.Device }; 149 USBIO_DESCRIPTOR_REQUEST req = new USBIO_DESCRIPTOR_REQUEST() { DescriptorType = descriptorType, DescriptorIndex = index, LanguageId = langId, Recipient = USBIO_REQUEST_RECIPIENT.Device };
149 fixed (Byte* b = buffer) { 150 fixed (Byte* b = buffer) {
150 return DeviceIoControl(DeviceHandle, IOCTL_USBIO_GET_DESCRIPTOR, (IntPtr)(&req), sizeof(USBIO_DESCRIPTOR_REQUEST), (IntPtr)(b + offset), length); 151 return DeviceIoControl(DeviceHandle, IOCTL_USBIO_GET_DESCRIPTOR, (IntPtr)(&req), sizeof(USBIO_DESCRIPTOR_REQUEST), (IntPtr)(b + offset), length);
151 } 152 }
152 } 153 }
153 public override int BulkRead(byte endpoint, byte[] buffer, int offset, int length) { 154 public override unsafe int ControlTransfer(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) {
154 return PipeRead(endpoint, buffer, offset, length);
155 }
156 public override int BulkWrite(byte endpoint, byte[] buffer, int offset, int length) {
157 return PipeWrite(endpoint, buffer, offset, length);
158 }
159 public override void BulkReset(byte endpoint) {
160 PipeReset(endpoint);
161 }
162 public override int InterruptRead(byte endpoint, byte[] buffer, int offset, int length) {
163 return PipeRead(endpoint, buffer, offset, length);
164 }
165 public override int InterruptWrite(byte endpoint, byte[] buffer, int offset, int length) {
166 return PipeWrite(endpoint, buffer, offset, length);
167 }
168 public override void InterruptReset(byte endpoint) {
169 PipeReset(endpoint);
170 }
171 public unsafe override int ControlRead(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) {
172 return ControlTransfer(requestType, request, value, index, buffer, offset, length);
173 }
174 public override int ControlWrite(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) {
175 return ControlTransfer(requestType, request, value, index, buffer, offset, length);
176 }
177 private unsafe int ControlTransfer(UsbControlRequestType requestType, byte request, short value, short index, byte[] buffer, int offset, int length) {
178 if (buffer == null) { 155 if (buffer == null) {
179 if (offset != 0 || length != 0) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length"); 156 if (offset != 0 || length != 0) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length");
180 } else { 157 } else {
181 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length"); 158 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length");
182 } 159 }
243 else Array.Resize(ref PipeHandlesOut, epidx + 1); 220 else Array.Resize(ref PipeHandlesOut, epidx + 1);
244 PipeHandlesOut[epidx] = handle; 221 PipeHandlesOut[epidx] = handle;
245 return handle; 222 return handle;
246 } 223 }
247 } 224 }
248 unsafe int PipeRead(Byte epnum, Byte[] buffer, int offset, int length) { 225 public unsafe override int PipeTransfer(Byte epnum, Byte[] buffer, int offset, int length) {
249 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length"); 226 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length");
250 SafeFileHandle handle = GetHandleForPipe(epnum); 227 SafeFileHandle handle = GetHandleForPipe(epnum);
251 uint ret; 228 uint ret;
252 fixed (Byte* b = buffer) { 229 fixed (Byte* b = buffer) {
253 if (!ReadFile(handle, b + offset, (uint)length, out ret, IntPtr.Zero)) throw new Win32Exception(Marshal.GetLastWin32Error()); 230 Boolean success;
231 if ((epnum & (Byte)UsbControlRequestType.EndpointMask) == (Byte)UsbControlRequestType.EndpointIn)
232 success = ReadFile(handle, b + offset, (uint)length, out ret, IntPtr.Zero);
233 else
234 success = WriteFile(handle, b + offset, (uint)length, out ret, IntPtr.Zero);
235 if (!success) throw new Win32Exception(Marshal.GetLastWin32Error());
254 } 236 }
255 return (int)ret; 237 return (int)ret;
256 } 238 }
257 unsafe int PipeWrite(Byte epnum, Byte[] buffer, int offset, int length) { 239 public override void PipeReset(byte pipeID) {
258 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length");
259 SafeFileHandle handle = GetHandleForPipe(epnum);
260 uint ret;
261 fixed (Byte* b = buffer) {
262 if (!WriteFile(handle, b + offset, (uint)length, out ret, IntPtr.Zero)) throw new Win32Exception(Marshal.GetLastWin32Error());
263 }
264 return (int)ret;
265 }
266 public void PipeReset(byte pipeID) {
267 SafeFileHandle handle = GetHandleForPipe(pipeID); 240 SafeFileHandle handle = GetHandleForPipe(pipeID);
268 DeviceIoControl(handle, IOCTL_USBIO_RESET_PIPE, IntPtr.Zero, 0, IntPtr.Zero, 0); 241 DeviceIoControl(handle, IOCTL_USBIO_RESET_PIPE, IntPtr.Zero, 0, IntPtr.Zero, 0);
242 }
243 public override void PipeAbort(byte pipeID) {
244 SafeFileHandle handle = GetHandleForPipe(pipeID);
245 DeviceIoControl(handle, IOCTL_USBIO_ABORT_PIPE, IntPtr.Zero, 0, IntPtr.Zero, 0);
269 } 246 }
270 247
271 private unsafe int DeviceIoControl(SafeHandle hDevice, int IoControlCode, IntPtr InBuffer, int nInBufferSize, IntPtr OutBuffer, int nOutBufferSize) { 248 private unsafe int DeviceIoControl(SafeHandle hDevice, int IoControlCode, IntPtr InBuffer, int nInBufferSize, IntPtr OutBuffer, int nOutBufferSize) {
272 int pBytesReturned; 249 int pBytesReturned;
273 if (Kernel32.DeviceIoControl(hDevice, IoControlCode, InBuffer, nInBufferSize, OutBuffer, nOutBufferSize, out pBytesReturned, null)) 250 if (Kernel32.DeviceIoControl(hDevice, IoControlCode, InBuffer, nInBufferSize, OutBuffer, nOutBufferSize, out pBytesReturned, null))
274 return pBytesReturned; 251 return pBytesReturned;
275 throw new Win32Exception(Marshal.GetLastWin32Error()); 252 throw new Win32Exception(Marshal.GetLastWin32Error());
276 } 253 }
277 254
278 public override UsbPipeStream GetBulkStream(byte endpoint) { 255 public override UsbPipeStream GetPipeStream(byte endpoint) {
279 return new PipeStream(this, endpoint, false, GetHandleForPipe(endpoint)); 256 return new PipeStream(this, endpoint, GetHandleForPipe(endpoint));
280 }
281 public override UsbPipeStream GetInterruptStream(byte endpoint) {
282 return new PipeStream(this, endpoint, true, GetHandleForPipe(endpoint));
283 } 257 }
284 258
285 class PipeStream : UsbPipeStream { 259 class PipeStream : UsbPipeStream {
286 private SafeFileHandle Handle; 260 private SafeFileHandle Handle;
287 public PipeStream(IUsbInterface device, Byte endpoint, Boolean interrupt, SafeFileHandle handle) : base(device, endpoint, interrupt) { 261 public PipeStream(IUsbInterface device, Byte endpoint, SafeFileHandle handle) : base(device, endpoint) {
288 this.Handle = handle; 262 this.Handle = handle;
289 } 263 }
290 264
291 public unsafe override void Write(byte[] buffer, int offset, int length) { 265 public unsafe override void Write(byte[] buffer, int offset, int length) {
292 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length"); 266 if (offset < 0 || length < 0 || offset + length > buffer.Length) throw new ArgumentOutOfRangeException("length", "The specified offset and length exceed the buffer length");