Schalt‘ auf Überwachung, Kumpel…

Der Speedport ISDN-Adapter ist sowas von simpel, einfach anstecken und läuft. Da gibts nix einzustellen. Nur einmal im Kundencenter anmelden und gut ist. Leider stellt sich heraus, das bei so manchen Netzstörungen der Adapter nicht mehr funktioniert. Und das sieht man diesem auch nicht an. Entweder man stellt selbst fest, dass das Telefonieren nicht mehr geht. Oder man wird angesprochen, warum man nicht erreichbar ist. Da macht sich Frust breit und die einzige Lösung scheint ein PowerOnOff zu sein.

Um das Ausmaß der Störungen zu erfassen, hab ich das Script von Martins Technik Blog adaptiert. Dies wird auf einem Raspberry Pi minütlich durch Cron gestartet und schreibt in ein Log-File für weitere Auswertungen.

ISDN Check über linphone, Fritzbox und sipgate

Das Script selbst startet nun einen Anruf auf eine Rufnummer, um die Funktion des ISDN-Adapters zu testen. Sobald die Verbindung steht, legt das Script auf. Sollte die Verbindung nicht innerhalb von 10 Sekunden stehen, wird der Versucht abgebrochen. Als Zielrufnummer nutze ich eine kostenlose Ortsrufnummer von sipgate basic, welche auf den Anrufbeantworter aufläuft. Da die Verbindung nur für 2-3 Sekunden besteht, wird keine Nachricht auf der Box hinterlegt.

* * * * * pi /usr/local/bin/checkisdn.sh 0987654321 >> /dev/null 2>&1

Der Test wird über linphone auf einem Raspberry Pi durchgeführt. Neben der grafischen Anwendung bietet es auch ein Commandlinetool für Scripting. Als Bindeglied zwischen dem SIP-Client und dem ISDN-Adapter agiert eine Fritzbox.

Der nächste Schritt wäre nun eine kleine Schaltung am Raspi, um bei x-fehlgeschlagenen Versuchen einen Reset des Adapters durchzuführen.

Hier der angepasste Code:

#!/bin/bash
########################################
SIP_HOST='IP-ADRESSE'
SIP_USER='NEBENSTELLE'
SIP_PASS='PASSWORT'
CALL=${1}
TIMEOUT=10
LOG=/var/log/makecall.log
########################################

PID=$
SCRIPTNAME=`basename $0`
PIDFILE=/var/run/$SCRIPTNAME.pid

check_pid () {
 if [ -f "$PIDFILE" ]
 then
  RUNNINGPID=`cat "$PIDFILE"`
  echo "got pid from $RUNNINGPID from pidfile '$PIDFILE'"
  PROGRAMPID=`ps -e | grep "$SCRIPTNAME" | grep -v grep | awk '{print $1;}'`
  for PIDEL in $PROGRAMPID
  do
   echo "testing pid of running scripts '$PIDEL' == '$RUNNINGPID' from pidfile"
   if [ "$PIDEL" == "$RUNNINGPID" ]
   then
    echo "found PID $RUNNINGPID current running - end execution"
    ENDEXECUTION=1
    break
   fi
  done
 fi

 if [ "$ENDEXECUTION" == "1" ]
 then
  echo "Current script '$SCRIPTNAME' already running (pid $RUNNINGPID) - end execution"
  exit 1
 fi

 echo $PID > $PIDFILE
}

delete_pid () {
 rm $PIDFILE
}

log () {
 DATE=`date +"%b %d %H:%M:%S"`
 echo "$DATE $SCRIPTNAME[$PID] $1"
 echo "$DATE $SCRIPTNAME[$PID] $1" >> $LOG
}

get_phone_state () {
 linphonecsh status register 2>/dev/null 1>&2
 if [ $? -eq $1 ]; then
  true
 else
  false
 fi
}

get_call_state () {
 linphonecsh status hook 2>/dev/null 1>&2
 if [ $? -eq $1 ]; then
  true
 else
  false
 fi
}

check_pid

if [ $# -ne 1 ]; then
 echo "Usage: `basename $0` <number_to_dial>"
 exit 255
fi

while ! get_phone_state 255
do
 echo "Exit Phone client ..."
 linphonecsh exit
 sleep 1
done

# ret code 255 = no daemon started
if get_phone_state 255
then
 echo "Starting Phone client ..."
 linphonecsh init

 while get_phone_state 255
 do
  sleep 0.2
 done
else
 log "Phone client already started ($?) ..."
fi

# ret code 0 = unregistered
# ret code 1 = registered
if get_phone_state 0
then
 echo "Register Client on SIP Server ..."
 linphonecsh register --host ${SIP_HOST} --username ${SIP_USER} --password ${SIP_PASS}
else
 log "Client already registered ($?) ..."
fi

echo "Setup Soundcard ..."
linphonecsh soundcard use files

sleep 0.5

COUNT1=0
while ! get_phone_state 1
do
 sleep 0.5
 COUNT1=$((COUNT1+1))

 if [ $COUNT1 -ge 10 ]
 then
  log "ERROR $COUNT1 ticks timeout state 1"
  linphonecsh exit
  delete_pid
  exit 255
 fi
done

echo "INIT Calling Number: ${CALL} ..."
linphonecsh dial ${CALL}

sleep 0.5

COUNT2=0
while get_call_state 4
do
 sleep 0.5
 COUNT2=$((COUNT2+1))

 if [ $COUNT2 -ge 10 ]
 then
  log "ERROR $COUNT2 ticks timeout state 4"
  linphonecsh exit
  delete_pid
  exit 255
 fi
done

echo "Ringing on remote site ..." # what the heck,.. no hook=ringing or stuff like that

ABORT=false
COUNT=0
while [ "`linphonecsh status hook`" == "" ] && ! ${ABORT}; do
 sleep 1
 COUNT=$((COUNT+1))

 if [ $COUNT -ge $TIMEOUT ]
 then
  log "ERROR timeout in $COUNT sec"
  ABORT=true
 fi
done

if get_call_state 32
then
 log "OK connected in $COUNT sec"

fi

echo "Cleaning up ..."
linphonecsh generic terminate

linphonecsh unregister

echo "Exiting Daemon ..."
linphonecsh exit

delete_pid