0tis

Neuer User
Mitglied seit
8 Feb 2022
Beiträge
11
Punkte für Reaktionen
0
Punkte
1
Moin Moin,

meine Anfrage stammt von einem sehr alten Thread daher eröffne ich einen frischen, neuen um die Wahrscheinlichkeit auf Erfolg und Unterstützung zu erhöhen.
Ursprünglicher Thread -> Sprachkanäle beschränken

Folgendes Problem:

Wird eine Rufnummer X angerufen so sollen 3 Telefone gleichzeitig klingeln. Nun ist eins der Telefone im Gespräch und ein weiterer Anruf geht ein sodass nun zwei von drei Telefone klingelt. Nun ist auch das zweite von drei Telefone besetzt und wenn ein dritte Anruf rein kommt klingelt natürlich das dritte Telefon.

Nun würde ich es gerne so einrichten, dass wenn zwei Telefone (egal welche) mit einem Anruf belegt sind, ein dritter Anruf abgewiesen werden soll bzw. ein Besetztton hört. Das dritte Telefon soll erst gar nicht klingeln wenn beide Telefone mit einem Anruf belegt sind.




Nun bin ich auf diesen wunderbaren Thread gestoßen und habe versucht dies in meiner Anlage umzusetzen wobei das Limit bei max. zwei "Kanälen" liegt. Natürlich weicht meine Asterisk und Debian Version mit der obigen extrem ab, nichts desto trotz sollte das Ergebnis mit kleinen Anpassungen umsetzbar sein.

Ich nutze Asterisk 16.3.0 (und höher)
Auf: Debian 9.12 (Stretch) (und höher)

Hier die Quellen die mir etwas geholfen haben zu verstehen: AsteriskDocs, Voip-Info, Voip-Info/functions


Nun zur Praxis:

Ich habe die Datenbank in der CLI angelegt -> debian*CLI>: database put ContextX Value 2

So sieht nun mein Context in der extensions.conf aus:

Code:
[eingehend]

exten => _X.,1,NoOp(Anruf fuer Gruppe Zentrale)
same => n,Set(ANZAHL=${DB(ContextX/Value)})
same => n,GotoIf($[${ANZAHL} > 0]?5:9)
same => n,Set(SCHALTER=1)
same => n,Set(ANZAHLNEU=$[${ANZAHL} - 1])
same => n,Set(DB(ContextX/Value)=${ANZAHLNEU})
same => n,Set(CALLERID(num)=0${CALLERID(num)})  
same => n,Verbose(Eingehender Anruf von Rufnummer ${CALLERID(num)}.)
same => n,Dial(SIP/50&SIP/60&SIP/70,20)
same => n,Set(SCHALTER=0)
same => n,Playback(busy-signal)
same => n,Congestion
same => 102,Busy

exten => h,1,GotoIf($[${SCHALTER} = 1]?4:8)
exten => h,2,Set(ANZAHL=${DB(ContextX/Value)})
exten => h,3,Set(ANZAHLNEU=$[${ANZAHL} + 1])
exten => h,4,Set(DB(ContextX/Value)=${ANZAHLNEU})
exten => h,5,Set(SCHALTER=0)
exten => h,6,Hangup

Nun gibt die CLI foglendes aus:
Asterisk_CLI.jpg

Bei jedem laufenden Anruf wird die Value um 1 reduziert aber nach dem Hangup nicht wieder eins hochgezählt.
Außerdem wirft Asterisk einen Syntax-Error wegen dem '=' zeichen.
Ich hoffe genügend Infos mitgeteilt zu haben und bin über jeglichen Lösungsvorschlag sehr dankbar!
 

koyaanisqatsi

IPPF-Urgestein
Mitglied seit
24 Jan 2013
Beiträge
14,106
Punkte für Reaktionen
572
Punkte
113
Moinsen


Hab mal versucht das nachzustellen und bin momentan soweit, nach Korrekturen...
Rich (BBCode):
[eingehend]                                                                      
exten => _X.,1,NoOp(Anruf fuer Gruppe Zentrale)                                  
same => n,Set(ANZAHL=${DB(ContextX/Value)})                                      
same => n,GotoIf($[${ANZAHL}<0]?5:9)                                            
same => n,Set(SCHALTER=1)                                                        
same => n,Set(ANZAHLNEU=$[${ANZAHL}-1])                                          
same => n,Set(DB(ContextX/Value)=${ANZAHLNEU})                                   
same => n,Set(CALLERID(num)=0${CALLERID(num)})                                   
same => n,Verbose(Eingehender Anruf von Rufnummer ${CALLERID(num)}.)             
same => n,Verbose(1,SIP/50&SIP/60&SIP/70,20) ; Nur zum Testen, Verbose() statt Dial()
same => n,Set(SCHALTER=0)                                                        
same => n,Busy(10) ; Reicht für eine Busy Signalisierung
;same => n,Congestion ; Warum?
;same => 102,Busy ; Warum?

exten => h,1,GotoIf($[${SCHALTER}=1]?4:8)                                        
exten => h,2,Set(ANZAHL=${DB(ContextX/Value)})                                   
exten => h,3,Set(ANZAHLNEU=$[${ANZAHL} + 1])                                     
exten => h,4,Set(DB(ContextX/Value)=${ANZAHLNEU})                                
exten => h,5,Set(SCHALTER=0)                                                     
; exten => h,6,Hangup() ; Braucht es nicht, da h triggert wenn schon aufgelegt wurde
Die Syntaxfehler waren weg, nachdem ich den Datenbankeintrag in der Konsole erzeugt habe mit: database put ContextX Value 2
Prüfe also das was du in die Datenbank via Wahlplan geschrieben hast in der Konsole mit: database show

Beachte bitte, dass Channelvariablen, sofern sie nicht in [globals] in der extensions.conf definiert wurden, für jeden Channel lokal (definiert) sind.

Ich persönlich nutze als Ersatz für lokale/globale Variablen auch die AstDB, also schreibe, lese oder prüfe die direkt ohne den Umweg über lokale/globale Variablen.
Beispiel, wie ich das meine...
Rich (BBCode):
[eingehend]                                                                    
include => demo
                                                                            
exten => _X.,1,NoOp(Anruf fuer Gruppe Zentrale)                
same => n,GotoIf($[${DB(ContextX/Value)}=0]?7:3)
same => n,Set(DB(ContextX/Value)=$[${DB(ContextX/Value)}-1])
same => n,Verbose(1,Value = ${DB(ContextX/Value)})                     
same => n,Verbose(Eingehender Anruf von Rufnummer ${CALLERID(num)}.)
same => n,Goto(s,1)                                            
same => n,Set(DB(ContextX/Value)=$[${DB(ContextX/Value)}-1]) -- geht auf -1 und h zählt hoch auf 0
same => n,Busy(10)                                          
                                                                               
;exten => h,1,GotoIf($[${DB(ContextX/Value)}<2]?2:3)
exten => h,1,Set(DB(ContextX/Value)=$[${DB(ContextX/Value)} + 1])
;exten => h,3,Verbose(1,Value = ${DB(ContextX/Value)})
Der Abgewiesene (bei Value = 0) wird in Priorität 7 same => n,Set(DB(ContextX/Value)=$[${DB(ContextX/Value)}-1]) Value um 1 verringern, so muss an der Logik in h (Der wird ja auch aufgelegt) diesbezüglich (Limit von 2) nichts geändert werden.
Wenn ich mir das dann so angucke, kann dann auch die Prüfung in h Priorität 1 entfallen, nur die Erhöhung braucht es da.
Das Limit wird mit Value festgelegt, wenn gerade Ruhe ist.
Zum Beispiel, wenn jeder Anruf ein Busy bekommen soll, weil gerade Meeting ist: database put ContextX Value 0

Und hier die Ausgabe im Asterisk CLI für einen eingehenden Anruf, der dann beim Auflegen den Datenbankeintrag Value wieder um 1 erhöht.
Rich (BBCode):
  == Using SIP RTP CoS mark 5
    -- Executing [[email protected]:1] Goto("SIP/fritz.box-0000001d", "eingehend,08154711,1") in new stack
    -- Goto (eingehend,08154711,1)
    -- Executing [[email protected]:1] NoOp("SIP/fritz.box-0000001d", "Anruf fuer Gruppe Zentrale") in new stack
    -- Executing [[email protected]:2] GotoIf("SIP/fritz.box-0000001d", "0?7:3") in new stack
    -- Goto (eingehend,08154711,3)
    -- Executing [[email protected]:3] Set("SIP/fritz.box-0000001d", "DB(ContextX/Value)=1") in new stack
    -- Executing [[email protected]:4] Verbose("SIP/fritz.box-0000001d", "1,Value = 1") in new stack
 Value = 1
    -- Executing [[email protected]:5] Verbose("SIP/fritz.box-0000001d", "Eingehender Anruf von Rufnummer torwache.") in new stack
Eingehender Anruf von Rufnummer torwache.
    -- Executing [[email protected]:6] Goto("SIP/fritz.box-0000001d", "s,1") in new stack
    -- Goto (eingehend,s,1)
    -- Executing [[email protected]:1] Answer("SIP/fritz.box-0000001d", "250") in new stack
    -- Executing [[email protected]:2] Set("SIP/fritz.box-0000001d", "TIMEOUT(digit)=5") in new stack
    -- Digit timeout set to 5.000
    -- Executing [[email protected]:3] Set("SIP/fritz.box-0000001d", "TIMEOUT(response)=10") in new stack
    -- Response timeout set to 10.000
    -- Executing [[email protected]:4] Set("SIP/fritz.box-0000001d", "CHANNEL(language)=de") in new stack
    -- Executing [[email protected]:5] BackGround("SIP/fritz.box-0000001d", "demo-congrats") in new stack
    -- <SIP/fritz.box-0000001d> Playing 'demo-congrats.gsm' (language 'de')
    -- Executing [[email protected]:6] BackGround("SIP/fritz.box-0000001d", "demo-instruct") in new stack
    -- <SIP/fritz.box-0000001d> Playing 'demo-instruct.gsm' (language 'de')
    -- Executing [#@eingehend:1] Playback("SIP/fritz.box-0000001d", "demo-thanks") in new stack
    -- <SIP/fritz.box-0000001d> Playing 'demo-thanks.gsm' (language 'de')
    -- Executing [#@eingehend:2] Hangup("SIP/fritz.box-0000001d", "27") in new stack
  == Spawn extension (eingehend, #, 2) exited non-zero on 'SIP/fritz.box-0000001d'
    -- Executing [[email protected]:1] GotoIf("SIP/fritz.box-0000001d", "1?2:3") in new stack
    -- Goto (eingehend,h,2)
    -- Executing [[email protected]:2] Set("SIP/fritz.box-0000001d", "DB(ContextX/Value)=2") in new stack
    -- Executing [[email protected]:3] Verbose("SIP/fritz.box-0000001d", "1,Value = 2") in new stack
 Value = 2
Microknoppix*CLI>
 
Zuletzt bearbeitet:

0tis

Neuer User
Mitglied seit
8 Feb 2022
Beiträge
11
Punkte für Reaktionen
0
Punkte
1
Moin koyaanisqatsi

zunächst einmal vielen Dank für deine Hilfestellung! Das hat mir sehr geholfen und führte auch zu einer Lösung meines Problems.

Also, ich habe meine Dialplan - wie du empfohlen hast - abgeändert jedoch erhielt ich weiterhin die Syntaxfehler.

Natürlich habe ich auch den Datenbankeintrag mit: database put ContextX Value 2 stätig geprüft.
Danach habe ich die Variante direkt ohne den Umweg über lokale/globale Variablen getestet - wie du beschrieben hast - und tadaaa!!! Das hat nach ein paar kleinen Anpassungen dann auch wunderbar funktioniert!
Mit Anpassungen meine ich, dass ich in diesen Context wo die AstDB eingebaut ist, mehrere Wahlpläne für andere Telefone genutzt habe, dem entsprechend hat die AstDB auch für andere eingehende Anrufe gegriffen. Habe dann einfach die AstrDB in einen extra Context mit den betroffenen Teilnehmern gesetzt und dann lief das ganze auch.

Hier nun meine Lösung:

Code:
; Vorerst mit "database put ContextX Value 2"
; Value auf zwei gesetzte.
; Dann wurde bei jedem Anruf runtergezählt.
; Bei Value <0 war dann ein Besetztton zu hören.

[eingehend_zentrale]     ; einen extra Context nur für Teilnehmer SIP/49&SIP/92&SIP/91 angelegt
exten => _X.,1,NoOp(Anruf fuer Gruppe Zentrale)
same => n,GotoIf($[${DB(ContextX/Value)}=0]?7:3)
same => n,Set(DB(ContextX/Value)=$[${DB(ContextX/Value)}-1])
same => n,Verbose(1,Value = ${DB(ContextX/Value)})
same => n,Verbose(Anruf von Rufnummer ${CALLERID(num)}.)
same => n,GotoIfTime(8:00-16:30,mon-fri,*,*?8)
same => n,VoiceMail([email protected],su)
same => n,Dial(SIP/49&SIP/92&SIP/91)
same => n,Set(DB(ContextX/Value)=$[${DB(ContextX/Value)}-1])
same => n,Busy(10)

exten => h,1,Set(DB(ContextX/Value)=$[${DB(ContextX/Value)} + 1])
;-----------------------------------------------------------------------------

- Vielen Dank nochmal dafür!
 

0tis

Neuer User
Mitglied seit
8 Feb 2022
Beiträge
11
Punkte für Reaktionen
0
Punkte
1
Moin Moin,

kann man die Zeile
Code:
exten => h,1,Set(DB(ContextX/Value)=$[${DB(ContextX/Value)} + 1])
so umbauen, dass diese nur für diesen einen Block, also für exten => _X.,1,NoOp(Anruf fuer Gruppe Zentrale)
greift ?

Ich habe ja einen weiteren Context -> [eingehend_zentrale] zwar erstellt und diesen als include => eingehend_zentrale in den anderen Context (wo alle anderen Wahlpläne sich befinden) eingebaut aber nun greift das exten => h,1,Set ..., auch für diese Wahlpläne.

Also in etwa so (natürlich nicht funktioniert kann):

Code:
..
..
same => n,Dial(SIP/49&SIP/92&SIP/91)
same => n,Set(DB(ContextX/Value)=$[${DB(ContextX/Value)}-1])
same => n,Busy(10)

same => n,Set(DB(ContextX/Value)=$[${DB(ContextX/Value)} + 1])
;-----------------------------------------------------------------------------
 

koyaanisqatsi

IPPF-Urgestein
Mitglied seit
24 Jan 2013
Beiträge
14,106
Punkte für Reaktionen
572
Punkte
113
Das könnte klappen, könnte, weil noch nicht getestet, mit den Dial() Flags F(), g oder G().
Dann braucht es keine h-Extension mehr.
Siehe dafür...

Aber mit Goto() kannst du natürlich auch in eine extra Extension hüpfen, wo keine andere Extension stört.
Denn Goto() kehrt nicht in den aufrufenden Kontext zurück.
GoSub() macht das zum Beispiel (Return in den aufrufenden Kontext).
...und jeder Kontext darf auch eigene spezial Extensions haben.
Wie die h-Extension.

Dann wird es nicht so kompliziert (Keine zusätzlichen GotoIf() oder ExecIf()).
 
Zuletzt bearbeitet:

0tis

Neuer User
Mitglied seit
8 Feb 2022
Beiträge
11
Punkte für Reaktionen
0
Punkte
1
Klasse, ließ sich mit Goto() wunderbar umsetzten. Vielen Dank nochmal!
 

Mrs. Moose

Neuer User
Mitglied seit
24 Mrz 2021
Beiträge
22
Punkte für Reaktionen
0
Punkte
1
Genau für solche Zwecke gibt es Groups. Lassen sich einfach setzen und abfragen, und man muss nichts verbiegen um irgendwelche Datenbankeinträge wieder gelöscht zu kriegen.

Code:
[sip-in]
exten => _X.,1,ExecIf(${GROUP_COUNT(gruppe1)} > 1]?HangUp(17))
same => n,Set(GROUP(ankommend)=gruppe1)
...

[sip-out]
exten => _XXX.,1,Set(GROUP(abgehend)=gruppe1)
...
 

0tis

Neuer User
Mitglied seit
8 Feb 2022
Beiträge
11
Punkte für Reaktionen
0
Punkte
1

@Mrs. Moose

Vielen Dank für deinen tollen Lösungsansatz. Ich habe es zwar noch nicht getestet aber es ist wohl dann ein wesentlicher einfacher und schlankerer Weg.

Vielen Dank nochmal dafür!
 
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.