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_alt_packet_size(interface, alternate_setting, endpoint) ⇒ Fixnum
Calculate the maximum packet size which a specific endpoint is capable of sending or receiving in the duration of 1 microframe.
-
#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.
29 30 31 32 33 34 35 36 37 38 |
# File 'lib/libusb/device.rb', line 29 def initialize context, pDev @context = context @pDev = pDev register_context(context.instance_variable_get(:@ctx), :libusb_unref_device) Call.libusb_ref_device(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.
27 28 29 |
# File 'lib/libusb/device.rb', line 27 def context @context end |
Instance Method Details
#<=>(o) ⇒ Object
401 402 403 404 405 |
# File 'lib/libusb/device.rb', line 401 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.
298 299 300 |
# File 'lib/libusb/device.rb', line 298 def bcdDevice @pDevDesc[:bcdDevice] end |
#bcdUSB ⇒ Integer
USB specification release number which device complies too
257 258 259 |
# File 'lib/libusb/device.rb', line 257 def bcdUSB @pDevDesc[:bcdUSB] end |
#bDescriptorType ⇒ Object
Device Descriptor (0x01)
250 251 252 |
# File 'lib/libusb/device.rb', line 250 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
266 267 268 |
# File 'lib/libusb/device.rb', line 266 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)
278 279 280 |
# File 'lib/libusb/device.rb', line 278 def bDeviceProtocol @pDevDesc[:bDeviceProtocol] end |
#bDeviceSubClass ⇒ Object
USB-IF subclass code for the device, qualified by the #bDeviceClass value (Assigned by USB Org)
272 273 274 |
# File 'lib/libusb/device.rb', line 272 def bDeviceSubClass @pDevDesc[:bDeviceSubClass] end |
#bLength ⇒ Object
Size of the Descriptor in Bytes (18 bytes)
245 246 247 |
# File 'lib/libusb/device.rb', line 245 def bLength @pDevDesc[:bLength] end |
#bMaxPacketSize0 ⇒ Object
Maximum Packet Size for Endpoint 0. Valid Sizes are 8, 16, 32, 64
283 284 285 |
# File 'lib/libusb/device.rb', line 283 def bMaxPacketSize0 @pDevDesc[:bMaxPacketSize0] end |
#bNumConfigurations ⇒ Object
Number of Possible Configurations
318 319 320 |
# File 'lib/libusb/device.rb', line 318 def bNumConfigurations @pDevDesc[:bNumConfigurations] end |
#bus_number ⇒ Object
Get the number of the bus that a device is connected to.
87 88 89 |
# File 'lib/libusb/device.rb', line 87 def bus_number Call.libusb_get_bus_number(@pDev) end |
#config_descriptor(index) ⇒ Object
Obtain a config descriptor of the device.
235 236 237 238 239 240 241 242 |
# File 'lib/libusb/device.rb', line 235 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.
379 380 381 382 383 384 385 386 387 388 389 |
# File 'lib/libusb/device.rb', line 379 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.
92 93 94 |
# File 'lib/libusb/device.rb', line 92 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.
149 150 151 |
# File 'lib/libusb/device.rb', line 149 def device_speed Call.libusb_get_device_speed(@pDev) end |
#endpoints ⇒ Array<Endpoint>
Return all endpoints of all interfaces of this device.
399 |
# File 'lib/libusb/device.rb', line 399 def endpoints() self.settings.map {|d| d.endpoints }.flatten end |
#idProduct ⇒ Object
USB-IF product ID (Assigned by Manufacturer)
293 294 295 |
# File 'lib/libusb/device.rb', line 293 def idProduct @pDevDesc[:idProduct] end |
#idVendor ⇒ Object
USB-IF vendor ID (Assigned by USB Org)
288 289 290 |
# File 'lib/libusb/device.rb', line 288 def idVendor @pDevDesc[:idVendor] end |
#iManufacturer ⇒ Object
Index of string descriptor describing manufacturer.
303 304 305 |
# File 'lib/libusb/device.rb', line 303 def iManufacturer @pDevDesc[:iManufacturer] end |
#inspect ⇒ Object
323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 |
# File 'lib/libusb/device.rb', line 323 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.
393 |
# File 'lib/libusb/device.rb', line 393 def interfaces() self.configurations.map {|d| d.interfaces }.flatten end |
#iProduct ⇒ Object
Index of string descriptor describing product.
308 309 310 |
# File 'lib/libusb/device.rb', line 308 def iProduct @pDevDesc[:iProduct] end |
#iSerialNumber ⇒ Object
Index of string descriptor containing device serial number.
313 314 315 |
# File 'lib/libusb/device.rb', line 313 def iSerialNumber @pDevDesc[:iSerialNumber] end |
#manufacturer ⇒ Object
Return manufacturer of the device
352 353 354 355 356 357 |
# File 'lib/libusb/device.rb', line 352 def manufacturer return @manufacturer if defined? @manufacturer @manufacturer = try_string_descriptor_ascii(self.iManufacturer) @manufacturer = @manufacturer.strip if @manufacturer @manufacturer end |
#max_alt_packet_size(interface, alternate_setting, endpoint) ⇒ Fixnum
Calculate the maximum packet size which a specific endpoint is capable of sending or receiving in the duration of 1 microframe
Only the active configuration 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. For USB 3.0 device, it will attempts to retrieve the Endpoint Companion Descriptor to return wBytesPerInterval.
This function is useful for setting up isochronous transfers, for example you might pass the return value from this function to IsochronousTransfer.packet_lengths=
in order to set the length field of every isochronous packet in a transfer.
Available since libusb-1.0.27.
194 195 196 197 198 199 200 201 |
# File 'lib/libusb/device.rb', line 194 def max_alt_packet_size(interface, alternate_setting, endpoint) interface = interface.bInterfaceNumber if interface.respond_to? :bInterfaceNumber alternate_setting = alternate_setting.bAlternateSetting if alternate_setting.respond_to? :bAlternateSetting endpoint = endpoint.bEndpointAddress if endpoint.respond_to? :bEndpointAddress res = Call.libusb_get_max_alt_packet_size(@pDev, interface, alternate_setting, endpoint) LIBUSB.raise_error res, "in libusb_get_max_alt_packet_size" unless res>=0 res 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.
224 225 226 227 228 229 |
# File 'lib/libusb/device.rb', line 224 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.
159 160 161 162 163 164 |
# File 'lib/libusb/device.rb', line 159 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 )
58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/libusb/device.rb', line 58 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.
78 79 80 81 82 83 84 |
# File 'lib/libusb/device.rb', line 78 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.
112 113 114 115 116 117 118 119 120 |
# File 'lib/libusb/device.rb', line 112 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.
102 103 104 105 |
# File 'lib/libusb/device.rb', line 102 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.
128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/libusb/device.rb', line 128 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.
361 362 363 364 365 366 |
# File 'lib/libusb/device.rb', line 361 def product return @product if defined? @product @product = try_string_descriptor_ascii(self.iProduct) @product = @product.strip if @product @product end |
#serial_number ⇒ Object
Return serial number of the device.
370 371 372 373 374 375 |
# File 'lib/libusb/device.rb', line 370 def serial_number return @serial_number if defined? @serial_number @serial_number = try_string_descriptor_ascii(self.iSerialNumber) @serial_number = @serial_number.strip if @serial_number @serial_number end |
#settings ⇒ Array<Setting>
Return all interface decriptions of this device.
396 |
# File 'lib/libusb/device.rb', line 396 def settings() self.interfaces.map {|d| d.settings }.flatten end |
#try_string_descriptor_ascii(i) ⇒ Object
342 343 344 345 346 347 348 |
# File 'lib/libusb/device.rb', line 342 def try_string_descriptor_ascii(i) begin open{|h| h.string_descriptor_ascii(i) } rescue "?" end end |