libusb 0.6.4-x86-mingw32 → 0.7.1-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 +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 +46 -0
- data/README.md +29 -4
- data/Rakefile +43 -14
- 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/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
|
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_with_status %W[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 = []
|
data/lib/libusb/libusb_recipe.rb
CHANGED
@@ -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,
|
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
|