libusb 0.3.3-x64-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.
- checksums.yaml +7 -0
- data/.gitignore +8 -0
- data/.travis.yml +10 -0
- data/.yardopts +6 -0
- data/COPYING +165 -0
- data/Gemfile +16 -0
- data/History.md +77 -0
- data/README.md +144 -0
- data/Rakefile +185 -0
- data/lib/libusb.rb +51 -0
- data/lib/libusb/call.rb +316 -0
- data/lib/libusb/compat.rb +376 -0
- data/lib/libusb/configuration.rb +155 -0
- data/lib/libusb/constants.rb +151 -0
- data/lib/libusb/context.rb +305 -0
- data/lib/libusb/dev_handle.rb +450 -0
- data/lib/libusb/device.rb +359 -0
- data/lib/libusb/endpoint.rb +174 -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/transfer.rb +282 -0
- data/lib/libusb/version_gem.rb +19 -0
- data/lib/libusb/version_struct.rb +63 -0
- data/libusb.gemspec +31 -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 +181 -0
- data/test/test_libusb_event_machine.rb +118 -0
- data/test/test_libusb_gc.rb +37 -0
- data/test/test_libusb_iso_transfer.rb +50 -0
- data/test/test_libusb_mass_storage.rb +278 -0
- data/test/test_libusb_mass_storage2.rb +73 -0
- data/test/test_libusb_structs.rb +45 -0
- data/test/test_libusb_threads.rb +89 -0
- data/test/test_libusb_version.rb +40 -0
- metadata +126 -0
@@ -0,0 +1,174 @@
|
|
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 Endpoint < FFI::Struct
|
20
|
+
include Comparable
|
21
|
+
|
22
|
+
layout :bLength, :uint8,
|
23
|
+
:bDescriptorType, :uint8,
|
24
|
+
:bEndpointAddress, :uint8,
|
25
|
+
:bmAttributes, :uint8,
|
26
|
+
:wMaxPacketSize, :uint16,
|
27
|
+
:bInterval, :uint8,
|
28
|
+
:bRefresh, :uint8,
|
29
|
+
:bSynchAddress, :uint8,
|
30
|
+
:extra, :pointer,
|
31
|
+
:extra_length, :int
|
32
|
+
|
33
|
+
# Size of Descriptor in Bytes (7 bytes)
|
34
|
+
def bLength
|
35
|
+
self[:bLength]
|
36
|
+
end
|
37
|
+
|
38
|
+
# Descriptor type (0x05)
|
39
|
+
def bDescriptorType
|
40
|
+
self[:bDescriptorType]
|
41
|
+
end
|
42
|
+
|
43
|
+
# The address of the endpoint described by this descriptor.
|
44
|
+
#
|
45
|
+
# * Bits 0..3: Endpoint Number.
|
46
|
+
# * Bits 4..6: Reserved. Set to Zero
|
47
|
+
# * Bits 7: Direction 0 = Out, 1 = In (Ignored for Control Endpoints)
|
48
|
+
#
|
49
|
+
# @return [Integer]
|
50
|
+
#
|
51
|
+
# @see #endpoint_number
|
52
|
+
# @see #direction
|
53
|
+
def bEndpointAddress
|
54
|
+
self[:bEndpointAddress]
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [Integer]
|
58
|
+
def endpoint_number
|
59
|
+
bEndpointAddress & 0b1111
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return [Symbol] Either +:in+ or +:out+
|
63
|
+
def direction
|
64
|
+
bEndpointAddress & ENDPOINT_IN == 0 ? :out : :in
|
65
|
+
end
|
66
|
+
|
67
|
+
# Attributes which apply to the endpoint when it is configured using the {Configuration#bConfigurationValue}.
|
68
|
+
#
|
69
|
+
# * Bits 1..0: Transfer Type
|
70
|
+
# * 00 = Control
|
71
|
+
# * 01 = Isochronous
|
72
|
+
# * 10 = Bulk
|
73
|
+
# * 11 = Interrupt
|
74
|
+
# * Bits 7..2: are reserved. If Isochronous endpoint,
|
75
|
+
# * Bits 3..2: Synchronisation Type (Iso Mode)
|
76
|
+
# * 00 = No Synchonisation
|
77
|
+
# * 01 = Asynchronous
|
78
|
+
# * 10 = Adaptive
|
79
|
+
# * 11 = Synchronous
|
80
|
+
# * Bits 5..4: Usage Type (Iso Mode)
|
81
|
+
# * 00 = Data Endpoint
|
82
|
+
# * 01 = Feedback Endpoint
|
83
|
+
# * 10 = Explicit Feedback Data Endpoint
|
84
|
+
# * 11 = Reserved
|
85
|
+
#
|
86
|
+
# @return [Integer]
|
87
|
+
#
|
88
|
+
# @see #transfer_type
|
89
|
+
# @see #usage_type
|
90
|
+
# @see #synchronization_type
|
91
|
+
def bmAttributes
|
92
|
+
self[:bmAttributes]
|
93
|
+
end
|
94
|
+
|
95
|
+
TransferTypes = [:control, :isochronous, :bulk, :interrupt]
|
96
|
+
# @return [Symbol] One of {TransferTypes}
|
97
|
+
def transfer_type
|
98
|
+
TransferTypes[bmAttributes & 0b11]
|
99
|
+
end
|
100
|
+
|
101
|
+
SynchronizationTypes = [:no_synchronization, :asynchronous, :adaptive, :synchronous]
|
102
|
+
# @return [Symbol] One of {SynchronizationTypes}
|
103
|
+
def synchronization_type
|
104
|
+
return unless transfer_type == :isochronous
|
105
|
+
SynchronizationTypes[(bmAttributes & 0b1100) >> 2]
|
106
|
+
end
|
107
|
+
|
108
|
+
UsageTypes = [:data, :feedback, :implicit_feedback, :unknown]
|
109
|
+
# @return [Symbol] One of {UsageTypes}
|
110
|
+
def usage_type
|
111
|
+
return unless transfer_type == :isochronous
|
112
|
+
UsageTypes[(bmAttributes & 0b110000) >> 4]
|
113
|
+
end
|
114
|
+
|
115
|
+
# Maximum Packet Size this endpoint is capable of sending or receiving
|
116
|
+
def wMaxPacketSize
|
117
|
+
self[:wMaxPacketSize]
|
118
|
+
end
|
119
|
+
|
120
|
+
# Interval for polling endpoint data transfers. Value in frame counts.
|
121
|
+
# Ignored for Bulk & Control Endpoints. Isochronous must equal 1 and field
|
122
|
+
# may range from 1 to 255 for interrupt endpoints.
|
123
|
+
#
|
124
|
+
# The interval is respected by the kernel driver, so user mode processes
|
125
|
+
# using libusb don't need to care about it.
|
126
|
+
def bInterval
|
127
|
+
self[:bInterval]
|
128
|
+
end
|
129
|
+
|
130
|
+
# For audio devices only: the rate at which synchronization feedback is provided.
|
131
|
+
def bRefresh
|
132
|
+
self[:bRefresh]
|
133
|
+
end
|
134
|
+
|
135
|
+
# For audio devices only: the address if the synch endpoint.
|
136
|
+
def bSynchAddress
|
137
|
+
self[:bSynchAddress]
|
138
|
+
end
|
139
|
+
|
140
|
+
# Extra descriptors.
|
141
|
+
#
|
142
|
+
# @return [String]
|
143
|
+
def extra
|
144
|
+
return if self[:extra].null?
|
145
|
+
self[:extra].read_string(self[:extra_length])
|
146
|
+
end
|
147
|
+
|
148
|
+
def initialize(setting, *args)
|
149
|
+
@setting = setting
|
150
|
+
super(*args)
|
151
|
+
end
|
152
|
+
|
153
|
+
# @return [Setting] the setting this endpoint belongs to.
|
154
|
+
attr_reader :setting
|
155
|
+
|
156
|
+
def inspect
|
157
|
+
type = [transfer_type, synchronization_type, usage_type].compact
|
158
|
+
"\#<#{self.class} #{endpoint_number} #{direction} #{type.join(" ")}>"
|
159
|
+
end
|
160
|
+
|
161
|
+
# The {Device} this Endpoint belongs to.
|
162
|
+
def device() self.setting.interface.configuration.device end
|
163
|
+
# The {Configuration} this Endpoint belongs to.
|
164
|
+
def configuration() self.setting.interface.configuration end
|
165
|
+
# The {Interface} this Endpoint belongs to.
|
166
|
+
def interface() self.setting.interface end
|
167
|
+
|
168
|
+
def <=>(o)
|
169
|
+
t = setting<=>o.setting
|
170
|
+
t = bEndpointAddress<=>o.bEndpointAddress if t==0
|
171
|
+
t
|
172
|
+
end
|
173
|
+
end
|
174
|
+
end
|
@@ -0,0 +1,183 @@
|
|
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'
|
17
|
+
require 'eventmachine'
|
18
|
+
|
19
|
+
module LIBUSB
|
20
|
+
class Context
|
21
|
+
# Register libusb's file descriptors and timeouts to EventMachine.
|
22
|
+
#
|
23
|
+
# @example
|
24
|
+
# require 'libusb/eventmachine'
|
25
|
+
# context = LIBUSB::Context.new
|
26
|
+
# EventMachine.run do
|
27
|
+
# context.eventmachine_register
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# @see
|
31
|
+
# DevHandle#eventmachine_bulk_transfer
|
32
|
+
# DevHandle#eventmachine_control_transfer
|
33
|
+
# DevHandle#eventmachine_interrupt_transfer
|
34
|
+
def eventmachine_register
|
35
|
+
@eventmachine_attached_fds = {}
|
36
|
+
@eventmachine_timer = nil
|
37
|
+
|
38
|
+
pollfds = self.pollfds
|
39
|
+
if pollfds
|
40
|
+
pollfds.each do |pollfd|
|
41
|
+
eventmachine_add_pollfd(pollfd)
|
42
|
+
end
|
43
|
+
|
44
|
+
self.on_pollfd_added do |pollfd|
|
45
|
+
eventmachine_add_pollfd(pollfd)
|
46
|
+
end
|
47
|
+
|
48
|
+
self.on_pollfd_removed do |pollfd|
|
49
|
+
eventmachine_rm_pollfd(pollfd)
|
50
|
+
end
|
51
|
+
else
|
52
|
+
# Libusb pollfd API is not available on this platform.
|
53
|
+
# Use simple polling timer, instead:
|
54
|
+
EventMachine.add_periodic_timer(0.01) do
|
55
|
+
@eventmachine_timer = self.handle_events 0
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def eventmachine_unregister
|
61
|
+
@eventmachine_timer.cancel if @eventmachine_timer
|
62
|
+
@eventmachine_attached_fds.each do |fd, watcher|
|
63
|
+
watcher.detach
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
class EMPollfdHandler < EventMachine::Connection
|
68
|
+
def initialize
|
69
|
+
@callbacks = []
|
70
|
+
super
|
71
|
+
end
|
72
|
+
|
73
|
+
def on_need_handle_events(&block)
|
74
|
+
@callbacks << block
|
75
|
+
end
|
76
|
+
|
77
|
+
def need_handle_events
|
78
|
+
@callbacks.each do |cb|
|
79
|
+
cb.call
|
80
|
+
end
|
81
|
+
end
|
82
|
+
alias notify_readable need_handle_events
|
83
|
+
alias notify_writable need_handle_events
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
def eventmachine_add_pollfd(pollfd)
|
88
|
+
conn = EventMachine.watch(pollfd.io, EMPollfdHandler)
|
89
|
+
conn.notify_readable = pollfd.pollin?
|
90
|
+
conn.notify_writable = pollfd.pollout?
|
91
|
+
cb = proc do
|
92
|
+
if @eventmachine_timer
|
93
|
+
@eventmachine_timer.cancel
|
94
|
+
@eventmachine_timer = nil
|
95
|
+
end
|
96
|
+
|
97
|
+
self.handle_events 0
|
98
|
+
timeout = self.next_timeout
|
99
|
+
# puts "libusb new timeout: #{timeout.inspect}"
|
100
|
+
if timeout
|
101
|
+
@eventmachine_timer = EventMachine.add_timer(timeout, &cb)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
conn.on_need_handle_events(&cb)
|
105
|
+
|
106
|
+
@eventmachine_attached_fds[pollfd.fd] = conn
|
107
|
+
# puts "libusb pollfd added: #{pollfd.inspect}"
|
108
|
+
end
|
109
|
+
|
110
|
+
def eventmachine_rm_pollfd(pollfd)
|
111
|
+
@eventmachine_attached_fds[pollfd.fd].detach
|
112
|
+
# puts "libusb pollfd removed: #{pollfd.inspect}"
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
class DevHandle
|
117
|
+
class EMTransfer
|
118
|
+
include EM::Deferrable
|
119
|
+
|
120
|
+
def initialize(opts, dev_handle, transfer_method)
|
121
|
+
dev_handle.send(transfer_method, opts) do |res|
|
122
|
+
EM.next_tick do
|
123
|
+
if res.kind_of?(LIBUSB::Error)
|
124
|
+
fail res
|
125
|
+
else
|
126
|
+
succeed res
|
127
|
+
end
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Execute an eventmachine driven USB interrupt transfer.
|
134
|
+
#
|
135
|
+
# @see Context#eventmachine_register
|
136
|
+
# DevHandle#interrupt_transfer
|
137
|
+
def eventmachine_interrupt_transfer(opts={})
|
138
|
+
eventmachine_transfer(opts, :interrupt_transfer)
|
139
|
+
end
|
140
|
+
|
141
|
+
# Execute an eventmachine driven USB bulk transfer.
|
142
|
+
#
|
143
|
+
# @example
|
144
|
+
# tr = devh.eventmachine_bulk_transfer( :endpoint => 0x02, :dataOut => "data" )
|
145
|
+
# tr.callback do |data|
|
146
|
+
# puts "sent: #{data.inspect}"
|
147
|
+
# end
|
148
|
+
# tr.errback do |ex|
|
149
|
+
# puts "send-err: #{ex}"
|
150
|
+
# end
|
151
|
+
#
|
152
|
+
# @see Context#eventmachine_register
|
153
|
+
# DevHandle#bulk_transfer
|
154
|
+
def eventmachine_bulk_transfer(opts={})
|
155
|
+
eventmachine_transfer(opts, :bulk_transfer)
|
156
|
+
end
|
157
|
+
|
158
|
+
# Execute an eventmachine driven USB control transfer.
|
159
|
+
#
|
160
|
+
# @example
|
161
|
+
# tr = devh.eventmachine_control_transfer(
|
162
|
+
# :bmRequestType=>ENDPOINT_IN|REQUEST_TYPE_CLASS|RECIPIENT_INTERFACE,
|
163
|
+
# :bRequest=>0x01,
|
164
|
+
# :wValue=>0, :wIndex=>0, :dataIn=>1 )
|
165
|
+
# tr.callback do |data|
|
166
|
+
# puts "recved: #{data.inspect}"
|
167
|
+
# end
|
168
|
+
# tr.errback do |ex|
|
169
|
+
# puts "recv-err: #{ex}"
|
170
|
+
# end
|
171
|
+
#
|
172
|
+
# @see Context#eventmachine_register
|
173
|
+
# DevHandle#control_transfer
|
174
|
+
def eventmachine_control_transfer(opts={})
|
175
|
+
eventmachine_transfer(opts, :control_transfer)
|
176
|
+
end
|
177
|
+
|
178
|
+
private
|
179
|
+
def eventmachine_transfer(opts, method)
|
180
|
+
EMTransfer.new opts, self, method
|
181
|
+
end
|
182
|
+
end
|
183
|
+
end
|
@@ -0,0 +1,60 @@
|
|
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 Interface < FFI::Struct
|
20
|
+
include Comparable
|
21
|
+
|
22
|
+
layout :altsetting, :pointer,
|
23
|
+
:num_altsetting, :int
|
24
|
+
|
25
|
+
# Number of this interface.
|
26
|
+
def bInterfaceNumber
|
27
|
+
settings.first.bInterfaceNumber
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize(configuration, *args)
|
31
|
+
@configuration = configuration
|
32
|
+
super(*args)
|
33
|
+
end
|
34
|
+
|
35
|
+
# @return [Configuration] the configuration this interface belongs to.
|
36
|
+
attr_reader :configuration
|
37
|
+
|
38
|
+
def alt_settings
|
39
|
+
ifs = []
|
40
|
+
self[:num_altsetting].times do |i|
|
41
|
+
ifs << Setting.new(self, self[:altsetting] + i*Setting.size)
|
42
|
+
end
|
43
|
+
return ifs
|
44
|
+
end
|
45
|
+
alias settings alt_settings
|
46
|
+
|
47
|
+
def inspect
|
48
|
+
"\#<#{self.class} #{bInterfaceNumber}>"
|
49
|
+
end
|
50
|
+
|
51
|
+
# The {Device} this Interface belongs to.
|
52
|
+
def device() self.configuration.device end
|
53
|
+
# Return all endpoints of all alternative settings as Array of {Endpoint}s.
|
54
|
+
def endpoints() self.alt_settings.map {|d| d.endpoints }.flatten end
|
55
|
+
|
56
|
+
def <=>(o)
|
57
|
+
configuration<=>o.configuration
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,132 @@
|
|
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 Setting < FFI::Struct
|
20
|
+
include Comparable
|
21
|
+
|
22
|
+
layout :bLength, :uint8,
|
23
|
+
:bDescriptorType, :uint8,
|
24
|
+
:bInterfaceNumber, :uint8,
|
25
|
+
:bAlternateSetting, :uint8,
|
26
|
+
:bNumEndpoints, :uint8,
|
27
|
+
:bInterfaceClass, :uint8,
|
28
|
+
:bInterfaceSubClass, :uint8,
|
29
|
+
:bInterfaceProtocol, :uint8,
|
30
|
+
:iInterface, :uint8,
|
31
|
+
:endpoint, :pointer,
|
32
|
+
:extra, :pointer,
|
33
|
+
:extra_length, :int
|
34
|
+
|
35
|
+
# Size of this descriptor (in bytes).
|
36
|
+
def bLength
|
37
|
+
self[:bLength]
|
38
|
+
end
|
39
|
+
|
40
|
+
# Descriptor type (0x04)
|
41
|
+
def bDescriptorType
|
42
|
+
self[:bDescriptorType]
|
43
|
+
end
|
44
|
+
|
45
|
+
# Number of the interface this setting belongs to.
|
46
|
+
def bInterfaceNumber
|
47
|
+
self[:bInterfaceNumber]
|
48
|
+
end
|
49
|
+
|
50
|
+
# Value used to select this alternate setting for this interface.
|
51
|
+
def bAlternateSetting
|
52
|
+
self[:bAlternateSetting]
|
53
|
+
end
|
54
|
+
|
55
|
+
# Number of endpoints used by this interface (excluding the control endpoint).
|
56
|
+
def bNumEndpoints
|
57
|
+
self[:bNumEndpoints]
|
58
|
+
end
|
59
|
+
|
60
|
+
# USB-IF class code for this interface.
|
61
|
+
def bInterfaceClass
|
62
|
+
self[:bInterfaceClass]
|
63
|
+
end
|
64
|
+
|
65
|
+
# USB-IF subclass code for this interface, qualified by the {Setting#bInterfaceClass} value.
|
66
|
+
def bInterfaceSubClass
|
67
|
+
self[:bInterfaceSubClass]
|
68
|
+
end
|
69
|
+
|
70
|
+
# USB-IF protocol code for this interface, qualified by the {Setting#bInterfaceClass} and {Setting#bInterfaceSubClass} values.
|
71
|
+
def bInterfaceProtocol
|
72
|
+
self[:bInterfaceProtocol]
|
73
|
+
end
|
74
|
+
|
75
|
+
# Index of string descriptor describing this interface.
|
76
|
+
def iInterface
|
77
|
+
self[:iInterface]
|
78
|
+
end
|
79
|
+
|
80
|
+
# Extra descriptors.
|
81
|
+
#
|
82
|
+
# @return [String]
|
83
|
+
def extra
|
84
|
+
return if self[:extra].null?
|
85
|
+
self[:extra].read_string(self[:extra_length])
|
86
|
+
end
|
87
|
+
|
88
|
+
def initialize(interface, *args)
|
89
|
+
@interface = interface
|
90
|
+
super(*args)
|
91
|
+
end
|
92
|
+
|
93
|
+
# @return [Interface] the interface this setting belongs to.
|
94
|
+
attr_reader :interface
|
95
|
+
|
96
|
+
def endpoints
|
97
|
+
ifs = []
|
98
|
+
self[:bNumEndpoints].times do |i|
|
99
|
+
ifs << Endpoint.new(self, self[:endpoint] + i*Endpoint.size)
|
100
|
+
end
|
101
|
+
return ifs
|
102
|
+
end
|
103
|
+
|
104
|
+
def inspect
|
105
|
+
attrs = []
|
106
|
+
attrs << self.bAlternateSetting.to_s
|
107
|
+
devclass = LIBUSB.dev_string(self.bInterfaceClass, self.bInterfaceSubClass, self.bInterfaceProtocol)
|
108
|
+
attrs << devclass
|
109
|
+
desc = self.description
|
110
|
+
attrs << desc if desc != '?'
|
111
|
+
"\#<#{self.class} #{attrs.join(' ')}>"
|
112
|
+
end
|
113
|
+
|
114
|
+
# Return name of this interface as String.
|
115
|
+
def description
|
116
|
+
return @description if defined? @description
|
117
|
+
@description = device.try_string_descriptor_ascii(self.iInterface)
|
118
|
+
end
|
119
|
+
|
120
|
+
# The {Device} this Setting belongs to.
|
121
|
+
def device() self.interface.configuration.device end
|
122
|
+
# The {Configuration} this Setting belongs to.
|
123
|
+
def configuration() self.interface.configuration end
|
124
|
+
|
125
|
+
def <=>(o)
|
126
|
+
t = interface<=>o.interface
|
127
|
+
t = bInterfaceNumber<=>o.bInterfaceNumber if t==0
|
128
|
+
t = bAlternateSetting<=>o.bAlternateSetting if t==0
|
129
|
+
t
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|