ダイアログアスタリスクマネージャーインターフェイス

すべてのアスタリスクと同様に、発信通信に使用される複数のトランクがPBX上にあるという問題に繰り返し遭遇しました。 多くのお客様と同様に、私のお客様にとっても、これらのトランクのいくつかはメインのトランクであり、残りの部分は転倒/雇用/他の何かが最初に発生した場合のバックアップトランクの役割を果たします。







次の例は、このような問題を解決するための標準的なメカニズムと見なされます。



exten => _ <Che there>、1、Dial(SIP / trunk / <Che there>)

exten => _ <Che there>、n、GotoIf($ ["$ {DIALSTATUS}"!= "ANSWER"]?Dial_Another_Prov:Hangup)

exten => _ <Che there>、n(Dial_Another_Prov)、Dial(SIP / trunk2 / <Che there>)

exten => _ <Che there>、n(ハングアップ)、ハングアップ()



さて、またはここは、偶然、ネットワークの広大さにある例です



[マクロセーフダイヤル]

exten => s、1、Set(DIALSTART = $ {EPOCH})

exten => s、n、Dial($ {ARG1}、$ {ARG2}、$ {ARG3}、$ {ARG4})

exten => s、n、Goto(s-$ {DIALSTATUS}、1)



exten => s-NOANSWER、1、GotoIf($ ["$ {DTIME}" = "0"]?ここ)

exten => s-NOANSWER、n、ハングアップ

exten => s-NOANSWER、n(ここ)、Verbose(1、「$ {ARG1}」のフェイルオーバーが必要)

exten => s-BUSY、1、ビジー

exten => s-CHANUNAVAIL、1、詳細(1、「$ {ARG1}」のフェイルオーバーが必要)

exten => s-CONGESTION、1、輻輳

exten => _s-。、1、輻輳

exten => s-、1、輻輳



しばらくして、そのような決定は、そのボリュームの考慮と、クライアントに到達するためにすべての費用で質問があった顧客の1人のバックアップチャネルの数の増加に基づいて、私を嫌い始めました。 それは一般的に理解可能である:電話は常に電話のままで動作しなければならない。 だからこそ、それとPBX-作業を自動化し、頭痛を取り除くために。



その間に、すべての病棟を通常のダイヤルプランからルアに移し、戦うことにしました。



じゃあ 素晴らしい作業ツールが手元にあります-プログラミング言語全体。 彼の多くの兄弟と同様に、ネットワークインターフェースの操作方法を知っています。 これは、このプロパティを自分の利益のために使用できることを意味します。 トランクの状態を見てから、利用可能なトランクを呼び出してみませんか? 必要なのは:



1. AMIに接続します

2.トランク名を取得する

3.ステータスを取得する



など。 まず、ソケットライブラリをフックします。



local socket = require("socket")
      
      







トランクの分析には、AMIを使用します(おそらくすべての人が名前で推測したとおりです)。 AMIはtcpスタックで動作するため、説明します。



 tcp = socket.tcp() tcp:settimeout(100)
      
      







次に、トランクが呼び出されるコンテキストを説明し、必要な機能をアタッチします。 Say ... outgoing_calls_external_dst本質的に、この関数はコンテキストの本質です。 つまり、extensions.confのコンテキストに類似しています(これをコードでペイントしません。すべてがwiki.asterisk.orgにあります)



ここで、電話を受けると、アスタリスクのAMIインターフェイスに接続します。



 tcp:connect("127.0.0.1", 5038) result = tcp:receive() tcp:send("Action: Login\r\n") tcp:send("Username: pr\r\n") tcp:send("Secret: 1\r\n\r\n") LoginIsOk = 0 while LoginIsOk == 0 do result=tcp:receive() --          . if string.find(result,"Authentication accepted")~=nil then LoginIsOk = 1 end if string.find(result,"Response: Error")~=nil then LoginIsOk = 2 end end
      
      







さらに、一般に、楽しみが始まります。 すべてのごちそうをアスタリスクにお願いします。 「なぜですか?」読者は尋ねます。 「結局のところ、 SIPshowregistryがあります !」 はい あります。 しかし、最初に、彼は登録されたトランクのみを表示し、次にプロバイダーが利用できなくなって、登録時間がまだ切れていない場合、トランクの状態に関する情報はまだ無効になります。 「しかし、SIPpeersは顧客も表示します!」-これは正しい発言です。 そのため、トランクを準備する必要があります。

sip / users / <トランクをどこに置いているのか>各トランクI:



1.資格を有効にする

2.規定のパラメーターの説明=行



つまり、言い換えると、回線として記述されるものはすべてトランクです。 なぜこれが重要なのですか? SIPpeersは各宴会についてそのような説明を返すためです。 さらに-彼はあなたのmysqlファイル/テーブルに書かれている順番であなたにそれを返します



チャネルタイプ:SIP

ObjectName:mysupertrunk

ChanObjectType:ピア

IPアドレス:-なし-

IPport:0

動的:はい

AutoForcerport:いいえ

Forcerport:はい

AutoComedia:いいえ

コメディア:はい

VideoSupport:いいえ

TextSupport:いいえ

ACL:いいえ

ステータス:不明

RealtimeDevice:いいえ

説明:行



一般的に、サーバー上のピアからのものをすべて解析したので、穀物をもみ殻から完全に分離し、トランクと呼ばれる1つのバスケットに穀物を入れます。



 tcp:send("Action: SIPpeers\r\n\r\n") while result ~= "EventList: start" do result = tcp:receive() end trunks = {} i = 1 while result ~= "Event: PeerlistComplete" do result = tcp:receive() if string.find(result,"ObjectName")~=nil then ObjectName = splitted_value(result,": ") --splitted_value -   ,         end if string.find(result,"Description")~=nil then Description = splitted_value(result,": ") end if Description == "line" then trunks[i] = ObjectName i = i + 1 Description=nil --   .     . end end
      
      







一般に、アスタリスクにすべてのトランクのアレイ/プレートがあります。

どれが利用可能かを見つけ、それを通して呼び出すだけです。 これは、SIPpeerstatusを介して実行できます。



 for key,val in pairs(trunks) do tcp:send("Action: SIPpeerstatus\r\n") tcp:send("Peer: "..val.."\r\n\r\n") while result~="Event: SIPpeerstatusComplete" do result=tcp:receive() if string.find(result,"PeerStatus:")~=nil then status=split(result,": ") --split    ,      .       if status[2]=="Reachable" then app.Dial("SIP/"..val.."/"..extension) end end end end
      
      







まあ、あなたの後ろのドアを閉めることを忘れないでください))



 tcp:send("Action: Logoff\r\n\r\n") while result~="Response: Goodbye" do result=tcp:receive() end tcp:close()
      
      







これは通常、ダイヤルプラン自体でAMIを直接使用できる最も簡単な例です。 また、使用中のチャネルは何も認識しません。 sip show inuseコマンドの出力のみを解析する必要があります。 mysqlコネクタとredisの両方がここにねじ込まれ、必要に応じて他のものがねじ込まれます。 松葉杖なし。



PS怠け者には、ami-luaライブラリ全体があります。 ここにドキュメントがあるだけです...方法はありません。



All Articles