Ejemplo n.º 1
0
def comports():
    # Scan for all iokit serial ports
    services = GetIOServicesByType('IOSerialBSDClient')
    ports = []
    serial_interfaces = scan_interfaces()
    for service in services:
        # First, add the callout device file.
        device = get_string_property(service, "IOCalloutDevice")
        if device:
            info = list_ports_common.ListPortInfo(device)
            # If the serial port is implemented by IOUSBDevice
            usb_device = GetParentDeviceByType(service, "IOUSBDevice")
            if usb_device:
                # fetch some useful informations from properties
                info.vid = get_int_property(usb_device, "idVendor",
                                            kCFNumberSInt16Type)
                info.pid = get_int_property(usb_device, "idProduct",
                                            kCFNumberSInt16Type)
                info.serial_number = get_string_property(
                    usb_device, "USB Serial Number")
                info.product = get_string_property(usb_device,
                                                   "USB Product Name") or 'n/a'
                info.manufacturer = get_string_property(
                    usb_device, "USB Vendor Name")
                locationID = get_int_property(usb_device, "locationID",
                                              kCFNumberSInt32Type)
                info.location = location_to_string(locationID)
                info.interface = search_for_locationID_in_interfaces(
                    serial_interfaces, locationID)
                info.apply_usb_info()
            ports.append(info)
    return ports
Ejemplo n.º 2
0
def comports():
    GUIDs = (GUID * 8)()  # so far only seen one used, so hope 8 are enough...
    guids_size = DWORD()
    if not SetupDiClassGuidsFromName(Ports, GUIDs, ctypes.sizeof(GUIDs),
                                     ctypes.byref(guids_size)):
        raise ctypes.WinError()

    # repeat for all possible GUIDs
    for index in range(guids_size.value):
        g_hdi = SetupDiGetClassDevs(
            ctypes.byref(GUIDs[index]), None, NULL, DIGCF_PRESENT
        )  # was DIGCF_PRESENT|DIGCF_DEVICEINTERFACE which misses CDC ports

        devinfo = SP_DEVINFO_DATA()
        devinfo.cbSize = ctypes.sizeof(devinfo)
        index = 0
        while SetupDiEnumDeviceInfo(g_hdi, index, ctypes.byref(devinfo)):
            index += 1

            # get the real com port name
            hkey = SetupDiOpenDevRegKey(
                g_hdi,
                ctypes.byref(devinfo),
                DICS_FLAG_GLOBAL,
                0,
                DIREG_DEV,  # DIREG_DRV for SW info
                KEY_READ)
            port_name_buffer = byte_buffer(250)
            port_name_length = ULONG(ctypes.sizeof(port_name_buffer))
            RegQueryValueEx(hkey, PortName, None, None,
                            ctypes.byref(port_name_buffer),
                            ctypes.byref(port_name_length))
            RegCloseKey(hkey)

            # unfortunately does this method also include parallel ports.
            # we could check for names starting with COM or just exclude LPT
            # and hope that other "unknown" names are serial ports...
            if string(port_name_buffer).startswith('LPT'):
                continue

            # hardware ID
            szHardwareID = byte_buffer(250)
            # try to get ID that includes serial number
            if not SetupDiGetDeviceInstanceId(
                    g_hdi, ctypes.byref(devinfo), ctypes.byref(szHardwareID),
                    ctypes.sizeof(szHardwareID) - 1, None):
                # fall back to more generic hardware ID if that would fail
                if not SetupDiGetDeviceRegistryProperty(
                        g_hdi, ctypes.byref(devinfo), SPDRP_HARDWAREID, None,
                        ctypes.byref(szHardwareID),
                        ctypes.sizeof(szHardwareID) - 1, None):
                    # Ignore ERROR_INSUFFICIENT_BUFFER
                    if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
                        raise ctypes.WinError()
            # stringify
            szHardwareID_str = string(szHardwareID)

            info = list_ports_common.ListPortInfo(string(port_name_buffer))

            # in case of USB, make a more readable string, similar to that form
            # that we also generate on other platforms
            if szHardwareID_str.startswith('USB'):
                m = re.search(r'VID_([0-9a-f]{4})&PID_([0-9a-f]{4})(\\(\w+))?',
                              szHardwareID_str, re.I)
                if m:
                    info.vid = int(m.group(1), 16)
                    info.pid = int(m.group(2), 16)
                    if m.group(4):
                        info.serial_number = m.group(4)
                # calculate a location string
                loc_path_str = byte_buffer(250)
                if SetupDiGetDeviceRegistryProperty(
                        g_hdi, ctypes.byref(devinfo), SPDRP_LOCATION_PATHS,
                        None, ctypes.byref(loc_path_str),
                        ctypes.sizeof(loc_path_str) - 1, None):
                    #~ print (string(loc_path_str))
                    m = re.finditer(r'USBROOT\((\w+)\)|#USB\((\w+)\)',
                                    string(loc_path_str))
                    location = []
                    for g in m:
                        if g.group(1):
                            location.append('%d' % (int(g.group(1)) + 1))
                        else:
                            if len(location) > 1:
                                location.append('.')
                            else:
                                location.append('-')
                            location.append(g.group(2))
                    if location:
                        info.location = ''.join(location)
                info.hwid = info.usb_info()
            elif szHardwareID_str.startswith('FTDIBUS'):
                m = re.search(
                    r'VID_([0-9a-f]{4})\+PID_([0-9a-f]{4})(\+(\w+))?',
                    szHardwareID_str, re.I)
                if m:
                    info.vid = int(m.group(1), 16)
                    info.pid = int(m.group(2), 16)
                    if m.group(4):
                        info.serial_number = m.group(4)
                # USB location is hidden by FDTI driver :(
                info.hwid = info.usb_info()
            else:
                info.hwid = szHardwareID_str

            # friendly name
            szFriendlyName = byte_buffer(250)
            if SetupDiGetDeviceRegistryProperty(
                    g_hdi,
                    ctypes.byref(devinfo),
                    SPDRP_FRIENDLYNAME,
                    #~ SPDRP_DEVICEDESC,
                    None,
                    ctypes.byref(szFriendlyName),
                    ctypes.sizeof(szFriendlyName) - 1,
                    None):
                info.description = string(szFriendlyName)
            #~ else:
            # Ignore ERROR_INSUFFICIENT_BUFFER
            #~ if ctypes.GetLastError() != ERROR_INSUFFICIENT_BUFFER:
            #~ raise IOError("failed to get details for %s (%s)" % (devinfo, szHardwareID.value))
            # ignore errors and still include the port in the list, friendly name will be same as port name
            yield info
        SetupDiDestroyDeviceInfoList(g_hdi)
Ejemplo n.º 3
0
 def comports():
     devices = glob.glob('/dev/cua*[!.init][!.lock]')
     return [list_ports_common.ListPortInfo(d) for d in devices]
Ejemplo n.º 4
0
 def comports():
     """scan for available ports. return a list of device names."""
     devices = glob.glob('/dev/tty*')
     return [list_ports_common.ListPortInfo(d) for d in devices]
Ejemplo n.º 5
0
 def comports():
     devices = glob.glob('/dev/ttyS*')
     return [list_ports_common.ListPortInfo(d) for d in devices]