Method: LIBUSB::DevHandle#control_transfer

Defined in:
lib/libusb/dev_handle.rb

#control_transfer(bmRequestType:, bRequest:, wValue:, wIndex:, timeout: 1000, dataIn: nil, dataOut: nil, allow_device_memory: false) {|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)

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:



505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
# File 'lib/libusb/dev_handle.rb', line 505

def control_transfer(bmRequestType:,
                     bRequest:,
                     wValue:,
                     wIndex:,
                     timeout: 1000,
                     dataIn: nil,
                     dataOut: nil,
                     allow_device_memory: false,
                     &block)

  if bmRequestType&ENDPOINT_IN != 0
    raise ArgumentError, "invalid param :dataOut" unless dataOut.nil?
    dataIn ||= 0
    dataOut = ''
  else
    raise ArgumentError, "invalid param :dataIn" unless dataIn.nil?
    dataOut ||= ''
  end

  # reuse transfer struct to speed up transfer
  @control_transfer ||= ControlTransfer.new dev_handle: self, allow_device_memory: allow_device_memory
  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