Connect to a local device identified by *path* and load the
    appropriate device driver. The *path* argument is documented at
    :meth:`nfc.clf.ContactlessFrontend.open`. The return value is
    either a :class:`Device` instance or :const:`None`. Note that not
    all drivers can be autodetected, specifically for serial devices
    *path* must usually also specify the driver.

def connect(path):
    """Connect to a local device identified by *path* and load the
    appropriate device driver. The *path* argument is documented at
    :meth:`nfc.clf.ContactlessFrontend.open`. The return value is
    either a :class:`Device` instance or :const:`None`. Note that not
    all drivers can be autodetected, specifically for serial devices
    *path* must usually also specify the driver.

    """
    assert isinstance(path, str) and len(path) > 0

    found = transport.USB.find(path)
    if found is not None:
        for vid, pid, bus, dev in found:
            module = usb_device_map.get((vid, pid))
            if module is None:
                continue

            log.debug("loading {mod} driver for usb:{vid:04x}:{pid:04x}"
                      .format(mod=module, vid=vid, pid=pid))

            if sys.platform.startswith("linux"):
                devnode = "/dev/bus/usb/%03d/%03d" % (int(bus), int(dev))
                if not os.access(devnode, os.R_OK | os.W_OK):
                    log.debug("access denied to " + devnode)
                    if len(path.split(':')) < 3:
                        continue
                    else:
                        raise IOError(errno.EACCES, os.strerror(errno.EACCES))

            driver = importlib.import_module("nfc.clf." + module)
            try:
                device = driver.init(transport.USB(bus, dev))
            except IOError as error:
                log.debug(error)
                if len(path.split(':')) < 3:
                    continue
                else:
                    raise error

            device._path = "usb:{0:03}:{1:03}".format(int(bus), int(dev))
            return device

    found = transport.TTY.find(path)
    if found is not None:
        devices = found[0]
        drivers = [found[1]] if found[1] else tty_driver_list
        globbed = found[2] or drivers is tty_driver_list
        for drv in drivers:
            for dev in devices:
                log.debug("trying {0} on {1}".format(drv, dev))
                driver = importlib.import_module("nfc.clf." + drv)
                try:
                    tty = transport.TTY(dev)
                    device = driver.init(tty)
                    device._path = dev
                    return device
                except IOError as error:
                    log.debug(error)
                    tty.close()
                    if not globbed:
                        raise

    if path.startswith("udp"):
        path = path.split(':')
        host = str(path[1]) if len(path) > 1 and path[1] else 'localhost'
        port = int(path[2]) if len(path) > 2 and path[2] else 54321
        driver = importlib.import_module("nfc.clf.udp")
        device = driver.init(host, port)
        device._path = "udp:{0}:{1}".format(host, port)
        return device