libusb 0.6.4-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.
- checksums.yaml +4 -4
- data/.appveyor.yml +33 -0
- data/.github/workflows/ci.yml +185 -0
- data/.gitignore +1 -0
- data/.travis.yml +12 -7
- data/Gemfile +4 -1
- data/History.md +38 -0
- data/README.md +29 -4
- data/Rakefile +41 -12
- data/lib/libusb/bos.rb +85 -29
- data/lib/libusb/call.rb +132 -16
- data/lib/libusb/configuration.rb +3 -4
- data/lib/libusb/constants.rb +4 -0
- data/lib/libusb/context.rb +176 -35
- data/lib/libusb/context_reference.rb +38 -0
- data/lib/libusb/dependencies.rb +2 -2
- data/lib/libusb/dev_handle.rb +34 -24
- data/lib/libusb/device.rb +50 -8
- data/lib/libusb/endpoint.rb +3 -2
- data/lib/libusb/eventmachine.rb +8 -4
- data/lib/libusb/gem_helper.rb +9 -6
- data/lib/libusb/libusb_recipe.rb +2 -3
- data/lib/libusb/ss_companion.rb +9 -6
- data/lib/libusb/transfer.rb +10 -6
- data/lib/libusb/version_gem.rb +1 -1
- data/lib/libusb-1.0.dll +0 -0
- data/lib/libusb.rb +106 -18
- data/libusb.gemspec +1 -5
- data/test/test_libusb_bos.rb +22 -0
- data/test/test_libusb_bulk_stream_transfer.rb +23 -12
- data/test/test_libusb_context.rb +47 -0
- data/test/test_libusb_descriptors.rb +44 -11
- data/test/test_libusb_gc.rb +15 -0
- data/test/test_libusb_hotplug.rb +3 -1
- data/test/test_libusb_iso_transfer.rb +6 -0
- data/test/test_libusb_mass_storage.rb +6 -6
- metadata +7 -62
- data/appveyor.yml +0 -36
data/lib/libusb/call.rb
CHANGED
@@ -228,14 +228,23 @@ module LIBUSB
|
|
228
228
|
#
|
229
229
|
# @see Bos::DeviceCapability
|
230
230
|
BosTypes = enum :libusb_bos_type, [
|
231
|
-
# Wireless USB device capability
|
232
|
-
:
|
233
|
-
# USB
|
234
|
-
:
|
235
|
-
|
236
|
-
:
|
237
|
-
#
|
238
|
-
:
|
231
|
+
:BT_WIRELESS_USB_DEVICE_CAPABILITY, 0x01, # Wireless USB device capability
|
232
|
+
:BT_USB_2_0_EXTENSION, 0x02, # USB 2.0 extensions
|
233
|
+
:BT_SS_USB_DEVICE_CAPABILITY, 0x03, # SuperSpeed USB device capability
|
234
|
+
:BT_CONTAINER_ID, 0x04, # Container ID type
|
235
|
+
:BT_PLATFORM_DESCRIPTOR, 0x05, # Platform descriptor
|
236
|
+
:BT_POWER_DELIVERY_CAPABILITY, 0x06, # Defines the various PD Capabilities of this device
|
237
|
+
:BT_BATTERY_INFO_CAPABILITY, 0x07, # Provides information on each battery supported by the device
|
238
|
+
:BT_PD_CONSUMER_PORT_CAPABILITY, 0x08, # The consumer characteristics of a port on the device
|
239
|
+
:BT_PD_PROVIDER_PORT_CAPABILITY, 0x09, # The provider characteristics of a port on the device
|
240
|
+
:BT_SUPERSPEED_PLUS, 0x0A, # Defines the set of SuperSpeed Plus USB specific device level capabilities
|
241
|
+
:BT_PRECISION_TIME_MEASUREMENT, 0x0B, # Precision Time Measurement (PTM) Capability Descriptor
|
242
|
+
:BT_Wireless_USB_Ext, 0x0C, # Defines the set of Wireless USB 1.1-specific device level capabilities
|
243
|
+
:BT_BILLBOARD, 0x0D, # Billboard capability
|
244
|
+
:BT_AUTHENTICATION, 0x0E, # Authentication Capability Descriptor
|
245
|
+
:BT_BILLBOARD_EX, 0x0F, # Billboard Ex capability
|
246
|
+
:BT_CONFIGURATION_SUMMARY, 0x10, # Summarizes configuration information for a function implemented by the device
|
247
|
+
:BT_FWStatus_Capability, 0x11, # Describes the capability to support FWStatus
|
239
248
|
]
|
240
249
|
|
241
250
|
# Since libusb version 1.0.16.
|
@@ -274,6 +283,25 @@ module LIBUSB
|
|
274
283
|
:LOG_LEVEL_DEBUG, 4,
|
275
284
|
]
|
276
285
|
|
286
|
+
# /** \ingroup libusb_lib
|
287
|
+
# * Log callback mode.
|
288
|
+
# *
|
289
|
+
# * Since version 1.0.23, \ref LIBUSB_API_VERSION >= 0x01000107
|
290
|
+
# *
|
291
|
+
# * \see libusb_set_log_cb()
|
292
|
+
# */
|
293
|
+
# enum libusb_log_cb_mode {
|
294
|
+
# /** Callback function handling all log messages. */
|
295
|
+
# LIBUSB_LOG_CB_GLOBAL = (1 << 0),
|
296
|
+
#
|
297
|
+
# /** Callback function handling context related log messages. */
|
298
|
+
# LIBUSB_LOG_CB_CONTEXT = (1 << 1)
|
299
|
+
# };
|
300
|
+
LogCbMode = enum :libusb_log_cb_mode, [
|
301
|
+
:LOG_CB_GLOBAL, (1 << 0),
|
302
|
+
:LOG_CB_CONTEXT, (1 << 1),
|
303
|
+
]
|
304
|
+
|
277
305
|
# Available option values for {Context#set_option}.
|
278
306
|
Options = enum :libusb_option, [
|
279
307
|
# Set the log message verbosity.
|
@@ -296,7 +324,7 @@ module LIBUSB
|
|
296
324
|
#
|
297
325
|
# If libusb was compiled with verbose debug message logging, this function
|
298
326
|
# does nothing: you'll always get messages from all levels.
|
299
|
-
:OPTION_LOG_LEVEL,
|
327
|
+
:OPTION_LOG_LEVEL, 0,
|
300
328
|
|
301
329
|
# Use the UsbDk backend for a specific context, if available.
|
302
330
|
#
|
@@ -306,7 +334,33 @@ module LIBUSB
|
|
306
334
|
# Only valid on Windows.
|
307
335
|
#
|
308
336
|
# Available since libusb-1.0.22.
|
309
|
-
:OPTION_USE_USBDK,
|
337
|
+
:OPTION_USE_USBDK, 1,
|
338
|
+
|
339
|
+
# Do not scan for devices
|
340
|
+
#
|
341
|
+
# With this option set, libusb will skip scanning devices in
|
342
|
+
# libusb_init_context().
|
343
|
+
#
|
344
|
+
# Hotplug functionality will also be deactivated.
|
345
|
+
#
|
346
|
+
# The option is useful in combination with libusb_wrap_sys_device(),
|
347
|
+
# which can access a device directly without prior device scanning.
|
348
|
+
#
|
349
|
+
# This is typically needed on Android, where access to USB devices
|
350
|
+
# is limited.
|
351
|
+
#
|
352
|
+
# Only valid on Linux. Ignored on all other platforms.
|
353
|
+
:OPTION_NO_DEVICE_DISCOVERY, 2,
|
354
|
+
|
355
|
+
# Set the context log callback functon.
|
356
|
+
#
|
357
|
+
# Set the log callback function either on a context or globally.
|
358
|
+
# This option must be provided a Proc argument or +nil+ to remove the callback.
|
359
|
+
# Using this option with a +nil+ context is equivalent to calling libusb_set_log_cb with mode :LOG_CB_GLOBAL.
|
360
|
+
# Using it with a non- +nil+ context is equivalent to calling libusb_set_log_cb with mode :LOG_CB_CONTEXT.
|
361
|
+
:OPTION_LOG_CB, 3,
|
362
|
+
|
363
|
+
:OPTION_MAX, 4,
|
310
364
|
]
|
311
365
|
|
312
366
|
typedef :pointer, :libusb_context
|
@@ -315,15 +369,60 @@ module LIBUSB
|
|
315
369
|
typedef :pointer, :libusb_transfer
|
316
370
|
typedef :int, :libusb_hotplug_callback_handle
|
317
371
|
|
318
|
-
|
319
|
-
|
320
|
-
|
372
|
+
# /** \ingroup libusb_lib
|
373
|
+
# * Callback function for handling log messages.
|
374
|
+
# * \param ctx the context which is related to the log message, or +nil+ if it
|
375
|
+
# * is a global log message
|
376
|
+
# * \param level the log level, see \ref libusb_log_level for a description
|
377
|
+
# * \param str the log message
|
378
|
+
# *
|
379
|
+
# * Since version 1.0.23, \ref LIBUSB_API_VERSION >= 0x01000107
|
380
|
+
# *
|
381
|
+
# * \see libusb_set_log_cb()
|
382
|
+
# */
|
383
|
+
# typedef void (LIBUSB_CALL *libusb_log_cb)(libusb_context *ctx,
|
384
|
+
# enum libusb_log_level level, const char *str);
|
385
|
+
callback :libusb_log_cb, [:libusb_context, :libusb_log_level, :string], :void
|
386
|
+
|
387
|
+
# @private
|
388
|
+
# /** \ingroup libusb_lib
|
389
|
+
# * Structure used for setting options through \ref libusb_init_context.
|
390
|
+
# *
|
391
|
+
# */
|
392
|
+
# struct libusb_init_option {
|
393
|
+
# /** Which option to set */
|
394
|
+
# enum libusb_option option;
|
395
|
+
# /** An integer value used by the option (if applicable). */
|
396
|
+
# union {
|
397
|
+
# int64_t ival;
|
398
|
+
# libusb_log_cb log_cbval;
|
399
|
+
# } value;
|
400
|
+
# };
|
401
|
+
class InitOptionValue < FFI::Union
|
402
|
+
layout :ival, :int64_t,
|
403
|
+
:log_cbval, :libusb_log_cb
|
404
|
+
end
|
405
|
+
class InitOption < FFI::Struct
|
406
|
+
layout :option, :libusb_option,
|
407
|
+
:value, InitOptionValue
|
408
|
+
end
|
409
|
+
|
410
|
+
class << self
|
411
|
+
private def try_attach_function(method, *args, **kwargs)
|
412
|
+
if ffi_libraries.find{|lib| lib.find_function(method) }
|
413
|
+
attach_function method, *args, **kwargs
|
414
|
+
end
|
321
415
|
end
|
322
416
|
end
|
323
417
|
|
324
418
|
try_attach_function 'libusb_get_version', [], :pointer
|
325
419
|
|
326
420
|
attach_function 'libusb_init', [ :pointer ], :int
|
421
|
+
# int LIBUSB_CALL libusb_init_context(libusb_context **ctx, const struct libusb_init_option options[], int num_options);
|
422
|
+
try_attach_function 'libusb_init_context', [:pointer, :pointer, :int], :int
|
423
|
+
# may be deprecated in the future in favor of libusb_init_context()+libusb_set_option()
|
424
|
+
# void LIBUSB_CALL libusb_set_log_cb(libusb_context *ctx, libusb_log_cb cb, int mode);
|
425
|
+
try_attach_function 'libusb_set_log_cb', [:libusb_context, :libusb_log_cb, :int], :void
|
327
426
|
attach_function 'libusb_exit', [ :pointer ], :void
|
328
427
|
attach_function 'libusb_set_debug', [:pointer, :libusb_log_level], :void
|
329
428
|
try_attach_function 'libusb_set_option', [:libusb_context, :libusb_option, :varargs], :int
|
@@ -348,6 +447,8 @@ module LIBUSB
|
|
348
447
|
try_attach_function 'libusb_get_device_speed', [:pointer], :libusb_speed
|
349
448
|
attach_function 'libusb_get_max_packet_size', [:pointer, :uint8], :int
|
350
449
|
attach_function 'libusb_get_max_iso_packet_size', [:pointer, :uint8], :int
|
450
|
+
# int API_EXPORTED libusb_get_max_alt_packet_size(libusb_device *dev, int interface_number, int alternate_setting, unsigned char endpoint)
|
451
|
+
try_attach_function 'libusb_get_max_alt_packet_size', [:pointer, :int, :int, :uchar], :int
|
351
452
|
|
352
453
|
try_attach_function 'libusb_get_ss_endpoint_companion_descriptor', [:pointer, :pointer, :pointer], :int
|
353
454
|
try_attach_function 'libusb_free_ss_endpoint_companion_descriptor', [:pointer], :void
|
@@ -360,7 +461,11 @@ module LIBUSB
|
|
360
461
|
try_attach_function 'libusb_free_ss_usb_device_capability_descriptor', [:pointer], :void
|
361
462
|
try_attach_function 'libusb_get_container_id_descriptor', [:libusb_context, :pointer, :pointer], :int
|
362
463
|
try_attach_function 'libusb_free_container_id_descriptor', [:pointer], :void
|
464
|
+
try_attach_function 'libusb_get_platform_descriptor', [:libusb_context, :pointer, :pointer], :int
|
465
|
+
try_attach_function 'libusb_free_platform_descriptor', [:pointer], :void
|
363
466
|
|
467
|
+
# int LIBUSB_CALL libusb_wrap_sys_device(libusb_context *ctx, intptr_t sys_dev, libusb_device_handle **dev_handle);
|
468
|
+
try_attach_function 'libusb_wrap_sys_device', [:libusb_context, :intptr_t, :pointer], :int
|
364
469
|
attach_function 'libusb_open', [:pointer, :pointer], :int
|
365
470
|
attach_function 'libusb_close', [:pointer], :void
|
366
471
|
attach_function 'libusb_get_device', [:libusb_device_handle], :pointer
|
@@ -431,7 +536,7 @@ module LIBUSB
|
|
431
536
|
:wLength, :uint16
|
432
537
|
end
|
433
538
|
|
434
|
-
class Transfer < FFI::
|
539
|
+
class Transfer < FFI::Struct
|
435
540
|
layout :dev_handle, :libusb_device_handle,
|
436
541
|
:flags, :uint8,
|
437
542
|
:endpoint, :uchar,
|
@@ -445,8 +550,19 @@ module LIBUSB
|
|
445
550
|
:buffer, :pointer,
|
446
551
|
:num_iso_packets, :int
|
447
552
|
|
448
|
-
def
|
449
|
-
|
553
|
+
def initialize(*)
|
554
|
+
super
|
555
|
+
|
556
|
+
ptr = pointer
|
557
|
+
def ptr.free_struct(id)
|
558
|
+
Call.libusb_free_transfer(self)
|
559
|
+
return unless @ctx
|
560
|
+
@ctx.unref_context
|
561
|
+
end
|
562
|
+
# The ctx pointer is not yet assigned.
|
563
|
+
# It happens at LIBUSB::Transfer#dev_handle= later on.
|
564
|
+
ptr.instance_variable_set(:@ctx, nil)
|
565
|
+
ObjectSpace.define_finalizer(self, ptr.method(:free_struct))
|
450
566
|
end
|
451
567
|
end
|
452
568
|
|
data/lib/libusb/configuration.rb
CHANGED
@@ -16,8 +16,9 @@
|
|
16
16
|
require 'libusb/call'
|
17
17
|
|
18
18
|
module LIBUSB
|
19
|
-
class Configuration < FFI::
|
19
|
+
class Configuration < FFI::Struct
|
20
20
|
include Comparable
|
21
|
+
include ContextReference
|
21
22
|
|
22
23
|
layout :bLength, :uint8,
|
23
24
|
:bDescriptorType, :uint8,
|
@@ -108,10 +109,8 @@ module LIBUSB
|
|
108
109
|
def initialize(device, *args)
|
109
110
|
@device = device
|
110
111
|
super(*args)
|
111
|
-
end
|
112
112
|
|
113
|
-
|
114
|
-
Call.libusb_free_config_descriptor(ptr)
|
113
|
+
register_context(device.context.instance_variable_get(:@ctx), :libusb_free_config_descriptor)
|
115
114
|
end
|
116
115
|
|
117
116
|
# @return [Device] the device this configuration belongs to.
|
data/lib/libusb/constants.rb
CHANGED
@@ -34,6 +34,7 @@ module LIBUSB
|
|
34
34
|
Call::HotplugEvents,
|
35
35
|
Call::HotplugFlags,
|
36
36
|
Call::LogLevels,
|
37
|
+
Call::LogCbMode,
|
37
38
|
Call::Options,
|
38
39
|
].each do |enum|
|
39
40
|
enum.to_h.each{|k,v| const_set(k,v) }
|
@@ -52,6 +53,9 @@ module LIBUSB
|
|
52
53
|
end
|
53
54
|
end
|
54
55
|
|
56
|
+
class RemainingReferencesError < Error
|
57
|
+
end
|
58
|
+
|
55
59
|
# @private
|
56
60
|
ErrorClassForResult = {}
|
57
61
|
|
data/lib/libusb/context.rb
CHANGED
@@ -95,23 +95,87 @@ module LIBUSB
|
|
95
95
|
end
|
96
96
|
end
|
97
97
|
|
98
|
-
|
99
98
|
# Initialize libusb context.
|
100
|
-
|
99
|
+
#
|
100
|
+
# @param [Hash{Call::Options => Object}] options Options are available since libusb-1.0.27
|
101
|
+
# @option options [Integer, Symbol] :OPTION_LOG_LEVEL The log Level as a Integer or Symbol. See Call::LogLevels
|
102
|
+
# @option options [nil] :OPTION_USE_USBDK Enable the use of USBDK driver. Pass a +nil+ as value like so: +OPTION_USE_USBDK: nil+
|
103
|
+
# @option options [nil] :OPTION_NO_DEVICE_DISCOVERY Disable device discovery for use with libusb_wrap_sys_device(). Pass a +nil+ as value like so: +OPTION_NO_DEVICE_DISCOVERY: nil+
|
104
|
+
# @option options [Proc] :OPTION_LOG_CB Set a context related log callback Proc. It is called with parameters (context, level, logstring).
|
105
|
+
def initialize(options={})
|
101
106
|
m = FFI::MemoryPointer.new :pointer
|
102
|
-
|
103
|
-
|
107
|
+
if options.empty?
|
108
|
+
res = Call.libusb_init(m)
|
109
|
+
LIBUSB.raise_error res, "in libusb_init" if res!=0
|
110
|
+
else
|
111
|
+
raise ArgumentError, "options require libusb-1.0.27+" unless Call.respond_to?(:libusb_init_context)
|
112
|
+
i_opts = options.size
|
113
|
+
p_opts = FFI::MemoryPointer.new(Call::InitOption, i_opts)
|
114
|
+
options.each_with_index do |(k, v), i|
|
115
|
+
opt = Call::InitOption.new(p_opts + i * Call::InitOption.size)
|
116
|
+
opt[:option] = k
|
117
|
+
|
118
|
+
ffitype, ffival = LIBUSB.send(:option_args_to_ffi, k, Array(v), self)
|
119
|
+
case ffitype
|
120
|
+
when NilClass then nil
|
121
|
+
when :libusb_log_level then
|
122
|
+
opt[:value][:ival] = ffival
|
123
|
+
when :libusb_log_cb then
|
124
|
+
opt[:value][:log_cbval] = ffival
|
125
|
+
else raise ArgumentError, "internal error: unexpected ffitype: #{ffitype.inspect}"
|
126
|
+
end
|
127
|
+
end
|
128
|
+
res = Call.libusb_init_context(m, p_opts, i_opts)
|
129
|
+
LIBUSB.raise_error res, "in libusb_init_context" if res!=0
|
130
|
+
end
|
104
131
|
@ctx = m.read_pointer
|
105
132
|
@on_pollfd_added = nil
|
106
133
|
@on_pollfd_removed = nil
|
107
134
|
@hotplug_callbacks = {}
|
135
|
+
|
136
|
+
def @ctx.free_context(id)
|
137
|
+
@free_context = true
|
138
|
+
if @refs == 0
|
139
|
+
# puts "final libusb_exit #{to_i} #{id} #{caller[0]}"
|
140
|
+
if id # Is Context is about to be garbage collected?
|
141
|
+
# In GC mode there's no way to call the registered collbacks, since they are GC'ed as well.
|
142
|
+
# So disable callbacks now.
|
143
|
+
Call.libusb_set_log_cb(self, nil, LOG_CB_CONTEXT)
|
144
|
+
Call.libusb_set_pollfd_notifiers(self, nil, nil, nil)
|
145
|
+
end
|
146
|
+
Call.libusb_exit(self)
|
147
|
+
@refs = nil
|
148
|
+
end
|
149
|
+
end
|
150
|
+
def @ctx.ref_context
|
151
|
+
@refs += 1
|
152
|
+
# puts "ref_context #{to_i} #{@refs} #{caller[1]}"
|
153
|
+
self
|
154
|
+
end
|
155
|
+
def @ctx.unref_context
|
156
|
+
@refs -= 1
|
157
|
+
# puts "unref_context #{to_i} #{@refs}"
|
158
|
+
raise "more unref_context than ref_context" if @refs < 0
|
159
|
+
free_context(true) if @refs == 0 && @free_context
|
160
|
+
self
|
161
|
+
end
|
162
|
+
def @ctx.setref_context
|
163
|
+
@refs = 0
|
164
|
+
@free_context = false
|
165
|
+
end
|
166
|
+
def @ctx.refs
|
167
|
+
@refs
|
168
|
+
end
|
169
|
+
@ctx.setref_context
|
170
|
+
ObjectSpace.define_finalizer(self, @ctx.method(:free_context))
|
108
171
|
end
|
109
172
|
|
110
173
|
# Deinitialize libusb.
|
111
174
|
#
|
112
175
|
# Should be called after closing all open devices and before your application terminates.
|
113
176
|
def exit
|
114
|
-
|
177
|
+
raise RemainingReferencesError, "#{@ctx.refs} remaining references to LIBUSB::Context" if @ctx.refs.to_i > 0
|
178
|
+
@ctx.free_context nil
|
115
179
|
end
|
116
180
|
|
117
181
|
# @deprecated Use {Context#set_option} instead using the +:OPTION_LOG_LEVEL+ option.
|
@@ -119,30 +183,37 @@ module LIBUSB
|
|
119
183
|
Call.libusb_set_debug(@ctx, level)
|
120
184
|
end
|
121
185
|
|
122
|
-
def
|
123
|
-
|
186
|
+
private def wrap_log_cb(block, mode)
|
187
|
+
if block
|
188
|
+
cb_proc = proc do |p_ctx, lev, str|
|
189
|
+
ctx = case p_ctx
|
190
|
+
when FFI::Pointer::NULL then nil
|
191
|
+
when @ctx then self
|
192
|
+
else p_ctx.to_i
|
193
|
+
end
|
194
|
+
block.call(ctx, lev, str)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
# Avoid garbage collection of the proc, since only the function pointer is given to libusb
|
199
|
+
if Call::LogCbMode.to_native(mode, nil) & LOG_CB_GLOBAL != 0
|
200
|
+
@@log_cb_proc = cb_proc
|
201
|
+
end
|
202
|
+
if Call::LogCbMode.to_native(mode, nil) & LOG_CB_CONTEXT != 0
|
203
|
+
@log_cb_proc = cb_proc
|
204
|
+
end
|
205
|
+
cb_proc
|
124
206
|
end
|
125
|
-
private :expect_option_args
|
126
207
|
|
127
|
-
# Set a libusb option from the {Call::Options option list}.
|
208
|
+
# Set a context related libusb option from the {Call::Options option list}.
|
128
209
|
#
|
129
210
|
# @param [Symbol, Fixnum] option
|
130
211
|
# @param args Zero or more arguments depending on +option+
|
212
|
+
# @see set_options
|
131
213
|
def set_option(option, *args)
|
132
214
|
if Call.respond_to?(:libusb_set_option)
|
133
215
|
# Available since libusb-1.0.22
|
134
|
-
|
135
|
-
ffi_args = case option
|
136
|
-
when :OPTION_LOG_LEVEL, LIBUSB::OPTION_LOG_LEVEL
|
137
|
-
expect_option_args(1, args.length)
|
138
|
-
[:libusb_log_level, args[0]]
|
139
|
-
when :OPTION_USE_USBDK, LIBUSB::OPTION_USE_USBDK
|
140
|
-
expect_option_args(0, args.length)
|
141
|
-
[]
|
142
|
-
else
|
143
|
-
raise ArgumentError, "unknown option #{option.inspect}"
|
144
|
-
end
|
145
|
-
|
216
|
+
ffi_args = LIBUSB.send(:option_args_to_ffi, option, args, self)
|
146
217
|
res = Call.libusb_set_option(@ctx, option, *ffi_args)
|
147
218
|
LIBUSB.raise_error res, "in libusb_set_option" if res<0
|
148
219
|
|
@@ -154,6 +225,69 @@ module LIBUSB
|
|
154
225
|
end
|
155
226
|
end
|
156
227
|
|
228
|
+
# Convenience function to set context related options in the libusb library.
|
229
|
+
#
|
230
|
+
# Use this function to configure any number of options within the library.
|
231
|
+
# It takes a Hash the same way as given to {Context.initialize}.
|
232
|
+
# See also {Call::Options option list}.
|
233
|
+
#
|
234
|
+
# @param [Hash{Call::Options => Object}] options Option hash
|
235
|
+
# @see set_option
|
236
|
+
def set_options(options={})
|
237
|
+
options.each do |k, v|
|
238
|
+
set_option(k, *Array(v))
|
239
|
+
end
|
240
|
+
end
|
241
|
+
|
242
|
+
if Call.respond_to?(:libusb_set_log_cb)
|
243
|
+
# Set log handler.
|
244
|
+
#
|
245
|
+
# libusb will redirect its log messages to the provided method block.
|
246
|
+
# libusb supports redirection of per context and global log messages.
|
247
|
+
# Log messages sent to the context will be sent to the global log handler too.
|
248
|
+
#
|
249
|
+
# If libusb is compiled without message logging or USE_SYSTEM_LOGGING_FACILITY
|
250
|
+
# is defined then global callback function will never be called.
|
251
|
+
# If ENABLE_DEBUG_LOGGING is defined then per context callback function will
|
252
|
+
# never be called.
|
253
|
+
#
|
254
|
+
# To disable the log callback, execute set_log_cb without a block.
|
255
|
+
#
|
256
|
+
# Available since libusb-1.0.23, LIBUSB_API_VERSION >= 0x01000107
|
257
|
+
#
|
258
|
+
# @param [Symbol, Integer] mode mode of callback function operation.
|
259
|
+
# Several modes can be selected for a single callback function, see Call::LogCbMode for a description.
|
260
|
+
#
|
261
|
+
# @yieldparam [Context, nil] context The context which is related to the log message, or +nil+ if it is a global log message.
|
262
|
+
# @yieldparam [Symbol] level The log level, see Call::LogLevels for a description.
|
263
|
+
# @yieldparam [String] str The log message.
|
264
|
+
#
|
265
|
+
# @see Call::LogCbMode
|
266
|
+
#
|
267
|
+
def set_log_cb(mode, &block)
|
268
|
+
cb_proc = wrap_log_cb(block, mode)
|
269
|
+
Call.libusb_set_log_cb(@ctx, cb_proc, mode)
|
270
|
+
self
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
if Call.respond_to?(:libusb_wrap_sys_device)
|
275
|
+
def wrap_sys_device(dev_io)
|
276
|
+
dev_io = dev_io.is_a?(IO) ? dev_io.fileno : dev_io
|
277
|
+
|
278
|
+
ppHandle = FFI::MemoryPointer.new :pointer
|
279
|
+
res = Call.libusb_wrap_sys_device(@ctx, dev_io, ppHandle)
|
280
|
+
LIBUSB.raise_error res, "in libusb_wrap_sys_device" if res!=0
|
281
|
+
handle = DevHandle.new self, ppHandle.read_pointer
|
282
|
+
return handle unless block_given?
|
283
|
+
begin
|
284
|
+
yield handle
|
285
|
+
ensure
|
286
|
+
handle.close
|
287
|
+
end
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
157
291
|
def device_list
|
158
292
|
pppDevs = FFI::MemoryPointer.new :pointer
|
159
293
|
size = Call.libusb_get_device_list(@ctx, pppDevs)
|
@@ -327,14 +461,18 @@ module LIBUSB
|
|
327
461
|
# This block will be invoked for every new file descriptor that
|
328
462
|
# libusb uses as an event source.
|
329
463
|
#
|
464
|
+
# To disable the notification callback, execute on_pollfd_added without a block.
|
465
|
+
#
|
330
466
|
# Note that file descriptors may have been added even before you register these
|
331
467
|
# notifiers (e.g. at {Context#initialize} time).
|
332
468
|
#
|
333
469
|
# @yieldparam [Pollfd] pollfd The added file descriptor is yielded to the block
|
334
470
|
def on_pollfd_added &block
|
335
|
-
@on_pollfd_added =
|
336
|
-
|
337
|
-
|
471
|
+
@on_pollfd_added = if block
|
472
|
+
proc do |fd, events, _|
|
473
|
+
pollfd = Pollfd.new fd, events
|
474
|
+
block.call pollfd
|
475
|
+
end
|
338
476
|
end
|
339
477
|
Call.libusb_set_pollfd_notifiers @ctx, @on_pollfd_added, @on_pollfd_removed, nil
|
340
478
|
end
|
@@ -344,6 +482,8 @@ module LIBUSB
|
|
344
482
|
# This block will be invoked for every removed file descriptor that
|
345
483
|
# libusb uses as an event source.
|
346
484
|
#
|
485
|
+
# To disable the notification callback, execute on_pollfd_removed without a block.
|
486
|
+
#
|
347
487
|
# Note that the removal notifier may be called during {Context#exit}
|
348
488
|
# (e.g. when it is closing file descriptors that were opened and added to the poll
|
349
489
|
# set at {Context#initialize} time). If you don't want this, overwrite the notifier
|
@@ -351,9 +491,11 @@ module LIBUSB
|
|
351
491
|
#
|
352
492
|
# @yieldparam [Pollfd] pollfd The removed file descriptor is yielded to the block
|
353
493
|
def on_pollfd_removed &block
|
354
|
-
@on_pollfd_removed =
|
355
|
-
|
356
|
-
|
494
|
+
@on_pollfd_removed = if block
|
495
|
+
proc do |fd, _|
|
496
|
+
pollfd = Pollfd.new fd
|
497
|
+
block.call pollfd
|
498
|
+
end
|
357
499
|
end
|
358
500
|
Call.libusb_set_pollfd_notifiers @ctx, @on_pollfd_added, @on_pollfd_removed, nil
|
359
501
|
end
|
@@ -393,19 +535,18 @@ module LIBUSB
|
|
393
535
|
# @yieldparam [Symbol] event a {Call::HotplugEvents HotplugEvents} symbol
|
394
536
|
# @yieldreturn [Symbol] +:finish+ to deregister the callback, +:repeat+ to receive additional events
|
395
537
|
# @raise [ArgumentError, LIBUSB::Error] in case of failure
|
396
|
-
def on_hotplug_event(
|
397
|
-
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
raise ArgumentError, "invalid params #{args.inspect}" unless args.empty?
|
538
|
+
def on_hotplug_event(events: HOTPLUG_EVENT_DEVICE_ARRIVED | HOTPLUG_EVENT_DEVICE_LEFT,
|
539
|
+
flags: 0,
|
540
|
+
vendor_id: HOTPLUG_MATCH_ANY,
|
541
|
+
product_id: HOTPLUG_MATCH_ANY,
|
542
|
+
dev_class: HOTPLUG_MATCH_ANY,
|
543
|
+
&block)
|
403
544
|
|
404
545
|
handle = HotplugCallback.new self, @ctx, @hotplug_callbacks
|
405
546
|
|
406
547
|
block2 = proc do |ctx, pDevice, event, _user_data|
|
407
548
|
raise "internal error: unexpected context" unless @ctx==ctx
|
408
|
-
dev = Device.new
|
549
|
+
dev = Device.new self, pDevice
|
409
550
|
|
410
551
|
blres = block.call(dev, event)
|
411
552
|
|
@@ -0,0 +1,38 @@
|
|
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
|
+
module LIBUSB
|
17
|
+
module ContextReference
|
18
|
+
def register_context(ctx, free_sym)
|
19
|
+
ptr = pointer
|
20
|
+
def ptr.free_struct(id)
|
21
|
+
return unless @ctx
|
22
|
+
Call.send(@free_sym, self)
|
23
|
+
@ctx.unref_context
|
24
|
+
end
|
25
|
+
ptr.instance_variable_set(:@free_sym, free_sym)
|
26
|
+
ptr.instance_variable_set(:@ctx, ctx.ref_context)
|
27
|
+
ObjectSpace.define_finalizer(self, ptr.method(:free_struct))
|
28
|
+
end
|
29
|
+
|
30
|
+
def free
|
31
|
+
ptr = pointer
|
32
|
+
ptr.free_struct nil
|
33
|
+
ptr.instance_variable_set(:@ctx, nil)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
private_constant :ContextReference
|
38
|
+
end
|
data/lib/libusb/dependencies.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
module LIBUSB
|
2
|
-
LIBUSB_VERSION = ENV['LIBUSB_VERSION'] || '1.0.
|
2
|
+
LIBUSB_VERSION = ENV['LIBUSB_VERSION'] || '1.0.27'
|
3
3
|
LIBUSB_SOURCE_URI = "https://github.com/libusb/libusb/releases/download/v#{LIBUSB_VERSION}/libusb-#{LIBUSB_VERSION}.tar.bz2"
|
4
|
-
|
4
|
+
LIBUSB_SOURCE_SHA256 = 'ffaa41d741a8a3bee244ac8e54a72ea05bf2879663c098c82fc5757853441575'
|
5
5
|
|
6
6
|
MINI_PORTILE_VERSION = '~> 2.1'
|
7
7
|
end
|