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.
- 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
|