コード例 #1
0
 def parse_file(fn) :
     fd  = tzlib.read_whole_text_file(fn)
     return(a_recording.parse(fd))
コード例 #2
0
def find_likely_USB_ports(vendor_id = None, product_id = None, serial_number = None, list_level = 0) :
    """
        Return an array of COM# or /dev/tty(USB|ACM)# names of appropriate ports.

        There is probably an API to do this, but finding it and using it seems to be really something.
    """

    ports   =   []

    if  sys.platform == 'win32' :

        def get_all_usb_friendly_names() :
            """
                There is probably an API to do this, but finding it and using it seems to be really something.
            """

            if  not win32api :
                return([])

            regx    = re.compile("Vid_([0-9a-f]+)\&Pid_([0-9a-f]+)", re.IGNORECASE)

            def search_keys(nms, rdy, k, n, snm) :
                try :
                    if  not rdy             :
                        ( obj, val )        = win32api.RegQueryValueEx(k, r"HardwareID")
                        g                   = regx.search(str(obj))
                        # print "@@@@", snm, serial_number
                        if  g and ((vendor_id is None) or (int(g.group(1), 16) == vendor_id)) and ((product_id is None) or (int(g.group(2), 16) == product_id)) and ((serial_number is None) or (snm.lower() == str(serial_number).lower())) :
                            ( obj, val )    = win32api.RegQueryValueEx(k, r"FriendlyName")                          # just make sure it's there nowadays
                            rdy             = True
                        pass
                    else :
                        ( obj, val )        = win32api.RegQueryValueEx(k, r"PortName")
                        nms.append(str(obj))

                        return

                    pass
                except pywintypes.error :
                    # e   = sys.exc_info()
                    # print "fnam", e[0], e[1], n
                    pass


                i   = 0
                while True :
                    try :
                        kn  = "....."
                        s   = win32api.RegEnumKey(k, i)

                        kn  = n + "\\" + s
                        sk  = win32api.RegOpenKey(k, s, win32con.KEY_ENUMERATE_SUB_KEYS | win32con.KEY_READ)

                        search_keys(nms, rdy, sk, kn, s)

                        win32api.RegCloseKey(sk)
                    except pywintypes.error :
                        # e   = sys.exc_info()
                        # print "fnam", e[0], e[1], n
                        break

                    i      += 1

                pass


            nms = []
            for n in [ r"SYSTEM\CURRENTCONTROLSET\ENUM\USB", r"SYSTEM\CURRENTCONTROLSET\ENUM\FTDIBUS" ] :
                try :
                    k   = win32api.RegOpenKey(win32con.HKEY_LOCAL_MACHINE, n, win32con.KEY_ENUMERATE_SUB_KEYS + win32con.KEY_READ)
                    search_keys(nms, False, k, n, None)
                    win32api.RegCloseKey(k)
                except pywintypes.error :
                    pass
                pass

            return(nms)


        ports   = get_all_usb_friendly_names()

    else    :

        dvs = glob.glob('/sys/bus/usb/devices/*')
        for dn in dvs :
            try     :
                vid = int(tzlib.safe_read_whole_text_file(os.path.join(dn, "idVendor" )).strip(), 16)
                pid = int(tzlib.safe_read_whole_text_file(os.path.join(dn, "idProduct")).strip(), 16)
                snm =    (tzlib.safe_read_whole_text_file(os.path.join(dn, "serial"   )) or "").strip()
                # print "vid=%04x pid=%04x serial_number=[%s] %s" % ( vid, pid, snm, dn, )
                if  ((vendor_id is None) or (vid == vendor_id)) and ((product_id is None) or (pid == product_id)) and ((serial_number is None) or (snm.lower() == str(serial_number).lower())) :
                    # print "vid=%04x pid=%04x serial_number=[%s]" % ( vid, pid, snm ), serial_number
                    dns = glob.glob(os.path.join(dn, os.path.basename(dn) + "*"))
                    for sdn in dns :
                        for fn in glob.glob(os.path.join(sdn, "*")) :
                            # print "@@@@", fn
                            if  re.search(r"\/tty(USB|ACM)[0-9]+$", fn) :
                                ports.append(os.path.join("/dev", os.path.basename(fn)))
                            elif fn.endswith("/tty") :
                                for ffn in glob.glob(os.path.join(fn, "*")) :
                                    if  re.search(r"\/tty(USB|ACM)[0-9]+$", ffn) :
                                        ports.append(os.path.join("/dev", os.path.basename(ffn)))
                                    pass
                                pass
                            pass
                        pass
                    pass
                pass
            except ( ValueError, TypeError, AttributeError ) :
                # tzlib.print_exception()
                pass
            pass

        if  (not len(ports)) and usb    :
            fd  = None
            for bus in usb.busses()     :
                for dev in bus.devices  :
                    if  ((vendor_id is None) or (dev.idVendor == vendor_id)) and ((product_id is None) or (dev.idProduct == product_id)) and ((serial_number is None) or (str(dev.iSerialNumber).lower() == str(serial_number).lower())) :
                        # print "@@@@", "%04x:%04x" % ( dev.idVendor, dev.idProduct, ), dev.deviceClass, dev.deviceSubClass, dev.deviceProtocol, "Bus: %s  Device: %s" % ( str(bus.dirname), str(dev.filename) )
                        # print dir(dev.configurations[0].interfaces[0][0]), dev.configurations[0].interfaces[0][0], dev.configurations[0].interfaces[0][0].interfaceProtocol
                        # print dev.configurations[0].interfaces[0][0].endpoints[0].address, dev.configurations[0].interfaces[0][0].endpoints[0].type
                        if  True or ((dev.deviceClass == 0) and (dev.deviceSubClass == 0) and (dev.deviceProtocol == 0)) :
                            # print "found bus:", bus.dirname, "device:", dev.filename
                            #
                            # ?     how to find which ttyUSB%u it is, and how to find which ttyS%u that is (done with "ln -b /dev/ttyUSB0 /dev/ttyS0" where -b makes a ~ backup of the old link or whatever it is)
                            #       OR BETTER YET: we now take the command line parm /dev/ttyUSB%u and it works,
                            #          so all we need to do is to tie the usb device to the ttyUSB
                            #       hwinfo has enough info to find out:
                            #          bus.dirname and dev.filename give the hwinfo usb.bus_number and usb.linux.device_number
                            #          then linux.sysfs_path looks like this:
                            #              linux.sysfs_path = '/sys/devices/pci0000:00/0000:00:1d.7/usb8/8-2/8-2.2/8-2.2:1.0'
                            #          and that ties back to a previous device that has:
                            #              linux.sysfs_path = '/sys/devices/pci0000:00/0000:00:1d.7/usb8/8-2/8-2.2/8-2.2:1.0/ttyUSB1/tty/ttyUSB1'
                            #              serial.device = '/dev/ttyUSB1'
                            #              serial.port = 1 (0x1)
                            #              linux.device_file = '/dev/ttyUSB1'
                            #          or
                            #              hwinfo --usb
                            #              .
                            #              .
                            #              .
                            #              25: USB 00.0: 0700 Serial controller
                            #              .
                            #              .
                            #              .
                            #                Unique ID: Mwf_.yosUmW5iOW6
                            #                Parent ID: 2XnU.erpEvbsFWX1
                            #                Model: "Prolific PL2303 Serial Port"
                            #                Hotplug: USB
                            #                Vendor: usb 0x067b "Prolific Technology, Inc."
                            #                Device: usb 0x2303 "PL2303 Serial Port"
                            #              .
                            #              .
                            #              .
                            #                Device File: /dev/ttyUSB1
                            #              .
                            #              .
                            #              .
                            #           and so,
                            #              rx  = re.compile(r"  Vendor: usb 0x([0-9a-f]{4}).*?  Device: usb 0x([0-9a-f]{4}).*?  Device File: /dev/ttyUSB([0-9]+)", re.DOTALL)
                            #              print rx.findall(rs)
                            #
                            #
                            #        Also (later, after the devices have moved) dmesg (/var/log/messages) has this, looking from the bottom to the top:
                            #             [30309.568340] usb 8-2.2: new full speed USB device using ehci_hcd and address 36
                            #             [30309.660907] usb 8-2.2: configuration #1 chosen from 1 choice
                            #             [30309.661169] usb 8-2.2: cp210x converter detected
                            #             [30309.661246] usb 8-2.2: cp210x converter now attached to ttyUSB0
                            #          So it appears that the bus.dirname is in the "usb BUS.DIRNAME-2.2...
                            #             and the dev.filename is "address DEV.FILENAME"
                            #        !!!! code uses this method
                            #          Problem with this is that the log may have been flushed since the device was plugged in.
                            #
                            #        Also, The /sys/devices directory can be searched for the device. The files seem to have the information that lsusb and hwinfo output.
                            #          And, apparently, udev rules can be used to assign things to stable device names or whatever.
                            #        Also,
                            #            dir /sys/bus/usb-serial/devices/
                            #            total 0
                            #            drwxr-xr-x 2 root root 0 2011-11-08 21:09 ./
                            #            drwxr-xr-x 4 root root 0 2011-11-08 20:52 ../
                            #            lrwxrwxrwx 1 root root 0 2011-11-08 21:09 ttyUSB0 -> ../../../devices/pci0000:00/0000:00:13.1/usb6/6-1/6-1:1.0/ttyUSB0/
                            #       Also,
                            #            /sys/bus/usb/devices/5-3/idVendor           Contains the hex vendor  ID
                            #            /sys/bus/usb/devices/5-3/idProduct          Contains the hex product ID
                            #            /sys/bus/usb/devices/5-3/5-3:1.0/ttyUSB1/   Exists as a directory.
                            #         so searching all the sub-dirs of /sys/bus/usb/devices for the proper idVendor and idProduct, then searching in all subdirectories that start with the basename of the idVendor/idProduct dir's base name for ttyUSB# finds the port.
                            #
                            #
                            ps  = "Bus: %s  Device: %s" % ( str(bus.dirname), str(dev.filename) )


                            fnd = 0
                            if  not fd :
                                try :
                                    fd  = tzlib.read_whole_text_file("/var/log/messages")
                                except IOError :
                                    fd  = ""
                                pass
                            if  not fd :
                                break

                            ba  = str(int(str(bus.dirname),  10))
                            da  = str(int(str(dev.filename), 10))
                            fre = re.compile(r" usb " + ba + r"-\d[^\n]+? and address " + da + r".*? usb " + ba + r"-\d[^\n]+? now attached to (\S+)", re.DOTALL)
                            fa  = fre.findall(fd)
                            if  fa  :
                                ps  = "/dev/" + fa[-1]
                                ports.append(ps)
                                fnd = 1
                            ba  = str(int(str(bus.dirname),  10))
                            da  = str(int(str(dev.filename), 10))
                            fre = re.compile(r"cdc_acm\s+%s-%s[\d:\.]+\s+(ttyACM\d+): USB ACM device" % ( ba, da, ), re.DOTALL)
                            fa  = fre.findall(fd)
                            if  fa  :
                                ps  = "/dev/" + fa[-1]
                                ports.append(ps)
                                fnd = 1
                            if  list_level + fnd >= 2 :
                                print ps
                            pass
                        pass
                    pass
                pass

            if  False and (vendor_id is None) and (product_id is None) and (serial_number is None) :
                ports.append(glob.glob('/dev/ttyACM*'))             # can only find these generically. Oooof. And, since we examine all USB devices with the True in the if statement looking at the class and protocol, we don't need this code
            pass
        pass

    ports.sort()

    return(ports)