libusb 0.7.0-x64-mingw-ucrt

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.
Files changed (52) hide show
  1. checksums.yaml +7 -0
  2. data/.appveyor.yml +33 -0
  3. data/.github/workflows/ci.yml +185 -0
  4. data/.gitignore +9 -0
  5. data/.travis.yml +26 -0
  6. data/.yardopts +6 -0
  7. data/COPYING +165 -0
  8. data/Gemfile +19 -0
  9. data/History.md +193 -0
  10. data/README.md +184 -0
  11. data/Rakefile +79 -0
  12. data/lib/libusb/bos.rb +362 -0
  13. data/lib/libusb/call.rb +622 -0
  14. data/lib/libusb/compat.rb +376 -0
  15. data/lib/libusb/configuration.rb +154 -0
  16. data/lib/libusb/constants.rb +170 -0
  17. data/lib/libusb/context.rb +576 -0
  18. data/lib/libusb/context_reference.rb +38 -0
  19. data/lib/libusb/dependencies.rb +7 -0
  20. data/lib/libusb/dev_handle.rb +574 -0
  21. data/lib/libusb/device.rb +407 -0
  22. data/lib/libusb/endpoint.rb +195 -0
  23. data/lib/libusb/eventmachine.rb +187 -0
  24. data/lib/libusb/gem_helper.rb +151 -0
  25. data/lib/libusb/interface.rb +60 -0
  26. data/lib/libusb/libusb_recipe.rb +29 -0
  27. data/lib/libusb/setting.rb +132 -0
  28. data/lib/libusb/ss_companion.rb +72 -0
  29. data/lib/libusb/stdio.rb +25 -0
  30. data/lib/libusb/transfer.rb +418 -0
  31. data/lib/libusb/version_gem.rb +19 -0
  32. data/lib/libusb/version_struct.rb +63 -0
  33. data/lib/libusb-1.0.dll +0 -0
  34. data/lib/libusb.rb +146 -0
  35. data/libusb.gemspec +28 -0
  36. data/test/test_libusb.rb +42 -0
  37. data/test/test_libusb_bos.rb +140 -0
  38. data/test/test_libusb_bulk_stream_transfer.rb +61 -0
  39. data/test/test_libusb_compat.rb +78 -0
  40. data/test/test_libusb_compat_mass_storage.rb +81 -0
  41. data/test/test_libusb_context.rb +88 -0
  42. data/test/test_libusb_descriptors.rb +245 -0
  43. data/test/test_libusb_event_machine.rb +118 -0
  44. data/test/test_libusb_gc.rb +52 -0
  45. data/test/test_libusb_hotplug.rb +129 -0
  46. data/test/test_libusb_iso_transfer.rb +56 -0
  47. data/test/test_libusb_mass_storage.rb +268 -0
  48. data/test/test_libusb_mass_storage2.rb +96 -0
  49. data/test/test_libusb_structs.rb +87 -0
  50. data/test/test_libusb_threads.rb +89 -0
  51. data/wireshark-usb-sniffer.png +0 -0
  52. metadata +112 -0
@@ -0,0 +1,245 @@
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 TestLibusbDescriptors < Minitest::Test
20
+ include LIBUSB
21
+
22
+ attr_accessor :usb
23
+
24
+ def setup
25
+ @usb = Context.new
26
+ @usb.debug = 0
27
+ end
28
+
29
+ def test_descriptors
30
+ usb.devices.each do |dev|
31
+ assert_match(/Device/, dev.inspect, "Device#inspect should work")
32
+
33
+ assert_kind_of Integer, dev.bLength
34
+ assert_equal 1, dev.bDescriptorType
35
+ assert_kind_of Integer, dev.bcdUSB
36
+ assert_kind_of Integer, dev.bDeviceClass
37
+ assert_kind_of Integer, dev.bDeviceSubClass
38
+ assert_kind_of Integer, dev.bDeviceProtocol
39
+ assert_kind_of Integer, dev.bMaxPacketSize0
40
+ assert_kind_of Integer, dev.idVendor
41
+ assert_kind_of Integer, dev.idProduct
42
+ assert_kind_of Integer, dev.bcdDevice
43
+ assert_kind_of Integer, dev.iManufacturer
44
+ assert_kind_of Integer, dev.iProduct
45
+ assert_kind_of Integer, dev.iSerialNumber
46
+ assert_kind_of Integer, dev.bNumConfigurations
47
+
48
+ dev.configurations.each do |config_desc|
49
+ assert_match(/Configuration/, config_desc.inspect, "ConfigDescriptor#inspect should work")
50
+ assert dev.configurations.include?(config_desc), "Device#configurations should include this one"
51
+
52
+ assert_kind_of Integer, config_desc.bLength
53
+ assert_equal 2, config_desc.bDescriptorType
54
+ assert_kind_of Integer, config_desc.wTotalLength
55
+ assert_equal config_desc.interfaces.length, config_desc.bNumInterfaces
56
+ assert_kind_of Integer, config_desc.bConfigurationValue
57
+ assert_kind_of Integer, config_desc.iConfiguration
58
+ assert_kind_of Integer, config_desc.bmAttributes
59
+ assert_kind_of Integer, config_desc.bMaxPower
60
+ assert_kind_of Integer, config_desc.maxPower # deprecated
61
+ assert_kind_of String, config_desc.extra if config_desc.extra
62
+
63
+ config_desc.interfaces.each do |interface|
64
+ assert_match(/Interface/, interface.inspect, "Interface#inspect should work")
65
+
66
+ assert dev.interfaces.include?(interface), "Device#interfaces should include this one"
67
+ assert config_desc.interfaces.include?(interface), "ConfigDescriptor#interfaces should include this one"
68
+
69
+ interface.alt_settings.each do |if_desc|
70
+ assert_match(/Setting/, if_desc.inspect, "InterfaceDescriptor#inspect should work")
71
+
72
+ assert dev.settings.include?(if_desc), "Device#settings should include this one"
73
+ assert config_desc.settings.include?(if_desc), "ConfigDescriptor#settings should include this one"
74
+ assert interface.alt_settings.include?(if_desc), "Inteerface#alt_settings should include this one"
75
+
76
+ assert_kind_of Integer, if_desc.bLength
77
+ assert_equal 4, if_desc.bDescriptorType
78
+ assert_kind_of Integer, if_desc.bInterfaceNumber
79
+ assert_kind_of Integer, if_desc.bAlternateSetting
80
+ assert_equal if_desc.endpoints.length, if_desc.bNumEndpoints
81
+ assert_kind_of Integer, if_desc.bInterfaceClass
82
+ assert_kind_of Integer, if_desc.bInterfaceSubClass
83
+ assert_kind_of Integer, if_desc.bInterfaceProtocol
84
+ assert_kind_of Integer, if_desc.iInterface
85
+ assert_kind_of String, if_desc.extra if if_desc.extra
86
+
87
+ if_desc.endpoints.each do |ep|
88
+ assert_match(/Endpoint/, ep.inspect, "EndpointDescriptor#inspect should work")
89
+
90
+ assert dev.endpoints.include?(ep), "Device#endpoints should include this one"
91
+ assert config_desc.endpoints.include?(ep), "ConfigDescriptor#endpoints should include this one"
92
+ assert interface.endpoints.include?(ep), "Inteerface#endpoints should include this one"
93
+ assert if_desc.endpoints.include?(ep), "InterfaceDescriptor#endpoints should include this one"
94
+
95
+ assert_equal if_desc, ep.setting, "backref should be correct"
96
+ assert_equal interface, ep.interface, "backref should be correct"
97
+ assert_equal config_desc, ep.configuration, "backref should be correct"
98
+ assert_equal dev, ep.device, "backref should be correct"
99
+
100
+ assert_kind_of Integer, ep.bLength
101
+ assert_equal 5, ep.bDescriptorType
102
+ assert_kind_of Integer, ep.bEndpointAddress
103
+ assert_kind_of Integer, ep.bmAttributes
104
+ assert_operator 0, :<=, ep.wMaxPacketSize, "packet size should be > 0"
105
+ assert_kind_of Integer, ep.bInterval
106
+ assert_kind_of Integer, ep.bRefresh
107
+ assert_kind_of Integer, ep.bSynchAddress
108
+ assert_kind_of String, ep.extra if ep.extra
109
+ end
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+
116
+ def test_ss_companion
117
+ did_cc_companion = false
118
+ did_failing_cc_companion = false
119
+
120
+ usb.devices.each do |dev|
121
+ dev.endpoints.each do |ep|
122
+ if [:SPEED_SUPER, :SPEED_SUPER_PLUS].include?(dev.device_speed)
123
+ ss = ep.ss_companion
124
+ assert_match(/SsCompanion/, ss.inspect, "SsCompanion#inspect should work")
125
+
126
+ assert_kind_of Integer, ss.bLength
127
+ assert_equal LIBUSB::DT_SS_ENDPOINT_COMPANION, ss.bDescriptorType
128
+ assert_kind_of Integer, ss.bMaxBurst
129
+ assert_kind_of Integer, ss.bmAttributes
130
+ assert_kind_of Integer, ss.wBytesPerInterval
131
+ did_cc_companion = true
132
+ elsif !did_failing_cc_companion
133
+ assert_raises ERROR_NOT_FOUND do
134
+ ep.ss_companion
135
+ end
136
+ did_failing_cc_companion = true
137
+ end
138
+ end
139
+ end
140
+
141
+ skip "no device with cc_companion available" unless did_cc_companion
142
+ skip "no device without cc_companion available" unless did_failing_cc_companion
143
+ end
144
+
145
+ def test_constants
146
+ assert_equal 7, CLASS_PRINTER, "Printer class id should be defined"
147
+ assert_equal 48, ISO_USAGE_TYPE_MASK, "iso usage type should be defined"
148
+ end
149
+
150
+ def test_device_filter_mass_storages
151
+ devs1 = []
152
+ usb.devices.each do |dev|
153
+ dev.settings.each do |if_desc|
154
+ if if_desc.bInterfaceClass == CLASS_MASS_STORAGE &&
155
+ ( if_desc.bInterfaceSubClass == 0x01 ||
156
+ if_desc.bInterfaceSubClass == 0x06 ) &&
157
+ if_desc.bInterfaceProtocol == 0x50
158
+
159
+ devs1 << dev
160
+ end
161
+ end
162
+ end
163
+
164
+ devs2 = usb.devices( bClass: CLASS_MASS_STORAGE, bSubClass: 0x01, bProtocol: 0x50 )
165
+ devs2 += usb.devices( bClass: CLASS_MASS_STORAGE, bSubClass: 0x06, bProtocol: 0x50 )
166
+ assert_equal devs1.sort, devs2.sort, "devices and devices with filter should deliver the same device"
167
+
168
+ devs3 = usb.devices( bClass: [CLASS_MASS_STORAGE], bSubClass: [0x01,0x06], bProtocol: [0x50] )
169
+ assert_equal devs1.sort, devs3.sort, "devices and devices with array-filter should deliver the same device"
170
+ end
171
+
172
+ def test_device_filter_hubs
173
+ devs1 = []
174
+ usb.devices.each do |dev|
175
+ if dev.bDeviceClass==CLASS_PER_INTERFACE
176
+ dev.settings.each do |if_desc|
177
+ if if_desc.bInterfaceClass==CLASS_HUB
178
+ devs1 << dev
179
+ end
180
+ end
181
+ else
182
+ devs1 << dev if dev.bDeviceClass == CLASS_HUB
183
+ end
184
+ end
185
+
186
+ devs2 = usb.devices( bClass: CLASS_HUB )
187
+
188
+ assert_equal devs1.sort, devs2.sort, "devices and devices with filter should deliver the same device"
189
+ end
190
+
191
+ def test_device_methods
192
+ usb.devices.each do |dev|
193
+ ep = dev.endpoints.first
194
+ if ep
195
+ assert_operator dev.max_packet_size(ep), :>, 0, "#{dev.inspect} should have a usable packet size"
196
+ assert_operator dev.max_packet_size(ep.bEndpointAddress), :>, 0, "#{dev.inspect} should have a usable packet size"
197
+ assert_operator dev.max_iso_packet_size(ep), :>=, 0, "#{dev.inspect} should have a usable iso packet size"
198
+ assert_operator dev.max_iso_packet_size(ep.bEndpointAddress), :>=, 0, "#{dev.inspect} should have a usable iso packet size"
199
+ assert_operator dev.bus_number, :>=, 0, "#{dev.inspect} should have a bus_number"
200
+ assert_operator dev.device_address, :>=, 0, "#{dev.inspect} should have a device_address"
201
+ assert_operator([:SPEED_UNKNOWN, :SPEED_LOW, :SPEED_FULL, :SPEED_HIGH, :SPEED_SUPER, :SPEED_SUPER_PLUS], :include?, dev.device_speed, "#{dev.inspect} should have a device_speed")
202
+ path = dev.port_numbers
203
+ assert_kind_of Array, path, "#{dev.inspect} should have port_numbers"
204
+ path = dev.port_path
205
+ assert_kind_of Array, path, "#{dev.inspect} should have a port_path"
206
+ path.each do |port|
207
+ assert_operator port, :>, 0, "#{dev.inspect} should have proper port_path entries"
208
+ end
209
+ if path.empty?
210
+ assert_nil dev.port_number
211
+ else
212
+ assert_equal path[-1], dev.port_number, "#{dev.inspect} should have a port number out of the port_path"
213
+ if parent=dev.parent
214
+ assert_kind_of Device, parent, "#{dev.inspect} should have a parent"
215
+ assert_equal path[-2], parent.port_number, "#{dev.inspect} should have a parent port number out of the port_path" if parent.port_number
216
+ end
217
+ end
218
+ end
219
+ end
220
+ end
221
+
222
+ def test_wrap_sys_device
223
+ skip unless RUBY_PLATFORM =~ /linux/
224
+ d = usb.devices[0]
225
+ File.open(format("/dev/bus/usb/%03d/%03d", d.bus_number, d.device_address), "w+") do |io|
226
+ devh = usb.wrap_sys_device(io)
227
+ devh.kernel_driver_active?(0)
228
+ devh.close
229
+
230
+ usb.wrap_sys_device(io) do |devh|
231
+ devh.kernel_driver_active?(0)
232
+ end
233
+ end
234
+ end
235
+
236
+ def test_wrap_sys_device_failure
237
+ skip unless RUBY_PLATFORM =~ /linux/
238
+ d = usb.devices[0]
239
+ assert_raises(LIBUSB::ERROR_OTHER) do
240
+ File.open(format("/dev/bus/usb/%03d/%03d", d.bus_number, d.device_address), "r") do |io|
241
+ usb.wrap_sys_device(io).kernel_driver_active?(0)
242
+ end
243
+ end
244
+ end
245
+ end
@@ -0,0 +1,118 @@
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
+ require "libusb/eventmachine"
19
+ require "eventmachine"
20
+
21
+ class TestLibusbEventMachine < Minitest::Test
22
+ include LIBUSB
23
+ BOMS_GET_MAX_LUN = 0xFE
24
+
25
+ attr_accessor :context
26
+ attr_accessor :device
27
+ attr_accessor :devh
28
+ attr_accessor :endpoint_in
29
+ attr_accessor :endpoint_out
30
+
31
+ def setup
32
+ @context = Context.new
33
+ @context.debug = 3
34
+
35
+ @device = context.devices( bClass: CLASS_MASS_STORAGE, bSubClass: [0x06,0x01], bProtocol: 0x50 ).last
36
+ skip "no mass storage device found" unless @device
37
+
38
+ @endpoint_in = @device.endpoints.find{|ep| ep.bEndpointAddress&ENDPOINT_IN != 0 }
39
+ @endpoint_out = @device.endpoints.find{|ep| ep.bEndpointAddress&ENDPOINT_IN == 0 }
40
+ @devh = @device.open
41
+
42
+ if RUBY_PLATFORM=~/linux/i && devh.kernel_driver_active?(0)
43
+ devh.detach_kernel_driver(0)
44
+ end
45
+ devh.claim_interface(0)
46
+
47
+ # clear any pending data
48
+ devh.clear_halt(endpoint_in)
49
+ end
50
+
51
+ def teardown
52
+ end
53
+
54
+ def em_run
55
+ EventMachine.run do
56
+ @context.eventmachine_register
57
+
58
+ EventMachine.add_shutdown_hook do
59
+ @devh.release_interface(0) if @devh
60
+ @devh.close if @devh
61
+ @context.eventmachine_unregister
62
+ end
63
+
64
+ yield
65
+ end
66
+ end
67
+
68
+
69
+ def test_bulk_transfer
70
+ em_run do
71
+ ticks = 0
72
+ tr = devh.eventmachine_bulk_transfer(
73
+ endpoint: @endpoint_in,
74
+ timeout: 1500,
75
+ dataIn: 123 )
76
+ # puts "started usb transfer #{tr}"
77
+
78
+ tr.callback do |data|
79
+ # puts "recved: #{data.inspect}"
80
+
81
+ assert false, "the bulk transfer shouldn't succeed"
82
+ EventMachine.stop
83
+ end
84
+ tr.errback do |text|
85
+ # puts "recv-err: #{text}"
86
+ assert true, "the bulk transfer should fail"
87
+
88
+ assert_operator ticks, :>=, 4
89
+ EventMachine.stop
90
+ end
91
+
92
+ EventMachine.add_periodic_timer(0.333) do
93
+ ticks += 1
94
+ end
95
+ end
96
+ end
97
+
98
+ def test_event_loop
99
+ em_run do
100
+ tr = devh.eventmachine_control_transfer(
101
+ bmRequestType: ENDPOINT_IN|REQUEST_TYPE_CLASS|RECIPIENT_INTERFACE,
102
+ bRequest: BOMS_GET_MAX_LUN,
103
+ wValue: 0, wIndex: 0, dataIn: 1 )
104
+
105
+ # puts "started usb transfer #{tr}"
106
+ tr.callback do |data|
107
+ # puts "recved: #{data.inspect}"
108
+ assert true, "the control transfer should succeed"
109
+ EventMachine.stop
110
+ end
111
+ tr.errback do |text|
112
+ # puts "recv-err: #{text}"
113
+ assert false, "the control transfer shouldn't fail"
114
+ EventMachine.stop
115
+ end
116
+ end
117
+ end
118
+ end
@@ -0,0 +1,52 @@
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
+ # These tests should be started with valgrind to check for
17
+ # invalid memmory access.
18
+
19
+ require "minitest/autorun"
20
+ require "libusb"
21
+
22
+ class TestLibusbGc < Minitest::Test
23
+ include LIBUSB
24
+
25
+ def get_some_endpoint
26
+ Context.new.devices.each do |dev|
27
+ return dev.endpoints.last unless dev.endpoints.empty?
28
+ end
29
+ end
30
+
31
+ def test_descriptors
32
+ ep = get_some_endpoint
33
+ ps = ep.wMaxPacketSize
34
+ GC.start
35
+ assert_equal ps, ep.wMaxPacketSize, "GC should not free EndpointDescriptor"
36
+ end
37
+
38
+ def test_log_cb
39
+ LIBUSB.set_options OPTION_LOG_CB: proc{}, OPTION_LOG_LEVEL: LIBUSB::LOG_LEVEL_DEBUG
40
+
41
+ c = LIBUSB::Context.new OPTION_LOG_CB: proc{}, OPTION_NO_DEVICE_DISCOVERY: nil
42
+ GC.start
43
+ c.devices
44
+ c.set_log_cb(LIBUSB::LOG_CB_CONTEXT){}
45
+ c.devices
46
+ GC.start
47
+ c.devices
48
+
49
+ ensure
50
+ LIBUSB.set_options OPTION_LOG_CB: [nil], OPTION_LOG_LEVEL: LIBUSB::LOG_LEVEL_NONE
51
+ end
52
+ end
@@ -0,0 +1,129 @@
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
+ # No need to release the LIBUSB::Context any longer.
30
+ # It is cleaned up by the GC.
31
+ # @ctx.exit
32
+ end
33
+
34
+ def test_enumerate
35
+ devs = []
36
+ ctx.on_hotplug_event flags: HOTPLUG_ENUMERATE do |dev, event|
37
+ devs << dev
38
+ assert_equal :HOTPLUG_EVENT_DEVICE_ARRIVED, event
39
+ :repeat
40
+ end
41
+ # Not really necessary, but just to be sure that the callback was called:
42
+ ctx.handle_events 0
43
+
44
+ assert_equal ctx.devices.sort, devs.sort
45
+ end
46
+
47
+ def test_enumerate_with_left
48
+ devs = []
49
+ ctx.on_hotplug_event flags: HOTPLUG_ENUMERATE, events: HOTPLUG_EVENT_DEVICE_LEFT do |dev, event|
50
+ devs << dev
51
+ assert_equal :HOTPLUG_EVENT_DEVICE_ARRIVED, event
52
+ :repeat
53
+ end
54
+ # Not really necessary, but just to be sure that the callback was called:
55
+ ctx.handle_events 0
56
+
57
+ assert_equal [], devs.sort, "Enumerate should not send any LEFT events"
58
+ end
59
+
60
+ def test_deregister
61
+ handle1 = ctx.on_hotplug_event{ assert false, "Callback should not be called" }
62
+ handle2 = ctx.on_hotplug_event{ assert false, "Callback should not be called" }
63
+ handle1.deregister
64
+ handle2.deregister
65
+ ctx.handle_events 0
66
+ end
67
+
68
+ def test_wrong_yieldreturn
69
+ ex = assert_raises(ArgumentError) do
70
+ ctx.on_hotplug_event flags: :HOTPLUG_ENUMERATE do |dev, event|
71
+ end
72
+ end
73
+
74
+ assert_match(/:finish.*:repeat/, ex.to_s, "Should give a useful hint")
75
+ end
76
+
77
+ def test_context
78
+ handle = ctx.on_hotplug_event do |dev, event|
79
+ end
80
+ assert_equal ctx, handle.context, "The callback handle should have it's context"
81
+ end
82
+
83
+ def test_real_device_plugging_and_yieldreturn_and_gc_and_deregister
84
+ # This callback should be triggered once
85
+ devs = []
86
+ ctx.on_hotplug_event do |dev, event|
87
+ devs << [dev, event]
88
+ :finish
89
+ end
90
+
91
+ # This callback should be triggered twice
92
+ devs2 = []
93
+ ctx.on_hotplug_event do |dev, event|
94
+ devs2 << [dev, event]
95
+ puts format(" %p: %p", event, dev)
96
+ :repeat
97
+ end
98
+
99
+ # This callback should never be triggered
100
+ handle = ctx.on_hotplug_event{ assert false, "Deregistered callback should never be called" }
101
+
102
+ # GC shouldn't free any relevant callbacks or blocks
103
+ GC.start
104
+
105
+ print "\nPlease add and remove an USB device (2*5 sec): "
106
+ handle.deregister
107
+ ctx.handle_events 0
108
+ ctx.handle_events 5000
109
+ ctx.handle_events 5000
110
+
111
+ skip "no hotplug action taken" if devs.empty? && devs2.empty?
112
+ assert_equal 1, devs.length, "Should be deregistered after the first event"
113
+ assert_equal 2, devs2.length, "Should have received two events"
114
+ assert_operator devs2.map(&:last), :include?, :HOTPLUG_EVENT_DEVICE_ARRIVED, "Should have received ARRIVED"
115
+ assert_operator devs2.map(&:last), :include?, :HOTPLUG_EVENT_DEVICE_LEFT, "Should have received LEFT"
116
+ end
117
+
118
+ def test_interrupt_event_handler
119
+ th = Thread.new do
120
+ ctx.handle_events 5000
121
+ end
122
+
123
+ sleep 0.1 # Workaround a bug in libusb-1,0.21
124
+ st = Time.now
125
+ ctx.interrupt_event_handler
126
+ th.join
127
+ assert_operator Time.now-st, :<, 5.0
128
+ end
129
+ end
@@ -0,0 +1,56 @@
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 TestLibusbIsoTransfer < Minitest::Test
20
+ include LIBUSB
21
+
22
+ def setup
23
+ c = Context.new
24
+ begin
25
+ @dev = c.devices.first.open
26
+ rescue LIBUSB::ERROR_ACCESS
27
+ @dev = nil
28
+ skip "error opening device"
29
+ end
30
+ end
31
+
32
+ def teardown
33
+ @dev.close if @dev
34
+ end
35
+
36
+ def test_iso_transfer
37
+ tr = IsochronousTransfer.new 10, dev_handle: @dev
38
+ assert_equal 10, tr.num_packets, "number of packets should match"
39
+
40
+ tr.buffer = " "*130
41
+ tr.packet_lengths = 13
42
+ tr[7].length = 12
43
+ assert_equal 12, tr[7].length, "packet length should be set"
44
+ assert_equal 13, tr[8].length, "packet length should be set"
45
+
46
+ assert_raises(LIBUSB::ERROR_IO, "the randomly choosen device will probably not handle iso transfer") do
47
+ tr.submit!
48
+ end
49
+ end
50
+
51
+ def test_max_alt_packet_size
52
+ d = Context.new.devices[0]
53
+ size = d.max_alt_packet_size d.interfaces[0], d.settings[0], d.endpoints[0]
54
+ assert_operator 0, :<=, size
55
+ end
56
+ end