One of the things that has long annoyed me is that the internet periodically stops working on the Librem 5’s BM818 cellular modem. If I use the hardware kill switch to turn the modem off and then back on, the internet connection comes back.
Since I find it annoying to have to keep manually turning on and off the modem, I thought that I would write a script that periodically checks if there is internet, and if not, it would turn the modem off and then back on to bring back the internet.
However, all the ways that I have tried to turn off and on the modem don’t bring back the internet.
I tried restarting the ModemManager, but that doesn’t fix the problem:
sudo systemctl restart ModemManager
I also tried using resetting the USB connection to the modem:
sudo udevadm trigger --action=change --name-match=/sys/devices/platform/soc@0/38200000.usb/xhci-hcd.4.auto/usb1/1-1/1-1.2/1-1.2:1.0/ttyUSB0/tty/ttyUSB0
I tried unbinding the USB:
echo '1-1.2' | sudo tee /sys/bus/usb/drivers/usb/unbind
echo '1-1.2' | sudo tee /sys/bus/usb/drivers/usb/bind
Then, I found Chris Vogel’s librem5-recover-xhci-usb.sh script at: https://git.sr.ht/~chrichri/librem5-bm818-watchmodem
He uses this code to recover the USB hub and restart the modem:
rmmod xhci_plat_hcd xhci_hcd
echo 0 > /sys/class/leds/wwan_en/brightness
sleep 2
modprobe xhci_plat_hcd
sleep 5
echo 1 > /sys/class/leds/wwan_en/brightness
The file /sys/class/leds/wwan_en/brightness doesn’t exist in Crimson, so I tried to find equivalent files in Crimson:
rmmod xhci_plat_hcd xhci_hcd
echo 1 > /sys/class/leds/wwan_disable/brightness
sleep 2
modprobe xhci_plat_hcd
sleep 5
echo 0 > /sys/class/leds/wwan_disable/brightness
However, rmmod xhci_plat_hcd xhci_hcd causes the terminal to freeze and echo 1 > /sys/class/leds/wwan_disable/brightness doesn’t seem to have any effect.
Is there any way to turn the modem off and on that has the same effect as turning off and on the hardware kill switch for the modem?
PS: I wrote the following script to restart the modem if there is no internet, that I planned to execute as a cronjob, but I can’t figure out how to power cycle the modem:
#!/usr/bin/env python3
import subprocess
import logging
try:
logger = logging.getLogger(__name__)
logging.basicConfig(filename='/var/log/qmi_wwan.log',
format='%(asctime)s: %(message)s', level=logging.WARNING)
result = subprocess.run(["ping", "-c 1", "-t 19", "8.8.8.8"], capture_output=True, text=True, timeout=20)
#if no internet, then restart the modem
if result.stdout.find("ttl") == -1:
#Can't find the darn commands to power cycle the modem:
ret = subprocess.call("**turn off the modem**", shell=True)
ret = subprocess.call("**turn on the modem**", shell=True)
logging.warning("Restarted qmi_wwan.")
else:
logging.info("qmi_wwan working.")
except subprocess.CalledProcessError as e:
logging.error(f"Command failed with return code: {e.returncode}")
logging.error(f"stderr: {e.stderr.strip()}")