blob: cdeedfc7f1d167a499107cfaf83c0dbe08c9ac0f [file] [log] [blame]
"""Utility class representing a CfM USB device.
This class represents actual data found by running the usb-device command.
class UsbDevice(object):
"""Utility class representing a CfM USB device."""
def __init__(self,
@param vid: Vendor ID. String.
@param pid: Product ID. String.
@param product: Product description. String
@param interfaces: List of strings.
@param bus: The bus this device is connected to. Number.
@param port: The port number as specified in /sys/bus/usb/devices/usb*.
@param level: The level in the device hierarchy this device is connected
at. A device connected directly to a port is typically at level 1.
@param parent: Optional parent UsbDevice. A parent device is a device that
this device is connected to, typically a USB Hub.
self._vid = vid
self._pid = pid
self._product = product
self._interfaces = interfaces
self._bus = bus
self._port = port
self._level = level
self._parent = parent
def vendor_id(self):
"""Returns the vendor id for this USB device."""
return self._vid
def product_id(self):
"""Returns the product id for this USB device."""
return self._pid
def vid_pid(self):
"""Return the <vendor_id>:<product_id> as a string."""
return '%s:%s' % (self._vid, self._pid)
def product(self):
"""Returns the product name."""
return self._product
def interfaces(self):
"""Returns the list of interfaces."""
return self._interfaces
def port(self):
"""Returns the port this USB device is connected to."""
return self._port
def bus(self):
"""Returns the bus this USB device is connected to."""
return self._bus
def level(self):
"""Returns the level of this USB Device."""
return self._level
def parent(self):
Returns the parent device of this device.
Or None if this is the top level device.
@returns the parent or None.
return self._parent
def parent(self, value):
Sets the parent device of this device.
We allow setting parents to make it easier to create the device tree.
@param value the new parent.
self._parent = value
def interfaces_match_spec(self, usb_device_spec):
Checks that the interfaces of this device matches those of the given spec.
@param usb_device_spec an instance of UsbDeviceSpec
@returns True or False
# List of expected interfaces. This might be a sublist of the actual
# list of interfaces. Note: we have to use lists and not sets since
# the list of interfaces might contain duplicates.
expected_interfaces = sorted(usb_device_spec.interfaces)
length = len(expected_interfaces)
actual_interfaces = sorted(self.interfaces)
return actual_interfaces[0:length] == expected_interfaces
def get_parent(self, level):
Gets the parent device at the specified level.
Devices are connected in a hierarchy. Typically like this:
Level 0: Machine's internal USB hub
+--+ Level 1: Device connected to the machine's physical ports.
+--+ Level 2: If level 1 is a Hub, this is a device connected to
that Hub.
A typical application of this method is when power cycling. Then we get a
device's parent at level 1 to locate the port that should be power cycled.
@param level the level of the parent to return.
@returns A UsbDevice instance of the parent at the specified level.
@raises ValueError if we did not find a device at the specified level.
device = self
while device != None:
if device.level < level:
raise ValueError(
'Reached lower level without finding level %d', level)
if device.level == level:
return device
device = device.parent
def __str__(self):
return "%s (%s)" % (self._product, self.vid_pid)
def __repr__(self):
return "%s (%s), bus=%s, port=%s, parent=%s" % (
self._product, self.vid_pid, self._bus, self._port, self.parent)