libusb 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,3 +1,10 @@
1
+ === 0.1.2 / 2012-03-14
2
+
3
+ * Mark all blocking functions as blocking in FFI, so that parallel threads are not blocked
4
+ * Add method Device#open_interface
5
+ * Add block variant to #claim_interface
6
+ * update API documentation
7
+
1
8
  === 0.1.1 / 2011-12-09
2
9
 
3
10
  * avoid ffi calls with :blocking=>true, als long as it isn't stable on win32
@@ -13,3 +13,4 @@ test/test_libusb_descriptors.rb
13
13
  test/test_libusb_gc.rb
14
14
  test/test_libusb_iso_transfer.rb
15
15
  test/test_libusb_mass_storage.rb
16
+ test/test_libusb_mass_storage2.rb
@@ -17,7 +17,7 @@ LIBUSB for Ruby is covered by the GNU Lesser General Public License version 3.
17
17
 
18
18
  == FEATURES:
19
19
  * Access to descriptors of devices, configurations, interfaces, settings and endpoints
20
- * Synchronous and asynchronous communication for bulk, control and interrupt transfers
20
+ * Synchronous and asynchronous communication for bulk, control, interrupt and isochronous transfers
21
21
  * Compatibility layer for ruby-usb[http://www.a-k-r.org/ruby-usb/] (API based on libusb-0.1). See {::USB} for description.
22
22
 
23
23
  == SYNOPSIS:
@@ -27,9 +27,9 @@ LIBUSB for Ruby is covered by the GNU Lesser General Public License version 3.
27
27
  usb = LIBUSB::Context.new
28
28
  device = usb.devices(:idVendor => 0x04b4, :idProduct => 0x8613).first
29
29
  device.open do |handle|
30
- handle.claim_interface(0)
31
- handle.control_transfer(:bmRequestType => 0x40, :bRequest => 0xa0, :wValue => 0xe600, :wIndex => 0x0000, :dataOut => 1.chr)
32
- handle.release_interface(0)
30
+ handle.claim_interface(0) do
31
+ handle.control_transfer(:bmRequestType => 0x40, :bRequest => 0xa0, :wValue => 0xe600, :wIndex => 0x0000, :dataOut => 1.chr)
32
+ end
33
33
  end
34
34
  {LIBUSB::Context#devices} is used to get all or only particular devices.
35
35
  After opening the {LIBUSB::Device} the resulting {LIBUSB::DevHandle} can be
@@ -55,9 +55,9 @@ maximum packet size.
55
55
 
56
56
  == REQUIREMENTS:
57
57
 
58
- * libusb version 1.0 or greater
58
+ * libusb version 1.0 or greater (bundled with Windows binary gem)
59
59
  * FFI-gem[http://github.com/ffi/ffi]
60
- * Linux, MacOSX or Windows system
60
+ * Linux, MacOSX or Windows system with Ruby MRI 1.8.7/1.9.x or JRuby
61
61
 
62
62
  == INSTALL:
63
63
 
@@ -65,8 +65,7 @@ maximum packet size.
65
65
 
66
66
  In order to use LIBUSB, you need the libusb-1.0 library (but not its header files).
67
67
  * On Debian and Ubuntu system, install the +libusb-1.0-0+ package.
68
- * The gem for Windows comes with a precompiled +libusb.dll+ and can be used
69
- together with a precompiled FFI-gem, so there is no need for a compiler.
68
+ * The gem for Windows comes with a precompiled +libusb.dll+, so there is no need for a compiler.
70
69
 
71
70
  Latest code can be used in this way:
72
71
 
data/Rakefile CHANGED
@@ -93,9 +93,8 @@ file LIBUSB_MAKEFILE => LIBUSB_CONFIGURE do |t|
93
93
  options = [
94
94
  '--target=i386-mingw32',
95
95
  "--host=#{Rake::ExtensionCompiler.mingw_host}",
96
+ "--build=#{RbConfig::CONFIG["host"]}",
96
97
  ]
97
- build_host = `sh config.guess`.chomp
98
- options << "--build=#{build_host}" unless build_host.to_s.empty?
99
98
 
100
99
  configure_path = STATIC_LIBUSB_BUILDDIR + 'configure'
101
100
  cmd = [ configure_path.to_s, *options ]
@@ -18,7 +18,7 @@ require 'ffi'
18
18
 
19
19
 
20
20
  module LIBUSB
21
- VERSION = "0.1.1"
21
+ VERSION = "0.1.2"
22
22
 
23
23
  module Call
24
24
  extend FFI::Library
@@ -165,15 +165,15 @@ module LIBUSB
165
165
  attach_function 'libusb_close', [:pointer], :void
166
166
  attach_function 'libusb_get_device', [:libusb_device_handle], :pointer
167
167
 
168
- attach_function 'libusb_set_configuration', [:libusb_device_handle, :int], :int
168
+ attach_function 'libusb_set_configuration', [:libusb_device_handle, :int], :int, :blocking=>true
169
169
  attach_function 'libusb_claim_interface', [:libusb_device_handle, :int], :int
170
- attach_function 'libusb_release_interface', [:libusb_device_handle, :int], :int
170
+ attach_function 'libusb_release_interface', [:libusb_device_handle, :int], :int, :blocking=>true
171
171
 
172
172
  attach_function 'libusb_open_device_with_vid_pid', [:pointer, :int, :int], :pointer
173
173
 
174
- attach_function 'libusb_set_interface_alt_setting', [:libusb_device_handle, :int, :int], :int
175
- attach_function 'libusb_clear_halt', [:libusb_device_handle, :int], :int
176
- attach_function 'libusb_reset_device', [:libusb_device_handle], :int
174
+ attach_function 'libusb_set_interface_alt_setting', [:libusb_device_handle, :int, :int], :int, :blocking=>true
175
+ attach_function 'libusb_clear_halt', [:libusb_device_handle, :int], :int, :blocking=>true
176
+ attach_function 'libusb_reset_device', [:libusb_device_handle], :int, :blocking=>true
177
177
 
178
178
  attach_function 'libusb_kernel_driver_active', [:libusb_device_handle, :int], :int
179
179
  attach_function 'libusb_detach_kernel_driver', [:libusb_device_handle, :int], :int
@@ -186,7 +186,7 @@ module LIBUSB
186
186
  attach_function 'libusb_cancel_transfer', [:pointer], :int
187
187
  attach_function 'libusb_free_transfer', [:pointer], :void
188
188
 
189
- attach_function 'libusb_handle_events', [:libusb_context], :int
189
+ attach_function 'libusb_handle_events', [:libusb_context], :int, :blocking=>true
190
190
 
191
191
 
192
192
  callback :libusb_transfer_cb_fn, [:pointer], :void
@@ -971,7 +971,7 @@ module LIBUSB
971
971
  LIBUSB.raise_error res, "in libusb_get_device_descriptor" if res!=0
972
972
  end
973
973
 
974
- # Open a device and obtain a device handle.
974
+ # Open the device and obtain a device handle.
975
975
  #
976
976
  # A handle allows you to perform I/O on the device in question.
977
977
  # This is a non-blocking function; no requests are sent over the bus.
@@ -996,6 +996,21 @@ module LIBUSB
996
996
  end
997
997
  end
998
998
 
999
+ # Open the device and claim an interface.
1000
+ #
1001
+ # This is a convenience method to {Device#open} and {DevHandle#claim_interface}.
1002
+ # Must be called with a block. When the block has finished, the interface
1003
+ # will be released and the device will be closed.
1004
+ #
1005
+ # @param [Interface, Fixnum] interface the interface or it's bInterfaceNumber you wish to claim
1006
+ def open_interface(interface)
1007
+ open do |dev|
1008
+ dev.claim_interface(interface) do
1009
+ yield dev
1010
+ end
1011
+ end
1012
+ end
1013
+
999
1014
  # Get the number of the bus that a device is connected to.
1000
1015
  def bus_number
1001
1016
  Call.libusb_get_bus_number(@pDev)
@@ -1199,11 +1214,20 @@ module LIBUSB
1199
1214
  #
1200
1215
  # This is a non-blocking function.
1201
1216
  #
1217
+ # If called with a block, the device handle is passed through to the block
1218
+ # and the interface is released when the block has finished.
1219
+ #
1202
1220
  # @param [Interface, Fixnum] interface the interface or it's bInterfaceNumber you wish to claim
1203
1221
  def claim_interface(interface)
1204
1222
  interface = interface.bInterfaceNumber if interface.respond_to? :bInterfaceNumber
1205
1223
  res = Call.libusb_claim_interface(@pHandle, interface)
1206
1224
  LIBUSB.raise_error res, "in libusb_claim_interface" if res!=0
1225
+ return self unless block_given?
1226
+ begin
1227
+ yield self
1228
+ ensure
1229
+ release_interface(interface)
1230
+ end
1207
1231
  end
1208
1232
 
1209
1233
  # Release an interface previously claimed with {DevHandle#claim_interface}.
@@ -1272,8 +1296,7 @@ module LIBUSB
1272
1296
  # to activate or the bInterfaceNumber of the previously-claimed interface
1273
1297
  # @param [Fixnum, nil] alternate_setting the bAlternateSetting of the alternate setting to activate
1274
1298
  # (only if first param is a Fixnum)
1275
- def set_interface_alt_setting(setting_or_interface_number,
1276
- alternate_setting=nil)
1299
+ def set_interface_alt_setting(setting_or_interface_number, alternate_setting=nil)
1277
1300
  alternate_setting ||= setting_or_interface_number.bAlternateSetting if setting_or_interface_number.respond_to? :bAlternateSetting
1278
1301
  setting_or_interface_number = setting_or_interface_number.bInterfaceNumber if setting_or_interface_number.respond_to? :bInterfaceNumber
1279
1302
  res = Call.libusb_set_interface_alt_setting(@pHandle, setting_or_interface_number, alternate_setting)
@@ -1356,7 +1379,7 @@ alternate_setting=nil)
1356
1379
  # The direction of the transfer is inferred from the direction bits of the
1357
1380
  # endpoint address.
1358
1381
  #
1359
- # For bulk reads, the :dataIn param indicates the maximum length of data you are
1382
+ # For bulk reads, the +:dataIn+ param indicates the maximum length of data you are
1360
1383
  # expecting to receive. If less data arrives than expected, this function will
1361
1384
  # return that data.
1362
1385
  #
@@ -1373,6 +1396,8 @@ alternate_setting=nil)
1373
1396
  # @param [Endpoint, Fixnum] :endpoint the (address of a) valid endpoint to communicate with
1374
1397
  # @param [String] :dataOut the data to send with an outgoing transfer
1375
1398
  # @param [Fixnum] :dataIn the number of bytes expected to receive with an ingoing transfer
1399
+ # @param [Fixnum] :timeout timeout (in millseconds) that this function should wait before giving
1400
+ # up due to no response being received. For an unlimited timeout, use value 0. Defaults to 1000 ms.
1376
1401
  #
1377
1402
  # @return [Fixnum] Number of bytes sent for an outgoing transfer
1378
1403
  # @return [String] Received data for an ingoing transfer
@@ -1412,7 +1437,7 @@ alternate_setting=nil)
1412
1437
  # The direction of the transfer is inferred from the direction bits of the
1413
1438
  # endpoint address.
1414
1439
  #
1415
- # For interrupt reads, the :dataIn param indicates the maximum length of data you
1440
+ # For interrupt reads, the +:dataIn+ param indicates the maximum length of data you
1416
1441
  # are expecting to receive. If less data arrives than expected, this function will
1417
1442
  # return that data.
1418
1443
  #
@@ -1431,6 +1456,8 @@ alternate_setting=nil)
1431
1456
  # @param [Endpoint, Fixnum] :endpoint the (address of a) valid endpoint to communicate with
1432
1457
  # @param [String] :dataOut the data to send with an outgoing transfer
1433
1458
  # @param [Fixnum] :dataIn the number of bytes expected to receive with an ingoing transfer
1459
+ # @param [Fixnum] :timeout timeout (in millseconds) that this function should wait before giving
1460
+ # up due to no response being received. For an unlimited timeout, use value 0. Defaults to 1000 ms.
1434
1461
  #
1435
1462
  # @return [Fixnum] Number of bytes sent for an outgoing transfer
1436
1463
  # @return [String] Received data for an ingoing transfer
@@ -1467,7 +1494,7 @@ alternate_setting=nil)
1467
1494
 
1468
1495
  # Perform a USB control transfer.
1469
1496
  #
1470
- # The direction of the transfer is inferred from the bmRequestType field of the
1497
+ # The direction of the transfer is inferred from the +:bmRequestType+ field of the
1471
1498
  # setup packet.
1472
1499
  #
1473
1500
  # @param [Fixnum] :bmRequestType the request type field for the setup packet
@@ -1479,7 +1506,7 @@ alternate_setting=nil)
1479
1506
  # @param [Fixnum] :dataIn the number of bytes expected to receive with an ingoing transfer
1480
1507
  # (excluding setup packet)
1481
1508
  # @param [Fixnum] :timeout timeout (in millseconds) that this function should wait before giving
1482
- # up due to no response being received. For an unlimited timeout, use value 0.
1509
+ # up due to no response being received. For an unlimited timeout, use value 0. Defaults to 1000 ms.
1483
1510
  #
1484
1511
  # @return [Fixnum] Number of bytes sent (excluding setup packet) for outgoing transfer
1485
1512
  # @return [String] Received data (without setup packet) for ingoing transfer
@@ -215,7 +215,7 @@ class TestLibusbMassStorage < Test::Unit::TestCase
215
215
  end
216
216
  end
217
217
  assert_raise(CSWError, LIBUSB::ERROR_TIMEOUT) do
218
- invalid_command
218
+ bulk_transfer(:endpoint=>endpoint_in, :dataIn=>123)
219
219
  end
220
220
  th.kill
221
221
  dev.clear_halt(endpoint_in)
@@ -0,0 +1,69 @@
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
+
17
+ require "test/unit"
18
+ require "libusb"
19
+
20
+ class TestLibusbMassStorage2 < Test::Unit::TestCase
21
+ include LIBUSB
22
+
23
+ attr_accessor :usb
24
+ attr_accessor :device
25
+
26
+ def setup
27
+ @usb = Context.new
28
+ @usb.debug = 3
29
+ @device = usb.devices( :bClass=>CLASS_MASS_STORAGE, :bSubClass=>[0x06,0x01], :bProtocol=>0x50 ).last
30
+ abort "no mass storage device found" unless @device
31
+
32
+ # Ensure kernel driver is detached
33
+ device.open do |dev|
34
+ if RUBY_PLATFORM=~/linux/i && dev.kernel_driver_active?(0)
35
+ dev.detach_kernel_driver(0)
36
+ end
37
+ end
38
+ end
39
+
40
+ def teardown
41
+ end
42
+
43
+ def test_open_with_block
44
+ device.open do |dev|
45
+ assert_kind_of DevHandle, dev
46
+ assert_kind_of String, dev.string_descriptor_ascii(1)
47
+ end
48
+ end
49
+
50
+ def test_claim_interface_with_block
51
+ res = device.open do |dev|
52
+ dev.claim_interface(0) do |dev2|
53
+ assert_kind_of DevHandle, dev2
54
+ assert_kind_of String, dev2.string_descriptor_ascii(1)
55
+ 12345
56
+ end
57
+ end
58
+ assert_equal 12345, res, "Block versions should pass through the result"
59
+ end
60
+
61
+ def test_open_interface
62
+ res = device.open_interface(0) do |dev|
63
+ assert_kind_of DevHandle, dev
64
+ assert_kind_of String, dev.string_descriptor_ascii(1)
65
+ 12345
66
+ end
67
+ assert_equal 12345, res, "Block versions should pass through the result"
68
+ end
69
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libusb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-12-09 00:00:00.000000000 Z
12
+ date: 2012-03-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: ffi
16
- requirement: &20041800 !ruby/object:Gem::Requirement
16
+ requirement: &7425600 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '1.0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *20041800
24
+ version_requirements: *7425600
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake-compiler
27
- requirement: &20040960 !ruby/object:Gem::Requirement
27
+ requirement: &7424760 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,18 +32,29 @@ dependencies:
32
32
  version: '0.6'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *20040960
35
+ version_requirements: *7424760
36
+ - !ruby/object:Gem::Dependency
37
+ name: rdoc
38
+ requirement: &7423680 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ~>
42
+ - !ruby/object:Gem::Version
43
+ version: '3.10'
44
+ type: :development
45
+ prerelease: false
46
+ version_requirements: *7423680
36
47
  - !ruby/object:Gem::Dependency
37
48
  name: hoe
38
- requirement: &20040440 !ruby/object:Gem::Requirement
49
+ requirement: &7422380 !ruby/object:Gem::Requirement
39
50
  none: false
40
51
  requirements:
41
52
  - - ~>
42
53
  - !ruby/object:Gem::Version
43
- version: '2.12'
54
+ version: '2.16'
44
55
  type: :development
45
56
  prerelease: false
46
- version_requirements: *20040440
57
+ version_requirements: *7422380
47
58
  description: LIBUSB is a Ruby binding that gives Ruby programmers access to all functionality
48
59
  of libusb, version 1.0
49
60
  email:
@@ -70,7 +81,7 @@ files:
70
81
  - test/test_libusb_gc.rb
71
82
  - test/test_libusb_iso_transfer.rb
72
83
  - test/test_libusb_mass_storage.rb
73
- - test/test_libusb_keyboard.rb
84
+ - test/test_libusb_mass_storage2.rb
74
85
  homepage: http://github.com/larskanis/libusb
75
86
  licenses: []
76
87
  post_install_message:
@@ -94,15 +105,15 @@ required_rubygems_version: !ruby/object:Gem::Requirement
94
105
  version: '0'
95
106
  requirements: []
96
107
  rubyforge_project: libusb
97
- rubygems_version: 1.8.10
108
+ rubygems_version: 1.8.17
98
109
  signing_key:
99
110
  specification_version: 3
100
111
  summary: Access USB devices from Ruby via libusb-1.0
101
112
  test_files:
102
- - test/test_libusb_compat_mass_storage.rb
103
- - test/test_libusb_gc.rb
113
+ - test/test_libusb_compat.rb
104
114
  - test/test_libusb_iso_transfer.rb
115
+ - test/test_libusb_mass_storage2.rb
105
116
  - test/test_libusb_descriptors.rb
106
- - test/test_libusb_compat.rb
107
- - test/test_libusb_keyboard.rb
108
117
  - test/test_libusb_mass_storage.rb
118
+ - test/test_libusb_compat_mass_storage.rb
119
+ - test/test_libusb_gc.rb
@@ -1,50 +0,0 @@
1
- # This test requires a connected, but not mounted mass storage device with
2
- # read/write access allowed. Based on the following specifications:
3
- # http://www.usb.org/developers/devclass_docs/usbmassbulk_10.pdf
4
- # http://en.wikipedia.org/wiki/SCSI_command
5
- #
6
-
7
- require "test/unit"
8
- require "libusb"
9
-
10
- class TestLibusbKeyboard < Test::Unit::TestCase
11
- include LIBUSB
12
-
13
- attr_accessor :usb
14
- attr_accessor :device
15
- attr_accessor :dev
16
- attr_accessor :endpoint_in
17
- attr_accessor :endpoint_out
18
-
19
- def setup
20
- @usb = Context.new
21
- @usb.debug = 3
22
-
23
- @device = usb.devices( :bDeviceClass=>CLASS_HID, :bDeviceProtocol=>1 ).first
24
- abort "no keyboard device found" unless @device
25
-
26
- @endpoint_in = @device.endpoints.find{|ep| ep.bEndpointAddress&ENDPOINT_IN != 0 }.bEndpointAddress
27
- @endpoint_out = @device.endpoints.find{|ep| ep.bEndpointAddress&ENDPOINT_IN == 0 }.bEndpointAddress
28
-
29
- @dev = @device.open
30
-
31
- if RUBY_PLATFORM=~/linux/i && dev.kernel_driver_active?(0)
32
- dev.detach_kernel_driver(0)
33
- end
34
- dev.claim_interface(0)
35
-
36
- # clear any pending data
37
- dev.clear_halt(endpoint_in)
38
- end
39
-
40
- def teardown
41
- dev.release_interface(0) if dev
42
- dev.close if dev
43
- end
44
-
45
- def test_read
46
- data_length = 8
47
- recv = dev.interrupt_transfer(:endpoint=>endpoint_in, :dataIn=>data_length)
48
- p recv
49
- end
50
- end