Das letzte Update hat einige Änderungen in der Daten Ausgabe der FRITZ!Box mitgebracht. Dadurch ging meine uralte Anrufliste nicht mehr, die schon ewig im LAN direkt abrufbar ist.
Das alte PHP script hat sich eines shellscriptes namens fblogin.sh
bedient, mit der die Session-ID an PHP übergeben wurde, Dieses Shellscript lag ausserhalb der vom Webserver erreichbaren Pfade, was einen zusätzlichen Sicherheitsaspekt darstellt, denn in diesem Script stehen Username und Password.
Die erste nicht mehr funktionierende Zeile im Shellscript war
SID=$(curl -i -s -k -d "response=${RESPONSE}&username=${USER}" "${FBF}" | grep -Po -m 1 '(?<=sid=)[a-f\d]+')
Die muss geändert werden auf
SID=$(curl -i -s -k -d "response=${RESPONSE}&username=${USER}" "${FBF}" | grep -Po -m 1 '(?<=\"sid\"\:\")[a-f\d]+')
damit der Output wieder passt.
Im PHP-Script gab es dann die Zeile
$sid = shell_exec(" /Pfad/zum/Script/fblogin.sh");
um die Session-ID zu „holen“ und weiter unten mit
$cl = simplexml_load_string(file_get_contents(sprintf('http://%s:49000/calllist.lua?sid=%s&days=7', $fritz_url, $sid)));
den Plaintext-Output der FB abzuholen und in XML zu formatieren.
Da die Korrektur im Shell Skript allein das Problem des nicht funktionierenden Skripts nicht gelöst hat, habe ich mir den Output dann direkt angesehen. Es ist schon XML. Dann habe ich das Shellscript dahingehend erweitert, das es nicht die Session-ID liefert, sondern gleich das XML der Anrufer. Das ist zwar nicht so flexibel für den Fall, das das Login auch von anderen PHP-Scripten verwendet wird, aber ich kenne keine Anwendung, die das an der Stelle benötigt. Zur Sicherheit habe ich aber zunächst das Shellscript in ein neues kopiert, welches fpcalllist.sh
heisst. Das liefert als Antwort die Anrufliste in XML. Und im PHP hab ich einen Schritt weggelassen und schiebe den XML-Output direkt in eine Tabelle.
- Bonus: Ich hab noch einen Filter dazu gesetzt, der Anrufer herausfiltert, die nicht in der Liste auftauchen müssen. Dafür ist die Voraussetzung, das die im Telefonbuch hinterlegt sind, denn der Filter basiert auf den Namen. Seit die FB allerdings einen Lesezugriff auf das iCloud-Telefonbuch konfiguriert bekommen kann, ist das zumindest für iCloud-User kein Problem, das Telefonbuch live aktuell zu halten.
Lange Rede, Kurzer Sinn, hier kommen die vollständigen Scripte:
Das fpcalllist.sh
liegt bei mir im Pfad /var/www/
und sieht anonymisiert so aus:
/#!/bin/bash
FBF="192.168.178.1"
USER="fritz0815" # falls keine User angelegt sind, den default-Usernamen unter System > FRITZ!Box-Benutzer ablesen und hier verwenden
PASS="Geheimespassw0rt"
CHALLENGE=$(curl -s -k "${FBF}/login_sid.lua" | grep -Po '(?<=<Challenge>).*(?=</Challenge>)')
MD5=$(echo -n ${CHALLENGE}"-"${PASS} | iconv -f ISO8859-1 -t UTF-16LE | md5sum -b | awk '{print substr($0,1,32)}')
RESPONSE="${CHALLENGE}-${MD5}"
SID=$(curl -i -s -k -d "response=${RESPONSE}&username=${USER}" "${FBF}" | grep -Po -m 1 '(?<=\"sid\"\:\")[a-f\d]+')
CALLIST=$(curl -s -k "${FBF}:49000/calllist.lua?sid=${SID}&days=100")
echo ${CALLIST}
Das aufrufbare PHP-Script anrufe.php
liegt bei mir im /var/www/html/
Ordner, der vom Apache gelesen werden kann.
<html>
<head>
<meta charset="utf-8"/>
<title>Anrufe</title>
<style>
tr {border-bottom: 1px solid #a9a9a9;}
td {padding-right: 5px; padding-left: 5px;}
.rein {background-color: #9fc; }
.rein td:first-child { color: #6c9;}
.raus {background-color: #6c9;}
.raus td:first-child {color: #396;}
.nix {background-color: #ff9933;}
.nix td:first-child {color: #cc6600;}
</style>
</head>
<body>
<table>
<tr> <th>⬍</th><th>Datum</th><th>Gegenstelle</th><th>Eigen</th><th>Dauer</th><th>Name</th></tr>
<?php
// Get Calllist
$cl = simplexml_load_string(shell_exec("/var/www/fpcalllist.sh"));
foreach($cl->Call as $call) {
switch($call->Name) {
case 'Unsichtbarer Anrufer 1':
break;
case 'Max Mustermann':
break;
case 'Mia Musterfrau':
break;
default:
switch($call->Type) {
case 3:
echo sprintf("<tr class=\"raus\"><td class=\"i\"> ⬆ </td><td>%s </td><td>%s </td><td>%s </td><td>%s</td><td>%s</td></tr>\n", $call->Date, $call->Called, $call->CallerNumber, $call->Duration, $call->Name);
break;
case 2:
echo sprintf("<tr class=\"nix\"><td class=\"i\"> ⦿ </td><td>%s </td><td>%s </td><td>%s </td><td>%s</td><td>%s</td></tr>\n", $call->Date, $call->Caller, $call->CalledNumber, $call->Duration, $call->Name);
break;
default:
echo sprintf("<tr class=\"rein\"><td class=\"i\"> ⬇ </td><td>%s </td><td>%s </td><td>%s </td><td>%s</td><td>%s</td></tr>\n", $call->Date, $call->Caller, $call->CalledNumber, $call->Duration, $call->Name);
break;
}
}
}
?>
</table>
</body>
</html>
Abrakadabra, eine Anrufliste die wieder funktioniert.
Wer mal ein schöneres CSS dafür machen möchte, kann mir das ja zukommen lassen. Ich hab bewusst auf grafische Elemente verzichtet, da diese kaum Mehrwert bieten.
Falls jetzt in diesem Zusammenhang jemand hier zum ersten mal davon gehört hat, dem sei noch gesagt, das man den Zugriff zunächst freischalten muss:

Sollte sich jemand finden, der den Kram ohne Doubletten in eine SQL-Tabelle malen kann, oder eine Idee hat, wie man die Rufnummern der gerade aktiven Anrufe anzeigen kann (Das Display an meinen Handsets ist zu kurz und vor allem am Ohr), da wär ich auch noch dran interessiert.
Über den Autor