From 1c7d7cbd3963428888068af679946e6329567451 Mon Sep 17 00:00:00 2001 From: Christian Poessinger Date: Sun, 7 Jun 2020 14:04:36 +0200 Subject: wwan: T2529: migrate device from ttyUSB to usbXbY.YpZ.Z During testing it was discovered that there is a well known problem (we had for ethernet interfaces) also in the serial port world. They will be enumerated and mapped to /dev/ttyUSBxxx differently from boot to boot. This is especially painful on my development APU4 board which also has a Sierra Wireless MC7710 LTE module installed. The serial port will toggle between ttyUSB2 and ttyUSB5 depending on the amount of serial port extenders attached (FT4232H). The shipped udev rule (/usr/lib/udev/rules.d/60-serial.rules) partly solves this by enumerating the devices into /dev/serial/by-id folder with their name and serial number - it's a very good idea but I've found that not all of the FT4232H dongles have a serial number programmed - this leads to the situation that when you plug in two cables with both having serial number 0 - only one device symlink will appear - the previous one is always overwritten by the latter one. Derive /usr/lib/udev/rules.d/60-serial.rules and create a /dev/serial/by-bus directory and group devices by attached USB root port. vyos@vyos:~$ find /dev/serial/by-bus/ -name usb* -exec basename {} \; | sort usb0b1.3p1.0 usb0b1.3p1.2 usb0b1.3p1.3 usb0b2.4p1.0 usb0b2.4p1.1 usb0b2.4p1.2 usb0b2.4p1.3 So we have USB root 0 with bus 1.3 and port 1.0. The enumeration is constant accross reboots. --- src/conf_mode/interfaces-wirelessmodem.py | 32 +++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) (limited to 'src/conf_mode/interfaces-wirelessmodem.py') diff --git a/src/conf_mode/interfaces-wirelessmodem.py b/src/conf_mode/interfaces-wirelessmodem.py index a13c70990..f16457a7f 100755 --- a/src/conf_mode/interfaces-wirelessmodem.py +++ b/src/conf_mode/interfaces-wirelessmodem.py @@ -16,9 +16,10 @@ import os -from sys import exit from copy import deepcopy +from fnmatch import fnmatch from netifaces import interfaces +from sys import exit from vyos.config import Config from vyos.ifconfig import BridgeIf, Section @@ -36,7 +37,7 @@ default_config_data = { 'chat_script': '', 'deleted': False, 'description': '', - 'device': 'ttyUSB0', + 'device': '', 'disable': False, 'disable_link_detect': 1, 'on_demand': False, @@ -56,6 +57,16 @@ def check_kmod(): if call(f'modprobe {module}') != 0: raise ConfigError(f'Loading Kernel module {module} failed') +def find_device_file(device): + """ Recurively search /dev for the given device file and return its full path. + If no device file was found 'None' is returned """ + for root, dirs, files in os.walk('/dev'): + for basename in files: + if fnmatch(basename, device): + return os.path.join(root, basename) + + return None + def get_config(): wwan = deepcopy(default_config_data) conf = Config() @@ -93,7 +104,13 @@ def get_config(): # System device name if conf.exists(['device']): - wwan['device'] = conf.return_value(['device']) + tmp = conf.return_value(['device']) + wwan['device'] = find_device_file(tmp) + # If device file was not found in /dev we will just re-use + # the plain device name, thus we can trigger the exception + # in verify() as it's a non existent file + if wwan['device'] == None: + wwan['device'] = tmp # disable interface if conf.exists('disable'): @@ -131,7 +148,10 @@ def verify(wwan): return None if not wwan['apn']: - raise ConfigError(f"APN for {wwan['intf']} not configured") + raise ConfigError('No APN configured for "{intf}"'.format(**wwan)) + + if not wwan['device']: + raise ConfigError('Physical "device" must be configured') # we can not use isfile() here as Linux device files are no regular files # thus the check will return False @@ -169,7 +189,7 @@ def generate(wwan): script_wwan_ip_up, script_wwan_ip_down] # Always hang-up WWAN connection prior generating new configuration file - cmd(f'systemctl stop ppp@{intf}.service') + call(f'systemctl stop ppp@{intf}.service') if wwan['deleted']: # Delete PPP configuration files @@ -205,9 +225,9 @@ def apply(wwan): if not wwan['disable']: # "dial" WWAN connection intf = wwan['intf'] - cmd(f'systemctl start ppp@{intf}.service') # make logfile owned by root / vyattacfg chown(wwan['logfile'], 'root', 'vyattacfg') + call(f'systemctl start ppp@{intf}.service') # re-add ourselves to any bridge we might have fallen out of # FIXME: wwan isn't under vyos.ifconfig so we can't call -- cgit v1.2.3