libusb 0.5.1-x64-mingw32 → 0.6.0-x64-mingw32

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 7a4bd5976cd03324ad2345ce42c220da84fe9a90
4
- data.tar.gz: 9412dd0efbf424aed55987eff4e81baf202da6e9
3
+ metadata.gz: a20d98f43636caf12240a486b0e9c22bb190394b
4
+ data.tar.gz: c47aa11c776f146fb16fb5329586b2a96fcecc84
5
5
  SHA512:
6
- metadata.gz: c7fb7068c318e2a034882fe7f54bad93c203960974c65c790f7e522cb7d7dcc842b60ad94e465f7c2453d5cc784d22b0b547eefa1b1f7c23d7a491133e04019f
7
- data.tar.gz: dbd3595551464323fb62366fb61994177e992a846fb022ee3f02fbe060fc81fd7926845bd16baeb140f9dbc07ac99244b9dee2d07b4f7b11f6d47580fffb84a2
6
+ metadata.gz: 83426e897d09ae1a468d134a69a31385f9694dabba99fc36bcfb71c92563098c7276cf43a8b77e1b0dfad39695327df034858e21fa9671d2a2768b9070298381
7
+ data.tar.gz: 6401e3b895dae693a044ffb9b894e4fb1f19e5a1d5cccbbf190572c5731bb1cfbfa6e1010218910586f6177bc94d604a71789feac26c4d3954d7313af83dac01
@@ -1,11 +1,17 @@
1
1
  language: ruby
2
2
  sudo: false
3
3
  rvm:
4
- - "1.8.7"
5
4
  - "1.9.3"
6
5
  - "2.0.0"
7
6
  - "2.1"
8
7
  - "2.2"
9
- - jruby
8
+ - "2.3.1"
9
+ - "2.3.1-clang"
10
+ - jruby-1.7.26
11
+ - jruby-9.1.5.0
10
12
  - rbx
13
+ matrix:
14
+ allow_failures:
15
+ - rvm: rbx
16
+ - rvm: "2.3.1-clang"
11
17
  script: bundle exec rake travis
data/Gemfile CHANGED
@@ -7,3 +7,5 @@ group :test do
7
7
  gem 'eventmachine'
8
8
  gem 'minitest'
9
9
  end
10
+
11
+ gem 'rake-compiler-dock', git: 'http://github.com/rake-compiler/rake-compiler-dock'
data/History.md CHANGED
@@ -1,3 +1,15 @@
1
+ 0.6.0 / 2016-12-09
2
+ ------------------
3
+ * Update bundled libusb version to 1.0.21.
4
+ * Set minimum Ruby version requirement to 1.9.3.
5
+ * Add binary gems for Linux in addition to Windows.
6
+ * Switch to mini_portile2 for (cross-) builing the libusb library.
7
+ * Add Context#interrupt_event_handler new in libusb-1.0.21
8
+ * Add support for persistent/zerocopy device memory for transfers.
9
+ It is new in libusb-1.0.21 and enabled by default for DevHandle#*_transfer methods.
10
+ * Raise a more meaningful exception in case of bulk stream transfers on too old libusb versions.
11
+ * Prefer the bundled libusb-dll over installed system library.
12
+
1
13
  0.5.1 / 2015-09-29
2
14
  ------------------
3
15
  * Add ability to force use of the system or builtin libusb-1.0 library.
data/README.md CHANGED
@@ -1,6 +1,7 @@
1
1
  <!-- -*- coding: utf-8 -*- -->
2
2
 
3
3
  [![Build Status](https://travis-ci.org/larskanis/libusb.svg)](https://travis-ci.org/larskanis/libusb)
4
+ [![Build Status](https://ci.appveyor.com/api/projects/status/mdfnfdwu4mil42o3?svg=true)](https://ci.appveyor.com/project/larskanis/libusb)
4
5
 
5
6
  Access USB devices from Ruby
6
7
  ============================
@@ -23,15 +24,13 @@ Features
23
24
 
24
25
  Synopsis
25
26
  --------
26
- See [the documentation](http://rubydoc.info/gems/libusb/frames) for a full API description.
27
-
28
27
  ```ruby
29
28
  require "libusb"
30
29
 
31
30
  usb = LIBUSB::Context.new
32
- device = usb.devices(:idVendor => 0x04b4, :idProduct => 0x8613).first
31
+ device = usb.devices(idVendor: 0x04b4, idProduct: 0x8613).first
33
32
  device.open_interface(0) do |handle|
34
- handle.control_transfer(:bmRequestType => 0x40, :bRequest => 0xa0, :wValue => 0xe600, :wIndex => 0x0000, :dataOut => 1.chr)
33
+ handle.control_transfer(bmRequestType: 0x40, bRequest: 0xa0, wValue: 0xe600, wIndex: 0x0000, dataOut: 1.chr)
35
34
  end
36
35
  ```
37
36
  {LIBUSB::Context#devices} is used to get all or only particular devices.
@@ -55,18 +54,20 @@ Each {LIBUSB::Setting} specifies it's own set of communication endpoints.
55
54
  Each {LIBUSB::Endpoint} specifies the type of transfer, direction, polling interval and
56
55
  maximum packet size.
57
56
 
57
+ See [the documentation](http://rubydoc.info/gems/libusb/frames) for a full API description.
58
58
 
59
59
  Prerequisites
60
60
  -------------
61
61
 
62
- * Linux, MacOSX or Windows system with Ruby MRI 1.8.7/1.9/2.0, JRuby or recent version of Rubinius
63
- * Optionally: [libusb](http://libusb.info) or [libusbx](http://libusbx.org) library version 1.0.8+ :
62
+ * Linux, MacOS or Windows system with Ruby MRI 1.9/2.x, JRuby or recent version of Rubinius
63
+ * Optionally: [libusb](http://libusb.info) C-library version 1.0.8 or any newer version.
64
+ The system libusb library can be installed like so:
64
65
  * Debian or Ubuntu:
65
66
 
66
67
  ```
67
68
  $ sudo apt-get install libusb-1.0-0-dev
68
69
  ```
69
- * OS-X: install with homebrew:
70
+ * MacOS: install with homebrew:
70
71
 
71
72
  ```
72
73
  $ brew install libusb
@@ -83,7 +84,7 @@ Install
83
84
 
84
85
  $ gem install libusb
85
86
 
86
- While ```gem install``` the system is checked for a usable libusb(x) library installation.
87
+ While ```gem install``` the system is checked for a usable libusb library installation.
87
88
  If none could be found, a bundled libusb version is built and used, instead.
88
89
 
89
90
  Latest code can be used in this way:
@@ -92,11 +93,21 @@ Latest code can be used in this way:
92
93
  $ bundle
93
94
  $ rake install_gem
94
95
 
96
+ Troubleshooting
97
+ ------------------------
98
+ In order to implement a driver for a USB device, it's essential to have a look at the packets that are send to and received back from the USB device. [Wireshark](https://www.wireshark.org) has builtin capabilities to sniff USB traffic. On Linux you possibly need to load the usbmon kernel module before start:
99
+ ```
100
+ sudo modprobe usbmon
101
+ ```
102
+ On Windows it's possible to sniff USB, if the USB kernel driver was installed by the Wireshark setup.
103
+
104
+ ![Wireshark](wireshark-usb-sniffer.png?raw=true "Wireshark sniffing USB packets")
105
+
95
106
  Device hotplug support
96
107
  ----------------------
97
108
 
98
109
  Support for device hotplugging can be used, if ```LIBUSB.has_capability?(:CAP_HAS_HOTPLUG)``` returns ```true```.
99
- This requires libusb(x)-1.0.16 or newer on Linux or OS-X. Windows support is [still on the way](https://github.com/libusbx/libusbx/issues/9).
110
+ This requires libusb-1.0.16 or newer on Linux or MacOS. Windows support is [still on the way](https://github.com/libusbx/libusbx/issues/9).
100
111
 
101
112
  A hotplug event handler can be registered with {LIBUSB::Context#on_hotplug_event}.
102
113
  You then need to call {LIBUSB::Context#handle_events} in order to receive any events.
@@ -109,21 +120,21 @@ Usage on Windows
109
120
 
110
121
  In contrast to Linux, any access to an USB device by LIBUSB on Windows requires a proper driver
111
122
  installed in the system. Fortunately creating such a driver is quite easy with
112
- [Zadig](http://sourceforge.net/projects/libwdi/files/zadig/). Select the interesting USB device,
123
+ [Zadig](http://zadig.akeo.ie/). Select the interesting USB device,
113
124
  choose WinUSB driver and press "Install Driver". That's it. You may take the generated output directory
114
- with it's INI-file and use it for driver installation on other 32 or 64 bit Windows
125
+ with it's INI-file and use it for driver installations on other 32 or 64 bit Windows
115
126
  systems.
116
127
 
117
128
 
118
129
  Cross compiling for Windows
119
130
  ---------------------------
120
131
 
121
- Libusb-gem can be cross built for the win32 platform, using the [rake-compiler-dock](https://github.com/larskanis/rake-compiler-dock) .
132
+ Libusb-gem can be cross built for Windows and Linux operating systems, using the [rake-compiler-dock](https://github.com/larskanis/rake-compiler-dock) .
122
133
  Just run:
123
134
 
124
- $ rake gem:windows
135
+ $ rake gem:native
125
136
 
126
- If everything works, there should be `libusb-VERSION-x86-mingw32.gem` in the pkg
137
+ If everything works, there are several platform specific gem files (like `libusb-VERSION-x64-mingw32.gem`) in the pkg
127
138
  directory.
128
139
 
129
140
  EventMachine integration
data/Rakefile CHANGED
@@ -8,10 +8,11 @@ require 'uri'
8
8
  require 'ostruct'
9
9
  require 'rake/clean'
10
10
  require 'rake_compiler_dock'
11
+ require_relative 'ext/libusb_recipe'
11
12
 
12
13
  task :gem => :build
13
14
  task :compile do
14
- sh "ruby ext/extconf.rb"
15
+ sh "ruby ext/extconf.rb --disable-system-libusb"
15
16
  end
16
17
 
17
18
  task :test=>:compile do
@@ -24,110 +25,62 @@ task :travis=>:compile do
24
25
  end
25
26
  task :default => :test
26
27
 
27
- task 'gem:windows' do
28
- RakeCompilerDock.sh "bundle && rake cross gem"
29
- end
30
-
31
- COMPILE_HOME = Pathname( "./tmp" ).expand_path
32
- STATIC_SOURCESDIR = COMPILE_HOME + 'sources'
33
-
34
- # Fetch tarball from sourceforge
35
- LIBUSB_VERSION = ENV['LIBUSB_VERSION'] || '1.0.20'
36
- LIBUSB_SOURCE_URI = URI( "http://downloads.sourceforge.net/project/libusb/libusb-1.0/libusb-#{LIBUSB_VERSION}/libusb-#{LIBUSB_VERSION}.tar.bz2" )
37
- LIBUSB_TARBALL = STATIC_SOURCESDIR + File.basename( LIBUSB_SOURCE_URI.path )
38
-
39
- # Fetch tarball from git repo
40
- # LIBUSB_VERSION = ENV['LIBUSB_VERSION'] || '295c9d1'
41
- # LIBUSB_SOURCE_URI = URI( "http://git.libusb.org/?p=libusb.git;a=snapshot;h=#{LIBUSB_VERSION};sf=tbz2" )
42
- # LIBUSB_TARBALL = STATIC_SOURCESDIR + "libusb-#{LIBUSB_VERSION}.tar.bz2"
28
+ task "release:tag" do
29
+ hfile = "History.md"
30
+ version = LIBUSB::VERSION
31
+ reldate = Time.now.strftime("%Y-%m-%d")
32
+ headline = '([^\w]*)(\d+\.\d+\.\d+)([^\w]+)([2Y][0Y][0-9Y][0-9Y]-[0-1M][0-9M]-[0-3D][0-9D])([^\w]*|$)'
43
33
 
44
- # Fetch tarball from libusbx
45
- # LIBUSB_VERSION = ENV['LIBUSB_VERSION'] || '1.0.17'
46
- # LIBUSB_SOURCE_URI = URI( "http://downloads.sourceforge.net/project/libusbx/releases/#{LIBUSB_VERSION[/^\d+\.\d+\.\d+/]}/source/libusbx-#{LIBUSB_VERSION}.tar.bz2" )
47
- # LIBUSB_TARBALL = STATIC_SOURCESDIR + File.basename( LIBUSB_SOURCE_URI.path )
48
-
49
- # Fetch tarball from Pete Batard's git repo
50
- # LIBUSB_VERSION = ENV['LIBUSB_VERSION'] || '4cc72d0'
51
- # LIBUSB_SOURCE_URI = URI( "http://git.libusb.org/?p=libusb-pbatard.git;a=snapshot;h=#{LIBUSB_VERSION};sf=tbz2" )
52
- # LIBUSB_TARBALL = STATIC_SOURCESDIR + "libusb-pbatard-#{LIBUSB_VERSION}.tar.bz2"
34
+ hin = File.read(hfile)
35
+ hout = hin.sub(/#{headline}/) do
36
+ raise "#{hfile} isn't up-to-date for version #{version}" unless $2==version
37
+ $1 + $2 + $3 + reldate + $5
38
+ end
39
+ if hout != hin
40
+ Bundler.ui.confirm "Updating #{hfile} for release."
41
+ File.write(hfile, hout)
42
+ sh "git", "commit", hfile, "-m", "Update release date in #{hfile}"
43
+ end
53
44
 
54
- EXT_BUILDDIR = Pathname( "./ext" ).expand_path
55
- EXT_LIBUSB_BUILDDIR = EXT_BUILDDIR + LIBUSB_TARBALL.basename(".tar.bz2")
45
+ Bundler.ui.confirm "Tag release with annotation:"
46
+ m = hout.match(/(?<annotation>#{headline}.*?)#{headline}/m) || raise("Unable to find release notes in #{hfile}")
47
+ Bundler.ui.info(m[:annotation].gsub(/^/, " "))
48
+ IO.popen(["git", "tag", "--file=-", version], "w") do |fd|
49
+ fd.write m[:annotation]
50
+ end
51
+ end
56
52
 
57
- directory STATIC_SOURCESDIR.to_s
53
+ task "release:guard_clean" => "release:tag"
58
54
 
59
- # libusb source file should be stored there
60
- file LIBUSB_TARBALL => STATIC_SOURCESDIR do |t|
61
- # download the source file using wget or curl
62
- chdir File.dirname(t.name) do
63
- url = LIBUSB_SOURCE_URI
64
- sh "wget '#{url}' -O #{LIBUSB_TARBALL}"
55
+ task "release:rubygem_push" => "gem:native" do
56
+ CrossLibraries.each do |ruby_platform, _|
57
+ gh = Bundler::GemHelper.new
58
+ gh.rubygem_push(gh.spec_path.gsub(".gem", "-#{ruby_platform}.gem"))
65
59
  end
66
60
  end
67
61
 
62
+ task 'gem:native' do
63
+ sh "bundle package"
64
+ RakeCompilerDock.sh <<-EOT
65
+ bundle --local &&
66
+ rake cross gem
67
+ EOT
68
+ end
68
69
 
69
70
  class CrossLibrary < OpenStruct
70
71
  include Rake::DSL
71
72
 
72
- def initialize(ruby_platform, host_platform)
73
+ def initialize(ruby_platform, host_platform, libusb_dllname)
73
74
  super()
74
75
 
75
- self.ruby_platform = ruby_platform
76
- self.host_platform = host_platform
77
-
78
- self.static_builddir = COMPILE_HOME + 'builds' + ruby_platform
79
- self.ruby_build = RbConfig::CONFIG["host"]
80
-
81
- # Static libusb build vars
82
- self.static_libusb_builddir = static_builddir + LIBUSB_TARBALL.basename(".tar.bz2")
83
- self.libusb_configure = static_libusb_builddir + 'configure'
84
- self.libusb_makefile = static_libusb_builddir + 'Makefile'
85
- self.libusb_dll = static_libusb_builddir + 'libusb/.libs/libusb-1.0.dll'
86
-
87
- #
88
- # Static libusb build tasks
89
- #
90
- CLEAN.include static_libusb_builddir.to_s
91
-
92
- directory static_libusb_builddir.to_s
76
+ self.ruby_platform = ruby_platform
77
+ self.recipe = LibusbRecipe.new
78
+ recipe.host = host_platform
79
+ recipe.configure_options << "--host=#{recipe.host}"
80
+ self.libusb_dll = Pathname.new(recipe.path) + libusb_dllname
93
81
 
94
- # Extract the libusb builds
95
- file static_libusb_builddir => LIBUSB_TARBALL do |t|
96
- sh 'tar', '-xjf', LIBUSB_TARBALL.to_s, '-C', static_libusb_builddir.parent.to_s
97
- libusb_makefile.unlink if libusb_makefile.exist?
98
- end
99
-
100
- file libusb_configure => static_libusb_builddir do |t|
101
- Dir.chdir( static_libusb_builddir ) do
102
- sh "sh autogen.sh && make distclean"
103
- end
104
- end
105
-
106
- libusb_env = [
107
- "CFLAGS='-fno-omit-frame-pointer'",
108
- "LDFLAGS='-static-libgcc'",
109
- "CC='#{host_platform}-gcc -static-libgcc'", # hack libtool, since it doesn't support -static-libgcc yet.
110
- ]
111
-
112
- # generate the makefile in a clean build location
113
- file libusb_makefile => libusb_configure do |t|
114
- Dir.chdir( static_libusb_builddir ) do
115
- options = [
116
- "--target=#{host_platform}",
117
- "--host=#{host_platform}",
118
- "--build=#{ruby_build}",
119
- ]
120
-
121
- configure_path = static_libusb_builddir + 'configure'
122
- sh "env #{[libusb_env, configure_path.to_s, *options].join(" ")}"
123
- end
124
- end
125
-
126
- # make libusb-1.0.dll
127
- task libusb_dll => [ libusb_makefile ] do |t|
128
- Dir.chdir( static_libusb_builddir ) do
129
- sh 'make'
130
- end
82
+ file libusb_dll do
83
+ recipe.cook
131
84
  end
132
85
 
133
86
  task "libusb_dll:#{ruby_platform}" => libusb_dll
@@ -137,9 +90,17 @@ class CrossLibrary < OpenStruct
137
90
  spec = Gem::Specification::load("libusb.gemspec").dup
138
91
  spec.platform = Gem::Platform.new(ruby_platform)
139
92
  spec.extensions = []
93
+
94
+ # Remove files unnecessary for native gems
140
95
  spec.files -= `git ls-files ext`.split("\n")
96
+ spec.files.reject!{|f| f.start_with?('ports') }
141
97
  spec_text_files = spec.files.dup
142
- spec.files << "lib/#{File.basename(libusb_dll)}"
98
+
99
+ # Add native libusb-dll
100
+ spec.files << "lib/#{libusb_dll.basename}"
101
+
102
+ # MiniPortile isn't required for native gems
103
+ spec.dependencies.reject!{|d| d.name=="mini_portile2" }
143
104
 
144
105
  # Generate a package for this gem
145
106
  pkg = Gem::PackageTask.new(spec) do |pkg|
@@ -161,32 +122,24 @@ class CrossLibrary < OpenStruct
161
122
  end
162
123
 
163
124
  # copy libusb.dll to pkg directory
164
- f = "#{pkg.package_dir_path}/lib/#{File.basename(libusb_dll)}"
125
+ f = "#{pkg.package_dir_path}/lib/#{libusb_dll.basename}"
165
126
  mkdir_p File.dirname(f)
166
127
  rm_f f
167
- safe_ln libusb_dll, f
128
+ safe_ln libusb_dll.realpath, f
168
129
  end
169
130
 
170
- file "lib/#{File.basename(libusb_dll)}" => [libusb_dll]
131
+ file "lib/#{libusb_dll.basename}" => [libusb_dll]
171
132
  end
172
133
  end
173
134
  end
174
135
 
175
136
  CrossLibraries = [
176
- ['i386-mingw32', 'i686-w64-mingw32'],
177
- ['x64-mingw32', 'x86_64-w64-mingw32'],
178
- ].map do |ruby_platform, host_platform|
179
- CrossLibrary.new ruby_platform, host_platform
180
- end
181
-
182
- desc "Download and update bundled libusb"
183
- task :update_libusb => LIBUSB_TARBALL do
184
- sh 'rm', '-r', (EXT_BUILDDIR + "libusb-*").to_s do end
185
- sh 'git', 'rm', '-rfq', (EXT_BUILDDIR + "libusb-*").to_s do end
186
- sh 'tar', '-xjf', LIBUSB_TARBALL.to_s, '-C', EXT_LIBUSB_BUILDDIR.parent.to_s
187
- drops = %w[msvc].map{|f| (EXT_LIBUSB_BUILDDIR+f).to_s }
188
- sh 'rm', '-r', '-f', *drops
189
- sh 'git', 'add', EXT_LIBUSB_BUILDDIR.to_s
137
+ ['i386-mingw32', 'i686-w64-mingw32', 'bin/libusb-1.0.dll'],
138
+ ['x64-mingw32', 'x86_64-w64-mingw32', 'bin/libusb-1.0.dll'],
139
+ ['x86-linux', 'i686-linux-gnu', 'lib/libusb-1.0.so'],
140
+ ['x86_64-linux', 'x86_64-linux-gnu', 'lib/libusb-1.0.so'],
141
+ ].each do |ruby_platform, host_platform, libusb_dll|
142
+ CrossLibrary.new ruby_platform, host_platform, libusb_dll
190
143
  end
191
144
 
192
145
  # vim: syntax=ruby
@@ -0,0 +1,23 @@
1
+ init:
2
+ - SET PATH=C:\Ruby%ruby_version%\bin;%PATH%
3
+ - SET PATH=C:\MinGW\msys\1.0\bin;%PATH%
4
+ - SET RAKEOPT=-rdevkit
5
+ install:
6
+ - ruby --version
7
+ - gem --version
8
+ - bundle install
9
+ build_script:
10
+ - bundle exec rake compile
11
+ test_script:
12
+ - bundle exec rake travis
13
+ environment:
14
+ matrix:
15
+ - ruby_version: "193"
16
+ - ruby_version: "200"
17
+ - ruby_version: "200-x64"
18
+ - ruby_version: "21"
19
+ - ruby_version: "21-x64"
20
+ - ruby_version: "22"
21
+ - ruby_version: "22-x64"
22
+ - ruby_version: "23"
23
+ - ruby_version: "23-x64"
@@ -28,7 +28,7 @@ module LIBUSB
28
28
  prefix = FFI::Platform::LIBPREFIX.empty? ? 'lib' : FFI::Platform::LIBPREFIX
29
29
  bundled_dll = File.join(root_path, "lib/#{prefix}usb-1.0.#{ext}")
30
30
  bundled_dll_cygwin = File.join(root_path, "bin/#{prefix}usb-1.0.#{ext}")
31
- ffi_lib(["#{prefix}usb-1.0", bundled_dll, bundled_dll_cygwin])
31
+ ffi_lib([bundled_dll, bundled_dll_cygwin, "#{prefix}usb-1.0"])
32
32
 
33
33
  ClassCodes = enum :libusb_class_code, [
34
34
  :CLASS_PER_INTERFACE, 0,
@@ -292,7 +292,7 @@ module LIBUSB
292
292
  try_attach_function 'libusb_get_ss_endpoint_companion_descriptor', [:pointer, :pointer, :pointer], :int
293
293
  try_attach_function 'libusb_free_ss_endpoint_companion_descriptor', [:pointer], :void
294
294
 
295
- try_attach_function 'libusb_get_bos_descriptor', [:libusb_device_handle, :pointer], :int, :blocking=>true
295
+ try_attach_function 'libusb_get_bos_descriptor', [:libusb_device_handle, :pointer], :int, blocking: true
296
296
  try_attach_function 'libusb_free_bos_descriptor', [:pointer], :void
297
297
  try_attach_function 'libusb_get_usb_2_0_extension_descriptor', [:libusb_context, :pointer, :pointer], :int
298
298
  try_attach_function 'libusb_free_usb_2_0_extension_descriptor', [:pointer], :void
@@ -305,17 +305,19 @@ module LIBUSB
305
305
  attach_function 'libusb_close', [:pointer], :void
306
306
  attach_function 'libusb_get_device', [:libusb_device_handle], :pointer
307
307
 
308
- attach_function 'libusb_set_configuration', [:libusb_device_handle, :int], :int, :blocking=>true
308
+ attach_function 'libusb_set_configuration', [:libusb_device_handle, :int], :int, blocking: true
309
309
  attach_function 'libusb_claim_interface', [:libusb_device_handle, :int], :int
310
- attach_function 'libusb_release_interface', [:libusb_device_handle, :int], :int, :blocking=>true
310
+ attach_function 'libusb_release_interface', [:libusb_device_handle, :int], :int, blocking: true
311
311
 
312
312
  attach_function 'libusb_open_device_with_vid_pid', [:pointer, :int, :int], :pointer
313
313
 
314
- attach_function 'libusb_set_interface_alt_setting', [:libusb_device_handle, :int, :int], :int, :blocking=>true
315
- attach_function 'libusb_clear_halt', [:libusb_device_handle, :int], :int, :blocking=>true
316
- attach_function 'libusb_reset_device', [:libusb_device_handle], :int, :blocking=>true
314
+ attach_function 'libusb_set_interface_alt_setting', [:libusb_device_handle, :int, :int], :int, blocking: true
315
+ attach_function 'libusb_clear_halt', [:libusb_device_handle, :int], :int, blocking: true
316
+ attach_function 'libusb_reset_device', [:libusb_device_handle], :int, blocking: true
317
317
  try_attach_function 'libusb_alloc_streams', [:libusb_device_handle, :uint32, :pointer, :int], :int
318
318
  try_attach_function 'libusb_free_streams', [:libusb_device_handle, :pointer, :int], :int
319
+ try_attach_function 'libusb_dev_mem_alloc', [:libusb_device_handle, :size_t], :pointer
320
+ try_attach_function 'libusb_dev_mem_free', [:libusb_device_handle, :pointer, :size_t], :int
319
321
 
320
322
  attach_function 'libusb_kernel_driver_active', [:libusb_device_handle, :int], :int
321
323
  attach_function 'libusb_detach_kernel_driver', [:libusb_device_handle, :int], :int
@@ -331,10 +333,11 @@ module LIBUSB
331
333
  try_attach_function 'libusb_transfer_set_stream_id', [:libusb_transfer, :uint32], :void
332
334
  try_attach_function 'libusb_transfer_get_stream_id', [:libusb_transfer], :uint32
333
335
 
334
- attach_function 'libusb_handle_events', [:libusb_context], :int, :blocking=>true
335
- try_attach_function 'libusb_handle_events_completed', [:libusb_context, :pointer], :int, :blocking=>true
336
- attach_function 'libusb_handle_events_timeout', [:libusb_context, :pointer], :int, :blocking=>true
337
- try_attach_function 'libusb_handle_events_timeout_completed', [:libusb_context, :pointer, :pointer], :int, :blocking=>true
336
+ attach_function 'libusb_handle_events', [:libusb_context], :int, blocking: true
337
+ try_attach_function 'libusb_handle_events_completed', [:libusb_context, :pointer], :int, blocking: true
338
+ attach_function 'libusb_handle_events_timeout', [:libusb_context, :pointer], :int, blocking: true
339
+ try_attach_function 'libusb_handle_events_timeout_completed', [:libusb_context, :pointer, :pointer], :int, blocking: true
340
+ try_attach_function 'libusb_interrupt_event_handler', [:libusb_context], :void
338
341
 
339
342
  callback :libusb_pollfd_added_cb, [:int, :short, :pointer], :void
340
343
  callback :libusb_pollfd_removed_cb, [:int, :pointer], :void
@@ -130,7 +130,7 @@ module USB
130
130
  end
131
131
 
132
132
  def USB.each_device_by_class(devclass, subclass=nil, protocol=nil)
133
- devs = default_context.devices :bClass=>devclass, :bSubClass=>subclass, :bProtocol=>protocol
133
+ devs = default_context.devices bClass: devclass, bSubClass: subclass, bProtocol: protocol
134
134
  devs.each do |dev|
135
135
  yield Device.new(dev)
136
136
  end
@@ -313,31 +313,31 @@ module USB
313
313
  def usb_control_msg(requesttype, request, value, index, bytes, timeout)
314
314
  if requesttype&LIBUSB::ENDPOINT_IN != 0
315
315
  # transfer direction in
316
- res = @dev.control_transfer(:bmRequestType=>requesttype, :bRequest=>request,
317
- :wValue=>value, :wIndex=>index, :dataIn=>bytes.bytesize, :timeout=>timeout)
316
+ res = @dev.control_transfer(bmRequestType: requesttype, bRequest: request,
317
+ wValue: value, wIndex: index, dataIn: bytes.bytesize, timeout: timeout)
318
318
  bytes[0, res.bytesize] = res
319
319
  res.bytesize
320
320
  else
321
321
  # transfer direction out
322
- @dev.control_transfer(:bmRequestType=>requesttype, :bRequest=>request, :wValue=>value,
323
- :wIndex=>index, :dataOut=>bytes, :timeout=>timeout)
322
+ @dev.control_transfer(bmRequestType: requesttype, bRequest: request, wValue: value,
323
+ wIndex: index, dataOut: bytes, timeout: timeout)
324
324
  end
325
325
  end
326
326
 
327
327
  def usb_bulk_write(endpoint, bytes, timeout)
328
- @dev.bulk_transfer(:endpoint=>endpoint, :dataOut=>bytes, :timeout=>timeout)
328
+ @dev.bulk_transfer(endpoint: endpoint, dataOut: bytes, timeout: timeout)
329
329
  end
330
330
  def usb_bulk_read(endpoint, bytes, timeout)
331
- res = @dev.bulk_transfer(:endpoint=>endpoint, :dataIn=>bytes.bytesize, :timeout=>timeout)
331
+ res = @dev.bulk_transfer(endpoint: endpoint, dataIn: bytes.bytesize, timeout: timeout)
332
332
  bytes[0, res.bytesize] = res
333
333
  res.bytesize
334
334
  end
335
335
 
336
336
  def usb_interrupt_write(endpoint, bytes, timeout)
337
- @dev.interrupt_transfer(:endpoint=>endpoint, :dataOut=>bytes, :timeout=>timeout)
337
+ @dev.interrupt_transfer(endpoint: endpoint, dataOut: bytes, timeout: timeout)
338
338
  end
339
339
  def usb_interrupt_read(endpoint, bytes, timeout)
340
- res = @dev.interrupt_transfer(:endpoint=>endpoint, :dataIn=>bytes.bytesize, :timeout=>timeout)
340
+ res = @dev.interrupt_transfer(endpoint: endpoint, dataIn: bytes.bytesize, timeout: timeout)
341
341
  bytes[0, res.bytesize] = res
342
342
  res.bytesize
343
343
  end
@@ -181,6 +181,8 @@ module LIBUSB
181
181
  # @param [Integer, nil] timeout the maximum time (in millseconds) to block waiting for
182
182
  # events, or 0 for non-blocking mode
183
183
  # @param [Context::CompletionFlag, nil] completion_flag CompletionFlag to check
184
+ #
185
+ # @see interrupt_event_handler
184
186
  def handle_events(timeout=nil, completion_flag=nil)
185
187
  if completion_flag && !completion_flag.is_a?(Context::CompletionFlag)
186
188
  raise ArgumentError, "completion_flag is not a CompletionFlag"
@@ -203,6 +205,19 @@ module LIBUSB
203
205
  LIBUSB.raise_error res, "in libusb_handle_events" if res<0
204
206
  end
205
207
 
208
+ if Call.respond_to?(:libusb_interrupt_event_handler)
209
+ # Interrupt any active thread that is handling events.
210
+ #
211
+ # This is mainly useful for interrupting a dedicated event handling thread when an application wishes to call {Context#exit}.
212
+ #
213
+ # Available since libusb-1.0.21.
214
+ #
215
+ # @see handle_events
216
+ def interrupt_event_handler
217
+ Call.libusb_interrupt_event_handler(@ctx)
218
+ end
219
+ end
220
+
206
221
  # Obtain a list of devices currently attached to the USB system, optionally matching certain criteria.
207
222
  #
208
223
  # @param [Hash] filter_hash A number of criteria can be defined in key-value pairs.
@@ -218,7 +233,7 @@ module LIBUSB
218
233
  #
219
234
  # @example
220
235
  # # Return all devices of vendor 0x0ab1 where idProduct is 3 or 4:
221
- # context.device :idVendor=>0x0ab1, :idProduct=>[0x0003, 0x0004]
236
+ # context.device idVendor: 0x0ab1, idProduct: [0x0003, 0x0004]
222
237
  #
223
238
  # @return [Array<LIBUSB::Device>]
224
239
  def devices(filter_hash={})
@@ -0,0 +1,7 @@
1
+ module LIBUSB
2
+ LIBUSB_VERSION = ENV['LIBUSB_VERSION'] || '1.0.21'
3
+ LIBUSB_SOURCE_URI = "https://github.com/libusb/libusb/releases/download/v#{LIBUSB_VERSION}/libusb-#{LIBUSB_VERSION}.tar.bz2"
4
+ LIBUSB_SOURCE_SHA1 = '54d71841542eb1a6f0b0420878a4d5434efe8d28'
5
+
6
+ MINI_PORTILE_VERSION = '~> 2.1'
7
+ end
@@ -41,6 +41,9 @@ module LIBUSB
41
41
  #
42
42
  # This is a non-blocking function; no requests are sent over the bus.
43
43
  def close
44
+ @bulk_transfer.free_buffer if @bulk_transfer
45
+ @interrupt_transfer.free_buffer if @interrupt_transfer
46
+ @control_transfer.free_buffer if @control_transfer
44
47
  Call.libusb_close(@pHandle)
45
48
  end
46
49
 
@@ -235,6 +238,13 @@ module LIBUSB
235
238
  LIBUSB.raise_error res, "in libusb_free_streams" unless res>=0
236
239
  nil
237
240
  end
241
+
242
+ else
243
+
244
+ def alloc_streams(num_streams, endpoints)
245
+ raise NotImplementedError, "libusb-1.0.19+ is required for bulk stream transfers"
246
+ end
247
+
238
248
  end
239
249
 
240
250
  # Determine if a kernel driver is active on an interface.
@@ -374,7 +384,7 @@ module LIBUSB
374
384
  raise ArgumentError, "invalid params #{args.inspect}" unless args.empty?
375
385
 
376
386
  # reuse transfer struct to speed up transfer
377
- @bulk_transfer ||= BulkTransfer.new :dev_handle => self
387
+ @bulk_transfer ||= BulkTransfer.new dev_handle: self, allow_device_memory: true
378
388
  tr = @bulk_transfer
379
389
  tr.endpoint = endpoint
380
390
  tr.timeout = timeout
@@ -442,7 +452,7 @@ module LIBUSB
442
452
  raise ArgumentError, "invalid params #{args.inspect}" unless args.empty?
443
453
 
444
454
  # reuse transfer struct to speed up transfer
445
- @interrupt_transfer ||= InterruptTransfer.new :dev_handle => self
455
+ @interrupt_transfer ||= InterruptTransfer.new dev_handle: self, allow_device_memory: true
446
456
  tr = @interrupt_transfer
447
457
  tr.endpoint = endpoint
448
458
  tr.timeout = timeout
@@ -502,7 +512,7 @@ module LIBUSB
502
512
  raise ArgumentError, "invalid params #{args.inspect}" unless args.empty?
503
513
 
504
514
  # reuse transfer struct to speed up transfer
505
- @control_transfer ||= ControlTransfer.new :dev_handle => self
515
+ @control_transfer ||= ControlTransfer.new dev_handle: self, allow_device_memory: true
506
516
  tr = @control_transfer
507
517
  tr.timeout = timeout
508
518
  if dataIn
@@ -141,7 +141,7 @@ class DevHandle
141
141
  # Execute an eventmachine driven USB bulk transfer.
142
142
  #
143
143
  # @example
144
- # tr = devh.eventmachine_bulk_transfer( :endpoint => 0x02, :dataOut => "data" )
144
+ # tr = devh.eventmachine_bulk_transfer( endpoint: 0x02, dataOut: "data" )
145
145
  # tr.callback do |data|
146
146
  # puts "sent: #{data.inspect}"
147
147
  # end
@@ -159,9 +159,9 @@ class DevHandle
159
159
  #
160
160
  # @example
161
161
  # tr = devh.eventmachine_control_transfer(
162
- # :bmRequestType=>ENDPOINT_IN|REQUEST_TYPE_CLASS|RECIPIENT_INTERFACE,
163
- # :bRequest=>0x01,
164
- # :wValue=>0, :wIndex=>0, :dataIn=>1 )
162
+ # bmRequestType: ENDPOINT_IN|REQUEST_TYPE_CLASS|RECIPIENT_INTERFACE,
163
+ # bRequest: 0x01,
164
+ # wValue: 0, wIndex: 0, dataIn: 1 )
165
165
  # tr.callback do |data|
166
166
  # puts "recved: #{data.inspect}"
167
167
  # end
@@ -25,10 +25,29 @@ module LIBUSB
25
25
  # Using {Transfer} derived classes directly, however, is needed for isochronous transfers and
26
26
  # allows a more advanced buffer management.
27
27
  class Transfer
28
+ class ZeroCopyMemory < FFI::Pointer
29
+ attr_reader :size
30
+
31
+ def initialize(dev_handle, ptr, size)
32
+ @dev_handle = dev_handle
33
+ @size = size
34
+ super(ptr)
35
+ end
36
+
37
+ def free(id=nil)
38
+ return unless @size
39
+ # puts format("libusb_dev_mem_free(%#x, %d)%s", address, @size, id ? " by GC" : '')
40
+ res = Call.libusb_dev_mem_free( @dev_handle.pHandle, self, @size )
41
+ LIBUSB.raise_error res, "in libusb_dev_mem_free" if res!=0
42
+ @size = nil
43
+ end
44
+ end
45
+
28
46
  def initialize(args={})
29
- args.each{|k,v| send("#{k}=", v) }
30
47
  @buffer = nil
31
48
  @completion_flag = Context::CompletionFlag.new
49
+ @allow_device_memory = false
50
+ args.each{|k,v| send("#{k}=", v) }
32
51
  end
33
52
  private :initialize
34
53
 
@@ -52,11 +71,9 @@ module LIBUSB
52
71
  end
53
72
 
54
73
  # Set output data that should be sent.
74
+ # @see #allow_device_memory
55
75
  def buffer=(data)
56
- if !@buffer || data.bytesize>@buffer.size
57
- free_buffer
58
- @buffer = FFI::MemoryPointer.new(data.bytesize, 1, false)
59
- end
76
+ ensure_enough_buffer(data.bytesize)
60
77
  @buffer.put_bytes(0, data)
61
78
  @transfer[:buffer] = @buffer
62
79
  @transfer[:length] = data.bytesize
@@ -81,11 +98,9 @@ module LIBUSB
81
98
  #
82
99
  # @param [Fixnum] len Number of bytes to allocate
83
100
  # @param [String, nil] data some data to initialize the buffer with
101
+ # @see #allow_device_memory
84
102
  def alloc_buffer(len, data=nil)
85
- if !@buffer || len>@buffer.size
86
- free_buffer
87
- @buffer = FFI::MemoryPointer.new(len, 1, false)
88
- end
103
+ ensure_enough_buffer(len)
89
104
  @buffer.put_bytes(0, data) if data
90
105
  @transfer[:buffer] = @buffer
91
106
  @transfer[:length] = len
@@ -96,6 +111,52 @@ module LIBUSB
96
111
  @transfer[:actual_length]
97
112
  end
98
113
 
114
+ # Try to use persistent device memory.
115
+ #
116
+ # If enabled, attempts to allocate a block of persistent DMA memory suitable for transfers against the given device.
117
+ # The memory is allocated by {#alloc_buffer} or {#buffer=}.
118
+ # If unsuccessful, ordinary user space memory will be used.
119
+ #
120
+ # Using this memory instead of regular memory means that the host controller can use DMA directly into the buffer to increase performance, and also that transfers can no longer fail due to kernel memory fragmentation.
121
+ #
122
+ # It requires libusb-1.0.21 and Linux-4.6 to be effective, but it can safely be enabled on other systems.
123
+ #
124
+ # Note that this type of memory is bound to the {#dev_handle=}.
125
+ # So even if the {DevHandle} is closed, the memory is still accessable and the device is locked.
126
+ # It is free'd by the garbage collector eventually, but in order to close the device deterministic, it is required to call {#free_buffer} on all {Transfer}s which use persistent device memory.
127
+ #
128
+ # @see #free_buffer
129
+ # @see #memory_type
130
+ attr_accessor :allow_device_memory
131
+
132
+ # @return +:device_memory+ - If persistent device memory is allocated.
133
+ # @return +:user_space+ - If user space memory is allocated.
134
+ # @return +nil+ - If no memory is allocated.
135
+ def memory_type
136
+ case @buffer
137
+ when ZeroCopyMemory then :device_memory
138
+ when FFI::MemoryPointer then :user_space
139
+ else nil
140
+ end
141
+ end
142
+
143
+ def ensure_enough_buffer(len)
144
+ if !@buffer || len>@buffer.size
145
+ free_buffer
146
+ # Try to use zero-copy-memory and fallback to FFI-memory if not available
147
+ if @allow_device_memory && @dev_handle && Call.respond_to?(:libusb_dev_mem_alloc)
148
+ ptr = Call.libusb_dev_mem_alloc( @dev_handle.pHandle, len )
149
+ # puts format("libusb_dev_mem_alloc(%d) => %#x", len, ptr.address)
150
+ unless ptr.null?
151
+ buffer = ZeroCopyMemory.new(@dev_handle, ptr, len)
152
+ ObjectSpace.define_finalizer(self, buffer.method(:free))
153
+ end
154
+ end
155
+ @buffer = buffer || FFI::MemoryPointer.new(len, 1, false)
156
+ end
157
+ end
158
+ private :ensure_enough_buffer
159
+
99
160
  # Retrieve the data actually transferred.
100
161
  #
101
162
  # @param [Fixnum] offset optional offset of the retrieved data in the buffer.
@@ -228,7 +289,7 @@ module LIBUSB
228
289
 
229
290
  # Get a transfers bulk stream id.
230
291
  #
231
- # Since version 1.0.19.
292
+ # Available since libusb-1.0.19.
232
293
  #
233
294
  # @return [Fixnum] the stream id for the transfer
234
295
  def stream_id
@@ -15,5 +15,5 @@
15
15
 
16
16
  module LIBUSB
17
17
  # Library version of libusb for Ruby
18
- VERSION = "0.5.1"
18
+ VERSION = "0.6.0"
19
19
  end
@@ -1,6 +1,7 @@
1
1
  # -*- encoding: utf-8 -*-
2
2
  $:.push File.expand_path("../lib", __FILE__)
3
3
  require "libusb/version_gem"
4
+ require "libusb/dependencies"
4
5
 
5
6
  Gem::Specification.new do |s|
6
7
  s.name = "libusb"
@@ -10,19 +11,20 @@ Gem::Specification.new do |s|
10
11
  s.homepage = "http://github.com/larskanis/libusb"
11
12
  s.summary = %q{Access USB devices from Ruby via libusb-1.0}
12
13
  s.description = %q{LIBUSB is a Ruby binding that gives Ruby programmers access to arbitrary USB devices}
13
- s.licenses = ['LGPL-3']
14
+ s.licenses = ['LGPL-3.0']
14
15
  s.rdoc_options = %w[--main README.md --charset=UTF-8]
15
16
 
16
- s.rubyforge_project = "libusb"
17
-
18
17
  s.files = `git ls-files`.split("\n")
18
+ s.files << "ports/archives/libusb-#{LIBUSB::LIBUSB_VERSION}.tar.bz2"
19
19
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
20
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
21
21
  s.require_paths = ["lib"]
22
22
  s.extensions = ['ext/extconf.rb']
23
23
 
24
- s.add_runtime_dependency 'ffi', '>= 1.0'
24
+ s.required_ruby_version = Gem::Requirement.new(">= 1.9.3")
25
+ s.add_runtime_dependency 'ffi', '~> 1.0'
26
+ s.add_runtime_dependency 'mini_portile2', LIBUSB::MINI_PORTILE_VERSION
25
27
  s.add_development_dependency 'rake-compiler', '~> 0.9'
26
28
  s.add_development_dependency 'rake-compiler-dock', '~> 0.2'
27
- s.add_development_dependency 'bundler'
29
+ s.add_development_dependency 'bundler', '~> 1.0'
28
30
  end
@@ -44,7 +44,7 @@ class TestLibusbBulkStreamTransfer < Minitest::Test
44
44
  end
45
45
 
46
46
  def test_bulk_stream_transfer
47
- tr = BulkStreamTransfer.new :dev_handle=>@dev, :stream_id=>123, :buffer=>' '*100
47
+ tr = BulkStreamTransfer.new dev_handle: @dev, stream_id: 123, buffer: ' '*100
48
48
  assert_equal 123, tr.stream_id, "stream_id should match"
49
49
  end
50
50
  end
@@ -161,11 +161,11 @@ class TestLibusbDescriptors < Minitest::Test
161
161
  end
162
162
  end
163
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 )
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
166
  assert_equal devs1.sort, devs2.sort, "devices and devices with filter should deliver the same device"
167
167
 
168
- devs3 = usb.devices( :bClass=>[CLASS_MASS_STORAGE], :bSubClass=>[0x01,0x06], :bProtocol=>[0x50] )
168
+ devs3 = usb.devices( bClass: [CLASS_MASS_STORAGE], bSubClass: [0x01,0x06], bProtocol: [0x50] )
169
169
  assert_equal devs1.sort, devs3.sort, "devices and devices with array-filter should deliver the same device"
170
170
  end
171
171
 
@@ -179,7 +179,7 @@ class TestLibusbDescriptors < Minitest::Test
179
179
  end
180
180
  end
181
181
 
182
- devs2 = usb.devices( :bClass=>CLASS_HUB )
182
+ devs2 = usb.devices( bClass: CLASS_HUB )
183
183
  assert_equal devs1.sort, devs2.sort, "devices and devices with filter should deliver the same device"
184
184
  end
185
185
 
@@ -32,7 +32,7 @@ class TestLibusbEventMachine < Minitest::Test
32
32
  @context = Context.new
33
33
  @context.debug = 3
34
34
 
35
- @device = context.devices( :bClass=>CLASS_MASS_STORAGE, :bSubClass=>[0x06,0x01], :bProtocol=>0x50 ).last
35
+ @device = context.devices( bClass: CLASS_MASS_STORAGE, bSubClass: [0x06,0x01], bProtocol: 0x50 ).last
36
36
  skip "no mass storage device found" unless @device
37
37
 
38
38
  @endpoint_in = @device.endpoints.find{|ep| ep.bEndpointAddress&ENDPOINT_IN != 0 }
@@ -70,9 +70,9 @@ class TestLibusbEventMachine < Minitest::Test
70
70
  em_run do
71
71
  ticks = 0
72
72
  tr = devh.eventmachine_bulk_transfer(
73
- :endpoint => @endpoint_in,
74
- :timeout => 1500,
75
- :dataIn => 123 )
73
+ endpoint: @endpoint_in,
74
+ timeout: 1500,
75
+ dataIn: 123 )
76
76
  # puts "started usb transfer #{tr}"
77
77
 
78
78
  tr.callback do |data|
@@ -98,9 +98,9 @@ class TestLibusbEventMachine < Minitest::Test
98
98
  def test_event_loop
99
99
  em_run do
100
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 )
101
+ bmRequestType: ENDPOINT_IN|REQUEST_TYPE_CLASS|RECIPIENT_INTERFACE,
102
+ bRequest: BOMS_GET_MAX_LUN,
103
+ wValue: 0, wIndex: 0, dataIn: 1 )
104
104
 
105
105
  # puts "started usb transfer #{tr}"
106
106
  tr.callback do |data|
@@ -31,7 +31,7 @@ class TestLibusbHotplug < Minitest::Test
31
31
 
32
32
  def test_enumerate
33
33
  devs = []
34
- ctx.on_hotplug_event :flags => HOTPLUG_ENUMERATE do |dev, event|
34
+ ctx.on_hotplug_event flags: HOTPLUG_ENUMERATE do |dev, event|
35
35
  devs << dev
36
36
  assert_equal :HOTPLUG_EVENT_DEVICE_ARRIVED, event
37
37
  :repeat
@@ -44,7 +44,7 @@ class TestLibusbHotplug < Minitest::Test
44
44
 
45
45
  def test_enumerate_with_left
46
46
  devs = []
47
- ctx.on_hotplug_event :flags => HOTPLUG_ENUMERATE, :events => HOTPLUG_EVENT_DEVICE_LEFT do |dev, event|
47
+ ctx.on_hotplug_event flags: HOTPLUG_ENUMERATE, events: HOTPLUG_EVENT_DEVICE_LEFT do |dev, event|
48
48
  devs << dev
49
49
  assert_equal :HOTPLUG_EVENT_DEVICE_ARRIVED, event
50
50
  :repeat
@@ -65,7 +65,7 @@ class TestLibusbHotplug < Minitest::Test
65
65
 
66
66
  def test_wrong_yieldreturn
67
67
  ex = assert_raises(ArgumentError) do
68
- ctx.on_hotplug_event :flags => :HOTPLUG_ENUMERATE do |dev, event|
68
+ ctx.on_hotplug_event flags: :HOTPLUG_ENUMERATE do |dev, event|
69
69
  end
70
70
  end
71
71
 
@@ -112,4 +112,16 @@ class TestLibusbHotplug < Minitest::Test
112
112
  assert_operator devs2.map(&:last), :include?, :HOTPLUG_EVENT_DEVICE_ARRIVED, "Should have received ARRIVED"
113
113
  assert_operator devs2.map(&:last), :include?, :HOTPLUG_EVENT_DEVICE_LEFT, "Should have received LEFT"
114
114
  end
115
+
116
+ def test_interrupt_event_handler
117
+ th = Thread.new do
118
+ ctx.handle_events 5000
119
+ end
120
+
121
+ sleep 0.1 # Workaround a bug in libusb-1,0.21
122
+ st = Time.now
123
+ ctx.interrupt_event_handler
124
+ th.join
125
+ assert_operator Time.now-st, :<, 5.0
126
+ end
115
127
  end
@@ -34,7 +34,7 @@ class TestLibusbIsoTransfer < Minitest::Test
34
34
  end
35
35
 
36
36
  def test_iso_transfer
37
- tr = IsochronousTransfer.new 10, :dev_handle=>@dev
37
+ tr = IsochronousTransfer.new 10, dev_handle: @dev
38
38
  assert_equal 10, tr.num_packets, "number of packets should match"
39
39
 
40
40
  tr.buffer = " "*130
@@ -40,7 +40,7 @@ class TestLibusbMassStorage < Minitest::Test
40
40
  @usb.debug = 3
41
41
  @asynchron = false
42
42
 
43
- @device = usb.devices( :bClass=>CLASS_MASS_STORAGE, :bSubClass=>[0x06,0x01], :bProtocol=>0x50 ).last
43
+ @device = usb.devices( bClass: CLASS_MASS_STORAGE, bSubClass: [0x06,0x01], bProtocol: 0x50 ).last
44
44
  skip "no mass storage device found" unless @device
45
45
 
46
46
  @endpoint_in = @device.endpoints.find{|ep| ep.bEndpointAddress&ENDPOINT_IN != 0 }
@@ -97,10 +97,10 @@ class TestLibusbMassStorage < Minitest::Test
97
97
  cbw = ['USBC', expected_tag, data_length, direction, lun, cdb.length, cdb].pack('a*VVCCCa*')
98
98
  cbw = cbw.ljust(31, "\0")
99
99
 
100
- num_bytes = bulk_transfer(:endpoint=>endpoint_out, :dataOut=>cbw)
100
+ num_bytes = bulk_transfer(endpoint: endpoint_out, dataOut: cbw)
101
101
  assert_equal 31, num_bytes, "31 bytes CBW should be sent"
102
102
 
103
- recv = bulk_transfer(:endpoint=>endpoint_in, :dataIn=>data_length)
103
+ recv = bulk_transfer(endpoint: endpoint_in, dataIn: data_length)
104
104
 
105
105
  get_mass_storage_status(expected_tag)
106
106
  return recv
@@ -109,7 +109,7 @@ class TestLibusbMassStorage < Minitest::Test
109
109
  def get_mass_storage_status(expected_tag)
110
110
  retries = 5
111
111
  buffer = begin
112
- bulk_transfer(:endpoint=>endpoint_in, :dataIn=>13)
112
+ bulk_transfer(endpoint: endpoint_in, dataIn: 13)
113
113
  rescue LIBUSB::ERROR_PIPE
114
114
  if (retries-=1)>=0
115
115
  dev.clear_halt(endpoint_in)
@@ -167,23 +167,23 @@ class TestLibusbMassStorage < Minitest::Test
167
167
 
168
168
  def mass_storage_reset
169
169
  res = control_transfer(
170
- :bmRequestType=>ENDPOINT_OUT|REQUEST_TYPE_CLASS|RECIPIENT_INTERFACE,
171
- :bRequest=>BOMS_RESET,
172
- :wValue=>0, :wIndex=>0)
170
+ bmRequestType: ENDPOINT_OUT|REQUEST_TYPE_CLASS|RECIPIENT_INTERFACE,
171
+ bRequest: BOMS_RESET,
172
+ wValue: 0, wIndex: 0)
173
173
  assert_equal 0, res, "BOMS_RESET response should be 0 byte"
174
174
 
175
175
  res = control_transfer(
176
- :bmRequestType=>ENDPOINT_OUT|REQUEST_TYPE_CLASS|RECIPIENT_INTERFACE,
177
- :bRequest=>BOMS_RESET,
178
- :wValue=>0, :wIndex=>0, :dataOut=>'')
176
+ bmRequestType: ENDPOINT_OUT|REQUEST_TYPE_CLASS|RECIPIENT_INTERFACE,
177
+ bRequest: BOMS_RESET,
178
+ wValue: 0, wIndex: 0, dataOut: '')
179
179
  assert_equal 0, res, "BOMS_RESET response should be 0 byte"
180
180
  end
181
181
 
182
182
  def read_max_lun
183
183
  res = control_transfer(
184
- :bmRequestType=>ENDPOINT_IN|REQUEST_TYPE_CLASS|RECIPIENT_INTERFACE,
185
- :bRequest=>BOMS_GET_MAX_LUN,
186
- :wValue=>0, :wIndex=>0, :dataIn=>1)
184
+ bmRequestType: ENDPOINT_IN|REQUEST_TYPE_CLASS|RECIPIENT_INTERFACE,
185
+ bRequest: BOMS_GET_MAX_LUN,
186
+ wValue: 0, wIndex: 0, dataIn: 1)
187
187
  assert [0].pack("C")==res || [1].pack("C")==res, "BOMS_GET_MAX_LUN response is usually 0 or 1"
188
188
  end
189
189
 
@@ -217,7 +217,7 @@ class TestLibusbMassStorage < Minitest::Test
217
217
  end
218
218
  assert_raises(LIBUSB::ERROR_TIMEOUT) do
219
219
  begin
220
- bulk_transfer(:endpoint=>endpoint_in, :dataIn=>123)
220
+ bulk_transfer(endpoint: endpoint_in, dataIn: 123)
221
221
  rescue LIBUSB::ERROR_TIMEOUT => err
222
222
  assert_kind_of String, err.transferred
223
223
  raise
@@ -258,11 +258,11 @@ class TestLibusbMassStorage < Minitest::Test
258
258
  end
259
259
 
260
260
  def test_wrong_argument
261
- assert_raises(ArgumentError){ dev.bulk_transfer(:endpoint=>endpoint_in, :dataOut=>"data") }
262
- assert_raises(ArgumentError){ dev.interrupt_transfer(:endpoint=>endpoint_in, :dataOut=>"data") }
261
+ assert_raises(ArgumentError){ dev.bulk_transfer(endpoint: endpoint_in, dataOut: "data") }
262
+ assert_raises(ArgumentError){ dev.interrupt_transfer(endpoint: endpoint_in, dataOut: "data") }
263
263
  assert_raises(ArgumentError){ dev.control_transfer(
264
- :bmRequestType=>ENDPOINT_OUT|REQUEST_TYPE_CLASS|RECIPIENT_INTERFACE,
265
- :bRequest=>BOMS_RESET,
266
- :wValue=>0, :wIndex=>0, :dataIn=>123) }
264
+ bmRequestType: ENDPOINT_OUT|REQUEST_TYPE_CLASS|RECIPIENT_INTERFACE,
265
+ bRequest: BOMS_RESET,
266
+ wValue: 0, wIndex: 0, dataIn: 123) }
267
267
  end
268
268
  end
@@ -27,7 +27,7 @@ class TestLibusbMassStorage2 < Minitest::Test
27
27
  def setup
28
28
  @usb = Context.new
29
29
  @usb.debug = 3
30
- @device = usb.devices( :bClass=>CLASS_MASS_STORAGE, :bSubClass=>[0x06,0x01], :bProtocol=>0x50 ).last
30
+ @device = usb.devices( bClass: CLASS_MASS_STORAGE, bSubClass: [0x06,0x01], bProtocol: 0x50 ).last
31
31
  skip "no mass storage device found" unless @device
32
32
 
33
33
  @interface = device.interfaces.first
@@ -42,4 +42,17 @@ class TestLibusbStructs < Minitest::Test
42
42
  assert_equal false, s.completed?
43
43
  assert_equal 0, s[:completed]
44
44
  end
45
+
46
+ def test_Transfer
47
+ t = LIBUSB::InterruptTransfer.new allow_device_memory: true
48
+ assert_equal :TRANSFER_COMPLETED, t.status
49
+ assert_equal true, t.allow_device_memory
50
+ assert_equal nil, t.memory_type
51
+
52
+ t.alloc_buffer(10)
53
+ assert_equal :user_space, t.memory_type, "no device assigned -> should use memory from user space"
54
+
55
+ t.free_buffer
56
+ assert_equal nil, t.memory_type
57
+ end
45
58
  end
@@ -34,7 +34,7 @@ class TestLibusbThreads < Minitest::Test
34
34
  @usb = Context.new
35
35
  @usb.debug = 3
36
36
 
37
- @devices = usb.devices( :bClass=>CLASS_MASS_STORAGE, :bSubClass=>[0x06,0x01], :bProtocol=>0x50 )
37
+ @devices = usb.devices( bClass: CLASS_MASS_STORAGE, bSubClass: [0x06,0x01], bProtocol: 0x50 )
38
38
  skip "less than two mass storage devices found" unless @devices.length >= 2
39
39
 
40
40
  @devs = @devices.map do |device|
@@ -71,7 +71,7 @@ class TestLibusbThreads < Minitest::Test
71
71
  1.times do
72
72
  st = Time.now
73
73
  assert_raises LIBUSB::ERROR_TIMEOUT do
74
- dev.bulk_transfer(:endpoint=>endpoint, :dataIn=>123, :timeout=>100)
74
+ dev.bulk_transfer(endpoint: endpoint, dataIn: 123, timeout: 100)
75
75
  end
76
76
  assert_operator Time.now-st, :<, 5
77
77
  dev.clear_halt(endpoint)
Binary file
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: libusb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.1
4
+ version: 0.6.0
5
5
  platform: x64-mingw32
6
6
  authors:
7
7
  - Lars Kanis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-29 00:00:00.000000000 Z
11
+ date: 2016-12-09 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
19
  version: '1.0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
26
  version: '1.0'
27
27
  - !ruby/object:Gem::Dependency
@@ -56,16 +56,16 @@ dependencies:
56
56
  name: bundler
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
- - - ">="
59
+ - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0'
61
+ version: '1.0'
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
- - - ">="
66
+ - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0'
68
+ version: '1.0'
69
69
  description: LIBUSB is a Ruby binding that gives Ruby programmers access to arbitrary
70
70
  USB devices
71
71
  email:
@@ -82,6 +82,7 @@ files:
82
82
  - History.md
83
83
  - README.md
84
84
  - Rakefile
85
+ - appveyor.yml
85
86
  - lib/libusb-1.0.dll
86
87
  - lib/libusb.rb
87
88
  - lib/libusb/bos.rb
@@ -90,6 +91,7 @@ files:
90
91
  - lib/libusb/configuration.rb
91
92
  - lib/libusb/constants.rb
92
93
  - lib/libusb/context.rb
94
+ - lib/libusb/dependencies.rb
93
95
  - lib/libusb/dev_handle.rb
94
96
  - lib/libusb/device.rb
95
97
  - lib/libusb/endpoint.rb
@@ -117,9 +119,10 @@ files:
117
119
  - test/test_libusb_structs.rb
118
120
  - test/test_libusb_threads.rb
119
121
  - test/test_libusb_version.rb
122
+ - wireshark-usb-sniffer.png
120
123
  homepage: http://github.com/larskanis/libusb
121
124
  licenses:
122
- - LGPL-3
125
+ - LGPL-3.0
123
126
  metadata: {}
124
127
  post_install_message:
125
128
  rdoc_options:
@@ -132,15 +135,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
132
135
  requirements:
133
136
  - - ">="
134
137
  - !ruby/object:Gem::Version
135
- version: '0'
138
+ version: 1.9.3
136
139
  required_rubygems_version: !ruby/object:Gem::Requirement
137
140
  requirements:
138
141
  - - ">="
139
142
  - !ruby/object:Gem::Version
140
143
  version: '0'
141
144
  requirements: []
142
- rubyforge_project: libusb
143
- rubygems_version: 2.4.8
145
+ rubyforge_project:
146
+ rubygems_version: 2.5.2
144
147
  signing_key:
145
148
  specification_version: 4
146
149
  summary: Access USB devices from Ruby via libusb-1.0