libusb 0.6.3-x64-mingw32 → 0.7.0-x64-mingw32

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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,25 +28,30 @@ 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
44
44
  end
45
45
 
46
+ class << self
47
+ private :new
48
+ end
49
+
46
50
  def initialize(args={})
47
51
  @buffer = nil
48
52
  @completion_flag = Context::CompletionFlag.new
49
53
  @allow_device_memory = false
54
+ @dev_handle = nil
50
55
  args.each{|k,v| send("#{k}=", v) }
51
56
  end
52
57
  private :initialize
@@ -55,15 +60,29 @@ module LIBUSB
55
60
  def dev_handle=(dev)
56
61
  @dev_handle = dev
57
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)
58
67
  end
59
68
 
60
- # Timeout for this transfer in millseconds.
69
+ # The handle for the device to communicate with.
70
+ attr_reader :dev_handle
71
+
72
+ # Set timeout for this transfer in millseconds.
61
73
  #
62
74
  # A value of 0 indicates no timeout.
63
75
  def timeout=(value)
64
76
  @transfer[:timeout] = value
65
77
  end
66
78
 
79
+ # Get timeout for this transfer in millseconds.
80
+ #
81
+ # A value of 0 indicates no timeout.
82
+ def timeout
83
+ @transfer[:timeout]
84
+ end
85
+
67
86
  # Set the address of a valid endpoint to communicate with.
68
87
  def endpoint=(endpoint)
69
88
  endpoint = endpoint.bEndpointAddress if endpoint.respond_to? :bEndpointAddress
@@ -148,7 +167,7 @@ module LIBUSB
148
167
  ptr = Call.libusb_dev_mem_alloc( @dev_handle.pHandle, len )
149
168
  # puts format("libusb_dev_mem_alloc(%d) => %#x", len, ptr.address)
150
169
  unless ptr.null?
151
- buffer = ZeroCopyMemory.new(@dev_handle, ptr, len)
170
+ buffer = ZeroCopyMemory.new(@dev_handle.pHandle, ptr, len)
152
171
  ObjectSpace.define_finalizer(self, buffer.method(:free))
153
172
  end
154
173
  end
@@ -225,6 +244,8 @@ module LIBUSB
225
244
  #
226
245
  # Inspect {#status} to check for transfer errors.
227
246
  def submit_and_wait
247
+ raise ArgumentError, "#{self.class}#dev_handle not set" unless @dev_handle
248
+
228
249
  @completion_flag.completed = false
229
250
  submit! do |tr2|
230
251
  @completion_flag.completed = true
@@ -235,7 +256,7 @@ module LIBUSB
235
256
  @dev_handle.device.context.handle_events nil, @completion_flag
236
257
  rescue ERROR_INTERRUPTED
237
258
  next
238
- rescue LIBUSB::Error
259
+ rescue Exception
239
260
  cancel!
240
261
  until @completion_flag.completed?
241
262
  @dev_handle.device.context.handle_events nil, @completion_flag
@@ -256,6 +277,10 @@ module LIBUSB
256
277
  end
257
278
 
258
279
  class BulkTransfer < Transfer
280
+ def self.new(*)
281
+ super
282
+ end
283
+
259
284
  def initialize(args={})
260
285
  @transfer = Call::Transfer.new Call.libusb_alloc_transfer(0)
261
286
  @transfer[:type] = TRANSFER_TYPE_BULK
@@ -272,6 +297,10 @@ module LIBUSB
272
297
  #
273
298
  # Available since libusb-1.0.19.
274
299
  class BulkStreamTransfer < Transfer
300
+ def self.new(*)
301
+ super
302
+ end
303
+
275
304
  def initialize(args={})
276
305
  @transfer = Call::Transfer.new Call.libusb_alloc_transfer(0)
277
306
  @transfer[:type] = TRANSFER_TYPE_BULK_STREAM
@@ -299,6 +328,10 @@ module LIBUSB
299
328
  end
300
329
 
301
330
  class ControlTransfer < Transfer
331
+ def self.new(*)
332
+ super
333
+ end
334
+
302
335
  def initialize(args={})
303
336
  @transfer = Call::Transfer.new Call.libusb_alloc_transfer(0)
304
337
  @transfer[:type] = TRANSFER_TYPE_CONTROL
@@ -308,6 +341,10 @@ module LIBUSB
308
341
  end
309
342
 
310
343
  class InterruptTransfer < Transfer
344
+ def self.new(*)
345
+ super
346
+ end
347
+
311
348
  def initialize(args={})
312
349
  @transfer = Call::Transfer.new Call.libusb_alloc_transfer(0)
313
350
  @transfer[:type] = TRANSFER_TYPE_INTERRUPT
@@ -339,6 +376,10 @@ module LIBUSB
339
376
  end
340
377
 
341
378
  class IsochronousTransfer < Transfer
379
+ def self.new(*)
380
+ super
381
+ end
382
+
342
383
  def initialize(num_packets, args={})
343
384
  @ptr = Call.libusb_alloc_transfer(num_packets)
344
385
  @transfer = Call::Transfer.new @ptr
@@ -15,5 +15,5 @@
15
15
 
16
16
  module LIBUSB
17
17
  # Library version of libusb for Ruby
18
- VERSION = "0.6.3"
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
@@ -20,11 +20,9 @@ Gem::Specification.new do |s|
20
20
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
21
  s.require_paths = ["lib"]
22
22
  s.extensions = ['ext/extconf.rb']
23
+ s.metadata["yard.run"] = "yri"
23
24
 
24
- s.required_ruby_version = Gem::Requirement.new(">= 1.9.3")
25
+ s.required_ruby_version = Gem::Requirement.new(">= 2.5.0")
25
26
  s.add_runtime_dependency 'ffi', '~> 1.0'
26
27
  s.add_runtime_dependency 'mini_portile2', LIBUSB::MINI_PORTILE_VERSION
27
- s.add_development_dependency 'rake-compiler', '~> 1.0'
28
- s.add_development_dependency 'rake-compiler-dock', '~> 0.2'
29
- s.add_development_dependency 'bundler', '~> 1.0'
30
28
  end
@@ -16,22 +16,24 @@
16
16
  require "minitest/autorun"
17
17
  require "libusb"
18
18
 
19
- class TestLibusbVersion < Minitest::Test
20
- def setup
21
- @v = LIBUSB.version
19
+ class TestLibusb < Minitest::Test
20
+ def test_has_capability
21
+ assert LIBUSB.has_capability?(:CAP_HAS_CAPABILITY)
22
22
  end
23
23
 
24
24
  def test_version_parts
25
- assert_operator @v.major, :>=, 0
26
- assert_operator @v.minor, :>=, 0
27
- assert_operator @v.micro, :>=, 0
28
- assert_operator @v.nano, :>=, 0
29
- assert_kind_of String, @v.rc
25
+ v = LIBUSB.version
26
+ assert_operator v.major, :>=, 0
27
+ assert_operator v.minor, :>=, 0
28
+ assert_operator v.micro, :>=, 0
29
+ assert_operator v.nano, :>=, 0
30
+ assert_kind_of String, v.rc
30
31
  end
31
32
 
32
33
  def test_version_string
33
- assert_match(/^\d+\.\d+\.\d+/, @v.to_s)
34
- assert_match(/^#<LIBUSB::Version \d+\.\d+\.\d+/, @v.inspect)
34
+ v = LIBUSB.version
35
+ assert_match(/^\d+\.\d+\.\d+/, v.to_s)
36
+ assert_match(/^#<LIBUSB::Version \d+\.\d+\.\d+/, v.inspect)
35
37
  end
36
38
 
37
39
  def test_gem_version_string
@@ -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
@@ -0,0 +1,88 @@
1
+ # This file is part of Libusb for Ruby.
2
+ #
3
+ # Libusb for Ruby is free software: you can redistribute it and/or modify
4
+ # it under the terms of the GNU Lesser General Public License as published by
5
+ # the Free Software Foundation, either version 3 of the License, or
6
+ # (at your option) any later version.
7
+ #
8
+ # Libusb for Ruby is distributed in the hope that it will be useful,
9
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
10
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
+ # GNU Lesser General Public License for more details.
12
+ #
13
+ # You should have received a copy of the GNU Lesser General Public License
14
+ # along with Libusb for Ruby. If not, see <http://www.gnu.org/licenses/>.
15
+
16
+ require "minitest/autorun"
17
+ require "libusb"
18
+
19
+ class TestLibusbContext < Minitest::Test
20
+ def setup
21
+ @c = LIBUSB::Context.new
22
+ end
23
+
24
+ def teardown
25
+ @c.exit if @c
26
+ end
27
+
28
+ def test_set_option
29
+ @c.set_option LIBUSB::OPTION_LOG_LEVEL, LIBUSB::LOG_LEVEL_NONE
30
+ @c.set_option LIBUSB::OPTION_LOG_LEVEL, LIBUSB::LOG_LEVEL_ERROR
31
+ @c.set_option LIBUSB::OPTION_LOG_LEVEL, LIBUSB::LOG_LEVEL_WARNING
32
+ @c.set_option LIBUSB::OPTION_LOG_LEVEL, LIBUSB::LOG_LEVEL_INFO
33
+ @c.set_option LIBUSB::OPTION_LOG_LEVEL, LIBUSB::LOG_LEVEL_DEBUG
34
+ @c.set_option :OPTION_LOG_LEVEL, :LOG_LEVEL_NONE
35
+ end
36
+
37
+ def test_set_debug
38
+ @c.debug = 4
39
+ @c.debug = 0
40
+ end
41
+
42
+ def test_left_references
43
+ @test_devs = @c.devices
44
+ assert_raises(LIBUSB::RemainingReferencesError) do
45
+ @c.exit
46
+ end
47
+ @c = nil
48
+ end
49
+
50
+ def test_double_exit
51
+ @c.exit
52
+ end
53
+
54
+ def test_log_callback
55
+ skip "only supported on Linux" unless RUBY_PLATFORM=~/linux/
56
+ skip "libusb version older than 1.0.27" if Gem::Version.new(LIBUSB.version) < Gem::Version.new("1.0.27")
57
+
58
+ LIBUSB.set_options OPTION_LOG_CB: [nil], OPTION_LOG_LEVEL: LIBUSB::LOG_LEVEL_NONE
59
+ begin
60
+ called = Hash.new { |h, k| h[k] = [] }
61
+ LIBUSB.set_options OPTION_LOG_CB: proc{|*a| called[:global] << a }, OPTION_LOG_LEVEL: LIBUSB::LOG_LEVEL_DEBUG
62
+
63
+ c = LIBUSB::Context.new OPTION_LOG_CB: proc{|*a| called[:ctx1] << a }, OPTION_NO_DEVICE_DISCOVERY: nil
64
+ c.devices
65
+ c.set_log_cb(LIBUSB::LOG_CB_CONTEXT){|*a| called[:ctx2] << a }
66
+ c.devices
67
+
68
+ #pp called
69
+ assert_nil called[:global][0][0]
70
+ assert_equal :LOG_LEVEL_DEBUG, called[:global][0][1], called[:global][0][2]
71
+ assert_match(/libusb_init_context/, called[:global].join)
72
+ assert_match(/no device discovery/, called[:global].join)
73
+
74
+ assert_operator called[:ctx1].size, :>, called[:ctx2].size
75
+ assert_equal c, called[:ctx1][-1][0]
76
+ assert_equal :LOG_LEVEL_DEBUG, called[:ctx1][-1][1]
77
+ assert_match(/libusb_get_device_list/, called[:ctx1][-1][2])
78
+ assert_match(/no device discovery/, called[:ctx1].join)
79
+
80
+ assert_equal c, called[:ctx2][-1][0]
81
+ assert_equal :LOG_LEVEL_DEBUG, called[:ctx2][-1][1]
82
+ assert_match(/libusb_get_device_list/, called[:ctx2][-1][2])
83
+
84
+ ensure
85
+ LIBUSB.set_options OPTION_LOG_CB: [nil], OPTION_LOG_LEVEL: LIBUSB::LOG_LEVEL_NONE
86
+ end
87
+ end
88
+ end
@@ -119,7 +119,7 @@ class TestLibusbDescriptors < Minitest::Test
119
119
 
120
120
  usb.devices.each do |dev|
121
121
  dev.endpoints.each do |ep|
122
- if dev.device_speed == :SPEED_SUPER
122
+ if [:SPEED_SUPER, :SPEED_SUPER_PLUS].include?(dev.device_speed)
123
123
  ss = ep.ss_companion
124
124
  assert_match(/SsCompanion/, ss.inspect, "SsCompanion#inspect should work")
125
125
 
@@ -172,14 +172,19 @@ class TestLibusbDescriptors < Minitest::Test
172
172
  def test_device_filter_hubs
173
173
  devs1 = []
174
174
  usb.devices.each do |dev|
175
- dev.settings.each do |if_desc|
176
- if if_desc.bInterfaceClass == CLASS_HUB
177
- devs1 << dev
175
+ if dev.bDeviceClass==CLASS_PER_INTERFACE
176
+ dev.settings.each do |if_desc|
177
+ if if_desc.bInterfaceClass==CLASS_HUB
178
+ devs1 << dev
179
+ end
178
180
  end
181
+ else
182
+ devs1 << dev if dev.bDeviceClass == CLASS_HUB
179
183
  end
180
184
  end
181
185
 
182
186
  devs2 = usb.devices( bClass: CLASS_HUB )
187
+
183
188
  assert_equal devs1.sort, devs2.sort, "devices and devices with filter should deliver the same device"
184
189
  end
185
190
 
@@ -189,11 +194,11 @@ class TestLibusbDescriptors < Minitest::Test
189
194
  if ep
190
195
  assert_operator dev.max_packet_size(ep), :>, 0, "#{dev.inspect} should have a usable packet size"
191
196
  assert_operator dev.max_packet_size(ep.bEndpointAddress), :>, 0, "#{dev.inspect} should have a usable packet size"
192
- assert_operator dev.max_iso_packet_size(ep), :>, 0, "#{dev.inspect} should have a usable iso packet size"
193
- assert_operator dev.max_iso_packet_size(ep.bEndpointAddress), :>, 0, "#{dev.inspect} should have a usable iso packet size"
197
+ assert_operator dev.max_iso_packet_size(ep), :>=, 0, "#{dev.inspect} should have a usable iso packet size"
198
+ assert_operator dev.max_iso_packet_size(ep.bEndpointAddress), :>=, 0, "#{dev.inspect} should have a usable iso packet size"
194
199
  assert_operator dev.bus_number, :>=, 0, "#{dev.inspect} should have a bus_number"
195
200
  assert_operator dev.device_address, :>=, 0, "#{dev.inspect} should have a device_address"
196
- assert_operator([:SPEED_UNKNOWN, :SPEED_LOW, :SPEED_FULL, :SPEED_HIGH, :SPEED_SUPER], :include?, dev.device_speed, "#{dev.inspect} should have a device_speed")
201
+ assert_operator([:SPEED_UNKNOWN, :SPEED_LOW, :SPEED_FULL, :SPEED_HIGH, :SPEED_SUPER, :SPEED_SUPER_PLUS], :include?, dev.device_speed, "#{dev.inspect} should have a device_speed")
197
202
  path = dev.port_numbers
198
203
  assert_kind_of Array, path, "#{dev.inspect} should have port_numbers"
199
204
  path = dev.port_path
@@ -201,12 +206,40 @@ class TestLibusbDescriptors < Minitest::Test
201
206
  path.each do |port|
202
207
  assert_operator port, :>, 0, "#{dev.inspect} should have proper port_path entries"
203
208
  end
204
- assert_equal path[-1], dev.port_number, "#{dev.inspect} should have a port number out of the port_path"
205
- if parent=dev.parent
206
- assert_kind_of Device, parent, "#{dev.inspect} should have a parent"
207
- assert_equal path[-2], parent.port_number, "#{dev.inspect} should have a parent port number out of the port_path"
209
+ if path.empty?
210
+ assert_nil dev.port_number
211
+ else
212
+ assert_equal path[-1], dev.port_number, "#{dev.inspect} should have a port number out of the port_path"
213
+ if parent=dev.parent
214
+ assert_kind_of Device, parent, "#{dev.inspect} should have a parent"
215
+ assert_equal path[-2], parent.port_number, "#{dev.inspect} should have a parent port number out of the port_path" if parent.port_number
216
+ end
208
217
  end
209
218
  end
210
219
  end
211
220
  end
221
+
222
+ def test_wrap_sys_device
223
+ skip unless RUBY_PLATFORM =~ /linux/
224
+ d = usb.devices[0]
225
+ File.open(format("/dev/bus/usb/%03d/%03d", d.bus_number, d.device_address), "w+") do |io|
226
+ devh = usb.wrap_sys_device(io)
227
+ devh.kernel_driver_active?(0)
228
+ devh.close
229
+
230
+ usb.wrap_sys_device(io) do |devh|
231
+ devh.kernel_driver_active?(0)
232
+ end
233
+ end
234
+ end
235
+
236
+ def test_wrap_sys_device_failure
237
+ skip unless RUBY_PLATFORM =~ /linux/
238
+ d = usb.devices[0]
239
+ assert_raises(LIBUSB::ERROR_OTHER) do
240
+ File.open(format("/dev/bus/usb/%03d/%03d", d.bus_number, d.device_address), "r") do |io|
241
+ usb.wrap_sys_device(io).kernel_driver_active?(0)
242
+ end
243
+ end
244
+ end
212
245
  end