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.
@@ -95,23 +95,87 @@ module LIBUSB
95
95
  end
96
96
  end
97
97
 
98
-
99
98
  # Initialize libusb context.
100
- def initialize
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
- res = Call.libusb_init(m)
103
- LIBUSB.raise_error res, "in libusb_init" if res!=0
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
- Call.libusb_exit(@ctx)
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 expect_option_args(exp, is)
123
- raise ArgumentError, "wrong number of arguments (given #{is+1}, expected #{exp+1})" if is != exp
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 = proc do |fd, events, _|
336
- pollfd = Pollfd.new fd, events
337
- block.call pollfd
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 = proc do |fd, _|
355
- pollfd = Pollfd.new fd
356
- block.call pollfd
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(args={}, &block)
397
- events = args.delete(:events) || (HOTPLUG_EVENT_DEVICE_ARRIVED | HOTPLUG_EVENT_DEVICE_LEFT)
398
- flags = args.delete(:flags) || 0
399
- vendor_id = args.delete(:vendor_id) || HOTPLUG_MATCH_ANY
400
- product_id = args.delete(:product_id) || HOTPLUG_MATCH_ANY
401
- dev_class = args.delete(:dev_class) || HOTPLUG_MATCH_ANY
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 @ctx, pDevice
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
@@ -1,7 +1,7 @@
1
1
  module LIBUSB
2
- LIBUSB_VERSION = ENV['LIBUSB_VERSION'] || '1.0.22'
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
- LIBUSB_SOURCE_SHA1 = '10116aa265aac4273a0c894faa089370262ec0dc'
4
+ LIBUSB_SOURCE_SHA256 = 'ffaa41d741a8a3bee244ac8e54a72ea05bf2879663c098c82fc5757853441575'
5
5
 
6
6
  MINI_PORTILE_VERSION = '~> 2.1'
7
7
  end
@@ -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(args={}, &block)
376
- timeout = args.delete(:timeout) || 1000
377
- endpoint = args.delete(:endpoint) || raise(ArgumentError, "no endpoint given")
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 = args.delete(:dataIn) || raise(ArgumentError, "no :dataIn given for bulk read")
384
+ dataIn || raise(ArgumentError, "no :dataIn given for bulk read")
381
385
  else
382
- dataOut = args.delete(:dataOut) || raise(ArgumentError, "no :dataOut given for bulk write")
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: true
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(args={}, &block)
444
- timeout = args.delete(:timeout) || 1000
445
- endpoint = args.delete(:endpoint) || raise(ArgumentError, "no endpoint given")
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 = args.delete(:dataIn) || raise(ArgumentError, "no :dataIn given for interrupt read")
454
+ dataIn || raise(ArgumentError, "no :dataIn given for interrupt read")
449
455
  else
450
- dataOut = args.delete(:dataOut) || raise(ArgumentError, "no :dataOut given for interrupt write")
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: true
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(args={}, &block)
501
- bmRequestType = args.delete(:bmRequestType) || raise(ArgumentError, "param :bmRequestType not given")
502
- bRequest = args.delete(:bRequest) || raise(ArgumentError, "param :bRequest not given")
503
- wValue = args.delete(:wValue) || raise(ArgumentError, "param :wValue not given")
504
- wIndex = args.delete(:wIndex) || raise(ArgumentError, "param :wIndex not given")
505
- timeout = args.delete(:timeout) || 1000
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
- dataIn = args.delete(:dataIn) || 0
516
+ raise ArgumentError, "invalid param :dataOut" unless dataOut.nil?
517
+ dataIn ||= 0
508
518
  dataOut = ''
509
519
  else
510
- dataOut = args.delete(:dataOut) || ''
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: true
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! if @manufacturer
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! if @product
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! if @serial_number
373
+ @serial_number = @serial_number.strip if @serial_number
332
374
  @serial_number
333
375
  end
334
376
 
@@ -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
- device.context.instance_variable_get(:@ctx),
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
@@ -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
 
@@ -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
- sh_with_code "git tag -d #{version_tag}"
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 = host_platform
91
- recipe.configure_options << "--host=#{recipe.host}"
92
- recipe.configure_options << "CC=#{recipe.host}-gcc -static-libgcc" if recipe.host =~ /mingw/
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 win32'
102
- task :cross => [ "libusb_dll:#{ruby_platform}" ] do |t|
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 = []
@@ -11,7 +11,8 @@ module LIBUSB
11
11
  def initialize
12
12
  super("libusb", LIBUSB_VERSION)
13
13
  self.target = File.join(ROOT, "ports")
14
- self.files = [url: LIBUSB_SOURCE_URI, sha1: LIBUSB_SOURCE_SHA1]
14
+ self.files = [url: LIBUSB_SOURCE_URI, sha256: LIBUSB_SOURCE_SHA256]
15
+ self.patch_files = Dir[File.join(ROOT, "patches", self.name, self.version, "*.patch")].sort
15
16
  self.configure_options = []
16
17
  end
17
18
 
@@ -24,7 +25,5 @@ module LIBUSB
24
25
  self.activate
25
26
  self
26
27
  end
27
-
28
- public :files_hashs
29
28
  end
30
29
  end