このページの最終更新日: 2008/01/16

Asteriskで音声会議室(Conference call)を実現する

インターネット越しの音声会議を実現すべく、Asteriskサーバを立ち上げました。
触り程度の解説を交えつつ、覚書を公開します。

なお、このドキュメントは設定完了後に思い出しつつ書いた部分が多いため、このままで動作を保証するものではありません (特に設定ファイルの変更点あたり)。
ご指摘いただければ、都度加筆・訂正致します。

Asteriskとは

Asteriskとは、構内交換機(以下、PBX)の代わりとなるオープン・ソースのサーバ・アプリケーションです。 しかもIPベースのため、IPネットワークの及ぶところであれば地理的制約に縛られずに端末(市販されているIP電話機、あるいはSkypeのようにPC上で動作するソフトウェア・クライアント)を敷設することができます。
このサーバさえ設置しておけば、遠隔地にある端末(IP電話機あるいはソフトウェア)の端末同士をあたかも館内にいるかのように内線番号で呼び出したり、外線からの着信を転送することができます。
例えば社内にAsteriskサーバを設置し、在宅勤務のスタッフが自宅で端末を立ち上げた場合、社内の電話端末からは在宅スタッフを内線番号一つでシームレスに呼び出せますし、外部から会社受付に宛てられた電話を保留にし、在宅スタッフに転送することも可能です。

昨今、数名程度の音声会議であればSkypeで大抵事足りるでしょう。
これと比して、Asteriskのアドバンテージは

背景を少し…導入前の豆知識

・Asteriskのバージョンには現在、1.2系、1.4系、1.6系が存在します。
簡単なコンファレンス用サーバを設ける分には、特に差異はないと思います。(筆者は1.6系はまだ試しておりません)
・元々はPBXの代替サーバなので、アナログ電話回線、ISDN回線と接続するカードが存在します。
というよりAsteriskの開発元Digiumはアプリケーションをオープンにする代わりに、外線接続カードの製造・販売およびコンサルティングにより利益を上げているものと理解しています。
さて、このカードは外線接続に必要なインターフェースを提供する他、音声処理のクロック・ソースとしても機能します。ソフトウェア・クライアント同士、一対一で直接通話する場合、音声データを右から左に流すだけなのでAsteriskサーバ以外に特に必要なアプリケーションはありません。しかし、会議室のように複数の音声ソースを混ぜたりと、サーバの作業に時間制御が絡んでくるモジュールを使用する際には、クロック・ソースとなるカードを制御するための、カーネルモジュールが少なくとも1つはロードされている必要があります。
これはカードを必要としない状況も例外ではなく、この場合は「ダミー」のモジュール(後述)をロードします。

で、このカーネルモジュールなのですが、ほぼ同様のものに対して2つの呼び名があります。
1.4系の半ばまでは、Zapata(転じて、モジュール名Zaptel, チャンネル名(後述)Zapなど)と呼ばれていました(メキシコ革命の指導者に由来するらしい)。しかし、ある時期にZaptelが別の企業により商標登録されていることが判明したのを機に、名称を"DAHDI"に改めました。
この名残から、カーネル・モジュールおよび外線接続のインターフェースに関して、以下の名称スキームが取られています。
Version 1.2 → Zapataのみ(Zaptel, Zapなど)
Version 1.4 → Zapata, DAHDIの両者を併用
Version 1.6 → DAHDIのみ

導入

ディストリビューションがパッケージを提供している場合、そちらを使用してもよいかも知れません。Debian 4.0 Etchにおいては、1.2系のパッケージが標準で用意されています。
今回は、筆者が個人的に数年間使用している1.2と、後継となる1.4の互換性を確認するという目的もありますので、1.4系のソースを入手してビルドしました。

以下、Debian 4.0 Etchの使用を前提に話を進めます。
クリーンなDebian EtchにAteriskを導入する場合、とりあえず以下のパッケージを入手します。

カーネルヘッダはdahdi-linuxのビルドに必要
doxygenは任意。(ドキュメントのビルドに必要)

■入手するtar ball
http://www.asterisk.org/downloads
(ページ右端"Asterisk Downloads"より)

DAHDIカーネル・モジュールがインストールされていないと、Asteriskビルド時にMeetMe(会議室用のモジュール)がビルドされません。なので、上記3つは上から記載順にインストールします。

各ソース・パッケージは、一般に以下の手順でビルド&インストールします。

$ ./confiugre
$ make menuselect ←※注
$ make
# make install
二手目の"make menuselect"にご注意下さい。
configureで得たシステム情報を元に、コンソール・ベースのメニューから実際にビルドするオプションを選択します。Asterisk本体をビルドする段階でDAHDIがインストールされていないと、このメニューからMeetMeを選択することができません。
標準の音声ガイダンスなどの音声ファイルはAsterisk本体のmake install時にdigiumのHTTPサーバよりダウンロードされる仕組みのため、この段においてはインターネットに接続できるようにしておいた方がよいでしょう。

■設定ファイルについて

設定は /etc/asterisk ディレクトリ以下に、機能別に異なるファイルを用意して記述します。
しかし、デフォルトでは /etc/asterisk 以下には一つもファイルはありません。
手っ取り早いのは、Asterisk本体のビルド成功直後に表示されるメッセージに従い、サンプルの設定ファイルを作成することです。
以下の手順を実行します。

(Asteriskソース・パッケージのパスにて)

# make samples
このコマンドを実行すると存在しうる全ての設定ファイルが、サンプルと解説を含んだ状態で作成されます。なお、一部のサンプルはコメント・アウトされておらず、デモがてら実際に機能を有効にします。これはセキュリティ上好ましくない場合もあるかも知れません。
筆者は以下のように設定ファイルを一旦別のディレクトリに退避させ、その都度必要な機能に関連する設定ファイルだけを/etc/asterisk以下にコピーした後、編集して使用しています。
# mkdir /etc/asterisk/backup
# mv /etc/asterisk/*.conf /etc/asterisk/backup
# cp /etc/asterisk/backup/(任意の設定ファイル) /etc/asterisk/

今回は以下の設定ファイルをコピーしました。

chan_dahdi.conf DAHDI関連
extensions.conf 内線番号の割り当てはここで(後述)
iax.conf クライアントの設定(後述)
logger.conf ロギングの設定
manager.conf 管理ツールの接続関連設定
meetme.conf 会議室設定
modules.conf モジュールを強制的にロード/ロードさせない場合に指定
musiconhold.conf これが無いと保留時にBGMが鳴らない
oss.conf サウンドカード出力を有効にして、会議室の様子を接続したスピーカにて傍聴するため。
以下、「設定ファイルが見つからない」旨の警告文が出たので、なんとなく設置したもの。

■会議室を作成

meetme.confに、以下の一行を追加します。

conf => 1000
「会議室番号1000」が作成されました。
ただし、内線番号1000でこの会議室に接続できるわけではないことにご注意下さい。
現段階では、あくまでタグを割り当てているだけです。

■クライアントの登録

PBXに接続できるクライアントを登録します。
Asteriskサーバに端末として接続する際には、数通りのチャンネルが選択可能で、設定ファイルもこのチャンネル毎に分かれています。

「チャンネル」
広義には、各端末がAsteriskサーバに接続する方法、あるいはプロトコルの違いと言えます。
主なチャンネルには以下のものがあります。

ここでは、呼制御と音声が単一に単一のポート(4569:UDP)を使用し、最もNAT越えの容易なIAX2プロトコルを使用する端末を登録します。
設定は、iax.confに記述します。

[user01] <= 括弧内のワードが、端末の名前になる
type=friend <= ユーザ登録と同時に、他の端末から発信可能にする(ただし、まだ番号は割り当てられていない)
host=dynamic <= ダイナミックなアドレスから接続される旨を明示
secret=pass <= 任意のログイン・パスワード
context=default <= コンテキスト名(要約すると、この端末から発信できる内線番号の一覧)

[user02]
type=friend
host=dynamic
secret=pass
context=default
これで、このPBXに接続可能な端末2つを登録できました。
この時点でZoiper, iaxCommなどのIAX2対応クライアントを使用しての接続が可能となります。

■内線番号

さて、クライアントの一覧と会議室を作成はしたものの、まだ互いを呼び出す手段がありません。
任意の内線番号に接続先や各種機能を割り当てるには、extensions.confを編集します。
内線番号は主に以下の書式で登録します。

[context_name]
exten => 内線番号, 優先度, コマンド
※注
コマンドは正確には「アプリケーション」と呼ばれており、一覧は「アプリケーション・リファレンス」などに記述されています。
ここで、context_nameが、iax.conf内にて指定したコンテキスト名となります。先ほどのサンプルでは context=defaultに設定しましたので、[default]以下に登録した内線番号にのみ発信可能となります。

たとえば、内線番号100番を呼び出した場合に
1. 交換機が電話に応答する
2. 音声メッセージだけ流して
3. 終了
する場合、以下のように記述します。
exten => 100, 1, Answer()
exten => 100, 2, Playback(file_name)
exten => 100, 3, Hangup()

<= 音声ファイル名の拡張子は指定しない(後述)

このように、任意の内線番号にダイヤルすると、優先度の順にコマンド(アプリケーション)が実行されます。また、2行目以降の優先度指定は、後述のように "n" と置いた場合、記載順に実行することが可能です。

今回は、extensions.conf内に以下のように記述しました。

[default]
exten => 1000, 1, Answer()
exten => 1000, n, Wait(1)
exten => 1000, n, MeetMe(1000, rM)
<= context=defaultと設定したクライアントに以下の設定を該当
<= 応答
<= 一部、応答直後のレスポンスに弱いクライアントに対応するためのウェイト
<= 会議室1000に転送

・オプション
r = 会議室に人が入ると、自動的に音声を録音開始
M = 会議室内に一人しかいない場合は保留音を再生
exten => 01, 1, Dial(IAX2/user01, 60, tT) 各ユーザに内線番号01, 02は、それぞれの端末を呼び出す。
exten => 02, 1, Dial(IAX2/user02, 60, tT)
最後の二行に注目して下さい。Dialアプリケーションなどで端末を明示する場合、「接続チャンネル/ユーザ名」を一対として指定します。上記の場合は「IAX2プロトコルで接続中のuser01」と読み替えられます。

考え方としては、次の二つの説明のうち、後者の方がより正確であると言えます。
 ×「user01に内線番号01を割り当てる」
 ○「context=defaultのユーザが"01"を発信した場合、IAX2チャンネルで接続中のuser01を呼び出す」

Asteriskの実行

一応、筆者はTDM400(2FXO, 1FXS)を所有していますが、今回はインターネット越しのソフトウェア・クライアントのみ接続予定ですので、カードは使用しておりません。前述の理由により、とりあえず必要となるダミーのカーネル・モジュールをロードしておきます。

# modprobe dahdi_dummy

Asteriskの実行
# asterisk

Asteriskの制御およびモニタは、サーバの実行とは独立したアプリケーションから行えます。
終了するには exit [enter]を入力。

# asterisk -vvvr (メッセージをどのぐらい詳細に表示するかを決定する"v"の個数は任意)

その他

■音声ファイルの拡張子省略について

音声ファイルを録音/再生する場合、基本的に拡張子は指定しない。
該当ディレクトリに存在する同名ファイルより、最も変換コストの少ない形式を自動的に選択する。
(例:クライアントがgsmで接続していれば、gsm形式のファイルを優先的に探して再生しようと試みる)