libusb 0.4.1-x64-mingw32 → 0.5.0-x64-mingw32
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- checksums.yaml.gz.sig +3 -0
- data.tar.gz.sig +2 -0
- data/.travis.yml +3 -3
- data/History.md +8 -0
- data/README.md +1 -0
- data/Rakefile +14 -14
- data/lib/libusb.rb +3 -1
- data/lib/libusb/bos.rb +306 -0
- data/lib/libusb/call.rb +84 -0
- data/lib/libusb/constants.rb +4 -0
- data/lib/libusb/dev_handle.rb +77 -0
- data/lib/libusb/endpoint.rb +20 -0
- data/lib/libusb/ss_companion.rb +69 -0
- data/lib/libusb/transfer.rb +34 -0
- data/lib/libusb/version_gem.rb +1 -1
- data/libusb.gemspec +1 -0
- data/test/test_libusb_bos.rb +118 -0
- data/test/test_libusb_bulk_stream_transfer.rb +50 -0
- data/test/test_libusb_descriptors.rb +29 -0
- data/test/test_libusb_hotplug.rb +1 -1
- data/test/test_libusb_threads.rb +1 -1
- metadata +47 -29
- metadata.gz.sig +3 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 73cc1af425996963568d9c77e4909d821a825140
|
4
|
+
data.tar.gz: f68970c05f9bd6cdf91dd1e640afd872a074d00c
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3b0b81620aac1dcc34065a8f19e86e40ee672676f507c9f87998af9fbbf581c420c8b5748afd202a37b28efbbf00cd80db278ba059a19ac0d30cb643eb366e42
|
7
|
+
data.tar.gz: 8de2450c4be88e6157990ce53368b38897b2333fde913f7c60024a600143df29b1c318083c67ffc815f92d7c6b94c957d209050c681acc93667f2556d69e77ff
|
checksums.yaml.gz.sig
ADDED
data.tar.gz.sig
ADDED
data/.travis.yml
CHANGED
data/History.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
0.5.0 / 2015-01-08
|
2
|
+
------------------
|
3
|
+
* Add support for BOS describtors of libusb-1.0.16
|
4
|
+
* Add support for superspeed endpoint companion descriptors of libusb-1.0.16
|
5
|
+
* Add support for USB-3.0 bulk streams of libusb-1.0.19
|
6
|
+
* Update bundled libusb version to 1.0.19.
|
7
|
+
* Update windows cross build to gcc-4.8 and recent rubygems
|
8
|
+
|
1
9
|
0.4.1 / 2014-05-17
|
2
10
|
------------------
|
3
11
|
* Update bundled libusb version to 1.0.18.
|
data/README.md
CHANGED
@@ -18,6 +18,7 @@ Features
|
|
18
18
|
|
19
19
|
* Access to descriptors of devices, configurations, interfaces, settings and endpoints
|
20
20
|
* Synchronous and asynchronous communication for bulk, control, interrupt and isochronous transfers
|
21
|
+
* Support for USB-3.0 descriptors and bulk streams
|
21
22
|
* Compatibility layer for [ruby-usb](http://www.a-k-r.org/ruby-usb/) (API based on libusb-0.1). See {::USB} for description.
|
22
23
|
|
23
24
|
Synopsis
|
data/Rakefile
CHANGED
@@ -25,7 +25,7 @@ COMPILE_HOME = Pathname( "./tmp" ).expand_path
|
|
25
25
|
STATIC_SOURCESDIR = COMPILE_HOME + 'sources'
|
26
26
|
|
27
27
|
# Fetch tarball from sourceforge
|
28
|
-
LIBUSB_VERSION = ENV['LIBUSB_VERSION'] || '1.0.
|
28
|
+
LIBUSB_VERSION = ENV['LIBUSB_VERSION'] || '1.0.19'
|
29
29
|
LIBUSB_SOURCE_URI = URI( "http://downloads.sourceforge.net/project/libusb/libusb-1.0/libusb-#{LIBUSB_VERSION}/libusb-#{LIBUSB_VERSION}.tar.bz2" )
|
30
30
|
LIBUSB_TARBALL = STATIC_SOURCESDIR + File.basename( LIBUSB_SOURCE_URI.path )
|
31
31
|
|
@@ -98,6 +98,8 @@ class CrossLibrary < OpenStruct
|
|
98
98
|
|
99
99
|
libusb_env = [
|
100
100
|
"CFLAGS='-fno-omit-frame-pointer'",
|
101
|
+
"LDFLAGS='-static-libgcc'",
|
102
|
+
"CC='#{host_platform}-gcc -static-libgcc'", # hack libtool, since it doesn't support -static-libgcc yet.
|
101
103
|
]
|
102
104
|
|
103
105
|
# generate the makefile in a clean build location
|
@@ -123,17 +125,14 @@ class CrossLibrary < OpenStruct
|
|
123
125
|
|
124
126
|
task "libusb_dll:#{ruby_platform}" => libusb_dll
|
125
127
|
|
126
|
-
desc "compile static libusb libraries"
|
127
|
-
task :libusb_dll => "libusb_dll:#{ruby_platform}"
|
128
|
-
|
129
128
|
desc 'Cross compile libusb for win32'
|
130
129
|
task :cross => [ "libusb_dll:#{ruby_platform}" ] do |t|
|
131
|
-
spec = Gem::Specification::load("libusb.gemspec")
|
132
|
-
spec.instance_variable_set(:"@cache_file", nil) if spec.respond_to?(:cache_file)
|
130
|
+
spec = Gem::Specification::load("libusb.gemspec").dup
|
133
131
|
spec.platform = Gem::Platform.new(ruby_platform)
|
134
|
-
spec.files << "lib/#{File.basename(libusb_dll)}"
|
135
|
-
spec.files -= `git ls-files ext`.split("\n")
|
136
132
|
spec.extensions = []
|
133
|
+
spec.files -= `git ls-files ext`.split("\n")
|
134
|
+
spec_text_files = spec.files.dup
|
135
|
+
spec.files << "lib/#{File.basename(libusb_dll)}"
|
137
136
|
|
138
137
|
# Generate a package for this gem
|
139
138
|
pkg = Gem::PackageTask.new(spec) do |pkg|
|
@@ -145,22 +144,23 @@ class CrossLibrary < OpenStruct
|
|
145
144
|
end
|
146
145
|
|
147
146
|
# copy files of the gem to pkg directory
|
148
|
-
file pkg.package_dir_path =>
|
149
|
-
|
150
|
-
next if fn == "lib/#{File.basename(libusb_dll)}"
|
147
|
+
file pkg.package_dir_path => spec_text_files do
|
148
|
+
spec_text_files.each do |fn|
|
151
149
|
f = File.join(pkg.package_dir_path, fn)
|
152
150
|
fdir = File.dirname(f)
|
153
151
|
mkdir_p(fdir) if !File.exist?(fdir)
|
154
152
|
rm_f f
|
155
153
|
safe_ln(fn, f)
|
156
154
|
end
|
157
|
-
|
158
|
-
|
159
|
-
file pkg.package_dir_path => [libusb_dll] do
|
155
|
+
|
156
|
+
# copy libusb.dll to pkg directory
|
160
157
|
f = "#{pkg.package_dir_path}/lib/#{File.basename(libusb_dll)}"
|
158
|
+
mkdir_p File.dirname(f)
|
161
159
|
rm_f f
|
162
160
|
safe_ln libusb_dll, f
|
163
161
|
end
|
162
|
+
|
163
|
+
file "lib/#{File.basename(libusb_dll)}" => [libusb_dll]
|
164
164
|
end
|
165
165
|
end
|
166
166
|
end
|
data/lib/libusb.rb
CHANGED
@@ -25,7 +25,9 @@ module LIBUSB
|
|
25
25
|
autoload :Endpoint, 'libusb/endpoint'
|
26
26
|
autoload :Interface, 'libusb/interface'
|
27
27
|
autoload :Setting, 'libusb/setting'
|
28
|
-
|
28
|
+
autoload :SsCompanion, 'libusb/ss_companion'
|
29
|
+
autoload :Bos, 'libusb/bos'
|
30
|
+
%w[ Transfer BulkTransfer BulkStreamTransfer ControlTransfer InterruptTransfer IsoPacket IsochronousTransfer ].each do |klass|
|
29
31
|
autoload klass, 'libusb/transfer'
|
30
32
|
end
|
31
33
|
|
data/lib/libusb/bos.rb
ADDED
@@ -0,0 +1,306 @@
|
|
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 'libusb/call'
|
17
|
+
|
18
|
+
module LIBUSB
|
19
|
+
# A structure representing the Binary Device Object Store (BOS) descriptor.
|
20
|
+
# This descriptor is documented in section 9.6.2 of the USB 3.0 specification.
|
21
|
+
# All multiple-byte fields are represented in host-endian format.
|
22
|
+
class Bos < FFI::ManagedStruct
|
23
|
+
|
24
|
+
module GenericMethods
|
25
|
+
# @return [Integer] Size of this descriptor (in bytes)
|
26
|
+
def bLength
|
27
|
+
self[:bLength]
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [Integer] Descriptor type. Will have value LIBUSB::DT_DEVICE_CAPABILITY
|
31
|
+
# in this context.
|
32
|
+
def bDescriptorType
|
33
|
+
self[:bDescriptorType]
|
34
|
+
end
|
35
|
+
|
36
|
+
# @return [Integer] Device Capability type
|
37
|
+
def bDevCapabilityType
|
38
|
+
self[:bDevCapabilityType]
|
39
|
+
end
|
40
|
+
|
41
|
+
def inspect
|
42
|
+
"\#<#{self.class} cap: #{bDevCapabilityType} data: #{dev_capability_data.unpack("H*")[0]}>"
|
43
|
+
end
|
44
|
+
|
45
|
+
# @return [String] Device Capability data (bLength - 3 bytes)
|
46
|
+
def dev_capability_data
|
47
|
+
pointer.read_bytes(bLength - 3)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
# A generic representation of a BOS Device Capability descriptor.
|
52
|
+
class DeviceCapability < FFI::Struct
|
53
|
+
include GenericMethods
|
54
|
+
|
55
|
+
layout :bLength, :uint8,
|
56
|
+
:bDescriptorType, :uint8,
|
57
|
+
:bDevCapabilityType, :uint8
|
58
|
+
|
59
|
+
def initialize( bos, *args)
|
60
|
+
# Avoid that the bos struct is GC'ed before this instance
|
61
|
+
@bos = bos
|
62
|
+
super(*args)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# A structure representing the USB 2.0 Extension descriptor
|
67
|
+
# This descriptor is documented in section 9.6.2.1 of the USB 3.0 specification.
|
68
|
+
# All multiple-byte fields are represented in host-endian format.
|
69
|
+
class Usb20Extension < FFI::ManagedStruct
|
70
|
+
include GenericMethods
|
71
|
+
|
72
|
+
layout :bLength, :uint8,
|
73
|
+
:bDescriptorType, :uint8,
|
74
|
+
:bDevCapabilityType, :uint8,
|
75
|
+
:bmAttributes, :uint32
|
76
|
+
|
77
|
+
# Bitmap encoding of supported device level features.
|
78
|
+
# A value of one in a bit location indicates a feature is
|
79
|
+
# supported; a value of zero indicates it is not supported.
|
80
|
+
# @see Call::Usb20ExtensionAttributes
|
81
|
+
def bmAttributes
|
82
|
+
self[:bmAttributes]
|
83
|
+
end
|
84
|
+
|
85
|
+
# @return [Boolean] Supports Link Power Management (LPM)
|
86
|
+
def bm_lpm_support?
|
87
|
+
(bmAttributes & BM_LPM_SUPPORT) != 0
|
88
|
+
end
|
89
|
+
|
90
|
+
def inspect
|
91
|
+
attrs = Call::Usb20ExtensionAttributes.to_h.map do |k, v|
|
92
|
+
(bmAttributes & v) ? k.to_s : nil
|
93
|
+
end
|
94
|
+
"\#<#{self.class} #{attrs.compact.join(",")}>"
|
95
|
+
end
|
96
|
+
|
97
|
+
# @private
|
98
|
+
def self.release(ptr)
|
99
|
+
Call.libusb_free_usb_2_0_extension_descriptor(ptr)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# A structure representing the SuperSpeed USB Device Capability descriptor
|
104
|
+
# This descriptor is documented in section 9.6.2.2 of the USB 3.0 specification.
|
105
|
+
# All multiple-byte fields are represented in host-endian format.
|
106
|
+
class SsUsbDeviceCapability < FFI::ManagedStruct
|
107
|
+
include GenericMethods
|
108
|
+
|
109
|
+
layout :bLength, :uint8,
|
110
|
+
:bDescriptorType, :uint8,
|
111
|
+
:bDevCapabilityType, :uint8,
|
112
|
+
:bmAttributes, :uint32,
|
113
|
+
:wSpeedSupported, :uint16,
|
114
|
+
:bFunctionalitySupport, :uint8,
|
115
|
+
:bU1DevExitLat, :uint8,
|
116
|
+
:bU2DevExitLat, :uint16
|
117
|
+
|
118
|
+
# Bitmap encoding of supported device level features.
|
119
|
+
# A value of one in a bit location indicates a feature is
|
120
|
+
# supported; a value of zero indicates it is not supported.
|
121
|
+
#
|
122
|
+
# @return [Integer]
|
123
|
+
# @see Call::SsUsbDeviceCapabilityAttributes
|
124
|
+
def bmAttributes
|
125
|
+
self[:bmAttributes]
|
126
|
+
end
|
127
|
+
|
128
|
+
# @return [Boolean] Supports Latency Tolerance Messages (LTM)
|
129
|
+
def bm_ltm_support?
|
130
|
+
(bmAttributes & BM_LTM_SUPPORT) != 0
|
131
|
+
end
|
132
|
+
|
133
|
+
def inspect
|
134
|
+
attrs = Call::SsUsbDeviceCapabilityAttributes.to_h.map do |k,v|
|
135
|
+
(bmAttributes & v) != 0 ? k.to_s : nil
|
136
|
+
end
|
137
|
+
"\#<#{self.class} #{attrs.compact.join(",")} #{supported_speeds.join(",")}>"
|
138
|
+
end
|
139
|
+
|
140
|
+
# Bitmap encoding of the speed supported by this device when
|
141
|
+
# operating in SuperSpeed mode.
|
142
|
+
#
|
143
|
+
# @return [Integer]
|
144
|
+
# @see Call::SupportedSpeeds
|
145
|
+
def wSpeedSupported
|
146
|
+
self[:wSpeedSupported]
|
147
|
+
end
|
148
|
+
|
149
|
+
# @return [Array<Symbol>] speeds supported by this device when
|
150
|
+
# operating in SuperSpeed mode {Call::SupportedSpeeds}
|
151
|
+
def supported_speeds
|
152
|
+
speeds = Call::SupportedSpeeds.to_h.map do |k,v|
|
153
|
+
(wSpeedSupported & v) != 0 ? k : nil
|
154
|
+
end
|
155
|
+
speeds.compact
|
156
|
+
end
|
157
|
+
|
158
|
+
# The lowest speed at which all the functionality supported
|
159
|
+
# by the device is available to the user. For example if the
|
160
|
+
# device supports all its functionality when connected at
|
161
|
+
# full speed and above then it sets this value to 1.
|
162
|
+
#
|
163
|
+
# 0 - low speed
|
164
|
+
# 1 - full speed
|
165
|
+
# 2 - high speed
|
166
|
+
# 3 - super speed
|
167
|
+
# @return [Integer]
|
168
|
+
def bFunctionalitySupport
|
169
|
+
self[:bFunctionalitySupport]
|
170
|
+
end
|
171
|
+
|
172
|
+
# @return [Integer] U1 Device Exit Latency.
|
173
|
+
def bU1DevExitLat
|
174
|
+
self[:bU1DevExitLat]
|
175
|
+
end
|
176
|
+
|
177
|
+
# @return [Integer] U2 Device Exit Latency.
|
178
|
+
def bU2DevExitLat
|
179
|
+
self[:bU2DevExitLat]
|
180
|
+
end
|
181
|
+
|
182
|
+
# @private
|
183
|
+
def self.release(ptr)
|
184
|
+
Call.libusb_free_ss_usb_device_capability_descriptor(ptr)
|
185
|
+
end
|
186
|
+
end
|
187
|
+
|
188
|
+
# A structure representing the Container ID descriptor.
|
189
|
+
# This descriptor is documented in section 9.6.2.3 of the USB 3.0 specification.
|
190
|
+
# All multiple-byte fields, except UUIDs, are represented in host-endian format.
|
191
|
+
class ContainerId < FFI::ManagedStruct
|
192
|
+
include GenericMethods
|
193
|
+
|
194
|
+
layout :bLength, :uint8,
|
195
|
+
:bDescriptorType, :uint8,
|
196
|
+
:bDevCapabilityType, :uint8,
|
197
|
+
:bReserved, :uint8,
|
198
|
+
:ContainerID, [:uint8, 16]
|
199
|
+
|
200
|
+
# Reserved field
|
201
|
+
def bReserved
|
202
|
+
self[:bReserved]
|
203
|
+
end
|
204
|
+
|
205
|
+
# @return [String] 128 bit UUID
|
206
|
+
def container_id
|
207
|
+
self[:ContainerID].to_ptr.read_bytes(16)
|
208
|
+
end
|
209
|
+
|
210
|
+
def inspect
|
211
|
+
"\#<#{self.class} #{container_id.unpack("H*")[0]}>"
|
212
|
+
end
|
213
|
+
|
214
|
+
# @private
|
215
|
+
def self.release(ptr)
|
216
|
+
Call.libusb_free_container_id_descriptor(ptr)
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
def initialize( ctx, *args)
|
221
|
+
@ctx = ctx
|
222
|
+
super(*args)
|
223
|
+
end
|
224
|
+
|
225
|
+
layout :bLength, :uint8,
|
226
|
+
:bDescriptorType, :uint8,
|
227
|
+
:wTotalLength, :uint16,
|
228
|
+
:bNumDeviceCaps, :uint8,
|
229
|
+
:dev_capability, [:pointer, 0]
|
230
|
+
|
231
|
+
# @return [Integer] Size of this descriptor (in bytes)
|
232
|
+
def bLength
|
233
|
+
self[:bLength]
|
234
|
+
end
|
235
|
+
|
236
|
+
# @return [Integer] Descriptor type. Will have value LIBUSB::DT_BOS LIBUSB_DT_BOS
|
237
|
+
# in this context.
|
238
|
+
def bDescriptorType
|
239
|
+
self[:bDescriptorType]
|
240
|
+
end
|
241
|
+
|
242
|
+
# @return [Integer] Length of this descriptor and all of its sub descriptors
|
243
|
+
def wTotalLength
|
244
|
+
self[:wTotalLength]
|
245
|
+
end
|
246
|
+
|
247
|
+
# @return [Integer] The number of separate device capability descriptors in
|
248
|
+
# the BOS
|
249
|
+
def bNumDeviceCaps
|
250
|
+
self[:bNumDeviceCaps]
|
251
|
+
end
|
252
|
+
|
253
|
+
# bNumDeviceCap Device Capability Descriptors
|
254
|
+
#
|
255
|
+
# @return [Array<Bos::DeviceCapability, Bos::Usb20Extension, Bos::SsUsbDeviceCapability, Bos::ContainerId>]
|
256
|
+
def device_capabilities
|
257
|
+
pp_ext = FFI::MemoryPointer.new :pointer
|
258
|
+
caps = []
|
259
|
+
# Capabilities are appended to the bos header
|
260
|
+
ptr = pointer + offset_of(:dev_capability)
|
261
|
+
bNumDeviceCaps.times do
|
262
|
+
cap = DeviceCapability.new self, ptr.read_pointer
|
263
|
+
case cap.bDevCapabilityType
|
264
|
+
when LIBUSB::BT_WIRELESS_USB_DEVICE_CAPABILITY
|
265
|
+
# no struct defined in libusb -> use generic DeviceCapability
|
266
|
+
when LIBUSB::BT_USB_2_0_EXTENSION
|
267
|
+
res = Call.libusb_get_usb_2_0_extension_descriptor(@ctx, cap.pointer, pp_ext)
|
268
|
+
cap = Usb20Extension.new(pp_ext.read_pointer) if res==0
|
269
|
+
when LIBUSB::BT_SS_USB_DEVICE_CAPABILITY
|
270
|
+
res = Call.libusb_get_ss_usb_device_capability_descriptor(@ctx, cap.pointer, pp_ext)
|
271
|
+
cap = SsUsbDeviceCapability.new(pp_ext.read_pointer) if res==0
|
272
|
+
when LIBUSB::BT_CONTAINER_ID
|
273
|
+
res = Call.libusb_get_container_id_descriptor(@ctx, cap.pointer, pp_ext)
|
274
|
+
cap = ContainerId.new(pp_ext.read_pointer) if res==0
|
275
|
+
else
|
276
|
+
# unknown capability -> use generic DeviceCapability
|
277
|
+
end
|
278
|
+
ptr += FFI.type_size(:pointer)
|
279
|
+
caps << cap
|
280
|
+
end
|
281
|
+
caps
|
282
|
+
end
|
283
|
+
|
284
|
+
# @return [Array<Symbol>] Types of Capabilities
|
285
|
+
#
|
286
|
+
# @see Call::BosTypes
|
287
|
+
def device_capability_types
|
288
|
+
# Capabilities are appended to the bos header
|
289
|
+
ptr = pointer + offset_of(:dev_capability)
|
290
|
+
bNumDeviceCaps.times.map do
|
291
|
+
cap = DeviceCapability.new self, ptr.read_pointer
|
292
|
+
ptr += FFI.type_size(:pointer)
|
293
|
+
Call::BosTypes.find cap.bDevCapabilityType
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
def inspect
|
298
|
+
"\#<#{self.class} #{device_capability_types.join(", ")}>"
|
299
|
+
end
|
300
|
+
|
301
|
+
# @private
|
302
|
+
def self.release(ptr)
|
303
|
+
Call.libusb_free_bos_descriptor(ptr)
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
data/lib/libusb/call.rb
CHANGED
@@ -81,11 +81,18 @@ module LIBUSB
|
|
81
81
|
:TRANSFER_ADD_ZERO_PACKET, 1 << 3,
|
82
82
|
]
|
83
83
|
|
84
|
+
# Values for {Endpoint#transfer_type}.
|
84
85
|
TransferTypes = enum :libusb_transfer_type, [
|
86
|
+
# Control endpoint
|
85
87
|
:TRANSFER_TYPE_CONTROL, 0,
|
88
|
+
# Isochronous endpoint
|
86
89
|
:TRANSFER_TYPE_ISOCHRONOUS, 1,
|
90
|
+
# Bulk endpoint
|
87
91
|
:TRANSFER_TYPE_BULK, 2,
|
92
|
+
# Interrupt endpoint
|
88
93
|
:TRANSFER_TYPE_INTERRUPT, 3,
|
94
|
+
# Stream endpoint
|
95
|
+
:TRANSFER_TYPE_BULK_STREAM, 4,
|
89
96
|
]
|
90
97
|
|
91
98
|
StandardRequests = enum :libusb_standard_request, [
|
@@ -108,15 +115,32 @@ module LIBUSB
|
|
108
115
|
]
|
109
116
|
|
110
117
|
DescriptorTypes = enum :libusb_descriptor_type, [
|
118
|
+
# Device descriptor. See {Device}
|
111
119
|
:DT_DEVICE, 0x01,
|
120
|
+
# Configuration descriptor. See {Configuration}
|
112
121
|
:DT_CONFIG, 0x02,
|
122
|
+
# String descriptor
|
113
123
|
:DT_STRING, 0x03,
|
124
|
+
# Interface descriptor. See {Interface}
|
114
125
|
:DT_INTERFACE, 0x04,
|
126
|
+
# Endpoint descriptor. See {Endpoint}
|
115
127
|
:DT_ENDPOINT, 0x05,
|
128
|
+
# BOS descriptor
|
129
|
+
:DT_BOS, 0x0f,
|
130
|
+
# Device Capability descriptor
|
131
|
+
:DT_DEVICE_CAPABILITY, 0x10,
|
132
|
+
# HID descriptor
|
116
133
|
:DT_HID, 0x21,
|
134
|
+
# HID report descriptor
|
117
135
|
:DT_REPORT, 0x22,
|
136
|
+
# Physical descriptor
|
118
137
|
:DT_PHYSICAL, 0x23,
|
138
|
+
# Hub descriptor
|
119
139
|
:DT_HUB, 0x29,
|
140
|
+
# SuperSpeed Hub descriptor
|
141
|
+
:DT_SUPERSPEED_HUB, 0x2a,
|
142
|
+
# SuperSpeed Endpoint Companion descriptor
|
143
|
+
:DT_SS_ENDPOINT_COMPANION, 0x30,
|
120
144
|
]
|
121
145
|
|
122
146
|
RequestTypes = enum :libusb_request_type, [
|
@@ -148,6 +172,19 @@ module LIBUSB
|
|
148
172
|
:SPEED_SUPER, 4,
|
149
173
|
]
|
150
174
|
|
175
|
+
# Supported speeds (wSpeedSupported) bitfield. Indicates what
|
176
|
+
# speeds the device supports.
|
177
|
+
SupportedSpeeds = enum :libusb_supported_speed, [
|
178
|
+
# Low speed operation supported (1.5MBit/s).
|
179
|
+
:LOW_SPEED_OPERATION, 1,
|
180
|
+
# Full speed operation supported (12MBit/s).
|
181
|
+
:FULL_SPEED_OPERATION, 2,
|
182
|
+
# High speed operation supported (480MBit/s).
|
183
|
+
:HIGH_SPEED_OPERATION, 4,
|
184
|
+
# Superspeed operation supported (5000MBit/s).
|
185
|
+
:SUPER_SPEED_OPERATION, 8,
|
186
|
+
]
|
187
|
+
|
151
188
|
Capabilities = enum :libusb_capability, [
|
152
189
|
:CAP_HAS_CAPABILITY, 0x0000,
|
153
190
|
# Hotplug support is available on this platform.
|
@@ -162,6 +199,36 @@ module LIBUSB
|
|
162
199
|
:CAP_SUPPORTS_DETACH_KERNEL_DRIVER, 0x0101,
|
163
200
|
]
|
164
201
|
|
202
|
+
# Masks for the bits of the
|
203
|
+
# {Bos::Usb20Extension#bmAttributes} field
|
204
|
+
# of the USB 2.0 Extension descriptor.
|
205
|
+
Usb20ExtensionAttributes = enum :libusb_usb_2_0_extension_attributes, [
|
206
|
+
# Supports Link Power Management (LPM)
|
207
|
+
:BM_LPM_SUPPORT, 2,
|
208
|
+
]
|
209
|
+
|
210
|
+
# Masks for the bits of the
|
211
|
+
# {Bos::SsUsbDeviceCapability#bmAttributes} field
|
212
|
+
# field of the SuperSpeed USB Device Capability descriptor.
|
213
|
+
SsUsbDeviceCapabilityAttributes = enum :libusb_ss_usb_device_capability_attributes, [
|
214
|
+
# Supports Latency Tolerance Messages (LTM)
|
215
|
+
:BM_LTM_SUPPORT, 2,
|
216
|
+
]
|
217
|
+
|
218
|
+
# USB capability types
|
219
|
+
#
|
220
|
+
# @see Bos::DeviceCapability
|
221
|
+
BosTypes = enum :libusb_bos_type, [
|
222
|
+
# Wireless USB device capability
|
223
|
+
:BT_WIRELESS_USB_DEVICE_CAPABILITY, 1,
|
224
|
+
# USB 2.0 extensions
|
225
|
+
:BT_USB_2_0_EXTENSION, 2,
|
226
|
+
# SuperSpeed USB device capability
|
227
|
+
:BT_SS_USB_DEVICE_CAPABILITY, 3,
|
228
|
+
# Container ID type
|
229
|
+
:BT_CONTAINER_ID, 4,
|
230
|
+
]
|
231
|
+
|
165
232
|
# Since libusb version 1.0.16.
|
166
233
|
#
|
167
234
|
# Hotplug events
|
@@ -186,6 +253,7 @@ module LIBUSB
|
|
186
253
|
typedef :pointer, :libusb_context
|
187
254
|
typedef :pointer, :libusb_device
|
188
255
|
typedef :pointer, :libusb_device_handle
|
256
|
+
typedef :pointer, :libusb_transfer
|
189
257
|
typedef :int, :libusb_hotplug_callback_handle
|
190
258
|
|
191
259
|
def self.try_attach_function(method, *args)
|
@@ -221,6 +289,18 @@ module LIBUSB
|
|
221
289
|
attach_function 'libusb_get_max_packet_size', [:pointer, :uint8], :int
|
222
290
|
attach_function 'libusb_get_max_iso_packet_size', [:pointer, :uint8], :int
|
223
291
|
|
292
|
+
try_attach_function 'libusb_get_ss_endpoint_companion_descriptor', [:pointer, :pointer, :pointer], :int
|
293
|
+
try_attach_function 'libusb_free_ss_endpoint_companion_descriptor', [:pointer], :void
|
294
|
+
|
295
|
+
try_attach_function 'libusb_get_bos_descriptor', [:libusb_device_handle, :pointer], :int, :blocking=>true
|
296
|
+
try_attach_function 'libusb_free_bos_descriptor', [:pointer], :void
|
297
|
+
try_attach_function 'libusb_get_usb_2_0_extension_descriptor', [:libusb_context, :pointer, :pointer], :int
|
298
|
+
try_attach_function 'libusb_free_usb_2_0_extension_descriptor', [:pointer], :void
|
299
|
+
try_attach_function 'libusb_get_ss_usb_device_capability_descriptor', [:libusb_context, :pointer, :pointer], :int
|
300
|
+
try_attach_function 'libusb_free_ss_usb_device_capability_descriptor', [:pointer], :void
|
301
|
+
try_attach_function 'libusb_get_container_id_descriptor', [:libusb_context, :pointer, :pointer], :int
|
302
|
+
try_attach_function 'libusb_free_container_id_descriptor', [:pointer], :void
|
303
|
+
|
224
304
|
attach_function 'libusb_open', [:pointer, :pointer], :int
|
225
305
|
attach_function 'libusb_close', [:pointer], :void
|
226
306
|
attach_function 'libusb_get_device', [:libusb_device_handle], :pointer
|
@@ -234,6 +314,8 @@ module LIBUSB
|
|
234
314
|
attach_function 'libusb_set_interface_alt_setting', [:libusb_device_handle, :int, :int], :int, :blocking=>true
|
235
315
|
attach_function 'libusb_clear_halt', [:libusb_device_handle, :int], :int, :blocking=>true
|
236
316
|
attach_function 'libusb_reset_device', [:libusb_device_handle], :int, :blocking=>true
|
317
|
+
try_attach_function 'libusb_alloc_streams', [:libusb_device_handle, :uint32, :pointer, :int], :int
|
318
|
+
try_attach_function 'libusb_free_streams', [:libusb_device_handle, :pointer, :int], :int
|
237
319
|
|
238
320
|
attach_function 'libusb_kernel_driver_active', [:libusb_device_handle, :int], :int
|
239
321
|
attach_function 'libusb_detach_kernel_driver', [:libusb_device_handle, :int], :int
|
@@ -246,6 +328,8 @@ module LIBUSB
|
|
246
328
|
attach_function 'libusb_submit_transfer', [:pointer], :int
|
247
329
|
attach_function 'libusb_cancel_transfer', [:pointer], :int
|
248
330
|
attach_function 'libusb_free_transfer', [:pointer], :void
|
331
|
+
try_attach_function 'libusb_transfer_set_stream_id', [:libusb_transfer, :uint32], :void
|
332
|
+
try_attach_function 'libusb_transfer_get_stream_id', [:libusb_transfer], :uint32
|
249
333
|
|
250
334
|
attach_function 'libusb_handle_events', [:libusb_context], :int, :blocking=>true
|
251
335
|
try_attach_function 'libusb_handle_events_completed', [:libusb_context, :pointer], :int, :blocking=>true
|
data/lib/libusb/constants.rb
CHANGED
@@ -26,6 +26,10 @@ module LIBUSB
|
|
26
26
|
Call::IsoSyncTypes.to_h.each{|k,v| const_set(k,v) }
|
27
27
|
Call::Speeds.to_h.each{|k,v| const_set(k,v) }
|
28
28
|
Call::Capabilities.to_h.each{|k,v| const_set(k,v) }
|
29
|
+
Call::SupportedSpeeds.to_h.each{|k,v| const_set(k,v) }
|
30
|
+
Call::Usb20ExtensionAttributes.to_h.each{|k,v| const_set(k,v) }
|
31
|
+
Call::SsUsbDeviceCapabilityAttributes.to_h.each{|k,v| const_set(k,v) }
|
32
|
+
Call::BosTypes.to_h.each{|k,v| const_set(k,v) }
|
29
33
|
Call::HotplugEvents.to_h.each{|k,v| const_set(k,v) }
|
30
34
|
Call::HotplugFlags.to_h.each{|k,v| const_set(k,v) }
|
31
35
|
|
data/lib/libusb/dev_handle.rb
CHANGED
@@ -189,6 +189,54 @@ module LIBUSB
|
|
189
189
|
LIBUSB.raise_error res, "in libusb_reset_device" if res!=0
|
190
190
|
end
|
191
191
|
|
192
|
+
if Call.respond_to?(:libusb_alloc_streams)
|
193
|
+
|
194
|
+
# @method alloc_streams
|
195
|
+
#
|
196
|
+
# Allocate up to num_streams usb bulk streams on the specified endpoints. This
|
197
|
+
# function takes an array of endpoints rather then a single endpoint because
|
198
|
+
# some protocols require that endpoints are setup with similar stream ids.
|
199
|
+
# All endpoints passed in must belong to the same interface.
|
200
|
+
#
|
201
|
+
# Note this function may return less streams then requested. Also note that the
|
202
|
+
# same number of streams are allocated for each endpoint in the endpoint array.
|
203
|
+
#
|
204
|
+
# Stream id 0 is reserved, and should not be used to communicate with devices.
|
205
|
+
# If {alloc_streams} returns with a value of N, you may use stream ids
|
206
|
+
# 1 to N.
|
207
|
+
#
|
208
|
+
# Available since libusb-1.0.19.
|
209
|
+
#
|
210
|
+
# @param [Fixnum] num_streams number of streams to try to allocate
|
211
|
+
# @param [Array<Fixnum>, Array<Endpoint>] endpoints array of endpoints to allocate streams on
|
212
|
+
# @return [Fixnum] number of streams allocated
|
213
|
+
# @see #free_streams
|
214
|
+
# @see BulkStreamTransfer
|
215
|
+
def alloc_streams(num_streams, endpoints)
|
216
|
+
pEndpoints = endpoints_as_ffi_bytes(endpoints)
|
217
|
+
res = Call.libusb_alloc_streams(@pHandle, num_streams, pEndpoints, endpoints.length)
|
218
|
+
LIBUSB.raise_error res, "in libusb_alloc_streams" unless res>=0
|
219
|
+
res
|
220
|
+
end
|
221
|
+
|
222
|
+
# @method free_streams
|
223
|
+
#
|
224
|
+
# Free usb bulk streams allocated with {alloc_streams}
|
225
|
+
#
|
226
|
+
# Note streams are automatically free-ed when releasing an interface.
|
227
|
+
#
|
228
|
+
# Available since libusb-1.0.19.
|
229
|
+
#
|
230
|
+
# @param [Array<Fixnum>, Array<Endpoint>] endpoints array of endpoints to free streams on
|
231
|
+
# @see #alloc_streams
|
232
|
+
def free_streams(endpoints)
|
233
|
+
pEndpoints = endpoints_as_ffi_bytes(endpoints)
|
234
|
+
res = Call.libusb_free_streams(@pHandle, pEndpoints, endpoints.length)
|
235
|
+
LIBUSB.raise_error res, "in libusb_free_streams" unless res>=0
|
236
|
+
nil
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
192
240
|
# Determine if a kernel driver is active on an interface.
|
193
241
|
#
|
194
242
|
# If a kernel driver is active, you cannot claim the interface,
|
@@ -253,6 +301,26 @@ module LIBUSB
|
|
253
301
|
end
|
254
302
|
end
|
255
303
|
|
304
|
+
# @private
|
305
|
+
if Call.respond_to?(:libusb_get_bos_descriptor)
|
306
|
+
|
307
|
+
# @method bos
|
308
|
+
# Get a Binary Object Store (BOS) descriptor.
|
309
|
+
#
|
310
|
+
# This is a BLOCKING function, which will send requests to the device.
|
311
|
+
#
|
312
|
+
# Since libusb version 1.0.16.
|
313
|
+
#
|
314
|
+
# @return [Bos]
|
315
|
+
def bos
|
316
|
+
ctx = device.context.instance_variable_get(:@ctx)
|
317
|
+
pp_desc = FFI::MemoryPointer.new :pointer
|
318
|
+
res = Call.libusb_get_bos_descriptor(@pHandle, pp_desc)
|
319
|
+
LIBUSB.raise_error res, "in libusb_get_bos_descriptor" if res!=0
|
320
|
+
Bos.new(ctx, pp_desc.read_pointer)
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
256
324
|
# Perform a USB bulk transfer.
|
257
325
|
#
|
258
326
|
# When called without a block, the transfer is done synchronously - so all events are handled
|
@@ -473,5 +541,14 @@ module LIBUSB
|
|
473
541
|
res
|
474
542
|
end
|
475
543
|
end
|
544
|
+
|
545
|
+
def endpoints_as_ffi_bytes(endpoints)
|
546
|
+
pEndpoints = FFI::MemoryPointer.new :char, endpoints.length
|
547
|
+
endpoints.each_with_index do |ep, epi|
|
548
|
+
ep = ep.bEndpointAddress if ep.respond_to? :bEndpointAddress
|
549
|
+
pEndpoints.put_uchar(epi, ep)
|
550
|
+
end
|
551
|
+
pEndpoints
|
552
|
+
end
|
476
553
|
end
|
477
554
|
end
|
data/lib/libusb/endpoint.rb
CHANGED
@@ -170,5 +170,25 @@ module LIBUSB
|
|
170
170
|
t = bEndpointAddress<=>o.bEndpointAddress if t==0
|
171
171
|
t
|
172
172
|
end
|
173
|
+
|
174
|
+
if Call.respond_to?(:libusb_get_ss_endpoint_companion_descriptor)
|
175
|
+
|
176
|
+
# @method ss_companion
|
177
|
+
# Get the endpoints superspeed endpoint companion descriptor (if any).
|
178
|
+
#
|
179
|
+
# Since libusb version 1.0.16.
|
180
|
+
#
|
181
|
+
# @return [SsCompanion]
|
182
|
+
def ss_companion
|
183
|
+
ep_comp = FFI::MemoryPointer.new :pointer
|
184
|
+
res = Call.libusb_get_ss_endpoint_companion_descriptor(
|
185
|
+
device.context.instance_variable_get(:@ctx),
|
186
|
+
pointer,
|
187
|
+
ep_comp
|
188
|
+
)
|
189
|
+
LIBUSB.raise_error res, "in libusb_get_ss_endpoint_companion_descriptor" if res!=0
|
190
|
+
SsCompanion.new ep_comp.read_pointer
|
191
|
+
end
|
192
|
+
end
|
173
193
|
end
|
174
194
|
end
|
@@ -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
|
+
require 'libusb/call'
|
17
|
+
|
18
|
+
module LIBUSB
|
19
|
+
# A structure representing the superspeed endpoint companion descriptor.
|
20
|
+
#
|
21
|
+
# This descriptor is documented in section 9.6.7 of the USB 3.0 specification. All multiple-byte fields are represented in host-endian format.
|
22
|
+
class SsCompanion < FFI::ManagedStruct
|
23
|
+
layout :bLength, :uint8,
|
24
|
+
:bDescriptorType, :uint8,
|
25
|
+
:bMaxBurst, :uint8,
|
26
|
+
:bmAttributes, :uint8,
|
27
|
+
:wBytesPerInterval, :uint16
|
28
|
+
|
29
|
+
# Size of this descriptor (in bytes)
|
30
|
+
def bLength
|
31
|
+
self[:bLength]
|
32
|
+
end
|
33
|
+
|
34
|
+
# Descriptor type.
|
35
|
+
#
|
36
|
+
# Will have value LIBUSB::DT_SS_ENDPOINT_COMPANION in this context.
|
37
|
+
def bDescriptorType
|
38
|
+
self[:bDescriptorType]
|
39
|
+
end
|
40
|
+
|
41
|
+
# The maximum number of packets the endpoint can send or recieve as part of a burst.
|
42
|
+
def bMaxBurst
|
43
|
+
self[:bMaxBurst]
|
44
|
+
end
|
45
|
+
|
46
|
+
# In bulk EP: bits 4:0 represents the maximum number of streams the EP supports.
|
47
|
+
#
|
48
|
+
# In isochronous EP: bits 1:0 represents the Mult - a zero based value that determines the maximum number of packets within a service interval
|
49
|
+
def bmAttributes
|
50
|
+
self[:bmAttributes]
|
51
|
+
end
|
52
|
+
|
53
|
+
# The total number of bytes this EP will transfer every service interval.
|
54
|
+
#
|
55
|
+
# valid only for periodic EPs.
|
56
|
+
def wBytesPerInterval
|
57
|
+
self[:wBytesPerInterval]
|
58
|
+
end
|
59
|
+
|
60
|
+
def inspect
|
61
|
+
"\#<#{self.class} burst: #{bMaxBurst} attrs: #{bmAttributes}>"
|
62
|
+
end
|
63
|
+
|
64
|
+
# @private
|
65
|
+
def self.release(ptr)
|
66
|
+
Call.libusb_free_ss_endpoint_companion_descriptor(ptr)
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/lib/libusb/transfer.rb
CHANGED
@@ -203,6 +203,40 @@ module LIBUSB
|
|
203
203
|
end
|
204
204
|
end
|
205
205
|
|
206
|
+
if Call.respond_to?(:libusb_transfer_get_stream_id)
|
207
|
+
|
208
|
+
# Transfer class for USB bulk transfers using USB-3.0 streams.
|
209
|
+
#
|
210
|
+
# @see DevHandle#alloc_streams
|
211
|
+
#
|
212
|
+
# Available since libusb-1.0.19.
|
213
|
+
class BulkStreamTransfer < Transfer
|
214
|
+
def initialize(args={})
|
215
|
+
@transfer = Call::Transfer.new Call.libusb_alloc_transfer(0)
|
216
|
+
@transfer[:type] = TRANSFER_TYPE_BULK_STREAM
|
217
|
+
@transfer[:timeout] = 1000
|
218
|
+
super
|
219
|
+
end
|
220
|
+
|
221
|
+
# Set a transfers bulk stream id.
|
222
|
+
#
|
223
|
+
# @param [Fixnum] stream_id the stream id to set
|
224
|
+
def stream_id=(v)
|
225
|
+
Call.libusb_transfer_set_stream_id(@transfer, v)
|
226
|
+
v
|
227
|
+
end
|
228
|
+
|
229
|
+
# Get a transfers bulk stream id.
|
230
|
+
#
|
231
|
+
# Since version 1.0.19.
|
232
|
+
#
|
233
|
+
# @return [Fixnum] the stream id for the transfer
|
234
|
+
def stream_id
|
235
|
+
Call.libusb_transfer_get_stream_id(@transfer)
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
206
240
|
class ControlTransfer < Transfer
|
207
241
|
def initialize(args={})
|
208
242
|
@transfer = Call::Transfer.new Call.libusb_alloc_transfer(0)
|
data/lib/libusb/version_gem.rb
CHANGED
data/libusb.gemspec
CHANGED
@@ -10,6 +10,7 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.homepage = "http://github.com/larskanis/libusb"
|
11
11
|
s.summary = %q{Access USB devices from Ruby via libusb-1.0}
|
12
12
|
s.description = %q{LIBUSB is a Ruby binding that gives Ruby programmers access to arbitrary USB devices}
|
13
|
+
s.licenses = ['LGPL-3']
|
13
14
|
s.rdoc_options = %w[--main README.md --charset=UTF-8]
|
14
15
|
|
15
16
|
s.rubyforge_project = "libusb"
|
@@ -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
|
+
|
19
|
+
class TestLibusbBos < 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_bos
|
30
|
+
did_bos = false
|
31
|
+
did_cap = false
|
32
|
+
usb.devices.each do |dev|
|
33
|
+
# devices with USB version >= 0x201 could support bos
|
34
|
+
# devices with USB version >= 0x210 must support bos
|
35
|
+
if dev.bcdUSB >= 0x210
|
36
|
+
dev.open do |devh|
|
37
|
+
bos = devh.bos
|
38
|
+
did_bos = true
|
39
|
+
|
40
|
+
assert_equal 5, bos.bLength
|
41
|
+
assert_equal 0x0f, bos.bDescriptorType
|
42
|
+
assert_operator 5, :<=, bos.wTotalLength
|
43
|
+
assert_operator 0, :<=, bos.bNumDeviceCaps
|
44
|
+
|
45
|
+
caps = bos.device_capabilities
|
46
|
+
assert_equal bos.bNumDeviceCaps, caps.length
|
47
|
+
cap_types = bos.device_capability_types
|
48
|
+
assert_equal bos.bNumDeviceCaps, cap_types.length
|
49
|
+
|
50
|
+
cap_types.each do |cap_type|
|
51
|
+
assert_operator [
|
52
|
+
:BT_WIRELESS_USB_DEVICE_CAPABILITY,
|
53
|
+
:BT_USB_2_0_EXTENSION,
|
54
|
+
:BT_SS_USB_DEVICE_CAPABILITY,
|
55
|
+
:BT_CONTAINER_ID,
|
56
|
+
], :include?, cap_type
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
caps.each do |cap|
|
61
|
+
did_cap = true
|
62
|
+
|
63
|
+
assert_operator 4, :<=, cap.bLength
|
64
|
+
assert_equal LIBUSB::DT_DEVICE_CAPABILITY, cap.bDescriptorType
|
65
|
+
assert_kind_of String, cap.dev_capability_data, "should provide binary capability data"
|
66
|
+
assert_kind_of String, cap.inspect, "should respond to inspect"
|
67
|
+
assert_operator 1, :<=, cap.dev_capability_data.length, "dev_capability_data should be at least one byte"
|
68
|
+
|
69
|
+
case cap
|
70
|
+
when Bos::DeviceCapability
|
71
|
+
assert_kind_of Integer, cap.bDevCapabilityType
|
72
|
+
|
73
|
+
when Bos::Usb20Extension
|
74
|
+
assert_equal 2, cap.bDevCapabilityType
|
75
|
+
assert_operator 0, :<=, cap.bmAttributes
|
76
|
+
assert_operator [true, false], :include?, cap.bm_lpm_support?
|
77
|
+
|
78
|
+
when Bos::SsUsbDeviceCapability
|
79
|
+
assert_equal 3, cap.bDevCapabilityType
|
80
|
+
assert_operator 0, :<=, cap.bmAttributes
|
81
|
+
assert_operator [true, false], :include?, cap.bm_ltm_support?
|
82
|
+
assert_operator 0, :<=, cap.wSpeedSupported
|
83
|
+
assert_kind_of Array, cap.supported_speeds
|
84
|
+
assert_operator 0, :<=, cap.bFunctionalitySupport
|
85
|
+
assert_operator 0, :<=, cap.bU1DevExitLat
|
86
|
+
assert_operator 0, :<=, cap.bU2DevExitLat
|
87
|
+
|
88
|
+
when Bos::ContainerId
|
89
|
+
assert_equal 4, cap.bDevCapabilityType
|
90
|
+
assert_operator 0, :<=, cap.bReserved
|
91
|
+
assert_operator 16, :==, cap.container_id.bytesize, "container_id should be 16 bytes long"
|
92
|
+
|
93
|
+
else
|
94
|
+
refute true, "invalid device capability class"
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
skip "no device with BOS available" unless did_bos
|
101
|
+
skip "no device with BOS capability available" unless did_cap
|
102
|
+
end
|
103
|
+
|
104
|
+
def test_no_bos
|
105
|
+
did_failing_bos = false
|
106
|
+
|
107
|
+
# devices with USB version < 0x201 shouldn't support bos
|
108
|
+
if dev=usb.devices.find{|dev| dev.bcdUSB < 0x201 }
|
109
|
+
dev.open do |devh|
|
110
|
+
assert_raises LIBUSB::ERROR_PIPE do
|
111
|
+
devh.bos
|
112
|
+
end
|
113
|
+
did_failing_bos = true
|
114
|
+
end
|
115
|
+
end
|
116
|
+
skip "no device without BOS available" unless did_failing_bos
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,50 @@
|
|
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 TestLibusbBulkStreamTransfer < 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_alloc_streams
|
37
|
+
assert_raises(ERROR_NOT_SUPPORTED, "TODO: test with a OS that supports bulk streams and against a real device") do
|
38
|
+
nr_allocated = @dev.alloc_streams( 2, @dev.device.endpoints )
|
39
|
+
end
|
40
|
+
|
41
|
+
assert_raises(ERROR_NOT_SUPPORTED) do
|
42
|
+
@dev.free_streams( [0x01,0x82] )
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def test_bulk_stream_transfer
|
47
|
+
tr = BulkStreamTransfer.new :dev_handle=>@dev, :stream_id=>123, :buffer=>' '*100
|
48
|
+
assert_equal 123, tr.stream_id, "stream_id should match"
|
49
|
+
end
|
50
|
+
end
|
@@ -113,6 +113,35 @@ class TestLibusbDescriptors < Minitest::Test
|
|
113
113
|
end
|
114
114
|
end
|
115
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 dev.device_speed == :SPEED_SUPER
|
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
|
+
|
116
145
|
def test_constants
|
117
146
|
assert_equal 7, CLASS_PRINTER, "Printer class id should be defined"
|
118
147
|
assert_equal 48, ISO_USAGE_TYPE_MASK, "iso usage type should be defined"
|
data/test/test_libusb_hotplug.rb
CHANGED
@@ -106,7 +106,7 @@ class TestLibusbHotplug < Minitest::Test
|
|
106
106
|
ctx.handle_events 5000
|
107
107
|
ctx.handle_events 5000
|
108
108
|
|
109
|
-
skip if devs.empty? && devs2.empty?
|
109
|
+
skip "no hotplug action taken" if devs.empty? && devs2.empty?
|
110
110
|
assert_equal 1, devs.length, "Should be deregistered after the first event"
|
111
111
|
assert_equal 2, devs2.length, "Should have received two events"
|
112
112
|
assert_operator devs2.map(&:last), :include?, :HOTPLUG_EVENT_DEVICE_ARRIVED, "Should have received ARRIVED"
|
data/test/test_libusb_threads.rb
CHANGED
@@ -70,7 +70,7 @@ class TestLibusbThreads < Minitest::Test
|
|
70
70
|
endpoint = endpoints_in[dev]
|
71
71
|
1.times do
|
72
72
|
st = Time.now
|
73
|
-
|
73
|
+
assert_raises LIBUSB::ERROR_TIMEOUT do
|
74
74
|
dev.bulk_transfer(:endpoint=>endpoint, :dataIn=>123, :timeout=>100)
|
75
75
|
end
|
76
76
|
assert_operator Time.now-st, :<, 5
|
metadata
CHANGED
@@ -1,62 +1,76 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: libusb
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.5.0
|
6
5
|
platform: x64-mingw32
|
7
6
|
authors:
|
8
7
|
- Lars Kanis
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
|
-
cert_chain:
|
12
|
-
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
MIIDLjCCAhagAwIBAgIBAjANBgkqhkiG9w0BAQUFADA9MQ4wDAYDVQQDDAVrYW5p
|
14
|
+
czEXMBUGCgmSJomT8ixkARkWB2NvbWNhcmQxEjAQBgoJkiaJk/IsZAEZFgJkZTAe
|
15
|
+
Fw0xNDAyMjYwOTMzMDBaFw0xNTAyMjYwOTMzMDBaMD0xDjAMBgNVBAMMBWthbmlz
|
16
|
+
MRcwFQYKCZImiZPyLGQBGRYHY29tY2FyZDESMBAGCgmSJomT8ixkARkWAmRlMIIB
|
17
|
+
IjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApop+rNmg35bzRugZ21VMGqI6
|
18
|
+
HGzPLO4VHYncWn/xmgPU/ZMcZdfj6MzIaZJ/czXyt4eHpBk1r8QOV3gBXnRXEjVW
|
19
|
+
9xi+EdVOkTV2/AVFKThcbTAQGiF/bT1n2M+B1GTybRzMg6hyhOJeGPqIhLfJEpxn
|
20
|
+
lJi4+ENAVT4MpqHEAGB8yFoPC0GqiOHQsdHxQV3P3c2OZqG+yJey74QtwA2tLcLn
|
21
|
+
Q53c63+VLGsOjODl1yPn/2ejyq8qWu6ahfTxiIlSar2UbwtaQGBDFdb2CXgEufXT
|
22
|
+
L7oaPxlmj+Q2oLOfOnInd2Oxop59HoJCQPsg8f921J43NCQGA8VHK6paxIRDLQID
|
23
|
+
AQABozkwNzAJBgNVHRMEAjAAMAsGA1UdDwQEAwIEsDAdBgNVHQ4EFgQUvgTdT7fe
|
24
|
+
x17ugO3IOsjEJwW7KP4wDQYJKoZIhvcNAQEFBQADggEBAFmIAhRT0awqLQN9e4Uv
|
25
|
+
ZEk+jUWv4zkb+TWiKFJXlwjPyjGbZY9gVfOwAwMibYOK/t/+57ZzW3d0L12OUwvo
|
26
|
+
on84NVvYtIr1/iskJFWFkMoIquAFCdi9p68stSPMQK2XcrJJuRot29fJtropsZBa
|
27
|
+
2cpaNd/sRYdK4oep2usdKifA1lI0hIkPb3r5nLfwG2lAqBH7WZsUICHcTgR0VEbG
|
28
|
+
z9Ug5qQp9Uz73xC9YdGvGiuOX53LYobHAR4MWi2xxDlHI+ER8mRz0eY2FUuNu/Wj
|
29
|
+
GrqF74zpLl7/KFdHC8VmzwZS18hvDjxeLVuVI2gIGnBInqnlqv05g/l4/1pISh5j
|
30
|
+
dS4=
|
31
|
+
-----END CERTIFICATE-----
|
32
|
+
date: 2015-01-08 00:00:00.000000000 Z
|
13
33
|
dependencies:
|
14
34
|
- !ruby/object:Gem::Dependency
|
15
35
|
name: ffi
|
16
36
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
37
|
requirements:
|
19
|
-
- -
|
38
|
+
- - ">="
|
20
39
|
- !ruby/object:Gem::Version
|
21
40
|
version: '1.0'
|
22
41
|
type: :runtime
|
23
42
|
prerelease: false
|
24
43
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
44
|
requirements:
|
27
|
-
- -
|
45
|
+
- - ">="
|
28
46
|
- !ruby/object:Gem::Version
|
29
47
|
version: '1.0'
|
30
48
|
- !ruby/object:Gem::Dependency
|
31
49
|
name: rake-compiler
|
32
50
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
51
|
requirements:
|
35
|
-
- -
|
52
|
+
- - ">="
|
36
53
|
- !ruby/object:Gem::Version
|
37
54
|
version: '0.6'
|
38
55
|
type: :development
|
39
56
|
prerelease: false
|
40
57
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
58
|
requirements:
|
43
|
-
- -
|
59
|
+
- - ">="
|
44
60
|
- !ruby/object:Gem::Version
|
45
61
|
version: '0.6'
|
46
62
|
- !ruby/object:Gem::Dependency
|
47
63
|
name: bundler
|
48
64
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
65
|
requirements:
|
51
|
-
- -
|
66
|
+
- - ">="
|
52
67
|
- !ruby/object:Gem::Version
|
53
68
|
version: '0'
|
54
69
|
type: :development
|
55
70
|
prerelease: false
|
56
71
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
72
|
requirements:
|
59
|
-
- -
|
73
|
+
- - ">="
|
60
74
|
- !ruby/object:Gem::Version
|
61
75
|
version: '0'
|
62
76
|
description: LIBUSB is a Ruby binding that gives Ruby programmers access to arbitrary
|
@@ -67,15 +81,17 @@ executables: []
|
|
67
81
|
extensions: []
|
68
82
|
extra_rdoc_files: []
|
69
83
|
files:
|
70
|
-
- .gitignore
|
71
|
-
- .travis.yml
|
72
|
-
- .yardopts
|
84
|
+
- ".gitignore"
|
85
|
+
- ".travis.yml"
|
86
|
+
- ".yardopts"
|
73
87
|
- COPYING
|
74
88
|
- Gemfile
|
75
89
|
- History.md
|
76
90
|
- README.md
|
77
91
|
- Rakefile
|
92
|
+
- lib/libusb-1.0.dll
|
78
93
|
- lib/libusb.rb
|
94
|
+
- lib/libusb/bos.rb
|
79
95
|
- lib/libusb/call.rb
|
80
96
|
- lib/libusb/compat.rb
|
81
97
|
- lib/libusb/configuration.rb
|
@@ -87,10 +103,13 @@ files:
|
|
87
103
|
- lib/libusb/eventmachine.rb
|
88
104
|
- lib/libusb/interface.rb
|
89
105
|
- lib/libusb/setting.rb
|
106
|
+
- lib/libusb/ss_companion.rb
|
90
107
|
- lib/libusb/transfer.rb
|
91
108
|
- lib/libusb/version_gem.rb
|
92
109
|
- lib/libusb/version_struct.rb
|
93
110
|
- libusb.gemspec
|
111
|
+
- test/test_libusb_bos.rb
|
112
|
+
- test/test_libusb_bulk_stream_transfer.rb
|
94
113
|
- test/test_libusb_capability.rb
|
95
114
|
- test/test_libusb_compat.rb
|
96
115
|
- test/test_libusb_compat_mass_storage.rb
|
@@ -104,32 +123,31 @@ files:
|
|
104
123
|
- test/test_libusb_structs.rb
|
105
124
|
- test/test_libusb_threads.rb
|
106
125
|
- test/test_libusb_version.rb
|
107
|
-
- lib/libusb-1.0.dll
|
108
126
|
homepage: http://github.com/larskanis/libusb
|
109
|
-
licenses:
|
127
|
+
licenses:
|
128
|
+
- LGPL-3
|
129
|
+
metadata: {}
|
110
130
|
post_install_message:
|
111
131
|
rdoc_options:
|
112
|
-
- --main
|
132
|
+
- "--main"
|
113
133
|
- README.md
|
114
|
-
- --charset=UTF-8
|
134
|
+
- "--charset=UTF-8"
|
115
135
|
require_paths:
|
116
136
|
- lib
|
117
137
|
required_ruby_version: !ruby/object:Gem::Requirement
|
118
|
-
none: false
|
119
138
|
requirements:
|
120
|
-
- -
|
139
|
+
- - ">="
|
121
140
|
- !ruby/object:Gem::Version
|
122
141
|
version: '0'
|
123
142
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
|
-
none: false
|
125
143
|
requirements:
|
126
|
-
- -
|
144
|
+
- - ">="
|
127
145
|
- !ruby/object:Gem::Version
|
128
146
|
version: '0'
|
129
147
|
requirements: []
|
130
148
|
rubyforge_project: libusb
|
131
|
-
rubygems_version:
|
149
|
+
rubygems_version: 2.4.5
|
132
150
|
signing_key:
|
133
|
-
specification_version:
|
151
|
+
specification_version: 4
|
134
152
|
summary: Access USB devices from Ruby via libusb-1.0
|
135
153
|
test_files: []
|
metadata.gz.sig
ADDED