Add web GUI, docs, scripts, and 5G router config
- Web app (Flask): status, config, firewall, logs, users, restart - Docs: AT commands, deploy, DNS, quickstart, web GUI - Scripts: connect, deploy, diag, healthcheck, modem-status, speedtest, status, troubleshoot - Init and iptables: 5g-router, 5g-webgui, rules.v4 - CHANGELOG, TODO, REVISION; config and README updates
This commit is contained in:
105
scripts/modem-status-at.sh
Normal file
105
scripts/modem-status-at.sh
Normal file
@@ -0,0 +1,105 @@
|
||||
#!/bin/sh
|
||||
# Alpine 5G Router – modem status via AT commands (AT_COMMANDS_REFERENCE.md)
|
||||
# Outputs JSON. Used by Web GUI /api/status.
|
||||
# Rev: 2 (see REVISION in repo root)
|
||||
|
||||
CONFIG="/etc/5g-router.conf"
|
||||
AT_PORT="${AT_PORT:-/dev/ttyUSB1}"
|
||||
[ -f "$CONFIG" ] && . "$CONFIG"
|
||||
|
||||
get_at() {
|
||||
_cmd="$1"
|
||||
_wait="${2:-1}"
|
||||
timeout $((_wait + 2)) sh -c "
|
||||
cat $AT_PORT 2>/dev/null &
|
||||
_p=\$!
|
||||
sleep 0.3
|
||||
echo -e '${_cmd}\r' > $AT_PORT
|
||||
sleep $_wait
|
||||
kill \$_p 2>/dev/null
|
||||
" 2>/dev/null
|
||||
}
|
||||
|
||||
json_str() { printf '"%s"' "$(echo "$1" | sed 's/\\/\\\\/g; s/"/\\"/g; s/\r//g' | tr '\n' ' ')"; }
|
||||
|
||||
# Probe port: send AT, return 0 if we see OK
|
||||
try_at_port() {
|
||||
_port="$1"
|
||||
[ ! -c "$_port" ] && return 1
|
||||
_out=$(timeout 4 sh -c "
|
||||
cat $_port 2>/dev/null &
|
||||
_p=\$!
|
||||
sleep 0.3
|
||||
echo -e 'AT\r' > $_port
|
||||
sleep 1
|
||||
kill \$_p 2>/dev/null
|
||||
" 2>/dev/null)
|
||||
echo "$_out" | grep -q 'OK' && return 0 || return 1
|
||||
}
|
||||
|
||||
# Use configured port if it exists and is a char device; else try common Fibocom AT ports
|
||||
if [ ! -c "$AT_PORT" ]; then
|
||||
for p in /dev/ttyUSB0 /dev/ttyUSB1 /dev/ttyUSB2; do
|
||||
if try_at_port "$p"; then
|
||||
AT_PORT="$p"
|
||||
break
|
||||
fi
|
||||
done
|
||||
fi
|
||||
|
||||
[ ! -c "$AT_PORT" ] && echo '{}' && exit 0
|
||||
|
||||
# Disable command echo so we get only response lines (ATE0); avoids parsing "AT+CGMI" as manufacturer
|
||||
get_at "ATE0" 1 >/dev/null 2>&1
|
||||
sleep 0.2
|
||||
|
||||
# Query AT commands (reference: AT_COMMANDS_REFERENCE.md)
|
||||
r_cgmi=$(get_at "AT+CGMI" 1)
|
||||
r_cgmm=$(get_at "AT+CGMM" 1)
|
||||
r_cgmr=$(get_at "AT+CGMR" 1)
|
||||
r_cgsn=$(get_at "AT+CGSN" 1)
|
||||
r_csq=$(get_at "AT+CSQ" 1)
|
||||
r_creg=$(get_at "AT+CREG?" 1)
|
||||
r_cereg=$(get_at "AT+CEREG?" 1)
|
||||
r_usbmode=$(get_at "AT+GTUSBMODE?" 1)
|
||||
r_ccid=$(get_at "AT+CCID" 1)
|
||||
r_cops=$(get_at "AT+COPS?" 1)
|
||||
r_cgpaddr=$(get_at "AT+CGPADDR=1" 1)
|
||||
|
||||
# Parse (skip echoed command lines: lines starting with AT or +)
|
||||
manufacturer=$(echo "$r_cgmi" | grep -vE '^AT|^\+' | grep -oE '^[A-Za-z0-9 ].*' | head -1 | sed 's/\r$//; s/^ *//; s/ *$//')
|
||||
model=$(echo "$r_cgmm" | grep -vE '^AT|^\+' | grep -oE '^[A-Za-z0-9\-].*' | head -1 | sed 's/\r$//; s/^ *//; s/ *$//')
|
||||
revision=$(echo "$r_cgmr" | grep -vE '^(AT|OK|\+)' | head -1 | sed 's/\r$//; s/^ *//; s/ *$//')
|
||||
imei=$(echo "$r_cgsn" | grep -oE '[0-9]{15}' | head -1)
|
||||
csq=$(echo "$r_csq" | grep "+CSQ:" | grep -oE '[0-9]+' | head -1)
|
||||
creg=$(echo "$r_creg" | grep "+CREG:" | head -1)
|
||||
cereg=$(echo "$r_cereg" | grep "+CEREG:" | head -1)
|
||||
usb_mode=$(echo "$r_usbmode" | grep "+GTUSBMODE:" | grep -oE '[0-9]+' | head -1)
|
||||
iccid=$(echo "$r_ccid" | grep "+CCID:" | sed 's/+CCID:[[:space:]]*//; s/\r$//; s/"//g' | head -1)
|
||||
cops=$(echo "$r_cops" | grep "+COPS:" | sed 's/+COPS:[[:space:]]*//; s/\r$//' | head -1)
|
||||
modem_ip=$(echo "$r_cgpaddr" | grep "+CGPADDR:" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | head -1)
|
||||
|
||||
# Registration: CREG 0,1 = registered home, 0,5 = registered roaming; CEREG same
|
||||
creg_status=""
|
||||
case "$creg" in *",1"*) creg_status="registered_home";; *",5"*) creg_status="registered_roaming";; *",2"*) creg_status="searching";; *",0"*) creg_status="not_registered";; *) creg_status="unknown";; esac
|
||||
cereg_status=""
|
||||
case "$cereg" in *",1"*) cereg_status="registered_home";; *",5"*) cereg_status="registered_roaming";; *",2"*) cereg_status="searching";; *",0"*) cereg_status="not_registered";; *) cereg_status="unknown";; esac
|
||||
|
||||
# Operator name from +COPS: 0,0,"Vodafone",7
|
||||
operator_name=$(echo "$cops" | sed -n 's/.*"\([^"]*\)".*/\1/p')
|
||||
|
||||
# Build JSON (no jq)
|
||||
printf '{\n'
|
||||
printf ' "at_port": '; json_str "$AT_PORT"; printf ',\n'
|
||||
printf ' "manufacturer": '; json_str "${manufacturer:-}"; printf ',\n'
|
||||
printf ' "model": '; json_str "${model:-}"; printf ',\n'
|
||||
printf ' "revision": '; json_str "${revision:-}"; printf ',\n'
|
||||
printf ' "imei": '; json_str "${imei:-}"; printf ',\n'
|
||||
printf ' "signal_csq": %s,\n' "${csq:-null}"
|
||||
printf ' "creg_status": '; json_str "$creg_status"; printf ',\n'
|
||||
printf ' "cereg_status": '; json_str "$cereg_status"; printf ',\n'
|
||||
printf ' "usb_mode": '; json_str "${usb_mode:-}"; printf ',\n'
|
||||
printf ' "iccid": '; json_str "${iccid:-}"; printf ',\n'
|
||||
printf ' "operator": '; json_str "${operator_name:-}"; printf ',\n'
|
||||
printf ' "modem_ip": '; json_str "${modem_ip:-}"; printf '\n'
|
||||
printf '}\n'
|
||||
Reference in New Issue
Block a user