fix(telefon): FreeSWITCH-Profil nach Wechsel der oeffentlichen IP neu starten

FreeSWITCH meldete Plusnet nach einer Zwangstrennung weiter die alte IP
als Contact - Trunk blieb REGED, eingehende Anrufe kamen nie an.
starten.sh gleicht jetzt bei jedem Watchdog-Lauf STUN-IP und Ext-SIP-IP ab.
HANDOFF.md dokumentiert zusaetzlich AbandonProcessGroup im launchd-plist.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Jeuner 2026-09-17 05:33:08 +02:00
parent f42ac7ded5
commit 9c4903043e
2 changed files with 58 additions and 0 deletions

View file

@ -4,6 +4,40 @@
Voller Weg funktioniert Ende-zu-Ende: externer Anruf auf Durchwahl 9 (Plusnet → FreeSWITCH → `dialog/pipecat_bootstrap.py` → WebSocket → Astra) erreicht Astra, und Astra liefert jetzt auch eine echte, fertige Antwort statt nur "Einen Moment bitte" (Fix 2026-09-13, siehe unten) - kein offener Blocker mehr bekannt.
## 2026-09-17 — Leitung stumm nach IP-Wechsel, Watchdog-Kinder sterben
**Symptom:** Durchwahl 9 (und die ganze Leitung) nahm nicht ab. Letzter
eingehender Anruf im FreeSWITCH-Log: 2026-09-15 18:05. Trunks trotzdem
REGED/UP.
### 1. Veraltete öffentliche IP im Contact
FreeSWITCH ermittelt die externe IP per STUN nur beim Laden der XML
(`vars.xml`, `stun-set`). Contact an Plusnet war noch `9.246.125.72`,
tatsächlich `217.142.18.120` (Zwangstrennung, 05:17 kurz 408/DOWN).
Registrierung und Pings gehen weiter raus, eingehende INVITEs laufen ins
Leere - kein Fehler im Log.
**Fix:** `starten.sh` vergleicht bei jedem Watchdog-Lauf
`fs_cli -x 'stun stun.freeswitch.org'` mit `Ext-SIP-IP` des
external-Profils; bei Abweichung und 0 Gesprächen `reloadxml` +
`sofia profile external restart`. Nach einem IP-Wechsel ist die Leitung
also bis zu 5 min stumm. Profil-Neustart von Hand getestet (Trunks sofort
wieder REGED); der Abweichungsfall selbst noch nicht real ausgelöst.
### 2. launchd beendete alles, was starten.sh im Hintergrund startet
Vom Watchdog gestarteter Pipecat-Bootstrap band Port 8095 und war
Sekunden später weg, ohne Log. Ursache: launchd räumt nach Jobende die
Prozessgruppe ab. Betraf auch `pipe.monitor`/`pipe.watch`/`pipe.server` -
Fix 3 vom 2026-09-14 (Störungswache zuerst) griff unter launchd also nie.
FreeSWITCH überlebt, weil es sich selbst abkoppelt.
**Fix:** `<key>AbandonProcessGroup</key><true/>` in
`~/Library/LaunchAgents/net.dillenberg.fonagent.plist` (liegt **nicht** im
Repo), per `launchctl bootout`/`bootstrap` neu geladen. Verifiziert:
Bootstrap per Watchdog gestartet, lebt nach Jobende weiter.
## 2026-09-14 — Leitung nach Neustart ~80 min tot: Watchdog bekam nichts hoch
**Symptom:** Nach einem Neustart des Mac mini (~12:39) blieb die Leitung

View file

@ -108,6 +108,30 @@ else
sleep 15
fi
# Oeffentliche IP abgleichen. FreeSWITCH holt sie per STUN nur beim Laden der
# XML (vars.xml, stun-set) und meldet sie Plusnet als Contact. Nach einer
# Zwangstrennung des Routers mit neuer IP bleibt der Trunk trotzdem REGED/UP
# (Registrierung und Pings gehen raus), aber eingehende INVITEs laufen an die
# alte Adresse - die ganze Leitung ist stumm, ohne Fehler im Log. So am
# 2026-09-17 passiert: Contact 9.246.125.72, tatsaechlich 217.142.18.120.
# Bei Abweichung: reloadxml (STUN neu) + external-Profil neu starten, nur wenn
# gerade kein Gespraech laeuft - sonst im naechsten Watchdog-Lauf.
aktuell=$(fs_cli -P "$FS_PORT" -x "stun stun.freeswitch.org" 2>/dev/null | head -1 | cut -d: -f1)
gemeldet=$(fs_cli -P "$FS_PORT" -x "sofia status profile external" 2>/dev/null \
| awk '/^Ext-SIP-IP/{print $2}')
if [[ "$aktuell" =~ ^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+$ ]] && [ -n "$gemeldet" ] \
&& [ "$aktuell" != "$gemeldet" ]; then
gespraeche=$(fs_cli -P "$FS_PORT" -x "show calls count" 2>/dev/null | awk '/total/{print $1}')
if [ "${gespraeche:-0}" = "0" ]; then
echo "$(date '+%F %T') Oeffentliche IP geaendert ($gemeldet -> $aktuell) - external-Profil wird neu gestartet."
fs_cli -P "$FS_PORT" -x "reloadxml" >/dev/null 2>&1
fs_cli -P "$FS_PORT" -x "sofia profile external restart" >/dev/null 2>&1
sleep 10
else
echo "$(date '+%F %T') Oeffentliche IP geaendert ($gemeldet -> $aktuell), aber $gespraeche Gespraech(e) aktiv - naechster Lauf."
fi
fi
# Auf die Registrierung beim Provider warten.
# Quelle ist fs_cli, nicht das Log: das Log wird zum Testen geleert und taugt
# dann nicht mehr als Zustandsquelle.