AVM Fritz!Box und TipTel 3110 MWI LED

Inhaltsverzeichnis

 

1. Vorwort Inhalt

Seit neuestem habe auch ich von meinem Provider eine FritzBox 7490 zur Verfügung gestellt bekommen und damit meine eigene Asterisk-Installation über Bord geworfen. Ich muß sagen, zusammen mit einem TipTel 3110 funktioniert das wirklich gut, sofern man den PCMU Codec als einzigen zuläßt im TipTel. Ein kleines Manko blieb bestehen, und zwar ist es mir nicht gelungen, das TipTel für die MWI-Notifikation der FirtzBox zu erwärmen. Es registriert sich zwar brav und SUBSCRIBEd sich gleich hinterher, beide male mit Digest. und erhält auch 2x ein 200 OK  von der FritzBox, aber alle folgenden NOTIFY-Nachrichten der FB, egal ob neue oder alte Nachrichten vorhanden sind, enthalten „messages-waiting: no“. Meiner Meinung nach also klar ein Fehler der FritzBox.

2. „Was tun?“ sprach Zeus… Inhalt

Zunächst hatte ich im IP Phone Forum angefragt, ob dort jemand schon einmal das Problem hatte; leider konnte mir keiner Auskunft geben. Der Eintrag ist dennoch interessant, denn die ganzen SIP-Traces sind dort angehängt.

Auch bin ich mit dem AVM-Support in regem Kontakt, der -Stand heute- aber auch keine Lösung oder Idee bezüglich des Problems hat. Vielleicht ergibt sich da noch etwas, aber wir können auch selbst Hand anlegen.

3. Wenn Weihnachten wäre… Inhalt

Das Konzept ist recht einfach: Wir scripten die FB-Weboberfläche (PITA btw.) und fischen und darüber die Anzahl der neuen und alten Nachrichten auf dem AB. Dann benutzen wir die Low-Level Funktionen des TipTel, um einfach „von Hand“ eine LED neben einem Zielwahlknopf ein- und auszuschalten. Das Script wird auf einem kleinen Webserver geparkt und einfach jede Minute aufgerufen. Es sollte natürlich  den letzten Zustand speichern, damit das TipTel nicht jede Minute eine Nachricht bekommt, sondern nur bei Änderung. So werden schon einmal alle Änderungen am AB, z.B. von einem anderen Telefon aus mit der LED synchronisiert.

Leider überschreibt das TipTel den LED-Zustand bei einer Zielwahltaste: Drücke ich drauf, schaltet die LED auf Rot, und bleibt nach dem Auflegen aus. Wenn ich also den AB anrufe zum Abhören, wäre danach die LED dunkel. Wir müssen das Script also vom Telefon aus auch triggern, und zwar genau dann, wenn der Anruf zum AB wieder beendet ist, damit dann der Zustand in der FB abgefragt und wieder mit der LED synchronisiert wird.

Der Einfachheit halber hab ich das Script in PHP geschrieben. Es sollte sich in jede andere Sprache auch schnell portieren lassen.

3.1 FB Session ID abholen Inhalt

Leider ist das Scripten der FB nicht einfach seit Firmware Version 5.29, und ich hab auf der 7490 schon 6.50 drauf. Zunächst holt man sich eine Nonce („Challenge“) per simplem HTTP-GET:

// Open connection to FB and get the Login Challenge...
$xml = curl_get("http://".$FBADDR."/login_sid.lua");
if ($xml=="") die("Could not read FB's /login_sid.lua.");
preg_match("/<Challenge>([0-9a-fA-F]{8})<\/Challenge>/i", $xml, $fb_challenge);
$fbChl = $fb_challenge[1];
print " FB Challenge: ". $fbChl ."\n";

3.2 Login Challenge Inhalt

Diese muß mit speziell aufbereitet werden, und zwar wird das Paßwort angehängt, und dieser gesamte String nach jedem Zeichen mit einem „\0“ versehen. Letztlich muß der so entstandene String dann mit MD5 behandelt und gePOSTed werden:

$fbChlResponse = $fbChl ."-". md5(fb_zFillChar($fbChl."-".$FBPASS));
print " FB  Response: ". $fbChlResponse ."\n";
// Step Three: POST the Challenge and get a valid SID
$xml = curl_post_array("http://".$FBADDR."/login_sid.lua", array("response"=>$fbChlResponse));
preg_match("/<SID>([0-9a-fA-F]{16})<\/SID>/i", $xml, $fb_sid);
$fbSid = $fb_sid[1];
print " FB       SID: ". $fbSid ."\n";

3.3 Datenseite des Anrufbeantworters Inhalt

Mit der erhaltenen Session-ID können wir uns die Datenseite des Anrufbeantworters fischen. Ein PITA deswegen, weil AVM hier die gesamte Seite überträgt per XHR, nicht nur die wesentlichen Daten als JSON. Wir bekommen also Table-Elemente, Scripts, CSS, usw. in diesem einen Request mit, der daher auch etwas länger dauert.

// Step Four: get the Answer machine HTML page from data.lua (Yes, it's a crappy design by AVM this way!)
$xml = curl_post_array("http://".$FBADDR."/data.lua", array("xh1"=>"1", "sid"=>$fbSid, "lang"=>"de", "page"=>"tam", "no_sidrenew"=>""));
// Step five: Fish the messages table
// Note: Within this page, there is a table for each Answer Machine, since I only have one, I'll fish the first one only. Extend as necessary.
preg_match("/<table[^>]*>(.*)<\/table>/i", $xml, $fb_abTable);
$fbAbTable = $fb_abTable[1];

3.4 Zeilen zählen Inhalt

Aus der Tabelle fischen wir uns die Zeilen, die tatsächlich AB-Nachrichten enthalten und parsen entsprechend. Letztlich bekommen wir dabei die Anzahl der neuen und alten Nachrichten heraus:

// Step Six: Fish the rows with messages in them and count
// Note: The Header row, while also being a TR, has a class attached. <tr class="xx"> will not match this findall.
preg_match("/(<tr>.*?<\/tr>)/i", $fbAbTable, $fb_abTrs);
unset($fb_abTrs[0]);
$fb_abTrs = array_values($fb_abTrs);
$fbNrOfNewMessages = 0;
$fbNrOfOldMessages = 0;
if ((count($fb_abTrs)==1) && (strpos($fb_abTrs[0], "keine Nachrichten")>0)) {
	$fbNrOfOldMessages = 0;
	$fbNrOfNewMessages = 0;
} else {
	foreach ($fb_abTrs as $tr) {
		if (strpos($tr, "tamcall_new.gif")>0) { $fbNrOfNewMessages++; } else { $fbNrOfOldMessages++; }
	} 
}
print " FB  Old Msgs: ". $fbNrOfOldMessages ."\n";
print " FB  New Msgs: ". $fbNrOfNewMessages ."\n";

Damit können wir nun weiterarbeiten.

3.5 TipTel füttern Inhalt

Meine Logik sieht sehr einfach aus:

  • Keine Nachrichten: LED aus
  • Mindestens eine neue Nachricht: LED blinkt rot
  • Ansonsten: LED leuchtet grün
$fbLed = "Led:fkey1=off";
if ($fbNrOfNewMessages>0) { $fbLed = "Led:fkey1_red=slowflash"; } elseif ($fbNrOfOldMessages>0) { $fbLed = "Led:fkey1_green=on"; }
print " FB   ==> LED: ". $fbLed ."\n";
// Update if either state different OR requested from a URL via Webserver
if (trim(file_get_contents("led.txt"))==$fbLed) {
	if (!$_GET["u"]) {
		die("\n      ==> RESULT: No update necessary.");
	} else {
		print "\n      ==> RESULT: State the same but requested from WEB! UPDATE!";
	}
}
// Send this to the TipTel
$msg = '<?xml version="1.0" ?><TiptelIPPhoneExecute><ExecuteItem URI="Led:backlight=off"/><ExecuteItem URI="'. $fbLed .'"/></TiptelIPPhoneExecute>';
curl_post_xml("http://".$TTIP."/xmlservice", $msg, $TTUSER, $TTPASS);

3.6 TipTel Self-Update Inhalt

Eine Besonderheit ist in der Nachricht enthalten: Ich setze darin die Hintergrundbeleuchtung auf aus, damit das Display nicht aufleuchtet. Leider blitzt es trotzdem ganz kurz auf, was sehr nervig sein kann. Der Code enthält deswegen einen Zwischenspeicher im Dateisystem („led.txt“) um den letzten Zustand, wie oben beschrieben, zu verwerten. Allerdings kann man ein Update erzwingen, wenn man das Script nicht von der Kommandozeile aus, sondern über einen Webserver/Browser aufruft, und den GET Parameter „u“ auf einen beliebigen Wert setzt.

Ich benutze das, um im TipTel unter Telefon =>PBX-Sync =>Anruf erfolglos/beendet die URL des Webservers http://$raspi-ip-address/ttled/ttled.php?u=1 einzutragen und das TipTel dadurch ein Update der LED zu veranlassen:

  1. TipTel ruft nach jedem beendeten Anruf das Script auf dem Webserver auf
  2. Script ermittelt die jetzt geltende Anzahl an AB Nachrichten und die LED Farbe
  3. Script setzt die LED-Farbe neu

3.7 Vom Raspi angestoßenes Update Inhalt

Wie gesagt muß der RasPi oder jeder andere beliebige Server das Script regelmäßig, z.B. jede Minute, ausführen, damit die LED aktuell bleibt. Dafür eignet sich cron sehr gut:

#minute hour    mday    month   wday    who     command
#if your ttled.php resides in /var/www/ttled...
*/1     *       *       *       *       root    /var/www/ttled/ttled.php

Ihr müßt in der ttled.php  natürlich noch den Pfad zu PHP oben in die erste Zeile eintragen, z.B. #!/usr/bin/php oder wo eben PHP installiert ist. Alternativ geht das auch im crontab:

#minute hour    mday    month   wday    who     command
#if your PHP resides in/usr/bin and ttled.php resides in /var/www/ttled...
*/1     *       *       *       *       root    /usr/bin/php /var/www/ttled/ttled.php

4. Fazit Inhalt

Ein nettes kleines Stück Coding, nicht wahr… Hoffe, es hilft noch jemandem. Hier gibt’s das vollständige PHP-File: ttled.zip

Ein Kommentar zu “AVM Fritz!Box und TipTel 3110 MWI LED”

1.   Kommentar von luckyrings
Erstellt am 31. Mai 2016 um 12:28 Uhr.

Den Fehler mit fehlender MWI-Benachritung und FritzBox Version 6.50/bzw. 6.51 kann ich nachvollziehen. Vor Version 6.50 wurden die internen SIP-Telefoniegeräte schön benachrichtigt, wenn Anrufe auf dem AB eingegangen sind. Jetzt klappt das nicht mehr. Leider habe ich keine Lösung, da an den Telefone (Snom 760) nichts geändert wurde, tippe ich auf Fehler in FritzBox.

Einen Kommentar hinterlassen