Class: LIBUSB::Device
- Inherits:
-
Object
- Object
- LIBUSB::Device
- Includes:
- Comparable
- Defined in:
- lib/libusb/device.rb
Overview
Class representing a USB device detected on the system.
Devices of the system can be obtained with Context#devices .
Instance Attribute Summary collapse
-
#context ⇒ Context
readonly
The context this device belongs to.
Instance Method Summary collapse
- #<=>(o) ⇒ Object
-
#bcdDevice ⇒ Object
Device release number in binary-coded decimal.
-
#bcdUSB ⇒ Integer
USB specification release number which device complies too.
-
#bDescriptorType ⇒ Object
Device Descriptor (0x01).
-
#bDeviceClass ⇒ Object
USB-IF class code for the device (Assigned by USB Org).
-
#bDeviceProtocol ⇒ Object
USB-IF protocol code for the device, qualified by the #bDeviceClass and #bDeviceSubClass values (Assigned by USB Org).
-
#bDeviceSubClass ⇒ Object
USB-IF subclass code for the device, qualified by the #bDeviceClass value (Assigned by USB Org).
-
#bLength ⇒ Object
Size of the Descriptor in Bytes (18 bytes).
-
#bMaxPacketSize0 ⇒ Object
Maximum Packet Size for Endpoint 0.
-
#bNumConfigurations ⇒ Object
Number of Possible Configurations.
-
#bus_number ⇒ Object
Get the number of the bus that a device is connected to.
-
#config_descriptor(index) ⇒ Object
Obtain a config descriptor of the device.
-
#configurations ⇒ Array<Configuration>
Return configurations of the device.
-
#device_address ⇒ Object
Get the address of the device on the bus it is connected to.
-
#device_speed ⇒ Symbol
Get the negotiated connection speed for a device.
-
#endpoints ⇒ Array<Endpoint>
Return all endpoints of all interfaces of this device.
-
#idProduct ⇒ Object
USB-IF product ID (Assigned by Manufacturer).
-
#idVendor ⇒ Object
USB-IF vendor ID (Assigned by USB Org).
-
#iManufacturer ⇒ Object
Index of string descriptor describing manufacturer.
-
#initialize(context, pDev) ⇒ Device
constructor
A new instance of Device.
- #inspect ⇒ Object
-
#interfaces ⇒ Array<Interface>
Return all interfaces of this device.
-
#iProduct ⇒ Object
Index of string descriptor describing product.
-
#iSerialNumber ⇒ Object
Index of string descriptor containing device serial number.
-
#manufacturer ⇒ Object
Return manufacturer of the device.
-
#max_iso_packet_size(endpoint) ⇒ Fixnum
Calculate the maximum packet size which a specific endpoint is capable is sending or receiving in the duration of 1 microframe.
-
#max_packet_size(endpoint) ⇒ Fixnum
Convenience function to retrieve the wMaxPacketSize value for a particular endpoint in the active device configuration.
-
#open ⇒ DevHandle
Open the device and obtain a device handle.
-
#open_interface(interface) ⇒ Object
Open the device and claim an interface.
-
#parent ⇒ Device?
Get the the parent from the specified device [EXPERIMENTAL].
-
#port_number ⇒ Fixnum?
Get the number of the port that a device is connected to.
-
#port_numbers ⇒ Array<Fixnum>
(also: #port_path)
Get the list of all port numbers from root for the specified device.
-
#product ⇒ Object
Return product name of the device.
-
#serial_number ⇒ Object
Return serial number of the device.
-
#settings ⇒ Array<Setting>
Return all interface decriptions of this device.
- #try_string_descriptor_ascii(i) ⇒ Object
Constructor Details
#initialize(context, pDev) ⇒ Device
Returns a new instance of Device.
28 29 30 31 32 33 34 35 36 37 38 39 40 |
# File 'lib/libusb/device.rb', line 28 def initialize context, pDev @context = context def pDev.unref_device(id) Call.libusb_unref_device(self) end ObjectSpace.define_finalizer(self, pDev.method(:unref_device)) Call.libusb_ref_device(pDev) @pDev = pDev @pDevDesc = Call::DeviceDescriptor.new res = Call.libusb_get_device_descriptor(@pDev, @pDevDesc) LIBUSB.raise_error res, "in libusb_get_device_descriptor" if res!=0 end |
Instance Attribute Details
#context ⇒ Context (readonly)
Returns the context this device belongs to.
26 27 28 |
# File 'lib/libusb/device.rb', line 26 def context @context end |
Instance Method Details
#<=>(o) ⇒ Object
359 360 361 362 363 |
# File 'lib/libusb/device.rb', line 359 def <=>(o) t = bus_number<=>o.bus_number t = device_address<=>o.device_address if t==0 t end |
#bcdDevice ⇒ Object
Device release number in binary-coded decimal.
256 257 258 |
# File 'lib/libusb/device.rb', line 256 def bcdDevice @pDevDesc[:bcdDevice] end |
#bcdUSB ⇒ Integer
USB specification release number which device complies too
215 216 217 |
# File 'lib/libusb/device.rb', line 215 def bcdUSB @pDevDesc[:bcdUSB] end |
#bDescriptorType ⇒ Object
Device Descriptor (0x01)
208 209 210 |
# File 'lib/libusb/device.rb', line 208 def bDescriptorType @pDevDesc[:bDescriptorType] end |
#bDeviceClass ⇒ Object
USB-IF class code for the device (Assigned by USB Org)
-
If equal to 0x00, each interface specifies it’s own class code
-
If equal to 0xFF, the class code is vendor specified
-
Otherwise field is valid Class Code
224 225 226 |
# File 'lib/libusb/device.rb', line 224 def bDeviceClass @pDevDesc[:bDeviceClass] end |
#bDeviceProtocol ⇒ Object
USB-IF protocol code for the device, qualified by the #bDeviceClass and #bDeviceSubClass values (Assigned by USB Org)
236 237 238 |
# File 'lib/libusb/device.rb', line 236 def bDeviceProtocol @pDevDesc[:bDeviceProtocol] end |
#bDeviceSubClass ⇒ Object
USB-IF subclass code for the device, qualified by the #bDeviceClass value (Assigned by USB Org)
230 231 232 |
# File 'lib/libusb/device.rb', line 230 def bDeviceSubClass @pDevDesc[:bDeviceSubClass] end |
#bLength ⇒ Object
Size of the Descriptor in Bytes (18 bytes)
203 204 205 |
# File 'lib/libusb/device.rb', line 203 def bLength @pDevDesc[:bLength] end |
#bMaxPacketSize0 ⇒ Object
Maximum Packet Size for Endpoint 0. Valid Sizes are 8, 16, 32, 64
241 242 243 |
# File 'lib/libusb/device.rb', line 241 def bMaxPacketSize0 @pDevDesc[:bMaxPacketSize0] end |
#bNumConfigurations ⇒ Object
Number of Possible Configurations
276 277 278 |
# File 'lib/libusb/device.rb', line 276 def bNumConfigurations @pDevDesc[:bNumConfigurations] end |
#bus_number ⇒ Object
Get the number of the bus that a device is connected to.
84 85 86 |
# File 'lib/libusb/device.rb', line 84 def bus_number Call.libusb_get_bus_number(@pDev) end |
#config_descriptor(index) ⇒ Object
Obtain a config descriptor of the device.
193 194 195 196 197 198 199 200 |
# File 'lib/libusb/device.rb', line 193 def config_descriptor(index) ppConfig = FFI::MemoryPointer.new :pointer res = Call.libusb_get_config_descriptor(@pDev, index, ppConfig) LIBUSB.raise_error res, "in libusb_get_config_descriptor" if res!=0 pConfig = ppConfig.read_pointer config = Configuration.new(self, pConfig) config end |
#configurations ⇒ Array<Configuration>
Return configurations of the device.
337 338 339 340 341 342 343 344 345 346 347 |
# File 'lib/libusb/device.rb', line 337 def configurations configs = [] bNumConfigurations.times do |config_index| begin configs << config_descriptor(config_index) rescue RuntimeError # On Windows some devices don't return it's configuration. end end configs end |
#device_address ⇒ Object
Get the address of the device on the bus it is connected to.
89 90 91 |
# File 'lib/libusb/device.rb', line 89 def device_address Call.libusb_get_device_address(@pDev) end |
#device_speed ⇒ Symbol
Get the negotiated connection speed for a device. Available since libusb-1.0.9.
146 147 148 |
# File 'lib/libusb/device.rb', line 146 def device_speed Call.libusb_get_device_speed(@pDev) end |
#endpoints ⇒ Array<Endpoint>
Return all endpoints of all interfaces of this device.
357 |
# File 'lib/libusb/device.rb', line 357 def endpoints() self.settings.map {|d| d.endpoints }.flatten end |
#idProduct ⇒ Object
USB-IF product ID (Assigned by Manufacturer)
251 252 253 |
# File 'lib/libusb/device.rb', line 251 def idProduct @pDevDesc[:idProduct] end |
#idVendor ⇒ Object
USB-IF vendor ID (Assigned by USB Org)
246 247 248 |
# File 'lib/libusb/device.rb', line 246 def idVendor @pDevDesc[:idVendor] end |
#iManufacturer ⇒ Object
Index of string descriptor describing manufacturer.
261 262 263 |
# File 'lib/libusb/device.rb', line 261 def iManufacturer @pDevDesc[:iManufacturer] end |
#inspect ⇒ Object
281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 |
# File 'lib/libusb/device.rb', line 281 def inspect attrs = [] attrs << "#{self.bus_number}/#{self.device_address}" attrs << ("%04x:%04x" % [self.idVendor, self.idProduct]) attrs << self.manufacturer attrs << self.product attrs << self.serial_number if self.bDeviceClass == LIBUSB::CLASS_PER_INTERFACE devclass = self.settings.map {|i| LIBUSB.dev_string(i.bInterfaceClass, i.bInterfaceSubClass, i.bInterfaceProtocol) }.join(", ") else devclass = LIBUSB.dev_string(self.bDeviceClass, self.bDeviceSubClass, self.bDeviceProtocol) end attrs << "(#{devclass})" attrs.compact! "\#<#{self.class} #{attrs.join(' ')}>" end |
#interfaces ⇒ Array<Interface>
Return all interfaces of this device.
351 |
# File 'lib/libusb/device.rb', line 351 def interfaces() self.configurations.map {|d| d.interfaces }.flatten end |
#iProduct ⇒ Object
Index of string descriptor describing product.
266 267 268 |
# File 'lib/libusb/device.rb', line 266 def iProduct @pDevDesc[:iProduct] end |
#iSerialNumber ⇒ Object
Index of string descriptor containing device serial number.
271 272 273 |
# File 'lib/libusb/device.rb', line 271 def iSerialNumber @pDevDesc[:iSerialNumber] end |
#manufacturer ⇒ Object
Return manufacturer of the device
310 311 312 313 314 315 |
# File 'lib/libusb/device.rb', line 310 def manufacturer return @manufacturer if defined? @manufacturer @manufacturer = try_string_descriptor_ascii(self.iManufacturer) @manufacturer.strip! if @manufacturer @manufacturer end |
#max_iso_packet_size(endpoint) ⇒ Fixnum
Calculate the maximum packet size which a specific endpoint is capable is sending or receiving in the duration of 1 microframe.
Only the active configution is examined. The calculation is based on the wMaxPacketSize field in the endpoint descriptor as described in section 9.6.6 in the USB 2.0 specifications.
If acting on an isochronous or interrupt endpoint, this function will multiply the value found in bits 0:10 by the number of transactions per microframe (determined by bits 11:12). Otherwise, this function just returns the numeric value found in bits 0:10.
This function is useful for setting up isochronous transfers, for example you might use the return value from this function to call IsoPacket#alloc_buffer in order to set the length field of an isochronous packet in a transfer.
182 183 184 185 186 187 |
# File 'lib/libusb/device.rb', line 182 def max_iso_packet_size(endpoint) endpoint = endpoint.bEndpointAddress if endpoint.respond_to? :bEndpointAddress res = Call.libusb_get_max_iso_packet_size(@pDev, endpoint) LIBUSB.raise_error res, "in libusb_get_max_iso_packet_size" unless res>=0 res end |
#max_packet_size(endpoint) ⇒ Fixnum
Convenience function to retrieve the wMaxPacketSize value for a particular endpoint in the active device configuration.
156 157 158 159 160 161 |
# File 'lib/libusb/device.rb', line 156 def max_packet_size(endpoint) endpoint = endpoint.bEndpointAddress if endpoint.respond_to? :bEndpointAddress res = Call.libusb_get_max_packet_size(@pDev, endpoint) LIBUSB.raise_error res, "in libusb_get_max_packet_size" unless res>=0 res end |
#open ⇒ DevHandle
Open the device and obtain a device handle.
A handle allows you to perform I/O on the device in question. This is a non-blocking function; no requests are sent over the bus.
If called with a block, the handle is passed to the block and is closed when the block has finished.
You need proper device access:
-
Linux: read+write permissions to
/dev/bus/usb/<bus>/<dev>
-
Windows: by installing a WinUSB-driver for the device (see README )
55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/libusb/device.rb', line 55 def open ppHandle = FFI::MemoryPointer.new :pointer res = Call.libusb_open(@pDev, ppHandle) LIBUSB.raise_error res, "in libusb_open" if res!=0 handle = DevHandle.new self, ppHandle.read_pointer return handle unless block_given? begin yield handle ensure handle.close end end |
#open_interface(interface) ⇒ Object
Open the device and claim an interface.
This is a convenience method to #open and LIBUSB::DevHandle#claim_interface. Must be called with a block. When the block has finished, the interface will be released and the device will be closed.
75 76 77 78 79 80 81 |
# File 'lib/libusb/device.rb', line 75 def open_interface(interface) open do |dev| dev.claim_interface(interface) do yield dev end end end |
#parent ⇒ Device?
Get the the parent from the specified device [EXPERIMENTAL]. Available since libusb-1.0.12.
109 110 111 112 113 114 115 116 117 |
# File 'lib/libusb/device.rb', line 109 def parent pppDevs = FFI::MemoryPointer.new :pointer Call.libusb_get_device_list(@context.instance_variable_get(:@ctx), pppDevs) ppDevs = pppDevs.read_pointer pParent = Call.libusb_get_parent(@pDev) parent = pParent.null? ? nil : Device.new(@context, pParent) Call.libusb_free_device_list(ppDevs, 1) parent end |
#port_number ⇒ Fixnum?
Get the number of the port that a device is connected to. Available since libusb-1.0.12.
99 100 101 102 |
# File 'lib/libusb/device.rb', line 99 def port_number r = Call.libusb_get_port_number(@pDev) r==0 ? nil : r end |
#port_numbers ⇒ Array<Fixnum> Also known as: port_path
Get the list of all port numbers from root for the specified device. Available since libusb-1.0.12.
125 126 127 128 129 130 131 132 133 134 135 136 |
# File 'lib/libusb/device.rb', line 125 def port_numbers # As per the USB 3.0 specs, the current maximum limit for the depth is 7. path_len = 7 pPath = FFI::MemoryPointer.new :pointer, path_len l = if Call.respond_to?(:libusb_get_port_numbers) Call.libusb_get_port_numbers(@pDev, pPath, path_len) else Call.libusb_get_port_path(@context.instance_variable_get(:@ctx), @pDev, pPath, path_len) end pPath.read_array_of_uint8(l) end |
#product ⇒ Object
Return product name of the device.
319 320 321 322 323 324 |
# File 'lib/libusb/device.rb', line 319 def product return @product if defined? @product @product = try_string_descriptor_ascii(self.iProduct) @product.strip! if @product @product end |
#serial_number ⇒ Object
Return serial number of the device.
328 329 330 331 332 333 |
# File 'lib/libusb/device.rb', line 328 def serial_number return @serial_number if defined? @serial_number @serial_number = try_string_descriptor_ascii(self.iSerialNumber) @serial_number.strip! if @serial_number @serial_number end |
#settings ⇒ Array<Setting>
Return all interface decriptions of this device.
354 |
# File 'lib/libusb/device.rb', line 354 def settings() self.interfaces.map {|d| d.settings }.flatten end |
#try_string_descriptor_ascii(i) ⇒ Object
300 301 302 303 304 305 306 |
# File 'lib/libusb/device.rb', line 300 def try_string_descriptor_ascii(i) begin open{|h| h.string_descriptor_ascii(i) } rescue "?" end end |