15
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Asterisk検証まとめ

Last updated at Posted at 2018-07-05

Asterisk検証めも
検証が進むにつれ追記していきます。たぶん。

環境

OS Asterisk AGI Library Python
CentOS 7.3 Asterisk 15.3 pyst2 Python 3.4

pyst2
https://github.com/rdegges/pyst2

構築

事前準備

必要パッケージインストール

# yum update
# yum install make wget openssl-devel ncurses-devel newt-devel libxml2-devel kernel-devel gcc gcc-c++ sqlite-devel libuuid-devel json-glib json-glib.i686 json-glib-devel.x86_64 jansson-devel.x86_64
# reboot

公式から以下のファイルをダウンロード
※今回はアナログ回線を接続しないのでdadhiとlibpriは不要

asterisk-15-current.tar.gz

Githubから以下をダウンロード(pjsip)
https://raw.githubusercontent.com/asterisk/third-party/master/pjproject/2.7.1/pjproject-2.7.1.tar.bz2
https://raw.githubusercontent.com/asterisk/third-party/master/pjproject/2.7.1/MD5SUM.TXT

// 解凍
# tar zxvf asterisk-15-current.tar.gz

// 本体配置
# mv asterisk-15.3.0 /usr/local/src/


// ローカルインストール用ディレクトリ作成
# mkdir /tmp/downloads

// pjsip 配置
# mv pjproject-2.7.1.tar.bz2 /tmp/downloads/
# mv MD5SUM.TXT /tmp/downloads/pjproject-2.7.1.md5

// fax用モジュールインストール
# tar zxvf spandsp-20180108.tar.gz
# cd spandsp-0.0.6
# ./configure
# make
# make install

//サウンドファイル配置 (使いたいファイルだけセットで落としてくる)
# mv asterisk-core-sounds-en-wav-1.6.1.tar.gz /tmp/downloads/
# mv asterisk-core-sounds-en-wav-1.6.1.tar.gz.sha1 /tmp/downloads/

インストール

// Asteriskインストール
# cd /usr/local/src/asterisk-15.3.0
# ./configure --with-download-cache=/tmp/downloads
# make menuselect

※他に必要なモジュールがあればチェックを付ける(mp3やFax等)
// faxモジュール
[*] res_fax
[*] res_fax_spandsp

// mp3モジュール
[*] format_mp3

# make
# make install
# make samples
# make config

# systemctl start asterisk
# systemctl status asterisk
# systemctl enable asterisk

設定

基本的にはインストールで実施した手順でサンプルのコンフィグファイルが生成されているはずですので、
該当部分をコメントアウトすればOKだと思います。

API設定

AsteriskのRestfulAPIをオン

/etc/asterisk/ari.conf
enabled=yes
pretty=yes

[asterisk]
type=user
read_only=no
password=パスワード
/etc/asterisk/http.conf
[general]
enable=yes
bindaddr=0.0.0.0
bindport=8088

言語設定(任意、デフォルトの音声データ参照先ディレクトリが変わります)

/etc/asterisk/asterisk.conf
defaultlanguage=ja

###ログ出力設定

デフォルトだといくつかログ出力のレベルが低いので設定します

/etc/asterisk/logger.conf
console => notice,warning,error,debug,dtmf,verbose,security,fax
messages => notice,warning,error,debug,dtmf,verbose,security,fax

外線設定(楽天コミュニケーションズ IP電話 B2BUA OpenGate サービス)

今回楽コムのOpenGateサービスにしたのは主に以下の理由です。

  1. 支払方法・費用
  2. Asteriskの動作実績

1についてですが、これはうちの会社だと開発の部署で法人名義のクレカが使えなかったためです。
そのため第一候補に挙がっていたtwilioに請求書払いが可能かどうか問い合わせたところ、
書類手続きに月5000円かかるとのことなのでこちらになりました。

第2候補ではありましたが、細かい質問に対しても割とレスポンスが早く、開発部署と連携して回答頂いたので個人的に楽コムは好印象でした。

ただ法人としての契約の場合、実印や印鑑証明書や履歴事項全部証明書を求められるので・・・・
所属しているのが大企業の場合は素直にTwilioをおすすめします。
(手続きや申請が苦にならないならどちらでも良いと思いますが)

sip.conf
[general]
maxexpirey=3600
defaultexpirey=3600
srvlookup=no
allowguest=no

port=5060
bindaddr=aaaa.aaaa.aaaa.aaaa
transport=udp

rtptimeout=60
rtpholdtimeout=300
session-timers=refuse
session-expires=3600
session-refresher=uas

localnet=xxxx.xxxx.xxxx.xxxx/255.255.255.255(サブネット)
externaddr=yyyy.yyyy.yyyy.yyyy
register=ユーザID:パスワード@sipプロキシ/test(設定名)

[test]
type=frined
username=ユーザID
fromuser=ユーザID
secret=パスワード
host=sipプロキシ
fromdomain=okj.sip.0038.net
insecure=port,invite
context=コンテキスト名

※セッション周りの設定はいらないかも・・・

発信

Asteriskでの発信方法は概ね以下の3つになる。

  1. call fileの作成
  2. channels API(ARI)の利用
  3. SIPクライアントからの直接発信

ARI と AGI

AsteriskでのREST APIは **ARI (Asterisk REST Interface)**という名前でまとめられていて、
逆にローカルで直接Asteriskを操作するようなインターフェースは
**AGI (Asterisk Gateway Interface)**を利用します。

ARI
https://wiki.asterisk.org/wiki/pages/viewpage.action?pageId=29395573

AGI
https://wiki.asterisk.org/wiki/pages/viewpage.action?pageId=32375589

channles API

まず今回主に利用するchannles APIですが、書式は以下です。

API

method URI optional
POST /channels/{channle_id} channel_id

パラメータ

param required type description
endpoint true string 宛先
extension exclusive string extensions.confのextension
context exclusive string extensions.confのconext
callerId false string 発信元
timeout false int タイムアウト(sec)

その他のオプションは今回あまり使わないので知りたい場合はリファレンスを参照してください

API経由での発信

SIPクライアント同士がAsteriskを経由して通話を行うのは比較的簡単です。
しかしAsteriskのAPIをトリガーに複雑な制御を行った発信を行うにはいくつか注意が必要です。

例えば、APIリクエスト時には発信先を指定せずリクエストに載せた追加パラメータに沿って複数に発信したい場合などです。
何故ならAsteriskでは実在する(レジストされた)SIPデバイスしかendpointに指定出来ないので、
リクエスト時に発信先を必ず指定する必要があるからです。
つまりこの方法でやるとなると、通常は代表番号のようなものを用意して必ず同じ番号を1つendpointに設定することになります。

ローカルチャンネル

上記の問題を解決するのがローカルチャンネルです。
ローカルチャンネルはAsterisk内部に仮想endpointを生成し、そこを経由することにより実デバイス同士が通信しているように見せかけます。

Asterisk ====> 仮想エンドポイント ====> ブリッジ ====> 宛先

以下のようにextension.confを設定し、リクエストに所定のパラメータを設定するとtalkコンテキストに飛んで「ハロー」という音声が流れるはずです。

あとはcallコンテキストの部分をスクリプトで置き換え、やりたいことに合わせてスクリプトで発信の制御を行えば順番に発信したり一斉に発信したりすることが可能です。

extension.conf

[call]
exten => s, 1, Call(SIP/111)

[talk]
exten => s, 1, Answer()
exten => s, n, Playback(hello)
exten => s, n, Hangup()
ari.py
#!/usr/bin/env python3
# -*- coding:utf-8 -*-

import requests
import json


class ARI: 

    def __init__(self, *, user='asterisk', password='asterisk', ip_addr='localhost', port='8088'):
        self.user = user
        self.password = password
        self.port = port
        self.base_url = 'http://{user}:{password}@{ip_addr}:{port}/ari/'.format(
            user=user, password=password, ip_addr=ip_addr, port=port    
        )

    def call(self, params, data, headers):
        api = "channels"
        url = self.base_url + api
        print("URL:" + url)
        print(json.dumps(data))
        response = requests.post(url, params=params, data=json.dumps(data), headers=headers)
        return response


def main():
    asterisk = ARI(user="asterisk", password="asterisk")

    headers = {'content-type':'application/json'}
    call_params = {
        "endpoint":"Local/s@call/n",
        "extension":"s",
        "context":"talk",
        "priority":"1",
        "timeout":"10",
    }
    data = {"variables": {"call_list":"[111,222]"}}
    print(asterisk.call(call_params, data, headers).text)

if __name__ == '__main__':
    main()

CallFileでの発信

発信時のステータス遷移

発信時にはAsterisk内部でchannelが生成され、クライアント側・サーバ側の動作によりこのchannel内部のchannelStatusが変化する。
現在のチャンネルの状態はこのchannelStatusを確認することで判断することが出来る。
この値はextensions.confであれば**${DIALSTAUTS}**で取得可能。

なお、帰ってくる値は対向のSIP Gatewayによる場合もあるので必ずしもこうなるとは限りません。
例えば楽天経由で050から0120番号へかけるとCONGESTIONが帰ってきます(050からは普通繋がらない)。

動作 ステータス
宛先端末への疎通不可 CHANUNAVAIL
タイムアウト CANCEL
応答拒否 BUSY
応答なし NOANSWER
応答 ANSWER
混雑中 CONGESTION

https://wiki.asterisk.org/wiki/display/AST/Asterisk+13+Application_Dial
https://www.voip-info.org/asterisk-variable-dialstatus/

リファレンス等を見ると他にも色々ありますが、よく出てくるのは上記6つ程度かと思います。

15
14
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
14

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?