larskanis/libusb

result of control_transfer

tcurdt opened this issue · 9 comments

Based on the docs I came up with this code

require "libusb"

usb = LIBUSB::Context.new

device = usb.devices(:idVendor => 0x16d0, :idProduct => 0x0753).first

raise "device not found" if device.nil?

device.open_interface(0) do |handle|
  handle.control_transfer({
    :bmRequestType => LIBUSB::ENDPOINT_IN|LIBUSB::REQUEST_TYPE_CLASS|LIBUSB::RECIPIENT_INTERFACE,
    :bRequest => 0x01,
    :wIndex => 0,
    :wValue => 0,
    :dataIn => 1,
    :timeout => 0
  }) do |result|
    puts "result #{result}"
  end
end

but it never returns.
Does the libusb gem require eventmachine? or what am I doing wrong?

If DevHandle#control_transfer is called with a block, then the transfer will be started asynchronously and will run in the background. Therefore Context#handle_events must be called properly, so that the transfer can be completed.

However you probably want to start the control transfer in a blocking manner. So you should call:

result = handle.control_transfer(...)
puts "result #{result}"

Does the libusb gem require eventmachine?

libusb gem has some EventMachine-support, but this is optional and not active per default.

Thanks for the clarification, @larskanis.

Like this it returns immediately - but the result is just an empty string.

device.open_interface(0) do |handle|
  loop do
    result = handle.control_transfer({
      :bmRequestType => LIBUSB::ENDPOINT_IN|LIBUSB::REQUEST_TYPE_CLASS|LIBUSB::RECIPIENT_INTERFACE,
      :bRequest => 0x01,
      :wIndex => 0,
      :wValue => 0,
      :dataIn => 1,
      :timeout => 0
    })
    puts "result '#{result}' [#{result.class}]"
  end
end

Might be that the request is wrong (I will check with the manufacturer).
But with dataIn => 1 shouldn't there be at least one byte?

But with dataIn => 1 shouldn't there be at least one byte?

With dataIn => 1 you send a request for one byte, but if you get an empty string back, the device returned zero bytes only. You need to check with the manufacturer or use the USB/device documentation. Unfortunately I'm no expert regarding the USB protocol.

...but without a timeout it should wait forever (until there is one byte), no?
Why would it return with zero bytes?

@tcurdt Could you solve your USB issue?

I found a non-ruby way that works. I could try it again now in ruby - just for the fun of it.

I just googled for your USB device ids and found the following ruby implementation for it here . Is it your device?

It's the digispark pro http://digistump.com/products/109
http://digistump.com/wiki/digispark/tutorials/debugging

I was trying to get gem working https://rubygems.org/gems/digiusb/versions/1.0.5 which is at https://github.com/Bluebie/digiusb.rb

Since that didn't work so well I thought I give it try directly.

Closing, since the issue is probably solved in the meantime.