Method: LIBUSB::DevHandle#control_transfer

Defined in:
lib/libusb/dev_handle.rb

#control_transfer(args = {}) {|result| ... } ⇒ Fixnum, ...

Perform a USB control transfer.

When called without a block, the transfer is done synchronously - so all events are handled internally and the sent/received data will be returned after completion or an exception will be raised.

When called with a block, the method returns immediately after submitting the transfer. You then have to ensure, that Context#handle_events is called properly. As soon as the transfer is completed, the block is called with the sent/received data in case of success or the exception instance in case of failure.

The direction of the transfer is inferred from the :bmRequestType field of the setup packet.

Parameters:

  • args (Hash) (defaults to: {})

Options Hash (args):

  • :bmRequestType (Fixnum)

    the request type field for the setup packet

  • :bRequest (Fixnum)

    the request field for the setup packet

  • :wValue (Fixnum)

    the value field for the setup packet

  • :wIndex (Fixnum)

    the index field for the setup packet

  • :dataOut (String)

    the data to send with an outgoing transfer, it is appended to the setup packet

  • :dataIn (Fixnum)

    the number of bytes expected to receive with an ingoing transfer (excluding setup packet)

  • :timeout (Fixnum)

    timeout (in millseconds) that this function should wait before giving up due to no response being received. For an unlimited timeout, use value 0. Defaults to 1000 ms.

Yield Parameters:

  • result (String, Integer, LIBUSB::Error)

    result of the transfer is yielded to the block, when the asynchronous transfer has finished

Returns:

  • (Fixnum)

    Number of bytes sent (excluding setup packet) for outgoing transfer

  • (String)

    Received data (without setup packet) for ingoing transfer

  • (self)

    When called with a block

Raises:



422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
# File 'lib/libusb/dev_handle.rb', line 422

def control_transfer(args={}, &block)
  bmRequestType = args.delete(:bmRequestType) || raise(ArgumentError, "param :bmRequestType not given")
  bRequest = args.delete(:bRequest) || raise(ArgumentError, "param :bRequest not given")
  wValue = args.delete(:wValue) || raise(ArgumentError, "param :wValue not given")
  wIndex = args.delete(:wIndex) || raise(ArgumentError, "param :wIndex not given")
  timeout = args.delete(:timeout) || 1000
  if bmRequestType&ENDPOINT_IN != 0
    dataIn = args.delete(:dataIn) || 0
    dataOut = ''
  else
    dataOut = args.delete(:dataOut) || ''
  end
  raise ArgumentError, "invalid params #{args.inspect}" unless args.empty?

  # reuse transfer struct to speed up transfer
  @control_transfer ||= ControlTransfer.new :dev_handle => self
  tr = @control_transfer
  tr.timeout = timeout
  if dataIn
    setup_data = [bmRequestType, bRequest, wValue, wIndex, dataIn].pack('CCvvv')
    tr.alloc_buffer( dataIn + CONTROL_SETUP_SIZE, setup_data )
  else
    tr.buffer = [bmRequestType, bRequest, wValue, wIndex, dataOut.bytesize, dataOut].pack('CCvvva*')
  end

  submit_transfer(tr, dataIn, CONTROL_SETUP_SIZE, &block)
end