libusb 0.6.0-x86-linux
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.travis.yml +17 -0
- data/.yardopts +6 -0
- data/COPYING +165 -0
- data/Gemfile +11 -0
- data/History.md +124 -0
- data/README.md +159 -0
- data/Rakefile +145 -0
- data/appveyor.yml +23 -0
- data/lib/libusb.rb +58 -0
- data/lib/libusb/bos.rb +306 -0
- data/lib/libusb/call.rb +446 -0
- data/lib/libusb/compat.rb +376 -0
- data/lib/libusb/configuration.rb +155 -0
- data/lib/libusb/constants.rb +160 -0
- data/lib/libusb/context.rb +426 -0
- data/lib/libusb/dependencies.rb +7 -0
- data/lib/libusb/dev_handle.rb +564 -0
- data/lib/libusb/device.rb +365 -0
- data/lib/libusb/endpoint.rb +194 -0
- data/lib/libusb/eventmachine.rb +183 -0
- data/lib/libusb/interface.rb +60 -0
- data/lib/libusb/setting.rb +132 -0
- data/lib/libusb/ss_companion.rb +69 -0
- data/lib/libusb/stdio.rb +25 -0
- data/lib/libusb/transfer.rb +377 -0
- data/lib/libusb/version_gem.rb +19 -0
- data/lib/libusb/version_struct.rb +63 -0
- data/libusb.gemspec +30 -0
- data/test/test_libusb_bos.rb +118 -0
- data/test/test_libusb_bulk_stream_transfer.rb +50 -0
- data/test/test_libusb_capability.rb +23 -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 +212 -0
- data/test/test_libusb_event_machine.rb +118 -0
- data/test/test_libusb_gc.rb +37 -0
- data/test/test_libusb_hotplug.rb +127 -0
- data/test/test_libusb_iso_transfer.rb +50 -0
- data/test/test_libusb_mass_storage.rb +268 -0
- data/test/test_libusb_mass_storage2.rb +96 -0
- data/test/test_libusb_structs.rb +58 -0
- data/test/test_libusb_threads.rb +89 -0
- data/test/test_libusb_version.rb +40 -0
- data/wireshark-usb-sniffer.png +0 -0
- metadata +150 -0
data/lib/libusb/call.rb
ADDED
@@ -0,0 +1,446 @@
|
|
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 'rubygems'
|
17
|
+
require 'ffi'
|
18
|
+
|
19
|
+
module LIBUSB
|
20
|
+
# C level interface - for internal use only
|
21
|
+
#
|
22
|
+
# All enum codes are available as constants in {LIBUSB} namespace.
|
23
|
+
module Call
|
24
|
+
extend FFI::Library
|
25
|
+
|
26
|
+
root_path = File.expand_path("../../..", __FILE__)
|
27
|
+
ext = FFI::Platform::LIBSUFFIX
|
28
|
+
prefix = FFI::Platform::LIBPREFIX.empty? ? 'lib' : FFI::Platform::LIBPREFIX
|
29
|
+
bundled_dll = File.join(root_path, "lib/#{prefix}usb-1.0.#{ext}")
|
30
|
+
bundled_dll_cygwin = File.join(root_path, "bin/#{prefix}usb-1.0.#{ext}")
|
31
|
+
ffi_lib([bundled_dll, bundled_dll_cygwin, "#{prefix}usb-1.0"])
|
32
|
+
|
33
|
+
ClassCodes = enum :libusb_class_code, [
|
34
|
+
:CLASS_PER_INTERFACE, 0,
|
35
|
+
:CLASS_AUDIO, 1,
|
36
|
+
:CLASS_COMM, 2,
|
37
|
+
:CLASS_HID, 3,
|
38
|
+
:CLASS_PRINTER, 7,
|
39
|
+
:CLASS_PTP, 6,
|
40
|
+
:CLASS_MASS_STORAGE, 8,
|
41
|
+
:CLASS_HUB, 9,
|
42
|
+
:CLASS_DATA, 10,
|
43
|
+
:CLASS_WIRELESS, 0xe0,
|
44
|
+
:CLASS_APPLICATION, 0xfe,
|
45
|
+
:CLASS_VENDOR_SPEC, 0xff
|
46
|
+
]
|
47
|
+
|
48
|
+
Errors = enum :libusb_error, [
|
49
|
+
:SUCCESS, 0,
|
50
|
+
:ERROR_IO, -1,
|
51
|
+
:ERROR_INVALID_PARAM, -2,
|
52
|
+
:ERROR_ACCESS, -3,
|
53
|
+
:ERROR_NO_DEVICE, -4,
|
54
|
+
:ERROR_NOT_FOUND, -5,
|
55
|
+
:ERROR_BUSY, -6,
|
56
|
+
:ERROR_TIMEOUT, -7,
|
57
|
+
:ERROR_OVERFLOW, -8,
|
58
|
+
:ERROR_PIPE, -9,
|
59
|
+
:ERROR_INTERRUPTED, -10,
|
60
|
+
:ERROR_NO_MEM, -11,
|
61
|
+
:ERROR_NOT_SUPPORTED, -12,
|
62
|
+
:ERROR_OTHER, -99,
|
63
|
+
]
|
64
|
+
|
65
|
+
# Transfer status codes
|
66
|
+
TransferStatus = enum :libusb_transfer_status, [
|
67
|
+
:TRANSFER_COMPLETED,
|
68
|
+
:TRANSFER_ERROR,
|
69
|
+
:TRANSFER_TIMED_OUT,
|
70
|
+
:TRANSFER_CANCELLED,
|
71
|
+
:TRANSFER_STALL,
|
72
|
+
:TRANSFER_NO_DEVICE,
|
73
|
+
:TRANSFER_OVERFLOW,
|
74
|
+
]
|
75
|
+
|
76
|
+
# libusb_transfer.flags values
|
77
|
+
TransferFlags = enum :libusb_transfer_flags, [
|
78
|
+
:TRANSFER_SHORT_NOT_OK, 1 << 0,
|
79
|
+
:TRANSFER_FREE_BUFFER, 1 << 1,
|
80
|
+
:TRANSFER_FREE_TRANSFER, 1 << 2,
|
81
|
+
:TRANSFER_ADD_ZERO_PACKET, 1 << 3,
|
82
|
+
]
|
83
|
+
|
84
|
+
# Values for {Endpoint#transfer_type}.
|
85
|
+
TransferTypes = enum :libusb_transfer_type, [
|
86
|
+
# Control endpoint
|
87
|
+
:TRANSFER_TYPE_CONTROL, 0,
|
88
|
+
# Isochronous endpoint
|
89
|
+
:TRANSFER_TYPE_ISOCHRONOUS, 1,
|
90
|
+
# Bulk endpoint
|
91
|
+
:TRANSFER_TYPE_BULK, 2,
|
92
|
+
# Interrupt endpoint
|
93
|
+
:TRANSFER_TYPE_INTERRUPT, 3,
|
94
|
+
# Stream endpoint
|
95
|
+
:TRANSFER_TYPE_BULK_STREAM, 4,
|
96
|
+
]
|
97
|
+
|
98
|
+
StandardRequests = enum :libusb_standard_request, [
|
99
|
+
:REQUEST_GET_STATUS, 0x00,
|
100
|
+
:REQUEST_CLEAR_FEATURE, 0x01,
|
101
|
+
:REQUEST_SET_FEATURE, 0x03,
|
102
|
+
:REQUEST_SET_ADDRESS, 0x05,
|
103
|
+
:REQUEST_GET_DESCRIPTOR, 0x06,
|
104
|
+
:REQUEST_SET_DESCRIPTOR, 0x07,
|
105
|
+
:REQUEST_GET_CONFIGURATION, 0x08,
|
106
|
+
:REQUEST_SET_CONFIGURATION, 0x09,
|
107
|
+
:REQUEST_GET_INTERFACE, 0x0A,
|
108
|
+
:REQUEST_SET_INTERFACE, 0x0B,
|
109
|
+
:REQUEST_SYNCH_FRAME, 0x0C,
|
110
|
+
]
|
111
|
+
|
112
|
+
EndpointDirections = enum :libusb_endpoint_direction, [
|
113
|
+
:ENDPOINT_IN, 0x80,
|
114
|
+
:ENDPOINT_OUT, 0x00,
|
115
|
+
]
|
116
|
+
|
117
|
+
DescriptorTypes = enum :libusb_descriptor_type, [
|
118
|
+
# Device descriptor. See {Device}
|
119
|
+
:DT_DEVICE, 0x01,
|
120
|
+
# Configuration descriptor. See {Configuration}
|
121
|
+
:DT_CONFIG, 0x02,
|
122
|
+
# String descriptor
|
123
|
+
:DT_STRING, 0x03,
|
124
|
+
# Interface descriptor. See {Interface}
|
125
|
+
:DT_INTERFACE, 0x04,
|
126
|
+
# Endpoint descriptor. See {Endpoint}
|
127
|
+
:DT_ENDPOINT, 0x05,
|
128
|
+
# BOS descriptor
|
129
|
+
:DT_BOS, 0x0f,
|
130
|
+
# Device Capability descriptor
|
131
|
+
:DT_DEVICE_CAPABILITY, 0x10,
|
132
|
+
# HID descriptor
|
133
|
+
:DT_HID, 0x21,
|
134
|
+
# HID report descriptor
|
135
|
+
:DT_REPORT, 0x22,
|
136
|
+
# Physical descriptor
|
137
|
+
:DT_PHYSICAL, 0x23,
|
138
|
+
# Hub descriptor
|
139
|
+
:DT_HUB, 0x29,
|
140
|
+
# SuperSpeed Hub descriptor
|
141
|
+
:DT_SUPERSPEED_HUB, 0x2a,
|
142
|
+
# SuperSpeed Endpoint Companion descriptor
|
143
|
+
:DT_SS_ENDPOINT_COMPANION, 0x30,
|
144
|
+
]
|
145
|
+
|
146
|
+
RequestTypes = enum :libusb_request_type, [
|
147
|
+
:REQUEST_TYPE_STANDARD, (0x00 << 5),
|
148
|
+
:REQUEST_TYPE_CLASS, (0x01 << 5),
|
149
|
+
:REQUEST_TYPE_VENDOR, (0x02 << 5),
|
150
|
+
:REQUEST_TYPE_RESERVED, (0x03 << 5),
|
151
|
+
]
|
152
|
+
|
153
|
+
RequestRecipients = enum :libusb_request_recipient, [
|
154
|
+
:RECIPIENT_DEVICE, 0x00,
|
155
|
+
:RECIPIENT_INTERFACE, 0x01,
|
156
|
+
:RECIPIENT_ENDPOINT, 0x02,
|
157
|
+
:RECIPIENT_OTHER, 0x03,
|
158
|
+
]
|
159
|
+
|
160
|
+
IsoSyncTypes = enum :libusb_iso_sync_type, [
|
161
|
+
:ISO_SYNC_TYPE_NONE, 0,
|
162
|
+
:ISO_SYNC_TYPE_ASYNC, 1,
|
163
|
+
:ISO_SYNC_TYPE_ADAPTIVE, 2,
|
164
|
+
:ISO_SYNC_TYPE_SYNC, 3,
|
165
|
+
]
|
166
|
+
|
167
|
+
Speeds = enum :libusb_speed, [
|
168
|
+
:SPEED_UNKNOWN, 0,
|
169
|
+
:SPEED_LOW, 1,
|
170
|
+
:SPEED_FULL, 2,
|
171
|
+
:SPEED_HIGH, 3,
|
172
|
+
:SPEED_SUPER, 4,
|
173
|
+
]
|
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
|
+
|
188
|
+
Capabilities = enum :libusb_capability, [
|
189
|
+
:CAP_HAS_CAPABILITY, 0x0000,
|
190
|
+
# Hotplug support is available on this platform.
|
191
|
+
:CAP_HAS_HOTPLUG, 0x0001,
|
192
|
+
# The library can access HID devices without requiring user intervention.
|
193
|
+
# Note that before being able to actually access an HID device, you may
|
194
|
+
# still have to call additional libusb functions such as
|
195
|
+
# {DevHandle#detach_kernel_driver}.
|
196
|
+
:CAP_HAS_HID_ACCESS, 0x0100,
|
197
|
+
# The library supports detaching of the default USB driver, using
|
198
|
+
# {DevHandle#detach_kernel_driver}, if one is set by the OS kernel.
|
199
|
+
:CAP_SUPPORTS_DETACH_KERNEL_DRIVER, 0x0101,
|
200
|
+
]
|
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
|
+
|
232
|
+
# Since libusb version 1.0.16.
|
233
|
+
#
|
234
|
+
# Hotplug events
|
235
|
+
HotplugEvents = enum :libusb_hotplug_event, [
|
236
|
+
# A device has been plugged in and is ready to use.
|
237
|
+
:HOTPLUG_EVENT_DEVICE_ARRIVED, 0x01,
|
238
|
+
|
239
|
+
# A device has left and is no longer available.
|
240
|
+
# It is the user's responsibility to call libusb_close on any handle associated with a disconnected device.
|
241
|
+
# It is safe to call libusb_get_device_descriptor on a device that has left.
|
242
|
+
:HOTPLUG_EVENT_DEVICE_LEFT, 0x02,
|
243
|
+
]
|
244
|
+
|
245
|
+
# Since libusb version 1.0.16.
|
246
|
+
#
|
247
|
+
# Flags for hotplug events */
|
248
|
+
HotplugFlags = enum :libusb_hotplug_flag, [
|
249
|
+
# Arm the callback and fire it for all matching currently attached devices.
|
250
|
+
:HOTPLUG_ENUMERATE, 1,
|
251
|
+
]
|
252
|
+
|
253
|
+
typedef :pointer, :libusb_context
|
254
|
+
typedef :pointer, :libusb_device
|
255
|
+
typedef :pointer, :libusb_device_handle
|
256
|
+
typedef :pointer, :libusb_transfer
|
257
|
+
typedef :int, :libusb_hotplug_callback_handle
|
258
|
+
|
259
|
+
def self.try_attach_function(method, *args)
|
260
|
+
if ffi_libraries.find{|lib| lib.find_function(method) }
|
261
|
+
attach_function method, *args
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
try_attach_function 'libusb_get_version', [], :pointer
|
266
|
+
|
267
|
+
attach_function 'libusb_init', [ :pointer ], :int
|
268
|
+
attach_function 'libusb_exit', [ :pointer ], :void
|
269
|
+
attach_function 'libusb_set_debug', [:pointer, :int], :void
|
270
|
+
try_attach_function 'libusb_has_capability', [:libusb_capability], :int
|
271
|
+
|
272
|
+
attach_function 'libusb_get_device_list', [:pointer, :pointer], :ssize_t
|
273
|
+
attach_function 'libusb_free_device_list', [:pointer, :int], :void
|
274
|
+
attach_function 'libusb_ref_device', [:pointer], :pointer
|
275
|
+
attach_function 'libusb_unref_device', [:pointer], :void
|
276
|
+
|
277
|
+
attach_function 'libusb_get_device_descriptor', [:pointer, :pointer], :int
|
278
|
+
attach_function 'libusb_get_active_config_descriptor', [:pointer, :pointer], :int
|
279
|
+
attach_function 'libusb_get_config_descriptor', [:pointer, :uint8, :pointer], :int
|
280
|
+
attach_function 'libusb_get_config_descriptor_by_value', [:pointer, :uint8, :pointer], :int
|
281
|
+
attach_function 'libusb_free_config_descriptor', [:pointer], :void
|
282
|
+
attach_function 'libusb_get_bus_number', [:pointer], :uint8
|
283
|
+
try_attach_function 'libusb_get_port_number', [:pointer], :uint8
|
284
|
+
try_attach_function 'libusb_get_parent', [:pointer], :pointer
|
285
|
+
try_attach_function 'libusb_get_port_path', [:pointer, :pointer, :pointer, :uint8], :uint8
|
286
|
+
try_attach_function 'libusb_get_port_numbers', [:pointer, :pointer, :uint8], :uint8
|
287
|
+
attach_function 'libusb_get_device_address', [:pointer], :uint8
|
288
|
+
try_attach_function 'libusb_get_device_speed', [:pointer], :libusb_speed
|
289
|
+
attach_function 'libusb_get_max_packet_size', [:pointer, :uint8], :int
|
290
|
+
attach_function 'libusb_get_max_iso_packet_size', [:pointer, :uint8], :int
|
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
|
+
|
304
|
+
attach_function 'libusb_open', [:pointer, :pointer], :int
|
305
|
+
attach_function 'libusb_close', [:pointer], :void
|
306
|
+
attach_function 'libusb_get_device', [:libusb_device_handle], :pointer
|
307
|
+
|
308
|
+
attach_function 'libusb_set_configuration', [:libusb_device_handle, :int], :int, blocking: true
|
309
|
+
attach_function 'libusb_claim_interface', [:libusb_device_handle, :int], :int
|
310
|
+
attach_function 'libusb_release_interface', [:libusb_device_handle, :int], :int, blocking: true
|
311
|
+
|
312
|
+
attach_function 'libusb_open_device_with_vid_pid', [:pointer, :int, :int], :pointer
|
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
|
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
|
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
|
321
|
+
|
322
|
+
attach_function 'libusb_kernel_driver_active', [:libusb_device_handle, :int], :int
|
323
|
+
attach_function 'libusb_detach_kernel_driver', [:libusb_device_handle, :int], :int
|
324
|
+
attach_function 'libusb_attach_kernel_driver', [:libusb_device_handle, :int], :int
|
325
|
+
try_attach_function 'libusb_set_auto_detach_kernel_driver', [:libusb_device_handle, :int], :int
|
326
|
+
|
327
|
+
attach_function 'libusb_get_string_descriptor_ascii', [:pointer, :uint8, :pointer, :int], :int
|
328
|
+
|
329
|
+
attach_function 'libusb_alloc_transfer', [:int], :pointer
|
330
|
+
attach_function 'libusb_submit_transfer', [:pointer], :int
|
331
|
+
attach_function 'libusb_cancel_transfer', [:pointer], :int
|
332
|
+
attach_function 'libusb_free_transfer', [:pointer], :void
|
333
|
+
try_attach_function 'libusb_transfer_set_stream_id', [:libusb_transfer, :uint32], :void
|
334
|
+
try_attach_function 'libusb_transfer_get_stream_id', [:libusb_transfer], :uint32
|
335
|
+
|
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
|
341
|
+
|
342
|
+
callback :libusb_pollfd_added_cb, [:int, :short, :pointer], :void
|
343
|
+
callback :libusb_pollfd_removed_cb, [:int, :pointer], :void
|
344
|
+
|
345
|
+
attach_function 'libusb_get_pollfds', [:libusb_context], :pointer
|
346
|
+
attach_function 'libusb_get_next_timeout', [:libusb_context, :pointer], :int
|
347
|
+
attach_function 'libusb_set_pollfd_notifiers', [:libusb_context, :libusb_pollfd_added_cb, :libusb_pollfd_removed_cb, :pointer], :void
|
348
|
+
try_attach_function 'libusb_free_pollfds', [:pointer], :void
|
349
|
+
|
350
|
+
callback :libusb_transfer_cb_fn, [:pointer], :void
|
351
|
+
|
352
|
+
callback :libusb_hotplug_callback_fn, [:libusb_context, :libusb_device, :libusb_hotplug_event, :pointer], :int
|
353
|
+
try_attach_function 'libusb_hotplug_register_callback', [
|
354
|
+
:libusb_context, :libusb_hotplug_event, :libusb_hotplug_flag,
|
355
|
+
:int, :int, :int, :libusb_hotplug_callback_fn,
|
356
|
+
:pointer, :pointer], :int
|
357
|
+
try_attach_function 'libusb_hotplug_deregister_callback', [:libusb_context, :libusb_hotplug_callback_handle], :void
|
358
|
+
|
359
|
+
class IsoPacketDescriptor < FFI::Struct
|
360
|
+
layout :length, :uint,
|
361
|
+
:actual_length, :uint,
|
362
|
+
:status, :libusb_transfer_status
|
363
|
+
end
|
364
|
+
|
365
|
+
# Setup packet for control transfers.
|
366
|
+
class ControlSetup < FFI::Struct
|
367
|
+
layout :bmRequestType, :uint8,
|
368
|
+
:bRequest, :uint8,
|
369
|
+
:wValue, :uint16,
|
370
|
+
:wIndex, :uint16,
|
371
|
+
:wLength, :uint16
|
372
|
+
end
|
373
|
+
|
374
|
+
class Transfer < FFI::ManagedStruct
|
375
|
+
layout :dev_handle, :libusb_device_handle,
|
376
|
+
:flags, :uint8,
|
377
|
+
:endpoint, :uchar,
|
378
|
+
:type, :uchar,
|
379
|
+
:timeout, :uint,
|
380
|
+
:status, :libusb_transfer_status,
|
381
|
+
:length, :int,
|
382
|
+
:actual_length, :int,
|
383
|
+
:callback, :libusb_transfer_cb_fn,
|
384
|
+
:user_data, :pointer,
|
385
|
+
:buffer, :pointer,
|
386
|
+
:num_iso_packets, :int
|
387
|
+
|
388
|
+
def self.release(ptr)
|
389
|
+
Call.libusb_free_transfer(ptr)
|
390
|
+
end
|
391
|
+
end
|
392
|
+
|
393
|
+
class DeviceDescriptor < FFI::Struct
|
394
|
+
include Comparable
|
395
|
+
|
396
|
+
layout :bLength, :uint8,
|
397
|
+
:bDescriptorType, :uint8,
|
398
|
+
:bcdUSB, :uint16,
|
399
|
+
:bDeviceClass, :uint8,
|
400
|
+
:bDeviceSubClass, :uint8,
|
401
|
+
:bDeviceProtocol, :uint8,
|
402
|
+
:bMaxPacketSize0, :uint8,
|
403
|
+
:idVendor, :uint16,
|
404
|
+
:idProduct, :uint16,
|
405
|
+
:bcdDevice, :uint16,
|
406
|
+
:iManufacturer, :uint8,
|
407
|
+
:iProduct, :uint8,
|
408
|
+
:iSerialNumber, :uint8,
|
409
|
+
:bNumConfigurations, :uint8
|
410
|
+
end
|
411
|
+
|
412
|
+
class Timeval < FFI::Struct
|
413
|
+
layout :tv_sec, :long,
|
414
|
+
:tv_usec, :long
|
415
|
+
|
416
|
+
# set timeval to the number of milliseconds
|
417
|
+
# @param [Fixnum] value
|
418
|
+
def in_ms=(value)
|
419
|
+
self[:tv_sec], self[:tv_usec] = (value*1000).divmod(1000000)
|
420
|
+
end
|
421
|
+
|
422
|
+
# get the number of milliseconds in timeval
|
423
|
+
# @return [Fixnum]
|
424
|
+
def in_ms
|
425
|
+
self[:tv_sec]*1000 + self[:tv_usec]/1000
|
426
|
+
end
|
427
|
+
|
428
|
+
# set timeval to the number of seconds
|
429
|
+
# @param [Numeric] value
|
430
|
+
def in_s=(value)
|
431
|
+
self[:tv_sec], self[:tv_usec] = (value*1000000).divmod(1000000)
|
432
|
+
end
|
433
|
+
|
434
|
+
# get the number of seconds in timeval
|
435
|
+
# @return [Float]
|
436
|
+
def in_s
|
437
|
+
self[:tv_sec] + self[:tv_usec]/1000000.0
|
438
|
+
end
|
439
|
+
end
|
440
|
+
|
441
|
+
class Pollfd < FFI::Struct
|
442
|
+
layout :fd, :int,
|
443
|
+
:events, :short
|
444
|
+
end
|
445
|
+
end
|
446
|
+
end
|
@@ -0,0 +1,376 @@
|
|
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
|
+
@default_context = nil
|
41
|
+
def self.default_context
|
42
|
+
@default_context ||= LIBUSB::Context.new
|
43
|
+
end
|
44
|
+
|
45
|
+
@default_bus = nil
|
46
|
+
def self.default_bus
|
47
|
+
@default_bus ||= Bus.new(default_context)
|
48
|
+
end
|
49
|
+
|
50
|
+
USB_CLASS_PER_INTERFACE = LIBUSB::CLASS_PER_INTERFACE
|
51
|
+
USB_CLASS_AUDIO = LIBUSB::CLASS_AUDIO
|
52
|
+
USB_CLASS_COMM = LIBUSB::CLASS_COMM
|
53
|
+
USB_CLASS_HID = LIBUSB::CLASS_HID
|
54
|
+
USB_CLASS_PRINTER = LIBUSB::CLASS_PRINTER
|
55
|
+
USB_CLASS_PTP = LIBUSB::CLASS_PTP
|
56
|
+
USB_CLASS_MASS_STORAGE = LIBUSB::CLASS_MASS_STORAGE
|
57
|
+
USB_CLASS_HUB = LIBUSB::CLASS_HUB
|
58
|
+
USB_CLASS_DATA = LIBUSB::CLASS_DATA
|
59
|
+
USB_CLASS_VENDOR_SPEC = LIBUSB::CLASS_VENDOR_SPEC
|
60
|
+
|
61
|
+
USB_DT_DEVICE = LIBUSB::DT_DEVICE
|
62
|
+
USB_DT_CONFIG = LIBUSB::DT_CONFIG
|
63
|
+
USB_DT_STRING = LIBUSB::DT_STRING
|
64
|
+
USB_DT_INTERFACE = LIBUSB::DT_INTERFACE
|
65
|
+
USB_DT_ENDPOINT = LIBUSB::DT_ENDPOINT
|
66
|
+
USB_DT_HID = LIBUSB::DT_HID
|
67
|
+
USB_DT_REPORT = LIBUSB::DT_REPORT
|
68
|
+
USB_DT_PHYSICAL = LIBUSB::DT_PHYSICAL
|
69
|
+
USB_DT_HUB = LIBUSB::DT_HUB
|
70
|
+
USB_DT_DEVICE_SIZE = LIBUSB::DT_DEVICE_SIZE
|
71
|
+
USB_DT_CONFIG_SIZE = LIBUSB::DT_CONFIG_SIZE
|
72
|
+
USB_DT_INTERFACE_SIZE = LIBUSB::DT_INTERFACE_SIZE
|
73
|
+
USB_DT_ENDPOINT_SIZE = LIBUSB::DT_ENDPOINT_SIZE
|
74
|
+
USB_DT_ENDPOINT_AUDIO_SIZE = LIBUSB::DT_ENDPOINT_AUDIO_SIZE
|
75
|
+
USB_DT_HUB_NONVAR_SIZE = LIBUSB::DT_HUB_NONVAR_SIZE
|
76
|
+
|
77
|
+
USB_ENDPOINT_ADDRESS_MASK = LIBUSB::ENDPOINT_ADDRESS_MASK
|
78
|
+
USB_ENDPOINT_DIR_MASK = LIBUSB::ENDPOINT_DIR_MASK
|
79
|
+
USB_ENDPOINT_IN = LIBUSB::ENDPOINT_IN
|
80
|
+
USB_ENDPOINT_OUT = LIBUSB::ENDPOINT_OUT
|
81
|
+
|
82
|
+
USB_ENDPOINT_TYPE_MASK = LIBUSB::TRANSFER_TYPE_MASK
|
83
|
+
USB_ENDPOINT_TYPE_CONTROL = LIBUSB::TRANSFER_TYPE_CONTROL
|
84
|
+
USB_ENDPOINT_TYPE_ISOCHRONOUS = LIBUSB::TRANSFER_TYPE_ISOCHRONOUS
|
85
|
+
USB_ENDPOINT_TYPE_BULK = LIBUSB::TRANSFER_TYPE_BULK
|
86
|
+
USB_ENDPOINT_TYPE_INTERRUPT = LIBUSB::TRANSFER_TYPE_INTERRUPT
|
87
|
+
|
88
|
+
USB_REQ_GET_STATUS = LIBUSB::REQUEST_GET_STATUS
|
89
|
+
USB_REQ_CLEAR_FEATURE = LIBUSB::REQUEST_CLEAR_FEATURE
|
90
|
+
USB_REQ_SET_FEATURE = LIBUSB::REQUEST_SET_FEATURE
|
91
|
+
USB_REQ_SET_ADDRESS = LIBUSB::REQUEST_SET_ADDRESS
|
92
|
+
USB_REQ_GET_DESCRIPTOR = LIBUSB::REQUEST_GET_DESCRIPTOR
|
93
|
+
USB_REQ_SET_DESCRIPTOR = LIBUSB::REQUEST_SET_DESCRIPTOR
|
94
|
+
USB_REQ_GET_CONFIGURATION = LIBUSB::REQUEST_GET_CONFIGURATION
|
95
|
+
USB_REQ_SET_CONFIGURATION = LIBUSB::REQUEST_SET_CONFIGURATION
|
96
|
+
USB_REQ_GET_INTERFACE = LIBUSB::REQUEST_GET_INTERFACE
|
97
|
+
USB_REQ_SET_INTERFACE = LIBUSB::REQUEST_SET_INTERFACE
|
98
|
+
USB_REQ_SYNCH_FRAME = LIBUSB::REQUEST_SYNCH_FRAME
|
99
|
+
USB_TYPE_STANDARD = LIBUSB::REQUEST_TYPE_STANDARD
|
100
|
+
USB_TYPE_CLASS = LIBUSB::REQUEST_TYPE_CLASS
|
101
|
+
USB_TYPE_VENDOR = LIBUSB::REQUEST_TYPE_VENDOR
|
102
|
+
USB_TYPE_RESERVED = LIBUSB::REQUEST_TYPE_RESERVED
|
103
|
+
USB_RECIP_DEVICE = LIBUSB::RECIPIENT_DEVICE
|
104
|
+
USB_RECIP_INTERFACE = LIBUSB::RECIPIENT_INTERFACE
|
105
|
+
USB_RECIP_ENDPOINT = LIBUSB::RECIPIENT_ENDPOINT
|
106
|
+
USB_RECIP_OTHER = LIBUSB::RECIPIENT_OTHER
|
107
|
+
|
108
|
+
HAS_GET_DRIVER_NP = !FFI::Platform.windows?
|
109
|
+
HAS_DETACH_KERNEL_DRIVER_NP = !FFI::Platform.windows?
|
110
|
+
|
111
|
+
# not defined by libusb-1.0, but typical values are:
|
112
|
+
USB_MAXENDPOINTS = 32
|
113
|
+
USB_MAXINTERFACES = 32
|
114
|
+
USB_MAXALTSETTING = 128
|
115
|
+
USB_MAXCONFIG = 8
|
116
|
+
|
117
|
+
|
118
|
+
def USB.busses
|
119
|
+
[default_bus]
|
120
|
+
end
|
121
|
+
|
122
|
+
def USB.devices; default_context.devices.map{|c| Device.new(c) }; end
|
123
|
+
def USB.configurations() USB.devices.map {|d| d.configurations }.flatten end
|
124
|
+
def USB.interfaces() USB.configurations.map {|d| d.interfaces }.flatten end
|
125
|
+
def USB.settings() USB.interfaces.map {|d| d.settings }.flatten end
|
126
|
+
def USB.endpoints() USB.settings.map {|d| d.endpoints }.flatten end
|
127
|
+
|
128
|
+
def USB.find_bus(n)
|
129
|
+
default_bus
|
130
|
+
end
|
131
|
+
|
132
|
+
def USB.each_device_by_class(devclass, subclass=nil, protocol=nil)
|
133
|
+
devs = default_context.devices bClass: devclass, bSubClass: subclass, bProtocol: protocol
|
134
|
+
devs.each do |dev|
|
135
|
+
yield Device.new(dev)
|
136
|
+
end
|
137
|
+
nil
|
138
|
+
end
|
139
|
+
|
140
|
+
class Bus
|
141
|
+
def initialize(context)
|
142
|
+
@ct = context
|
143
|
+
end
|
144
|
+
def devices
|
145
|
+
@ct.devices.map{|d| Device.new(d) }
|
146
|
+
end
|
147
|
+
|
148
|
+
def configurations() self.devices.map{|d| d.configurations }.flatten end
|
149
|
+
def interfaces() self.configurations.map {|d| d.interfaces }.flatten end
|
150
|
+
def settings() self.interfaces.map {|d| d.settings }.flatten end
|
151
|
+
def endpoints() self.settings.map {|d| d.endpoints }.flatten end
|
152
|
+
|
153
|
+
def find_device(n)
|
154
|
+
raise NotImplementedError
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def USB.dev_string(base_class, sub_class, protocol)
|
159
|
+
LIBUSB.dev_string(base_class, sub_class, protocol)
|
160
|
+
end
|
161
|
+
|
162
|
+
class Device
|
163
|
+
extend Forwardable
|
164
|
+
include Comparable
|
165
|
+
|
166
|
+
def initialize(dev)
|
167
|
+
@dev = dev
|
168
|
+
end
|
169
|
+
|
170
|
+
def_delegators :@dev, :bLength, :bDescriptorType, :bcdUSB, :bDeviceClass,
|
171
|
+
:bDeviceSubClass, :bDeviceProtocol, :bMaxPacketSize0, :idVendor, :idProduct,
|
172
|
+
:bcdDevice, :iManufacturer, :iProduct, :iSerialNumber, :bNumConfigurations,
|
173
|
+
:manufacturer, :product, :serial_number,
|
174
|
+
:inspect
|
175
|
+
|
176
|
+
def <=>(o)
|
177
|
+
@dev<=>o.instance_variable_get(:@dev)
|
178
|
+
end
|
179
|
+
|
180
|
+
def open
|
181
|
+
h = DevHandle.new(@dev.open)
|
182
|
+
if block_given?
|
183
|
+
begin
|
184
|
+
yield h
|
185
|
+
ensure
|
186
|
+
h.usb_close
|
187
|
+
end
|
188
|
+
else
|
189
|
+
h
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def bus; default_bus; end
|
194
|
+
def configurations; @dev.configurations.map{|c| Configuration.new(c) }; end
|
195
|
+
def interfaces; @dev.interfaces.map{|c| Interface.new(c) }; end
|
196
|
+
def settings; @dev.settings.map{|c| Setting.new(c) }; end
|
197
|
+
def endpoints; @dev.endpoints.map{|c| Endpoint.new(c) }; end
|
198
|
+
end
|
199
|
+
|
200
|
+
class Configuration
|
201
|
+
extend Forwardable
|
202
|
+
include Comparable
|
203
|
+
|
204
|
+
def initialize(cd)
|
205
|
+
@cd = cd
|
206
|
+
end
|
207
|
+
|
208
|
+
def_delegators :@cd, :bLength, :bDescriptorType, :wTotalLength, :bNumInterfaces,
|
209
|
+
:bConfigurationValue, :iConfiguration, :bmAttributes, :bMaxPower,
|
210
|
+
:inspect
|
211
|
+
|
212
|
+
def <=>(o)
|
213
|
+
@cd<=>o.instance_variable_get(:@cd)
|
214
|
+
end
|
215
|
+
|
216
|
+
def bus; default_bus; end
|
217
|
+
def device() Device.new(@cd.device) end
|
218
|
+
def interfaces; @cd.interfaces.map{|c| Interface.new(c) }; end
|
219
|
+
def settings() self.interfaces.map {|d| d.settings }.flatten end
|
220
|
+
def endpoints() self.settings.map {|d| d.endpoints }.flatten end
|
221
|
+
end
|
222
|
+
|
223
|
+
class Interface
|
224
|
+
extend Forwardable
|
225
|
+
include Comparable
|
226
|
+
|
227
|
+
def initialize(i)
|
228
|
+
@i = i
|
229
|
+
end
|
230
|
+
|
231
|
+
def_delegators :@i, :inspect
|
232
|
+
|
233
|
+
def <=>(o)
|
234
|
+
@i<=>o.instance_variable_get(:@i)
|
235
|
+
end
|
236
|
+
|
237
|
+
def bus() self.configuration.device.bus end
|
238
|
+
def device() self.configuration.device end
|
239
|
+
def configuration; Configuration.new(@i.configuration); end
|
240
|
+
def settings; @i.alt_settings.map{|c| Setting.new(c) }; end
|
241
|
+
def endpoints() self.settings.map {|d| d.endpoints }.flatten end
|
242
|
+
end
|
243
|
+
|
244
|
+
class Setting
|
245
|
+
extend Forwardable
|
246
|
+
include Comparable
|
247
|
+
|
248
|
+
def initialize(id)
|
249
|
+
@id = id
|
250
|
+
end
|
251
|
+
|
252
|
+
def_delegators :@id, :bLength, :bDescriptorType, :bInterfaceNumber, :bAlternateSetting,
|
253
|
+
:bNumEndpoints, :bInterfaceClass, :bInterfaceSubClass, :bInterfaceProtocol,
|
254
|
+
:iInterface, :inspect
|
255
|
+
|
256
|
+
def <=>(o)
|
257
|
+
@id<=>o.instance_variable_get(:@id)
|
258
|
+
end
|
259
|
+
|
260
|
+
def bus() self.interface.configuration.device.bus end
|
261
|
+
def device() self.interface.configuration.device end
|
262
|
+
def configuration() self.interface.configuration end
|
263
|
+
def interface; Interface.new(@id.interface); end
|
264
|
+
def endpoints() @id.endpoints.map {|d| Endpoint.new(d) }.flatten end
|
265
|
+
end
|
266
|
+
|
267
|
+
class Endpoint
|
268
|
+
extend Forwardable
|
269
|
+
include Comparable
|
270
|
+
|
271
|
+
def initialize(ep)
|
272
|
+
@ep = ep
|
273
|
+
end
|
274
|
+
|
275
|
+
def_delegators :@ep, :bLength, :bDescriptorType, :bEndpointAddress, :bmAttributes,
|
276
|
+
:wMaxPacketSize, :bInterval, :bRefresh, :bSynchAddress,
|
277
|
+
:inspect
|
278
|
+
|
279
|
+
def <=>(o)
|
280
|
+
@ep<=>o.instance_variable_get(:@ep)
|
281
|
+
end
|
282
|
+
|
283
|
+
def bus() self.setting.interface.configuration.device.bus end
|
284
|
+
def device() self.setting.interface.configuration.device end
|
285
|
+
def configuration() self.setting.interface.configuration end
|
286
|
+
def interface() self.setting.interface end
|
287
|
+
def setting; Setting.new(@ep.setting); end
|
288
|
+
end
|
289
|
+
|
290
|
+
class DevHandle
|
291
|
+
def initialize(dev)
|
292
|
+
@dev = dev
|
293
|
+
end
|
294
|
+
|
295
|
+
def usb_close; @dev.close; end
|
296
|
+
def usb_set_configuration(c); @dev.configuration=c; end
|
297
|
+
def usb_set_altinterface(c); @dev.set_interface_alt_setting=c; end
|
298
|
+
def usb_clear_halt(c); @dev.clear_halt(c); end
|
299
|
+
def usb_reset; @dev.reset_device; end
|
300
|
+
def usb_claim_interface(c); @dev.claim_interface(c); end
|
301
|
+
def usb_release_interface(c); @dev.release_interface(c); end
|
302
|
+
def usb_get_string(index, langid, buffer)
|
303
|
+
t = @dev.string_descriptor(index, langid)
|
304
|
+
buffer[0, t.length] = t
|
305
|
+
t.length
|
306
|
+
end
|
307
|
+
def usb_get_string_simple(index, buffer)
|
308
|
+
t = @dev.string_descriptor_ascii(index)
|
309
|
+
buffer[0, t.length] = t
|
310
|
+
t.length
|
311
|
+
end
|
312
|
+
|
313
|
+
def usb_control_msg(requesttype, request, value, index, bytes, timeout)
|
314
|
+
if requesttype&LIBUSB::ENDPOINT_IN != 0
|
315
|
+
# transfer direction in
|
316
|
+
res = @dev.control_transfer(bmRequestType: requesttype, bRequest: request,
|
317
|
+
wValue: value, wIndex: index, dataIn: bytes.bytesize, timeout: timeout)
|
318
|
+
bytes[0, res.bytesize] = res
|
319
|
+
res.bytesize
|
320
|
+
else
|
321
|
+
# transfer direction out
|
322
|
+
@dev.control_transfer(bmRequestType: requesttype, bRequest: request, wValue: value,
|
323
|
+
wIndex: index, dataOut: bytes, timeout: timeout)
|
324
|
+
end
|
325
|
+
end
|
326
|
+
|
327
|
+
def usb_bulk_write(endpoint, bytes, timeout)
|
328
|
+
@dev.bulk_transfer(endpoint: endpoint, dataOut: bytes, timeout: timeout)
|
329
|
+
end
|
330
|
+
def usb_bulk_read(endpoint, bytes, timeout)
|
331
|
+
res = @dev.bulk_transfer(endpoint: endpoint, dataIn: bytes.bytesize, timeout: timeout)
|
332
|
+
bytes[0, res.bytesize] = res
|
333
|
+
res.bytesize
|
334
|
+
end
|
335
|
+
|
336
|
+
def usb_interrupt_write(endpoint, bytes, timeout)
|
337
|
+
@dev.interrupt_transfer(endpoint: endpoint, dataOut: bytes, timeout: timeout)
|
338
|
+
end
|
339
|
+
def usb_interrupt_read(endpoint, bytes, timeout)
|
340
|
+
res = @dev.interrupt_transfer(endpoint: endpoint, dataIn: bytes.bytesize, timeout: timeout)
|
341
|
+
bytes[0, res.bytesize] = res
|
342
|
+
res.bytesize
|
343
|
+
end
|
344
|
+
|
345
|
+
# rb_define_method(rb_cUSB_DevHandle, "usb_get_descriptor", rusb_get_descriptor, 3);
|
346
|
+
# rb_define_method(rb_cUSB_DevHandle, "usb_get_descriptor_by_endpoint", rusb_get_descriptor_by_endpoint, 4);
|
347
|
+
|
348
|
+
if HAS_DETACH_KERNEL_DRIVER_NP
|
349
|
+
def usb_detach_kernel_driver_np(interface, dummy=nil)
|
350
|
+
@dev.detach_kernel_driver(interface)
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
if HAS_GET_DRIVER_NP
|
355
|
+
def usb_get_driver_np(interface, buffer)
|
356
|
+
if @dev.kernel_driver_active?(interface)
|
357
|
+
t = "unknown driver"
|
358
|
+
buffer[0, t.length] = t
|
359
|
+
else
|
360
|
+
raise Errno::ENODATA, "No data available"
|
361
|
+
end
|
362
|
+
nil
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
alias set_configuration usb_set_configuration
|
367
|
+
alias set_altinterface usb_set_altinterface
|
368
|
+
alias clear_halt usb_clear_halt
|
369
|
+
alias claim_interface usb_claim_interface
|
370
|
+
alias release_interface usb_release_interface
|
371
|
+
|
372
|
+
def get_string_simple(index)
|
373
|
+
@dev.string_descriptor_ascii(index)
|
374
|
+
end
|
375
|
+
end
|
376
|
+
end
|