libusb 0.6.0-x86-linux

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.
Files changed (47) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -0
  3. data/.travis.yml +17 -0
  4. data/.yardopts +6 -0
  5. data/COPYING +165 -0
  6. data/Gemfile +11 -0
  7. data/History.md +124 -0
  8. data/README.md +159 -0
  9. data/Rakefile +145 -0
  10. data/appveyor.yml +23 -0
  11. data/lib/libusb.rb +58 -0
  12. data/lib/libusb/bos.rb +306 -0
  13. data/lib/libusb/call.rb +446 -0
  14. data/lib/libusb/compat.rb +376 -0
  15. data/lib/libusb/configuration.rb +155 -0
  16. data/lib/libusb/constants.rb +160 -0
  17. data/lib/libusb/context.rb +426 -0
  18. data/lib/libusb/dependencies.rb +7 -0
  19. data/lib/libusb/dev_handle.rb +564 -0
  20. data/lib/libusb/device.rb +365 -0
  21. data/lib/libusb/endpoint.rb +194 -0
  22. data/lib/libusb/eventmachine.rb +183 -0
  23. data/lib/libusb/interface.rb +60 -0
  24. data/lib/libusb/setting.rb +132 -0
  25. data/lib/libusb/ss_companion.rb +69 -0
  26. data/lib/libusb/stdio.rb +25 -0
  27. data/lib/libusb/transfer.rb +377 -0
  28. data/lib/libusb/version_gem.rb +19 -0
  29. data/lib/libusb/version_struct.rb +63 -0
  30. data/libusb.gemspec +30 -0
  31. data/test/test_libusb_bos.rb +118 -0
  32. data/test/test_libusb_bulk_stream_transfer.rb +50 -0
  33. data/test/test_libusb_capability.rb +23 -0
  34. data/test/test_libusb_compat.rb +78 -0
  35. data/test/test_libusb_compat_mass_storage.rb +81 -0
  36. data/test/test_libusb_descriptors.rb +212 -0
  37. data/test/test_libusb_event_machine.rb +118 -0
  38. data/test/test_libusb_gc.rb +37 -0
  39. data/test/test_libusb_hotplug.rb +127 -0
  40. data/test/test_libusb_iso_transfer.rb +50 -0
  41. data/test/test_libusb_mass_storage.rb +268 -0
  42. data/test/test_libusb_mass_storage2.rb +96 -0
  43. data/test/test_libusb_structs.rb +58 -0
  44. data/test/test_libusb_threads.rb +89 -0
  45. data/test/test_libusb_version.rb +40 -0
  46. data/wireshark-usb-sniffer.png +0 -0
  47. metadata +150 -0
@@ -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
@@ -0,0 +1,69 @@
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
+ # A structure representing the superspeed endpoint companion descriptor.
20
+ #
21
+ # This descriptor is documented in section 9.6.7 of the USB 3.0 specification. All multiple-byte fields are represented in host-endian format.
22
+ class SsCompanion < FFI::ManagedStruct
23
+ layout :bLength, :uint8,
24
+ :bDescriptorType, :uint8,
25
+ :bMaxBurst, :uint8,
26
+ :bmAttributes, :uint8,
27
+ :wBytesPerInterval, :uint16
28
+
29
+ # Size of this descriptor (in bytes)
30
+ def bLength
31
+ self[:bLength]
32
+ end
33
+
34
+ # Descriptor type.
35
+ #
36
+ # Will have value LIBUSB::DT_SS_ENDPOINT_COMPANION in this context.
37
+ def bDescriptorType
38
+ self[:bDescriptorType]
39
+ end
40
+
41
+ # The maximum number of packets the endpoint can send or recieve as part of a burst.
42
+ def bMaxBurst
43
+ self[:bMaxBurst]
44
+ end
45
+
46
+ # In bulk EP: bits 4:0 represents the maximum number of streams the EP supports.
47
+ #
48
+ # In isochronous EP: bits 1:0 represents the Mult - a zero based value that determines the maximum number of packets within a service interval
49
+ def bmAttributes
50
+ self[:bmAttributes]
51
+ end
52
+
53
+ # The total number of bytes this EP will transfer every service interval.
54
+ #
55
+ # valid only for periodic EPs.
56
+ def wBytesPerInterval
57
+ self[:wBytesPerInterval]
58
+ end
59
+
60
+ def inspect
61
+ "\#<#{self.class} burst: #{bMaxBurst} attrs: #{bmAttributes}>"
62
+ end
63
+
64
+ # @private
65
+ def self.release(ptr)
66
+ Call.libusb_free_ss_endpoint_companion_descriptor(ptr)
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,25 @@
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
+ module Stdio
21
+ extend FFI::Library
22
+ ffi_lib FFI::Platform::LIBC
23
+ attach_function :free, [ :pointer ], :void
24
+ end
25
+ end