Asterisk AEL

目次

AEL(Asterisk Extension Language)

Asterisk 1.2以降ではAsterisk Extension Languageと呼ばれる機能が追加されています。従来のextensions.confをより簡単に記述するための言語です。
AELはAsterisk 1.2では『試験的実装』と位置付けられ、1.4からは正式実装となっています。
AELの記述は、extensions.aelというファイルで行い、これが存在しない場合には以下のようなWARNINGがログに出力されますが従来のextensions.confを使用しているのであれば、無視して問題はありません。

Oct  2 23:31:21 WARNING[9612] pbx_ael.c: Unable to open '/etc/asterisk/extensions.ael': 
                No such file or directory
Oct  2 23:31:21 WARNING[9612] pbx.c: Requested contexts didn't get merged

AELの機能を削って軽量化をはかる場合にはmodules.confに以下のように記述しておくと良いでしょう。

noload => pbx_ael.so

なお、現在まで(~1.4)の実装では、AELは一種のコンパイラ的に動作しており、AELで記述された内容はextensions.confの形式に変換され、extensions.confとマージするという動作をしています。

AELの使い方

 AELは従来のextensions.confとは全く独立したアプリケーションで、前述のように、これまでのextensions.confと同時に使うことができます。もちろんAELを使わなくてもAsteriskは動作しますので、従来のままのextensions.confを使いたければ、そのまま使えば良いわけです。AELはAsterisk 1.2で初めてリリースされた機能ですので今後、extensionの記述が従来の1.x系になるのか、AELに統一されるのかはまだわかりません。
 AELを使用するにはモジュール pbx_ael.so がロードされる必要があります。通常はautoloadで使用していると思いますので、設定ファイルを記述すれば使用できます。 設定ファイル(というより記述ファイルですが)は/etc/asterisk/extensions.aelで、このファイルにAELにのっとって記述を行います。たとえば内線番号8000番としてコールキューに入れる処理を記述してみることにします。この場合には以下のようにAELで書きます。

context default {
    8000 => {
        Answer();
        Wait(1);
        PlayBack(q-default);
        Queue(queue1,t);
        Hangup();
    };
};

 まずcontext{};で括られた内側がそのコンテキストになります。8000=>がそのエクステンションで、8000 => {};で括られた内側がその処理になります。従来のようにプライオリティをいちいち記述する必要はありません。話中処理などプライオリティジャンプさせていた部分は、if~else式の条件処理に置換されるようです。  この記述がちょっと微妙です。例えばdeafult {の部分、deault {と、defaultの後ろにホワイトスペースがないと正しく認識されません。default{と書いてはいけないようです。

仕様上の注意

 コンテキストがextensions.confとextensions.aelで衝突すると、extensions.confが優先されてしまいます(リロード時には後からリロードされた側)コンテキスト内でのマージはできません。
例えばextensions.confで次のように記述しておき

[default]
exten => 800,1,Something...

extensions.aelで次のように記述すると

context default {
    exten => 900 {
        some_app();
    };
};

期待するのは[default]コンテキスト内に800と900のエクステンションが登録されることなのですが実際には800のみが登録されます。
extensions.confで次のように記述し

[default]
exten => 800,1,Something...
exten => 900,1,Goto(ael-test,100,1)

extensions.aelに次のように記述すると

context ael-test {
    exten => 100 {
        some_app();
    };
};

この場合にはコンテキストが異なるので期待した通りの動作をします。 AELと従来のextensions.confを併用する場合にはこの挙動に注意してください。

extensionの名前制御

AELではswitchの中などで、extensionの名前が意図せずに変わってしまう。 これはPickup()を使う場合に都合が悪い。

_0. => {
	...
	switch ($FOONUMBER) {
	case 911:
		jump to911;
		break;
	...
	}
}

to911 => {
	Dial(SIP/234&SIP/456,30,tw);
	Congestion();
}

などとして分岐の無いextensionへjumpさせれば変化しにくくなる。 変化したかどうかはael reload後にdialplan showして確認すること。 以下のようにPickup()でjumpした先を指定すればいい。

*88 => {
	Pickup(to911); // Dial()部分はto911からは変化しないはず
	...
}

リロード方法

extensions.confのリロードは従来通り

*CLI> extensions reload

で行いますが、AELの場合には以下を使います(1.2.0あたり)

*CLI> reload pbx_ael.soAsterisk

1.2.5ではael reloadがサポートされています。

*CLI> ael ?
debug   no      reload
*CLI> ael reload

従来形式とAELを併用している場合には片側のコマンド実行だけではエクステンションのリロードが完全には行われませんから注意します。

確認方法

AELで作成したextensionsが正しく展開されているかどうかを確認するには、CLIでshow dialplanを使います。特定のコンテキストのみを確認する場合にはshow dialplan ael-testのようにコンテキストを指定します。

*CLI> show dialplan
[ Context 'myext' created by 'pbx_config' ]
  '111' =>          1. NoOp()                                     [pbx_config]

[ Context 'default' created by 'pbx_ael' ]
  '117' =>          1. Answer()                                   [pbx_ael]
                    2. Wait(1)                                    [pbx_ael]
                    3. Set(FutureTime=$Math{(${EPOCH}+5)})        [pbx_ael]
                    4. SayUnixTime(${FutureTime}||PHM)            [pbx_ael]
                    5. PlayBack(beep)                             [pbx_ael]
                    6. Hangup()                                   [pbx_ael]

[]の中のpbx_configはextensions.confで作成されたもの、pbx_aelがAELで記述されたものになります。