def __init__(self, tmp_dev, device_desc): """ :param tmp_dev: temporary device handle, do not save. :param device_desc: USB device descriptor. """ self.__desc__ = device_desc self.vendor_id = device_desc.idVendor self.product_id = device_desc.idProduct self.bus = usb.get_bus_number(tmp_dev) self.address = usb.get_device_address(tmp_dev) # find device path. dev_path = (ct.c_uint8 * 8)() ret = usb.get_port_numbers(tmp_dev, dev_path, ct.sizeof(dev_path)) if ret > 0: self.path = '.'.join([f"{p:d}" for p in dev_path][:ret]) _logger.debug( ' * {:04x}:{:04x} - bus: {:d}, device: {:d}, path: {}'.format( self.vendor_id, self.product_id, self.bus, self.address, self.path)) # Calculate usb product key. self.dev_key = f'{self.vendor_id:04x}:{self.product_id:04x}' # Find USB product group, based on first 3 digits of product id. if self.dev_key[:8] in _USB_PRODUCT_CLASSES: product_class = _USB_PRODUCT_CLASSES[self.dev_key[:8]] self.class_id = product_class.class_id self.class_descr = product_class.class_descr self.__dev_class__ = product_class # Find USB product description. if self.dev_key in USB_PRODUCT_DESCRIPTIONS: self.product_name = USB_PRODUCT_DESCRIPTIONS[self.dev_key]
def print_devs(devs): path = (ct.c_uint8 * 8)() i = 0 while devs[i]: dev = devs[i] desc = usb.device_descriptor() r = usb.get_device_descriptor(dev, ct.byref(desc)) if r < 0: print("failed to get device descriptor", file=sys.stderr) return print("{:04x}:{:04x} (bus {:d}, device {:d})".format( desc.idVendor, desc.idProduct, usb.get_bus_number(dev), usb.get_device_address(dev)), end="") r = usb.get_port_numbers(dev, path, ct.sizeof(path)) if r > 0: print(" path: {:d}".format(path[0]), end="") for j in range(1, r): print(".{:d}".format(path[j]), end="") print() i += 1
def print_devs(devs): path = (ct.c_uint8 * 8)() i = 0 while devs[i]: dev = devs[i] dev_handle = ct.POINTER(usb.device_handle)() vendor_str = '' product_str = 'unknown' desc = usb.device_descriptor() r = usb.get_device_descriptor(dev, ct.byref(desc)) if r < 0: print("failed to get device descriptor", file=sys.stderr) return r = usb.open(dev, ct.byref(dev_handle)) buf = ct.create_string_buffer(1024) if r >= 0: # for field in desc._fields_: if desc.iProduct: ret = usb.get_string_descriptor_ascii( dev_handle, desc.idProduct, ct.cast(buf, ct.POINTER(ct.c_ubyte)), ct.sizeof(buf)) if ret > 0: product_str = buf.value.decode('utf-8') else: print(f'Error: returned {usb.error_name(r).decode("utf-8")} ({r})') print( "{:04x}:{:04x} (bus {:d}, device {:d} : Vendor: {}, Product: {})". format(desc.idVendor, desc.idProduct, usb.get_bus_number(dev), usb.get_device_address(dev), vendor_str, product_str), end="") r = usb.get_port_numbers(dev, path, ct.sizeof(path)) if r > 0: print(" path: {:d}".format(path[0]), end="") for j in range(1, r): print(".{:d}".format(path[j]), end="") print() i += 1
def test_device(vid, pid): speed_name = [ "Unknown", "1.5 Mbit/s (USB LowSpeed)", "12 Mbit/s (USB FullSpeed)", "480 Mbit/s (USB HighSpeed)", "5000 Mbit/s (USB SuperSpeed)", ] handle = usb.open_device_with_vid_pid(None, vid, pid) if not handle: perr(" Failed.\n") return -1 try: dev = usb.get_device(handle) # usb.device* bus = usb.get_bus_number(dev) # c_uint8 port_path = (c_uint8 * 8)() r = usb.get_port_numbers(dev, port_path, sizeof(port_path)) if r > 0: print("\nDevice properties:") print(" bus number: {}".format(bus)) print(" port path: {}".format(port_path[0]), end="") for i in range(1, r): print("->{}".format(port_path[i]), end="") print(" (from root hub)") r = usb.get_device_speed(dev) if r < 0 or r > 4: r = 0 print(" speed: {}".format(speed_name[r])) print("\nReading device descriptor:") dev_desc = usb.device_descriptor() r = usb.get_device_descriptor(dev, byref(dev_desc)) if r < 0: return err_exit(r) print(" length: {}".format(dev_desc.bLength)) print(" device class: {}".format(dev_desc.bDeviceClass)) print(" VID:PID: {:04X}:{:04X}".format( dev_desc.idVendor, dev_desc.idProduct)) print(" bcdDevice: {:04X}".format(dev_desc.bcdDevice)) # Copy the string descriptors for easier parsing string_index = {} # indexes of the string descriptors string_index["Manufacturer"] = dev_desc.iManufacturer string_index["Product"] = dev_desc.iProduct string_index["Serial Number"] = dev_desc.iSerialNumber print("\nReading string descriptors:") string = (c_uint8 * 128)() for key in string_index.keys(): if string_index[key] == 0: continue r = usb.get_string_descriptor_ascii(handle, string_index[key], string, sizeof(string)) if r > 0: print(" {}: {}".format(key, bytearray(string[:r]).decode())) # MS OS 1.0 Descriptors read_ms_os_10_descriptors(handle) print("\nReading BOS descriptor: ", end="") bos_desc = POINTER(usb.bos_descriptor)() if usb.get_bos_descriptor(handle, pointer(bos_desc)) == usb.LIBUSB_SUCCESS: print((bos_desc[0].bNumDeviceCaps)) caps = cast(pointer(bos_desc[0].dev_capability), POINTER(POINTER(usb.bos_dev_capability_descriptor))) for i in range(bos_desc[0].bNumDeviceCaps): # print_device_cap(caps[i]) if caps[i][0].bDevCapabilityType == 0x05: desc = cast(caps[i], POINTER(PlatformCapabilityDescriptor))[0] uuid = uuid_to_string(desc.PlatformCapabilityUUID) if uuid == MS_OS_20_PLATFORM_CAPABILITY_UUID: print(" MS OS 2.0 Platform Capability Descriptor") print(" UUID: {}".format(uuid)) desc = cast( caps[i], POINTER(MSOS20PlatformCapabilityDescriptor))[0] print(" VendorCode: 0x{:02X}".format( desc.bVendorCode)) read_ms_os_20_descriptors(handle, desc.bVendorCode) elif uuid == WEBUSB_PLATFORM_CAPABILITY_UUID: print(" WebUSB Platform Capability UUID") print(" UUID: {}".format(uuid)) desc = cast( caps[i], POINTER(WebUSBPlatformCapabilityDescriptor))[0] print(" VendorCode: 0x{:02X}".format( desc.bVendorCode)) else: print(" UUID: {}".format(uuid)) usb.free_bos_descriptor(bos_desc) else: print("no descriptor") finally: usb.close(handle) return 0
def test_device(vid, pid): #int r; speed_name = [ "Unknown", "1.5 Mbit/s (USB LowSpeed)", "12 Mbit/s (USB FullSpeed)", "480 Mbit/s (USB HighSpeed)", "5000 Mbit/s (USB SuperSpeed)", ] print("Opening device {:04X}:{:04X}...".format(vid, pid)) #handle = ct.POINTER(usb.device_handle)() handle = usb.open_device_with_vid_pid(None, vid, pid) if not handle: perr(" Failed.\n") return -1 endpoint_in = 0 # default IN endpoint endpoint_out = 0 # default OUT endpoint try: dev = usb.get_device(handle) # usb.device* bus = usb.get_bus_number(dev) # ct.c_uint8 if extra_info: port_path = (ct.c_uint8 * 8)() r = usb.get_port_numbers(dev, port_path, ct.sizeof(port_path)) if r > 0: print("\nDevice properties:") print(" bus number: {}".format(bus)) print(" port path: {}".format(port_path[0]), end="") for i in range(1, r): print("->{}".format(port_path[i]), end="") print(" (from root hub)") r = usb.get_device_speed(dev) if r < 0 or r > 4: r = 0 print(" speed: {}".format(speed_name[r])) print("\nReading device descriptor:") dev_desc = usb.device_descriptor() r = usb.get_device_descriptor(dev, ct.byref(dev_desc)) if r < 0: return err_exit(r) print(" length: {}".format(dev_desc.bLength)) print(" device class: {}".format(dev_desc.bDeviceClass)) print(" S/N: {}".format(dev_desc.iSerialNumber)) print(" VID:PID: {:04X}:{:04X}".format(dev_desc.idVendor, dev_desc.idProduct)) print(" bcdDevice: {:04X}".format(dev_desc.bcdDevice)) print(" iMan:iProd:iSer: {}:{}:{}".format( dev_desc.iManufacturer, dev_desc.iProduct, dev_desc.iSerialNumber)) print(" nb confs: {}".format(dev_desc.bNumConfigurations)) # Copy the string descriptors for easier parsing string_index = (ct.c_uint8 * 3)() # indexes of the string descriptors string_index[0] = dev_desc.iManufacturer string_index[1] = dev_desc.iProduct string_index[2] = dev_desc.iSerialNumber print("\nReading BOS descriptor: ", end="") bos_desc = usb.bos_descriptor*() if usb.get_bos_descriptor(handle, ct.byref(bos_desc)) == usb.LIBUSB_SUCCESS: print("{} caps".format(bos_desc[0].bNumDeviceCaps)) for i in range(bos_desc[0].bNumDeviceCaps): print_device_cap(bos_desc[0].dev_capability[i]) usb.free_bos_descriptor(bos_desc) else: print("no descriptor") print("\nReading first configuration descriptor:") conf_desc = usb.config_descriptor*() r = usb.get_config_descriptor(dev, 0, ct.byref(conf_desc)) if r < 0: return err_exit(r) nb_ifaces = conf_desc[0].bNumInterfaces # int print(" nb interfaces: {}".format(nb_ifaces)) first_iface = (conf_desc[0].usb_interface[0].altsetting[0].bInterfaceNumber if nb_ifaces > 0 else -1) for i in range(nb_ifaces): usb_interface = conf_desc[0].usb_interface[i] print(" interface[{}]: id = {}".format( i, usb_interface.altsetting[0].bInterfaceNumber)) for j in range(usb_interface.num_altsetting): altsetting = usb_interface.altsetting[j] print("interface[{}].altsetting[{}]: num endpoints = {}".format( i, j, altsetting.bNumEndpoints)) print(" Class.SubClass.Protocol: {:02X}.{:02X}.{:02X}".format( altsetting.bInterfaceClass, altsetting.bInterfaceSubClass, altsetting.bInterfaceProtocol)) if (altsetting.bInterfaceClass == usb.LIBUSB_CLASS_MASS_STORAGE and (altsetting.bInterfaceSubClass == 0x01 or altsetting.bInterfaceSubClass == 0x06) and altsetting.bInterfaceProtocol == 0x50): # Mass storage devices that can use basic SCSI commands test_mode = USE_SCSI for k in range(altsetting.bNumEndpoints): endpoint = altsetting.endpoint[k] # const usb.endpoint_descriptor* print(" endpoint[{}].address: {:02X}".format( k, endpoint.bEndpointAddress)) # Use the first interrupt or bulk IN/OUT endpoints as default for testing if ((endpoint.bmAttributes & usb.LIBUSB_TRANSFER_TYPE_MASK) & (usb.LIBUSB_TRANSFER_TYPE_BULK | usb.LIBUSB_TRANSFER_TYPE_INTERRUPT)): if endpoint.bEndpointAddress & usb.LIBUSB_ENDPOINT_IN: if not endpoint_in: endpoint_in = endpoint.bEndpointAddress else: if not endpoint_out: endpoint_out = endpoint.bEndpointAddress print(" max packet size: {:04X}".format(endpoint.wMaxPacketSize)) print(" polling interval: {:02X}".format(endpoint.bInterval)) ep_comp = ct.POINTER(usb.ss_endpoint_companion_descriptor)() usb.get_ss_endpoint_companion_descriptor(None, ct.byref(altsetting.endpoint[k]), ct.byref(ep_comp)) if ep_comp: print(" max burst: {:02X} (USB 3.0)".format(ep_comp[0].bMaxBurst)) print(" bytes per interval: {:04X} (USB 3.0)".format(ep_comp[0].wBytesPerInterval)) usb.free_ss_endpoint_companion_descriptor(ep_comp) usb.free_config_descriptor(conf_desc) usb.set_auto_detach_kernel_driver(handle, 1) for iface in range(nb_ifaces): print("\nClaiming interface {}...".format(iface)) r = usb.claim_interface(handle, iface) if r != usb.LIBUSB_SUCCESS: perr(" Failed.\n") print("\nReading string descriptors:") string = (ct.c_char * 128)() for i in range(3): if string_index[i] == 0: continue if usb.get_string_descriptor_ascii(handle, string_index[i], ct.cast(string, ct.POINTER(ct.c_ubyte)), ct.sizeof(string)) > 0: print(" String ({:#04X}): \"{}\"".format(string_index[i], string)) # Read the OS String Descriptor r = usb.get_string_descriptor(handle, MS_OS_DESC_STRING_INDEX, 0, ct.cast(string, ct.POINTER(ct.c_ubyte)), MS_OS_DESC_STRING_LENGTH) if r == MS_OS_DESC_STRING_LENGTH and memcmp(ms_os_desc_string, string, sizeof(ms_os_desc_string)) == 0: # If this is a Microsoft OS String Descriptor, # attempt to read the WinUSB extended Feature Descriptors read_ms_winsub_feature_descriptors(handle, string[MS_OS_DESC_VENDOR_CODE_OFFSET], first_iface) if test_mode == USE_PS3: r = display_ps3_status(handle) if r < 0: return err_exit(r) elif test_mode == USE_XBOX: r = display_xbox_status(handle) if r < 0: return err_exit(r) r = set_xbox_actuators(handle, 128, 222) if r < 0: return err_exit(r) msleep(2000) r = set_xbox_actuators(handle, 0, 0) if r < 0: return err_exit(r) elif test_mode == USE_HID: test_hid(handle, endpoint_in) elif test_mode == USE_SCSI: r = test_mass_storage(handle, endpoint_in, endpoint_out) if r < 0: return err_exit(r) elif test_mode == USE_GENERIC: pass print() for iface in range(nb_ifaces): print("Releasing interface {}...".format(iface)) usb.release_interface(handle, iface) print("Closing device...") finally: usb.close(handle) return 0