Created
February 27, 2024 12:55
-
-
Save odevodyssey/52ff8daf2ea8aa40ecee4c798789b7ca to your computer and use it in GitHub Desktop.
Scripts to monitor cellular connection for 4G LTE RPi on OpenWrt
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/bin/sh | |
# Internet Monitoring Script for QMI Modem | |
# Modem: Quectel EG25-G | |
# Script inspired from conmon.sh in ROOter project. | |
# https://www.ofmodemsandmen.com/ | |
# What is most likely to happen in my experience is modem gets a new IP from ISP, randomly, and interface does not update, therefore outbound traffic stops | |
# This script will cover both scenarios | |
# Scenario 1: Obtain new IP by forcing udhcpc to get new address. Verify address with AT command IP. If not the same, repeat until IP is the same | |
# Scenario 2: IPs are the same, outbound traffic not working, reset modem | |
# But so far, easier to only implement Scenario 2, and by that, resetting the modem when there is any connection issue | |
# At worst case scenario, router restart | |
# Define variables | |
GCOM_DIR="/etc/gcom" | |
CPORT=2 | |
RST_CNT=0 | |
RST_CNT_FLR=2 | |
PKT_LOSS_FLR=40 | |
SLEEP_TIME=30 | |
SLEEP_PLUS=10 | |
SLEEP_CNT=0 | |
SLEEP_CNT_FLR=3 | |
TRCK_IP="8.8.8.8" | |
# Define functions | |
# unused function, for now | |
restart_udhcpc() { | |
udhcpc_pid=$(pidof udhcpc) | |
/bin/kill -SIGUSR2 $(udhcpc_pid) | |
/bin/kill -SIGUSR1 $(udhcpc_pid) | |
} | |
log() { | |
logger -t "conmond" "$@" | |
} | |
get_modem_ip() { | |
# run gcom script | |
export ATCMD="AT+CGPADDR" | |
local ATRES=$(comgt -d "/dev/ttyUSB$CPORT" -s $GCOM_DIR/run-at.gcom) | |
# parse variable output, return modem IP | |
local modem_ip=$(echo $ATRES | cut -d "," -s -f2 | cut -d "\"" -s -f2) | |
log "Obtained Modem IP: $modem_ip using command $ATCMD" | |
unset ATCMD | |
echo $modem_ip | |
} | |
get_wwan0_ip() { | |
local wwan0_ip=$(ip addr show wwan0 | grep 'inet ' | cut -d' ' -f6 | cut -d "/" -s -f1) | |
log "Obtained wwan0 IP: $wwan0_ip" | |
echo $wwan0_ip | |
} | |
reset_modem() { | |
export ATCMD="AT+CFUN=4;+CFUN=1,1" | |
comgt -d "/dev/ttyUSB$CPORT" -s $GCOM_DIR/run-at.gcom | |
log "Modem reset with command $ATCMD" | |
unset ATCMD | |
} | |
check_rsts_reboot() { | |
if [ "$RST_CNT" -gt "$RST_CNT_FLR" ]; then | |
log "Modem Reset $RST_CNT times failed to restart internet. Rebooting now ..." | |
reboot -f | |
fi | |
} | |
check_internet() { | |
# Perform Ping Test to check for connectivitiy issues | |
# Ping Test Fails > Obtain IP (v4) of interface and check against IP from AT command | |
initial_wwan0_ip=$(get_wwan0_ip) | |
pkt_loss=$(ping -c 5 $TRCK_IP | tail -2 | head -1 | awk '{print $7}' | sed 's/.$//') | |
if [ -z $pkt_loss ]; then | |
pkt_loss=100 | |
fi | |
if [ "$pkt_loss" -gt "$PKT_LOSS_FLR" ]; then | |
check_rsts_reboot | |
RST_CNT=$((RST_CNT+1)) | |
log "$pkt_loss% is greater than $PKT_LOSS_FLR%, Internet Down" | |
log "Initiate modem reset $RST_CNT" | |
reset_modem | |
sleep $SLEEP_TIME | |
modem_ip=$(get_modem_ip) | |
wwan0_ip=$(get_wwan0_ip) | |
while [ -z "$modem_ip" ] && [ "$SLEEP_CNT" -lt "$SLEEP_CNT_FLR" ] | |
do | |
log "Sleep $SLEEP_PLUS until Modem IP resolves" | |
sleep $SLEEP_PLUS | |
modem_ip=$(get_modem_ip) | |
SLEEP_CNT=$((SLEEP_CNT+1)) | |
done | |
SLEEP_CNT=0 | |
while [ -z "$wwan0_ip" ] && [ "$SLEEP_CNT" -lt "$SLEEP_CNT_FLR" ] | |
do | |
log "Sleep $SLEEP_PLUS until wwan0 IP resolves" | |
sleep $SLEEP_PLUS | |
wwan0_ip=$(get_wwan0_ip) | |
SLEEP_CNT=$((SLEEP_CNT+1)) | |
done | |
if [ -z "$modem_ip" ] || [ -z "$wwan0_ip" ]; then | |
check_rsts_reboot | |
RST_CNT=$((RST_CNT+1)) | |
log "Modem IP: $modem_ip or wwan0 IP: $wwan0_ip is empty | Initiate subsequent modem reset $RST_CNT" | |
reset_modem | |
sleep $SLEEP_TIME | |
check_internet | |
elif [ "$modem_ip" = "$wwan0_ip" ]; then | |
log "Modem IP: $modem_ip and wwan0 IP: $wwan0_ip match | Retest with ping" | |
check_internet | |
else | |
check_rsts_reboot | |
RST_CNT=$((RST_CNT+1)) | |
log "Modem IP: $modem_ip and wwan0 IP $wwan0_ip do not match | Initiate subsequent modem reset $RST_CNT" | |
reset_modem | |
sleep $SLEEP_TIME | |
check_internet | |
fi | |
else | |
log "Internet operational with IP: $initial_wwan0_ip" | |
exit 0 | |
fi | |
} | |
check_internet | |
# be sure to write number of reconnects to file (append latest reconnect with timestamp, regardless of reconnect method used) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
*/5 * * * * /etc/conmon.sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
opengt | |
set com 115200n81 | |
set comecho off | |
set senddelay 0.05 | |
waitquiet 1 0.2 | |
:start | |
let f=25 | |
let $x=$env("ATCMD") | |
if $x="" goto error | |
send $x | |
send "^m" | |
let t=time()+f | |
gosub getresult | |
if $s="^mTIMEOUT ERROR" print $s | |
:continue | |
exit 0 | |
:error | |
print "No ATCMD var set" | |
exit 1 | |
:getresult | |
get 1 "^m" $s | |
let x=len($s) | |
if x=0 let $s="^mTIMEOUT ERROR" | |
else print $s | |
if $s="^jOK" return | |
if $mid($s,0,6)="^jERROR" return | |
if $mid($s,0,8)="^jCOMMAND" return | |
if $mid($s,0,11)="^j+CME ERROR" return | |
if time()>t return | |
goto getresult |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment