fix: auto-detect WAN roles — cellular vs fiber
- Detect Eyeride cellular interface by checking 192.168.10.x subnet - Map correctly: ethernet/fiber → wan, Eyeride 5G → modem_0001 - Add carrier detection: AT&T for fiber gateways, Eyeride for cellular - Fix sel_primary: fiber is active by default unless cellular route exists - Fixes console showing 'on cellular' when actually on AT&T fiber Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -293,6 +293,76 @@ _collect_wan() {
|
||||
|
||||
# ── Telemetry Collection ───────────────────────────────────────────────────
|
||||
|
||||
# Detect which interface is the Eyeride cellular link.
|
||||
# The Eyeride runs on 192.168.10.x subnet; the interface with an IP in that
|
||||
# range is the cellular path. The other WAN interface is the primary/fiber uplink.
|
||||
# Returns: cellular_iface ethernet_iface
|
||||
_detect_wan_roles() {
|
||||
# Check if WAN2 is on the Eyeride subnet
|
||||
_wan2_ip=$(ip addr show "$WAN2_IFACE" 2>/dev/null | grep 'inet ' | awk '{print $2}' | cut -d/ -f1)
|
||||
if echo "$_wan2_ip" | grep -q '^192\.168\.10\.'; then
|
||||
echo "$WAN2_IFACE $WAN1_IFACE" # WAN2 = cellular, WAN1 = ethernet
|
||||
else
|
||||
# Check if WAN1 is on the Eyeride subnet
|
||||
_wan1_ip=$(ip addr show "$WAN1_IFACE" 2>/dev/null | grep 'inet ' | awk '{print $2}' | cut -d/ -f1)
|
||||
if echo "$_wan1_ip" | grep -q '^192\.168\.10\.'; then
|
||||
echo "$WAN1_IFACE $WAN2_IFACE" # WAN1 = cellular, WAN2 = ethernet
|
||||
else
|
||||
# Default: WAN2 is cellular (Eyeride typically on secondary port)
|
||||
echo "$WAN2_IFACE $WAN1_IFACE"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
# Derive carrier name for an interface. Uses reverse DNS on gateway or ISP detection.
|
||||
# For the Eyeride (192.168.10.x), the carrier comes from the Eyeride's cellular operator.
|
||||
_detect_carrier() {
|
||||
_iface="$1"
|
||||
_gw=$(ip route show default 2>/dev/null | grep "$_iface" | awk '{print $3}' | head -1)
|
||||
# Check if this is the Eyeride network
|
||||
_ip=$(ip addr show "$_iface" 2>/dev/null | grep 'inet ' | awk '{print $2}' | cut -d/ -f1)
|
||||
if echo "$_ip" | grep -q '^192\.168\.10\.'; then
|
||||
# This is the Eyeride — carrier comes from the Eyeride's cellular operator
|
||||
_sig=$(_eyeride_signal 2>/dev/null)
|
||||
_sig_carrier=$(echo "$_sig" | awk '{print $5}')
|
||||
if [ -n "$_sig_carrier" ] && [ "$_sig_carrier" != "null" ] && [ "$_sig_carrier" != "Eyeride" ]; then
|
||||
echo "$_sig_carrier"; return
|
||||
fi
|
||||
echo "Eyeride"; return
|
||||
fi
|
||||
# For the primary/ethernet interface, try to detect from gateway
|
||||
if [ -n "$_gw" ]; then
|
||||
# Common AT&T gateways
|
||||
if echo "$_gw" | grep -qE '^192\.168\.[01]\.'; then
|
||||
echo "AT&T"; return
|
||||
fi
|
||||
# Common Spectrum/Charter
|
||||
if echo "$_gw" | grep -qE '^192\.168\.[0-9]+\.'; then
|
||||
_rev=$(nslookup "$_gw" 2>/dev/null | grep -i name | head -1 | sed 's/.*= //')
|
||||
if echo "$_rev" | grep -qi 'att\|sbcglobal\|bellsouth'; then
|
||||
echo "AT&T"; return
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
# Fallback
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Add carrier and identity fields to a WAN JSON object.
|
||||
# Usage: _add_wan_identity <wan_json> <iface>
|
||||
_add_wan_identity() {
|
||||
_json="$1" _iface="$2"
|
||||
_carrier=$(_detect_carrier "$_iface")
|
||||
_esc_carrier=$(_json_str "${_carrier}")
|
||||
# Strip closing brace, add carrier, re-close
|
||||
printf '%s' "$_json" | sed 's/}$//'
|
||||
if [ -n "$_carrier" ]; then
|
||||
printf ',"carrier":"%s"}' "${_esc_carrier}"
|
||||
else
|
||||
printf '}'
|
||||
fi
|
||||
}
|
||||
|
||||
# Build the full telemetry JSON payload (canonical GL format).
|
||||
# Emits JSON to stdout; never fails — uses defaults for missing fields.
|
||||
telemetry_collect() {
|
||||
@@ -309,42 +379,69 @@ telemetry_collect() {
|
||||
gps_fix=$(echo "$gps_out" | awk '{print $3}')
|
||||
fi
|
||||
|
||||
# WAN1 (primary uplink, typically Ethernet → modem_0001 in canonical format)
|
||||
wan1_json=$(_collect_wan "$WAN1_IFACE")
|
||||
# Auto-detect which interface is cellular vs ethernet/fiber
|
||||
_cell_iface="" _eth_iface=""
|
||||
if _roles=$(_detect_wan_roles 2>/dev/null); then
|
||||
_cell_iface=$(echo "$_roles" | awk '{print $1}')
|
||||
_eth_iface=$(echo "$_roles" | awk '{print $2}')
|
||||
else
|
||||
_cell_iface="$WAN2_IFACE"
|
||||
_eth_iface="$WAN1_IFACE"
|
||||
fi
|
||||
|
||||
# WAN2 (Eyeride cellular → wan in canonical format)
|
||||
wan2_json=$(_collect_wan "$WAN2_IFACE")
|
||||
# Collect metrics for both WANs
|
||||
_eth_json=$(_collect_wan "$_eth_iface")
|
||||
_cell_json=$(_collect_wan "$_cell_iface")
|
||||
|
||||
# Eyeride cellular signal for WAN2 (try to enrich with rsrp/rsrq/sinr)
|
||||
# Add carrier identity to each WAN
|
||||
_eth_json=$(_add_wan_identity "$_eth_json" "$_eth_iface")
|
||||
_cell_json=$(_add_wan_identity "$_cell_json" "$_cell_iface")
|
||||
|
||||
# Eyeride cellular signal for the cellular interface
|
||||
eyeride_sig=$(_eyeride_signal 2>/dev/null)
|
||||
_rsrp=$(echo "$eyeride_sig" | awk '{print $1}')
|
||||
_rsrq=$(echo "$eyeride_sig" | awk '{print $2}')
|
||||
_sinr=$(echo "$eyeride_sig" | awk '{print $3}')
|
||||
_tech=$(echo "$eyeride_sig" | awk '{print $4}')
|
||||
_carrier=$(echo "$eyeride_sig" | awk '{print $5}')
|
||||
|
||||
# Build WAN2 JSON with cellular signal if available
|
||||
# Add cellular signal fields to the cellular WAN JSON
|
||||
if echo "$_cell_json" | grep -q '"loss_pct"'; then
|
||||
_cell_json=$(printf '%s' "$_cell_json" | sed 's/}$//')
|
||||
if [ "$_rsrp" != "null" ] && [ -n "$_rsrp" ]; then
|
||||
# Replace closing brace with signal fields
|
||||
wan2_json=$(printf '%s' "$wan2_json" | sed 's/}$//')
|
||||
_esc_tech=$(_json_str "${_tech:-unknown}")
|
||||
_esc_carrier=$(_json_str "${_carrier:-Eyeride}")
|
||||
wan2_json="${wan2_json},\"rsrp_dbm\":${_rsrp},\"rsrq_db\":${_rsrq},\"sinr_db\":${_sinr},\"technology\":\"${_esc_tech}\",\"carrier\":\"${_esc_carrier}\"}"
|
||||
_cell_json="${_cell_json},\"rsrp_dbm\":${_rsrp},\"rsrq_db\":${_rsrq},\"sinr_db\":${_sinr},\"technology\":\"${_esc_tech}\"}"
|
||||
else
|
||||
_cell_json="${_cell_json}}"
|
||||
fi
|
||||
fi
|
||||
|
||||
# WAN mapping in canonical GL format:
|
||||
# modem_0001 = cellular (Eyeride 5G)
|
||||
# wan = ethernet/fiber (AT&T Uverse)
|
||||
_wan_modem="$WAN2_IFACE" # which physical iface maps to modem_0001
|
||||
_wan_ether="$WAN1_IFACE" # which physical iface maps to wan
|
||||
|
||||
# Check if roles were swapped by auto-detection
|
||||
if [ "$_cell_iface" != "$WAN2_IFACE" ]; then
|
||||
# WAN1 is cellular, WAN2 is ethernet
|
||||
_modem_json="$_cell_json"
|
||||
_ether_json="$_eth_json"
|
||||
else
|
||||
# WAN2 is cellular, WAN1 is ethernet (normal)
|
||||
_modem_json="$_cell_json"
|
||||
_ether_json="$_eth_json"
|
||||
fi
|
||||
|
||||
# Active WAN: determine from routing table (default route interface)
|
||||
sel_primary="modem_0001"
|
||||
sel_primary="wan" # default: fiber/ethernet is primary
|
||||
default_iface=$(ip route show default 2>/dev/null | awk '{print $5}' | head -1)
|
||||
if [ "$default_iface" = "$WAN2_IFACE" ]; then
|
||||
sel_primary="wan"
|
||||
if [ "$default_iface" = "$_cell_iface" ]; then
|
||||
sel_primary="modem_0001" # cellular is the active path
|
||||
fi
|
||||
|
||||
# Starlink — detect if present
|
||||
sl_lat="null" sl_dl="null" sl_obs="0" sl_outage="0"
|
||||
# Starlink is typically on a USB ethernet adapter or separate VLAN
|
||||
if ip link show 2>/dev/null | grep -qi starlink; then
|
||||
# Basic Starlink check — if interface exists, try to get metrics
|
||||
sl_iface=$(ip link show 2>/dev/null | grep -i starlink | head -1 | awk -F': ' '{print $2}' | awk '{print $1}')
|
||||
sl_iface=$(ip link show 2>/dev/null | grep -i starlink | head -1 | awk -F": " '{print $2}' | awk '{print $1}')
|
||||
if [ -n "$sl_iface" ]; then
|
||||
sl_ping=$(_ping_iface "$sl_iface")
|
||||
sl_lat=$(echo "$sl_ping" | awk '{print $1}')
|
||||
@@ -362,7 +459,7 @@ telemetry_collect() {
|
||||
printf '{"device_id":"%s","timestamp":%d,"uptime":%d,"version":"%s","platform":"synology","sel_primary":"%s","active_wan":"%s","gps":{"lat":%s,"lon":%s,"fix":%s},"wan":{"modem_0001":%s,"wan":%s},"sim_slot":null,"starlink":{"latency_ms":%s,"dl_bps":%s,"obstructed":%s,"outage":%s},"state":%s}\n' \
|
||||
"${esc_id}" "${now:-0}" "${uptime_s:-0}" "${esc_ver}" "${esc_sel}" "${esc_sel}" \
|
||||
"${gps_lat}" "${gps_lon}" "${gps_fix}" \
|
||||
"${wan1_json}" "${wan2_json}" \
|
||||
"${_modem_json}" "${_ether_json}" \
|
||||
"${sl_lat}" "${sl_dl}" "${sl_obs}" "${sl_outage}" \
|
||||
"${state}"
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user