Class: LIBUSB::Transfer
- Inherits:
-
Object
- Object
- LIBUSB::Transfer
- Defined in:
- lib/libusb/transfer.rb
Overview
Abstract base class for USB transfers. Use ControlTransfer, BulkTransfer, InterruptTransfer, IsochronousTransfer to do transfers.
There are convenience methods for DevHandle#bulk_transfer, DevHandle#control_transfer and DevHandle#interrupt_transfer, that fit for most use cases. Using Transfer derived classes directly, however, is needed for isochronous transfers and allows a more advanced buffer management.
Direct Known Subclasses
BulkTransfer, ControlTransfer, InterruptTransfer, IsochronousTransfer
Constant Summary
- TransferStatusToError =
{ :TRANSFER_ERROR => LIBUSB::ERROR_IO, :TRANSFER_TIMED_OUT => LIBUSB::ERROR_TIMEOUT, :TRANSFER_CANCELLED => LIBUSB::ERROR_INTERRUPTED, :TRANSFER_STALL => LIBUSB::ERROR_PIPE, :TRANSFER_NO_DEVICE => LIBUSB::ERROR_NO_DEVICE, :TRANSFER_OVERFLOW => LIBUSB::ERROR_OVERFLOW, }
Instance Method Summary (collapse)
-
- (Object) actual_buffer(offset = 0)
Retrieve the data actually transferred.
-
- (Object) actual_length
The number of bytes actually transferred.
-
- (Object) alloc_buffer(len, data = nil)
Allocate len bytes of data buffer for input transfer.
-
- (Object) buffer
Retrieve the current data buffer.
-
- (Object) buffer=(data)
Set output data that should be sent.
-
- (Object) callback=(proc)
Set the block that will be invoked when the transfer completes, fails, or is cancelled.
-
- (Object) cancel!
Asynchronously cancel a previously submitted transfer.
-
- (Object) dev_handle=(dev)
Set the handle for the device to communicate with.
-
- (Object) endpoint=(endpoint)
Set the address of a valid endpoint to communicate with.
-
- (Object) free_buffer
Clear the current data buffer.
-
- (Object) status
The status of the transfer.
-
- (Object) submit!(&block)
Submit a transfer.
-
- (Object) submit_and_wait
Submit the transfer and wait until the transfer completes or fails.
-
- (Object) submit_and_wait!
Submit the transfer and wait until the transfer completes or fails.
-
- (Object) timeout=(value)
Timeout for this transfer in millseconds.
Instance Method Details
- (Object) actual_buffer(offset = 0)
Retrieve the data actually transferred.
102 103 104 |
# File 'lib/libusb/transfer.rb', line 102 def actual_buffer(offset=0) @transfer[:buffer].get_bytes(offset, @transfer[:actual_length]) end |
- (Object) actual_length
The number of bytes actually transferred.
95 96 97 |
# File 'lib/libusb/transfer.rb', line 95 def actual_length @transfer[:actual_length] end |
- (Object) alloc_buffer(len, data = nil)
Allocate len bytes of data buffer for input transfer.
84 85 86 87 88 89 90 91 92 |
# File 'lib/libusb/transfer.rb', line 84 def alloc_buffer(len, data=nil) if !@buffer || len>@buffer.size free_buffer @buffer = FFI::MemoryPointer.new(len, 1, false) end @buffer.put_bytes(0, data) if data @transfer[:buffer] = @buffer @transfer[:length] = len end |
- (Object) buffer
Retrieve the current data buffer.
66 67 68 |
# File 'lib/libusb/transfer.rb', line 66 def buffer @transfer[:buffer].read_string(@transfer[:length]) end |
- (Object) buffer=(data)
Set output data that should be sent.
55 56 57 58 59 60 61 62 63 |
# File 'lib/libusb/transfer.rb', line 55 def buffer=(data) if !@buffer || data.bytesize>@buffer.size free_buffer @buffer = FFI::MemoryPointer.new(data.bytesize, 1, false) end @buffer.put_bytes(0, data) @transfer[:buffer] = @buffer @transfer[:length] = data.bytesize end |
- (Object) callback=(proc)
Set the block that will be invoked when the transfer completes, fails, or is cancelled.
110 111 112 113 114 115 116 117 |
# File 'lib/libusb/transfer.rb', line 110 def callback=(proc) # Save proc to instance variable so that GC doesn't free # the proc object before the transfer. @callback_proc = proc do |pTrans| proc.call(self) end @transfer[:callback] = @callback_proc end |
- (Object) cancel!
Asynchronously cancel a previously submitted transfer.
This function returns immediately, but this does not indicate cancellation is complete. Your callback function will be invoked at some later time with a transfer status of :TRANSFER_CANCELLED.
149 150 151 152 |
# File 'lib/libusb/transfer.rb', line 149 def cancel! res = Call.libusb_cancel_transfer( @transfer ) LIBUSB.raise_error res, "in libusb_cancel_transfer" if res!=0 end |
- (Object) dev_handle=(dev)
Set the handle for the device to communicate with.
36 37 38 39 |
# File 'lib/libusb/transfer.rb', line 36 def dev_handle=(dev) @dev_handle = dev @transfer[:dev_handle] = @dev_handle.pHandle end |
- (Object) endpoint=(endpoint)
Set the address of a valid endpoint to communicate with.
49 50 51 52 |
# File 'lib/libusb/transfer.rb', line 49 def endpoint=(endpoint) endpoint = endpoint.bEndpointAddress if endpoint.respond_to? :bEndpointAddress @transfer[:endpoint] = endpoint end |
- (Object) free_buffer
Clear the current data buffer.
71 72 73 74 75 76 77 78 |
# File 'lib/libusb/transfer.rb', line 71 def free_buffer if @buffer @buffer.free @buffer = nil @transfer[:buffer] = nil @transfer[:length] = 0 end end |
- (Object) status
The status of the transfer.
Only for use within transfer callback function or after the callback was called.
If this is an isochronous transfer, this field may read :TRANSFER_COMPLETED even if there were errors in the frames. Use the status field in each packet to determine if errors occurred.
126 127 128 |
# File 'lib/libusb/transfer.rb', line 126 def status @transfer[:status] end |
- (Object) submit!(&block)
Submit a transfer.
This function will fire off the USB transfer and then return immediately. This method can be called with block. It is called when the transfer completes, fails, or is cancelled.
135 136 137 138 139 140 141 142 |
# File 'lib/libusb/transfer.rb', line 135 def submit!(&block) self.callback = block if block_given? # puts "submit transfer #{@transfer.inspect} buffer: #{@transfer[:buffer].inspect} length: #{@transfer[:length].inspect} status: #{@transfer[:status].inspect} callback: #{@transfer[:callback].inspect} dev_handle: #{@transfer[:dev_handle].inspect}" res = Call.libusb_submit_transfer( @transfer ) LIBUSB.raise_error res, "in libusb_submit_transfer" if res!=0 end |
- (Object) submit_and_wait
Submit the transfer and wait until the transfer completes or fails.
Inspect #status to check for transfer errors.
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/libusb/transfer.rb', line 166 def submit_and_wait @completion_flag.completed = false submit! do |tr2| @completion_flag.completed = true end until @completion_flag.completed? begin @dev_handle.device.context.handle_events nil, @completion_flag rescue ERROR_INTERRUPTED next rescue LIBUSB::Error cancel! until @completion_flag.completed? @dev_handle.device.context.handle_events nil, @completion_flag end raise end end end |
- (Object) submit_and_wait!
Submit the transfer and wait until the transfer completes or fails.
A proper Error is raised, in case the transfer did not complete.
190 191 192 193 194 |
# File 'lib/libusb/transfer.rb', line 190 def submit_and_wait! submit_and_wait raise( TransferStatusToError[status] || ERROR_OTHER, "error #{status}") unless status==:TRANSFER_COMPLETED end |
- (Object) timeout=(value)
Timeout for this transfer in millseconds.
A value of 0 indicates no timeout.
44 45 46 |
# File 'lib/libusb/transfer.rb', line 44 def timeout=(value) @transfer[:timeout] = value end |