static void config_op(MonoUsbDeviceHandle handle, byte endpoint, byte[] data, int readcnt) { int actual_length = 0; int res; byte[] recv_buf = new byte[1024]; GCHandle data_gc = GCHandle.Alloc(data, GCHandleType.Pinned); GCHandle recv_buf_gc = GCHandle.Alloc(recv_buf, GCHandleType.Pinned); MonoUsbTransferDelegate d = noop_usb_callback; MonoUsbTransfer transfer = new MonoUsbTransfer(0); wait = 0; Console.WriteLine("data_gc addr = {0}", data_gc.AddrOfPinnedObject()); Console.WriteLine("recv_buf_gc addr = {0}", recv_buf_gc.AddrOfPinnedObject()); // Execute the write operation (asynchronous). transfer.FillBulk(handle, endpoint, data_gc.AddrOfPinnedObject(), data.Length, d, recv_buf_gc.AddrOfPinnedObject(), 4000); transfer.Submit(); Thread.Sleep(300); // Execute the specified number of read operations (synchronous). for (int x = 0; x < readcnt; ++x) { res = Usb.BulkTransfer(handle, (byte)(endpoint | 0x80), recv_buf_gc.AddrOfPinnedObject(), recv_buf.Length, out actual_length, 4000); if (res != 0) { throw new Exception("config_op Usb.BulkTransfer failure"); } // Should only be here once the above transfer completes. } // Wait for the first write asynchronous to return. // Do not poll forever. Abort if it takes too long. var st = DateTime.Now; if (readcnt > 0) { while (wait == 0 && (DateTime.Now - st).TotalSeconds < 30) { Thread.Sleep(100); } } data_gc.Free(); recv_buf_gc.Free(); }
// This function originated from do_sync_bulk_transfer() // in sync.c of the Libusb-1.0 source code. private static MonoUsbError doBulkAsyncTransfer(MonoUsbDeviceHandle dev_handle, byte endpoint, byte[] buffer, int length, out int transferred, int timeout) { transferred = 0; MonoUsbTransfer transfer = new MonoUsbTransfer(0); if (transfer.IsInvalid) { return(MonoUsbError.ErrorNoMem); } MonoUsbTransferDelegate monoUsbTransferCallbackDelegate = bulkTransferCB; int[] userCompleted = new int[] { 0 }; GCHandle gcUserCompleted = GCHandle.Alloc(userCompleted, GCHandleType.Pinned); MonoUsbError e; GCHandle gcBuffer = GCHandle.Alloc(buffer, GCHandleType.Pinned); transfer.FillBulk( dev_handle, endpoint, gcBuffer.AddrOfPinnedObject(), length, monoUsbTransferCallbackDelegate, gcUserCompleted.AddrOfPinnedObject(), timeout); e = transfer.Submit(); if ((int)e < 0) { transfer.Free(); gcUserCompleted.Free(); return(e); } int r; Console.WriteLine("Transfer Submitted.."); while (userCompleted[0] == 0) { e = (MonoUsbError)(r = Usb.HandleEvents(sessionHandle)); if (r < 0) { if (e == MonoUsbError.ErrorInterrupted) { continue; } transfer.Cancel(); while (userCompleted[0] == 0) { if (Usb.HandleEvents(sessionHandle) < 0) { break; } } transfer.Free(); gcUserCompleted.Free(); return(e); } } transferred = transfer.ActualLength; e = MonoUsbApi.MonoLibUsbErrorFromTransferStatus(transfer.Status); transfer.Free(); gcUserCompleted.Free(); return(e); }