libusb 0.3.4 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (136) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/Gemfile +1 -0
  5. data/History.md +10 -0
  6. data/README.md +19 -6
  7. data/Rakefile +1 -1
  8. data/ext/extconf.rb +17 -1
  9. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/AUTHORS +18 -6
  10. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/COPYING +0 -0
  11. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ChangeLog +58 -1
  12. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/INSTALL +0 -0
  13. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.am +6 -1
  14. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/Makefile.in +248 -174
  15. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/NEWS +2 -2
  16. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/PORTING +0 -0
  17. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/README +2 -1
  18. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/TODO +0 -0
  19. data/ext/libusbx-1.0.17/Xcode/common.xcconfig +40 -0
  20. data/ext/libusbx-1.0.17/Xcode/config.h +28 -0
  21. data/ext/libusbx-1.0.17/Xcode/debug.xcconfig +29 -0
  22. data/ext/libusbx-1.0.17/Xcode/libusbx.xcconfig +21 -0
  23. data/ext/libusbx-1.0.17/Xcode/libusbx.xcodeproj/project.pbxproj +864 -0
  24. data/ext/libusbx-1.0.17/Xcode/libusbx_debug.xcconfig +21 -0
  25. data/ext/libusbx-1.0.17/Xcode/libusbx_release.xcconfig +21 -0
  26. data/ext/libusbx-1.0.17/Xcode/release.xcconfig +29 -0
  27. data/ext/libusbx-1.0.17/aclocal.m4 +1112 -0
  28. data/ext/libusbx-1.0.17/android/README +114 -0
  29. data/ext/libusbx-1.0.17/android/config.h +90 -0
  30. data/ext/libusbx-1.0.17/android/jni/Android.mk +23 -0
  31. data/ext/libusbx-1.0.17/android/jni/Application.mk +19 -0
  32. data/ext/libusbx-1.0.17/android/jni/examples.mk +134 -0
  33. data/ext/libusbx-1.0.17/android/jni/libusb.mk +54 -0
  34. data/ext/libusbx-1.0.17/android/jni/tests.mk +56 -0
  35. data/ext/libusbx-1.0.17/compile +347 -0
  36. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.guess +164 -130
  37. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.h.in +37 -1
  38. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/config.sub +174 -89
  39. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure +723 -302
  40. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/configure.ac +71 -20
  41. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/depcomp +345 -185
  42. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.am +0 -0
  43. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/Makefile.in +95 -32
  44. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/doc/doxygen.cfg.in +1 -1
  45. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.am +5 -4
  46. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/Makefile.in +208 -104
  47. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp.c +1 -1
  48. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/dpfp_threaded.c +1 -1
  49. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.c +188 -8
  50. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/ezusb.h +18 -5
  51. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/fxload.c +90 -64
  52. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.c +0 -0
  53. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt.h +0 -0
  54. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/getopt/getopt1.c +0 -0
  55. data/ext/libusbx-1.0.17/examples/hotplugtest.c +97 -0
  56. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/listdevs.c +12 -4
  57. data/ext/libusbx-1.0.17/examples/sam3u_benchmark.c +193 -0
  58. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/examples/xusb.c +106 -49
  59. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/install-sh +21 -14
  60. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb-1.0.pc.in +1 -1
  61. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/Makefile.am +29 -10
  62. data/ext/libusbx-1.0.17/libusb/Makefile.in +914 -0
  63. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/core.c +378 -87
  64. data/ext/libusbx-1.0.17/libusb/descriptor.c +1199 -0
  65. data/ext/libusbx-1.0.17/libusb/hotplug.c +322 -0
  66. data/ext/libusbx-1.0.17/libusb/hotplug.h +82 -0
  67. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/io.c +182 -62
  68. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.def +32 -0
  69. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb-1.0.rc +2 -0
  70. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusb.h +481 -32
  71. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/libusbi.h +135 -38
  72. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.c +591 -496
  73. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/darwin_usb.h +39 -46
  74. data/ext/libusbx-1.0.17/libusb/os/linux_netlink.c +345 -0
  75. data/ext/libusbx-1.0.17/libusb/os/linux_udev.c +306 -0
  76. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.c +653 -617
  77. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/linux_usbfs.h +32 -0
  78. data/ext/{libusbx-1.0.14/libusb/os/openbsd_usb.c → libusbx-1.0.17/libusb/os/netbsd_usb.c} +70 -63
  79. data/ext/libusbx-1.0.17/libusb/os/openbsd_usb.c +823 -0
  80. data/ext/libusbx-1.0.17/libusb/os/poll_posix.c +51 -0
  81. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_posix.h +2 -1
  82. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.c +85 -106
  83. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/poll_windows.h +14 -3
  84. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.c +3 -1
  85. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_posix.h +0 -0
  86. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.c +6 -5
  87. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/threads_windows.h +0 -0
  88. data/ext/libusbx-1.0.17/libusb/os/wince_usb.c +1026 -0
  89. data/ext/libusbx-1.0.17/libusb/os/wince_usb.h +131 -0
  90. data/ext/libusbx-1.0.17/libusb/os/windows_common.h +108 -0
  91. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.c +92 -57
  92. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/os/windows_usb.h +2 -63
  93. data/ext/libusbx-1.0.17/libusb/strerror.c +184 -0
  94. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/sync.c +24 -38
  95. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/libusb/version.h +1 -1
  96. data/ext/libusbx-1.0.17/libusb/version_nano.h +1 -0
  97. data/ext/{libusbx-1.0.14 → libusbx-1.0.17}/ltmain.sh +60 -41
  98. data/ext/{libusbx-1.0.14/aclocal.m4 → libusbx-1.0.17/m4/libtool.m4} +229 -1723
  99. data/ext/libusbx-1.0.17/m4/ltoptions.m4 +384 -0
  100. data/ext/libusbx-1.0.17/m4/ltsugar.m4 +123 -0
  101. data/ext/libusbx-1.0.17/m4/ltversion.m4 +23 -0
  102. data/ext/libusbx-1.0.17/m4/lt~obsolete.m4 +98 -0
  103. data/ext/libusbx-1.0.17/missing +215 -0
  104. data/ext/libusbx-1.0.17/tests/Makefile.am +6 -0
  105. data/ext/libusbx-1.0.17/tests/Makefile.in +583 -0
  106. data/ext/libusbx-1.0.17/tests/libusbx_testlib.h +107 -0
  107. data/ext/libusbx-1.0.17/tests/stress.c +160 -0
  108. data/ext/libusbx-1.0.17/tests/testlib.c +276 -0
  109. data/lib/libusb.rb +4 -0
  110. data/lib/libusb/call.rb +43 -1
  111. data/lib/libusb/constants.rb +5 -0
  112. data/lib/libusb/context.rb +100 -0
  113. data/lib/libusb/dev_handle.rb +27 -0
  114. data/lib/libusb/device.rb +10 -4
  115. data/lib/libusb/version_gem.rb +1 -1
  116. data/test/test_libusb_capability.rb +2 -2
  117. data/test/test_libusb_compat.rb +2 -2
  118. data/test/test_libusb_compat_mass_storage.rb +2 -2
  119. data/test/test_libusb_descriptors.rb +4 -2
  120. data/test/test_libusb_event_machine.rb +2 -2
  121. data/test/test_libusb_gc.rb +2 -2
  122. data/test/test_libusb_hotplug.rb +115 -0
  123. data/test/test_libusb_iso_transfer.rb +3 -3
  124. data/test/test_libusb_mass_storage.rb +6 -16
  125. data/test/test_libusb_mass_storage2.rb +26 -3
  126. data/test/test_libusb_structs.rb +2 -2
  127. data/test/test_libusb_threads.rb +2 -2
  128. data/test/test_libusb_version.rb +2 -2
  129. metadata +127 -68
  130. metadata.gz.sig +0 -0
  131. data/ext/libusbx-1.0.14/THANKS +0 -7
  132. data/ext/libusbx-1.0.14/compile +0 -143
  133. data/ext/libusbx-1.0.14/libusb/Makefile.in +0 -721
  134. data/ext/libusbx-1.0.14/libusb/descriptor.c +0 -731
  135. data/ext/libusbx-1.0.14/libusb/version_nano.h +0 -1
  136. data/ext/libusbx-1.0.14/missing +0 -376
data/lib/libusb.rb CHANGED
@@ -47,5 +47,9 @@ module LIBUSB
47
47
  r = Call.libusb_has_capability(capability)
48
48
  return r != 0
49
49
  end
50
+ else
51
+ def self.has_capability?(capability)
52
+ false
53
+ end
50
54
  end
51
55
  end
data/lib/libusb/call.rb CHANGED
@@ -149,11 +149,44 @@ module LIBUSB
149
149
  ]
150
150
 
151
151
  Capabilities = enum :libusb_capability, [
152
- :CAP_HAS_CAPABILITY, 0,
152
+ :CAP_HAS_CAPABILITY, 0x0000,
153
+ # Hotplug support is available on this platform.
154
+ :CAP_HAS_HOTPLUG, 0x0001,
155
+ # The library can access HID devices without requiring user intervention.
156
+ # Note that before being able to actually access an HID device, you may
157
+ # still have to call additional libusb functions such as
158
+ # {DevHandle#detach_kernel_driver}.
159
+ :CAP_HAS_HID_ACCESS, 0x0100,
160
+ # The library supports detaching of the default USB driver, using
161
+ # {DevHandle#detach_kernel_driver}, if one is set by the OS kernel.
162
+ :CAP_SUPPORTS_DETACH_KERNEL_DRIVER, 0x0101,
163
+ ]
164
+
165
+ # Since libusb version 1.0.16.
166
+ #
167
+ # Hotplug events
168
+ HotplugEvents = enum :libusb_hotplug_event, [
169
+ # A device has been plugged in and is ready to use.
170
+ :HOTPLUG_EVENT_DEVICE_ARRIVED, 0x01,
171
+
172
+ # A device has left and is no longer available.
173
+ # It is the user's responsibility to call libusb_close on any handle associated with a disconnected device.
174
+ # It is safe to call libusb_get_device_descriptor on a device that has left.
175
+ :HOTPLUG_EVENT_DEVICE_LEFT, 0x02,
176
+ ]
177
+
178
+ # Since libusb version 1.0.16.
179
+ #
180
+ # Flags for hotplug events */
181
+ HotplugFlags = enum :libusb_hotplug_flag, [
182
+ # Arm the callback and fire it for all matching currently attached devices.
183
+ :HOTPLUG_ENUMERATE, 1,
153
184
  ]
154
185
 
155
186
  typedef :pointer, :libusb_context
187
+ typedef :pointer, :libusb_device
156
188
  typedef :pointer, :libusb_device_handle
189
+ typedef :int, :libusb_hotplug_callback_handle
157
190
 
158
191
  def self.try_attach_function(method, *args)
159
192
  if ffi_libraries.find{|lib| lib.find_function(method) }
@@ -182,6 +215,7 @@ module LIBUSB
182
215
  try_attach_function 'libusb_get_port_number', [:pointer], :uint8
183
216
  try_attach_function 'libusb_get_parent', [:pointer], :pointer
184
217
  try_attach_function 'libusb_get_port_path', [:pointer, :pointer, :pointer, :uint8], :uint8
218
+ try_attach_function 'libusb_get_port_numbers', [:pointer, :pointer, :uint8], :uint8
185
219
  attach_function 'libusb_get_device_address', [:pointer], :uint8
186
220
  try_attach_function 'libusb_get_device_speed', [:pointer], :libusb_speed
187
221
  attach_function 'libusb_get_max_packet_size', [:pointer, :uint8], :int
@@ -204,6 +238,7 @@ module LIBUSB
204
238
  attach_function 'libusb_kernel_driver_active', [:libusb_device_handle, :int], :int
205
239
  attach_function 'libusb_detach_kernel_driver', [:libusb_device_handle, :int], :int
206
240
  attach_function 'libusb_attach_kernel_driver', [:libusb_device_handle, :int], :int
241
+ try_attach_function 'libusb_set_auto_detach_kernel_driver', [:libusb_device_handle, :int], :int
207
242
 
208
243
  attach_function 'libusb_get_string_descriptor_ascii', [:pointer, :uint8, :pointer, :int], :int
209
244
 
@@ -226,6 +261,13 @@ module LIBUSB
226
261
 
227
262
  callback :libusb_transfer_cb_fn, [:pointer], :void
228
263
 
264
+ callback :libusb_hotplug_callback_fn, [:libusb_context, :libusb_device, :libusb_hotplug_event, :pointer], :int
265
+ try_attach_function 'libusb_hotplug_register_callback', [
266
+ :libusb_context, :libusb_hotplug_event, :libusb_hotplug_flag,
267
+ :int, :int, :int, :libusb_hotplug_callback_fn,
268
+ :pointer, :pointer], :int
269
+ try_attach_function 'libusb_hotplug_deregister_callback', [:libusb_context, :libusb_hotplug_callback_handle], :void
270
+
229
271
  class IsoPacketDescriptor < FFI::Struct
230
272
  layout :length, :uint,
231
273
  :actual_length, :uint,
@@ -26,6 +26,8 @@ module LIBUSB
26
26
  Call::IsoSyncTypes.to_h.each{|k,v| const_set(k,v) }
27
27
  Call::Speeds.to_h.each{|k,v| const_set(k,v) }
28
28
  Call::Capabilities.to_h.each{|k,v| const_set(k,v) }
29
+ Call::HotplugEvents.to_h.each{|k,v| const_set(k,v) }
30
+ Call::HotplugFlags.to_h.each{|k,v| const_set(k,v) }
29
31
 
30
32
  # Base class of libusb errors
31
33
  class Error < RuntimeError
@@ -73,6 +75,9 @@ module LIBUSB
73
75
  POLLIN = 1
74
76
  POLLOUT = 4
75
77
 
78
+ # Wildcard matching for hotplug events.
79
+ HOTPLUG_MATCH_ANY = -1
80
+
76
81
 
77
82
  # http://www.usb.org/developers/defined_class
78
83
  # @private
@@ -70,6 +70,31 @@ module LIBUSB
70
70
  end
71
71
  end
72
72
 
73
+ class HotplugCallback < FFI::Struct
74
+ layout :handle, :int
75
+
76
+ attr_reader :context
77
+
78
+ # @private
79
+ def initialize(context, ctx, callbacks)
80
+ super()
81
+ @context = context
82
+ @ctx = ctx
83
+ @callbacks = callbacks
84
+ end
85
+
86
+ # Deregisters the hotplug callback.
87
+ #
88
+ # Deregister a callback from a {Context}. This function is safe to call from within
89
+ # a hotplug callback.
90
+ #
91
+ # Since libusb version 1.0.16.
92
+ def deregister
93
+ Call.libusb_hotplug_deregister_callback(@ctx, self[:handle])
94
+ @callbacks.delete(self[:handle])
95
+ end
96
+ end
97
+
73
98
 
74
99
  # Initialize libusb context.
75
100
  def initialize
@@ -79,6 +104,7 @@ module LIBUSB
79
104
  @ctx = m.read_pointer
80
105
  @on_pollfd_added = nil
81
106
  @on_pollfd_removed = nil
107
+ @hotplug_callbacks = {}
82
108
  end
83
109
 
84
110
  # Deinitialize libusb.
@@ -304,5 +330,79 @@ module LIBUSB
304
330
  end
305
331
  Call.libusb_set_pollfd_notifiers @ctx, @on_pollfd_added, @on_pollfd_removed, nil
306
332
  end
333
+
334
+ # Register a hotplug event notification.
335
+ #
336
+ # Register a callback with the {LIBUSB::Context}. The callback will fire
337
+ # when a matching event occurs on a matching device. The callback is armed
338
+ # until either it is deregistered with {HotplugCallback#deregister} or the
339
+ # supplied block returns +:finish+ to indicate it is finished processing events.
340
+ #
341
+ # If the flag {Call::HotplugFlags HOTPLUG_ENUMERATE} is passed the callback will be
342
+ # called with a {Call::HotplugEvents :HOTPLUG_EVENT_DEVICE_ARRIVED} for all devices
343
+ # already plugged into the machine. Note that libusb modifies its internal
344
+ # device list from a separate thread, while calling hotplug callbacks from
345
+ # {#handle_events}, so it is possible for a device to already be present
346
+ # on, or removed from, its internal device list, while the hotplug callbacks
347
+ # still need to be dispatched. This means that when using
348
+ # {Call::HotplugFlags HOTPLUG_ENUMERATE}, your callback may be called twice for the arrival
349
+ # of the same device, once from {#on_hotplug_event} and once
350
+ # from {#handle_events}; and/or your callback may be called for the
351
+ # removal of a device for which an arrived call was never made.
352
+ #
353
+ # Since libusb version 1.0.16.
354
+ #
355
+ # @param [Hash] args
356
+ # @option args [Fixnum,Symbol] :events bitwise or of events that will trigger this callback.
357
+ # Default is +LIBUSB::HOTPLUG_EVENT_DEVICE_ARRIVED|LIBUSB::HOTPLUG_EVENT_DEVICE_LEFT+ .
358
+ # See {Call::HotplugEvents HotplugEvents}
359
+ # @option args [Fixnum,Symbol] :flags hotplug callback flags. Default is 0. See {Call::HotplugFlags HotplugFlags}
360
+ # @option args [Fixnum] :vendor_id the vendor id to match. Default is {HOTPLUG_MATCH_ANY}.
361
+ # @option args [Fixnum] :product_id the product id to match. Default is {HOTPLUG_MATCH_ANY}.
362
+ # @option args [Fixnum] :dev_class the device class to match. Default is {HOTPLUG_MATCH_ANY}.
363
+ # @return [HotplugCallback] The handle to the registered callback.
364
+ #
365
+ # @yieldparam [Device] device the attached or removed {Device} is yielded to the block
366
+ # @yieldparam [Symbol] event a {Call::HotplugEvents HotplugEvents} symbol
367
+ # @yieldreturn [Symbol] +:finish+ to deregister the callback, +:repeat+ to receive additional events
368
+ # @raise [ArgumentError, LIBUSB::Error] in case of failure
369
+ def on_hotplug_event(args={}, &block)
370
+ events = args.delete(:events) || (HOTPLUG_EVENT_DEVICE_ARRIVED | HOTPLUG_EVENT_DEVICE_LEFT)
371
+ flags = args.delete(:flags) || 0
372
+ vendor_id = args.delete(:vendor_id) || HOTPLUG_MATCH_ANY
373
+ product_id = args.delete(:product_id) || HOTPLUG_MATCH_ANY
374
+ dev_class = args.delete(:dev_class) || HOTPLUG_MATCH_ANY
375
+ raise ArgumentError, "invalid params #{args.inspect}" unless args.empty?
376
+
377
+ handle = HotplugCallback.new self, @ctx, @hotplug_callbacks
378
+
379
+ block2 = proc do |ctx, pDevice, event, _user_data|
380
+ raise "internal error: unexpected context" unless @ctx==ctx
381
+ dev = Device.new @ctx, pDevice
382
+
383
+ blres = block.call(dev, event)
384
+
385
+ case blres
386
+ when :finish
387
+ 1
388
+ when :repeat
389
+ 0
390
+ else
391
+ raise ArgumentError, "hotplug event handler must return :finish or :repeat"
392
+ end
393
+ end
394
+
395
+ res = Call.libusb_hotplug_register_callback(@ctx,
396
+ events, flags,
397
+ vendor_id, product_id, dev_class,
398
+ block2, nil, handle)
399
+
400
+ LIBUSB.raise_error res, "in libusb_hotplug_register_callback" if res<0
401
+
402
+ # Avoid GC'ing of the block:
403
+ @hotplug_callbacks[handle[:handle]] = block2
404
+
405
+ return handle
406
+ end
307
407
  end
308
408
  end
@@ -225,6 +225,33 @@ module LIBUSB
225
225
  LIBUSB.raise_error res, "in libusb_attach_kernel_driver" if res!=0
226
226
  end
227
227
 
228
+ # @private
229
+ if Call.respond_to?(:libusb_set_auto_detach_kernel_driver)
230
+
231
+ # @method auto_detach_kernel_driver=
232
+ # Enable/disable libusb's automatic kernel driver detachment.
233
+ #
234
+ # When this is enabled libusb will automatically detach the kernel driver on an
235
+ # interface when claiming the interface, and attach it when releasing the
236
+ # interface.
237
+ #
238
+ # Automatic kernel driver detachment is disabled on newly opened device handles by
239
+ # default.
240
+ #
241
+ # On platforms which do not have CAP_SUPPORTS_DETACH_KERNEL_DRIVER this
242
+ # function will return ERROR_NOT_SUPPORTED, and libusb will continue as if
243
+ # this function was never called.
244
+ #
245
+ # Available since libusb-1.0.16.
246
+ #
247
+ # @param [Boolean] enable whether to enable or disable auto kernel driver detachment
248
+ #
249
+ # @see LIBUSB.has_capability?
250
+ def auto_detach_kernel_driver=(enable)
251
+ res = Call.libusb_set_auto_detach_kernel_driver(@pHandle, enable ? 1 : 0)
252
+ LIBUSB.raise_error res, "in libusb_set_auto_detach_kernel_driver" if res!=0
253
+ end
254
+ end
228
255
 
229
256
  # Perform a USB bulk transfer.
230
257
  #
data/lib/libusb/device.rb CHANGED
@@ -95,7 +95,7 @@ module LIBUSB
95
95
  # Available since libusb-1.0.12.
96
96
  #
97
97
  # @return [Fixnum, nil] the port number (+nil+ if not available)
98
- # @see #port_path
98
+ # @see #port_numbers
99
99
  def port_number
100
100
  r = Call.libusb_get_port_number(@pDev)
101
101
  r==0 ? nil : r
@@ -105,7 +105,7 @@ module LIBUSB
105
105
  # Available since libusb-1.0.12.
106
106
  #
107
107
  # @return [Device, nil] the device parent or +nil+ if not available
108
- # @see #port_path
108
+ # @see #port_numbers
109
109
  def parent
110
110
  pppDevs = FFI::MemoryPointer.new :pointer
111
111
  Call.libusb_get_device_list(@context.instance_variable_get(:@ctx), pppDevs)
@@ -122,13 +122,19 @@ module LIBUSB
122
122
  # @return [Array<Fixnum>]
123
123
  # @see #parent
124
124
  # @see #port_number
125
- def port_path
125
+ def port_numbers
126
126
  # As per the USB 3.0 specs, the current maximum limit for the depth is 7.
127
127
  path_len = 7
128
128
  pPath = FFI::MemoryPointer.new :pointer, path_len
129
- l = Call.libusb_get_port_path(@context.instance_variable_get(:@ctx), @pDev, pPath, path_len)
129
+
130
+ l = if Call.respond_to?(:libusb_get_port_numbers)
131
+ Call.libusb_get_port_numbers(@pDev, pPath, path_len)
132
+ else
133
+ Call.libusb_get_port_path(@context.instance_variable_get(:@ctx), @pDev, pPath, path_len)
134
+ end
130
135
  pPath.read_array_of_uint8(l)
131
136
  end
137
+ alias port_path port_numbers
132
138
  end
133
139
 
134
140
  if Call.respond_to?(:libusb_get_device_speed)
@@ -15,5 +15,5 @@
15
15
 
16
16
  module LIBUSB
17
17
  # Library version of libusb for Ruby
18
- VERSION = "0.3.4"
18
+ VERSION = "0.4.0"
19
19
  end
@@ -13,10 +13,10 @@
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
- require "test/unit"
16
+ require "minitest/autorun"
17
17
  require "libusb"
18
18
 
19
- class TestLibusbCapability < Test::Unit::TestCase
19
+ class TestLibusbCapability < Minitest::Test
20
20
  def test_version_parts
21
21
  assert LIBUSB.has_capability?(:CAP_HAS_CAPABILITY)
22
22
  end
@@ -13,10 +13,10 @@
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
- require "test/unit"
16
+ require "minitest/autorun"
17
17
  require "libusb/compat"
18
18
 
19
- class TestLibusbCompat < Test::Unit::TestCase
19
+ class TestLibusbCompat < Minitest::Test
20
20
  include USB
21
21
 
22
22
  attr_accessor :usb
@@ -13,10 +13,10 @@
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
- require "test/unit"
16
+ require "minitest/autorun"
17
17
  require "libusb/compat"
18
18
 
19
- class TestLibusbCompatMassStorage < Test::Unit::TestCase
19
+ class TestLibusbCompatMassStorage < Minitest::Test
20
20
  include USB
21
21
 
22
22
  attr_accessor :devh
@@ -13,10 +13,10 @@
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
- require "test/unit"
16
+ require "minitest/autorun"
17
17
  require "libusb"
18
18
 
19
- class TestLibusbDescriptors < Test::Unit::TestCase
19
+ class TestLibusbDescriptors < Minitest::Test
20
20
  include LIBUSB
21
21
 
22
22
  attr_accessor :usb
@@ -165,6 +165,8 @@ class TestLibusbDescriptors < Test::Unit::TestCase
165
165
  assert_operator dev.bus_number, :>=, 0, "#{dev.inspect} should have a bus_number"
166
166
  assert_operator dev.device_address, :>=, 0, "#{dev.inspect} should have a device_address"
167
167
  assert_operator([:SPEED_UNKNOWN, :SPEED_LOW, :SPEED_FULL, :SPEED_HIGH, :SPEED_SUPER], :include?, dev.device_speed, "#{dev.inspect} should have a device_speed")
168
+ path = dev.port_numbers
169
+ assert_kind_of Array, path, "#{dev.inspect} should have port_numbers"
168
170
  path = dev.port_path
169
171
  assert_kind_of Array, path, "#{dev.inspect} should have a port_path"
170
172
  path.each do |port|
@@ -13,12 +13,12 @@
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
- require "test/unit"
16
+ require "minitest/autorun"
17
17
  require "libusb"
18
18
  require "libusb/eventmachine"
19
19
  require "eventmachine"
20
20
 
21
- class TestLibusbEventMachine < Test::Unit::TestCase
21
+ class TestLibusbEventMachine < Minitest::Test
22
22
  include LIBUSB
23
23
  BOMS_GET_MAX_LUN = 0xFE
24
24
 
@@ -16,10 +16,10 @@
16
16
  # These tests should be started with valgrind to check for
17
17
  # invalid memmory access.
18
18
 
19
- require "test/unit"
19
+ require "minitest/autorun"
20
20
  require "libusb"
21
21
 
22
- class TestLibusbGc < Test::Unit::TestCase
22
+ class TestLibusbGc < Minitest::Test
23
23
  include LIBUSB
24
24
 
25
25
  def get_some_endpoint
@@ -0,0 +1,115 @@
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
+ require "minitest/autorun"
17
+ require "libusb"
18
+
19
+ class TestLibusbHotplug < Minitest::Test
20
+ include LIBUSB
21
+
22
+ attr_reader :ctx
23
+
24
+ def setup
25
+ @ctx = Context.new
26
+ end
27
+
28
+ def teardown
29
+ @ctx.exit
30
+ end
31
+
32
+ def test_enumerate
33
+ devs = []
34
+ ctx.on_hotplug_event :flags => HOTPLUG_ENUMERATE do |dev, event|
35
+ devs << dev
36
+ assert_equal :HOTPLUG_EVENT_DEVICE_ARRIVED, event
37
+ :repeat
38
+ end
39
+ # Not really necessary, but just to be sure that the callback was called:
40
+ ctx.handle_events 0
41
+
42
+ assert_equal ctx.devices.sort, devs.sort
43
+ end
44
+
45
+ def test_enumerate_with_left
46
+ devs = []
47
+ ctx.on_hotplug_event :flags => HOTPLUG_ENUMERATE, :events => HOTPLUG_EVENT_DEVICE_LEFT do |dev, event|
48
+ devs << dev
49
+ assert_equal :HOTPLUG_EVENT_DEVICE_ARRIVED, event
50
+ :repeat
51
+ end
52
+ # Not really necessary, but just to be sure that the callback was called:
53
+ ctx.handle_events 0
54
+
55
+ assert_equal [], devs.sort, "Enumerate should not send any LEFT events"
56
+ end
57
+
58
+ def test_deregister
59
+ handle1 = ctx.on_hotplug_event{ assert false, "Callback should not be called" }
60
+ handle2 = ctx.on_hotplug_event{ assert false, "Callback should not be called" }
61
+ handle1.deregister
62
+ handle2.deregister
63
+ ctx.handle_events 0
64
+ end
65
+
66
+ def test_wrong_yieldreturn
67
+ ex = assert_raises(ArgumentError) do
68
+ ctx.on_hotplug_event :flags => :HOTPLUG_ENUMERATE do |dev, event|
69
+ end
70
+ end
71
+
72
+ assert_match(/:finish.*:repeat/, ex.to_s, "Should give a useful hint")
73
+ end
74
+
75
+ def test_context
76
+ handle = ctx.on_hotplug_event do |dev, event|
77
+ end
78
+ assert_equal ctx, handle.context, "The callback handle should have it's context"
79
+ end
80
+
81
+ def test_real_device_plugging_and_yieldreturn_and_gc_and_deregister
82
+ # This callback should be triggered once
83
+ devs = []
84
+ ctx.on_hotplug_event do |dev, event|
85
+ devs << [dev, event]
86
+ :finish
87
+ end
88
+
89
+ # This callback should be triggered twice
90
+ devs2 = []
91
+ ctx.on_hotplug_event do |dev, event|
92
+ devs2 << [dev, event]
93
+ puts format(" %p: %p", event, dev)
94
+ :repeat
95
+ end
96
+
97
+ # This callback should never be triggered
98
+ handle = ctx.on_hotplug_event{ assert false, "Deregistered callback should never be called" }
99
+
100
+ # GC shouldn't free any relevant callbacks or blocks
101
+ GC.start
102
+
103
+ print "\nPlease add and remove an USB device (2*5 sec): "
104
+ handle.deregister
105
+ ctx.handle_events 0
106
+ ctx.handle_events 5000
107
+ ctx.handle_events 5000
108
+
109
+ skip if devs.empty? && devs2.empty?
110
+ assert_equal 1, devs.length, "Should be deregistered after the first event"
111
+ assert_equal 2, devs2.length, "Should have received two events"
112
+ assert_operator devs2.map(&:last), :include?, :HOTPLUG_EVENT_DEVICE_ARRIVED, "Should have received ARRIVED"
113
+ assert_operator devs2.map(&:last), :include?, :HOTPLUG_EVENT_DEVICE_LEFT, "Should have received LEFT"
114
+ end
115
+ end