ModemManager Hotplug script: Request for review

This hotplug script is intended to work with ModemManager connections to keep the modem connection up and running. Sometimes ModemManager will think the modem is connected even though the data session is inactive. I don't have a full understanding, but I surmise it is basically because the object referencing the previous state of the modem (bearers, modem, etc) has gone stale. The way I'm working around this is to just restart the ModemManager service and bring the iface back up.

One problem at the moment is if you disable/stop the modem interface it will be restarted by the hotplug script. Is there a hotplug event that could be used to not fire the script in that case? Or Perhaps just reference a UCI configuration element?

Currently it only works with ModemManager 1.8, but work on updating it to 1.10 should start soon.

Refactored

1 Like
  1. Useless use of cat:
cat FILE | grep PATTERN

grep PATTERN FILE
  1. Deadline for ping is mandatory:
ping ...

ping -w 30 ...
  1. Extract large command blocks:
if EXPR; then
    LARGE_BLOCK_OF_COMMANDS
fi
EOF

if ! EXPR; then
    exit
fi
LARGE_BLOCK_OF_COMMANDS
EOF
1 Like

Thank you for the suggestions. It makes sense

  1. Use grep only, so it just uses one command
  2. So we put a maximum running time on that command
  3. To exit early to save some CPU cycles
1 Like

Is there currently any way to restart an interface that went down? I have a Rasbperry Pi 4 with 4 huawei e3372h-320. They work fine most of the time, but at certain points they get disconnected and I have to either manually restart them from Luci or ifup from cli. I tried also to do the same from mwan3.user with

if [ "${ACTION}" = "disconnected" ] && [ "${INTERFACE}" = "tmobile" ] ; then
curl -X POST --silent --data-urlencode \
"payload={\"text\": \"<@UA9128UNL> <@U671KBC4W4S> whale tmobile down\"}" \
https://hooks.slack.com/services/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
ifdown tmobile ; sleep 5; ifup tmobile
fi

I get the slack notification, but the interface remains down. I'd prefer to restart only the interface and not the whole modemmanager, as the rest of the interfaces are working.

You might want to look into issuing a reboot command to that particular modem before doing an ifup of that modem's OpenWrt interface. If you don't care about preserving the Modem object state, a straightforward way to achieve this via ModemManager is by sending your modem's reboot AT command to that modem via --command.

Most of the times it seems that a modem reconnection is enough before issuing the ifup. To automate it I came up with the following script. It waits until the modem reaches a registered state, when connection is possible. Not very elegant, but open to suggestions.

#!/bin/sh

for i in $(/usr/bin/mmcli -L | cut -d '/' -f 6 | cut -b 1)
do
        echo Setting state for modem $i.
        state=$(/usr/bin/mmcli -m $i | grep "|             state:" | cut -d ':' -f 2 | cut -d ' ' -f 2 | sed -r "s/\x1B\[([0-9]{1,3}(;[0-9]{1,2})?)?[mGK]//g")
        #echo "state set"
        echo Modem $i is in $state state.
        while [ $state != "connected" ]
                do
                        echo "entered while"
                        if [ $state == "registered" ]
                        then
                                echo "registered state, connecting..."
                                /usr/bin/mmcli -m $i --simple-connect="apn=internet,ip-type=ipv4,allow-roaming=yes"
                                sleep 15
                                echo "setting new state"
                                state=$(/usr/bin/mmcli -m $i | grep "|             state:" | cut -d ':' -f 2 | cut -d ' ' -f 2 | sed -r "s/\x1B\[([0-9]{1,3}(;[0-9]{1,2})?)?[mGK]//g")
                                echo New state is $state
                        else
                                echo Not Registered.
                                sleep 5
                                state=$(/usr/bin/mmcli -m $i | grep "|             state:" | cut -d ':' -f 2 | cut -d ' ' -f 2 | sed -r "s/\x1B\[([0-9]{1,3}(;[0-9]{1,2})?)?[mGK]//g")
                        fi
                done
done
echo All connected, bye...

edit: fixed the formatting of the connected which didn't work with the comparison in while.