blob: bed7bfa81232e2163b4e2b5e5b06e2aa606c9650 [file] [log] [blame]
"""
python-libusb1 device tree scan example.
This program shows the entire tree of devices/configurations/interfaces/endpoints
that are available on your computer. It should be useful when interfacing with a
new USB device (since you can easily examine what features are available on the device).
"""
import usb1
def scan_device_tree():
with usb1.USBContext() as context:
for dev in context.getDeviceIterator(skip_on_error=True):
dev: usb1.USBDevice
try:
print(
f"- Device: {dev.getVendorID():04x}:{dev.getProductID():04x}, {dev.getManufacturer()} {dev.getProduct()}, SerNo: {dev.getSerialNumber()}"
)
except usb1.USBError:
print(
f"- Device: {dev.getVendorID():04x}:{dev.getProductID():04x} <failed to open, on Windows this is because it does not have the WinUSB driver attached>"
)
for cfg in dev:
# Note: for docs on USBConfiguration, see here: https://libusb.sourceforge.io/api-1.0/structlibusb__config__descriptor.html
# Also see https://www.beyondlogic.org/usbnutshell/usb5.shtml#ConfigurationDescriptors
cfg: usb1.USBConfiguration
print(
f"---> Cfg: Num Interfaces: {cfg.getNumInterfaces()}, Identifier: {cfg.getConfigurationValue()}, "
f"Attributes: 0x{cfg.getAttributes():02x}"
)
for iface_idx, iface in enumerate(cfg):
iface: usb1.USBInterface
print(f" ---> Interface {iface_idx}")
for altsetting_idx, altsetting in enumerate(iface):
altsetting: usb1.USBInterfaceSetting
# The docs for USBInterfaceSetting can be seen here:
# https://libusb.sourceforge.io/api-1.0/structlibusb__interface__descriptor.html
# For an enumeration of defined class, subclass, and protocol values, see here:
# https://www.usb.org/defined-class-codes
print(
f" ---> Alternate settings {altsetting_idx}: Num Endpoints: {altsetting.getNumEndpoints()}, "
f"Class and SubClass: (0x{altsetting.getClass():02x}, 0x{altsetting.getSubClass():02x}), "
f"Protocol: {altsetting.getProtocol()}"
)
for endpoint in altsetting:
endpoint: usb1.USBEndpoint
# The docs for USBEndpoint can be seen here:
# https://libusb.sourceforge.io/api-1.0/structlibusb__endpoint__descriptor.html#a111d087a09cbeded8e15eda9127e23d2
# Process attributes field
if endpoint.getAttributes() & 3 == 0:
ep_type = "Control"
elif endpoint.getAttributes() & 3 == 1:
ep_type = "Isochronous"
elif endpoint.getAttributes() & 3 == 2:
ep_type = "Bulk"
else:
ep_type = "Interrupt"
print(
f" ---> Endpoint 0x{endpoint.getAddress():02x}: Direction: "
f"{'Dev-To-Host' if endpoint.getAddress() & 0x80 != 0 else 'Host-To-Dev'}, Type: {ep_type}"
)
if __name__ == '__main__':
scan_device_tree()