usb-ruby 0.1.0
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.
- checksums.yaml +7 -0
- data/LICENSE.txt +21 -0
- data/README.md +52 -0
- data/Rakefile +8 -0
- data/lib/usb/bos_descriptor.rb +54 -0
- data/lib/usb/bos_dev_capability.rb +48 -0
- data/lib/usb/config_descriptor.rb +94 -0
- data/lib/usb/constants.rb +129 -0
- data/lib/usb/container_id.rb +43 -0
- data/lib/usb/context.rb +148 -0
- data/lib/usb/device.rb +134 -0
- data/lib/usb/device_descriptor.rb +61 -0
- data/lib/usb/device_handle.rb +246 -0
- data/lib/usb/endpoint_descriptor.rb +91 -0
- data/lib/usb/error.rb +94 -0
- data/lib/usb/event_handling.rb +149 -0
- data/lib/usb/ffi_bindings.rb +319 -0
- data/lib/usb/hotplug.rb +47 -0
- data/lib/usb/interface.rb +31 -0
- data/lib/usb/interface_descriptor.rb +65 -0
- data/lib/usb/iso_packet.rb +26 -0
- data/lib/usb/pollfds.rb +33 -0
- data/lib/usb/ss_device_capability.rb +59 -0
- data/lib/usb/ss_endpoint_companion.rb +51 -0
- data/lib/usb/transfer.rb +201 -0
- data/lib/usb/usb20_extension.rb +47 -0
- data/lib/usb/version.rb +5 -0
- data/lib/usb.rb +49 -0
- metadata +83 -0
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module USB
|
|
4
|
+
class SSDeviceCapability
|
|
5
|
+
def self.finalizer(ptr)
|
|
6
|
+
proc do
|
|
7
|
+
FFIBindings.libusb_free_ss_usb_device_capability_descriptor(ptr) unless ptr.nil? || ptr.null?
|
|
8
|
+
rescue StandardError
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def initialize(ptr)
|
|
13
|
+
raise ArgumentError, "SS device capability pointer is required" if ptr.nil? || ptr.null?
|
|
14
|
+
|
|
15
|
+
@ptr = ptr
|
|
16
|
+
@struct = FFIBindings::SSDeviceCapabilityStruct.new(@ptr)
|
|
17
|
+
ObjectSpace.define_finalizer(self, self.class.finalizer(@ptr))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def attributes
|
|
21
|
+
@struct[:bmAttributes]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def speed_supported
|
|
25
|
+
@struct[:wSpeedSupported]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def functionality_support
|
|
29
|
+
@struct[:bFunctionalitySupport]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def u1_dev_exit_lat
|
|
33
|
+
@struct[:bU1DevExitLat]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def u2_dev_exit_lat
|
|
37
|
+
@struct[:bU2DevExitLat]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def close
|
|
41
|
+
return if @ptr.nil? || @ptr.null?
|
|
42
|
+
|
|
43
|
+
ObjectSpace.undefine_finalizer(self)
|
|
44
|
+
FFIBindings.libusb_free_ss_usb_device_capability_descriptor(@ptr)
|
|
45
|
+
@ptr = FFI::Pointer::NULL
|
|
46
|
+
@struct = nil
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
alias free close
|
|
50
|
+
|
|
51
|
+
def to_ptr
|
|
52
|
+
@ptr
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
def inspect
|
|
56
|
+
"#<USB::SSDeviceCapability speed_supported=0x#{speed_supported.to_s(16)}>"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module USB
|
|
4
|
+
class SSEndpointCompanion
|
|
5
|
+
def self.finalizer(ptr)
|
|
6
|
+
proc do
|
|
7
|
+
FFIBindings.libusb_free_ss_endpoint_companion_descriptor(ptr) unless ptr.nil? || ptr.null?
|
|
8
|
+
rescue StandardError
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def initialize(ptr)
|
|
13
|
+
raise ArgumentError, "SS endpoint companion pointer is required" if ptr.nil? || ptr.null?
|
|
14
|
+
|
|
15
|
+
@ptr = ptr
|
|
16
|
+
@struct = FFIBindings::SSEndpointCompanionStruct.new(@ptr)
|
|
17
|
+
ObjectSpace.define_finalizer(self, self.class.finalizer(@ptr))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def max_burst
|
|
21
|
+
@struct[:bMaxBurst]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def attributes
|
|
25
|
+
@struct[:bmAttributes]
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def bytes_per_interval
|
|
29
|
+
@struct[:wBytesPerInterval]
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def close
|
|
33
|
+
return if @ptr.nil? || @ptr.null?
|
|
34
|
+
|
|
35
|
+
ObjectSpace.undefine_finalizer(self)
|
|
36
|
+
FFIBindings.libusb_free_ss_endpoint_companion_descriptor(@ptr)
|
|
37
|
+
@ptr = FFI::Pointer::NULL
|
|
38
|
+
@struct = nil
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
alias free close
|
|
42
|
+
|
|
43
|
+
def to_ptr
|
|
44
|
+
@ptr
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def inspect
|
|
48
|
+
"#<USB::SSEndpointCompanion max_burst=#{max_burst} bytes_per_interval=#{bytes_per_interval}>"
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
data/lib/usb/transfer.rb
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module USB
|
|
4
|
+
class Transfer
|
|
5
|
+
CALLBACK = FFI::Function.new(:void, [:pointer]) do |transfer_ptr|
|
|
6
|
+
transfer = from_pointer(transfer_ptr)
|
|
7
|
+
transfer&.send(:invoke_callback)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
class << self
|
|
11
|
+
def registry
|
|
12
|
+
@registry ||= {}
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def from_pointer(ptr)
|
|
16
|
+
registry[ptr.address]
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def control(handle:, bm_request_type:, b_request:, w_value:, w_index:, data_or_length:, timeout: 1000)
|
|
20
|
+
data =
|
|
21
|
+
if data_or_length.is_a?(Integer)
|
|
22
|
+
"\x00".b * data_or_length
|
|
23
|
+
else
|
|
24
|
+
data_or_length.to_s.b
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
setup = [bm_request_type, b_request, w_value, w_index, data.bytesize].pack("CCvvv")
|
|
28
|
+
transfer = new
|
|
29
|
+
transfer.dev_handle = handle
|
|
30
|
+
transfer.type = TRANSFER_TYPE_CONTROL
|
|
31
|
+
transfer.timeout = timeout
|
|
32
|
+
transfer.buffer = setup + data
|
|
33
|
+
transfer
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def bulk(handle:, endpoint:, data:, timeout: 1000)
|
|
37
|
+
transfer = new
|
|
38
|
+
transfer.dev_handle = handle
|
|
39
|
+
transfer.endpoint = endpoint
|
|
40
|
+
transfer.type = TRANSFER_TYPE_BULK
|
|
41
|
+
transfer.timeout = timeout
|
|
42
|
+
transfer.buffer = data
|
|
43
|
+
transfer
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def interrupt(handle:, endpoint:, data:, timeout: 1000)
|
|
47
|
+
transfer = new
|
|
48
|
+
transfer.dev_handle = handle
|
|
49
|
+
transfer.endpoint = endpoint
|
|
50
|
+
transfer.type = TRANSFER_TYPE_INTERRUPT
|
|
51
|
+
transfer.timeout = timeout
|
|
52
|
+
transfer.buffer = data
|
|
53
|
+
transfer
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
def isochronous(handle:, endpoint:, data:, num_iso_packets:, timeout: 1000)
|
|
57
|
+
transfer = new(num_iso_packets: num_iso_packets)
|
|
58
|
+
transfer.dev_handle = handle
|
|
59
|
+
transfer.endpoint = endpoint
|
|
60
|
+
transfer.type = TRANSFER_TYPE_ISOCHRONOUS
|
|
61
|
+
transfer.timeout = timeout
|
|
62
|
+
transfer.buffer = data
|
|
63
|
+
transfer
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
def finalizer(ptr)
|
|
67
|
+
proc do
|
|
68
|
+
FFIBindings.libusb_free_transfer(ptr) unless ptr.nil? || ptr.null?
|
|
69
|
+
rescue StandardError
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def initialize(num_iso_packets: 0)
|
|
75
|
+
FFIBindings.ensure_loaded!
|
|
76
|
+
@ptr = FFIBindings.libusb_alloc_transfer(num_iso_packets)
|
|
77
|
+
raise Error, "libusb_alloc_transfer returned null" if @ptr.null?
|
|
78
|
+
|
|
79
|
+
@struct = FFIBindings::TransferStruct.new(@ptr)
|
|
80
|
+
@struct[:callback] = CALLBACK
|
|
81
|
+
@struct[:user_data] = FFI::Pointer::NULL
|
|
82
|
+
@callback = nil
|
|
83
|
+
@buffer = nil
|
|
84
|
+
ObjectSpace.define_finalizer(self, self.class.finalizer(@ptr))
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def free
|
|
88
|
+
return if @ptr.nil? || @ptr.null?
|
|
89
|
+
|
|
90
|
+
ObjectSpace.undefine_finalizer(self)
|
|
91
|
+
self.class.registry.delete(@ptr.address)
|
|
92
|
+
FFIBindings.libusb_free_transfer(@ptr)
|
|
93
|
+
@ptr = FFI::Pointer::NULL
|
|
94
|
+
@struct = nil
|
|
95
|
+
@buffer = nil
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def dev_handle=(handle)
|
|
99
|
+
@struct[:dev_handle] = handle.is_a?(DeviceHandle) ? handle.to_ptr : handle
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def endpoint=(endpoint)
|
|
103
|
+
@struct[:endpoint] = endpoint
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def type=(transfer_type)
|
|
107
|
+
@struct[:type] = transfer_type
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def timeout=(milliseconds)
|
|
111
|
+
@struct[:timeout] = milliseconds
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def buffer=(data)
|
|
115
|
+
bytes = data.to_s.b
|
|
116
|
+
@buffer = FFI::MemoryPointer.new(:uint8, [bytes.bytesize, 1].max)
|
|
117
|
+
@buffer.put_bytes(0, bytes) unless bytes.empty?
|
|
118
|
+
@struct[:buffer] = @buffer
|
|
119
|
+
@struct[:length] = bytes.bytesize
|
|
120
|
+
end
|
|
121
|
+
|
|
122
|
+
def flags
|
|
123
|
+
@struct[:flags]
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def flags=(value)
|
|
127
|
+
@struct[:flags] = value
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def status
|
|
131
|
+
@struct[:status]
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def actual_length
|
|
135
|
+
@struct[:actual_length]
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def submit
|
|
139
|
+
free_transfer = (flags & TRANSFER_FREE_TRANSFER) != 0
|
|
140
|
+
self.class.registry[@ptr.address] = self
|
|
141
|
+
Error.raise_on_error(FFIBindings.libusb_submit_transfer(@ptr))
|
|
142
|
+
ObjectSpace.undefine_finalizer(self) if free_transfer
|
|
143
|
+
self
|
|
144
|
+
rescue StandardError
|
|
145
|
+
self.class.registry.delete(@ptr.address)
|
|
146
|
+
raise
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
def cancel
|
|
150
|
+
Error.raise_on_error(FFIBindings.libusb_cancel_transfer(@ptr))
|
|
151
|
+
self
|
|
152
|
+
end
|
|
153
|
+
|
|
154
|
+
def on_complete(&block)
|
|
155
|
+
@callback = block
|
|
156
|
+
self
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def callback
|
|
160
|
+
@callback
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def iso_packet(index)
|
|
164
|
+
raise IndexError, "iso packet index out of bounds" if index.negative? || index >= num_iso_packets
|
|
165
|
+
|
|
166
|
+
IsoPacket.new(self, FFIBindings::IsoPacketDescriptorStruct.new(iso_packet_pointer(index)))
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
def set_iso_packet_lengths(length)
|
|
170
|
+
num_iso_packets.times do |index|
|
|
171
|
+
iso_packet(index).length = length
|
|
172
|
+
end
|
|
173
|
+
self
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
def num_iso_packets
|
|
177
|
+
@struct[:num_iso_packets]
|
|
178
|
+
end
|
|
179
|
+
|
|
180
|
+
def to_ptr
|
|
181
|
+
@ptr
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
private
|
|
185
|
+
|
|
186
|
+
def invoke_callback
|
|
187
|
+
free_transfer = !@struct.nil? && (flags & TRANSFER_FREE_TRANSFER) != 0
|
|
188
|
+
self.class.registry.delete(@ptr.address)
|
|
189
|
+
@callback&.call(self)
|
|
190
|
+
return unless free_transfer
|
|
191
|
+
|
|
192
|
+
@ptr = FFI::Pointer::NULL
|
|
193
|
+
@struct = nil
|
|
194
|
+
@buffer = nil
|
|
195
|
+
end
|
|
196
|
+
|
|
197
|
+
def iso_packet_pointer(index)
|
|
198
|
+
@ptr + FFIBindings::TransferStruct.size + (index * FFIBindings::IsoPacketDescriptorStruct.size)
|
|
199
|
+
end
|
|
200
|
+
end
|
|
201
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module USB
|
|
4
|
+
class USB20Extension
|
|
5
|
+
def self.finalizer(ptr)
|
|
6
|
+
proc do
|
|
7
|
+
FFIBindings.libusb_free_usb_2_0_extension_descriptor(ptr) unless ptr.nil? || ptr.null?
|
|
8
|
+
rescue StandardError
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def initialize(ptr)
|
|
13
|
+
raise ArgumentError, "USB 2.0 extension pointer is required" if ptr.nil? || ptr.null?
|
|
14
|
+
|
|
15
|
+
@ptr = ptr
|
|
16
|
+
@struct = FFIBindings::USB20ExtensionStruct.new(@ptr)
|
|
17
|
+
ObjectSpace.define_finalizer(self, self.class.finalizer(@ptr))
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def attributes
|
|
21
|
+
@struct[:bmAttributes]
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def supports_lpm?
|
|
25
|
+
(attributes & 0x02) != 0
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
def close
|
|
29
|
+
return if @ptr.nil? || @ptr.null?
|
|
30
|
+
|
|
31
|
+
ObjectSpace.undefine_finalizer(self)
|
|
32
|
+
FFIBindings.libusb_free_usb_2_0_extension_descriptor(@ptr)
|
|
33
|
+
@ptr = FFI::Pointer::NULL
|
|
34
|
+
@struct = nil
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
alias free close
|
|
38
|
+
|
|
39
|
+
def to_ptr
|
|
40
|
+
@ptr
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def inspect
|
|
44
|
+
"#<USB::USB20Extension attributes=0x#{attributes.to_s(16)}>"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
data/lib/usb/version.rb
ADDED
data/lib/usb.rb
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require "ffi"
|
|
4
|
+
|
|
5
|
+
require_relative "usb/version"
|
|
6
|
+
require_relative "usb/constants"
|
|
7
|
+
require_relative "usb/error"
|
|
8
|
+
require_relative "usb/ffi_bindings"
|
|
9
|
+
require_relative "usb/context"
|
|
10
|
+
require_relative "usb/device"
|
|
11
|
+
require_relative "usb/device_handle"
|
|
12
|
+
require_relative "usb/device_descriptor"
|
|
13
|
+
require_relative "usb/config_descriptor"
|
|
14
|
+
require_relative "usb/interface"
|
|
15
|
+
require_relative "usb/interface_descriptor"
|
|
16
|
+
require_relative "usb/endpoint_descriptor"
|
|
17
|
+
require_relative "usb/ss_endpoint_companion"
|
|
18
|
+
require_relative "usb/bos_descriptor"
|
|
19
|
+
require_relative "usb/bos_dev_capability"
|
|
20
|
+
require_relative "usb/usb20_extension"
|
|
21
|
+
require_relative "usb/ss_device_capability"
|
|
22
|
+
require_relative "usb/container_id"
|
|
23
|
+
require_relative "usb/transfer"
|
|
24
|
+
require_relative "usb/iso_packet"
|
|
25
|
+
require_relative "usb/hotplug"
|
|
26
|
+
require_relative "usb/event_handling"
|
|
27
|
+
require_relative "usb/pollfds"
|
|
28
|
+
|
|
29
|
+
module USB
|
|
30
|
+
class << self
|
|
31
|
+
def version
|
|
32
|
+
FFIBindings.ensure_loaded!
|
|
33
|
+
ptr = FFIBindings.libusb_get_version
|
|
34
|
+
return nil if ptr.null?
|
|
35
|
+
|
|
36
|
+
version = FFIBindings::VersionStruct.new(ptr)
|
|
37
|
+
"#{version[:major]}.#{version[:minor]}.#{version[:micro]}"
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def has_capability?(capability)
|
|
41
|
+
FFIBindings.ensure_loaded!
|
|
42
|
+
FFIBindings.libusb_has_capability(capability) != 0
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def devices(**filters)
|
|
46
|
+
Context.open { |context| context.devices(**filters) }
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: usb-ruby
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Yudai Takada
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: ffi
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '1.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '1.0'
|
|
26
|
+
description: usb-ruby provides idiomatic Ruby access to libusb 1.0 via FFI without
|
|
27
|
+
native extensions.
|
|
28
|
+
email:
|
|
29
|
+
- t.yudai92@gmail.com
|
|
30
|
+
executables: []
|
|
31
|
+
extensions: []
|
|
32
|
+
extra_rdoc_files: []
|
|
33
|
+
files:
|
|
34
|
+
- LICENSE.txt
|
|
35
|
+
- README.md
|
|
36
|
+
- Rakefile
|
|
37
|
+
- lib/usb.rb
|
|
38
|
+
- lib/usb/bos_descriptor.rb
|
|
39
|
+
- lib/usb/bos_dev_capability.rb
|
|
40
|
+
- lib/usb/config_descriptor.rb
|
|
41
|
+
- lib/usb/constants.rb
|
|
42
|
+
- lib/usb/container_id.rb
|
|
43
|
+
- lib/usb/context.rb
|
|
44
|
+
- lib/usb/device.rb
|
|
45
|
+
- lib/usb/device_descriptor.rb
|
|
46
|
+
- lib/usb/device_handle.rb
|
|
47
|
+
- lib/usb/endpoint_descriptor.rb
|
|
48
|
+
- lib/usb/error.rb
|
|
49
|
+
- lib/usb/event_handling.rb
|
|
50
|
+
- lib/usb/ffi_bindings.rb
|
|
51
|
+
- lib/usb/hotplug.rb
|
|
52
|
+
- lib/usb/interface.rb
|
|
53
|
+
- lib/usb/interface_descriptor.rb
|
|
54
|
+
- lib/usb/iso_packet.rb
|
|
55
|
+
- lib/usb/pollfds.rb
|
|
56
|
+
- lib/usb/ss_device_capability.rb
|
|
57
|
+
- lib/usb/ss_endpoint_companion.rb
|
|
58
|
+
- lib/usb/transfer.rb
|
|
59
|
+
- lib/usb/usb20_extension.rb
|
|
60
|
+
- lib/usb/version.rb
|
|
61
|
+
homepage: https://github.com/ydah/usb-ruby
|
|
62
|
+
licenses:
|
|
63
|
+
- MIT
|
|
64
|
+
metadata:
|
|
65
|
+
source_code_uri: https://github.com/ydah/usb-ruby
|
|
66
|
+
rdoc_options: []
|
|
67
|
+
require_paths:
|
|
68
|
+
- lib
|
|
69
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
70
|
+
requirements:
|
|
71
|
+
- - ">="
|
|
72
|
+
- !ruby/object:Gem::Version
|
|
73
|
+
version: '3.0'
|
|
74
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
75
|
+
requirements:
|
|
76
|
+
- - ">="
|
|
77
|
+
- !ruby/object:Gem::Version
|
|
78
|
+
version: '0'
|
|
79
|
+
requirements: []
|
|
80
|
+
rubygems_version: 4.0.6
|
|
81
|
+
specification_version: 4
|
|
82
|
+
summary: Ruby FFI bindings for libusb 1.0
|
|
83
|
+
test_files: []
|