libusb 0.2.2 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +8 -0
- data/.travis.yml +10 -0
- data/.yardopts +6 -1
- data/Gemfile +16 -0
- data/{History.txt → History.md} +28 -16
- data/README.md +144 -0
- data/Rakefile +28 -24
- data/ext/extconf.rb +33 -0
- data/ext/libusbx-1.0.14/AUTHORS +50 -0
- data/ext/libusbx-1.0.14/COPYING +504 -0
- data/ext/libusbx-1.0.14/ChangeLog +139 -0
- data/ext/libusbx-1.0.14/INSTALL +234 -0
- data/ext/libusbx-1.0.14/Makefile.am +23 -0
- data/ext/libusbx-1.0.14/Makefile.in +803 -0
- data/ext/libusbx-1.0.14/NEWS +2 -0
- data/ext/libusbx-1.0.14/PORTING +94 -0
- data/ext/libusbx-1.0.14/README +28 -0
- data/ext/libusbx-1.0.14/THANKS +7 -0
- data/ext/libusbx-1.0.14/TODO +2 -0
- data/ext/libusbx-1.0.14/aclocal.m4 +9480 -0
- data/ext/libusbx-1.0.14/compile +143 -0
- data/ext/libusbx-1.0.14/config.guess +1501 -0
- data/ext/libusbx-1.0.14/config.h.in +116 -0
- data/ext/libusbx-1.0.14/config.sub +1705 -0
- data/ext/libusbx-1.0.14/configure +14818 -0
- data/ext/libusbx-1.0.14/configure.ac +230 -0
- data/ext/libusbx-1.0.14/depcomp +630 -0
- data/ext/libusbx-1.0.14/doc/Makefile.am +9 -0
- data/ext/libusbx-1.0.14/doc/Makefile.in +380 -0
- data/ext/libusbx-1.0.14/doc/doxygen.cfg.in +1288 -0
- data/ext/libusbx-1.0.14/examples/Makefile.am +18 -0
- data/ext/libusbx-1.0.14/examples/Makefile.in +596 -0
- data/ext/libusbx-1.0.14/examples/dpfp.c +506 -0
- data/ext/libusbx-1.0.14/examples/dpfp_threaded.c +544 -0
- data/ext/libusbx-1.0.14/examples/ezusb.c +616 -0
- data/ext/libusbx-1.0.14/examples/ezusb.h +107 -0
- data/ext/libusbx-1.0.14/examples/fxload.c +261 -0
- data/ext/libusbx-1.0.14/examples/getopt/getopt.c +1060 -0
- data/ext/libusbx-1.0.14/examples/getopt/getopt.h +180 -0
- data/ext/libusbx-1.0.14/examples/getopt/getopt1.c +188 -0
- data/ext/libusbx-1.0.14/examples/listdevs.c +63 -0
- data/ext/libusbx-1.0.14/examples/xusb.c +1036 -0
- data/ext/libusbx-1.0.14/install-sh +520 -0
- data/ext/libusbx-1.0.14/libusb-1.0.pc.in +11 -0
- data/ext/libusbx-1.0.14/libusb/Makefile.am +56 -0
- data/ext/libusbx-1.0.14/libusb/Makefile.in +721 -0
- data/ext/libusbx-1.0.14/libusb/core.c +1951 -0
- data/ext/libusbx-1.0.14/libusb/descriptor.c +731 -0
- data/ext/libusbx-1.0.14/libusb/io.c +2450 -0
- data/ext/libusbx-1.0.14/libusb/libusb-1.0.def +126 -0
- data/ext/libusbx-1.0.14/libusb/libusb-1.0.rc +59 -0
- data/ext/libusbx-1.0.14/libusb/libusb.h +1506 -0
- data/ext/libusbx-1.0.14/libusb/libusbi.h +910 -0
- data/ext/libusbx-1.0.14/libusb/os/darwin_usb.c +1807 -0
- data/ext/libusbx-1.0.14/libusb/os/darwin_usb.h +169 -0
- data/ext/libusbx-1.0.14/libusb/os/linux_usbfs.c +2569 -0
- data/ext/libusbx-1.0.14/libusb/os/linux_usbfs.h +149 -0
- data/ext/libusbx-1.0.14/libusb/os/openbsd_usb.c +727 -0
- data/ext/libusbx-1.0.14/libusb/os/poll_posix.h +10 -0
- data/ext/libusbx-1.0.14/libusb/os/poll_windows.c +747 -0
- data/ext/libusbx-1.0.14/libusb/os/poll_windows.h +114 -0
- data/ext/libusbx-1.0.14/libusb/os/threads_posix.c +80 -0
- data/ext/libusbx-1.0.14/libusb/os/threads_posix.h +50 -0
- data/ext/libusbx-1.0.14/libusb/os/threads_windows.c +211 -0
- data/ext/libusbx-1.0.14/libusb/os/threads_windows.h +87 -0
- data/ext/libusbx-1.0.14/libusb/os/windows_usb.c +4369 -0
- data/ext/libusbx-1.0.14/libusb/os/windows_usb.h +979 -0
- data/ext/libusbx-1.0.14/libusb/sync.c +321 -0
- data/ext/libusbx-1.0.14/libusb/version.h +18 -0
- data/ext/libusbx-1.0.14/libusb/version_nano.h +1 -0
- data/ext/libusbx-1.0.14/ltmain.sh +9636 -0
- data/ext/libusbx-1.0.14/missing +376 -0
- data/lib/libusb.rb +2 -3
- data/lib/libusb/call.rb +49 -7
- data/lib/libusb/compat.rb +15 -9
- data/lib/libusb/configuration.rb +15 -3
- data/lib/libusb/constants.rb +19 -6
- data/lib/libusb/context.rb +181 -3
- data/lib/libusb/dev_handle.rb +91 -40
- data/lib/libusb/endpoint.rb +41 -14
- data/lib/libusb/eventmachine.rb +183 -0
- data/lib/libusb/transfer.rb +21 -8
- data/lib/libusb/version_gem.rb +19 -0
- data/lib/libusb/{version.rb → version_struct.rb} +0 -0
- data/libusb.gemspec +31 -0
- data/test/test_libusb_compat.rb +1 -1
- data/test/test_libusb_compat_mass_storage.rb +2 -2
- data/test/test_libusb_descriptors.rb +1 -1
- data/test/test_libusb_event_machine.rb +118 -0
- data/test/test_libusb_iso_transfer.rb +6 -1
- data/test/test_libusb_mass_storage.rb +9 -3
- data/test/test_libusb_mass_storage2.rb +1 -1
- data/test/test_libusb_structs.rb +45 -0
- data/test/test_libusb_threads.rb +89 -0
- data/test/test_libusb_version.rb +4 -0
- metadata +109 -44
- data/.autotest +0 -23
- data/.gemtest +0 -0
- data/Manifest.txt +0 -3
- data/README.rdoc +0 -115
- data/test/test_libusb_keyboard.rb +0 -50
data/lib/libusb/endpoint.rb
CHANGED
@@ -47,18 +47,31 @@ module LIBUSB
|
|
47
47
|
# * Bits 7: Direction 0 = Out, 1 = In (Ignored for Control Endpoints)
|
48
48
|
#
|
49
49
|
# @return [Integer]
|
50
|
+
#
|
51
|
+
# @see #endpoint_number
|
52
|
+
# @see #direction
|
50
53
|
def bEndpointAddress
|
51
54
|
self[:bEndpointAddress]
|
52
55
|
end
|
53
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
|
+
|
54
67
|
# Attributes which apply to the endpoint when it is configured using the {Configuration#bConfigurationValue}.
|
55
68
|
#
|
56
|
-
# * Bits 0
|
69
|
+
# * Bits 1..0: Transfer Type
|
57
70
|
# * 00 = Control
|
58
71
|
# * 01 = Isochronous
|
59
72
|
# * 10 = Bulk
|
60
73
|
# * 11 = Interrupt
|
61
|
-
# * Bits 2
|
74
|
+
# * Bits 7..2: are reserved. If Isochronous endpoint,
|
62
75
|
# * Bits 3..2: Synchronisation Type (Iso Mode)
|
63
76
|
# * 00 = No Synchonisation
|
64
77
|
# * 01 = Asynchronous
|
@@ -71,10 +84,34 @@ module LIBUSB
|
|
71
84
|
# * 11 = Reserved
|
72
85
|
#
|
73
86
|
# @return [Integer]
|
87
|
+
#
|
88
|
+
# @see #transfer_type
|
89
|
+
# @see #usage_type
|
90
|
+
# @see #synchronization_type
|
74
91
|
def bmAttributes
|
75
92
|
self[:bmAttributes]
|
76
93
|
end
|
77
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
|
+
|
78
115
|
# Maximum Packet Size this endpoint is capable of sending or receiving
|
79
116
|
def wMaxPacketSize
|
80
117
|
self[:wMaxPacketSize]
|
@@ -117,18 +154,8 @@ module LIBUSB
|
|
117
154
|
attr_reader :setting
|
118
155
|
|
119
156
|
def inspect
|
120
|
-
|
121
|
-
|
122
|
-
inout = (endpoint_address & 0b10000000) == 0 ? "OUT" : "IN "
|
123
|
-
bits = self.bmAttributes
|
124
|
-
transfer_type = %w[Control Isochronous Bulk Interrupt][0b11 & bits]
|
125
|
-
type = [transfer_type]
|
126
|
-
if transfer_type == 'Isochronous'
|
127
|
-
synchronization_type = %w[NoSynchronization Asynchronous Adaptive Synchronous][(0b1100 & bits) >> 2]
|
128
|
-
usage_type = %w[Data Feedback ImplicitFeedback ?][(0b110000 & bits) >> 4]
|
129
|
-
type << synchronization_type << usage_type
|
130
|
-
end
|
131
|
-
"\#<#{self.class} #{num} #{inout} #{type.join(" ")}>"
|
157
|
+
type = [transfer_type, synchronization_type, usage_type].compact
|
158
|
+
"\#<#{self.class} #{endpoint_number} #{direction} #{type.join(" ")}>"
|
132
159
|
end
|
133
160
|
|
134
161
|
# The {Device} this Endpoint belongs to.
|
@@ -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
|
data/lib/libusb/transfer.rb
CHANGED
@@ -19,10 +19,16 @@ module LIBUSB
|
|
19
19
|
# Abstract base class for USB transfers. Use
|
20
20
|
# {ControlTransfer}, {BulkTransfer}, {InterruptTransfer}, {IsochronousTransfer}
|
21
21
|
# to do transfers.
|
22
|
+
#
|
23
|
+
# There are convenience methods for {DevHandle#bulk_transfer}, {DevHandle#control_transfer}
|
24
|
+
# and {DevHandle#interrupt_transfer}, that fit for most use cases.
|
25
|
+
# Using {Transfer} derived classes directly, however, is needed for isochronous transfers and
|
26
|
+
# allows a more advanced buffer management.
|
22
27
|
class Transfer
|
23
28
|
def initialize(args={})
|
24
29
|
args.each{|k,v| send("#{k}=", v) }
|
25
30
|
@buffer = nil
|
31
|
+
@completion_flag = Context::CompletionFlag.new
|
26
32
|
end
|
27
33
|
private :initialize
|
28
34
|
|
@@ -156,26 +162,33 @@ module LIBUSB
|
|
156
162
|
|
157
163
|
# Submit the transfer and wait until the transfer completes or fails.
|
158
164
|
#
|
159
|
-
#
|
160
|
-
def submit_and_wait
|
161
|
-
completed = false
|
165
|
+
# Inspect {#status} to check for transfer errors.
|
166
|
+
def submit_and_wait
|
167
|
+
@completion_flag.completed = false
|
162
168
|
submit! do |tr2|
|
163
|
-
completed = true
|
169
|
+
@completion_flag.completed = true
|
164
170
|
end
|
165
171
|
|
166
|
-
until completed
|
172
|
+
until @completion_flag.completed?
|
167
173
|
begin
|
168
|
-
@dev_handle.device.context.handle_events
|
174
|
+
@dev_handle.device.context.handle_events nil, @completion_flag
|
169
175
|
rescue ERROR_INTERRUPTED
|
170
176
|
next
|
171
177
|
rescue LIBUSB::Error
|
172
178
|
cancel!
|
173
|
-
until completed
|
174
|
-
@dev_handle.device.context.handle_events
|
179
|
+
until @completion_flag.completed?
|
180
|
+
@dev_handle.device.context.handle_events nil, @completion_flag
|
175
181
|
end
|
176
182
|
raise
|
177
183
|
end
|
178
184
|
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# Submit the transfer and wait until the transfer completes or fails.
|
188
|
+
#
|
189
|
+
# A proper {LIBUSB::Error} is raised, in case the transfer did not complete.
|
190
|
+
def submit_and_wait!
|
191
|
+
submit_and_wait
|
179
192
|
|
180
193
|
raise( TransferStatusToError[status] || ERROR_OTHER, "error #{status}") unless status==:TRANSFER_COMPLETED
|
181
194
|
end
|
@@ -0,0 +1,19 @@
|
|
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
|
+
module LIBUSB
|
17
|
+
# Library version of libusb for Ruby
|
18
|
+
VERSION = "0.3.0"
|
19
|
+
end
|
File without changes
|
data/libusb.gemspec
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "libusb/version_gem"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "libusb"
|
7
|
+
s.version = LIBUSB::VERSION
|
8
|
+
s.authors = ["Lars Kanis"]
|
9
|
+
s.email = ["lars@greiz-reinsdorf.de"]
|
10
|
+
s.homepage = "http://github.com/larskanis/libusb"
|
11
|
+
s.summary = %q{Access USB devices from Ruby via libusb-1.0}
|
12
|
+
s.description = %q{LIBUSB is a Ruby binding that gives Ruby programmers access to arbitrary USB devices}
|
13
|
+
s.rdoc_options = %w[--main README.md --charset=UTF-8]
|
14
|
+
|
15
|
+
s.rubyforge_project = "libusb"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
s.extensions = ['ext/extconf.rb']
|
22
|
+
|
23
|
+
# travis currently runs a slightly older version of rbx,
|
24
|
+
# that needs a special ffi version.
|
25
|
+
unless ENV['TRAVIS'] && defined?(RUBY_ENGINE) && RUBY_ENGINE=='rbx'
|
26
|
+
s.add_runtime_dependency 'ffi', '>= 1.0'
|
27
|
+
end
|
28
|
+
|
29
|
+
s.add_development_dependency 'rake-compiler', '>= 0.6'
|
30
|
+
s.add_development_dependency 'bundler'
|
31
|
+
end
|
data/test/test_libusb_compat.rb
CHANGED
@@ -68,7 +68,7 @@ class TestLibusbCompat < Test::Unit::TestCase
|
|
68
68
|
assert_equal config_desc, ep.configuration, "backref should be correct"
|
69
69
|
assert_equal dev, ep.device, "backref should be correct"
|
70
70
|
|
71
|
-
assert_operator 0,
|
71
|
+
assert_operator 0, :<=, ep.wMaxPacketSize, "packet size should be > 0"
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
@@ -16,7 +16,7 @@
|
|
16
16
|
require "test/unit"
|
17
17
|
require "libusb/compat"
|
18
18
|
|
19
|
-
class
|
19
|
+
class TestLibusbCompatMassStorage < Test::Unit::TestCase
|
20
20
|
include USB
|
21
21
|
|
22
22
|
attr_accessor :devh
|
@@ -30,7 +30,7 @@ class TestLibusbCompat < Test::Unit::TestCase
|
|
30
30
|
USB.each_device_by_class(USB_CLASS_MASS_STORAGE, 0x06, 0x50){|dev| devs << dev }
|
31
31
|
|
32
32
|
dev = devs.last
|
33
|
-
|
33
|
+
skip "no mass storage device found" unless dev
|
34
34
|
devh = dev.open
|
35
35
|
if RUBY_PLATFORM=~/linux/i
|
36
36
|
data = " "*1000
|
@@ -101,7 +101,7 @@ class TestLibusbDescriptors < Test::Unit::TestCase
|
|
101
101
|
assert_equal 5, ep.bDescriptorType
|
102
102
|
assert_kind_of Integer, ep.bEndpointAddress
|
103
103
|
assert_kind_of Integer, ep.bmAttributes
|
104
|
-
assert_operator 0,
|
104
|
+
assert_operator 0, :<=, ep.wMaxPacketSize, "packet size should be > 0"
|
105
105
|
assert_kind_of Integer, ep.bInterval
|
106
106
|
assert_kind_of Integer, ep.bRefresh
|
107
107
|
assert_kind_of Integer, ep.bSynchAddress
|
@@ -0,0 +1,118 @@
|
|
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 "test/unit"
|
17
|
+
require "libusb"
|
18
|
+
require "libusb/eventmachine"
|
19
|
+
require "eventmachine"
|
20
|
+
|
21
|
+
class TestLibusbEventMachine < Test::Unit::TestCase
|
22
|
+
include LIBUSB
|
23
|
+
BOMS_GET_MAX_LUN = 0xFE
|
24
|
+
|
25
|
+
attr_accessor :context
|
26
|
+
attr_accessor :device
|
27
|
+
attr_accessor :devh
|
28
|
+
attr_accessor :endpoint_in
|
29
|
+
attr_accessor :endpoint_out
|
30
|
+
|
31
|
+
def setup
|
32
|
+
@context = Context.new
|
33
|
+
@context.debug = 3
|
34
|
+
|
35
|
+
@device = context.devices( :bClass=>CLASS_MASS_STORAGE, :bSubClass=>[0x06,0x01], :bProtocol=>0x50 ).last
|
36
|
+
skip "no mass storage device found" unless @device
|
37
|
+
|
38
|
+
@endpoint_in = @device.endpoints.find{|ep| ep.bEndpointAddress&ENDPOINT_IN != 0 }
|
39
|
+
@endpoint_out = @device.endpoints.find{|ep| ep.bEndpointAddress&ENDPOINT_IN == 0 }
|
40
|
+
@devh = @device.open
|
41
|
+
|
42
|
+
if RUBY_PLATFORM=~/linux/i && devh.kernel_driver_active?(0)
|
43
|
+
devh.detach_kernel_driver(0)
|
44
|
+
end
|
45
|
+
devh.claim_interface(0)
|
46
|
+
|
47
|
+
# clear any pending data
|
48
|
+
devh.clear_halt(endpoint_in)
|
49
|
+
end
|
50
|
+
|
51
|
+
def teardown
|
52
|
+
end
|
53
|
+
|
54
|
+
def em_run
|
55
|
+
EventMachine.run do
|
56
|
+
@context.eventmachine_register
|
57
|
+
|
58
|
+
EventMachine.add_shutdown_hook do
|
59
|
+
@devh.release_interface(0) if @devh
|
60
|
+
@devh.close if @devh
|
61
|
+
@context.eventmachine_unregister
|
62
|
+
end
|
63
|
+
|
64
|
+
yield
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
def test_bulk_transfer
|
70
|
+
em_run do
|
71
|
+
ticks = 0
|
72
|
+
tr = devh.eventmachine_bulk_transfer(
|
73
|
+
:endpoint => @endpoint_in,
|
74
|
+
:timeout => 1500,
|
75
|
+
:dataIn => 123 )
|
76
|
+
# puts "started usb transfer #{tr}"
|
77
|
+
|
78
|
+
tr.callback do |data|
|
79
|
+
# puts "recved: #{data.inspect}"
|
80
|
+
|
81
|
+
assert false, "the bulk transfer shouldn't succeed"
|
82
|
+
EventMachine.stop
|
83
|
+
end
|
84
|
+
tr.errback do |text|
|
85
|
+
# puts "recv-err: #{text}"
|
86
|
+
assert true, "the bulk transfer should fail"
|
87
|
+
|
88
|
+
assert_operator ticks, :>=, 4
|
89
|
+
EventMachine.stop
|
90
|
+
end
|
91
|
+
|
92
|
+
EventMachine.add_periodic_timer(0.333) do
|
93
|
+
ticks += 1
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_event_loop
|
99
|
+
em_run do
|
100
|
+
tr = devh.eventmachine_control_transfer(
|
101
|
+
:bmRequestType=>ENDPOINT_IN|REQUEST_TYPE_CLASS|RECIPIENT_INTERFACE,
|
102
|
+
:bRequest=>BOMS_GET_MAX_LUN,
|
103
|
+
:wValue=>0, :wIndex=>0, :dataIn=>1 )
|
104
|
+
|
105
|
+
# puts "started usb transfer #{tr}"
|
106
|
+
tr.callback do |data|
|
107
|
+
# puts "recved: #{data.inspect}"
|
108
|
+
assert true, "the control transfer should succeed"
|
109
|
+
EventMachine.stop
|
110
|
+
end
|
111
|
+
tr.errback do |text|
|
112
|
+
# puts "recv-err: #{text}"
|
113
|
+
assert false, "the control transfer shouldn't fail"
|
114
|
+
EventMachine.stop
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|