web-dev-qa-db-ja.com

アスタリスク:ピアに到達できない場合は転送

特定のピアが到達可能かどうかを確認して着信に応答し、それに応じて適切な番号をダイヤルしたいと思います。

現在、私はこれを行いました:

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()

これが許容できるかどうか、およびベストプラクティスを使用して改善できるかどうかを教えてください。

1
Cedric H.

着信コールでアスタリスクのシェルを実行することは、私には正しく感じられません。おそらく問題なく動作しますが、ピアのステータスがすでにアスタリスクで認識されているべきではありませんか?

ピアのステータスをリクエストできる関数 SIPPEER() を使用しています。 (OK (44 ms)の)最初の3文字がOKの場合、ピアを呼び出すことができます。別のピアに転送できる他のすべての状況。

私はこのようなことをします:

_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()
_

これにより、Dial()に進む前にステータスがチェックされ、ピアが使用できない、ビジーである、またはその他の点でOKでない場合は、n(forward)に進みます。

ただし、これには小さな問題があります。ピアが通話を拒否した場合(または別の理由で利用できない場合、たとえば、次のオンラインチェックの前にオンラインになった場合)、通話は通過しません。

関数があります DIALSTATUSDial()の後に使用して、呼び出しが正常に応答されたかどうかを確認できます。したがって、これはDial()の後に使用し、応答がない場合は転送も実行します。 (私が行ったテストでは機能しました。呼び出しを拒否すると、ログにBUSYが記録され、次のピアに移動しました)

あなたはこのようなものを手に入れます:

_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()
_

私はこの最後のビット(DIALSTATUSを使用)を広範囲にテストしなかったので、いくつかのテストを行う必要がありますが、ここでは機能しているようです。

5
Rik

@arheopsが述べたように、1:1マッピング(1つのデバイスに1つのアカウント)の場合、DEVICE_STATE()を使用して特定のデバイスのステータスを取得できます。以下を使用できます。

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

もう1つの可能性は、1:manyマッピング(複数のデバイスを持つ1つの拡張)がある場合のEXTENSION_STATE()関数です。

複数のデバイスを使用するために1人のユーザーが必要な場合は、両方に説明されているヒントを含めることができます ここここ 動的ヒントの作成方法を確認できます

1
Stoinov