fritzcap: Tool für Etherreal Trace und Audiodaten-Extraktion v2.0

Ich verfolge das Thema nicht weiter.
"Da du es anscheinend nicht gelesen hast."
1. Ist das hier ein Internet-Forum, da geht es nicht nur um dich, […]

Ob die Diskusion für dich beendet ist oder nicht interesiert mich eher sekundär. Für andere ist sie das ggf. eben noch nicht. Und wenn man das, was du geschrieben/behauptest hattest, unkommentiert stehen lässt, glauben das andere vielleicht auch noch ohne es selbst vielleicht erst einmal zu testen. Und wenn du eben nicht (mehr) bereit bist das überhaupt zu testen, dann vielleicht eben andere. Das Forum ist eben nun mal nicht nur für dich da!
 
  • Like
Reaktionen: PeterPawn
Hallo zusammen,

habe nochmal nachgedacht bzw. nachgeguckt.
Meine Theorie, dass es einer Änderung an der decoder.py bedarf, ist natürlich Blödsinn. Wie @NDiIPP schon sinngemäß ausgeführt hat, ändert eine neue HW bzw. SW ja nichts an der TAL, also in dem Fall der Telefonleitung, sprich: Jemand mit einem TAD200 wird nichts davon merken, dass sein Nachbar jetzt 7.56 auf seiner Fritbox hat und weiterhin normal telefonieren können. ;-)

Desweiteren habe ich nach dem funktionierenden String mit einer FW 7.29 geguckt, und der sieht so aus:

Code:
http://192.168.178.1/cgi-bin/capture_notimeout?start=1&start1=Start&ifaceorminor= &sid=****************

Siehe auch hier.

Hoffe, dass damit jemand evtl weiter kommt.
Grüße

JD.
 
Zuletzt bearbeitet:
Hallo zusammen,

ich habe nochmal bei meiner 7490 mit Fritz!OS 7.29 und funktionierendem fritzcap ein wenig weiter geforscht.
Die Codierung ist G.711 (Telefonie->Eigene Rufnummern->Sprachübertragung).
Netzwerkschnittstellen sind: eth3, ppptty, ifb0, wlan_guest, wlan_wan, lan, eth2, tunl0, eth1, ing0, wlan_hotspot, ptm_vr9, eoam, eth0, guest, ifb1, wlan.

Wie könnte denn damit für Fritz!OS 7.56 ein geeigneter Startstring hinsichtlich ifaceorminor bzw. cap_interface aussehen ?
Grüße

JD.
 
Also ich habe mal mit meiner 6591 V7.57 vodafone getestet und es funktioniert bei mir wie folgt:


Ich zeichen den lan port auf der 1-lan heisst in der Liste und die Pakete haben eine maximale Länge von 294 bei meinem vodafoneanschluss
die kommen manchmal mit 214 manchmal mit 294.

Beim stoppen funktioniert das:


Die Datei wird normal erzeugt und kann dekodiert werden. Wie und an welcher Stelle ihr das in Euer pythonscript einbaut müsst ihr entscheiden.
 
Zuletzt bearbeitet:
Offtopic: Du solltest es mit dem kompletten String versuchen, du benutzt ja nur den gekürzten mit Punkten ;)

Für die anderen:
Ich hoffe die meisten wissen wie sie das ins python einsetzen, sollte ja nicht so schwierig sein, die SID wird ja bei
dazukopiert und sollte natürlich nicht die von oben sein.
 
Hallo,
vielleicht könnte ja The_Surfer doch noch zeigen wie er die Datei angepasst hat.
Nach einiger Testerei bekomme ich es nicht zum laufen.
Jetzt weis ich nicht ob es am Anbieter, am meiner zusammensetzung oder an beidem liegt.

MfG
 
in der config sind meine Strings wie folgt:
start_str = ?start=1&start1=Start
stop_str = ?stop=1&stop1=Stop
cap_interface = 1-lan

und im script in capture_monitor beim capture-Start:
url_start = self.base_url + '/cgi-bin/capture_notimeout' + self.start_str + '&snaplen=294' + "&filter=" + "&ifaceorminor=" + self.cap_interface + "&capture=Start"

beim stoppen:
self.ifaceorminor = self.cap_interface.split("-") -> musst die Variable noch definieren in der Klasse mit z.B: ifaceorminor = ["0", "0"] oder den minor und iface von Hand reinschreiben.
url_stop = self.base_url + '/cgi-bin/capture_notimeout' + self.stop_str + "&iface=lan" + "&minor=" + self.ifaceorminor[1] + "&type=" + self.ifaceorminor[0] + "&capture=Stop"
 
Zuletzt bearbeitet:
  • Like
Reaktionen: claudioso
Ich muss einmal nachfragen.
Habe die Fritzbox 7490 mit der aktuellen FW 7.57

Es werden auch alle 4 Dateien erstellt, die mix_0_1.wav funktioniert einwandfrei.
Das Problem ist das die .cap nach auflegen weiter geschrieben wird, warscheinlich schreibt er so lange bis irgendwann die HD voll ist.
Bei erneutem Anruf wird zwar ein neuer Ordner und .cap angelegt diese wird allerdings nicht gefüllt, vom ersten Anruf die .cap läuft weiter hoch.
Ich muss fritzcap beenden/ ich starte den Raspberry neu damit die Datei nicht weiter voll geschrieben wird, und ein erneuter Anruf möglich ist.
Wie lautet der Befehl um Fritzcap zu beenden? Dann benötige ich nicht immer einen Neustart vom Raspberry.
Mein Aufruf:

Code:
python fritzcap.py --capture_files --decode_files --monitor_calls --cap_interface 3-17 --box_name 191.168.178.1 --username xxxx --password xxxxx

Die Fritzcap.conf
Code:
[settings]
# capture_files        =
# decode_files         =
# monitor_calls        =
# password             = xxxx

# logging_config       =
# box_name             = fritz.box
# call_service_port    = 1012
# login_not_required   =
# protocol             = http
# cap_folder             = captures/%(tcaps.Y-m-d/HMS)/
cap_folder             = usb/Fritzbox/%(tcaps.Y-m-d/HMS)/
# cap_file               = capture_%(callevent.name)_%(dialed.number)_%(caller.number)_%(tcaps.Y-m-d-H-M-S).cap
cap_file               = capture_%(callevent.name)_%(dialed.number)_%(caller.number)_%(tcaps.H-M-S).cap
# after_capture_time   = 10
# decode_workers_count = 2

default_login   = getpage=../html/de/menus/menu2.html&errorpage=../html/index.html&var:lang=de&var:pagename=home&var:menu=home&=&login:command/password=%s
# default_login   = getpage=../html/de/menus/menu2.html&errorpage=../html/index.html&var:lang=de&var:pagename=home&var:menu=home&=&login:command/password=xxxxxx
sid_challenge   = getpage=../html/login_sid.xml
sid_login       = login:command/response=%s&getpage=../html/login_sid.xml
start_str       = ?start=1&start1=Start
stop_str        = ?stop=1&stop1=Stop
cap_interface   = 1-lan

capture_monitor.py
Code:
#!/usr/bin/python
# -*- coding: iso-8859-1 -*-
#################################################################################
# Simple FritzCap python port
# Simplifies generation and examination of traces taken from AVM FritzBox and/or SpeedPort
# Traces can be examined using WireShark
# (c) tom2bor 2011 (tom2bor in http://www.ip-phone-forum.de/)
# based on the Windows GUI exe with same name
##################################################################################
# Copyright (c) 2011, tom2bor
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#    * Redistributions of source code must retain the above copyright
#      notice, this list of conditions and the following disclaimer.
#    * Redistributions in binary form must reproduce the above copyright
#      notice, this list of conditions and the following disclaimer in the
#      documentation and/or other materials provided with the distribution.
#    * Neither the name of the <organization> nor the
#      names of its contributors may be used to endorse or promote products
#      derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##################################################################################

import datetime
import logging
import threading
import Queue
import time, datetime, random
import urllib
import os
import re
import hashlib

from log import Log
from string_helper import StringHelper
from tracer import Tracer
from exception_logging_thread import ExceptionLoggingThread

class CaptureMonitor(ExceptionLoggingThread):

    state_started = False
    next_stop_time = 0
    next_start_time = 0
    cap_file_path = ""
    def __init__(self, decode_work_queue, data_map, box_name, username, password, protocol, cap_folder, cap_file, cap_interface, login_required, default_login, sid_challenge, sid_login, start_str, stop_str, after_capture_time):
        ExceptionLoggingThread.__init__(self)
        self._stop = threading.Event()

        self.decode_work_queue = decode_work_queue
        self.data_map = data_map
        self.box_name = box_name
        self.username = username
        self.password = password
        self.protocol = protocol
        self.cap_folder = cap_folder
        self.cap_file = cap_file
        self.cap_interface = cap_interface
        self.login_required = login_required
        self.default_login = default_login
        self.sid_challenge = sid_challenge
        self.sid_login = sid_login
        self.start_str = start_str
        self.stop_str = stop_str
        self.after_capture_time = int(after_capture_time)
        self.SID = ''

        self.base_url = self.protocol + '://' + self.box_name

        self.wait_condition = threading.Condition()

        self.logger = Log().getLogger()
        self.logger.debug("CaptureMonitor(decode_work_queue:'%s', data_map:'%s', box_name:'%s', username:'%s', password:'%s', protocol:'%s', cap_folder:'%s', cap_file:'%s', cap_interface:'%s', login_required:'%s', default_login:'%s', sid_challenge:'%s', sid_login:'%s', start_str:'%s', stop_str:'%s', after_capture_time:'%s')" % (decode_work_queue,data_map,box_name,username,password,protocol,cap_folder,cap_file,cap_interface,login_required,default_login,sid_challenge,sid_login,start_str,stop_str,after_capture_time))

    def run_logic(self):
        self.logger.debug("Thread started.")

        if self.login_required:
           if (not self.init_login()):
               self.logger.debug("Could not login. Stop the capture thread.")
               self._stop.set()

        while not self._stop.isSet():
            ###################
            ### pre_capture ###
            ###################
            # Wait until start_capture command was started...
            self.logger.debug("pre_capture acquire lock.")
            self.wait_condition.acquire()
            self.logger.debug("pre_capture acquire lock finished.")
            while not self._stop.isSet() and (self.state_started == False or self.next_start_time > time.time()):
                if self.next_start_time > time.time():
                    waittime = self.next_start_time - time.time()
                    if (self.logger.isEnabledFor(logging.DEBUG)):
                        self.logger.debug("pre_capture wait(%f)." % (waittime))
                    self.wait_condition.wait(waittime)
                    if (self.logger.isEnabledFor(logging.DEBUG)):
                        self.logger.debug("pre_capture wait(%f) finished." % (waittime))
                else:
                    if (self.logger.isEnabledFor(logging.DEBUG)):
                        self.logger.debug("pre_capture wait().")
                    self.wait_condition.wait()
                    if (self.logger.isEnabledFor(logging.DEBUG)):
                        self.logger.debug("pre_capture wait() finished.")

            self.logger.debug("pre_capture release lock.")
            self.wait_condition.release()
            self.logger.debug("pre_capture release lock finished.")

            if (self._stop.isSet()):
                logging.debug("The capture was not started. Not need to stop the capture. Can stop immediately.")
                break

            self.sub_start_capture()

            ####################
            ### post_capture ###
            ####################
            # Wait until stop_capture command was started...
            self.logger.debug("post_capture acquire lock.")
            self.wait_condition.acquire()
            self.logger.debug("post_capture acquire lock finished.")
            while not self._stop.isSet() and (self.state_started == True or self.next_stop_time > time.time()):
                if self.next_stop_time > time.time():
                    waittime = self.next_stop_time - time.time()
                    if (self.logger.isEnabledFor(logging.DEBUG)):
                        self.logger.debug("post_capture wait(%f)." % (waittime))
                    self.wait_condition.wait(waittime)
                    if (self.logger.isEnabledFor(logging.DEBUG)):
                        self.logger.debug("post_capture wait(%f) finished." % (waittime))
                else:
                    if (self.logger.isEnabledFor(logging.DEBUG)):
                        self.logger.debug("post_capture wait().")
                    self.wait_condition.wait()
                    if (self.logger.isEnabledFor(logging.DEBUG)):
                        self.logger.debug("post_capture wait() finished.")
            self.logger.debug("post_capture release lock.")
            self.wait_condition.release()
            self.logger.debug("post_capture release lock finished.")

            self.sub_stop_capture()

        if (self._stop.isSet()):
            if (self.decode_work_queue is not None):
                self.decode_work_queue.put(None)
        else:
            self._stop.set()
        self.logger.debug("Thread stopped.")



    def init_login(self):
        try:
            self.logger.debug("Login attempt to the the FritzBox (box_name:%s)" % (self.box_name))

            # Try to get a session id SID
            conn_url = self.base_url + '/login_sid.lua'
            self.logger.debug("Call the challange token url (url:'%s')" % conn_url)
            self.sid = urllib.urlopen(conn_url)
            sid_http_result = self.sid.getcode()
            self.logger.debug("SID HTTP result:%s" % sid_http_result)
            if sid_http_result == 200:
                # Read and parse the response in order to get the challenge (not a full blown xml parser)
                readed_chalange_str = self.sid.read()
                challenge = re.search('<Challenge>(.*?)</Challenge>', readed_chalange_str).group(1)

                # Create a UTF-16LE string from challenge + '-' + password, non ISO-8859-1 characters will except here (e.g. EUR)
                challenge_bf = (challenge + '-' + self.password).decode('iso-8859-1').encode('utf-16le')

                # Calculate the MD5 hash
                m = hashlib.md5()
                m.update(challenge_bf)

                # Make a byte response string from challenge + '-' + md5_hex_value
                response_bf = challenge + '-' + m.hexdigest().lower()

                # Answer the challenge
                conn_url = self.base_url + '/login_sid.lua?username=' + self.username + '&response=' + response_bf
                self.logger.debug("Call the read seed token url (url:'%s', data:'%s')." % (conn_url,self.sid_login % response_bf))
                login = urllib.urlopen(conn_url)
                login_http_result = login.getcode()
                self.logger.debug("Login HTTP result:%s" % login_http_result)
                if login_http_result == 200:
                    read_login_str = login.read()
                    self.SID = re.search('<SID>(.*?)</SID>', read_login_str).group(1)
                    if (self.SID == '0000000000000000'):
                        self.logger.error("Could not login to the FritzBox: Not authorized.  (SID: %s)" % self.SID)
                    else:
                        self.logger.debug("Login OK (SID: %s)" % self.SID)
                    return True

                else:
                    self.logger.error("Could not login to the FritzBox: Unknown error")
            else:
                self.logger.error("Could not login to the FritzBox: Error 404.")
        except Exception as e:
            self.logger.debug("Exception during SID logon: %s" % e )
            # Legacy login
            command = urllib.urlopen(self.base_url + '/cgi-bin/webcm', self.default_login % self.password)
            response = command.read()
            # Right now I don't know how to check the result of a login operation. So I just search for the errorMessage
            if command.getcode() == 200:
                try:
                    result = urllib.unquote(re.search('<p class="errorMessage">(.*?)</p>', response).group(1).decode('iso-8859-1')).replace("&nbsp;"," ")
                except:
                    result = ''
                self.logger.error('Login attempt was made, but something was wrong: %s' % result)
        return False

    def init_capture_file(self):
    # Create capfile folder
    folder = ""
    sections = self.cap_folder.split("%(")
    for sec in sections:
        folder += StringHelper.parse_string("%("+sec, self.data_map)
        folder = folder.replace("%(","")
        folder = folder.replace("\\","/")
        if (not folder.endswith("/")):
            folder = folder+"/"

    file = ""
    sections = self.cap_file.split("%(")
    for sec in sections:
        file += StringHelper.parse_string("%("+sec, self.data_map)
        file = file.replace("%(","")

        self.cap_file_path = folder+file
        self.logger.debug("Initialize capture file (folder:%s, file:%s)." % (folder,file))
        if not os.path.exists(folder):
            self.logger.debug("Destination folder:'%s' not exists. Create." % folder)
            os.makedirs(folder)

    def sub_start_capture(self):
        # Start tracer thread, wait for console input to stop
        if self.login_required and not self.init_login():
            self.logger.debug("Could not login. Stop the capture thread.")
            self._stop.set()
            return

        self.set_data("tcaps",datetime.datetime.now())
        self.logger.debug("data_map:%s" % (self.data_map))
        self.init_capture_file()
        self.logger.info("Start capture (capture_file:'%s')." % (self.cap_file_path))
        url_start = self.base_url + '/cgi-bin/capture_notimeout' + self.start_str + "&ifaceorminor=" + self.cap_interface
        if self.SID != '':
            url = url_start + "&sid=%s" % self.SID
        else:
            url = url_start

        self.logger.debug("Send capture start request to the box          (url:'%s', capture_file:'%s')." % (url, self.cap_file_path))
        Tracer(url, self.cap_file_path).start()
        self.logger.debug("Send capture start request to the box finished (url:'%s', capture_file:'%s')." % (url, self.cap_file_path))

    def sub_stop_capture(self):
        # Clean stop
        if self.login_required and not self.init_login():
            self.logger.debug("Could not login. Stop the capture thread.")
            self._stop.set()
            return

        url_stop = self.base_url + '/cgi-bin/capture_notimeout' + self.stop_str + "&ifaceorminor=" + self.cap_interface
        if self.SID != '':
            url = url_stop + "&sid=%s" % self.SID
        else:
            url = url_stop
        self.logger.debug("Send capture stop request to the box           (url:'%s', capture_file:'%s')." % (url, self.cap_file_path))
        urllib.urlopen(url)
        self.logger.debug("Send capture stop request to the box finished  (url:'%s', capture_file:'%s')." % (url, self.cap_file_path))
        self.logger.info("Capture finished (capture_file:'%s')." % (self.cap_file_path))
        self.set_data("tcape",datetime.datetime.now())

        if (self.decode_work_queue is not None):
            self.logger.debug("Add captured file '%s' to the decoding work queue." % (self.cap_file_path))
            self.decode_work_queue.put(self.cap_file_path)

    def start_capture(self):
        self.wait_condition.acquire()
        self.logger.debug("start_capture called.")
        self.state_started = True
        self.wait_condition.notify_all()
        self.wait_condition.release()

    def stop_capture(self):
        self.wait_condition.acquire()
        self.logger.debug("stop_capture called.")
        self.state_started = False
        if self.after_capture_time > 0:
            self.next_stop_time = time.time() + self.after_capture_time
        self.wait_condition.notify_all()
        self.wait_condition.release()


    def stop (self):
        self.logger.debug("Received signal to stop the thread.")
        self._stop.set()
        self.wait_condition.acquire()
        if self.after_capture_time > 0:
            self.next_stop_time = time.time() + self.after_capture_time
        self.wait_condition.notify_all()
        self.wait_condition.release()

    def stopped (self):
        return self._stop.isSet()

    def set_callnumber(self, key, number):
        self.data_map[key+".number"] = number
        self.data_map[key+".name"] = ""
        self.data_map[key+".numbername"] = number
        if (self.data_map.has_key("pbook_number."+number)):
            self.data_map[key+".name"] = self.data_map.get("pbook_number."+number)
            self.data_map[key+".numbername"] = self.get_call_numbername(number)

    def get_call_numbername(self, number):
        if (not number):
            number = "Unknown"

        if (self.data_map.has_key("pbook_number."+number)):
            return number+"("+self.data_map.get("pbook_number."+number)+")"
        return number

    def set_data(self, key, value):
        self.data_map[key]=value

Ändere ich die Zeile:
Code:
url_stop = self.base_url + '/cgi-bin/capture_notimeout' + self.stop_str + "&ifaceorminor=" + self.cap_interface
in:
Code:
url_stop = self.base_url + '/cgi-bin/capture_notimeout' + self.stop_str + "&iface=lan" + "&minor=" + self.ifaceorminor[1] + "&type=" + self.ifaceorminor[0] + "&capture=Stop"

wird die .cap weiter geschrieben, es werden aber keine .waw erzeugt.
self.ifaceorminor = self.cap_interface.split("-") -> musst die Variable noch definieren in der Klasse mit z.B: ifaceorminor = ["0", "0"] oder den minor und iface von Hand reinschreiben.
Kann damit nix anfangen, was muss/ soll ich machen?
 
Kann damit nix anfangen, was muss/ soll ich machen?
Ich finde zwar irgendwo, daß Du es Dir mit dieser "Frage" etwas zu einfach machst, aber sei's drum ...

Bei einer 7490 sollte es ausreichen, wenn man auf dem lan-Interface mitschneidet und dazu müßte man als cap_interface den Wert 1-lan verwenden und - wenn man schon im Python-Code ändern will und nicht nur in der Konfigurationsdatei - die Zeile mit der URL zum Stoppen des Mitschnitts sollte dann so aussehen:
Code:
url_stop = self.base_url + '/cgi-bin/capture_notimeout' + self.stop_str + "&iface=lan&minor=-1&type=1&capture=Stop"
Will man am Python-Code nichts ändern, sollte stop_str in der Konfigurationsdatei dann so aussehen:
Code:
?iface=lan&minor=-1&type=1&capture=Stop
Die SID wird automatisch ergänzt und die zusätzlichen (ebenfalls automatisch ergänzten) Parameter sollten die Funktion nicht beeinträchtigen.

Wer anstelle von lan tatsächlich auf der "Schnittstelle 0 ('internet')" mitschneiden will, weil die Box selbst die Gegenstelle für das Telefonat ist (dann kommen die Daten nicht unbedingt auf dem lan-Interface vorbei), der kann auch als cap_interface den Wert 3-17 verwenden und für die Werte in der URL zum Stoppen dann iface=internet&minor=17&type=3.

Allerdings funktioniert auch das nur, wenn das Telefonat NICHT über ein zusätzliches (virtuelles) Interface geführt wird ... in einer solchen Konfiguration taucht dann i.d.R. noch eine weitere "Schnittstelle X ('voip')" auf, wobei das X nicht zwingend auch die 1 sein muß, falls z.B. auch noch für IPTV ein weiteres (ebenfalls virtuelles) Interface vorhanden sein sollte.

Welche Parameter für eine vorhandene zusätzliche voip-Schnittstelle verwendet werden müssen, kann man entweder selbst (ganz simpel mit einem aktuellen Browser) ermitteln oder man schneidet dann doch noch eine Ebene höher mit, wo die Daten der virtuellen Interfaces wieder gemeinsam sichtbar sind; das wäre dann die "Routingschnittstelle" mit dem Wert 3-0 für cap_interface und den Werten iface=all&minor=0&type=3 in der URL zum Stoppen der Aufzeichnung.

Allerdings muß man dabei auch wieder aufpassen, weil die Pakete hier ggf. bereits weitere Daten für die Kapselung auf dem Transportinterface (z.B. bei Verwendung von PPPoE) enthalten und dann nicht mehr korrekt dekodiert werden können, sofern man diese zusätzliche Kapselung nicht berücksichtigt. Daher sollte man im besten Falle immer soweit wie möglich "hinter" dem Router (von der WAN-Seite aus gesehen) mit dem eigenen Mitschnitt ansetzen, weil die Daten dort noch am ehesten nur den wirklich notwendigen Inhalt haben.

Alle Angaben für die Interfaces beziehen sich ausdrücklich auf das Modell 7490 - andere Modelle haben andere Interfaces und/oder Nummern.

Damit "verliert" man zwar die Flexibilität bei der Wahl des Interfaces für den Mitschnitt, aber wenn man dann erst einmal die korrekten Parameter für den Packet-Dump ermittelt und ausgetestet hat, kann man das nachträglich ja jederzeit wieder flexibler gestalten (falls das wirklich notwendig sein sollte).
 
Also was mir auffällt ist, dass du im Aufruf das Interface 3-17 aufzeichnen willst, aber in der fritzcap.conf mein "1-lan" eingetragen hast(meine Konfig). Ich weiß nicht was da priorität hat im Programm. Das Ganze doppelt anzugeben und an beiden Stellen etwas anderes zu übergeben ist schlecht.

Die Stopzeile würde ich dann hardkodieren, falls Du die Variable oben bei "class CaptureMonitor(ExceptionLoggingThread):"nicht anlegen kannst, ist natürlich eleganter mit ifaceorminor = ["0", "0"] diese vorbestzt anzulegen und dann beim stop dann auf die oben belegten configs zuzugreifen mit:
self.ifaceorminor = self.cap_interface.split("-")

url_stop = self.base_url + '/cgi-bin/capture_notimeout' + self.stop_str + "&iface=lan" + "&minor=" + self.ifaceorminor[1] + "&type=" + self.ifaceorminor[0] + "&capture=Stop"

oder so hardkodiert
url_stop = self.base_url + '/cgi-bin/capture_notimeout' + self.stop_str + "&iface=lan" + "&minor=17" + "&type=3" + "&capture=Stop"


Aber aufpassen, der Parameter iface verweisst laut PeterPawn auf den Namen des interfaces, soweit ich es verstanden habe und nicht auf das Interface. Bei mir heisst die Bezeichnung 1-lan "lan", deswegen habe ich es mal hardcodiert reingemacht, bei dir heisst sie wahrscheinlich "Schnittstelle 0 ('internet')" oder so, ich weiß nicht ob das der Fehler ist bei Dir?

Man müsste viielleicht eine neue Variable einbauen für das Stop das cap_interface_name oder so heisst und die dann mit dem Namen belegen.


EDIT: Oh das hat sich überschnitten mit Peters Beitrag, ich war zu langsam.
 
  • Like
Reaktionen: claudioso
Hallo ihr beiden, danke für eure ausführlichen Antworten.

Muss allerdings gestehen das ich nur die hälfte von dem was ihr versucht mir zu erklären verstehe.
Ich habe von Programierung nicht wirklich viel Ahnung.

Ich habe nun schon etliche Versuche hinter mir, leider Erfolglos.

Die Fritzcap.conf habe ich abgeändert:
Code:
[settings]
# capture_files        =
# decode_files         =
# monitor_calls        =
# password             = xxxxx

# logging_config       =
# box_name             = fritz.box
# call_service_port    = 1012
# login_not_required   =
# protocol             = http
# cap_folder             = captures/%(tcaps.Y-m-d/HMS)/
cap_folder             = usb/Fritzbox/%(tcaps.Y-m-d/HMS)/
# cap_file               = capture_%(callevent.name)_%(dialed.number)_%(caller.number)_%(tcaps.Y-m-d-H-M-S).cap
cap_file               = capture_%(callevent.name)_%(dialed.number)_%(caller.number)_%(tcaps.H-M-S).cap
# after_capture_time   = 10
# decode_workers_count = 2

default_login   = getpage=../html/de/menus/menu2.html&errorpage=../html/index.html&var:lang=de&var:pagename=home&var:menu=home&=&login:command/password=%s
# default_login   = getpage=../html/de/menus/menu2.html&errorpage=../html/index.html&var:lang=de&var:pagename=home&var:menu=home&=&login:command/password=xxxxx
sid_challenge   = getpage=../html/login_sid.xml
sid_login       = login:command/response=%s&getpage=../html/login_sid.xml
start_str       = ?start=1&start1=Start
stop_str        = ?iface=lan&minor=-1&type=1&capture=Stop

Wobei ich die:
stop_str = ?iface=lan&minor=-1&type=1&capture=Stop
erst nach einigen erfolglosen Versuchen auf die von Peter genannte geändert habe.


Die capture_monitor geändert auf:

Code:
url_stop = self.base_url + '/cgi-bin/capture_notimeout' + self.stop_str + "&iface=lan&minor=-1&type=1&capture=Stop"

ergibz mit dem Aufruf:
Code:
python /media/fritzcap.py --capture_files --decode_files --monitor_calls --cap_interface 1-lan --box_name 191.168.178.1 --username xxxxx --password xxxxx

eine gefüllte .cap Datei die auch nach beendetem Gespräch nicht weiter voll läuft, es werden allerdings leider etliche waw dateien mit 1-2 KB angelegt.

Der Aufruf:

Code:
python /media/fritzcap.py --capture_files --decode_files --monitor_calls --cap_interface 3-17 --box_name 191.168.178.1 --username xxxx--password xxxx

Ergibt eine voll laufende cap, es werden allerdings korrekte waw erzeugt.

capture_monitor geändert auf:
Code:
        url_stop = self.base_url + '/cgi-bin/capture_notimeout' + self.stop_str + "&iface=internet&minor=17&type=3&capture=Stop"

Aufruf :
Code:
python /media/fritzcap.py --capture_files --decode_files --monitor_calls --cap_interface 3-17 --box_name 191.168.178.1 --username xxx--password xxxx

Cap wird erzeugt und läuft voll, waw werden korrekt erstellt.

Mit aufruf
Code:
python /media/fritzcap.py --capture_files --decode_files --monitor_calls --cap_interface 1-lan --box_name 191.168.178.1 --username xxxx--password xxx

wird die cap nach gespräch beendet, waw 0 und 1 haben allerdings nur 1 bzw. 2 KB.


Mit:


Code:
url_stop = self.base_url + '/cgi-bin/capture_notimeout' + self.stop_str + "&iface=lan" + "&minor=" + self.ifaceorminor[1] + "&type=" + self.ifaceorminor[0] + "&capture=Stop"

Aufruf:
Code:
python /media/fritzcap.py --capture_files --decode_files --monitor_calls --cap_interface 1-lan --box_name 191.168.178.1 --username xxxx --password xxxx

Fehlermeldung in der Console:
Code:
AttributeError: 'CaptureMonitor' object has no attribute 'ifaceorminor'

cap läuft voll und es werden keine waw erstellt.

Fehlermeldung hat bestimmt etwas mit dem von Surfer
self.ifaceorminor = self.cap_interface.split("-")

zu tun, nur keine ahnung was ich wie/ wo dafür eintragen muss.

Ich hatte das ganze schon unter der FW. 7.29 am laufen, allerdings habe ich mir das ganze aus stückchen die ich hier und da gefunden habe zusammen gestückelt bis es endlich funktioniert hat.

Leider komme ich jetzt ohne eure Hilfe nicht weiter.
 
Was soll der Unsinn, sowohl im Python-Quelltext als auch in der Konfigurationsdatei IDENTISCHE Änderungen vorzunehmen? Ich verstehe nicht im Ansatz, wie man auf die Idee kommen kann, da sowohl als auch zu ändern ... kein Wunder, wenn das immer mehr durcheinander gerät.

url_stop = self.base_url + '/cgi-bin/capture_notimeout' + self.stop_str + "&iface=lan&minor=-1&type=1&capture=Stop"
ergibt eben i.V.m. einem stop_str-Parameter von ?iface=lan&minor=-1&type=1&capture=Stopam Ende eine URL:
Code:
https://192.168.178.1/cgi-bin/capture_notimeout?iface=lan&minor=-1&type=1&capture=Stop&iface=lan&minor=-1&type=1&capture=Stop&sid=...
- was könnte dabei wohl falsch gelaufen sein?

Kleiner Tipp: Irgendwo hier habe ich schon einmal erklärt, daß die MEHRFACHE Verwendung identisch benannter QueryString-Parameter so gar keine wirklich gute Idee ist, solange man nicht exakt weiß, wie der Parser auf der Server-Seite das am Ende zerlegt. Und außerdem gibt es gar keinen Grund für irgendein Echo ... der Server vergißt die Parameter auch dann nicht, wenn man sie ihm nur einmal vorsingt.

EDIT:
And by the way ... wie wäre es denn mal mit einem LOGFILE für die Aufrufe anstelle schwer verständlicher Beschreibungen in Prosa? Das dürfte für alle Seiten deutlich leichter und ergiebiger sein - just my 2 cents.

EDIT2:
PPS: Und auch die Angaben aus dem FRITZ!OS-GUI bei "Detailinformationen zu beendeten Anrufen" (unter Telefonie -> Eigene Rufnummern -> Sprachübertragung) wären sicherlich hilfreich ... sollten die noch nicht aufgezeichnet werden bei Deiner Box, dann wird es höchste Zeit, daß Du das an der beschriebenen Stelle aktivierst.
 
  • Like
Reaktionen: claudioso
Wenn du mit identische die :
stop_str = ?iface=lan&minor=-1&type=1&capture=Stop
in der fritzcap.conf meinst, diese habe ich erst eingefügt nachdem alle versuche gescheitert sind.

Habe es noch einma abgeändert die jetzige conf:

Code:
[settings]
# capture_files        =
# decode_files         =
# monitor_calls        =
# password             = xxxxx

# logging_config       =
# box_name             = fritz.box
# call_service_port    = 1012
# login_not_required   =
# protocol             = http
# cap_folder             = captures/%(tcaps.Y-m-d/HMS)/
cap_folder             = usb/Fritzbox/%(tcaps.Y-m-d/HMS)/
# cap_file               = capture_%(callevent.name)_%(dialed.number)_%(caller.number)_%(tcaps.Y-m-d-H-M-S).cap
cap_file               = capture_%(callevent.name)_%(dialed.number)_%(caller.number)_%(tcaps.H-M-S).cap
# after_capture_time   = 10
# decode_workers_count = 2

default_login   = getpage=../html/de/menus/menu2.html&errorpage=../html/index.html&var:lang=de&var:pagename=home&var:menu=home&=&login:command/password=%s
# default_login   = getpage=../html/de/menus/menu2.html&errorpage=../html/index.html&var:lang=de&var:pagename=home&var:menu=home&=&login:command/password=xxxxx
sid_challenge   = getpage=../html/login_sid.xml
sid_login       = login:command/response=%s&getpage=../html/login_sid.xml
start_str       = ?start=1&start1=Start
stop_str        = ?stop=1&stop1=Stop

Da der Aufruf mit cap_interface 3-17 funktionierende waw erzeugt die capture_monitor.py
den Eintrag:
Code:
url_stop = self.base_url + '/cgi-bin/capture_notimeout' + self.stop_str + "&iface=internet&minor=17&type=3&capture=Stop"

Aufruf mit:
Code:
python /media/fritzcap.py --capture_files --decode_files --monitor_calls --cap_interface 3-17 --box_name 191.168.178.1 --username xxxxxx --password xxxxx

Komplette capture_monitor.py:
Code:
#!/usr/bin/python
# -*- coding: iso-8859-1 -*-
#################################################################################
# Simple FritzCap python port
# Simplifies generation and examination of traces taken from AVM FritzBox and/or SpeedPort
# Traces can be examined using WireShark
# (c) tom2bor 2011 (tom2bor in http://www.ip-phone-forum.de/)
# based on the Windows GUI exe with same name
##################################################################################
# Copyright (c) 2011, tom2bor
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#    * Redistributions of source code must retain the above copyright
#      notice, this list of conditions and the following disclaimer.
#    * Redistributions in binary form must reproduce the above copyright
#      notice, this list of conditions and the following disclaimer in the
#      documentation and/or other materials provided with the distribution.
#    * Neither the name of the <organization> nor the
#      names of its contributors may be used to endorse or promote products
#      derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
# DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
# ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
##################################################################################

import datetime
import logging
import threading
import Queue
import time, datetime, random
import urllib
import os
import re
import hashlib

from log import Log
from string_helper import StringHelper
from tracer import Tracer
from exception_logging_thread import ExceptionLoggingThread

class CaptureMonitor(ExceptionLoggingThread):

    state_started = False
    next_stop_time = 0
    next_start_time = 0
    cap_file_path = ""
    def __init__(self, decode_work_queue, data_map, box_name, username, password, protocol, cap_folder, cap_file, cap_interface, login_required, default_login, sid_challenge, sid_login, start_str, stop_str, after_capture_time):
        ExceptionLoggingThread.__init__(self)
        self._stop = threading.Event()

        self.decode_work_queue = decode_work_queue
        self.data_map = data_map
        self.box_name = box_name
        self.username = username
        self.password = password
        self.protocol = protocol
        self.cap_folder = cap_folder
        self.cap_file = cap_file
        self.cap_interface = cap_interface
        self.login_required = login_required
        self.default_login = default_login
        self.sid_challenge = sid_challenge
        self.sid_login = sid_login
        self.start_str = start_str
        self.stop_str = stop_str
        self.after_capture_time = after_capture_time
        self.SID = ''

        self.base_url = self.protocol + '://' + self.box_name

        self.wait_condition = threading.Condition()

        self.logger = Log().getLogger()
        self.logger.debug("CaptureMonitor(decode_work_queue:'%s', data_map:'%s', box_name:'%s', username:'%s', password:'%s', protocol:'%s', cap_folder:'%s', cap_file:'%s', cap_interface:'%s', login_required:'%s', default_login:'%s', sid_challenge:'%s', sid_login:'%s', start_str:'%s', stop_str:'%s', after_capture_time:'%s')" % (decode_work_queue,data_map,box_name,username,password,protocol,cap_folder,cap_file,cap_interface,login_required,default_login,sid_challenge,sid_login,start_str,stop_str,after_capture_time))

    def run_logic(self):
        self.logger.debug("Thread started.")

        if self.login_required:
           if (not self.init_login()):
               self.logger.debug("Could not login. Stop the capture thread.")
               self._stop.set()

        while not self._stop.isSet():
            ###################
            ### pre_capture ###
            ###################
            # Wait until start_capture command was started...
            self.logger.debug("pre_capture acquire lock.")
            self.wait_condition.acquire()
            self.logger.debug("pre_capture acquire lock finished.")
            while not self._stop.isSet() and (self.state_started == False or self.next_start_time > time.time()):
                if self.next_start_time > time.time():
                    waittime = self.next_start_time - time.time()
                    if (self.logger.isEnabledFor(logging.DEBUG)):
                        self.logger.debug("pre_capture wait(%f)." % (waittime))
                    self.wait_condition.wait(waittime)
                    if (self.logger.isEnabledFor(logging.DEBUG)):
                        self.logger.debug("pre_capture wait(%f) finished." % (waittime))
                else:
                    if (self.logger.isEnabledFor(logging.DEBUG)):
                        self.logger.debug("pre_capture wait().")
                    self.wait_condition.wait()
                    if (self.logger.isEnabledFor(logging.DEBUG)):
                        self.logger.debug("pre_capture wait() finished.")

            self.logger.debug("pre_capture release lock.")
            self.wait_condition.release()
            self.logger.debug("pre_capture release lock finished.")

            if (self._stop.isSet()):
                logging.debug("The capture was not started. Not need to stop the capture. Can stop immediately.")
                break

            self.sub_start_capture()

            ####################
            ### post_capture ###
            ####################
            # Wait until stop_capture command was started...
            self.logger.debug("post_capture acquire lock.")
            self.wait_condition.acquire()
            self.logger.debug("post_capture acquire lock finished.")
            while not self._stop.isSet() and (self.state_started == True or self.next_stop_time > time.time()):
                if self.next_stop_time > time.time():
                    waittime = self.next_stop_time - time.time()
                    if (self.logger.isEnabledFor(logging.DEBUG)):
                        self.logger.debug("post_capture wait(%f)." % (waittime))
                    self.wait_condition.wait(waittime)
                    if (self.logger.isEnabledFor(logging.DEBUG)):
                        self.logger.debug("post_capture wait(%f) finished." % (waittime))
                else:
                    if (self.logger.isEnabledFor(logging.DEBUG)):
                        self.logger.debug("post_capture wait().")
                    self.wait_condition.wait()
                    if (self.logger.isEnabledFor(logging.DEBUG)):
                        self.logger.debug("post_capture wait() finished.")
            self.logger.debug("post_capture release lock.")
            self.wait_condition.release()
            self.logger.debug("post_capture release lock finished.")

            self.sub_stop_capture()

        if (self._stop.isSet()):
            if (self.decode_work_queue is not None):
                self.decode_work_queue.put(None)
        else:
            self._stop.set()
        self.logger.debug("Thread stopped.")



    def init_login(self):
        try:
            self.logger.debug("Login attempt to the the FritzBox (box_name:%s)" % (self.box_name))

            # Try to get a session id SID
            conn_url = self.base_url + '/login_sid.lua'
            self.logger.debug("Call the challange token url (url:'%s')" % conn_url)
            self.sid = urllib.urlopen(conn_url)
            sid_http_result = self.sid.getcode()
            self.logger.debug("SID HTTP result:%s" % sid_http_result)
            if sid_http_result == 200:
                # Read and parse the response in order to get the challenge (not a full blown xml parser)
                readed_chalange_str = self.sid.read()
                challenge = re.search('<Challenge>(.*?)</Challenge>', readed_chalange_str).group(1)

                # Create a UTF-16LE string from challenge + '-' + password, non ISO-8859-1 characters will except here (e.g. EUR)
                challenge_bf = (challenge + '-' + self.password).decode('iso-8859-1').encode('utf-16le')

                # Calculate the MD5 hash
                m = hashlib.md5()
                m.update(challenge_bf)

                # Make a byte response string from challenge + '-' + md5_hex_value
                response_bf = challenge + '-' + m.hexdigest().lower()

                # Answer the challenge
                conn_url = self.base_url + '/login_sid.lua?username=' + self.username + '&response=' + response_bf
                self.logger.debug("Call the read seed token url (url:'%s', data:'%s')." % (conn_url,self.sid_login % response_bf))
                login = urllib.urlopen(conn_url)
                login_http_result = login.getcode()
                self.logger.debug("Login HTTP result:%s" % login_http_result)
                if login_http_result == 200:
                    read_login_str = login.read()
                    self.SID = re.search('<SID>(.*?)</SID>', read_login_str).group(1)
                    if (self.SID == '0000000000000000'):
                        self.logger.error("Could not login to the FritzBox: Not authorized.  (SID: %s)" % self.SID)
                    else:
                        self.logger.debug("Login OK (SID: %s)" % self.SID)
                    return True

                else:
                    self.logger.error("Could not login to the FritzBox: Unknown error")
            else:
                self.logger.error("Could not login to the FritzBox: Error 404.")
        except Exception as e:
            self.logger.debug("Exception during SID logon: %s" % e )
            # Legacy login
            command = urllib.urlopen(self.base_url + '/cgi-bin/webcm', self.default_login % self.password)
            response = command.read()
            # Right now I don't know how to check the result of a login operation. So I just search for the errorMessage
            if command.getcode() == 200:
                try:
                    result = urllib.unquote(re.search('<p class="errorMessage">(.*?)</p>', response).group(1).decode('iso-8859-1')).replace("&nbsp;"," ")
                except:
                    result = ''
                self.logger.error('Login attempt was made, but something was wrong: %s' % result)
        return False

    def init_capture_file(self):
        # Create capfile folder
        folder = StringHelper.parse_string(self.cap_folder, self.data_map)
        folder = folder.replace("\\","/")
        if (not folder.endswith("/")):
            folder = folder+"/"

        file = StringHelper.parse_string(self.cap_file, self.data_map)

        self.cap_file_path = folder+file
        self.logger.debug("Initialize capture file (folder:%s, file:%s)." % (folder,file))
        if not os.path.exists(folder):
            self.logger.debug("Destination folder:'%s' not exists. Create." % folder)
            os.makedirs(folder)

    def sub_start_capture(self):
        # Start tracer thread, wait for console input to stop
        if self.login_required and not self.init_login():
            self.logger.debug("Could not login. Stop the capture thread.")
            self._stop.set()
            return

        self.set_data("tcaps",datetime.datetime.now())
        self.logger.debug("data_map:%s" % (self.data_map))
        self.init_capture_file()
        self.logger.info("Start capture (capture_file:'%s')." % (self.cap_file_path))
        url_start = self.base_url + '/cgi-bin/capture_notimeout' + self.start_str + '&snaplen=294' + "&filter=" + "&ifaceorminor=" + self.cap_interface + "&capture=Start"
        if self.SID != '':
            url = url_start + "&sid=%s" % self.SID
        else:
            url = url_start

        self.logger.debug("Send capture start request to the box          (url:'%s', capture_file:'%s')." % (url, self.cap_file_path))
        Tracer(url, self.cap_file_path).start()
        self.logger.debug("Send capture start request to the box finished (url:'%s', capture_file:'%s')." % (url, self.cap_file_path))

    def sub_stop_capture(self):
        # Clean stop
        if self.login_required and not self.init_login():
            self.logger.debug("Could not login. Stop the capture thread.")
            self._stop.set()
            return

        url_stop = self.base_url + '/cgi-bin/capture_notimeout' + self.stop_str + "&iface=internet&minor=17&type=3&capture=Stop"
        if self.SID != '':
            url = url_stop + "&sid=%s" % self.SID
        else:
            url = url_stop
        self.logger.debug("Send capture stop request to the box           (url:'%s', capture_file:'%s')." % (url, self.cap_file_path))
        urllib.urlopen(url)
        self.logger.debug("Send capture stop request to the box finished  (url:'%s', capture_file:'%s')." % (url, self.cap_file_path))
        self.logger.info("Capture finished (capture_file:'%s')." % (self.cap_file_path))
        self.set_data("tcape",datetime.datetime.now())

        if (self.decode_work_queue is not None):
            self.logger.debug("Add captured file '%s' to the decoding work queue." % (self.cap_file_path))
            self.decode_work_queue.put(self.cap_file_path)

    def start_capture(self):
        self.wait_condition.acquire()
        self.logger.debug("start_capture called.")
        self.state_started = True
        self.wait_condition.notify_all()
        self.wait_condition.release()

    def stop_capture(self):
        self.wait_condition.acquire()
        self.logger.debug("stop_capture called.")
        self.state_started = False
        if self.after_capture_time > 0:
            self.next_stop_time = time.time() + self.after_capture_time
        self.wait_condition.notify_all()
        self.wait_condition.release()


    def stop (self):
        self.logger.debug("Received signal to stop the thread.")
        self._stop.set()
        self.wait_condition.acquire()
        if self.after_capture_time > 0:
            self.next_stop_time = time.time() + self.after_capture_time
        self.wait_condition.notify_all()
        self.wait_condition.release()

    def stopped (self):
        return self._stop.isSet()

    def set_callnumber(self, key, number):
        self.data_map[key+".number"] = number
        self.data_map[key+".name"] = ""
        self.data_map[key+".numbername"] = number
        if (self.data_map.has_key("pbook_number."+number)):
            self.data_map[key+".name"] = self.data_map.get("pbook_number."+number)
            self.data_map[key+".numbername"] = self.get_call_numbername(number)

    def get_call_numbername(self, number):
        if (not number):
            number = "Unknown"

        if (self.data_map.has_key("pbook_number."+number)):
            return number+"("+self.data_map.get("pbook_number."+number)+")"
        return number

    def set_data(self, key, value):
        self.data_map[key]=value



Jetzt wollte ich gerade die von dir geforderten Logs hier mit einfügen und habe alles noch einmal durch gespielt, und nun funktioniert es scheinbar.

Die oben genannten Einstellungen passen für die 7490 mit FW 7.57

Das Problem welches ich hatte/ wie ich meine:
nach änderungen müssen die neuen Einstellungen neu eingelesen werden, das habe ich wohl nicht gemacht, in der Konsole STRG+Z bendet zwar Fritzcap, die gemachten Einstellungen werden aber wohl nicht neu eingelesen.
Den Befehl hierfür kenne ich nicht, habe mich nun mit einem Neustart vom Raspberry beholfen.

Danke euch beiden, hoffe das ich euch nicht komplett in den Wahnsinn getrieben habe, wie schon geschrieben habe kenne ich mich nicht wirklich gut aus.


Noch eins da ihr euch scheinbar super auskennt: ab und an (eine gute Woche läuft es) scheint Fritzcap ab zu stürzen, es werden keine Aufnahmen mehr erzeugt.

Lässt sich der Prozess irgendwie überwachen? Bzw. ein Cronjob mit dem ich 1 mal die Woche Fritzcap neu starte, dafür müsste ich aber den neustart befehl unter Debian Buster kennen um Fritzcap neu zu starten.
Bisher habe ich den kompletten Raspberry neu gestartet, funktioniert, ist aber nicht umbedingt das wahre.


Gibt es da schon etwas?
 
in der Konsole STRG+Z bendet zwar Fritzcap
Auch das ist (vermutlich) Unsinn - wenn wir hier über das CTRL-Z der Jobsteuerung in einer (üblichen) Shell-Session reden, dann suspendiert diese Tastenkombination den aktuellen Job (bzw. die darin laufende Prozessgruppe), während alle zugeordneten Ressourcen - mit Ausnahme der Timeslices bei der CPU-Nutzung - weiterhin zugeordnet bleiben und damit für andere Prozesse nicht verfügbar sind.

Du solltest Dich noch etwas mit den Shell-Grundlagen befassen, u.a. auch mit der Frage, welche Tastenkombinationen in einer (interaktiven) Shell-Session welche Signale auslösen.

Solange SIGINT in fritzcap nicht speziell behandelt wird, dürfte am ehesten die Tastenkombination CTRL-C zum Beenden des Programms führen.
 
  • Like
Reaktionen: claudioso
bezüglich crontab wäre evtl. so etwas möglich, ist nicht elegant, sollte aber um 3 Uhr nachts das erledigen.. natülich musst Du den aufruf entsprechend anpassen, wo dein script abgelegt ist und die Zeilen entsprechend in die crontab einfügen

0 3 * * * killall -9 fritzcap.py>/dev/null
1 3 * * * /media/fritzcap.py --capture_files --decode_files --monitor_calls --cap_interface 3-17 --box_name 191.168.178.1 --username xxxxxx --password xxxxx &

ich würde die ganzen parameter aber eher aus der *.conf holen und nicht alles beim Aufruf übergeben, die hast Du da doch eh drin und den Aufruf eher so:
1 3 * * * /media/fritzcap.py -c -d -m &

Kannst machen wie Du willst
 
Hallo,
was bei der 7390 läuft, geht bei der 7590 nicht.
Jede Box mit der aktuellsten FW ausgestattet.
Hat da jemand eine Idee ?

@ PeterPawn
welche Settings wären deiner Meinung nach eine saubere Lösung ?

MfG
 
Bei der 7390 ist die v6.88 die neuste, bei der 7590 die 7.57, das ist eine viel neuere Firmware, Du musst für die 7590 die Strings anpassen, wie in den Beiträgen geschrieben.
Was geht denn genau nicht, welche Settings hast Du denn?
 
Die korrekten Angaben für die passenden Interfaces kann/muß man sich dann halt mit einem Browser (bzw. mit dessen Entwicklerfunktionen, die eigentlich jeder moderne (Desktop-)Browser hat) ermitteln oder man versucht es mit der "eingebauten" Interface-Erkennung von fritzcap (einfach mal die Anleitung im GitHub-Repo lesen), wobei ich nicht weiß, wie weit die bei neueren (FRITZ!OS-)Versionen korrekt arbeitet.
 
Hallo,
die cap Datei wird erzeugt. Leider kommt keine wav dabei raus.

Habe alles eingestellt wie im Post 532 bei dem vermerkt
Ergibt eine voll laufende cap, es werden allerdings korrekte waw erzeugt.
Mit der 7390 läuft es auch, nur eben mit der 7590 nicht.

Ich hoffe das schaffe ich mit den Entwicklerfunktionen .....

Ich habe jetzt schon ein paar mal gelesen, wenn eine cap Datei erzeugt wird aber keine wav Dateien das es an der g711_decoder.py liegt.
Oder bin ich hier auf dem Holzweg ?

MfG
 
Zuletzt bearbeitet:
Holen Sie sich 3CX - völlig kostenlos!
Verbinden Sie Ihr Team und Ihre Kunden Telefonie Livechat Videokonferenzen

Gehostet oder selbst-verwaltet. Für bis zu 10 Nutzer dauerhaft kostenlos. Keine Kreditkartendetails erforderlich. Ohne Risiko testen.

3CX
Für diese E-Mail-Adresse besteht bereits ein 3CX-Konto. Sie werden zum Kundenportal weitergeleitet, wo Sie sich anmelden oder Ihr Passwort zurücksetzen können, falls Sie dieses vergessen haben.