def __plugDevice(flag, dom, usbmap): for dev in core.find(find_all=True): for cfg in dev: intf = util.find_descriptor(cfg, find_all=True) intf0 = util.find_descriptor(cfg, bInterfaceClass=0) intf3 = util.find_descriptor(cfg, bInterfaceClass=3) intf9 = util.find_descriptor(cfg, bInterfaceClass=9) if intf != None and intf0 == None and intf3 == None and intf9 == None: idVendor = str(hex(dev.idVendor)) if len(idVendor) < 6: idVendor = '0x' + '0' * (6 - len(idVendor)) + idVendor[2:] idProduct = str(hex(dev.idProduct)) if len(idProduct) < 6: idProduct = '0x' + '0' * (6 - len(idProduct)) + idProduct[2:] xml = __generateUSBXML(idVendor, idProduct) if dom != None and dom.isActive() == True: if flag: dom.attachDevice(xml) syspath=__getSysPath(idVendor, idProduct) if syspath != None: usbmap[syspath]=idProduct+idVendor else: dom.detachDevice(xml) syspath=__getSysPath(idVendor, idProduct) if syspath != None: usbmap.pop(syspath) else: pass
def clearHalt(self, endpoint): r"""Clears any halt status on the specified endpoint. Arguments: endpoint: endpoint number. """ cfg = self.dev.get_active_configuration() intf = util.find_descriptor(cfg, bInterfaceNumber = self.__claimed_interface) e = util.find_descriptor(intf, bEndpointAddress = endpoint) control.clear_feature(self.dev, control.ENDPOINT_HALT, e)
def get_interface(self, device, intf): # TODO: check the viability of issuing a GET_INTERFACE # request when we don't have a alternate setting cached if intf is None: cfg = self.get_active_configuration(device) return cfg[(0, 0)] elif isinstance(intf, Interface): return intf else: cfg = self.get_active_configuration(device) if intf in self._alt_set: return util.find_descriptor(cfg, bInterfaceNumber=intf, bAlternateSetting=self._alt_set[intf]) else: return util.find_descriptor(cfg, bInterfaceNumber=intf)
def setUp(self): self.dev = usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID, custom_match=find_by_serial(DUT_SERIAL)) self.assertIsNotNone(self.dev, "Couldn't find locm3 gadget0 device") self.cfg = uu.find_descriptor(self.dev, bConfigurationValue=2) self.assertIsNotNone(self.cfg, "Config 2 should exist") self.dev.set_configuration(self.cfg)
def managed_set_interface(self, device, intf, alt): if isinstance(intf, Interface): i = intf else: cfg = self.get_active_configuration(device) if intf is None: intf = cfg[(0,0)].bInterfaceNumber if alt is not None: i = util.find_descriptor(cfg, bInterfaceNumber=intf, bAlternateSetting=alt) else: i = util.find_descriptor(cfg, bInterfaceNumber=intf) self.managed_claim_interface(device, i) if alt is None: alt = i.bAlternateSetting self.backend.set_interface_altsetting(self.handle, i.bInterfaceNumber, alt) self._alt_set[i.bInterfaceNumber] = alt
def test_config_switch_2(self): """ Uses the API if you're interested in the cfg block """ cfg = uu.find_descriptor(self.dev, bConfigurationValue=2) self.assertIsNotNone(cfg, "Config 2 should exist") self.dev.set_configuration(cfg)
def managed_set_configuration(self, device, config): if config is None: cfg = device[0] elif isinstance(config, Configuration): cfg = config elif config == 0: # unconfigured state class MockConfiguration(object): def __init__(self): self.index = None self.bConfigurationValue = 0 cfg = MockConfiguration() else: cfg = util.find_descriptor(device, bConfigurationValue=config) if cfg is None: raise ValueError("Invalid configuration " + str(config)) self.managed_open() self.backend.set_configuration(self.handle, cfg.bConfigurationValue) # cache the index instead of the object to avoid cyclic references # of the device and Configuration (Device tracks the _ResourceManager, # which tracks the Configuration, which tracks the Device) self._active_cfg_index = cfg.index self._ep_info.clear()
def managed_set_configuration(self, device, config): if config is None: cfg = device[0] elif isinstance(config, Configuration): cfg = config elif config == 0: # unconfigured state class FakeConfiguration(object): def __init__(self): self.index = None self.bConfigurationValue = 0 cfg = FakeConfiguration() else: cfg = util.find_descriptor(device, bConfigurationValue=config) self.managed_open() self.backend.set_configuration(self.handle, cfg.bConfigurationValue) # cache the index instead of the object to avoid cyclic references # of the device and Configuration (Device tracks the _ResourceManager, # which tracks the Configuration, which tracks the Device) self._active_cfg_index = cfg.index # after changing configuration, our alternate setting and endpoint type caches # are not valid anymore self._ep_type_map.clear() self._alt_set.clear()
def setUp(self): self.dev = usb.core.find(idVendor=0xcafe, idProduct=0xcafe, custom_match=find_by_serial(DUT_SERIAL)) self.assertIsNotNone(self.dev, "Couldn't find locm3 gadget0 device") self.cfg = uu.find_descriptor(self.dev, bConfigurationValue=2) self.assertIsNotNone(self.cfg, "Config 2 should exist") self.dev.set_configuration(self.cfg); self.req = uu.CTRL_IN | uu.CTRL_TYPE_VENDOR | uu.CTRL_RECIPIENT_INTERFACE
def get_active_configuration(self, device): if self._active_cfg_index is None: cfg = util.find_descriptor(device, bConfigurationValue=self.backend.get_configuration(self.handle)) if cfg is None: raise USBError("Configuration not set") self._active_cfg_index = cfg.index return cfg return device[self._active_cfg_index]
def __call__(self, device): if device.bDeviceClass == self.__class: return True for cfg in device: intf = find_descriptor(cfg, bInterfaceClass=self.__class) if intf is not None: return True return False
def get_endpoint_type(self, device, address, intf): intf = self.get_interface(device, intf) key = (address, intf.bInterfaceNumber, intf.bAlternateSetting) try: return self._ep_type_map[key] except KeyError: e = util.find_descriptor(intf, bEndpointAddress=address) etype = util.endpoint_type(e.bmAttributes) self._ep_type_map[key] = etype return etype
def get_interface_and_endpoint(self, device, endpoint_address): try: return self._ep_info[endpoint_address] except KeyError: for intf in self.get_active_configuration(device): ep = util.find_descriptor(intf, bEndpointAddress=endpoint_address) if ep is not None: self._ep_info[endpoint_address] = (intf, ep) return intf, ep raise ValueError('Invalid endpoint address ' + hex(endpoint_address))
def setUp(self): self.dev = usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID, custom_match=find_by_serial(DUT_SERIAL)) self.assertIsNotNone(self.dev, "Couldn't find locm3 gadget0 device") self.cfg = uu.find_descriptor(self.dev, bConfigurationValue=2) self.assertIsNotNone(self.cfg, "Config 2 should exist") self.dev.set_configuration(self.cfg) self.intf = self.cfg[(0, 0)] # heh, kinda gross... self.ep_out = [ep for ep in self.intf if uu.endpoint_direction(ep.bEndpointAddress) == uu.ENDPOINT_OUT][0] self.ep_in = [ep for ep in self.intf if uu.endpoint_direction(ep.bEndpointAddress) == uu.ENDPOINT_IN][0]
def managed_set_interface(self, device, intf, alt): if isinstance(intf, Interface): i = intf else: cfg = self.get_active_configuration(device) if intf is None: intf = cfg[(0, 0)].bInterfaceNumber if alt is not None: i = util.find_descriptor(cfg, bInterfaceNumber=intf, bAlternateSetting=alt) else: i = util.find_descriptor(cfg, bInterfaceNumber=intf) self.managed_claim_interface(device, i) if alt is None: alt = i.bAlternateSetting self.backend.set_interface_altsetting(self.handle, i.bInterfaceNumber, alt)
def get_active_configuration(self, device): if self._active_cfg_index is None: self.managed_open() cfg = util.find_descriptor( device, bConfigurationValue=self.backend.get_configuration( self.handle)) if cfg is None: raise USBError('Configuration not set') self._active_cfg_index = cfg.index return cfg return device[self._active_cfg_index]
def connect(self): """Attempt to and return connection""" # Disconnect device if it's already connected. if self._connected: self.disconnect() # Find the device by the vendor ID. usb_device = core.find(idVendor=VENDOR_ID) if not usb_device: # Device not found return self._connected # Copy the default configuration. try: usb_device.set_configuration() except core.USBError as e: log.warning('Error connecting: %s', e) self._error() config = usb_device.get_active_configuration() interface = config[(0, 0)] # Get the write endpoint. endpoint_out = util.find_descriptor( interface, custom_match=lambda e: util.endpoint_direction( e.bEndpointAddress) == util.ENDPOINT_OUT) assert endpoint_out is not None, 'cannot find write endpoint' # Get the read endpoint. endpoint_in = util.find_descriptor( interface, custom_match=lambda e: util.endpoint_direction( e.bEndpointAddress) == util.ENDPOINT_IN) assert endpoint_in is not None, 'cannot find read endpoint' self._usb_device = usb_device self._endpoint_in = endpoint_in self._endpoint_out = endpoint_out self._connected = True return self._connected
def _open(self): # Most of this is straight from the PyUSB example documentation dev = findDeviceUSB(idVendor=self.idVendor, idProduct=self.idProduct) if dev is None: raise DriverError("Could not open device (not found)") # make sure the kernel driver is not active if dev.is_kernel_driver_active(0): try: dev.detach_kernel_driver(0) except USBError as e: exit("could not detach kernel driver: {}".format(e)) dev.set_configuration() cfg = dev.get_active_configuration() interfaceNumber = cfg[(0, 0)].bInterfaceNumber intf = find_descriptor(cfg, bInterfaceNumber=interfaceNumber, bAlternateSetting=get_interface( dev, interfaceNumber)) claim_interface(dev, interfaceNumber) endpoint_out_matcher = \ lambda e: endpoint_direction(e.bEndpointAddress) == ENDPOINT_OUT epOut = find_descriptor(intf, custom_match=endpoint_out_matcher) assert epOut is not None endpoint_in_matcher = \ lambda e: endpoint_direction(e.bEndpointAddress) == ENDPOINT_IN ep_in = find_descriptor(intf, custom_match=endpoint_in_matcher) assert ep_in is not None self._epOut = epOut self._epIn = ep_in self._dev = dev self._intNum = interfaceNumber
def __init__(self, dev): """ __init__(dev) -> None Initialize the DEV of CCID. device: usb.core.Device object. """ cfg = dev.get_active_configuration() intf = find_descriptor(cfg, bInterfaceClass=CCID_CLASS, bInterfaceSubClass=CCID_SUBCLASS, bInterfaceProtocol=CCID_PROTOCOL_0) if intf is None: raise ValueError("Not a CCID device") try: claim_interface(dev, intf) except Exception as e: print(e) for ep in intf: if endpoint_type(ep.bmAttributes) == ENDPOINT_TYPE_BULK and \ endpoint_direction(ep.bEndpointAddress) == ENDPOINT_OUT: self.__bulkout = ep.bEndpointAddress if endpoint_type(ep.bmAttributes) == ENDPOINT_TYPE_BULK and \ endpoint_direction(ep.bEndpointAddress) == ENDPOINT_IN: self.__bulkin = ep.bEndpointAddress assert len(intf.extra_descriptors) == 54 assert intf.extra_descriptors[1] == 33 if (intf.extra_descriptors[42] & 0x02): # Short APDU level exchange self.__use_APDU = True elif (intf.extra_descriptors[42] & 0x04): # Short and extended APDU level exchange self.__use_APDU = True elif (intf.extra_descriptors[42] & 0x01): # TPDU level exchange self.__use_APDU = False else: raise ValueError("Unknown exchange level") # Check other bits??? # intf.extra_descriptors[40] # intf.extra_descriptors[41] self.__dev = dev self.__timeout = 10000 self.__seq = 0
def get_usb_endpoints(device): device_config = device.get_active_configuration() if device_config is None: # Only set a new configuration if the device has not been previously been set up, # because this would tirgger a reset of the USB state device.set_configuration() device_config = device.get_active_configuration() # Get the first interface interface = device_config[(0,0)] # Get read and write endpoints read_ep = find_descriptor( interface, # Match the first IN endpoint custom_match=lambda e: usb.util.endpoint_direction(e.bEndpointAddress) == usb.util.ENDPOINT_IN ) write_ep = find_descriptor( interface, # Match the first OUT endpoint custom_match=lambda e: usb.util.endpoint_direction( e.bEndpointAddress ) == usb.util.ENDPOINT_OUT ) # Flush the read_ep (fingers crossed, that this is not some other device, that we are not interested in) try: while True: read_ep.read(64, timeout=1) except USBError as e: if e.errno == errno.ETIMEDOUT: # There is nothing to read, so we can carry on pass else: raise return read_ep, write_ep
def __init__(self, dev): """ __init__(dev) -> None Initialize the DEV of CCID. device: usb.core.Device object. """ cfg = dev.get_active_configuration() intf = find_descriptor(cfg, bInterfaceClass=CCID_CLASS, bInterfaceSubClass=CCID_SUBCLASS, bInterfaceProtocol=CCID_PROTOCOL_0) if intf is None: raise ValueError("Not a CCID device") claim_interface(dev, intf) for ep in intf: if endpoint_type(ep.bmAttributes) == ENDPOINT_TYPE_BULK and \ endpoint_direction(ep.bEndpointAddress) == ENDPOINT_OUT: self.__bulkout = ep.bEndpointAddress if endpoint_type(ep.bmAttributes) == ENDPOINT_TYPE_BULK and \ endpoint_direction(ep.bEndpointAddress) == ENDPOINT_IN: self.__bulkin = ep.bEndpointAddress assert len(intf.extra_descriptors) == 54 assert intf.extra_descriptors[1] == 33 if (intf.extra_descriptors[42] & 0x02): # Short APDU level exchange self.__use_APDU = True elif (intf.extra_descriptors[42] & 0x04): # Short and extended APDU level exchange self.__use_APDU = True elif (intf.extra_descriptors[42] & 0x01): # TPDU level exchange self.__use_APDU = False else: raise ValueError("Unknown exchange level") # Check other bits??? # intf.extra_descriptors[40] # intf.extra_descriptors[41] self.__dev = dev self.__timeout = 10000 self.__seq = 0
def isPassthroughUsbDevice(interfaceClass, idP, idV): for dev in core.find(find_all=True): for cfg in dev: intf = util.find_descriptor(cfg, bInterfaceClass=interfaceClass) if intf is not None: idVendor = str(hex(dev.idVendor)) if len(idVendor) < 6: idVendor = '0x' + '0' * (6 - len(idVendor)) + idVendor[2:] idProduct = str(hex(dev.idProduct)) if len(idProduct) < 6: idProduct = '0x' + '0' * (6 - len(idProduct)) + idProduct[2:] if idVendor !=None and idProduct != None and idVendor == idV and idProduct == idP: return True return False
def managed_set_configuration(self, device, config): if config is None: cfg = device[0] elif isinstance(config, Configuration): cfg = config else: cfg = util.find_descriptor(device, bConfigurationValue=config) self.managed_open() self.backend.set_configuration(self.handle, cfg.bConfigurationValue) # cache the index instead of the object to avoid cyclic references # of the device and Configuration (Device tracks the _ResourceManager, # which tracks the Configuration, which tracks the Device) self._active_cfg_index = cfg.index # after changing configuration, our alternate setting and endpoint type caches # are not valid anymore self._ep_type_map.clear() self._alt_set.clear()
def setUp(self): self.dev = usb.core.find(idVendor=VENDOR_ID, idProduct=PRODUCT_ID, custom_match=find_by_serial(DUT_SERIAL)) self.assertIsNotNone(self.dev, "Couldn't find locm3 gadget0 device") self.cfg = uu.find_descriptor(self.dev, bConfigurationValue=2) self.assertIsNotNone(self.cfg, "Config 2 should exist") self.dev.set_configuration(self.cfg) self.intf = self.cfg[(0, 0)] # heh, kinda gross... self.ep_out = [ ep for ep in self.intf if uu.endpoint_direction(ep.bEndpointAddress) == uu.ENDPOINT_OUT ][0] self.ep_in = [ ep for ep in self.intf if uu.endpoint_direction(ep.bEndpointAddress) == uu.ENDPOINT_IN ][0]
def __init__(self, dev): self.dev = dev self.cfg = cfg = dev.get_active_configuration() self.intf = intf = find_descriptor(cfg, bInterfaceClass=CCID_CLASS, bInterfaceSubClass=CCID_SUBCLASS) if intf is None: raise ValueError("Not a CCID device") claim_interface(dev, intf) for ep in intf: if (endpoint_type(ep.bmAttributes) == ENDPOINT_TYPE_BULK and endpoint_direction(ep.bEndpointAddress) == ENDPOINT_OUT): self.bulkout = ep.bEndpointAddress if (endpoint_type(ep.bmAttributes) == ENDPOINT_TYPE_BULK and endpoint_direction(ep.bEndpointAddress) == ENDPOINT_IN): self.bulkin = ep.bEndpointAddress self.seq = 0 self.timeout = 10000
def managed_set_configuration(self, device, config): if config is None: cfg = device[0] elif isinstance(config, Configuration): cfg = config elif config == 0: # unconfigured state class MockConfiguration(object): def __init__(self): self.index = None self.bConfigurationValue = 0 cfg = MockConfiguration() else: cfg = util.find_descriptor(device, bConfigurationValue=config) if cfg is None: raise ValueError("Invalid configuration " + str(config)) self.managed_open() self.backend.set_configuration(self.handle, cfg.bConfigurationValue) self._active_cfg_index = cfg.index self._ep_info.clear()
def managed_set_configuration(self, device, config): if config is None: cfg = device[0] elif isinstance(config, Configuration): cfg = config elif config == 0: # unconfigured state class MockConfiguration(object): def __init__(self): self.index = None self.bConfigurationValue = 0 cfg = MockConfiguration() else: cfg = util.find_descriptor(device, bConfigurationValue=config) self.managed_open() self.backend.set_configuration(self.handle, cfg.bConfigurationValue) # cache the index instead of the object to avoid cyclic references # of the device and Configuration (Device tracks the _ResourceManager, # which tracks the Configuration, which tracks the Device) self._active_cfg_index = cfg.index self._ep_info.clear()
def __init__(self, product: int, timeout: Optional[float] = 5) -> None: print(f"__init__({product}, {timeout})") if timeout is not None: timeout += time() while True: device = find(idVendor=0x27c6, idProduct=product) if device is not None: try: if get_status(device) == 0x0001: break except USBError as error: if (error.backend_error_code != -1 and error.backend_error_code != -4): raise error if timeout is not None and time() > timeout: if device is None: raise USBTimeoutError("Device not found", -5, 19) raise USBTimeoutError("Invalid device state", -12, 131) sleep(0.01) self.device: USBDevice = device print(f"Found Goodix device: \"{self.device.product}\" " f"from \"{self.device.manufacturer}\" " f"on bus {self.device.bus} " f"address {self.device.address}.") interface = find_descriptor(self.device.get_active_configuration(), bInterfaceClass=CLASS_DATA) if interface is None: raise USBError("Interface data not found", -5, 6) print(f"Found interface data: {interface.bInterfaceNumber}") endpoint_in = find_descriptor( interface, custom_match=lambda endpoint: endpoint_direction( endpoint.bEndpointAddress) == ENDPOINT_IN and endpoint_type( endpoint.bmAttributes) == ENDPOINT_TYPE_BULK) if endpoint_in is None: raise USBError("Endpoint in not found", -5, 6) self.endpoint_in: int = endpoint_in.bEndpointAddress print(f"Found endpoint in: {hex(self.endpoint_in)}") endpoint_out = find_descriptor( interface, custom_match=lambda endpoint: endpoint_direction( endpoint.bEndpointAddress) == ENDPOINT_OUT and endpoint_type( endpoint.bmAttributes) == ENDPOINT_TYPE_BULK) if endpoint_out is None: raise USBError("Endpoint out not found", -5, 6) self.endpoint_out: int = endpoint_out.bEndpointAddress print(f"Found endpoint out: {hex(self.endpoint_out)}") # Empty device reply buffer (Current patch while waiting for a fix) self.empty_buffer()