Hot to initialize LTE module using libqmi and systemd-network (networkd-dispatcher)

813 Views Asked by At

I want to initialize the lte module using libqmi and networkd-dispatcher. What I got so far is a shell script which is located at /etc/networkd-dispatcher/degraded.d/01-wwan.sh

     #!/bin/bash
    
    interface="${IFACE}"
    
    if [[ "$interface" == *"wwan"* ]]; then
      device="/dev/cdc-wdm${interface: -1}"
      is_wwan="y"
    fi
    
    if [[ "$is_wwan" == "y" ]]; then
      ip link set dev "${interface}" down
      echo "Y" > "/sys/class/net/${interface}/qmi/raw_ip"
      qmi-network "${device}" start || true
      qmicli -p -d "${device}" --wds-set-autoconnect-settings=enabled || true
      ip link set dev "${interface}" up
    fi

My problem now is that this script is called over and over again sometimes after an reboot and takes some time to be stable. I thought if I add a sleep 10s after taking it link up it solves the issue, but it doesn't. Any suggestions how to fix this?

1

There are 1 best solutions below

0
On BEST ANSWER

Sorry it's a bit late but just came across this question.

If just for the sake of completeness, a method that I found to be quite predictable and reliable is to link a systemd service file that starts a script with a udev rule:

Create a file in /etc/udev/rules.d, for example 10-lte-modem.rules, which should look like this:

SUBSYSTEM=="net",ACTION=="add",ENV{PRODUCT}=="PID-of-modem", TAG+="systemd",ENV{SYSTEMD_WANTS}

Note you can use different triggers, for example if your modem is at a fixed port on a usb hub then you can use KERNELS="1-1.1". The point is to trigger the systemd service on the enumeration of the modem (which allows you to reboot the modem and your script will automatically re-run). You also might have to add in a NAME= field to give your interface a deterministic name.

In your systemd service file that will start your script, you have something like:

[Unit]
ConditionPathExists=|!/sys/class/net/wwan1
ConditionPathExists=|!/sys/class/net/wwan2

[Service]
Type=simple
Restart=always
RemainAfterExit=no
ExecStart=/bin/sh /etc/networkd-dispatcher/degraded.d/01-wwan.sh

The |! syntax in systemd allows you to OR different conditions.

Depending on the exact setup of your system, like whether its a PCIe modem or USB, you might have to play around with the udev and systemd settings to get what you want, but I've found it results in very stable behaviour.