Handhabung des UI-Moduls voipstat [veraltet]/ von foncalls.lua

CaptainMorgan

Neuer User
Mitglied seit
28 Nov 2015
Beiträge
172
Punkte für Reaktionen
4
Punkte
18
Hallo liebe Experten,
ich versuche gerade ein lang nicht mehr gewartetes Skript zu reparieren (reconnect.sh aus Fritzload).
Ein gewisser Part davon scheint nicht mehr zu funktionieren, etwas scheint sich geändert zu haben.
Code:
voipcheck() {
   local voipstat
   voipcheck="$(sed -n 's/^voipcheck="\([^"]*\).*/\1/p' $pdir/config/fritzload.ini)"
   [ "$voipcheck" != 1 ] && return 1
   if [ "$voipCheckMsg" = 1 ]; then
       print "VoIP-Prüfung"
   fi
   login
   if [ "$boxextern" != 1 ]; then
       #voipstat="$(/usr/www/cgi-bin/webcm getpage=$pdir/html/voip.html | grep '^VOIP:\ ')"
       ctlmgr_ctl r voipstat status/load
       local voipcount=$(ctlmgr_ctl r voipstat status/localnames/count)
       local voipname=$(ctlmgr_ctl r voipstat status/localnames0/localname)
       ctlmgr_ctl r voipstat status/unload
       if [ "${voipcount:-0}" -gt 0 ]; then
           voipstat="VOIP: $voipname"
       else
           return 1
       fi
   else
       voipstat="$($CURL -s http://$box/cgi-bin/webcm \
       -d "getpage=../html/de/fon/qualitytable.html" \
       -d "var:lang=de" \
       -d "sid=$cgisid" \
       -d "login:command/password=$passvoip" \
       2>/dev/null \
       | sed -n '/<table id="tQoS2">/,/<\/table>/ s/.*TrRufnr("\([^"]*\).*/\1, /p' | tr -d '\n')"
       [ -n "$voipstat" ] && voipstat="VOIP: $voipstat"
   fi
   if [ -n "$voipstat" ]; then
       if [ "$voipCheckMsg" = 1 ]; then
           print "VoIP-Telefonat ($voipstat), warte..."
           voipCheckMsg=0
       fi
       [ ${showMsg:-0} -eq 1 ] && curl_msg_wait 20 "VoIP-Telefonat ($voipstat), warte 20 Sekunden..."
       sleep 20
       return 0
   fi
   return 1
Das ist der Code um den es geht. Es soll abgefragt werden ob zur Zeit eine VoIP-Telefonie stattfindet.
Boxextern ist immer Null, daher kann der große "else" Abschnitt erstmal ignoriert werden.
Obwohl dies der Fall ist gibt mir meine 7362SL mit OS 6.83 und Freetz 14560 folgendes aus:
Code:
root@fritz:/var/mod/root# ctlmgr_ctl u
super_ultra_mega_module_which_does_not_exist_yet - is no known module
All known UI modules:
boxusers
apps
country
time
interfaces
ddns
tr069
tr064
wlan
jasonii
myfritzdevice
fritzappurls
landevice
internet_ruleset
filter_profile
user
userglobal
userticket
autouser
parental_control
blocked_ip
igdforwardrules
inetstat
language
route
ipv6route
forwardrules
emailnotify
wakeup
dslmail
updatecheck
remoteman
openports
sip
sipextra
ontel
telcfg
connection_voip
dect
tam
capiotcp
voipjournal
voipstat
voipextension
netapp
trafficprio
nqos
ipv6
ipv6firewall
lisp
storagedirectories
ctlusb
usbdevices
filelinks
aura
mediasrv
t_media
gpmsrv
umts
umts_provider
webdavclient
vpn
power
dslstatglobal
dslstatistic
gsm
configd
timer
providerlist
capture
dns_excepted_domains
cfgtakeover
speedtest
dnsserver
dnscfg
plc
avm_pa
fritzinfo
hotspotgre
oncal
root@fritz:/var/mod/root# ctlmgr_ctl r voipstat status/load

root@fritz:/var/mod/root# ctlmgr_ctl r voipstat status/localnames/count
0
root@fritz:/var/mod/root# ctlmgr_ctl r voipstat status/localnames0/localname
root@fritz:/var/mod/root# ctlmgr_ctl r voipstat status/unload

root@fritz:/var/mod/root# ctlmgr_ctl u voipstat
voipstat:status/
 load=
 unload=

Zu den Modulen voipjournal und voipextension gibt es mehr Dokumentation, zumindest auf den gängigen Seiten, mir bekannten Anlaufstellen inklusive diesem Forum nichts.

Korrigiert werden muss nur der erste Teil, boxextern ist in jedem Fall 0, daher kann alles in grün denke ich ignoriert werden.
Dankbar bin ich für jeden Hinweis, auch simple Hinweise auf weitere Dokumentation oder ähnliches sind sehr Willkomen, wer natürlich einen Fehler im Code findet oder gar korrigieren kann der wird mein persönlicher Held der Woche.
Für autretende Unzulänglichkeiten bitte ich um Nachsicht, meine Programmierkenntnisse beschränken sich auf ein "Bestanden" in einem Java Grundkurs, aber ich denke sofern diese Möglichkeiten nicht irgendwann komplett aus der UI entfernt wurden sollte es möglich sein hier ein Troubleshooting vorzunehmen.
 
Zuletzt bearbeitet:
Wenn man schon auf der Box ist, kann man das "foncalls.lua"-Module von AVM verwenden, dort gibt es eine Funktion "get_activecalls". Wie man die AVM-Lua-Bibliotheken auch von der Shell aus benutzen kann, findet sich in ein paar Beispielen im YourFritz-Repo: https://github.com/PeterPawn/YourFritz/tree/master/luavar - einfach die passende Datei mit "require" einbinden und die Funktionen aufrufen. Notfalls kann man auch zu Fuß direkt auf die "libluacalllog.so" von AVM zugreifen, die ist der Motor hinter der "foncalls.lua" - ich würde aber mit der "foncalls.lua" arbeiten.
 
die webcm - Schnittstelle ist doch seit 6.5x oder so schon tot;
hier ist Migration nach LUA o.a. erforderlich
Das ist gut möglich. Wie gesagt ist die ganze else-Klammer ja aber tot, von daher....
Oder bezieht sich dass auf alles was mit den UI Modulen zusammenhängt?


@PeterPawn: Ich werde mir das mal anschauen, auch wenn ich Lua noch nie gesehen habe, und auch gar nicht wusste das die Box damit arbeitet.. Das ganze zu überprüfen ist aber natürlich kein Selbstzweck, es müssen ja die Variablen voipcount und voipname richtig belegt werden, damit falls telefoniert wird ein Reconnect der Box verhindert wird.
Wie gesagt ich werde versuchen dahinterzusteigen, aber kennst du vielleicht eine Möglichkeit die Module dazu zu bringen auszuspucken was sie können? --manual, --help und --? sind alle nutzlos geblieben.
 
aber kennst du vielleicht eine Möglichkeit die Module dazu zu bringen auszuspucken was sie können?
Ich verstehe die Frage gar nicht ... welche "Module" sind denn hier gemeint?

Wenn es um die vom "ctlmgr_ctl" geht ... da gibt es eben in aktueller Firmware keine weiteren Daten, die sich aus dieser "extension" mit dem Namen "voipstat" für den "ctlmgr" auslesen ließen ... auch AVM setzt bei der Anzeige im GUI auf das von mir erwähnte Lua-Modul (es gibt ja zwei Stellen, wo man aktive Anrufe sehen kann - 1x in der "home.lua" bei den Telefonaten und 1x in der Update-Seite).

Und die von AVM erstellten "Lua-Module" (in "/usr/lua") haben keine irgendwie geartete Dokumentation ... wenn man Glück hat, steht da irgendwo mal eine Kommentarzeile zwischen den Lua-Statements. Aber das ist ja alles "lesbar" (mit Ausnahme einiger Module bei der LTE-Unterstützung in der neuesten Labor-Version) und so kann man da leicht selbst einen Blick hineinwerfen.

Ansonsten ist Lua als Sprache genauso simpel aufgebaut, wie es Java ist ... wenn man das Konzept von "tables" und "objects" erst einmal verstanden hat, kommt man auch mit der AVM-Methode des Handlings von Variablen und Funktionen problemlos klar (ist eher der objektorientierte Ansatz von Lua, der von AVM verfolgt wird). Das einzige wirklich Nervige ist der Verzicht auf jedwede Strukturierung in den Lua-Quellen ... hier hilft ein passender Editor oder auch ein externer "beautifier" - so eine Schachtelung von "if"-Statements liest sich gleich ganz anders, wenn sie entsprechend eingerückt ist.
 
...
Wenn es um die vom "ctlmgr_ctl" geht ... da gibt es eben in aktueller Firmware keine weiteren Daten, die sich aus dieser "extension" mit dem Namen "voipstat" für den "ctlmgr" auslesen ließen ... auch AVM setzt bei der Anzeige im GUI auf das von mir erwähnte Lua-Modul (es gibt ja zwei Stellen, wo man aktive Anrufe sehen kann - 1x in der "home.lua" bei den Telefonaten und 1x in der Update-Seite).
...
Genau das habe ich gemeint, also kann folglicherweise die voipstat-extension gar nicht mehr funktioneren.
Ich habe die aktiven Anrufe bis jetzt immer nur auf der Home-Seite gesehen. Im Telefonie Untermenü werden aktive Anrufe nicht aufgeführt. Meinst du mit der Update Seite die System/Update/Fritz!OS-Version - Seite?
Ist mir noch nie aufgefallen....
Ich habe mir die foncalls.lua mal im Notepad++ angeschaut, und denke der relevante Part ist dieser (Zeile 295):
Code:
function foncalls.get_activecalls()
return calllog.GetAll(typemask('active','all'))
end

Ich bekomme also eine Tabelle zurück. Um Ehrlich zu sein bin da mit meinem derzeitigen Kenntnisstand schon überfordert. Auch möchte ich den bestehenden Code nicht unbedingt zu stark verändern.
Ich müsste die also zwischenspeichern und dann im Falle eines aktiven Anrufs
Code:
$(ctlmgr_ctl r voipstat status/localnames/count)
durch eine Eins ersetzen und
Code:
$(ctlmgr_ctl r voipstat status/localnames0/localname)
durch die aktive Telefonnummer, auch wenn das optional ist.
Das Ganze ohne das bestehende Skript irgendwie aus dem Konzept zu bringen.
Für jemanden der bis jetzt nur mit LegoMindStorm bunte Bälle sortiert hat durchaus ein mehrwöchiges Anliegen, für jemanden der es kann vermutlich auch als Dreizeiler zu lösen.

Auch "require" ist mir noch unklar, es ist auf jedenfall mal kein Befehl den die Telnet Konsole annimmt.
libluacalllog.so habe ich gesucht aber nicht gefunden, zumindest in /usr/bin und /usr/lua.

Mit deinem /luavar/ Verzeichnis komme ich leider nicht weiter. Ich glaube zwar Teile der Logik zu verstehen, aber da dies ja selbst *.lua's sind fällt es mir schwer daran zu erkennen wie ich eine ausführe, geschweige denn eine einzelne Zeile daraus.
 
Der Lua-Code in meinen Beispielen wird deshalb ausgeführt, weil dort als "SheBang" die Datei "/bin/luavar" angegeben ist und diese ist eine Art "Host" für die Ausführung von solchen Anweisungen. Ruft man so ein Lua-Skript also als ausführbare Datei auf (dazu muß die das "x"-Flag in den Berechtigungen gesetzt haben), startet das System automatisch "/bin/luavar" und übergibt dem auf STDIN dieses Skript, was dann von "luavar" abgearbeitet wird.

Man muß also nur in so einer eigenen Datei die notwendigen anderen Dateien einbinden (genau dafür dient das "require"), das erzeugt dann schon eine globale Variable, die man einfach für den Aufruf der Funktion benutzen kann.

Wenn Du mal einen Blick in die "update.lua" wirfst (es gibt m.W. nur eine, wenn man mal unterschiedliche Brandings außer acht läßt), dann findest Du dort in der Funktion "show_act_calls" einen solchen Aufruf, aus dessen Rückgabewert dann sowohl die bisherige Dauer als auch die Rufnummer und das lokale Telefoniegerät für jeden aktiven Anruf ausgelesen und in der HTML-Seite ausgegeben werden.

Das kann man auch einfach auf "STDOUT" schreiben lassen (wie das geht, steht wieder in meinen Beispielen, sowohl in "queries.lua" als auch in der Datei zum Auslesen der VPN-Verbindungen) und in Shell-Code über einen Aufruf (als Beispiel, nicht zu wörtlich nehmen):
Code:
my_own_lua_script_to_get_active_calls | \
while read line; do
    echo $line
done
Zeile für Zeile auslesen ... oder man bereitet es gleich in Lua so auf, daß man nur die tatsächlich benötigten Daten ausgibt (wobei ja durchaus auch mal zwei Anrufe aktiv sein könnten, da ist die Abfrage nur einer Nummer schon etwas zu kurz gedacht in meinen Augen) und das gleich mit "eval" o.ä. weiterverarbeiten kann (so gibt "queries.lua" seine Daten ja auch aus ... ggf. findest Du auch noch den IPPF-Thread zu diesem Skript - steht m.E. in der README.md in dem Verzeichnis).
 
Die Nummer ist optional, man könnte einfach die erste nehmen, oder in Reconnect.sh "voipname" einfach fixieren. Es ist ja egal ob eine Nummer oder zwei Telefonieren, unterbrochen werden darf die Verbindung ja dann schon nicht mehr.
Auf der ganzen Box, von der Root bis zum USB-Stick findet die Konsole außerdem weder update.lua noch libluacalllog.so.
Als kompletter Anfänger ist mir auch noch nicht ganz klar wie mein Endprodukt ausehen soll.
reconnect.sh hat ja bereits seine eigene "Laufzeitumgebung", #!/bin/ash.

In einem ersten Schritt würde ich also den ganzen luavar Ordner in den internen Speicher ( /bin/) kopieren.
Dann würde ich mir eine queries.lua nach diesem Vorbild
erstellen
Code:
#! /bin/luavar

lineno = 0;
rc = 0;

while true do
   local line = io.read("*line");
   if (line == nil) then
       if (lineno == 0) then
           io.stderr:write("Missing requests\n");
           os.exit(2);
       end
       break;
   end
   lineno = lineno + 1;
   local varname, query = string.match(line, "(.*)=(.*)");
   if (varname ~= nil and query ~= nil) then
       if (string.find(query, "%(.*%)") == nil) then
           local single_res = box.query(query);
           if (single_res == nil) then
               print(varname.."=\"***no result***\"");
           else
               print(varname.."=\""..single_res.."\"");
           end
       else   
           local columns = {};
           local first, last = string.find(query, "%(.*%)");
           local list = string.sub(query, first + 1, last - 1);
           for col in string.gmatch(list, "[^,]+") do
               table.insert(columns, col);
           end
           if (string.find(query, "listwindow%(.*%)") ~= nil) then
               table.remove(columns, 1);
               table.remove(columns, 1);
           end
           local result = box.multiquery(query);
           local index = 0;
           for i, entry in ipairs(result) do
               for j, value in ipairs(entry) do
                   j = j - 1;
                   if (j > 0) then
                       colname = columns[j];
                   else
                       colname = "index";
                   end
                   print(varname.."_"..i.."_"..colname.."=\""..value.."\"");
               end
               index = i;
           end
           print(varname.."_count="..index);
       end
   else
       io.stderr:write("Malformed request at line ",lineno,"\n");
       rc = 1;
-- die folgende Zeile aktivieren (-- am Beginn entfernen), um bei falscher Eingabe die Verarbeitung abzubrechen
--        break;
   end
end

os.exit(rc);
und setze cmod z.B. auf 777.
Dann ist die "Tabelle/Wert" in der gewünschten Variable im Speicher und kann auch von einem Shell-Skript abgerufen werden?
 
Ist schon spät und ich verstehe hier wohl auch nicht mehr alles ... fast bin ich versucht, das schnell selbst herunterzutippen, aber das kann ja auch nicht der Sinn der Sache sein.

Du willst doch ansonsten in dem Shell-Skript ganz am Anfang des Threads auch schon ein anderes Kommando aufrufen ... nämlich "ctlmgr_ctl" und das soll Dir doch auch nur auf STDOUT irgendwelche Zeichenketten liefern.

Du brauchst also nur eine eigene Datei, die als "SheBang" eben "/bin/luavar" verwendet und aus den Daten, die von "foncalls.get_activecalls()" zurückgegeben werden, die richtige Ausgabe auf STDOUT erzeugt - meinetwegen auch nur die Anzahl der aktiven Calls, die genau gleich der Anzahl der Einträge in der zurückgegebenen Tabelle sein dürfte - genau das wird aber in der "update.lua" direkt nach der Abfrage als Schleifenzähler verwendet. Man muß also nur diesen Wert "ausgeben" und schon hat man das Äquivalent zum früheren "count"-Aufruf über "ctlmgr_ctl".

Warum Du bei Dir die Datei "/usr/www/avm/system/update.lua" nicht finden kannst, steht auf einem ganz anderen Blatt ... existieren sollte sie schon; auch in einer 7362SL mit Firmware 06.83. Wenn ich jetzt (mehr im Scherz) frage, ob Du auch die Expertenansicht aktiviert hattest bei der Suche, irritiert Dich das aber vermutlich noch mehr. Vielleicht suchst Du ja einfach noch einmal nach der Datei - wenn sie tatsächlich fehlen sollte, ist Deine Firmware einfach nicht vollständig und wer weiß, was dann noch alles fehlt.

EDIT: Die angesprochene ELF-Datei für das Anrufprotokoll heißt dann eben nicht "libluacalllog.so", sondern "libcallloglua.so" ... aber nach der solltest Du eigentlich auch nicht selbst suchen. Die wird nämlich als allererstes in der Datei "foncalls.lua" eingebunden:
Code:
local calllog=require("libcallloglua")
 
Zuletzt bearbeitet:
Die Expertenansicht war aktiviert.

Ich werde mich heute Abend wieder ausführlich melden, aber eine Sache lies mir keine Ruhe, die fehlende update.lua, daher habe ich es eben in der Mittagspause per VPN schnell überprüft:

Ergebnis: Der Ordner /usr/www/avm/ ist bei mir nur eine Verknüpfung zu /usr/www/all.

Code:
root@fritz:/var/mod/root# cd /usr/
root@fritz:/usr# cd www
root@fritz:/usr/www# ls
1und1    all      avm      cgi-bin  css      html     js       kids
root@fritz:/usr/www# cd avm
root@fritz:/usr/www/all# ls
apple-touch-icon.png        net
assis                       networkchange.lua
capture.lua                 no_password.lua
cgi-bin                     post.lua
content.lua                 query.lua
crossdomain.xml             reboot.lua
css                         resetauth.lua
data.lua                    restore.lua
dect                        robots.txt
dsldiagstop.lua             secure_link.lua
errors                      services.lua
favicon.ico                 software
firmware_update_notify.lua  sorry.lua
flash.html                  sso_email.js
fon_devices                 sso_email.lua
fon_num                     sso_password.js
fritzinfo                   sso_password.lua
guest                       sta_reboot.lua
help                        storage
home                        support.lua
html                        surf.lua
index.lua                   system
internet                    templates
jason_boxinfo.xml           tools
js                          tr69_autoconfig
juis_boxinfo.xml            twofactor.lua
login.lua                   usb
login_sid.lua               vergessen.lua
lua                         wds2_final.lua
menus                       webservices
meter                       wlan
myfritz_email_verified.lua
root@fritz:/usr/www/all# cd /usr/www
root@fritz:/usr/www# ls
1und1    all      avm      cgi-bin  css      html     js       kids
root@fritz:/usr/www# cp -R avm/ /var/media/ftp/USB/
root@fritz:/usr/www#
Auch Filezilla zegit "avm", sobald es als Kopie im Ordner USB sichtbar ist, dann als Verknüpfung an.
Auch "find / update.lua" findet nichts, auf zwei Boxen, also eher kein "Bithüpfer". Beide sind "gefreetzt", Trunk 14560, aber dass sollte ja theoretisch keinen Unterschied machen.
Beide wurden auch schon einmal recovert, deshalb denke ich nicht dass zwei Boxen fehlerhaft ausgeliefert wurden, sondern das tatsächlich keine update.lua da ist.
Wie gesagt, ich werde heute Abend und übers Wochenende weiter an der Implementierung werkeln, aber vielleicht kann sich ja jemand einen Reim darauf machen und mir vielleicht sogar mit einer update.lua als Lernmaterial weiterhelfen.
 
Davon, daß auf der Box ein Freetz-Image installiert ist (da werden die Brandings zu "all" zusammengefaßt und nur per Symlink an die OEM-Variable gekoppelt), stand bisher nirgendwo etwas (und wir sind auch nicht im Freetz-Unterforum).

Aber dann findet sich die "update.lua" eben unterhalb von "/usr/www/all" ... so etwas sucht man normalerweise auch mittels "find":
Code:
root@FB7490:~ $ find / -xdev -name update.lua
/usr/www/1und1/system/update.lua
/usr/www/avm/system/update.lua
(das ist KEIN Freetz-Image bei mir).
 
Das mit Freetz stand im ersten Beitrag im zweiten Absatz, werde mir aber demnächst vielleicht mal eine Signatur anlegen.
Nichtsdestotrotz danke, anscheined habe ich find auch vorher falsch benutzt, sonst hätte ich update.lua ja gefunden. ("find / update.lua" ist falsch , "-name" hat gefehlt).

Würde soetwas funktionieren ( bitte Nachsicht, ich habe noch nie in Linux programmiert):
Code:
#! /usr/lua

while true do
   local count,
   require "foncalls"
   local calls = foncalls.get_activecalls()
   if #calls > 0 then
   count = #calls
   io.stdout:write(count);
   end
   else
   end
 
   --voipcheck.lua

Ich habe aber immer noch keinen Schimmer wie ich das Script ausführen kann.
chmod ist 777 aber es kommt immer "-sh: voipcheck.lua: not found".
Ich würde auch die Nummer noch mit einarbeiten, aber da ich den Output von .get_activecalls() noch nie gesehenn habe, mangels Kenntnis sie auszuführen, steht das logischerweise erstmals hinten an.
 
Zuletzt bearbeitet:
...Ausführen geht mit ./voipcheck.lua wenn du dich im selben Verzeichnis wie diese Datei befindest...
 
Das habe ich auch vermutet und mehrmals probiert,
Leider:
Code:
root@fritz:/var/media/ftp/USB/TEST# ./voipcheck.lua
-sh: ./voipcheck.lua: not found
 
Das kann auf dem USB-Stick nur funktionieren, wenn der ohne "noexec"-Option gemountet wird ... keine Ahnung, was FREETZMOUNT da zur Zeit veranstaltet, aber ein "mount" sollte die verwendeten Optionen ja anzeigen.

Aber man muß ja auch nicht unbedingt auf den USB-Stick gehen, im NAND-Flash sollten mehr als 10 MB frei sein.
 
Moins

Ists nicht das SHEBANG ?
...denn /usr/lua als Interpreter scheint mir nicht korrekt zu sein.
 
  • Like
Reaktionen: stoney
Welches Verzeichnis bietet sich da an?
/var/media/ftp, auch bekannt als InternerSpeicher liefert das selbe Ergebnis, in /usr/lua kopieren geht nicht, da "READ Only Filesystem"
 
Was ist jetzt mit "shebang" aka erste Zeile Deines Codes? (#16)
 
Kann ich dir noch nicht sagen, ich habe es noch nicht geschaft eine *.lua auszuführen.
Weißt du denn dass es falsch ist oder ist das nicht die richtige Umgebung für *.lua?
 
Wie sieht denn dein Script jetzt aus?
Code:
#! /bin/dash
while true do
   local count,
   require "foncalls"
   local calls = foncalls.get_activecalls()
   if #calls > 0 then
   count = #calls
   io.stdout:write(count);
   end
   else
   end

   --voipcheck.lua

so ? (siehe erste Zeile, über den Rest kann ich nichts sagen)
 
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.