Files
Alpine_5G/scripts/connect-5g.sh
nearxos 160ad641ce 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
2026-02-02 09:38:23 +02:00

169 lines
5.9 KiB
Bash
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/sh
# Alpine 5G Router connection script (run by 5g-router service or manually)
# Uses /etc/5g-router.conf if present. Supports watchdog and failover.
# Rev: 2 (see REVISION in repo root)
set -e
CONFIG="/etc/5g-router.conf"
LOG_FILE="/var/log/5g-router.log"
# Defaults
AT_PORT="/dev/ttyUSB1"
APN="internet"
WAN_IF="eth1"
LAN_IF="eth0.100"
FAILOVER_ENABLED="no"
FAILOVER_IF="eth0"
FAILOVER_METRIC="202"
WATCHDOG_INTERVAL="0"
LOG_SIGNAL="yes"
WEAK_SIGNAL_CSQ="10"
[ -f "$CONFIG" ] && . "$CONFIG"
log() { echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1" | tee -a "$LOG_FILE" 2>/dev/null || echo "[$(date '+%Y-%m-%d %H:%M:%S')] $1"; }
# Fix broken /dev/ttyUSB* node (if it is a regular file instead of char device - e.g. after modem reconnect)
fix_ttyusb_if_needed() {
case "$AT_PORT" in
/dev/ttyUSB[0-9]*) ;;
*) return 0 ;;
esac
[ ! -e "$AT_PORT" ] && return 0
if [ -f "$AT_PORT" ] && [ ! -c "$AT_PORT" ]; then
_num="${AT_PORT#/dev/ttyUSB}"
log "Fixing $AT_PORT (was regular file, recreating as char device)"
rm -f "$AT_PORT"
mknod "$AT_PORT" c 188 "$_num"
chmod 660 "$AT_PORT"
chown root:dialout "$AT_PORT" 2>/dev/null || true
fi
}
get_at_response() {
_cmd="$1"
_wait="${2:-2}"
timeout $((_wait + 4)) sh -c "
cat $AT_PORT 2>/dev/null &
_pid=\$!
sleep 0.5
echo \"${_cmd}\r\" > $AT_PORT
sleep $_wait
kill \$_pid 2>/dev/null
" 2>&1
}
wait_for_modem() {
log "Waiting for modem AT port..."
for _i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15; do
fix_ttyusb_if_needed
if [ -c "$AT_PORT" ]; then
log "Modem AT port available"
return 0
fi
sleep 2
done
log "Modem AT port not available"
return 1
}
check_usb_mode() {
if lsusb 2>/dev/null | grep -q "0e8d:7127"; then
log "WARN: Modem is in Mode 41 (7127). AT commands may not work. Reboot or power-cycle modem."
return 1
fi
return 0
}
do_connect() {
# eth1 (RNDIS) does NOT provide DHCP. We get IP (and DNS) only via AT commands
# and configure the interface manually. Do not run dhclient on eth1.
check_usb_mode || return 1
# Modem can take 35s to respond after boot; use 5s so service (started at boot) gets OK
get_at_response "AT" 5 | grep -q "OK" || { log "AT not OK (try longer wait or different AT port)"; return 1; }
# Signal (optional log)
_resp=$(get_at_response "AT+CSQ" 1)
_csq=$(echo "$_resp" | grep "+CSQ:" | grep -oE '[0-9]+' | head -1)
[ -n "$_csq" ] && [ "$LOG_SIGNAL" = "yes" ] && echo "$(date -Iseconds) CSQ=$_csq" >> "$LOG_FILE" 2>/dev/null || true
[ -n "$_csq" ] && [ -n "$WEAK_SIGNAL_CSQ" ] && [ "$WEAK_SIGNAL_CSQ" -gt 0 ] && [ "$_csq" -lt "$WEAK_SIGNAL_CSQ" ] && log "WARN weak signal CSQ=$_csq"
log "Configuring APN: $APN"
get_at_response "AT+CGDCONT=1,\"IP\",\"$APN\"" 2 | grep -q "OK" || true
log "Activating PDP context..."
get_at_response "AT+CGACT=1,1" 3 | grep -qE "(OK|CGEV)" || true
_ip=""
for _retry in 1 2 3 4 5; do
_resp=$(get_at_response "AT+CGPADDR=1" 2)
_ip=$(echo "$_resp" | grep "+CGPADDR:" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | head -1)
[ -n "$_ip" ] && break
[ $_retry -lt 5 ] && log "No IP yet, retry $_retry/5 in 3s..." && sleep 3
done
[ -z "$_ip" ] && log "Could not get modem IP (check signal/registration: AT+CSQ, AT+CEREG?)" && return 1
# Get DNS from modem (AT+CGCONTRDP=1); modem does not provide DHCP, only IP/DNS via AT
_dns1=""; _dns2=""
_contrdp=$(get_at_response "AT+CGCONTRDP=1" 2)
_allips=""
for _a in $(echo "$_contrdp" | grep -oE '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+'); do
[ "$_a" = "$_ip" ] && continue
_allips="${_allips} ${_a}"
done
for _a in $_allips; do [ -z "$_a" ] && continue; _dns2="$_dns1"; _dns1="$_a"; done
[ -z "$_dns1" ] && [ -n "$DNS_SERVERS" ] && _dns1=$(echo "$DNS_SERVERS" | cut -d',' -f1 | tr -d ' ') && _dns2=$(echo "$DNS_SERVERS" | cut -d',' -f2 | tr -d ' ')
if [ -n "$_dns1" ]; then
: > /etc/resolv.conf
echo "nameserver $_dns1" >> /etc/resolv.conf
[ -n "$_dns2" ] && echo "nameserver $_dns2" >> /etc/resolv.conf
log "DNS set (from modem or config)"
fi
log "Configuring $WAN_IF with IP $_ip (no DHCP - from AT+CGPADDR=1)"
ip link set "$WAN_IF" up 2>/dev/null || true
ip addr flush dev "$WAN_IF" 2>/dev/null || true
ip addr add "$_ip/32" dev "$WAN_IF"
ip route add default dev "$WAN_IF" metric 50 2>/dev/null || true
log "Interface configured"
log "Setting up NAT..."
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -C POSTROUTING -o "$WAN_IF" -j MASQUERADE 2>/dev/null || iptables -t nat -A POSTROUTING -o "$WAN_IF" -j MASQUERADE
iptables -C FORWARD -i "$LAN_IF" -o "$WAN_IF" -j ACCEPT 2>/dev/null || iptables -A FORWARD -i "$LAN_IF" -o "$WAN_IF" -j ACCEPT
iptables -C FORWARD -i "$WAN_IF" -o "$LAN_IF" -m state --state RELATED,ESTABLISHED -j ACCEPT 2>/dev/null || iptables -A FORWARD -i "$WAN_IF" -o "$LAN_IF" -m state --state RELATED,ESTABLISHED -j ACCEPT
log "NAT configured"
return 0
}
do_failover() {
[ "$FAILOVER_ENABLED" != "yes" ] && return 0
# Ensure there is a default route via failover interface (higher metric so 5G wins when up)
ip route add default dev "$FAILOVER_IF" metric "$FAILOVER_METRIC" 2>/dev/null || true
}
# Main
run_once() {
wait_for_modem || { do_failover; return 1; }
if do_connect; then
log "5G connection successful!"
return 0
else
do_failover
return 1
fi
}
if [ -n "$WATCHDOG_INTERVAL" ] && [ "$WATCHDOG_INTERVAL" -gt 0 ]; then
log "Starting 5G connection (watchdog every ${WATCHDOG_INTERVAL}s)..."
while true; do
run_once || true
sleep "$WATCHDOG_INTERVAL"
done
else
log "Starting 5G connection..."
run_once || true
log "Holding process for service (stop with: service 5g-router stop)."
exec sleep infinity
fi