libusb 0.1.0-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.autotest +23 -0
- data/.gemtest +0 -0
- data/COPYING +165 -0
- data/History.txt +15 -0
- data/Manifest.txt +15 -0
- data/README.rdoc +110 -0
- data/Rakefile +144 -0
- data/lib/libusb/compat.rb +370 -0
- data/lib/libusb-1.0.dll +0 -0
- data/lib/libusb.rb +1523 -0
- data/test/test_libusb_compat.rb +78 -0
- data/test/test_libusb_compat_mass_storage.rb +81 -0
- data/test/test_libusb_descriptors.rb +122 -0
- data/test/test_libusb_gc.rb +37 -0
- data/test/test_libusb_iso_transfer.rb +45 -0
- data/test/test_libusb_mass_storage.rb +271 -0
- metadata +107 -0
@@ -0,0 +1,370 @@
|
|
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
|
+
# This file is for compatibility with ruby-usb and libusb-0.1.
|
17
|
+
#
|
18
|
+
# Please visit the project website at http://github.com/larskanis/libusb
|
19
|
+
# for support.
|
20
|
+
|
21
|
+
require 'libusb'
|
22
|
+
require 'forwardable'
|
23
|
+
|
24
|
+
# Compatibility layer for ruby-usb[http://www.a-k-r.org/ruby-usb/] (API based on libusb-0.1)
|
25
|
+
#
|
26
|
+
# This module provides some limited compatibility to ruby-usb.
|
27
|
+
#
|
28
|
+
# Usage example:
|
29
|
+
# begin
|
30
|
+
# require 'usb'
|
31
|
+
# rescue LoadError
|
32
|
+
# require 'libusb/compat'
|
33
|
+
# end
|
34
|
+
# p USB.devices => [#<USB::Device ...>]
|
35
|
+
#
|
36
|
+
# Known issues:
|
37
|
+
# * Exceptions are different between ruby-usb and libusb and they don't get converted
|
38
|
+
# * libusb-1.0 doesn't explicitly manage USB-buses, so only one Bus is used currently
|
39
|
+
module USB
|
40
|
+
DefaultContext = LIBUSB::Context.new
|
41
|
+
|
42
|
+
USB_CLASS_PER_INTERFACE = LIBUSB::CLASS_PER_INTERFACE
|
43
|
+
USB_CLASS_AUDIO = LIBUSB::CLASS_AUDIO
|
44
|
+
USB_CLASS_COMM = LIBUSB::CLASS_COMM
|
45
|
+
USB_CLASS_HID = LIBUSB::CLASS_HID
|
46
|
+
USB_CLASS_PRINTER = LIBUSB::CLASS_PRINTER
|
47
|
+
USB_CLASS_PTP = LIBUSB::CLASS_PTP
|
48
|
+
USB_CLASS_MASS_STORAGE = LIBUSB::CLASS_MASS_STORAGE
|
49
|
+
USB_CLASS_HUB = LIBUSB::CLASS_HUB
|
50
|
+
USB_CLASS_DATA = LIBUSB::CLASS_DATA
|
51
|
+
USB_CLASS_VENDOR_SPEC = LIBUSB::CLASS_VENDOR_SPEC
|
52
|
+
|
53
|
+
USB_DT_DEVICE = LIBUSB::DT_DEVICE
|
54
|
+
USB_DT_CONFIG = LIBUSB::DT_CONFIG
|
55
|
+
USB_DT_STRING = LIBUSB::DT_STRING
|
56
|
+
USB_DT_INTERFACE = LIBUSB::DT_INTERFACE
|
57
|
+
USB_DT_ENDPOINT = LIBUSB::DT_ENDPOINT
|
58
|
+
USB_DT_HID = LIBUSB::DT_HID
|
59
|
+
USB_DT_REPORT = LIBUSB::DT_REPORT
|
60
|
+
USB_DT_PHYSICAL = LIBUSB::DT_PHYSICAL
|
61
|
+
USB_DT_HUB = LIBUSB::DT_HUB
|
62
|
+
USB_DT_DEVICE_SIZE = LIBUSB::DT_DEVICE_SIZE
|
63
|
+
USB_DT_CONFIG_SIZE = LIBUSB::DT_CONFIG_SIZE
|
64
|
+
USB_DT_INTERFACE_SIZE = LIBUSB::DT_INTERFACE_SIZE
|
65
|
+
USB_DT_ENDPOINT_SIZE = LIBUSB::DT_ENDPOINT_SIZE
|
66
|
+
USB_DT_ENDPOINT_AUDIO_SIZE = LIBUSB::DT_ENDPOINT_AUDIO_SIZE
|
67
|
+
USB_DT_HUB_NONVAR_SIZE = LIBUSB::DT_HUB_NONVAR_SIZE
|
68
|
+
|
69
|
+
USB_ENDPOINT_ADDRESS_MASK = LIBUSB::ENDPOINT_ADDRESS_MASK
|
70
|
+
USB_ENDPOINT_DIR_MASK = LIBUSB::ENDPOINT_DIR_MASK
|
71
|
+
USB_ENDPOINT_IN = LIBUSB::ENDPOINT_IN
|
72
|
+
USB_ENDPOINT_OUT = LIBUSB::ENDPOINT_OUT
|
73
|
+
|
74
|
+
USB_ENDPOINT_TYPE_MASK = LIBUSB::TRANSFER_TYPE_MASK
|
75
|
+
USB_ENDPOINT_TYPE_CONTROL = LIBUSB::TRANSFER_TYPE_CONTROL
|
76
|
+
USB_ENDPOINT_TYPE_ISOCHRONOUS = LIBUSB::TRANSFER_TYPE_ISOCHRONOUS
|
77
|
+
USB_ENDPOINT_TYPE_BULK = LIBUSB::TRANSFER_TYPE_BULK
|
78
|
+
USB_ENDPOINT_TYPE_INTERRUPT = LIBUSB::TRANSFER_TYPE_INTERRUPT
|
79
|
+
|
80
|
+
USB_REQ_GET_STATUS = LIBUSB::REQUEST_GET_STATUS
|
81
|
+
USB_REQ_CLEAR_FEATURE = LIBUSB::REQUEST_CLEAR_FEATURE
|
82
|
+
USB_REQ_SET_FEATURE = LIBUSB::REQUEST_SET_FEATURE
|
83
|
+
USB_REQ_SET_ADDRESS = LIBUSB::REQUEST_SET_ADDRESS
|
84
|
+
USB_REQ_GET_DESCRIPTOR = LIBUSB::REQUEST_GET_DESCRIPTOR
|
85
|
+
USB_REQ_SET_DESCRIPTOR = LIBUSB::REQUEST_SET_DESCRIPTOR
|
86
|
+
USB_REQ_GET_CONFIGURATION = LIBUSB::REQUEST_GET_CONFIGURATION
|
87
|
+
USB_REQ_SET_CONFIGURATION = LIBUSB::REQUEST_SET_CONFIGURATION
|
88
|
+
USB_REQ_GET_INTERFACE = LIBUSB::REQUEST_GET_INTERFACE
|
89
|
+
USB_REQ_SET_INTERFACE = LIBUSB::REQUEST_SET_INTERFACE
|
90
|
+
USB_REQ_SYNCH_FRAME = LIBUSB::REQUEST_SYNCH_FRAME
|
91
|
+
USB_TYPE_STANDARD = LIBUSB::REQUEST_TYPE_STANDARD
|
92
|
+
USB_TYPE_CLASS = LIBUSB::REQUEST_TYPE_CLASS
|
93
|
+
USB_TYPE_VENDOR = LIBUSB::REQUEST_TYPE_VENDOR
|
94
|
+
USB_TYPE_RESERVED = LIBUSB::REQUEST_TYPE_RESERVED
|
95
|
+
USB_RECIP_DEVICE = LIBUSB::RECIPIENT_DEVICE
|
96
|
+
USB_RECIP_INTERFACE = LIBUSB::RECIPIENT_INTERFACE
|
97
|
+
USB_RECIP_ENDPOINT = LIBUSB::RECIPIENT_ENDPOINT
|
98
|
+
USB_RECIP_OTHER = LIBUSB::RECIPIENT_OTHER
|
99
|
+
|
100
|
+
HAS_GET_DRIVER_NP = RUBY_PLATFORM=~/mswin|mingw/ ? false : true
|
101
|
+
HAS_DETACH_KERNEL_DRIVER_NP = RUBY_PLATFORM=~/mswin|mingw/ ? false : true
|
102
|
+
|
103
|
+
# not defined by libusb-1.0, but typical values are:
|
104
|
+
USB_MAXENDPOINTS = 32
|
105
|
+
USB_MAXINTERFACES = 32
|
106
|
+
USB_MAXALTSETTING = 128
|
107
|
+
USB_MAXCONFIG = 8
|
108
|
+
|
109
|
+
|
110
|
+
def USB.busses
|
111
|
+
[DefaultBus]
|
112
|
+
end
|
113
|
+
|
114
|
+
def USB.devices; DefaultContext.devices.map{|c| Device.new(c) }; end
|
115
|
+
def USB.configurations() USB.devices.map {|d| d.configurations }.flatten end
|
116
|
+
def USB.interfaces() USB.configurations.map {|d| d.interfaces }.flatten end
|
117
|
+
def USB.settings() USB.interfaces.map {|d| d.settings }.flatten end
|
118
|
+
def USB.endpoints() USB.settings.map {|d| d.endpoints }.flatten end
|
119
|
+
|
120
|
+
def USB.find_bus(n)
|
121
|
+
DefaultBus
|
122
|
+
end
|
123
|
+
|
124
|
+
def USB.each_device_by_class(devclass, subclass=nil, protocol=nil)
|
125
|
+
devs = DefaultContext.devices :bClass=>devclass, :bSubClass=>subclass, :bProtocol=>protocol
|
126
|
+
devs.each do |dev|
|
127
|
+
yield Device.new(dev)
|
128
|
+
end
|
129
|
+
nil
|
130
|
+
end
|
131
|
+
|
132
|
+
class Bus
|
133
|
+
def initialize(context)
|
134
|
+
@ct = context
|
135
|
+
end
|
136
|
+
def devices
|
137
|
+
@ct.devices.map{|d| Device.new(d) }
|
138
|
+
end
|
139
|
+
|
140
|
+
def configurations() self.devices.map{|d| d.configurations }.flatten end
|
141
|
+
def interfaces() self.configurations.map {|d| d.interfaces }.flatten end
|
142
|
+
def settings() self.interfaces.map {|d| d.settings }.flatten end
|
143
|
+
def endpoints() self.settings.map {|d| d.endpoints }.flatten end
|
144
|
+
|
145
|
+
def find_device(n)
|
146
|
+
raise NotImplementedError
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
DefaultBus = Bus.new(DefaultContext)
|
151
|
+
|
152
|
+
def USB.dev_string(base_class, sub_class, protocol)
|
153
|
+
LIBUSB.dev_string(base_class, sub_class, protocol)
|
154
|
+
end
|
155
|
+
|
156
|
+
class Device
|
157
|
+
extend Forwardable
|
158
|
+
include Comparable
|
159
|
+
|
160
|
+
def initialize(dev)
|
161
|
+
@dev = dev
|
162
|
+
end
|
163
|
+
|
164
|
+
def_delegators :@dev, :bLength, :bDescriptorType, :bcdUSB, :bDeviceClass,
|
165
|
+
:bDeviceSubClass, :bDeviceProtocol, :bMaxPacketSize0, :idVendor, :idProduct,
|
166
|
+
:bcdDevice, :iManufacturer, :iProduct, :iSerialNumber, :bNumConfigurations,
|
167
|
+
:manufacturer, :product, :serial_number,
|
168
|
+
:inspect
|
169
|
+
|
170
|
+
def <=>(o)
|
171
|
+
@dev<=>o.instance_variable_get(:@dev)
|
172
|
+
end
|
173
|
+
|
174
|
+
def open
|
175
|
+
h = DevHandle.new(@dev.open)
|
176
|
+
if block_given?
|
177
|
+
begin
|
178
|
+
r = yield h
|
179
|
+
ensure
|
180
|
+
h.usb_close
|
181
|
+
end
|
182
|
+
else
|
183
|
+
h
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
def bus; DefaultBus; end
|
188
|
+
def configurations; @dev.configurations.map{|c| Configuration.new(c) }; end
|
189
|
+
def interfaces; @dev.interfaces.map{|c| Interface.new(c) }; end
|
190
|
+
def settings; @dev.settings.map{|c| Setting.new(c) }; end
|
191
|
+
def endpoints; @dev.endpoints.map{|c| Endpoint.new(c) }; end
|
192
|
+
end
|
193
|
+
|
194
|
+
class Configuration
|
195
|
+
extend Forwardable
|
196
|
+
include Comparable
|
197
|
+
|
198
|
+
def initialize(cd)
|
199
|
+
@cd = cd
|
200
|
+
end
|
201
|
+
|
202
|
+
def_delegators :@cd, :bLength, :bDescriptorType, :wTotalLength, :bNumInterfaces,
|
203
|
+
:bConfigurationValue, :iConfiguration, :bmAttributes, :maxPower,
|
204
|
+
:inspect
|
205
|
+
|
206
|
+
def <=>(o)
|
207
|
+
@cd<=>o.instance_variable_get(:@cd)
|
208
|
+
end
|
209
|
+
|
210
|
+
def bus; DefaultBus; end
|
211
|
+
def device() Device.new(@cd.device) end
|
212
|
+
def interfaces; @cd.interfaces.map{|c| Interface.new(c) }; end
|
213
|
+
def settings() self.interfaces.map {|d| d.settings }.flatten end
|
214
|
+
def endpoints() self.settings.map {|d| d.endpoints }.flatten end
|
215
|
+
end
|
216
|
+
|
217
|
+
class Interface
|
218
|
+
extend Forwardable
|
219
|
+
include Comparable
|
220
|
+
|
221
|
+
def initialize(i)
|
222
|
+
@i = i
|
223
|
+
end
|
224
|
+
|
225
|
+
def_delegators :@i, :inspect
|
226
|
+
|
227
|
+
def <=>(o)
|
228
|
+
@i<=>o.instance_variable_get(:@i)
|
229
|
+
end
|
230
|
+
|
231
|
+
def bus() self.configuration.device.bus end
|
232
|
+
def device() self.configuration.device end
|
233
|
+
def configuration; Configuration.new(@i.configuration); end
|
234
|
+
def settings; @i.alt_settings.map{|c| Setting.new(c) }; end
|
235
|
+
def endpoints() self.settings.map {|d| d.endpoints }.flatten end
|
236
|
+
end
|
237
|
+
|
238
|
+
class Setting
|
239
|
+
extend Forwardable
|
240
|
+
include Comparable
|
241
|
+
|
242
|
+
def initialize(id)
|
243
|
+
@id = id
|
244
|
+
end
|
245
|
+
|
246
|
+
def_delegators :@id, :bLength, :bDescriptorType, :bInterfaceNumber, :bAlternateSetting,
|
247
|
+
:bNumEndpoints, :bInterfaceClass, :bInterfaceSubClass, :bInterfaceProtocol,
|
248
|
+
:iInterface, :inspect
|
249
|
+
|
250
|
+
def <=>(o)
|
251
|
+
@id<=>o.instance_variable_get(:@id)
|
252
|
+
end
|
253
|
+
|
254
|
+
def bus() self.interface.configuration.device.bus end
|
255
|
+
def device() self.interface.configuration.device end
|
256
|
+
def configuration() self.interface.configuration end
|
257
|
+
def interface; Interface.new(@id.interface); end
|
258
|
+
def endpoints() @id.endpoints.map {|d| Endpoint.new(d) }.flatten end
|
259
|
+
end
|
260
|
+
|
261
|
+
class Endpoint
|
262
|
+
extend Forwardable
|
263
|
+
include Comparable
|
264
|
+
|
265
|
+
def initialize(ep)
|
266
|
+
@ep = ep
|
267
|
+
end
|
268
|
+
|
269
|
+
def_delegators :@ep, :bLength, :bDescriptorType, :bEndpointAddress, :bmAttributes,
|
270
|
+
:wMaxPacketSize, :bInterval, :bRefresh, :bSynchAddress,
|
271
|
+
:inspect
|
272
|
+
|
273
|
+
def <=>(o)
|
274
|
+
@ep<=>o.instance_variable_get(:@ep)
|
275
|
+
end
|
276
|
+
|
277
|
+
def bus() self.setting.interface.configuration.device.bus end
|
278
|
+
def device() self.setting.interface.configuration.device end
|
279
|
+
def configuration() self.setting.interface.configuration end
|
280
|
+
def interface() self.setting.interface end
|
281
|
+
def setting; Setting.new(@ep.setting); end
|
282
|
+
end
|
283
|
+
|
284
|
+
class DevHandle
|
285
|
+
def initialize(dev)
|
286
|
+
@dev = dev
|
287
|
+
end
|
288
|
+
|
289
|
+
def usb_close; @dev.close; end
|
290
|
+
def usb_set_configuration(c); @dev.configuration=c; end
|
291
|
+
def usb_set_altinterface(c); @dev.set_interface_alt_setting=c; end
|
292
|
+
def usb_clear_halt(c); @dev.clear_halt(c); end
|
293
|
+
def usb_reset; @dev.reset_device; end
|
294
|
+
def usb_claim_interface(c); @dev.claim_interface(c); end
|
295
|
+
def usb_release_interface(c); @dev.release_interface(c); end
|
296
|
+
def usb_get_string(index, langid, buffer)
|
297
|
+
t = @dev.string_descriptor(index, langid)
|
298
|
+
buffer[0, t.length] = t
|
299
|
+
t.length
|
300
|
+
end
|
301
|
+
def usb_get_string_simple(index, buffer)
|
302
|
+
t = @dev.string_descriptor_ascii(index)
|
303
|
+
buffer[0, t.length] = t
|
304
|
+
t.length
|
305
|
+
end
|
306
|
+
|
307
|
+
def usb_control_msg(requesttype, request, value, index, bytes, timeout)
|
308
|
+
if requesttype&LIBUSB::ENDPOINT_IN != 0
|
309
|
+
# transfer direction in
|
310
|
+
res = @dev.control_transfer(:bmRequestType=>requesttype, :bRequest=>request,
|
311
|
+
:wValue=>value, :wIndex=>index, :dataIn=>bytes.bytesize, :timeout=>timeout)
|
312
|
+
bytes[0, res.bytesize] = res
|
313
|
+
res.bytesize
|
314
|
+
else
|
315
|
+
# transfer direction out
|
316
|
+
@dev.control_transfer(:bmRequestType=>requesttype, :bRequest=>request, :wValue=>value,
|
317
|
+
:wIndex=>index, :dataOut=>bytes, :timeout=>timeout)
|
318
|
+
end
|
319
|
+
end
|
320
|
+
|
321
|
+
def usb_bulk_write(endpoint, bytes, timeout)
|
322
|
+
@dev.bulk_transfer(:endpoint=>endpoint, :dataOut=>bytes, :timeout=>timeout)
|
323
|
+
end
|
324
|
+
def usb_bulk_read(endpoint, bytes, timeout)
|
325
|
+
res = @dev.bulk_transfer(:endpoint=>endpoint, :dataIn=>bytes.bytesize, :timeout=>timeout)
|
326
|
+
bytes[0, res.bytesize] = res
|
327
|
+
res.bytesize
|
328
|
+
end
|
329
|
+
|
330
|
+
def usb_interrupt_write(endpoint, bytes, timeout)
|
331
|
+
@dev.interrupt_transfer(:endpoint=>endpoint, :dataOut=>bytes, :timeout=>timeout)
|
332
|
+
end
|
333
|
+
def usb_interrupt_read(endpoint, bytes, timeout)
|
334
|
+
res = @dev.interrupt_transfer(:endpoint=>endpoint, :dataIn=>bytes.bytesize, :timeout=>timeout)
|
335
|
+
bytes[0, res.bytesize] = res
|
336
|
+
res.bytesize
|
337
|
+
end
|
338
|
+
|
339
|
+
# rb_define_method(rb_cUSB_DevHandle, "usb_get_descriptor", rusb_get_descriptor, 3);
|
340
|
+
# rb_define_method(rb_cUSB_DevHandle, "usb_get_descriptor_by_endpoint", rusb_get_descriptor_by_endpoint, 4);
|
341
|
+
|
342
|
+
if HAS_DETACH_KERNEL_DRIVER_NP
|
343
|
+
def usb_detach_kernel_driver_np(interface, dummy=nil)
|
344
|
+
@dev.detach_kernel_driver(interface)
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
if HAS_GET_DRIVER_NP
|
349
|
+
def usb_get_driver_np(interface, buffer)
|
350
|
+
if @dev.kernel_driver_active?(interface)
|
351
|
+
t = "unknown driver"
|
352
|
+
buffer[0, t.length] = t
|
353
|
+
else
|
354
|
+
raise Errno::ENODATA, "No data available"
|
355
|
+
end
|
356
|
+
nil
|
357
|
+
end
|
358
|
+
end
|
359
|
+
|
360
|
+
alias set_configuration usb_set_configuration
|
361
|
+
alias set_altinterface usb_set_altinterface
|
362
|
+
alias clear_halt usb_clear_halt
|
363
|
+
alias claim_interface usb_claim_interface
|
364
|
+
alias release_interface usb_release_interface
|
365
|
+
|
366
|
+
def get_string_simple(index)
|
367
|
+
@dev.string_descriptor_ascii(index)
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
data/lib/libusb-1.0.dll
ADDED
Binary file
|