FritzBox-Anrufmonitor über TCP

    • Offizieller Beitrag

    Möchte man für die FritzBox einen Anrufmonitor auf dem PC laufen lassen, so kann man dazu die FritzBox über den TCP-Port 1012 abfragen.
    Dieser muss vorher aber geöffnet werden:
    ; Zum öffnen des Ports muss man (einmalig), an einem an die FritzBox angeschlossenen Telefon, folgendes eingeben:
    ; Port öffnen: #96*5*
    ; Port schliessen: #96*4*

    Danach reicht ein einfaches Script, um die Meldungen zu empfangen:

    Spoiler anzeigen
    [autoit]


    Opt('TrayAutoPause', 0)
    HotKeySet('{ESC}', '_End')
    TCPStartup()

    [/autoit] [autoit][/autoit] [autoit]

    Global $sTelList = @ScriptDir & '\Anrufliste.txt' ; <- Datei, in der die Anrufe gespeichert werden

    [/autoit] [autoit][/autoit] [autoit]

    Global $sFritzBoxIP = TCPNameToIP('fritz.box') ; <- IP-Adresse der Fritzbox ermitteln

    [/autoit] [autoit][/autoit] [autoit]

    ; Zum öffnen des Ports muss man (einmalig), an einem an die FritzBox angeschlossenen Telefon, folgendes eingeben:
    ; Port öffnen: #96*5*
    ; Port schliessen: #96*4*
    Global $sFritzBoxPort = 1012 ; <- TCP-Port zur Abfrage der Fritzbox

    [/autoit] [autoit][/autoit] [autoit]

    Global $hFritzSocket = TCPConnect($sFritzBoxIP, $sFritzBoxPort) ; <- Verbindung zur Fritzbox herstellen
    If $hFritzSocket = -1 Then Exit MsgBox(0, 'Fehler!', 'Es konnte keine Verbindung zur FritzBox hergestellt werden.')

    [/autoit] [autoit][/autoit] [autoit]

    TrayTip('FritzBox', 'Anrufmonitor aktiv', 1000)
    Global $sFritzRecv = ''
    While Sleep(50)
    $sFritzRecv = TCPRecv($hFritzSocket, 2048)
    If $sFritzRecv <> '' Then _TelRing($sFritzRecv)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _TelRing($sRecv)
    ConsoleWrite($sRecv & @CR)
    Local $aMsg = StringSplit($sRecv, ';')
    If Not IsArray($aMsg) Then Return
    If $aMsg[0] < 5 Then Return
    Switch $aMsg[2]
    Case 'RING'
    FileWriteLine($sTelList, $aMsg[1] & ' Tel.-Nr.: ' & $aMsg[4])
    TrayTip('Anruf', $aMsg[4], 30, 1)
    Case 'DISCONNECT'
    TrayTip('', '', 0)
    EndSwitch
    EndFunc ;==>_TelRing

    [/autoit] [autoit][/autoit] [autoit]

    Func _End()
    TCPCloseSocket($hFritzSocket)
    TCPShutdown()
    Exit
    EndFunc ;==>_End

    [/autoit]

    Das funktioniert auf jeden Fall mit der 7170 und der 7490. Diese beiden Boxen besitze ich und damit ist das Script getestet.
    Es sollten aber auch die anderen FritzBoxen funktionieren. Ich würde mich über entsprechende Rückmeldungen freuen.

    Funktionierende Fritzboxen (getestet):
    Oscar: 7170 und 7490
    UEZ: 7362 SL
    Simulac2: 7330

  • Danke Oscar :)
    Hast du damit mal einen längeren Test gemacht? Ich habe das auch mal versucht. Aber nach einiger Zeit ist das Programm immer ausgestiegen und hat nicht mehr auf Anrufe reagiert.
    Außerdem hatte ich das Problem, dass immer nur ein Client bei der Fritzbox direkt abfragen konnte. Wenn ein zweiter Client gestartet wurde, war der erste spätestens beim nächsten Anruf raus und hat nicht mehr reagiert.
    Grüße autoiter

    Grüße autoiter

    • Offizieller Beitrag

    Was meinst Du mit "längeren Test"?
    Über mehrere Stunden läuft das auf jeden Fall problemlos. Jedes Mal, wenn ich meinen Rechner an habe, läuft auch der Anrufmonitor.
    Mehrere Clients habe ich bisher nicht getestet. Ich weiß nicht, ob die FritzBox mehrere Clients unterstützt. Wenn ich Zeit habe, werde ich das bei mir mal testen...

  • Was meinst Du mit "längeren Test"?
    Über mehrere Stunden läuft das auf jeden Fall problemlos. Jedes Mal, wenn ich meinen Rechner an habe, läuft auch der Anrufmonitor.


    Ja, ich meinte das in etwa so. Bei mir kam irgendwann keine Reaktion mehr. (Bsp: Morgens um acht angemacht und mittags um halb eins plötzlich keine Reaktion mehr auf Anrufe).
    Ich werde deinen mal testen. Wenn das durchläuft wäre das echt klasse. Da muss ich auch mal meinen Code raussuchen und vergleichen. Danke auf jeden Fall.
    Das Problem mit mehreren Clients hatte ich auch bei anderen Programmen die ich ausprobiert habe. Besser lauscht nur ein Client direkt auf die Box.

    Grüße autoiter

  • Hey...

    Was zum Thema Fritzbox...
    Mir ist gerade aufgefallen das man über die Verbindung schönen nen Traffic Monitor bauen kann, der nicht nur den Traffic vom PC sondern von der Fritzbox ( komplettes Haus ) anzeigt...
    Sollte auf den meisten FritzBoxen funzen...

    Spoiler anzeigen
    [autoit]

    #include<string.au3>
    #include<array.au3>

    [/autoit] [autoit][/autoit] [autoit]

    $FB_WANCommonInterface = 1
    $FB_Port = 49000
    $FB_IP = '192.168.178.1'

    [/autoit] [autoit][/autoit] [autoit]

    Global $NewByteSendRate,$NewByteReceiveRate,$NewPacketSendRate,$NewPacketReceiveRate,$NewTotalBytesSent, _
    $NewTotalBytesReceived,$NewAutoDisconnectTime,$NewIdleDisconnectTime,$NewDNSServer1,$NewDNSServer2, _
    $NewVoipDNSServer1,$NewVoipDNSServer2,$NewUpnpControlEnabled,$NewRoutedBridgedModeBoth

    [/autoit] [autoit][/autoit] [autoit]

    TCPStartup()
    $Conn = TCPConnect($FB_IP,$FB_Port)
    If @error Then
    MsgBox (16,"error","Kann nicht verbinden")
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    While 1

    [/autoit] [autoit][/autoit] [autoit]

    _FB_GetAddonInfos($Conn)
    ToolTip( 'NewByteSendRate: '&_ConvertSize($NewByteSendRate)&'/s'&@CRLF& _
    'NewByteReceiveRate: '&_ConvertSize($NewByteReceiveRate)&'/s'&@CRLF& _
    'NewTotalBytesSent: '&_ConvertSize($NewTotalBytesSent)&@CRLF& _
    'NewTotalBytesReceived: '&_ConvertSize($NewTotalBytesReceived)&@CRLF)

    [/autoit] [autoit][/autoit] [autoit]

    Sleep ( 1000 )

    [/autoit] [autoit][/autoit] [autoit]

    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _FB_GetAddonInfos($Conn)

    [/autoit] [autoit][/autoit] [autoit]

    $FB_POST_DATA = @crlf&'<?xml version="1.0"?>'&@crlf& _
    '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/"'&@crlf& _
    's:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'&@crlf& _
    '<s:Body><u:GetAddonInfos xmlns:u="urn:schemas-upnp-org:service:WANCommonInterfaceConfig:'&$FB_WANCommonInterface&'"></u:GetAddonInfos>'&@crlf& _
    '</s:Body>'&@crlf& _
    '</s:Envelope>'

    [/autoit] [autoit][/autoit] [autoit]

    $FB_POST_HEADER='POST /upnp/control/WANCommonIFC1 HTTP/1.1'&@crlf& _
    'SOAPACTION: urn:schemas-upnp-org:service:WANCommonInterfaceConfig:'&$FB_WANCommonInterface&'#GetAddonInfos'&@crlf& _
    'Content-Type: text/xml; charset="utf-8"'&@crlf& _
    'User-Agent: AVM UPnP/1.0 Client 1.0'&@crlf& _
    'Host: fritz.box:'&$FB_Port&@crlf& _
    'Content-Length: '&StringLen($FB_POST_DATA)&@crlf& _
    'Expect: 100-continue'&@crlf& _
    'Connection: Keep-Alive'&@crlf&@crlf

    [/autoit] [autoit][/autoit] [autoit]

    TCPSend ( $Conn, $FB_POST_HEADER )
    TCPSend ( $Conn, $FB_POST_DATA )

    [/autoit] [autoit][/autoit] [autoit]

    $FB_Recv = TCPRecv($Conn,2048)

    [/autoit] [autoit][/autoit] [autoit]

    $NewByteSendRate = _StringBetweenAsString($FB_Recv,'<NewByteSendRate>','</NewByteSendRate>')
    $NewByteReceiveRate = _StringBetweenAsString($FB_Recv,'<NewByteReceiveRate>','</NewByteReceiveRate>')
    $NewPacketSendRate = _StringBetweenAsString($FB_Recv,'<NewPacketSendRate>','</NewPacketSendRate>')
    $NewPacketReceiveRate = _StringBetweenAsString($FB_Recv,'<NewPacketReceiveRate>','</NewPacketReceiveRate>')
    $NewTotalBytesSent = _StringBetweenAsString($FB_Recv,'<NewTotalBytesSent>','</NewTotalBytesSent>')
    $NewTotalBytesReceived = _StringBetweenAsString($FB_Recv,'<NewTotalBytesReceived>','</NewTotalBytesReceived>')
    $NewAutoDisconnectTime = _StringBetweenAsString($FB_Recv,'<NewAutoDisconnectTime>','</NewAutoDisconnectTime>')
    $NewIdleDisconnectTime = _StringBetweenAsString($FB_Recv,'<NewIdleDisconnectTime>','</NewIdleDisconnectTime>')
    $NewDNSServer1 = _StringBetweenAsString($FB_Recv,'<NewIdleDisconnectTime>','</NewDNSServer1>')
    $NewDNSServer2 = _StringBetweenAsString($FB_Recv,'<NewDNSServer2>','</NewDNSServer2>')
    $NewVoipDNSServer1 = _StringBetweenAsString($FB_Recv,'<NewVoipDNSServer1>','</NewVoipDNSServer1>')
    $NewVoipDNSServer2 = _StringBetweenAsString($FB_Recv,'<NewVoipDNSServer2>','</NewVoipDNSServer2>')
    $NewUpnpControlEnabled = _StringBetweenAsString($FB_Recv,'<NewUpnpControlEnabled>','</NewUpnpControlEnabled>')
    $NewRoutedBridgedModeBoth = _StringBetweenAsString($FB_Recv,'<NewRoutedBridgedModeBoth>','</NewRoutedBridgedModeBoth>')

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    Func _StringBetweenAsString($String,$start,$end)

    [/autoit] [autoit][/autoit] [autoit]

    $return = _StringBetween($String,$start,$end)
    If @error Or Not IsArray($return) Then
    SetError( 1,0,'' )
    Else
    Return $return[0]
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    EndFunc

    [/autoit] [autoit][/autoit] [autoit]

    ; THX crzftx @ http://www.autoitscript.com/forum/topic/63…ile-size-in-mb/
    Func _ConvertSize($inputSize, $inputUnit = 0, $outputPlaces = 2, $outputString = True, $inputBits = False, $outputBits = False, $outputUnit = -4)
    Local $unitNames[9] = ["","K","M","G"]
    Local $bytes = $inputSize * 1024 ^ $inputUnit
    Local $b = "B"

    [/autoit] [autoit][/autoit] [autoit]

    If $inputBits Then $bytes /= 8
    If $outputBits Then
    $bytes *= 8
    $b = "b"
    EndIf
    If $outputUnit < 0 Then
    Local $outputMax = Abs($outputUnit)
    $outputUnit = Int(Log($bytes)/Log(1024))
    If $outputUnit > $outputMax Then $outputUnit = $outputMax
    EndIf
    If $outputString Then
    Return String(Round($bytes / 1024 ^ $outputUnit, $outputPlaces)) & $unitNames[$outputUnit] & $b
    Else
    Return Round($bytes / 1024 ^ $outputUnit, $outputPlaces)
    EndIf
    EndFunc

    [/autoit]

    Gleich mal in die UDF fürs Display von Tinkerforge machen *muhahahaha*

    MFG Chris :D

  • Dieser Callmonitor steigt bei mir auch nach einiger Zeit aus und meldet nichts mehr. Allerdings wohl kein Programmfehler.

    Da das bei anderen aber offensichtlich nicht so ist, liegt es wohl einfach an meiner Netzwerkkonfiguration. Vergesst also meine oben geschriebenen Bedenken.
    (Der Rechner auf dem der Callmonitor läuft, bekommt befindet sich im IP Kreis einer Fritzbox, die hinter der eigentlich mit dem Internet verbundenen Fritzbox liegt. Diese wird aber überwacht. Wahrscheinlich führt das zum Problem. Ich habe aber noch nicht getestet, ob es bei direkter Verbindung geht).

    Grüße autoiter

  • Hi OSCAR,
    hab da ein bisschen mit deinem CODE rumgebastelt
    Danke für die Idee!


    Spoiler anzeigen
    [autoit]

    #include <array.au3>
    #include <String.au3>
    #include <File.au3>

    [/autoit] [autoit][/autoit] [autoit]

    Opt('TrayAutoPause', 0)
    HotKeySet('^!{ESC}', '_End') ;~ mit Alt + Strg + ESC Programm beenden
    TCPStartup()

    [/autoit] [autoit][/autoit] [autoit]

    Global $sTelList = @ScriptDir & '\Anrufliste.txt' ; <- Datei, in der die Anrufe gespeichert werden

    [/autoit] [autoit][/autoit] [autoit]

    Global $sFritzBoxIP = TCPNameToIP('fritz.box') ; <- IP-Adresse der Fritzbox ermitteln

    [/autoit] [autoit][/autoit] [autoit]

    ; Zum öffnen des Ports muss man (einmalig), an einem an die FritzBox angeschlossenen Telefon, folgendes eingeben:
    ; Port öffnen: #96*5*
    ; Port schliessen: #96*4*
    Global $sFritzBoxPort = 1012 ; <- TCP-Port zur Abfrage der Fritzbox
    Global $TelefonbuchSeiteVor = 'http://www3.dastelefonbuch.de/?kw='
    Global $TelefonbuchSeiteHinter = '&s=a20000&cmd=search&ort_ok=0&sp=3&vert_ok=0&aktion=23'
    Global $EigeneVorwahl = 02676
    Global $FilterVor = 'itemprop="name" title="'
    Global $FilterHinter = '" rel="nofollow"'

    [/autoit] [autoit][/autoit] [autoit]

    Global $hFritzSocket = TCPConnect($sFritzBoxIP, $sFritzBoxPort) ; <- Verbindung zur Fritzbox herstellen
    If $hFritzSocket = -1 Then Exit MsgBox(0, 'Fehler!', 'Es konnte keine Verbindung zur FritzBox hergestellt werden.')

    [/autoit] [autoit][/autoit] [autoit]

    TrayTip('FritzBox', 'Anrufmonitor aktiv', 1000)
    Global $sFritzRecv = ''
    While Sleep(50)
    $sFritzRecv = TCPRecv($hFritzSocket, 2048)
    If $sFritzRecv <> '' Then _TelRing($sFritzRecv)
    WEnd

    [/autoit] [autoit][/autoit] [autoit]

    Func _TelRing($sRecv)
    ConsoleWrite($sRecv & @CR)
    Local $aMsg = StringSplit($sRecv, ';')
    If Not IsArray($aMsg) Then Return
    If $aMsg[0] < 5 Then Return
    Switch $aMsg[2]

    [/autoit] [autoit][/autoit] [autoit]

    Case 'RING'
    If $aMsg[4]=0 Then
    $aMsg[4]="Unterdrückte Rufnummer!"
    TrayTip('ankommender Anruf', $aMsg[4], 30, 1)
    FileWriteLine($sTelList, $aMsg[1] & ' Tel.-Nr.: ' & $aMsg[4])

    [/autoit] [autoit][/autoit] [autoit]

    Else
    If FileExists(@TempDir & '\telefonat.html') Then FileDelete(@TempDir & '\telefonat.html')
    InetGet($TelefonbuchSeiteVor&$aMsg[4]&$TelefonbuchSeiteHinter, @TempDir & '\telefonat.html')
    $Name = _StringBetween(FileRead(@TempDir & '\telefonat.html'), $FilterVor, $FilterHinter)
    If FileExists(@TempDir & '\telefonat.html') Then FileDelete(@TempDir & '\telefonat.html')
    If IsArray($Name) Then
    TrayTip('ankommender Anruf', $aMsg[4] & " " & $Name[0], 30, 1)
    FileWriteLine($sTelList, $aMsg[1] & ' Tel.-Nr.: ' & $aMsg[4] & ' ' & $Name[0])
    Else
    $Name = "Name nicht im Telefonbuch!"
    TrayTip('ankommender Anruf', $aMsg[4] & " " & $Name, 30, 1)
    FileWriteLine($sTelList, $aMsg[1] & ' Tel.-Nr.: ' & $aMsg[4] & ' ' & $Name)
    EndIf
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Case 'DISCONNECT'
    $zeit=Sec2Time($aMsg[4])
    TrayTip('Aufgelegt', 'Geführter Telefonat dauerte: ' & $zeit, 0)

    [/autoit] [autoit][/autoit] [autoit]

    Case 'CALL'
    $TelefonNummer = Stringsplit($aMsg[6], "")
    If Not $TelefonNummer[0]=0 Then $aMsg[6]=$EigeneVorwahl&$aMsg[6]
    If FileExists(@TempDir & '\telefonat.html') Then FileDelete(@TempDir & '\telefonat.html')
    InetGet($TelefonbuchSeiteVor&$aMsg[6]&$TelefonbuchSeiteHinter, @TempDir & '\telefonat.html')
    $Name = _StringBetween(FileRead(@TempDir & '\telefonat.html'), $FilterVor, $FilterHinter)
    If FileExists(@TempDir & '\telefonat.html') Then FileDelete(@TempDir & '\telefonat.html')
    If IsArray($Name) Then
    TrayTip('ausgehender Anruf', $aMsg[6] & " " & $Name[0], 30, 1)
    FileWriteLine($sTelList, $aMsg[1] & ' Tel.-Nr.: ' & $aMsg[6] & ' ' & $Name[0])
    Else
    $Name = "Name nicht im Telefonbuch!"
    TrayTip('ausgehender Anruf', $aMsg[6] & " " & $Name, 30, 1)
    FileWriteLine($sTelList, $aMsg[1] & ' Tel.-Nr.: ' & $aMsg[6] & ' ' & $Name)
    EndIf

    [/autoit] [autoit][/autoit] [autoit]

    Case 'CONNECT'
    If $aMsg[5]=0 Then $aMsg[5]="unterdrückte Rufnummer!"
    TrayTip('verbunden mit', $aMsg[5], 30, 1)

    [/autoit] [autoit][/autoit] [autoit]

    EndSwitch
    EndFunc ;==>_TelRing

    [/autoit] [autoit][/autoit] [autoit]

    Func Sec2Time($nr_sec)
    $sec2time_hour = Int($nr_sec / 3600)
    $sec2time_min = Int(($nr_sec - $sec2time_hour * 3600) / 60)
    $sec2time_sec = $nr_sec - $sec2time_hour * 3600 - $sec2time_min * 60
    Return StringFormat('%02d:%02d:%02d', $sec2time_hour, $sec2time_min, $sec2time_sec)
    EndFunc ;==>Sec2Time

    [/autoit] [autoit][/autoit] [autoit]

    Func _End()
    TCPCloseSocket($hFritzSocket)
    TCPShutdown()
    Exit
    EndFunc ;==>_End

    [/autoit]



    Edit Oscar: AutoIt- und Spoiler-Tags eingefügt.

    2 Mal editiert, zuletzt von Oscar (16. Februar 2015 um 18:15)

    • Offizieller Beitrag

    Bitte!
    Vielleicht solltest Du Dein Script als neuen Thread in "Scripte" erstellen, damit Dein Script leichter gefunden wird. Es ist ja doch etwas umfangreicher als mein obiges Beispielscript.
    Als kleinen Tip:
    Dein benutzen von InetGet erfordert zahlreiche Festplattenzugriffe (langsam und unnötig). Mit "InetRead" und "BinaryToString" geht es schneller und ohne Festplattenzugriffe.

  • Hab das jetzt so gelöst

    Code
    $Name = _UmlauteTauschen(_StringBetween(BinaryToString(InetRead($TelefonbuchSeiteVor & $aMsg[4] & $TelefonbuchSeiteHinter,16)), $FilterVor, $FilterHinter))

    klappt bis jetzt ganz gut