libusb 0.6.3-x86-mingw32 → 0.7.0-x86-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 +5 -5
- data/.appveyor.yml +33 -0
- data/.github/workflows/ci.yml +185 -0
- data/.gitignore +1 -0
- data/.travis.yml +17 -10
- data/Gemfile +9 -1
- data/History.md +57 -0
- data/README.md +30 -5
- data/Rakefile +41 -12
- data/lib/libusb/bos.rb +85 -29
- data/lib/libusb/call.rb +192 -16
- data/lib/libusb/configuration.rb +3 -4
- data/lib/libusb/constants.rb +26 -16
- data/lib/libusb/context.rb +195 -45
- data/{test/test_libusb_capability.rb → lib/libusb/context_reference.rb} +20 -5
- 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 +48 -7
- 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 +2 -4
- data/test/{test_libusb_version.rb → test_libusb.rb} +12 -10
- data/test/test_libusb_bos.rb +22 -0
- data/test/test_libusb_bulk_stream_transfer.rb +23 -12
- data/test/test_libusb_context.rb +88 -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
- data/test/test_libusb_structs.rb +32 -3
- metadata +11 -51
- data/appveyor.yml +0 -37
data/lib/libusb/context.rb
CHANGED
@@ -95,54 +95,197 @@ 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
|
-
#
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
181
|
+
# @deprecated Use {Context#set_option} instead using the +:OPTION_LOG_LEVEL+ option.
|
182
|
+
def debug=(level)
|
183
|
+
Call.libusb_set_debug(@ctx, level)
|
184
|
+
end
|
185
|
+
|
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
|
206
|
+
end
|
207
|
+
|
208
|
+
# Set a context related libusb option from the {Call::Options option list}.
|
136
209
|
#
|
137
|
-
#
|
138
|
-
#
|
210
|
+
# @param [Symbol, Fixnum] option
|
211
|
+
# @param args Zero or more arguments depending on +option+
|
212
|
+
# @see set_options
|
213
|
+
def set_option(option, *args)
|
214
|
+
if Call.respond_to?(:libusb_set_option)
|
215
|
+
# Available since libusb-1.0.22
|
216
|
+
ffi_args = LIBUSB.send(:option_args_to_ffi, option, args, self)
|
217
|
+
res = Call.libusb_set_option(@ctx, option, *ffi_args)
|
218
|
+
LIBUSB.raise_error res, "in libusb_set_option" if res<0
|
219
|
+
|
220
|
+
else
|
221
|
+
# Fallback to deprecated function, if the gem is linked to an older libusb.
|
222
|
+
|
223
|
+
raise ArgumentError, "unknown option #{option.inspect}" unless [:OPTION_LOG_LEVEL, LIBUSB::OPTION_LOG_LEVEL].include?(option)
|
224
|
+
Call.libusb_set_debug(@ctx, *args)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# Convenience function to set context related options in the libusb library.
|
139
229
|
#
|
140
|
-
#
|
141
|
-
#
|
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}.
|
142
233
|
#
|
143
|
-
# @param [
|
144
|
-
|
145
|
-
|
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
|
146
289
|
end
|
147
290
|
|
148
291
|
def device_list
|
@@ -318,14 +461,18 @@ module LIBUSB
|
|
318
461
|
# This block will be invoked for every new file descriptor that
|
319
462
|
# libusb uses as an event source.
|
320
463
|
#
|
464
|
+
# To disable the notification callback, execute on_pollfd_added without a block.
|
465
|
+
#
|
321
466
|
# Note that file descriptors may have been added even before you register these
|
322
467
|
# notifiers (e.g. at {Context#initialize} time).
|
323
468
|
#
|
324
469
|
# @yieldparam [Pollfd] pollfd The added file descriptor is yielded to the block
|
325
470
|
def on_pollfd_added &block
|
326
|
-
@on_pollfd_added =
|
327
|
-
|
328
|
-
|
471
|
+
@on_pollfd_added = if block
|
472
|
+
proc do |fd, events, _|
|
473
|
+
pollfd = Pollfd.new fd, events
|
474
|
+
block.call pollfd
|
475
|
+
end
|
329
476
|
end
|
330
477
|
Call.libusb_set_pollfd_notifiers @ctx, @on_pollfd_added, @on_pollfd_removed, nil
|
331
478
|
end
|
@@ -335,6 +482,8 @@ module LIBUSB
|
|
335
482
|
# This block will be invoked for every removed file descriptor that
|
336
483
|
# libusb uses as an event source.
|
337
484
|
#
|
485
|
+
# To disable the notification callback, execute on_pollfd_removed without a block.
|
486
|
+
#
|
338
487
|
# Note that the removal notifier may be called during {Context#exit}
|
339
488
|
# (e.g. when it is closing file descriptors that were opened and added to the poll
|
340
489
|
# set at {Context#initialize} time). If you don't want this, overwrite the notifier
|
@@ -342,9 +491,11 @@ module LIBUSB
|
|
342
491
|
#
|
343
492
|
# @yieldparam [Pollfd] pollfd The removed file descriptor is yielded to the block
|
344
493
|
def on_pollfd_removed &block
|
345
|
-
@on_pollfd_removed =
|
346
|
-
|
347
|
-
|
494
|
+
@on_pollfd_removed = if block
|
495
|
+
proc do |fd, _|
|
496
|
+
pollfd = Pollfd.new fd
|
497
|
+
block.call pollfd
|
498
|
+
end
|
348
499
|
end
|
349
500
|
Call.libusb_set_pollfd_notifiers @ctx, @on_pollfd_added, @on_pollfd_removed, nil
|
350
501
|
end
|
@@ -384,19 +535,18 @@ module LIBUSB
|
|
384
535
|
# @yieldparam [Symbol] event a {Call::HotplugEvents HotplugEvents} symbol
|
385
536
|
# @yieldreturn [Symbol] +:finish+ to deregister the callback, +:repeat+ to receive additional events
|
386
537
|
# @raise [ArgumentError, LIBUSB::Error] in case of failure
|
387
|
-
def on_hotplug_event(
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
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)
|
394
544
|
|
395
545
|
handle = HotplugCallback.new self, @ctx, @hotplug_callbacks
|
396
546
|
|
397
547
|
block2 = proc do |ctx, pDevice, event, _user_data|
|
398
548
|
raise "internal error: unexpected context" unless @ctx==ctx
|
399
|
-
dev = Device.new
|
549
|
+
dev = Device.new self, pDevice
|
400
550
|
|
401
551
|
blres = block.call(dev, event)
|
402
552
|
|
@@ -13,11 +13,26 @@
|
|
13
13
|
# You should have received a copy of the GNU Lesser General Public License
|
14
14
|
# along with Libusb for Ruby. If not, see <http://www.gnu.org/licenses/>.
|
15
15
|
|
16
|
-
|
17
|
-
|
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
|
18
29
|
|
19
|
-
|
20
|
-
|
21
|
-
|
30
|
+
def free
|
31
|
+
ptr = pointer
|
32
|
+
ptr.free_struct nil
|
33
|
+
ptr.instance_variable_set(:@ctx, nil)
|
34
|
+
end
|
22
35
|
end
|
36
|
+
|
37
|
+
private_constant :ContextReference
|
23
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
|
data/lib/libusb/dev_handle.rb
CHANGED
@@ -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(
|
376
|
-
|
377
|
-
|
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
|
384
|
+
dataIn || raise(ArgumentError, "no :dataIn given for bulk read")
|
381
385
|
else
|
382
|
-
dataOut
|
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:
|
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(
|
444
|
-
|
445
|
-
|
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
|
454
|
+
dataIn || raise(ArgumentError, "no :dataIn given for interrupt read")
|
449
455
|
else
|
450
|
-
dataOut
|
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:
|
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(
|
501
|
-
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
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
|
-
|
516
|
+
raise ArgumentError, "invalid param :dataOut" unless dataOut.nil?
|
517
|
+
dataIn ||= 0
|
508
518
|
dataOut = ''
|
509
519
|
else
|
510
|
-
|
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:
|
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
|
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
|
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
|
373
|
+
@serial_number = @serial_number.strip if @serial_number
|
332
374
|
@serial_number
|
333
375
|
end
|
334
376
|
|
data/lib/libusb/endpoint.rb
CHANGED
@@ -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
|
-
|
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
|
data/lib/libusb/eventmachine.rb
CHANGED
@@ -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
|
|
data/lib/libusb/gem_helper.rb
CHANGED
@@ -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
|
-
|
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 =
|
91
|
-
recipe.configure_options << "--host=#{
|
92
|
-
recipe.configure_options << "CC=#{
|
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
|
102
|
-
task :cross =>
|
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 = []
|