Ankündigung

Einklappen
Keine Ankündigung bisher.

Fritz!Box Telefonliste via TR-064

Einklappen
X
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    [Codebeispiel] Fritz!Box Telefonliste via TR-064

    Hallo,

    Ich hab eine neue Version des Fritz!Box Interfaces getippt.
    Diese Version verwendet TR-064 zum auslesen der Anruferliste,
    das ist ein Protokoll das nahe am UPnP Standard ist (SOAP).
    Der Vorteil ist hier das XML zurück kommt und man angeben kann wie viel
    Einträge man max. haben möchte.
    Beim alten CSV Download mussten immer alle 400 Einträge übertragen und verarbeitet werden.
    Das sind beim alten Skript 81,4 KB an Daten und der raspberry benötigt dazu 1547 ms.
    Das Neue holt standardmäßig nur die letzen 20 Einträge und das sind 4,32 KB
    bei einer Verarbeitungszeit von 328ms.
    Da das Interface standardisiert ist sollte sich das auch nicht mit jeder Fritz!Box Firmware ändern
    und mit den Internationalen (English) Versionen der Boxen klar kommen.
    Getestet hab ich es mit einer 7390 Version v6.03 und v6.20

    Weiterhin hab ich alle drei Möglichkeiten der Anmeldung getestet (ohne PWD, nur PWD, User mit PWD).
    Auf der Box muss halt nur TR-064 aktiv sein.
    Das ist meines Wissens mit allen Modellen die nach 2009
    auf dem Markt gekommen sind und die jeweils aktuelle Firmware haben möglich.

    Genug gequatscht - Version im Anhang.
    Einfach ins Verzeichniss "smartvisu\lib\phone\service" legen und in der Weboberfläche auswählen. "Zugriff für Anwendungen zulassen" muss in der FB aktiviert sein. Hiezu steht mehr in der PHP Datei.
    Grüße Stefan


    Datei: "fritz!box_via_TR-064.php"
    PHP-Code:
    <?php
    require_once '../../../lib/includes.php';
    require_once 
    const_path_system 'phone/phone.php';
    /**
     * This class reads the phonelist of an fritz!box phonesystem via TR-064 protocol
     * This can only work if you enable "Zugriff für Anwendungen zulassen".
     * you can found this config switch inside the web console -> Home network -> Network -> Network Settings
     * It is required that "Extented View" of the web console is enabled - that this checkbox is shown.
     *
     */
    class phone_fritzbox_via_TR064 extends phone
    {
        private 
    $max_calls_to_fetch;
        private 
    $challenge;
        private 
    $call_list_url;
        public function 
    __construct($http_vals)
        {
            
    parent::init($http_vals);
            
    // maximum number of records fetched from phonesystem.
            
    $this->max_calls_to_fetch 20;
            
    // use some default user if only password is set on smartvisu
            
    if (strlen($this->user) == && strlen($this->pass) > 0)
                
    $this->user 'admin';
        }
        
    /**
         * DoSOAPCall: issues a http post to the phone system on port 49000
         */
        
    private function DoSOAPCall($content)
        {
        
    $header[] = 'Content-type: text/xml;charset="utf-8"\r\n';
            
    $header[] = 'SOAPAction: urn:dslforum-org:service:X_AVM-DE_OnTel:1#GetCallList';
            
    $header[] = sprintf('Content-Length: %d'strlen($content));
            
    $context  = array(
                
    'http' => array(
                    
    'method' => 'POST',
                    
    'header' => implode("\r\n"$header),
                    
    'content' => $content
                
    )
            );
            
    $url      'http://' $this->server ':49000/upnp/control/x_contact';
            
            return (
    file_get_contents($urlfalsestream_context_create($context)));        
        }
        
    /**
         * InitChallenge: the phone systems responds to this SOAP message
         * always with "Unauthenticated" if a password is set
         * This is only used for getting the Nonce and Realm like :
         * <Nonce>A025059762AFE268</Nonce>  <Realm>F!Box SOAP-Auth</Realm>
         */
        
    private function InitChallenge()
        {
            
    // define soap message    
            
    $soap_msg_InitChallenge '
            <?xml version="1.0" encoding="utf-8"?>
            <s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
            xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" >
            <s:Header><h:InitChallenge xmlns:h="http://soap-authentication.org/digest/2001/10/" s:mustUnderstand="1">
            <UserID>' 
    $this->user '</UserID>
            </h:InitChallenge ></s:Header><s:Body><u:GetCallList xmlns:u="urn:dslforum-org:service:X_AVM-DE_OnTel:1">
            </u:GetCallList></s:Body></s:Envelope>'
    ;
            if ((
    $response $this->DoSOAPCall($soap_msg_InitChallenge)) === FALSE)
                return 
    FALSE;
            
    $this->debug($response"Fritz RAW response InitChallenge (Unauthenticated is OK at this point!)");
            if (
    preg_match_all("(\<.+\>(.+)\<\/.+\>)U"$response$this->challenge) === FALSE) {
                
    $this->error('Phone: fritz!box''SOAP Challenge parsing error!');
            }
            
    $this->debug($this->challenge"preg_matched InitChallenge (Unauthenticated is OK at this point!)");
        }
        
    /**
         * GetCallListURL: Create a authentication hash and use that with the real request to get the callList URL  
         */
        
    private function GetCallListURL()
        {
            
    //create authentication sting
            
    $Auth  MD5(MD5($this->user ':' $this->challenge['1']['2'] . ':' $this->pass) . ':' $this->challenge['1']['1']);
            
    // define soap message
            
    $soap_msg_GetCallList '
            <?xml version="1.0" encoding="utf-8"?>
            <s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
            xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" >
            <s:Header><h:ClientAuth xmlns:h="http://soap-authentication.org/digest/2001/10/" s:mustUnderstand="1">
            <Nonce>' 
    $this->challenge['1']['1'] . '</Nonce>
            <Auth>' 
    $Auth '</Auth>
            <UserID>' 
    $this->user '</UserID>
            <Realm>' 
    $this->challenge['1']['2'] . '</Realm>
            </h:ClientAuth></s:Header>
            <s:Body><u:GetCallList xmlns:u="urn:dslforum-org:service:X_AVM-DE_OnTel:1"></u:GetCallList></s:Body>
            </s:Envelope>'
    ;
            
    $this->debug($soap_msg_GetCallList"send GetCallList");
            
    $response $this->DoSOAPCall($soap_msg_GetCallList);
            if ((
    $response $this->DoSOAPCall($soap_msg_GetCallList)) === FALSE)
                return 
    FALSE;
            
    //$this->debug($response, "Fritz RAW response GetCallListURL");
            
    if (preg_match_all("(\<.+\>(.+)\<\/.+\>)U"$response$response_parts) === FALSE) {
                
    $this->error('Phone: fritz!box''SOAP parsing error!');
            }
            
    $this->debug($response_parts"preg_matched GetCallListURL");
            if (
    substr($response_parts['1']['3'], 04) === 'http') {
                
    $this->call_list_url $response_parts['1']['3'];
            } else {
                
    $this->error('Phone: fritz!box''GetCallList / Login failed!');
                return 
    FALSE;
            }
        }
        
    /**
         * TransformCallList: Download the callList limited by "calls_to_fetch" variable
         * and align the xml data to the standard format of smartvisu       
         */
        
    private function TransformCallList()
        {
            
    // build download url
            
    $url $this->call_list_url '&max=' $this->max_calls_to_fetch;
            
    $this->debug($url"URL for call_list");
            
    // download xml file and put it to xml parser
            
    $GetCallListXml file_get_contents($url);
            
    $simplexml      simplexml_load_string($GetCallListXml);
            
    $this->debug($GetCallListXml"GetCallListXml");
            
    /*
            [Id] => 1767
            [Type] => 1
            [Caller] => 0175000000
            [Called] => Amt ISDN 123456789
            [Name] => Mustermann, Max
            [Numbertype] => isdn
            [Device] => Wohnzimmer
            [Port] => 10
            [Date] => 08.02.14 12:43
            [Duration] => 0:32
            */
            // map fritz box xml values to the smartvisu standart        
            
    foreach ($simplexml->xpath('//Call') as $call) {
                
    // check if we got german date format and translate to ISO date
                //(smartvisu is using strtotime later on)
                
    if (preg_match("/[0-3]\d\.[0-1]\d\.\d{2}\s([0-1][0-9]|[2][0-3]):([0-5][0-9])/"$call->Date)) {
                    
    $date       DateTime::createFromFormat('d.m.y H:i'$call->Date);
                    
    $call->Date $date->format('Y-m-d H:i');
                }
                
    // bulid data array for smartvisu
                
    $this->data[] = array(
                    
    'pos' =>      (string) $call->Id,
                    
    'dir' =>      (string) ($call->Type == : ($call->Type == : -1)),
                    
    'date' =>     (string) $call->Date,
                    
    'number' =>   (string) $call->Caller,
                    
    'name' =>     (string) $call->Name,
                    
    'called' =>   (string) $call->Called,
                    
    'duration' => (string) $call->Duration
                
    );
                
    $call '';
            }
        }
        public function 
    run()

        {    
            
    $this->debug'smartvisu settings Server:"'.$this->server.'" User:"'.$this->user.'" Password:"'.$this->pass.'"' );
            
    // try to get Realm and Nonce from Box - this is required for login
            
    if ($this->InitChallenge() === FALSE) {
                
    $this->error('Phone: fritz!box''Error Connecting - check IP Address and TR-064 setting');
                return 
    FALSE;
                
    // when no password is set - InitChallenge returns CallList URL    directly    
            
    } elseif (substr($this->challenge['1']['0'], 04) == 'http') {
                
    $this->call_list_url $this->challenge['1']['0'];
                
    $this->TransformCallList();
                
    // login and gather login url
            
    } else {
                if (
    $this->GetCallListURL() !== FALSE) {
                    
    // get xml call data and transform to smartvisu format
                    
    $this->TransformCallList();
                }
            }
            
    // cleanup
            
    $this->challenge     '';
            
    $this->call_list_url '';
        }
    // class end

    // -----------------------------------------------------------------------------
    // call the service
    // -----------------------------------------------------------------------------
    $service = new phone_fritzbox_via_TR064(array_merge($_GET$_POST));
    echo 
    $service->json();
    ?>
    Angehängte Dateien
    Zuletzt geändert von voni99; 25.04.2015, 21:18.

    #2
    vielen Dank wird ausprobiert.
    OT: ist es eigentlich auch möglich den Anrufbeantworter abzufragen und abzuspielen?

    Kommentar


      #3
      Die Schnitstellen sind hier beschrieben:
      Schnittstellen für Entwickler | AVM Deutschland

      TAM-Messages: list, delete, download, mark as read

      zumindest kann man nachsehn ob eine neue Nachricht vorhanden ist und den AB ein- und ausschalten.
      Beim Download der Sprachdatei ist mir aktuell nicht bekannt in welchem Format das ist (Wave, MP3, oder was ganz anderes)...
      http://avm.de/fileadmin/user_upload/...llen/x_tam.pdf

      Kommentar


        #4
        Hallo,

        funktioniert bei mir leider nicht.
        IP, user, pw und Zugriff für Anwendungen zulassen ist alles richtig eingestellt.
        Habe es auch schon ohne pw in der Fritzbox probiert.
        Als Fehler bekomme ich:
        Error Connecting - check IP Address and TR-064 setting.

        Muss smartvisu hierfür auf der Fritzbox selbst laufen?


        Grüße

        Kommentar


          #5
          Hallo fidel86

          Zitat von fidel86 Beitrag anzeigen
          Muss smartvisu hierfür auf der Fritzbox selbst laufen?
          Nein smartvisu muss nicht direkt auf der Fritzbox laufen.
          Was zeigt der Browser an denn wenn Du versuchst diese Addresse zu öffnen: http://fritz.box:49000/

          Es müsste ein: "404 Not Found ERR_NOT_FOUND" Fehler erscheinen.
          Das bedeutet zumindest das die Fritzbox auf dem tcp port 49000 lauscht.

          Dann bitte auch nochmals mit der ip versuchen die im smartvisu
          in der Konfiguration unter der Phone "Addresse" eingetragen ist.
          http://<ip_der_fritz_box>:49000/

          Danach kann man sich den Output im Debugmodus vom smartvisu mit dem phone service angesehn :

          http://<-ip_vom_visu->/smartvisu/lib/phone/service/fritz!box_via_TR-064.php?debug=1

          Hier sind dann die Rohdaten ersichtlich:

          preg_matched InitChallenge (Unauthenticated is OK at this point!)
          ---------------------------------------------------
          Array (
          [0] => Array
          ([0] => Unauthenticated
          [1] => 82xxxxxxxxA97
          [2] => F!Box SOAP-Auth
          [3] => s:Client
          [4] => UPnPError
          [5] => 503
          [6] => Auth. failed...

          Bei mir läuft seit letzter Woche eine 7490 mit v6.23
          zuvor war es eine 7390 mit v6.20 ohne Probleme.


          Grüße Stefan

          Kommentar


            #6
            Hallo voni99,

            erstmal vielen Dank für Deine Hilfe.
            Ich habe http://192.168.1.1:49000/ aufgerufen und es kommt der Error 404.
            Ich kann es nur mit der IP aufrufen, da ich sonst auf der falschen Fritzbox lande.
            Der Error kommt jedoch unabhängig ob "Zugriff für Anwendungen zulassen" und "Statusinformationen über UPnP übertragen" aktiviert sind oder nicht.

            Der Aufruf von http://192.168.1.33/smartVISU/lib/ph...64.php?debug=1 liefert mir nur:

            data
            --------------------------------------------------------------------------------
            Array
            (
            [0] => Array
            (
            [title] => Phone: fritz!box
            [text] => Error Connecting - check IP Address and TR-064 setting
            )

            )

            [{"title":"Phone: fritz!box","text":"Error Connecting - check IP Address and TR-064 setting"}]

            Bei mir läuft eine 7390 mit 6.03 und eine 6320 mit 6.04.
            Welche Box ich abfrage ist eigentlich egal, da die Anrufe über beide ausgelesen werden können. Es funktioniert aber bei beiden nicht.

            Wie kann den Fehler weiter eingrenzen?
            Könnte es vielleicht ein Rechteproblem sein?

            Viele Grüße

            Kommentar


              #7
              Bei mir hats mit meiner alten 7170 auf Anhieb funktioniert !!
              Danke hierfür.. das alte Plugin ging nämlich nicht mehr !!

              good job !!!

              Gruß Martin
              Die Selbsthilfegruppe "UTF-8-Probleme" trifft sich diesmal abweichend im groüen Saal.

              Kommentar


                #8
                In Chrome bekomme ich in der Console einen Fehler:

                GET http://192.168.1.33/smartVISU/lib/ph...via_TR-064.php 601 (smartVISU Service Error)

                Ansonsten komme ich mit dem Plugin leider nicht weiter...

                Kommentar


                  #9
                  Hallo fidel86

                  Zitat von fidel86 Beitrag anzeigen
                  Wie kann den Fehler weiter eingrenzen?
                  Gut... dann weiter...
                  Ich gehe davon aus das Dein Smartvisu auf einem Linux läuft.
                  Erstelle bitte mal eine Datei namens "fritz_soap.xml" auf dem System wo auch die smartvisu läuft.

                  Inhalt der Datei sollte folgender sein:

                  Code:
                  <?xml version="1.0" encoding="utf-8"?>
                  <s:Envelope s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" >
                  <s:Header><h:InitChallenge xmlns:h="http://soap-authentication.org/digest/2001/10/" s:mustUnderstand="1">
                  <UserID>admin</UserID>
                  </h:InitChallenge ></s:Header><s:Body><u:GetCallList xmlns:u="urn:dslforum-org:service:X_AVM-DE_OnTel:1">
                  </u:GetCallList></s:Body>
                  </s:Envelope>
                  Dann bitte auf der Console folgenden Befehl ausführen:
                  Code:
                  wget http://<fritz_box_ip>:49000/upnp/control/x_contact --post-file=fritz_soap.xml --header="Content-type: text/xml" --header="SOAPAction: urn:dslforum-org:service:X_AVM-DE_OnTel:1#GetCallList" -O fritz_response.xml
                  Auf der console sollte das so aussehn:

                  Code:
                  --2015-01-29 22:14:05--  http://<fritz_box_ip>:49000/upnp/control/x_contact
                  Connecting to <fritz_box_ip>:49000... connected.
                  HTTP request sent, awaiting response... 200 OK
                  Length: 653 [text/xml]
                  Saving to: `fritz_response.xml'
                  
                  100%[======================================================>] 653         --.-K/s   in 0s      
                  
                  2015-01-29 22:14:05 (5.88 MB/s) - `fritz_response.xml' saved [653/653]
                  und in der Datei "fritz_response.xml" sollte folgendes zu finden sein
                  Code:
                  <?xml version="1.0"?>
                  <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
                  <s:Header>
                  <h:Challenge xmlns:h="http://soap-authentication.org/digest/2001/10/" s:mustUnderstand="1">
                  <Status>Unauthenticated</Status>
                  <Nonce>B8A1250B9EE87EEF</Nonce>
                  <Realm>F!Box SOAP-Auth</Realm>
                  </h:Challenge>
                  </s:Header>
                  <s:Body>
                  <s:Fault>
                  <faultcode>s:Client</faultcode>
                  <faultstring>UPnPError</faultstring>
                  <detail>
                  <UPnPError xmlns="urn:dslforum-org:control-1-0">
                  <errorCode>503</errorCode>
                  <errorDescription>Auth. failed</errorDescription>
                  </UPnPError>
                  </detail>
                  </s:Fault>
                  </s:Body>
                  </s:Envelope>

                  Kommentar


                    #10
                    Code:
                    wget http://192.168.1.1:49000/upnp/control/x_con                                                                                   tact --post-file=fritz_soap.xml --header="Content-type: text/xml" --header="SOAP                                                                                   Action: urn:dslforum-org:service:X_AVM-DE_OnTel:1#GetCallList" -O fritz_response                                                                                   .xml
                    --2015-01-29 23:14:15--  http://192.168.1.1:49000/upnp/control/x_contact
                    Connecting to 192.168.1.1:49000... connected.
                    HTTP request sent, awaiting response... 200 OK
                    Length: 372 [text/xml]
                    Saving to: `fritz_response.xml'
                    
                    100%[======================================>] 372         --.-K/s   in 0s
                    
                    2015-01-29 23:14:15 (6.33 MB/s) - `fritz_response.xml' saved [372/372]
                    liefert mir eine fritz_response.xml mit anderem Inhalt:

                    HTML-Code:
                    <?xml version="1.0"?>
                    <s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
                    <s:Body>
                    <u:GetCallListResponse xmlns:u="urn:dslforum-org:service:X_AVM-DE_OnTel:1">
                    <NewCallListURL>http://192.168.1.1:49000/calllist.lua?sid=890d3eb1c548e768</NewCallListURL>
                    </u:GetCallListResponse>
                    </s:Body>
                    </s:Envelope>

                    Kommentar


                      #11
                      Habe jetzt Passworteingabe wieder aktiviert (nur Passworteigabe) und jetzt sieht die response.xml bis auf die Zeile:
                      <Nonce>B8A1250B9EE87EEF</Nonce>
                      genauso aus...

                      Kommentar


                        #12
                        Hi fidel86

                        ok dein Gerät auf dem smartvisu läuft kommt an die FB (gut)
                        und die FB antwortet auch sofort mit der NewCallListURL.

                        Zitat von fidel86 Beitrag anzeigen
                        <NewCallListURL>http://192.168.1.1:49000/calllist.lua?sid=890d3eb1c548e768</NewCallListURL>
                        Du hast kein Passwort auf der FB ? stimmt oder ?

                        Hast du vieleicht einen user in der smartvisu phone einstellung eingetragen, obwohl kein passwort auf der FB ist, oder lautet der user der eingetragen ist anders als "admin"?

                        Wenn du kein Passwort auf der FB hast, versuch bitte mal beide Felder in der smartvisu leer zu lassen. Der zweite Versuch wär nur "admin" ohne passwort.

                        Sollte ein user und passwort eingerichtet sein, schau mal bitte ob dieser die Berechtigung hat für "Sprachnachrichten, Faxnachrichten, FRITZ!App Fon und Anrufliste" Dies ist eine Einstellung in der FB unter System-> Fritz!Box-Benutzer

                        ...
                        Sorry hab Deinen letzten Post nicht gelesen...
                        Ich stell das am Sontag mal bei mir nach - sorry geht nicht früher.
                        Bis bald.

                        Kommentar


                          #13
                          Hi,

                          ich habe in der DoSOAPCall für $this->server meine ip eingesetzt.
                          Daraufhin bekam ich den Fehler :
                          'Phone: fritz!box', 'GetCallList / Login failed!

                          Nachdem ich dann die Benutzeranmeldung abgeschalten habe klappt es auch mit dem auslesen und die Telefonliste wird angezeigt.

                          Kann ich mir irgendwie die den server, user und passwort anzeigen lassen, was da ausgelesen bzw. übergeben wird?

                          Grüße

                          Kommentar


                            #14
                            Zitat von fidel86 Beitrag anzeigen

                            Kann ich mir irgendwie die den server, user und passwort anzeigen lassen, was da ausgelesen bzw. übergeben wird?

                            Grüße
                            Klar
                            einfach in die die "run" Funktion folgende Zeile einfügen:

                            Code:
                                $this->debug( 'smartvisu settings Server:"'.$this->server.'" User:"'.$this->user.'" Password:"'.$this->pass.'"' );
                            schaut dann so aus:

                            Code:
                               public function run()
                                {    
                                    $this->debug( 'smartvisu settings Server:"'.$this->server.'" User:"'.$this->user.'" Password:"'.$this->pass.'"' );
                                    // try to get Realm and Nonce from Box - this is required for login
                                    if ($this->InitChallenge() === FALSE) {
                                        $this->error('Phone: fritz!box', 'Error Connecting - check IP Address and TR-064 setting'); 
                            ...
                            ...
                            Danach wieder smartvisu mit debug aufrufen:
                            http://<smartvisu_ip>/smartvisu/lib/phone/service/fritz!box_via_TR-064.php?debug=1

                            Bitte prüfe auch ob Leerzeichen vor oder nach den Parametern drin sind.
                            die Anführungszeichen müssen die Parameter genau einschließen.

                            Kommentar


                              #15
                              Ok,

                              ich bekomme 192.168.x.x und leeren Benutzer sowie Passwort.
                              Passe ich diese Daten in der default.php an, funktioniert alles.

                              Hast du einen Rat warum die Daten von der config Seite nicht angenommen werden?

                              Viele Grüße

                              Kommentar

                              Lädt...
                              X