astutus.usb package¶
Module contents¶
USB products are troublesome. The physical USB device that you purchase consists of various physical and logical USB components. The same physical components are used by various manufacturers to implement a large array of devices. In many, if not most cases, the physical components do not have stable, unique identifiers, such as serial numbers. Although, the cost to provide this capabilities is mere pennies in 2020, the large array of USB devices that have already been purchased will never have this feature. Instead, a more convoluted approach must be taken.
Each USB device is identified by a unique busnum and devnum while in operation. Unfortunately, the same device is likely to have a different busnum and devnum if it is unplugged and plugged into a different port, or even the same one at a later time. In addition, if a computer is rebooted, the devnum is likely to change, and the busnum may also change, depending on the exact start up time. The order can even be effected by the exact versions of drivers associated with particular devices.
In addition, each USB device is typically associated with a location in the directory structure of /sys/devices under the Unix family of operating system. AFAIK, with most computers this is connected to the devices in the PCI bus system. Unfortunately, the labeling of this hierachy is not stable upon reboot. The parts of the system that are initialized early are likely to be stably labeled, but due to timing of various start up activities, the lower reaches of the PCI bus tree are likely to be inconsistently labeled. So the /sys/devices hierachary can not be used to uniquely identify USB devices.
Next, the same physical device can have a different logical identity depending on what it is plugged into. Take a device that is a 3.1 USB hub. If it is plugged into a USB 1.1 port, the logical 3.0 port won’t be present. Or if it is plugged into a USB 3.0 port, but a USB 1.1 device is plugged into it, it will show up as USB 3.0 logical device, a USB 2.0 logical device, and a USB 1.1. logical device.
Despite these challenges, it is often possible to uniquely identify a particular USB device in a system based on how it connects with the computer of interest and how different physical devices are connected.
This module provides the capabilities to identify particular nodes for visualization as well as selection of nodes as needed for device control.
Submodules¶
astutus.usb.device_aliases module¶
Device aliases allow the USB device tree to identify a node with a label associated with the physical device.
This module provides the capabilities to identify particular nodes for visualization as well as selection of nodes as needed for device control.
The selectors implement here are influenced by XPath.
Conceptually, the directory hierarch for sys/devices could be mapped into an XML document. Then XPath could be directly applied to this. This approach might be used in a second implementation of this system. But for know, the initial implementation will be driven by the needs to identify particular USB relays plugged into the current computer.
To do this, four axes are considered:
Current node axis
Ancestor axis
Child axis
Sibling axis
In looking at the tree there are two distinct ilk of nodes:
PCI nodes identified by vendor and device
USB noded identified by idVendor and idProduct
The nodes are identified as:
pci({vendor}:{device})
usb({idVendor}:{idProduct})
The axis checks are implemented using this pattern:
[ {axis} {operator} {node} ]
A bare node is implicitly the current node axis and operator is implicitly equality.
For ancestor, the equality operator means that some ancestor matches the equality operator and specified node value.
For sibling or child, the equality operator means that some sibling or child matches the equality operator and node value.
Here are some examples of validly formated selectors:
usb(1a86:7523)
[ancestor==usb(05e3:0610)]usb(1a86:7523)[sibling==usb(0bda:8153)]
[ancestor==pci(0x1002:0x5a19)]usb(1a86:7523)[child=usb(0bda:8153)]
[ancestor==pci(0x1002:0x5a19)]usb(1a86:7523)
This module contains two key public features:
The find_pci_paths(selector) function for use in automation.
The DeviceAliases class used by the astutus-usb-tree command.
-
class
astutus.usb.device_aliases.
DeviceAliases
(*, filepath)¶ Bases:
object
The device aliases class provides a dictionary between selectors and aliases for a node.
The aliases should have the following attributes:
“color”
“label”
“order”
“priority”
Each of these attributes are string values.
Color should be as defined in astutus.util.term_color.py.
The order and priority values should be two character values, such as “44”.
Aliases with higher priority are selected over other potential aliases of lesser priority for a particular node.
Order is used in sorting the nodes in the USB tree for display.
Here is structure of the raw aliases file:
{ "[ancestor==usb(05e3:0610)]usb(1a86:7523)[sibling==usb(0bda:8153)]": { "color": "fushia", "label": "SMAKIN Relay into TECKNET USB 2.0", "order": "40", "priority": 98 }, }
-
get
(id, dirpath)¶ Get the alias of highest priority that matches the specified node.
Note: id is probably not needed, since dirpath should uniquely specify the node. Opportunity for refactoring???
-
label
(name)¶ Returns a simple label for the specified name. Only checks the current axis for equality.
-
static
parse_raw_aliases
(raw_aliases)¶
-
static
read_raw_from_json
(filepath)¶
-
static
write_raw_as_json
(filepath, raw_aliases)¶
-
astutus.usb.device_aliases.
ancestor_passes
(check, dirpath)¶ Checks if any ancestor of a node matches the specified check.
-
astutus.usb.device_aliases.
child_passes
(check, dirpath, skip_dirpaths=[])¶ Checks if any immediate child of a node matches the specified check.
-
astutus.usb.device_aliases.
find_all_pci_paths
(value)¶ Find all that terminate with a node that matches the value.
The value is something like usb(1a86:7523) or pci(0x1002:0x5a19)
-
astutus.usb.device_aliases.
find_pci_paths
(selector)¶ Find all paths in the sys/devices tree that matches a selector.
-
astutus.usb.device_aliases.
matches_as_node
(dirpath, ilk, vendor, device)¶
-
astutus.usb.device_aliases.
matches_as_pci_node
(dirpath, vendor, device)¶
-
astutus.usb.device_aliases.
matches_as_usb_node
(dirpath, vendor, product)¶
-
astutus.usb.device_aliases.
parse_selector
(selector)¶ Parse the selector into ancestor, current, sibling and child axes.
-
astutus.usb.device_aliases.
parse_value
(value)¶ Given a value break it down by the ilk of node (usb or pci), the vendor, and the device or product.
-
astutus.usb.device_aliases.
sibling_passes
(check, dirpath)¶ Checks if any immediate sibling of a node matches the specified check.
astutus.usb.lcus_1_usb_relay module¶
astutus.usb.tree module¶
-
class
astutus.usb.tree.
DeviceConfigurations
(filepath=None)¶ Bases:
object
-
find_usb_configuration
(data)¶
-
read_from_json
(filepath=None)¶
-
write_as_json
(filepath)¶
-
-
class
astutus.usb.tree.
DeviceNode
(tag, dirpath, data, config, alias, cls_order)¶ Bases:
object
-
property
colorized
¶
-
find_description_template
()¶
-
get_description
()¶
-
key
()¶
-
property
-
class
astutus.usb.tree.
PciDeviceNodeData
(*, tag, dirpath, data, config, alias_paths)¶ Bases:
astutus.usb.tree.DeviceNode
-
cls_order
= '10'¶
-
classmethod
extract_data
(tag, dirpath, filenames)¶
-
-
class
astutus.usb.tree.
UsbDeviceNodeData
(*, tag, dirpath, data, config, alias_paths)¶ Bases:
astutus.usb.tree.DeviceNode
-
cls_order
= '00'¶
-
classmethod
extract_data
(tag, dirpath, filenames)¶
-
-
astutus.usb.tree.
key_by_node_data_key
(node)¶
-
astutus.usb.tree.
main
()¶
-
astutus.usb.tree.
parse_args
(raw_args)¶
-
astutus.usb.tree.
print_tree
(*, device_aliases_filepath, device_configurations_filepath)¶
astutus.usb.usb_impl module¶
-
astutus.usb.usb_impl.
extract_specified_data
(tag, dirpath, filenames)¶
-
astutus.usb.usb_impl.
find_busnum_and_devnum_for_sym_link
(sym_link)¶
-
astutus.usb.usb_impl.
find_busnum_and_devnum_for_sys_device
(pci_path) -> (<class 'int'>, <class 'int'>)¶
-
astutus.usb.usb_impl.
find_busnum_and_devnum_for_tty
(tty)¶
-
astutus.usb.usb_impl.
find_paths_for_vendor_and_product
(vendor_id: str, product_id: str)¶
-
astutus.usb.usb_impl.
find_sym_link_for_tty
(tty)¶
-
astutus.usb.usb_impl.
find_tty_description_from_pci_path
(pci_path)¶
-
astutus.usb.usb_impl.
find_tty_for_busnum_and_devnum
(busnum, devnum)¶
-
astutus.usb.usb_impl.
find_vendor_info_from_busnum_and_devnum
(busnum: int, devnum: int)¶