aboutsummaryrefslogtreecommitdiff
path: root/serial/tools/list_ports_linux.py
diff options
context:
space:
mode:
Diffstat (limited to 'serial/tools/list_ports_linux.py')
-rw-r--r--serial/tools/list_ports_linux.py38
1 files changed, 31 insertions, 7 deletions
diff --git a/serial/tools/list_ports_linux.py b/serial/tools/list_ports_linux.py
index 0dfa81f..9346ae9 100644
--- a/serial/tools/list_ports_linux.py
+++ b/serial/tools/list_ports_linux.py
@@ -8,6 +8,8 @@
#
# SPDX-License-Identifier: BSD-3-Clause
+from __future__ import absolute_import
+
import glob
import os
from serial.tools import list_ports_common
@@ -18,7 +20,12 @@ class SysFS(list_ports_common.ListPortInfo):
def __init__(self, device):
super(SysFS, self).__init__(device)
- self.name = os.path.basename(device)
+ # special handling for links
+ if device is not None and os.path.islink(device):
+ device = os.path.realpath(device)
+ is_link = True
+ else:
+ is_link = False
self.usb_device_path = None
if os.path.exists('/sys/class/tty/{}/device'.format(self.name)):
self.device_path = os.path.realpath('/sys/class/tty/{}/device'.format(self.name))
@@ -28,17 +35,28 @@ class SysFS(list_ports_common.ListPortInfo):
self.subsystem = None
# check device type
if self.subsystem == 'usb-serial':
- self.usb_device_path = os.path.dirname(os.path.dirname(self.device_path))
+ self.usb_interface_path = os.path.dirname(self.device_path)
elif self.subsystem == 'usb':
- self.usb_device_path = os.path.dirname(self.device_path)
+ self.usb_interface_path = self.device_path
else:
- self.usb_device_path = None
+ self.usb_interface_path = None
# fill-in info for USB devices
- if self.usb_device_path is not None:
+ if self.usb_interface_path is not None:
+ self.usb_device_path = os.path.dirname(self.usb_interface_path)
+
+ try:
+ num_if = int(self.read_line(self.usb_device_path, 'bNumInterfaces'))
+ except ValueError:
+ num_if = 1
+
self.vid = int(self.read_line(self.usb_device_path, 'idVendor'), 16)
self.pid = int(self.read_line(self.usb_device_path, 'idProduct'), 16)
self.serial_number = self.read_line(self.usb_device_path, 'serial')
- self.location = os.path.basename(self.usb_device_path)
+ if num_if > 1: # multi interface devices like FT4232
+ self.location = os.path.basename(self.usb_interface_path)
+ else:
+ self.location = os.path.basename(self.usb_device_path)
+
self.manufacturer = self.read_line(self.usb_device_path, 'manufacturer')
self.product = self.read_line(self.usb_device_path, 'product')
self.interface = self.read_line(self.device_path, 'interface')
@@ -53,6 +71,9 @@ class SysFS(list_ports_common.ListPortInfo):
self.description = self.name
self.hwid = os.path.basename(self.device_path)
+ if is_link:
+ self.hwid += ' LINK={}'.format(device)
+
def read_line(self, *args):
"""\
Helper function to read a single line from a file.
@@ -67,13 +88,16 @@ class SysFS(list_ports_common.ListPortInfo):
return None
-def comports():
+def comports(include_links=False):
devices = glob.glob('/dev/ttyS*') # built-in serial ports
devices.extend(glob.glob('/dev/ttyUSB*')) # usb-serial with own driver
+ devices.extend(glob.glob('/dev/ttyXRUSB*')) # xr-usb-serial port exar (DELL Edge 3001)
devices.extend(glob.glob('/dev/ttyACM*')) # usb-serial with CDC-ACM profile
devices.extend(glob.glob('/dev/ttyAMA*')) # ARM internal port (raspi)
devices.extend(glob.glob('/dev/rfcomm*')) # BT serial devices
devices.extend(glob.glob('/dev/ttyAP*')) # Advantech multi-port serial controllers
+ if include_links:
+ devices.extend(list_ports_common.list_links(devices))
return [info
for info in [SysFS(d) for d in devices]
if info.subsystem != "platform"] # hide non-present internal serial ports