libusb 0.6.4-x86-mingw32 → 0.7.0-x86-mingw32

Sign up to get free protection for your applications and to get access to all the features.
@@ -372,19 +372,22 @@ module LIBUSB
372
372
  # @yieldparam [String, Integer, LIBUSB::Error] result result of the transfer is yielded to the block,
373
373
  # when the asynchronous transfer has finished
374
374
  # @raise [ArgumentError, LIBUSB::Error] in case of failure
375
- def bulk_transfer(args={}, &block)
376
- timeout = args.delete(:timeout) || 1000
377
- endpoint = args.delete(:endpoint) || raise(ArgumentError, "no endpoint given")
375
+ def bulk_transfer(timeout: 1000,
376
+ endpoint:,
377
+ dataIn: nil,
378
+ dataOut: nil,
379
+ allow_device_memory: false,
380
+ &block)
381
+
378
382
  endpoint = endpoint.bEndpointAddress if endpoint.respond_to? :bEndpointAddress
379
383
  if endpoint&ENDPOINT_IN != 0
380
- dataIn = args.delete(:dataIn) || raise(ArgumentError, "no :dataIn given for bulk read")
384
+ dataIn || raise(ArgumentError, "no :dataIn given for bulk read")
381
385
  else
382
- dataOut = args.delete(:dataOut) || raise(ArgumentError, "no :dataOut given for bulk write")
386
+ dataOut || raise(ArgumentError, "no :dataOut given for bulk write")
383
387
  end
384
- raise ArgumentError, "invalid params #{args.inspect}" unless args.empty?
385
388
 
386
389
  # reuse transfer struct to speed up transfer
387
- @bulk_transfer ||= BulkTransfer.new dev_handle: self, allow_device_memory: true
390
+ @bulk_transfer ||= BulkTransfer.new dev_handle: self, allow_device_memory: allow_device_memory
388
391
  tr = @bulk_transfer
389
392
  tr.endpoint = endpoint
390
393
  tr.timeout = timeout
@@ -440,19 +443,21 @@ module LIBUSB
440
443
  # @yieldparam [String, Integer, LIBUSB::Error] result result of the transfer is yielded to the block,
441
444
  # when the asynchronous transfer has finished
442
445
  # @raise [ArgumentError, LIBUSB::Error] in case of failure
443
- def interrupt_transfer(args={}, &block)
444
- timeout = args.delete(:timeout) || 1000
445
- endpoint = args.delete(:endpoint) || raise(ArgumentError, "no endpoint given")
446
+ def interrupt_transfer(timeout: 1000,
447
+ endpoint:,
448
+ dataIn: nil,
449
+ dataOut: nil,
450
+ allow_device_memory: false,
451
+ &block)
446
452
  endpoint = endpoint.bEndpointAddress if endpoint.respond_to? :bEndpointAddress
447
453
  if endpoint&ENDPOINT_IN != 0
448
- dataIn = args.delete(:dataIn) || raise(ArgumentError, "no :dataIn given for interrupt read")
454
+ dataIn || raise(ArgumentError, "no :dataIn given for interrupt read")
449
455
  else
450
- dataOut = args.delete(:dataOut) || raise(ArgumentError, "no :dataOut given for interrupt write")
456
+ dataOut || raise(ArgumentError, "no :dataOut given for interrupt write")
451
457
  end
452
- raise ArgumentError, "invalid params #{args.inspect}" unless args.empty?
453
458
 
454
459
  # reuse transfer struct to speed up transfer
455
- @interrupt_transfer ||= InterruptTransfer.new dev_handle: self, allow_device_memory: true
460
+ @interrupt_transfer ||= InterruptTransfer.new dev_handle: self, allow_device_memory: allow_device_memory
456
461
  tr = @interrupt_transfer
457
462
  tr.endpoint = endpoint
458
463
  tr.timeout = timeout
@@ -497,22 +502,27 @@ module LIBUSB
497
502
  # @yieldparam [String, Integer, LIBUSB::Error] result result of the transfer is yielded to the block,
498
503
  # when the asynchronous transfer has finished
499
504
  # @raise [ArgumentError, LIBUSB::Error] in case of failure
500
- def control_transfer(args={}, &block)
501
- bmRequestType = args.delete(:bmRequestType) || raise(ArgumentError, "param :bmRequestType not given")
502
- bRequest = args.delete(:bRequest) || raise(ArgumentError, "param :bRequest not given")
503
- wValue = args.delete(:wValue) || raise(ArgumentError, "param :wValue not given")
504
- wIndex = args.delete(:wIndex) || raise(ArgumentError, "param :wIndex not given")
505
- timeout = args.delete(:timeout) || 1000
505
+ def control_transfer(bmRequestType:,
506
+ bRequest:,
507
+ wValue:,
508
+ wIndex:,
509
+ timeout: 1000,
510
+ dataIn: nil,
511
+ dataOut: nil,
512
+ allow_device_memory: false,
513
+ &block)
514
+
506
515
  if bmRequestType&ENDPOINT_IN != 0
507
- dataIn = args.delete(:dataIn) || 0
516
+ raise ArgumentError, "invalid param :dataOut" unless dataOut.nil?
517
+ dataIn ||= 0
508
518
  dataOut = ''
509
519
  else
510
- dataOut = args.delete(:dataOut) || ''
520
+ raise ArgumentError, "invalid param :dataIn" unless dataIn.nil?
521
+ dataOut ||= ''
511
522
  end
512
- raise ArgumentError, "invalid params #{args.inspect}" unless args.empty?
513
523
 
514
524
  # reuse transfer struct to speed up transfer
515
- @control_transfer ||= ControlTransfer.new dev_handle: self, allow_device_memory: true
525
+ @control_transfer ||= ControlTransfer.new dev_handle: self, allow_device_memory: allow_device_memory
516
526
  tr = @control_transfer
517
527
  tr.timeout = timeout
518
528
  if dataIn
data/lib/libusb/device.rb CHANGED
@@ -21,24 +21,27 @@ module LIBUSB
21
21
  # Devices of the system can be obtained with {Context#devices} .
22
22
  class Device
23
23
  include Comparable
24
+ include ContextReference
24
25
 
25
26
  # @return [Context] the context this device belongs to.
26
27
  attr_reader :context
27
28
 
28
29
  def initialize context, pDev
29
30
  @context = context
30
- def pDev.unref_device(id)
31
- Call.libusb_unref_device(self)
32
- end
33
- ObjectSpace.define_finalizer(self, pDev.method(:unref_device))
34
- Call.libusb_ref_device(pDev)
35
31
  @pDev = pDev
32
+ register_context(context.instance_variable_get(:@ctx), :libusb_unref_device)
33
+ Call.libusb_ref_device(pDev)
36
34
 
37
35
  @pDevDesc = Call::DeviceDescriptor.new
38
36
  res = Call.libusb_get_device_descriptor(@pDev, @pDevDesc)
39
37
  LIBUSB.raise_error res, "in libusb_get_device_descriptor" if res!=0
40
38
  end
41
39
 
40
+ # The pointer for ContextReference
41
+ private def pointer
42
+ @pDev
43
+ end
44
+
42
45
  # Open the device and obtain a device handle.
43
46
  #
44
47
  # A handle allows you to perform I/O on the device in question.
@@ -160,6 +163,44 @@ module LIBUSB
160
163
  res
161
164
  end
162
165
 
166
+ if Call.respond_to?(:libusb_get_max_alt_packet_size)
167
+
168
+ # Calculate the maximum packet size which a specific endpoint is capable of
169
+ # sending or receiving in the duration of 1 microframe
170
+ #
171
+ # Only the active configuration is examined. The calculation is based on the
172
+ # wMaxPacketSize field in the endpoint descriptor as described in section
173
+ # 9.6.6 in the USB 2.0 specifications.
174
+ #
175
+ # If acting on an isochronous or interrupt endpoint, this function will
176
+ # multiply the value found in bits 0:10 by the number of transactions per
177
+ # microframe (determined by bits 11:12). Otherwise, this function just
178
+ # returns the numeric value found in bits 0:10. For USB 3.0 device, it
179
+ # will attempts to retrieve the Endpoint Companion Descriptor to return
180
+ # wBytesPerInterval.
181
+ #
182
+ # This function is useful for setting up isochronous transfers, for example
183
+ # you might pass the return value from this function to
184
+ # +IsochronousTransfer.packet_lengths=+ in order to set the length field of every
185
+ # isochronous packet in a transfer.
186
+ #
187
+ # Available since libusb-1.0.27.
188
+ #
189
+ # @param [Interface, Fixnum] interface the interface or its bInterfaceNumber of the interface the endpoint belongs to
190
+ # @param [Setting, Fixnum] alternate_setting the alternate setting or its bAlternateSetting
191
+ # @param [Endpoint, Fixnum] endpoint (address of) the endpoint in question
192
+ # @return [Fixnum] the maximum packet size which can be sent/received on this endpoint
193
+ # @see max_iso_packet_size
194
+ def max_alt_packet_size(interface, alternate_setting, endpoint)
195
+ interface = interface.bInterfaceNumber if interface.respond_to? :bInterfaceNumber
196
+ alternate_setting = alternate_setting.bAlternateSetting if alternate_setting.respond_to? :bAlternateSetting
197
+ endpoint = endpoint.bEndpointAddress if endpoint.respond_to? :bEndpointAddress
198
+ res = Call.libusb_get_max_alt_packet_size(@pDev, interface, alternate_setting, endpoint)
199
+ LIBUSB.raise_error res, "in libusb_get_max_alt_packet_size" unless res>=0
200
+ res
201
+ end
202
+ end
203
+
163
204
  # Calculate the maximum packet size which a specific endpoint is capable is
164
205
  # sending or receiving in the duration of 1 microframe.
165
206
  #
@@ -179,6 +220,7 @@ module LIBUSB
179
220
  #
180
221
  # @param [Endpoint, Fixnum] endpoint (address of) the endpoint in question
181
222
  # @return [Fixnum] the maximum packet size which can be sent/received on this endpoint
223
+ # @see max_alt_packet_size
182
224
  def max_iso_packet_size(endpoint)
183
225
  endpoint = endpoint.bEndpointAddress if endpoint.respond_to? :bEndpointAddress
184
226
  res = Call.libusb_get_max_iso_packet_size(@pDev, endpoint)
@@ -310,7 +352,7 @@ module LIBUSB
310
352
  def manufacturer
311
353
  return @manufacturer if defined? @manufacturer
312
354
  @manufacturer = try_string_descriptor_ascii(self.iManufacturer)
313
- @manufacturer.strip! if @manufacturer
355
+ @manufacturer = @manufacturer.strip if @manufacturer
314
356
  @manufacturer
315
357
  end
316
358
 
@@ -319,7 +361,7 @@ module LIBUSB
319
361
  def product
320
362
  return @product if defined? @product
321
363
  @product = try_string_descriptor_ascii(self.iProduct)
322
- @product.strip! if @product
364
+ @product = @product.strip if @product
323
365
  @product
324
366
  end
325
367
 
@@ -328,7 +370,7 @@ module LIBUSB
328
370
  def serial_number
329
371
  return @serial_number if defined? @serial_number
330
372
  @serial_number = try_string_descriptor_ascii(self.iSerialNumber)
331
- @serial_number.strip! if @serial_number
373
+ @serial_number = @serial_number.strip if @serial_number
332
374
  @serial_number
333
375
  end
334
376
 
@@ -181,13 +181,14 @@ module LIBUSB
181
181
  # @return [SsCompanion]
182
182
  def ss_companion
183
183
  ep_comp = FFI::MemoryPointer.new :pointer
184
+ ctx = device.context.instance_variable_get(:@ctx)
184
185
  res = Call.libusb_get_ss_endpoint_companion_descriptor(
185
- device.context.instance_variable_get(:@ctx),
186
+ ctx,
186
187
  pointer,
187
188
  ep_comp
188
189
  )
189
190
  LIBUSB.raise_error res, "in libusb_get_ss_endpoint_companion_descriptor" if res!=0
190
- SsCompanion.new ep_comp.read_pointer
191
+ SsCompanion.new ctx, ep_comp.read_pointer
191
192
  end
192
193
  end
193
194
  end
@@ -62,6 +62,10 @@ class Context
62
62
  @eventmachine_attached_fds.each do |fd, watcher|
63
63
  watcher.detach
64
64
  end
65
+
66
+ # Deregister callbacks
67
+ on_pollfd_added
68
+ on_pollfd_removed
65
69
  end
66
70
 
67
71
  class EMPollfdHandler < EventMachine::Connection
@@ -118,7 +122,7 @@ class DevHandle
118
122
  include EM::Deferrable
119
123
 
120
124
  def initialize(opts, dev_handle, transfer_method)
121
- dev_handle.send(transfer_method, opts) do |res|
125
+ dev_handle.send(transfer_method, **opts) do |res|
122
126
  EM.next_tick do
123
127
  if res.kind_of?(LIBUSB::Error)
124
128
  fail res
@@ -134,7 +138,7 @@ class DevHandle
134
138
  #
135
139
  # @see Context#eventmachine_register
136
140
  # DevHandle#interrupt_transfer
137
- def eventmachine_interrupt_transfer(opts={})
141
+ def eventmachine_interrupt_transfer(**opts)
138
142
  eventmachine_transfer(opts, :interrupt_transfer)
139
143
  end
140
144
 
@@ -151,7 +155,7 @@ class DevHandle
151
155
  #
152
156
  # @see Context#eventmachine_register
153
157
  # DevHandle#bulk_transfer
154
- def eventmachine_bulk_transfer(opts={})
158
+ def eventmachine_bulk_transfer(**opts)
155
159
  eventmachine_transfer(opts, :bulk_transfer)
156
160
  end
157
161
 
@@ -171,7 +175,7 @@ class DevHandle
171
175
  #
172
176
  # @see Context#eventmachine_register
173
177
  # DevHandle#control_transfer
174
- def eventmachine_control_transfer(opts={})
178
+ def eventmachine_control_transfer(**opts)
175
179
  eventmachine_transfer(opts, :control_transfer)
176
180
  end
177
181
 
@@ -66,7 +66,7 @@ module LIBUSB
66
66
  yield if block_given?
67
67
  rescue
68
68
  Bundler.ui.error "Untagging #{version_tag} due to error."
69
- sh_with_code "git tag -d #{version_tag}"
69
+ sh "git tag -d #{version_tag}"
70
70
  raise
71
71
  end
72
72
 
@@ -87,9 +87,9 @@ module LIBUSB
87
87
 
88
88
  self.ruby_platform = ruby_platform
89
89
  self.recipe = LIBUSB::LibusbRecipe.new
90
- recipe.host = host_platform
91
- recipe.configure_options << "--host=#{recipe.host}"
92
- recipe.configure_options << "CC=#{recipe.host}-gcc -static-libgcc" if recipe.host =~ /mingw/
90
+ recipe.host = ruby_platform
91
+ recipe.configure_options << "--host=#{host_platform}"
92
+ recipe.configure_options << "CC=#{host_platform}-gcc -static-libgcc" if recipe.host =~ /mingw/
93
93
  self.libusb_dll = Pathname.new(recipe.path) + libusb_dllname
94
94
 
95
95
  file libusb_dll do
@@ -98,8 +98,11 @@ module LIBUSB
98
98
 
99
99
  task "libusb_dll:#{ruby_platform}" => libusb_dll
100
100
 
101
- desc 'Cross compile libusb for win32'
102
- task :cross => [ "libusb_dll:#{ruby_platform}" ] do |t|
101
+ desc 'Cross compile libusb for all targets'
102
+ task :cross => "cross:#{ruby_platform}"
103
+
104
+ desc "Cross compile libusb for #{ruby_platform}"
105
+ task "cross:#{ruby_platform}" => [ "libusb_dll:#{ruby_platform}" ] do |t|
103
106
  spec = Gem::Specification::load("libusb.gemspec").dup
104
107
  spec.platform = Gem::Platform.new(ruby_platform)
105
108
  spec.extensions = []
@@ -11,7 +11,8 @@ module LIBUSB
11
11
  def initialize
12
12
  super("libusb", LIBUSB_VERSION)
13
13
  self.target = File.join(ROOT, "ports")
14
- self.files = [url: LIBUSB_SOURCE_URI, sha1: LIBUSB_SOURCE_SHA1]
14
+ self.files = [url: LIBUSB_SOURCE_URI, sha256: LIBUSB_SOURCE_SHA256]
15
+ self.patch_files = Dir[File.join(ROOT, "patches", self.name, self.version, "*.patch")].sort
15
16
  self.configure_options = []
16
17
  end
17
18
 
@@ -24,7 +25,5 @@ module LIBUSB
24
25
  self.activate
25
26
  self
26
27
  end
27
-
28
- public :files_hashs
29
28
  end
30
29
  end
@@ -19,13 +19,21 @@ module LIBUSB
19
19
  # A structure representing the superspeed endpoint companion descriptor.
20
20
  #
21
21
  # This descriptor is documented in section 9.6.7 of the USB 3.0 specification. All multiple-byte fields are represented in host-endian format.
22
- class SsCompanion < FFI::ManagedStruct
22
+ class SsCompanion < FFI::Struct
23
+ include ContextReference
24
+
23
25
  layout :bLength, :uint8,
24
26
  :bDescriptorType, :uint8,
25
27
  :bMaxBurst, :uint8,
26
28
  :bmAttributes, :uint8,
27
29
  :wBytesPerInterval, :uint16
28
30
 
31
+ def initialize(ctx, *args)
32
+ super(*args)
33
+
34
+ register_context(ctx, :libusb_free_ss_endpoint_companion_descriptor)
35
+ end
36
+
29
37
  # Size of this descriptor (in bytes)
30
38
  def bLength
31
39
  self[:bLength]
@@ -60,10 +68,5 @@ module LIBUSB
60
68
  def inspect
61
69
  "\#<#{self.class} burst: #{bMaxBurst} attrs: #{bmAttributes}>"
62
70
  end
63
-
64
- # @private
65
- def self.release(ptr)
66
- Call.libusb_free_ss_endpoint_companion_descriptor(ptr)
67
- end
68
71
  end
69
72
  end
@@ -28,16 +28,16 @@ module LIBUSB
28
28
  class ZeroCopyMemory < FFI::Pointer
29
29
  attr_reader :size
30
30
 
31
- def initialize(dev_handle, ptr, size)
32
- @dev_handle = dev_handle
31
+ def initialize(pDevhandle, ptr, size)
32
+ @pDevhandle = pDevhandle
33
33
  @size = size
34
34
  super(ptr)
35
35
  end
36
36
 
37
37
  def free(id=nil)
38
+ # puts format("libusb_dev_mem_free(%#x, %d)%s", address, @size||0, id ? " by GC" : '')
38
39
  return unless @size
39
- # puts format("libusb_dev_mem_free(%#x, %d)%s", address, @size, id ? " by GC" : '')
40
- res = Call.libusb_dev_mem_free( @dev_handle.pHandle, self, @size )
40
+ res = Call.libusb_dev_mem_free( @pDevhandle, self, @size )
41
41
  LIBUSB.raise_error res, "in libusb_dev_mem_free" if res!=0
42
42
  @size = nil
43
43
  end
@@ -60,6 +60,10 @@ module LIBUSB
60
60
  def dev_handle=(dev)
61
61
  @dev_handle = dev
62
62
  @transfer[:dev_handle] = @dev_handle.pHandle
63
+ # Now that the transfer is bound to a DevHandle, it must be registered in the Context.
64
+ # This ensures that the Call::Transfer is freed before libusb_exit, avoiding warnings about still referenced devices.
65
+ ctx = dev.device.context.instance_variable_get(:@ctx)
66
+ @transfer.instance_variable_set(:@ctx, ctx.ref_context)
63
67
  end
64
68
 
65
69
  # The handle for the device to communicate with.
@@ -163,7 +167,7 @@ module LIBUSB
163
167
  ptr = Call.libusb_dev_mem_alloc( @dev_handle.pHandle, len )
164
168
  # puts format("libusb_dev_mem_alloc(%d) => %#x", len, ptr.address)
165
169
  unless ptr.null?
166
- buffer = ZeroCopyMemory.new(@dev_handle, ptr, len)
170
+ buffer = ZeroCopyMemory.new(@dev_handle.pHandle, ptr, len)
167
171
  ObjectSpace.define_finalizer(self, buffer.method(:free))
168
172
  end
169
173
  end
@@ -252,7 +256,7 @@ module LIBUSB
252
256
  @dev_handle.device.context.handle_events nil, @completion_flag
253
257
  rescue ERROR_INTERRUPTED
254
258
  next
255
- rescue LIBUSB::Error
259
+ rescue Exception
256
260
  cancel!
257
261
  until @completion_flag.completed?
258
262
  @dev_handle.device.context.handle_events nil, @completion_flag
@@ -15,5 +15,5 @@
15
15
 
16
16
  module LIBUSB
17
17
  # Library version of libusb for Ruby
18
- VERSION = "0.6.4"
18
+ VERSION = "0.7.0"
19
19
  end
data/lib/libusb-1.0.dll CHANGED
Binary file
data/lib/libusb.rb CHANGED
@@ -20,6 +20,7 @@ module LIBUSB
20
20
  autoload :VERSION, 'libusb/version_gem'
21
21
  autoload :Version, 'libusb/version_struct'
22
22
  autoload :Configuration, 'libusb/configuration'
23
+ autoload :ContextReference, 'libusb/context_reference'
23
24
  autoload :DevHandle, 'libusb/dev_handle'
24
25
  autoload :Device, 'libusb/device'
25
26
  autoload :Endpoint, 'libusb/endpoint'
@@ -32,27 +33,114 @@ module LIBUSB
32
33
  autoload klass, 'libusb/transfer'
33
34
  end
34
35
 
35
- if Call.respond_to?(:libusb_get_version)
36
- # Get version of the underlying libusb library.
37
- # Available since libusb-1.0.10.
38
- # @return [Version] version object
39
- def self.version
40
- Version.new(Call.libusb_get_version)
36
+ class << self
37
+ if Call.respond_to?(:libusb_get_version)
38
+ # Get version of the underlying libusb library.
39
+ # Available since libusb-1.0.10.
40
+ # @return [Version] version object
41
+ def version
42
+ Version.new(Call.libusb_get_version)
43
+ end
44
+ end
45
+
46
+ if Call.respond_to?(:libusb_has_capability)
47
+ # Check at runtime if the loaded library has a given capability.
48
+ # Available since libusb-1.0.9.
49
+ # @param [Symbol] capability the {Call::Capabilities Capabilities} symbol to check for
50
+ # @return [Boolean] +true+ if the running library has the capability, +false+ otherwise
51
+ def has_capability?(capability)
52
+ r = Call.libusb_has_capability(capability)
53
+ return r != 0
54
+ end
55
+ else
56
+ def has_capability?(capability)
57
+ false
58
+ end
59
+ end
60
+
61
+ private def expect_option_args(exp, is)
62
+ raise ArgumentError, "wrong number of arguments (given #{is+1}, expected #{exp+1})" if is != exp
41
63
  end
42
- end
43
64
 
44
- if Call.respond_to?(:libusb_has_capability)
45
- # Check at runtime if the loaded library has a given capability.
46
- # Available since libusb-1.0.9.
47
- # @param [Symbol] capability the {Call::Capabilities Capabilities} symbol to check for
48
- # @return [Boolean] +true+ if the running library has the capability, +false+ otherwise
49
- def self.has_capability?(capability)
50
- r = Call.libusb_has_capability(capability)
51
- return r != 0
65
+ private def wrap_log_cb(block, mode)
66
+ if block
67
+ cb_proc = proc do |p_ctx, lev, str|
68
+ ctx = case p_ctx
69
+ when FFI::Pointer::NULL then nil
70
+ else p_ctx.to_i
71
+ end
72
+ block.call(ctx, lev, str)
73
+ end
74
+ end
75
+
76
+ # Avoid garbage collection of the proc, since only the function pointer is given to libusb
77
+ if Call::LogCbMode.to_native(mode, nil) & LOG_CB_GLOBAL != 0
78
+ @log_cb_global_proc = cb_proc
79
+ end
80
+ if Call::LogCbMode.to_native(mode, nil) & LOG_CB_CONTEXT != 0
81
+ @log_cb_context_proc = cb_proc
82
+ end
83
+ cb_proc
84
+ end
85
+
86
+ private def option_args_to_ffi(option, args, ctx)
87
+ case option
88
+ when :OPTION_LOG_LEVEL, LIBUSB::OPTION_LOG_LEVEL
89
+ expect_option_args(1, args.length)
90
+ [:libusb_log_level, args[0]]
91
+ when :OPTION_USE_USBDK, LIBUSB::OPTION_USE_USBDK
92
+ expect_option_args(0, args.length)
93
+ []
94
+ when :OPTION_NO_DEVICE_DISCOVERY, LIBUSB::OPTION_NO_DEVICE_DISCOVERY
95
+ expect_option_args(0, args.length)
96
+ []
97
+ when :OPTION_LOG_CB, LIBUSB::OPTION_LOG_CB
98
+ expect_option_args(1, args.length)
99
+ cb_proc = ctx.send(:wrap_log_cb, args[0], LOG_CB_CONTEXT)
100
+ [:libusb_log_cb, cb_proc]
101
+ else
102
+ raise ArgumentError, "unknown option #{option.inspect}"
103
+ end
52
104
  end
53
- else
54
- def self.has_capability?(capability)
55
- false
105
+
106
+ if Call.respond_to?(:libusb_set_option)
107
+ # Set an default option in the libusb library.
108
+ #
109
+ # Use this function to configure a specific option within the library.
110
+ # See {Call::Options option list}.
111
+ #
112
+ # Some options require one or more arguments to be provided.
113
+ # Consult each option's documentation for specific requirements.
114
+ #
115
+ # The option will be added to a list of default options that will be applied to all subsequently created contexts.
116
+ #
117
+ # Available since libusb-1.0.22, LIBUSB_API_VERSION >= 0x01000106
118
+ #
119
+ # @param [Symbol, Fixnum] option
120
+ # @param args Zero or more arguments depending on +option+
121
+ #
122
+ # Available since libusb-1.0.22
123
+ def set_option(option, *args)
124
+ ffi_args = option_args_to_ffi(option, args, self)
125
+ res = Call.libusb_set_option(nil, option, *ffi_args)
126
+ LIBUSB.raise_error res, "in libusb_set_option" if res<0
127
+ end
128
+
129
+ # Convenience function to set default options in the libusb library.
130
+ #
131
+ # Use this function to configure any number of options within the library.
132
+ # It takes a Hash the same way as given to {Context.initialize}.
133
+ # See also {Call::Options option list}.
134
+ #
135
+ # Available since libusb-1.0.22, LIBUSB_API_VERSION >= 0x01000106
136
+ #
137
+ # @param [Hash{Call::Options => Object}] options Option hash
138
+ # @see set_option
139
+ def set_options(options={})
140
+ options.each do |k, v|
141
+ set_option(k, *Array(v))
142
+ end
143
+ end
56
144
  end
57
145
  end
58
146
  end
data/libusb.gemspec CHANGED
@@ -22,11 +22,7 @@ Gem::Specification.new do |s|
22
22
  s.extensions = ['ext/extconf.rb']
23
23
  s.metadata["yard.run"] = "yri"
24
24
 
25
- s.required_ruby_version = Gem::Requirement.new(">= 1.9.3")
25
+ s.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
26
26
  s.add_runtime_dependency 'ffi', '~> 1.0'
27
27
  s.add_runtime_dependency 'mini_portile2', LIBUSB::MINI_PORTILE_VERSION
28
- s.add_development_dependency 'rake-compiler', '~> 1.0'
29
- s.add_development_dependency 'rake-compiler-dock', '~> 0.2'
30
- s.add_development_dependency 'bundler', '~> 1.0'
31
- s.add_development_dependency 'yard', '~> 0.6'
32
28
  end
@@ -53,6 +53,23 @@ class TestLibusbBos < Minitest::Test
53
53
  :BT_USB_2_0_EXTENSION,
54
54
  :BT_SS_USB_DEVICE_CAPABILITY,
55
55
  :BT_CONTAINER_ID,
56
+ :BT_WIRELESS_USB_DEVICE_CAPABILITY,
57
+ :BT_USB_2_0_EXTENSION,
58
+ :BT_SS_USB_DEVICE_CAPABILITY,
59
+ :BT_CONTAINER_ID,
60
+ :BT_PLATFORM_DESCRIPTOR,
61
+ :BT_POWER_DELIVERY_CAPABILITY,
62
+ :BT_BATTERY_INFO_CAPABILITY,
63
+ :BT_PD_CONSUMER_PORT_CAPABILITY,
64
+ :BT_PD_PROVIDER_PORT_CAPABILITY,
65
+ :BT_SUPERSPEED_PLUS,
66
+ :BT_PRECISION_TIME_MEASUREMENT,
67
+ :BT_Wireless_USB_Ext,
68
+ :BT_BILLBOARD,
69
+ :BT_AUTHENTICATION,
70
+ :BT_BILLBOARD_EX,
71
+ :BT_CONFIGURATION_SUMMARY,
72
+ :BT_FWStatus_Capability,
56
73
  ], :include?, cap_type
57
74
  end
58
75
 
@@ -90,6 +107,11 @@ class TestLibusbBos < Minitest::Test
90
107
  assert_operator 0, :<=, cap.bReserved
91
108
  assert_operator 16, :==, cap.container_id.bytesize, "container_id should be 16 bytes long"
92
109
 
110
+ when Bos::PlatformDescriptor
111
+ assert_operator 0, :<=, cap.bReserved
112
+ assert_operator 16, :==, cap.platformCapabilityUUID.bytesize, "container_id should be 16 bytes long"
113
+ assert_kind_of String, cap.capabilityData
114
+
93
115
  else
94
116
  refute true, "invalid device capability class"
95
117
  end
@@ -21,11 +21,18 @@ class TestLibusbBulkStreamTransfer < Minitest::Test
21
21
 
22
22
  def setup
23
23
  c = Context.new
24
- begin
25
- @dev = c.devices.first.open
26
- rescue LIBUSB::ERROR_ACCESS
27
- @dev = nil
28
- skip "error opening device"
24
+ c.devices.each do |dev|
25
+ if [:SPEED_SUPER, :SPEED_SUPER_PLUS].include?(dev.device_speed)
26
+ dev.endpoints.each do |ep|
27
+ if ep.transfer_type == :bulk
28
+ ss = ep.ss_companion
29
+ if ss.bmAttributes & 0x1f > 0
30
+ @dev = dev.open
31
+ break
32
+ end
33
+ end
34
+ end
35
+ end
29
36
  end
30
37
  end
31
38
 
@@ -34,17 +41,21 @@ class TestLibusbBulkStreamTransfer < Minitest::Test
34
41
  end
35
42
 
36
43
  def test_alloc_streams
37
- assert_raises(ERROR_NOT_SUPPORTED, "TODO: test with a OS that supports bulk streams and against a real device") do
38
- nr_allocated = @dev.alloc_streams( 2, @dev.device.endpoints )
39
- end
44
+ skip "no device found with bulk stream support" unless @dev
40
45
 
41
- assert_raises(ERROR_NOT_SUPPORTED) do
42
- @dev.free_streams( [0x01,0x82] )
43
- end
46
+ nr_allocated = @dev.alloc_streams( 2, @dev.device.endpoints )
47
+ assert_equal 2, nr_allocated
48
+
49
+ # TODO: test with a OS that supports bulk streams and against a real device
50
+
51
+ @dev.free_streams( [0x01,0x82] )
44
52
  end
45
53
 
46
54
  def test_bulk_stream_transfer
47
- tr = BulkStreamTransfer.new dev_handle: @dev, stream_id: 123, buffer: ' '*100
55
+ c = Context.new
56
+ dev = c.devices.first.open
57
+ tr = BulkStreamTransfer.new dev_handle: dev, stream_id: 123, buffer: ' '*100
48
58
  assert_equal 123, tr.stream_id, "stream_id should match"
59
+ dev.close
49
60
  end
50
61
  end