Asterisk: Weiterleiten, wenn Peer nicht erreichbar ist

1

Ich möchte auf eingehende Anrufe reagieren, indem ich überprüfe, ob ein bestimmter Peer erreichbar ist, und die entsprechende Nummer wähle.

Zur Zeit habe ich folgendes gemacht:

exten => 1200,1,Answer()
same => n,Set(reachable=${SHELL(asterisk -rx "sip show peers" | grep ^cedrich-phone.*OK)})
same => n,GotoIf($["${LEN(${reachable})}" = "0"]?extoffline)
same => n,Dial(SIP/cedrich-phone,20)
same => n(extoffline),Dial(SIP/another-phone,20,tr)
same => n,Hangup()

Können Sie mir mitteilen, ob dies akzeptabel ist und ob es durch die Verwendung der Best Practices verbessert werden kann?

Cedric H.
quelle

Antworten:

5

Das Ausführen einer Sternchen-Shell bei einem eingehenden Anruf fühlt sich für mich einfach nicht richtig an. Es funktioniert wahrscheinlich in Ordnung, aber sollte der Status eines Peers Asterisk nicht bereits bekannt sein?

Ich benutze die Funktion, SIPPEER()mit der Sie den Status eines Peers abfragen können. Wenn die ersten 3 Zeichen (von OK (44 ms)) sind OK, können Sie den Peer anrufen. Alle anderen Situationen können Sie an einen anderen Peer weiterleiten.

Ich mache so etwas:

exten => _202,1,Log(NOTICE,Dial Status of ${EXTEN}: ${SIPPEER(${EXTEN},status)})
exten => _202,n,GotoIf($["${SIPPEER(${EXTEN},status):0:3}"="OK "]?ok1:forward)
exten => _202,n(ok1),Log(NOTICE,Calling number is available)
exten => _202,n,Dial(SIP/${EXTEN},50,wW)
exten => _202,n,Hangup()
exten => _202,n(forward),Log(NOTICE,Calling forward number)
exten => _202,n,Dial(SIP/201,50,wW)
exten => _202,n,Hangup()

Dies überprüft den Status, bevor wir zu gehen Dial()und geht zu, n(forward)wenn der Peer nicht verfügbar, beschäftigt oder anderweitig nicht OK ist.

Es gibt jedoch ein kleines Problem damit. Wenn der Peer den Anruf ablehnt (oder aus einem anderen Grund nicht erreichbar ist, z. B. er vor unserem nächsten Online-Check online gegangen ist), kommt der Anruf nicht durch.

Es gibt eine Funktion, mit der DIALSTATUSwir nach dem Dial()überprüfen können, ob der Anruf erfolgreich beantwortet wurde. Verwenden Sie dies also nach dem Dial()und wenn es nicht beantwortet wird, führen Sie auch die Weiterleitung durch. (Es hat in einem von mir durchgeführten Test funktioniert. Das Ablehnen des Anrufs wurde BUSYim Protokoll vermerkt und ging zum nächsten Peer.)

Sie erhalten so etwas:

exten => _202,1,Log(NOTICE,Dial Status of ${EXTEN}: ${SIPPEER(${EXTEN},status)})
exten => _202,n,GotoIf($["${SIPPEER(${EXTEN},status):0:3}"="OK "]?ok1:forward)
exten => _202,n(ok1),Log(NOTICE,Calling number is available)
exten => _202,n,Dial(SIP/${EXTEN},50,wW)
exten => _202,n,Log(NOTICE,Dial status: ${DIALSTATUS})
exten => _202,n,GotoIf($["${DIALSTATUS)}"="ANSWER"]?ok2:forward)
exten => _202,n(ok2),Log(NOTICE,Successfull call)
exten => _202,n,Hangup()
exten => _202,n(forward),Log(NOTICE,Calling forward number)
exten => _202,n,Dial(SIP/201,50,wW)
exten => _202,n,Hangup()

Ich habe dieses letzte Bit (mit DIALSTATUS) nicht ausgiebig getestet, deshalb solltest du einen Test machen, aber hier scheint es zu funktionieren.

Rik
quelle
1

Wie bei @arheops bereits erwähnt, können Sie mit DEVICE_STATE () den Status eines bestimmten Geräts abrufen, wenn es sich um eine 1: 1-Zuordnung handelt (1 Konto auf 1 Gerät). Sie können Folgendes verwenden:

${DEVICE_STATE(${CHANNEL(channeltype)}/${CHANNEL(peername)})}

Eine andere Möglichkeit ist die EXTENSION_STATE () - Funktion für den Fall, dass Sie 1: viele Zuordnungen haben (eine Erweiterung mit mehr als einem Gerät).

Beide können die hier beschriebenen Hinweise enthalten , wenn Sie einen Benutzer benötigen, um mehrere Geräte zu verwenden. Hier können Sie sehen, wie Sie dynamische Hinweise machen

Stoinov
quelle
-1

Wenn Sie das System in dialplan verwenden, wird die Shell geöffnet und 2 Prozesse für jeden Anruf gestartet.

Klar hat asterisk funktion für deine aufgabe. Es ist in allen Büchern beschrieben.

-= Info about function 'DEVICE_STATE' =- 

[Synopsis]
Get or Set a device state. 

[Description]
The DEVICE_STATE function can be used to retrieve the device state from any
device state provider. For example:
NoOp(SIP/mypeer has state ${DEVICE_STATE(SIP/mypeer)})
NoOp(Conference number 1234 has state ${DEVICE_STATE(MeetMe:1234)})
The DEVICE_STATE function can also be used to set custom device state from
the dialplan.  The 'Custom:' prefix must be used. For example:
Set(DEVICE_STATE(Custom:lamp1)=BUSY)
Set(DEVICE_STATE(Custom:lamp2)=NOT_INUSE)
You can subscribe to the status of a custom device state using a hint in
the dialplan:
exten => 1234,hint,Custom:lamp1
The possible values for both uses of this function are:
UNKNOWN | NOT_INUSE | INUSE | BUSY | INVALID | UNAVAILABLE | RINGING |
RINGINUSE | ONHOLD
arheops
quelle
Gerne stimme ich Ihrer Antwort zu oder nehme sie sogar an, wenn Sie Ihren nutzlosen ersten Satz streichen und Ihre Antwort aufwenden könnten, statt nur zu kopieren ...
Cedric H.,
Ich bin in Ordnung, wenn Sie es nicht befürworten. Es tut mir leid, es ist nicht klar, was genau ich erweitert habe. WENN Sie weitere Informationen benötigen, können Sie immer nach den bereitgestellten Informationen suchen . Lesen Sie beispielsweise diese Seite voip-info.org/wiki/view/Asterisk+func+device_State . Oder installiere freepbx und überprüfe den Wählplan.
Arheops