Asteriskのダイヤルプラン

Asteriskの設定は多数のファイルセットで構成されますが、ダイヤルプラン(番号ごとのルーティング)はextensions.confに定義します。

簡素な内線の例

ダイヤルプランは次のような構文になっています。

[internal]

exten => _1XX,1,Dial(PJSIP/${EXTEN},30)
same => n,Hangup()

各番号にマッチさせるブロックの構文は次のような構造になっています。

  • 冒頭の見出し[internal]contextで、複数のルーティングを分類する役割を持つ。pjsip.confendpointから参照する。
  • 最初の行はexten => number,1,application()を記述する。右辺の各項目は左から次の内容を記述
    1. 1項目のnumberは 番号マッチのルール_1XX103199のように先頭の番号が1から始まる3桁の番号にマッチする
    2. 2項目の1はpriorityを表し、1番最初に実行する行であることを示す
    3. application()はAsteriskが提供する任意のアプリケーション処理
  • 2行目以降はsame => n,application()と記述することで、上から順に実行する
    1. same =>exten => number,の省略記法で、上の行と同じリクエストにマッチする
    2. 2項目のnは上の行の次点のpriorityを示すワイルドカード。必要に応じてn(label)の形式で他の行から参照できるラベルも付けられる
    3. application()は各行同じ

よってこの例では、まず Dial()を実行し、つぎに Hangup()を実行して終わります。
変数${EXTEN}にはリクエストされた番号が入っているため、1から始まる番号の場合、その番号のSIPクライアントを呼び出す挙動となります。

古い記述例ではsame =>を使わず全ての行をexten =>で定義している例がありますが、上から順に実行する例はsame =>に置き換えられます。

なお各アプリケーションはおおむね関数のような挙動をしますが、Voicemail(100, s)のように引数間にスペースを入れるとエラーの原因になる点には注意が必要です。エラーログからも空白文字が原因であることを読みとりづらいでしょう。

ボイスメール

[internal]

exten => _1XX,1,Dial(PJSIP/${EXTEN},30)
same => n,Answer()
same => n,Playback(/var/lib/asterisk/sounds/custom/voice-absent)
same => n,Wait(1)
same => n,Voicemail(${EXTEN},s)
same => n,Congestion
  • Answer()は、Asteriskが直接応答する挙動に切り替える。この例では30秒のDial()試行のタイムアウト後にAnswer()する
  • Playback(filepath)Voicemail(mailbox,options)は自動音声再生と、ファイルへの録音を行う
    • Voicemail()は既定の自動音声を再生する。sオプションで音声をスキップするため、Playback()を追加で指定する
    • Playback()のファイルは拡張子の指定を省略。決められた拡張子から適した音質のフォーマットを探す挙動になる。実用上は.wavのみで幅広く対応できる
  • Wait(sec)Congestion()は通話フローを制御する

なお、VoiceMail()のメールボックスは、別途voicemail.confで用途に合わせて設定が必要です。

voicemail.confではsendmail方式のメール送信も設定できますが、メール以外にダイヤルプランに System()を追加して任意のスクリプトを実行するという通知方法も実装できます。
System()は呼び出したコマンドの終了を待つため自動応答フローが一時停止しやすくなりますが、スクリプト内でバックグラウンド実行することで即座に後続処理に移る方法もとれます。なお、Hangup()後にはSystem()が実行されないようです。

自動音声用の音源ファイル

Asteriskがサポートするコーデックにはいくつかのバリエーションがありますが、安定して動作するのは固定ビットレート8000Hzサンプリングの8bitモノラルPCMです。

Linuxの場合、soxをインストールすると次のオプションで変換できます。

$ sox input.wav -b 8 -r 8000 -c 1 output.wav

# 32kHzの例
$ sox input.wav -b 16 -r 32000 -c 1 output.sln32

8000Hzのフォーマットはほぼ最低音質ですが、PSTN電話向けに広く使われている形式が8bit u-lawであるため、現状では互換性重視の妥協点と言えます。

より高音質な他フォーマットも、クライアントの対応コーデックの組み合わせやトランスコードなどにより動作する可能性があります。
ビットレートごとの拡張子に合わせる必要があります。じっさいに適切に再生できるかは実環境で動作させないと分からず、検証は必要です。

ボイスメール管理インターフェース

着信したボイスメールを再生したり削除するには、 VoiceMailMain()というアプリケーションを特定の内線番号に割り当てます。

[internal]

exten => 199,1,VoiceMailMain()
same => n,Hangup()

この例では内線199への通話で、ボイスメールを操作できます。
パスワード認証やEメール送信による通知などのセットアップは別途voicemail.confで設定します。

従来の電話網への発信

非SIPのPSTN電話に発信したい場合には、回線交換を提供する外部のSIPトランキングサービスを利用することになります。
SIPトランキングサービスへの接続はサービス仕様にもとづいて実装する必要があるため定型的な説明はできませんが、ダイヤルプラン設定のパートでできることはあまり多くありません。

[internal]

exten => _9.,1,Set(CALLERID(num)=+819876543210)
same => n,Dial(PJSIP/+81${EXTEN:1}@outbound-endpoint)
  • 9から始まる番号の場合に、外線に発信する定義とする例
  • CALLERID(num)に自分の電話番号をセットする
    • SIPのFromヘッダーに入る。大多数の場合、サービス提供者から自分に割当てられた番号になるはず
    • この例ではRFC2822形式で記述しているが、実際にはサービスの指定する形式に従うことになる
  • 相手の番号とendpintを指定してDial()する
    • ユーザー部分は、SIPのRequest-URIToヘッダーのためのオリジナルリクエストになる
    • この例ではRFC2822形式に変換するため、国番号を追加しリクエストされた番号を追加している。${EXTEN:1}はリクエストから1番目の数字を除去している。この例の9発信の最初の数字はPSTN電話番号ではないため
    • outbound-endpointは別途定義したエンドポイント名の例。

ダイヤルプランの設定だけでは、おそらくサービス接続に十分な設定として完結しません。これ以外のリクエスト設定は、pjsip.confのendpointで指定することになるでしょう。

従来の電話網からの着信

PSTN電話網からの着信も外部SIPトランキングサービスと接続する設定になります。
適切な接続はサービス仕様に合わせる必要がありますが、ダイヤルプラン設定のパートは比較的簡素です。

[dial-in]

exten => +819876543210,1,Dial(PJSIP/101&PJSIP/102,30)
same => n,Hangup()
  • PSTN電話番号宛てにリクエストが来た場合にマッチさせる定義
    • PSTN電話の受信はサービス契約で取得した番号宛てにリクエストが来るため、マッチ条件を限定できるはず
  • Dial()で呼び出したいendpointを指定する
    • この例では複数のクライアントを呼び出す想定で、エンドポイント101と102を指定している

適切に受信できたら、他のアプリケーションも追加できます。たとえばボイスメールはSIPネットワークの設定方法と同じです。

着信拒否

AsteriskにはCALLERIDをもとに拒否対象を判定する BLACKLIST()関数があります。
次のように、 GotoIf()と組み合わせて、該当時に特定のラベルを持つ行にジャンプする制御フローを書けます。GotoIf()の引数はよくある三項演算子と同様の記法になっています。

[dial-in]

exten => +8150.,1,GotoIf(${BLACKLIST()}?spam)
same => n,Dial(PJSIP/101,30)
same => n,Hangup()
same => n(spam),Hangup()

この例ではBLACKLIST()に該当しない場合はジャンプせず、2,3行目を実行します。

拒否リストはAsterisk標準のsqlite3を参照します。CLIのdatabaseコマンドで操作できます。

asterisk*CLI> database put blacklist +819876543210 note
asterisk*CLI> database del blacklist +819876543210
asterisk*CLI> database show blacklist

着信表示編集

SIPクライアントにはCALLERID(name)を表示できる機種が多くあります。
Dial()する前にSet()で編集することにより、たとえば着信番号ごとのプレフィクス文字を追加できます。

same => n,Set(CALLERID(name)=AA${CALLERID(num)})

この例では、発信者番号の前にAAという文字を追加したnameを設定しています。
たとえばSIP1回線しかレジストできない端末であっても、複数の電話番号を受信し回線を識別できます。

⁋ 2024/08/13↻ 2024/12/18
中馬崇尋
Chuma Takahiro