libusb 0.1.3-x86-mingw32 → 0.2.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/.yardopts +1 -0
- data/History.txt +8 -0
- data/Manifest.txt +2 -15
- data/README.rdoc +22 -16
- data/Rakefile +26 -10
- data/lib/libusb-1.0.dll +0 -0
- data/lib/libusb.rb +27 -1767
- data/lib/libusb/call.rb +271 -0
- data/lib/libusb/compat.rb +2 -2
- data/lib/libusb/configuration.rb +139 -0
- data/lib/libusb/constants.rb +138 -0
- data/lib/libusb/context.rb +127 -0
- data/lib/libusb/dev_handle.rb +399 -0
- data/lib/libusb/device.rb +359 -0
- data/lib/libusb/endpoint.rb +147 -0
- data/lib/libusb/interface.rb +51 -0
- data/lib/libusb/setting.rb +132 -0
- data/lib/libusb/transfer.rb +269 -0
- data/lib/libusb/version.rb +63 -0
- data/test/test_libusb_capability.rb +23 -0
- data/test/test_libusb_descriptors.rb +13 -0
- data/test/test_libusb_version.rb +36 -0
- metadata +30 -18
- data/test/test_libusb_keyboard.rb +0 -50
data/lib/libusb/call.rb
ADDED
@@ -0,0 +1,271 @@
|
|
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
|
21
|
+
module Call
|
22
|
+
extend FFI::Library
|
23
|
+
|
24
|
+
if FFI::Platform.windows?
|
25
|
+
bundled_dll = File.join(File.dirname(__FILE__), '..', 'libusb-1.0.dll')
|
26
|
+
ffi_lib(['libusb-1.0', bundled_dll])
|
27
|
+
else
|
28
|
+
ffi_lib 'libusb-1.0'
|
29
|
+
end
|
30
|
+
|
31
|
+
ClassCodes = enum :libusb_class_code, [
|
32
|
+
:CLASS_PER_INTERFACE, 0,
|
33
|
+
:CLASS_AUDIO, 1,
|
34
|
+
:CLASS_COMM, 2,
|
35
|
+
:CLASS_HID, 3,
|
36
|
+
:CLASS_PRINTER, 7,
|
37
|
+
:CLASS_PTP, 6,
|
38
|
+
:CLASS_MASS_STORAGE, 8,
|
39
|
+
:CLASS_HUB, 9,
|
40
|
+
:CLASS_DATA, 10,
|
41
|
+
:CLASS_WIRELESS, 0xe0,
|
42
|
+
:CLASS_APPLICATION, 0xfe,
|
43
|
+
:CLASS_VENDOR_SPEC, 0xff
|
44
|
+
]
|
45
|
+
|
46
|
+
Errors = enum :libusb_error, [
|
47
|
+
:SUCCESS, 0,
|
48
|
+
:ERROR_IO, -1,
|
49
|
+
:ERROR_INVALID_PARAM, -2,
|
50
|
+
:ERROR_ACCESS, -3,
|
51
|
+
:ERROR_NO_DEVICE, -4,
|
52
|
+
:ERROR_NOT_FOUND, -5,
|
53
|
+
:ERROR_BUSY, -6,
|
54
|
+
:ERROR_TIMEOUT, -7,
|
55
|
+
:ERROR_OVERFLOW, -8,
|
56
|
+
:ERROR_PIPE, -9,
|
57
|
+
:ERROR_INTERRUPTED, -10,
|
58
|
+
:ERROR_NO_MEM, -11,
|
59
|
+
:ERROR_NOT_SUPPORTED, -12,
|
60
|
+
:ERROR_OTHER, -99,
|
61
|
+
]
|
62
|
+
|
63
|
+
# Transfer status codes
|
64
|
+
TransferStatus = enum :libusb_transfer_status, [
|
65
|
+
:TRANSFER_COMPLETED,
|
66
|
+
:TRANSFER_ERROR,
|
67
|
+
:TRANSFER_TIMED_OUT,
|
68
|
+
:TRANSFER_CANCELLED,
|
69
|
+
:TRANSFER_STALL,
|
70
|
+
:TRANSFER_NO_DEVICE,
|
71
|
+
:TRANSFER_OVERFLOW,
|
72
|
+
]
|
73
|
+
|
74
|
+
# libusb_transfer.flags values
|
75
|
+
TransferFlags = enum :libusb_transfer_flags, [
|
76
|
+
:TRANSFER_SHORT_NOT_OK, 1 << 0,
|
77
|
+
:TRANSFER_FREE_BUFFER, 1 << 1,
|
78
|
+
:TRANSFER_FREE_TRANSFER, 1 << 2,
|
79
|
+
:TRANSFER_ADD_ZERO_PACKET, 1 << 3,
|
80
|
+
]
|
81
|
+
|
82
|
+
TransferTypes = enum :libusb_transfer_type, [
|
83
|
+
:TRANSFER_TYPE_CONTROL, 0,
|
84
|
+
:TRANSFER_TYPE_ISOCHRONOUS, 1,
|
85
|
+
:TRANSFER_TYPE_BULK, 2,
|
86
|
+
:TRANSFER_TYPE_INTERRUPT, 3,
|
87
|
+
]
|
88
|
+
|
89
|
+
StandardRequests = enum :libusb_standard_request, [
|
90
|
+
:REQUEST_GET_STATUS, 0x00,
|
91
|
+
:REQUEST_CLEAR_FEATURE, 0x01,
|
92
|
+
:REQUEST_SET_FEATURE, 0x03,
|
93
|
+
:REQUEST_SET_ADDRESS, 0x05,
|
94
|
+
:REQUEST_GET_DESCRIPTOR, 0x06,
|
95
|
+
:REQUEST_SET_DESCRIPTOR, 0x07,
|
96
|
+
:REQUEST_GET_CONFIGURATION, 0x08,
|
97
|
+
:REQUEST_SET_CONFIGURATION, 0x09,
|
98
|
+
:REQUEST_GET_INTERFACE, 0x0A,
|
99
|
+
:REQUEST_SET_INTERFACE, 0x0B,
|
100
|
+
:REQUEST_SYNCH_FRAME, 0x0C,
|
101
|
+
]
|
102
|
+
|
103
|
+
EndpointDirections = enum :libusb_endpoint_direction, [
|
104
|
+
:ENDPOINT_IN, 0x80,
|
105
|
+
:ENDPOINT_OUT, 0x00,
|
106
|
+
]
|
107
|
+
|
108
|
+
DescriptorTypes = enum :libusb_descriptor_type, [
|
109
|
+
:DT_DEVICE, 0x01,
|
110
|
+
:DT_CONFIG, 0x02,
|
111
|
+
:DT_STRING, 0x03,
|
112
|
+
:DT_INTERFACE, 0x04,
|
113
|
+
:DT_ENDPOINT, 0x05,
|
114
|
+
:DT_HID, 0x21,
|
115
|
+
:DT_REPORT, 0x22,
|
116
|
+
:DT_PHYSICAL, 0x23,
|
117
|
+
:DT_HUB, 0x29,
|
118
|
+
]
|
119
|
+
|
120
|
+
RequestTypes = enum :libusb_request_type, [
|
121
|
+
:REQUEST_TYPE_STANDARD, (0x00 << 5),
|
122
|
+
:REQUEST_TYPE_CLASS, (0x01 << 5),
|
123
|
+
:REQUEST_TYPE_VENDOR, (0x02 << 5),
|
124
|
+
:REQUEST_TYPE_RESERVED, (0x03 << 5),
|
125
|
+
]
|
126
|
+
|
127
|
+
RequestRecipients = enum :libusb_request_recipient, [
|
128
|
+
:RECIPIENT_DEVICE, 0x00,
|
129
|
+
:RECIPIENT_INTERFACE, 0x01,
|
130
|
+
:RECIPIENT_ENDPOINT, 0x02,
|
131
|
+
:RECIPIENT_OTHER, 0x03,
|
132
|
+
]
|
133
|
+
|
134
|
+
IsoSyncTypes = enum :libusb_iso_sync_type, [
|
135
|
+
:ISO_SYNC_TYPE_NONE, 0,
|
136
|
+
:ISO_SYNC_TYPE_ASYNC, 1,
|
137
|
+
:ISO_SYNC_TYPE_ADAPTIVE, 2,
|
138
|
+
:ISO_SYNC_TYPE_SYNC, 3,
|
139
|
+
]
|
140
|
+
|
141
|
+
Speeds = enum :libusb_speed, [
|
142
|
+
:SPEED_UNKNOWN, 0,
|
143
|
+
:SPEED_LOW, 1,
|
144
|
+
:SPEED_FULL, 2,
|
145
|
+
:SPEED_HIGH, 3,
|
146
|
+
:SPEED_SUPER, 4,
|
147
|
+
]
|
148
|
+
|
149
|
+
Capabilities = enum :libusb_capability, [
|
150
|
+
:CAP_HAS_CAPABILITY, 0,
|
151
|
+
]
|
152
|
+
|
153
|
+
typedef :pointer, :libusb_context
|
154
|
+
typedef :pointer, :libusb_device_handle
|
155
|
+
|
156
|
+
def self.try_attach_function(method, *args)
|
157
|
+
if ffi_libraries.find{|lib| lib.find_function(method) }
|
158
|
+
attach_function method, *args
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
try_attach_function 'libusb_get_version', [], :pointer
|
163
|
+
|
164
|
+
attach_function 'libusb_init', [ :pointer ], :int
|
165
|
+
attach_function 'libusb_exit', [ :pointer ], :void
|
166
|
+
attach_function 'libusb_set_debug', [:pointer, :int], :void
|
167
|
+
try_attach_function 'libusb_has_capability', [:libusb_capability], :int
|
168
|
+
|
169
|
+
attach_function 'libusb_get_device_list', [:pointer, :pointer], :size_t
|
170
|
+
attach_function 'libusb_free_device_list', [:pointer, :int], :void
|
171
|
+
attach_function 'libusb_ref_device', [:pointer], :pointer
|
172
|
+
attach_function 'libusb_unref_device', [:pointer], :void
|
173
|
+
|
174
|
+
attach_function 'libusb_get_device_descriptor', [:pointer, :pointer], :int
|
175
|
+
attach_function 'libusb_get_active_config_descriptor', [:pointer, :pointer], :int
|
176
|
+
attach_function 'libusb_get_config_descriptor', [:pointer, :uint8, :pointer], :int
|
177
|
+
attach_function 'libusb_get_config_descriptor_by_value', [:pointer, :uint8, :pointer], :int
|
178
|
+
attach_function 'libusb_free_config_descriptor', [:pointer], :void
|
179
|
+
attach_function 'libusb_get_bus_number', [:pointer], :uint8
|
180
|
+
try_attach_function 'libusb_get_port_number', [:pointer], :uint8
|
181
|
+
try_attach_function 'libusb_get_parent', [:pointer], :pointer
|
182
|
+
try_attach_function 'libusb_get_port_path', [:pointer, :pointer, :pointer, :uint8], :uint8
|
183
|
+
attach_function 'libusb_get_device_address', [:pointer], :uint8
|
184
|
+
try_attach_function 'libusb_get_device_speed', [:pointer], :libusb_speed
|
185
|
+
attach_function 'libusb_get_max_packet_size', [:pointer, :uint8], :int
|
186
|
+
attach_function 'libusb_get_max_iso_packet_size', [:pointer, :uint8], :int
|
187
|
+
|
188
|
+
attach_function 'libusb_open', [:pointer, :pointer], :int
|
189
|
+
attach_function 'libusb_close', [:pointer], :void
|
190
|
+
attach_function 'libusb_get_device', [:libusb_device_handle], :pointer
|
191
|
+
|
192
|
+
attach_function 'libusb_set_configuration', [:libusb_device_handle, :int], :int, :blocking=>true
|
193
|
+
attach_function 'libusb_claim_interface', [:libusb_device_handle, :int], :int
|
194
|
+
attach_function 'libusb_release_interface', [:libusb_device_handle, :int], :int, :blocking=>true
|
195
|
+
|
196
|
+
attach_function 'libusb_open_device_with_vid_pid', [:pointer, :int, :int], :pointer
|
197
|
+
|
198
|
+
attach_function 'libusb_set_interface_alt_setting', [:libusb_device_handle, :int, :int], :int, :blocking=>true
|
199
|
+
attach_function 'libusb_clear_halt', [:libusb_device_handle, :int], :int, :blocking=>true
|
200
|
+
attach_function 'libusb_reset_device', [:libusb_device_handle], :int, :blocking=>true
|
201
|
+
|
202
|
+
attach_function 'libusb_kernel_driver_active', [:libusb_device_handle, :int], :int
|
203
|
+
attach_function 'libusb_detach_kernel_driver', [:libusb_device_handle, :int], :int
|
204
|
+
attach_function 'libusb_attach_kernel_driver', [:libusb_device_handle, :int], :int
|
205
|
+
|
206
|
+
attach_function 'libusb_get_string_descriptor_ascii', [:pointer, :uint8, :pointer, :int], :int
|
207
|
+
|
208
|
+
attach_function 'libusb_alloc_transfer', [:int], :pointer
|
209
|
+
attach_function 'libusb_submit_transfer', [:pointer], :int
|
210
|
+
attach_function 'libusb_cancel_transfer', [:pointer], :int
|
211
|
+
attach_function 'libusb_free_transfer', [:pointer], :void
|
212
|
+
|
213
|
+
attach_function 'libusb_handle_events', [:libusb_context], :int, :blocking=>true
|
214
|
+
|
215
|
+
|
216
|
+
callback :libusb_transfer_cb_fn, [:pointer], :void
|
217
|
+
|
218
|
+
class IsoPacketDescriptor < FFI::Struct
|
219
|
+
layout :length, :uint,
|
220
|
+
:actual_length, :uint,
|
221
|
+
:status, :libusb_transfer_status
|
222
|
+
end
|
223
|
+
|
224
|
+
# Setup packet for control transfers.
|
225
|
+
class ControlSetup < FFI::Struct
|
226
|
+
layout :bmRequestType, :uint8,
|
227
|
+
:bRequest, :uint8,
|
228
|
+
:wValue, :uint16,
|
229
|
+
:wIndex, :uint16,
|
230
|
+
:wLength, :uint16
|
231
|
+
end
|
232
|
+
|
233
|
+
class Transfer < FFI::ManagedStruct
|
234
|
+
layout :dev_handle, :libusb_device_handle,
|
235
|
+
:flags, :uint8,
|
236
|
+
:endpoint, :uchar,
|
237
|
+
:type, :uchar,
|
238
|
+
:timeout, :uint,
|
239
|
+
:status, :libusb_transfer_status,
|
240
|
+
:length, :int,
|
241
|
+
:actual_length, :int,
|
242
|
+
:callback, :libusb_transfer_cb_fn,
|
243
|
+
:user_data, :pointer,
|
244
|
+
:buffer, :pointer,
|
245
|
+
:num_iso_packets, :int
|
246
|
+
|
247
|
+
def self.release(ptr)
|
248
|
+
Call.libusb_free_transfer(ptr)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
class DeviceDescriptor < FFI::Struct
|
253
|
+
include Comparable
|
254
|
+
|
255
|
+
layout :bLength, :uint8,
|
256
|
+
:bDescriptorType, :uint8,
|
257
|
+
:bcdUSB, :uint16,
|
258
|
+
:bDeviceClass, :uint8,
|
259
|
+
:bDeviceSubClass, :uint8,
|
260
|
+
:bDeviceProtocol, :uint8,
|
261
|
+
:bMaxPacketSize0, :uint8,
|
262
|
+
:idVendor, :uint16,
|
263
|
+
:idProduct, :uint16,
|
264
|
+
:bcdDevice, :uint16,
|
265
|
+
:iManufacturer, :uint8,
|
266
|
+
:iProduct, :uint8,
|
267
|
+
:iSerialNumber, :uint8,
|
268
|
+
:bNumConfigurations, :uint8
|
269
|
+
end
|
270
|
+
end
|
271
|
+
end
|
data/lib/libusb/compat.rb
CHANGED
@@ -97,8 +97,8 @@ module USB
|
|
97
97
|
USB_RECIP_ENDPOINT = LIBUSB::RECIPIENT_ENDPOINT
|
98
98
|
USB_RECIP_OTHER = LIBUSB::RECIPIENT_OTHER
|
99
99
|
|
100
|
-
HAS_GET_DRIVER_NP =
|
101
|
-
HAS_DETACH_KERNEL_DRIVER_NP =
|
100
|
+
HAS_GET_DRIVER_NP = !FFI::Platform.windows?
|
101
|
+
HAS_DETACH_KERNEL_DRIVER_NP = !FFI::Platform.windows?
|
102
102
|
|
103
103
|
# not defined by libusb-1.0, but typical values are:
|
104
104
|
USB_MAXENDPOINTS = 32
|
@@ -0,0 +1,139 @@
|
|
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
|
+
class Configuration < FFI::ManagedStruct
|
20
|
+
include Comparable
|
21
|
+
|
22
|
+
layout :bLength, :uint8,
|
23
|
+
:bDescriptorType, :uint8,
|
24
|
+
:wTotalLength, :uint16,
|
25
|
+
:bNumInterfaces, :uint8,
|
26
|
+
:bConfigurationValue, :uint8,
|
27
|
+
:iConfiguration, :uint8,
|
28
|
+
:bmAttributes, :uint8,
|
29
|
+
:maxPower, :uint8,
|
30
|
+
:interface, :pointer,
|
31
|
+
:extra, :pointer,
|
32
|
+
:extra_length, :int
|
33
|
+
|
34
|
+
# Size of this descriptor (in bytes).
|
35
|
+
def bLength
|
36
|
+
self[:bLength]
|
37
|
+
end
|
38
|
+
|
39
|
+
# Descriptor type (0x02)
|
40
|
+
def bDescriptorType
|
41
|
+
self[:bDescriptorType]
|
42
|
+
end
|
43
|
+
|
44
|
+
# Total length of data returned for this configuration.
|
45
|
+
def wTotalLength
|
46
|
+
self[:wTotalLength]
|
47
|
+
end
|
48
|
+
|
49
|
+
# Number of interfaces supported by this configuration.
|
50
|
+
def bNumInterfaces
|
51
|
+
self[:bNumInterfaces]
|
52
|
+
end
|
53
|
+
|
54
|
+
# Identifier value for this configuration.
|
55
|
+
def bConfigurationValue
|
56
|
+
self[:bConfigurationValue]
|
57
|
+
end
|
58
|
+
|
59
|
+
# Index of string descriptor describing this configuration.
|
60
|
+
def iConfiguration
|
61
|
+
self[:iConfiguration]
|
62
|
+
end
|
63
|
+
|
64
|
+
# Configuration characteristics.
|
65
|
+
#
|
66
|
+
# * Bit 7: Reserved, set to 1. (USB 1.0 Bus Powered)
|
67
|
+
# * Bit 6: Self Powered
|
68
|
+
# * Bit 5: Remote Wakeup
|
69
|
+
# * Bit 4..0: Reserved, set to 0.
|
70
|
+
#
|
71
|
+
# @return [Integer]
|
72
|
+
def bmAttributes
|
73
|
+
self[:bmAttributes]
|
74
|
+
end
|
75
|
+
|
76
|
+
# Maximum power consumption of the USB device from this bus in this configuration when the device is fully opreation.
|
77
|
+
#
|
78
|
+
# @return [Integer] Maximum Power Consumption in 2mA units
|
79
|
+
def maxPower
|
80
|
+
self[:maxPower]
|
81
|
+
end
|
82
|
+
|
83
|
+
# Extra descriptors.
|
84
|
+
#
|
85
|
+
# @return [String]
|
86
|
+
def extra
|
87
|
+
return if self[:extra].null?
|
88
|
+
self[:extra].read_string(self[:extra_length])
|
89
|
+
end
|
90
|
+
|
91
|
+
def initialize(device, *args)
|
92
|
+
@device = device
|
93
|
+
super(*args)
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.release(ptr)
|
97
|
+
Call.libusb_free_config_descriptor(ptr)
|
98
|
+
end
|
99
|
+
|
100
|
+
# @return [Device] the device this configuration belongs to.
|
101
|
+
attr_reader :device
|
102
|
+
|
103
|
+
def interfaces
|
104
|
+
ifs = []
|
105
|
+
self[:bNumInterfaces].times do |i|
|
106
|
+
ifs << Interface.new(self, self[:interface] + i*Interface.size)
|
107
|
+
end
|
108
|
+
return ifs
|
109
|
+
end
|
110
|
+
|
111
|
+
def inspect
|
112
|
+
attrs = []
|
113
|
+
attrs << self.bConfigurationValue.to_s
|
114
|
+
bits = self.bmAttributes
|
115
|
+
attrs << "SelfPowered" if (bits & 0b1000000) != 0
|
116
|
+
attrs << "RemoteWakeup" if (bits & 0b100000) != 0
|
117
|
+
desc = self.description
|
118
|
+
attrs << desc if desc != '?'
|
119
|
+
"\#<#{self.class} #{attrs.join(' ')}>"
|
120
|
+
end
|
121
|
+
|
122
|
+
# Return name of this configuration as String.
|
123
|
+
def description
|
124
|
+
return @description if defined? @description
|
125
|
+
@description = device.try_string_descriptor_ascii(self.iConfiguration)
|
126
|
+
end
|
127
|
+
|
128
|
+
# Return all interface decriptions of the configuration as Array of {Setting}s.
|
129
|
+
def settings() self.interfaces.map {|d| d.settings }.flatten end
|
130
|
+
# Return all endpoints of all interfaces of the configuration as Array of {Endpoint}s.
|
131
|
+
def endpoints() self.settings.map {|d| d.endpoints }.flatten end
|
132
|
+
|
133
|
+
def <=>(o)
|
134
|
+
t = device<=>o.device
|
135
|
+
t = bConfigurationValue<=>o.bConfigurationValue if t==0
|
136
|
+
t
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
@@ -0,0 +1,138 @@
|
|
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
|
+
Call::ClassCodes.to_h.each{|k,v| const_set(k,v) }
|
20
|
+
Call::TransferTypes.to_h.each{|k,v| const_set(k,v) }
|
21
|
+
Call::StandardRequests.to_h.each{|k,v| const_set(k,v) }
|
22
|
+
Call::RequestTypes.to_h.each{|k,v| const_set(k,v) }
|
23
|
+
Call::DescriptorTypes.to_h.each{|k,v| const_set(k,v) }
|
24
|
+
Call::EndpointDirections.to_h.each{|k,v| const_set(k,v) }
|
25
|
+
Call::RequestRecipients.to_h.each{|k,v| const_set(k,v) }
|
26
|
+
Call::IsoSyncTypes.to_h.each{|k,v| const_set(k,v) }
|
27
|
+
Call::Speeds.to_h.each{|k,v| const_set(k,v) }
|
28
|
+
Call::Capabilities.to_h.each{|k,v| const_set(k,v) }
|
29
|
+
|
30
|
+
# Base class of libusb errors
|
31
|
+
class Error < RuntimeError
|
32
|
+
end
|
33
|
+
# @private
|
34
|
+
ErrorClassForResult = {}
|
35
|
+
|
36
|
+
# define an exception class for each error code
|
37
|
+
Call::Errors.to_h.each do |k,v|
|
38
|
+
klass = Class.new(Error)
|
39
|
+
klass.send(:define_method, :code){ v }
|
40
|
+
const_set(k, klass)
|
41
|
+
ErrorClassForResult[v] = klass
|
42
|
+
end
|
43
|
+
|
44
|
+
def self.raise_error(res, text)
|
45
|
+
klass = ErrorClassForResult[res]
|
46
|
+
raise klass, "#{klass} #{text}"
|
47
|
+
end
|
48
|
+
|
49
|
+
CONTROL_SETUP_SIZE = 8
|
50
|
+
DT_DEVICE_SIZE = 18
|
51
|
+
DT_CONFIG_SIZE = 9
|
52
|
+
DT_INTERFACE_SIZE = 9
|
53
|
+
DT_ENDPOINT_SIZE = 7
|
54
|
+
DT_ENDPOINT_AUDIO_SIZE = 9 # Audio extension
|
55
|
+
DT_HUB_NONVAR_SIZE = 7
|
56
|
+
|
57
|
+
ENDPOINT_ADDRESS_MASK = 0x0f # in bEndpointAddress
|
58
|
+
ENDPOINT_DIR_MASK = 0x80
|
59
|
+
TRANSFER_TYPE_MASK = 0x03 # in bmAttributes
|
60
|
+
ISO_SYNC_TYPE_MASK = 0x0C
|
61
|
+
ISO_USAGE_TYPE_MASK = 0x30
|
62
|
+
|
63
|
+
|
64
|
+
# http://www.usb.org/developers/defined_class
|
65
|
+
# @private
|
66
|
+
CLASS_CODES = [
|
67
|
+
[0x01, nil, nil, "Audio"],
|
68
|
+
[0x02, nil, nil, "Comm"],
|
69
|
+
[0x03, nil, nil, "HID"],
|
70
|
+
[0x05, nil, nil, "Physical"],
|
71
|
+
[0x06, 0x01, 0x01, "StillImaging"],
|
72
|
+
[0x06, nil, nil, "Image"],
|
73
|
+
[0x07, nil, nil, "Printer"],
|
74
|
+
[0x08, 0x01, nil, "MassStorage RBC Bluk-Only"],
|
75
|
+
[0x08, 0x02, 0x50, "MassStorage ATAPI Bluk-Only"],
|
76
|
+
[0x08, 0x03, 0x50, "MassStorage QIC-157 Bluk-Only"],
|
77
|
+
[0x08, 0x04, nil, "MassStorage UFI"],
|
78
|
+
[0x08, 0x05, 0x50, "MassStorage SFF-8070i Bluk-Only"],
|
79
|
+
[0x08, 0x06, 0x50, "MassStorage SCSI Bluk-Only"],
|
80
|
+
[0x08, nil, nil, "MassStorage"],
|
81
|
+
[0x09, 0x00, 0x00, "Full speed Hub"],
|
82
|
+
[0x09, 0x00, 0x01, "Hi-speed Hub with single TT"],
|
83
|
+
[0x09, 0x00, 0x02, "Hi-speed Hub with multiple TTs"],
|
84
|
+
[0x09, nil, nil, "Hub"],
|
85
|
+
[0x0a, nil, nil, "CDC"],
|
86
|
+
[0x0b, nil, nil, "SmartCard"],
|
87
|
+
[0x0d, 0x00, 0x00, "ContentSecurity"],
|
88
|
+
[0x0e, nil, nil, "Video"],
|
89
|
+
[0xdc, 0x01, 0x01, "Diagnostic USB2"],
|
90
|
+
[0xdc, nil, nil, "Diagnostic"],
|
91
|
+
[0xe0, 0x01, 0x01, "Bluetooth"],
|
92
|
+
[0xe0, 0x01, 0x02, "UWB"],
|
93
|
+
[0xe0, 0x01, 0x03, "RemoteNDIS"],
|
94
|
+
[0xe0, 0x02, 0x01, "Host Wire Adapter Control/Data"],
|
95
|
+
[0xe0, 0x02, 0x02, "Device Wire Adapter Control/Data"],
|
96
|
+
[0xe0, 0x02, 0x03, "Device Wire Adapter Isochronous"],
|
97
|
+
[0xe0, nil, nil, "Wireless Controller"],
|
98
|
+
[0xef, 0x01, 0x01, "Active Sync"],
|
99
|
+
[0xef, 0x01, 0x02, "Palm Sync"],
|
100
|
+
[0xef, 0x02, 0x01, "Interface Association Descriptor"],
|
101
|
+
[0xef, 0x02, 0x02, "Wire Adapter Multifunction Peripheral"],
|
102
|
+
[0xef, 0x03, 0x01, "Cable Based Association Framework"],
|
103
|
+
[0xef, nil, nil, "Miscellaneous"],
|
104
|
+
[0xfe, 0x01, 0x01, "Device Firmware Upgrade"],
|
105
|
+
[0xfe, 0x02, 0x00, "IRDA Bridge"],
|
106
|
+
[0xfe, 0x03, 0x00, "USB Test and Measurement"],
|
107
|
+
[0xfe, 0x03, 0x01, "USB Test and Measurement (USBTMC USB488)"],
|
108
|
+
[0xfe, nil, nil, "Application Specific"],
|
109
|
+
[0xff, nil, nil, "Vendor specific"],
|
110
|
+
]
|
111
|
+
# @private
|
112
|
+
CLASS_CODES_HASH1 = {}
|
113
|
+
# @private
|
114
|
+
CLASS_CODES_HASH2 = {}
|
115
|
+
# @private
|
116
|
+
CLASS_CODES_HASH3 = {}
|
117
|
+
CLASS_CODES.each {|base_class, sub_class, protocol, desc|
|
118
|
+
if protocol
|
119
|
+
CLASS_CODES_HASH3[[base_class, sub_class, protocol]] = desc
|
120
|
+
elsif sub_class
|
121
|
+
CLASS_CODES_HASH2[[base_class, sub_class]] = desc
|
122
|
+
else
|
123
|
+
CLASS_CODES_HASH1[base_class] = desc
|
124
|
+
end
|
125
|
+
}
|
126
|
+
|
127
|
+
def self.dev_string(base_class, sub_class, protocol)
|
128
|
+
if desc = CLASS_CODES_HASH3[[base_class, sub_class, protocol]]
|
129
|
+
desc
|
130
|
+
elsif desc = CLASS_CODES_HASH2[[base_class, sub_class]]
|
131
|
+
desc + " (%02x)" % [protocol]
|
132
|
+
elsif desc = CLASS_CODES_HASH1[base_class]
|
133
|
+
desc + " (%02x,%02x)" % [sub_class, protocol]
|
134
|
+
else
|
135
|
+
"Unkonwn(%02x,%02x,%02x)" % [base_class, sub_class, protocol]
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|