,有時會在number數(shù)字后附加一些信息。如果向Asterisk發(fā)送了無效的命令,信息如下:510
Invalid or unknown command。對應(yīng)上面的命令,如下所示:
- AGI Rx << SET CONTEXT media_gw1
- AGI Tx >> 200 result=0
當AGI腳本執(zhí)行時,Asterisk會向腳本發(fā)送各種的信息,可以在做其他事情之前通過標準輸入獲取這些信息,每項數(shù)據(jù)都是一行,發(fā)送完畢Asterisk會發(fā)送一個空行,表示結(jié)束,如:
- AGI Tx >> agi_request: dial_agi.php
- AGI Tx >> agi_channel: SIP/25946-0821ea88
- AGI Tx >> agi_language: en
- AGI Tx >> agi_type: SIP
- AGI Tx >> agi_uniqueid: 1209093478.477
- AGI Tx >> agi_callerid: 0000123456
- AGI Tx >> agi_calleridname: beigaolin
- AGI Tx >> agi_dnid: 998866015810370728
- AGI Tx >> agi_context: default
- AGI Tx >> agi_extension: 998866015810370728
- AGI Tx >> agi_priority: 1
根據(jù)項目需求,如果需要這些數(shù)據(jù),就先保存起來,否則不用處理它。保存步驟按如下過程。
1.打開PHP輸出文件描述符:
$in = fopen("php://stdin","r");
2.分析從Asterisk傳到AGI的頭信息,如需要在AGI程序中獲取終端用戶的ID,那么從“agi_calleridname:
beigaolin”這個頭信息可以獲取,我們通過分析每一行這樣以:分隔的字符串,取到需要后續(xù)處理的字符串
while (!feof($stdin)) {
$temp = fgets($stdin);
$temp = str_replace("\n","",$temp);
$s = explode(":",$temp);
$agivar[$s[0]] = trim($s[1]);
if (($temp == "") || ($temp == "\n")) {
break;
}
}
4.使用開源PHP AGI類函數(shù)PHPAGI
像上一小節(jié)那樣先是獲取輸入流,分析從輸入頭字符串中獲取對應(yīng)某個輸入變量的值,或者獲取輸出流然后發(fā)送各種標準命令執(zhí)行某些Asterisk內(nèi)置應(yīng)用,如果在AGI程序中實現(xiàn)很復(fù)雜的業(yè)務(wù)邏輯,這樣的流程會顯得有點累贅,所以需要提取某些常用的操作,我們使用的時候不用關(guān)心這些操作,直接以調(diào)用類似Asterisk內(nèi)置應(yīng)用那樣的方式。PHPAGI就是這樣的一個開源PHP類函數(shù)。它封裝了對應(yīng)Asterisk內(nèi)置應(yīng)用的常用函數(shù)調(diào)用接口,比如說從PHP向Asterisk發(fā)送Dial命令的操作,可以直接調(diào)用PHP
AGI類函數(shù)中的exec_dial。使用PHP AGI能夠很容易的操作Asterisk AGI常用接口。使用這個類函數(shù)也很簡單:
- cd /var/lib/asterisk/agi-bin/(也有可能在用戶自定義的路徑中)
- wget http://nchc.dl.sourceforge.net/sourceforge/phpagi/phpagi-2.14.tgz
- tar zxvf phpagi-2.14.tgz
- include ("phpagi.php");//包含文件
- include ("phpagi-asmanager.php");
- $agi = new AGI;//引用PHPAGI類函數(shù)
5.使用AGI實現(xiàn)主叫號碼透傳功能
在這里以一個例子來說明AGI程序在VoIP開發(fā)中的作用以及開發(fā)思路。
假設(shè)說有個普通電話為02412345678,手機號為15810370728,而網(wǎng)絡(luò)電話虛擬號碼是0000123456,如果想讓撥打出去的電話號碼在被叫方(手機或者帶有來電顯示功能的座機)的來電顯示為02412345678或者15810370728,那么他們回復(fù)電話的時候就可以直接打到這個普通電話上,方便與主叫的業(yè)務(wù)聯(lián)系。這個需求就叫主叫號碼透傳,能不能進行主叫號碼的透傳,取決于VoIP落地網(wǎng)關(guān)運營商,語音網(wǎng)關(guān)可以設(shè)置IP側(cè)送過來的主叫號碼是否透傳。在保證號碼規(guī)范的前提下,透傳什么樣的主叫號碼,則取決于IP-PBX系統(tǒng),即Asterisk的設(shè)計了。
1.增加一個針對終端用戶賬戶ID的綁定管理系統(tǒng),如圖用戶在第二項中輸入自己的賬戶ID,然后再輸入想要作為來顯示的主叫號碼完成綁定操作,后臺php程序向數(shù)據(jù)庫中插入一條新記錄(X-Lite
ID對應(yīng)電話號碼或者手機號碼)。
圖1AGI后臺管理系統(tǒng)頁面
2.使用綁定了主叫號碼的X-Lite呼叫某個被叫(手機或者座機)
Asterisk的后臺PHP AGI程序的詳細設(shè)計主叫號碼透傳流程設(shè)計如圖2所示。
圖2Asterisk 主叫號碼透傳的后臺PHP AGI流程圖
以下代碼片斷展示的是PHP AGI中部分代碼,并且作了簡化。
#!/usr/local/php.5.2.5/bin/php –q
include_once("phpagi.php");//開源PHP類函數(shù)
......
//判斷當前這個id是否做了主叫號碼來電顯示的綁定操作
$query_string = "select * from xliteid where xliteid = '{$caller_name}'";
$query_result = mysql_query($query_string, $db_connection);
//如果當前這個id做了綁定操作,調(diào)用PHPAGI類函數(shù),設(shè)置Asterisk主叫號碼
if($query_result && mysql_num_rows($query_result) > 0)
{
caller_phone_display_agi ();
}
//沒有做綁定,設(shè)置一個隨機的號碼
else
{
caller_name = $argv[2];
$rand_num1 = rand(0,9);
$rand_num2 = rand(0,9);
$rand_num3 = rand(0,9);
$caller_phone= "024{$rand_num1}{$rand_num2}650{$rand_num3}{$rand_num4}";
land_media_gw1($caller_phone);
exit();
}
/**
*@caller_phone_display_agi 主叫號碼特殊顯示
*/
function caller_phone_display_agi()
{
global $db_connection, $callee_phone, $caller_name;
$query_string = "select caller_phone from caller_phone_display
_xliteid where skype_id = '{$caller_name}'";
$query_result = mysql_query($query_string, $db_connection);
{
$row = mysql_fetch_array($query_result);
$caller_phone = $row[0];
$callerid_cli = "\"{$caller_name}\"<{$caller_phone}>";
land_media_gw1($callerid_cli);
exit();
}
}
/**
*@ land_media_gw1 VoIP語音網(wǎng)關(guān)media_gw1
*/
function land_media_gw1($callerid_num)
{
global $agi, $callee_phone_withpre;
$agi->set_context("media_gw1");
$agi->set_extension($callee_phone_withpre);
$agi->set_priority(1);
//調(diào)用phpagi封裝的set_callerid方法,向Asterisk傳遞設(shè)置主叫號碼的指令
$agi->set_callerid($callerid_num);
}
對X-Lite賬戶gaolinb作了主叫號碼綁定,使用X-Lite軟終端呼叫普通的手機,在Asterisk中設(shè)置了agi
debug,從Asterisk后臺我們可以清晰地看到:
1.AGI Tx >> *CLI>上面部分,全是從Asterisk輸入到當前AGI的環(huán)境變量信息,它包含了當前這個呼叫的詳細信息,如Channel的類型,是SIP還是H.323,calleridname,即終端用戶是gaolinb等重要信息。
2.AGI Tx >> *CLI>下面部分,全是在上面調(diào)用PHPAGI類函數(shù)后將命令傳給了AGI程序執(zhí)行,對于主叫號碼來電顯示的命令是:
SET CALLERID ‘gaolinb’<15810370728>,Asterisk將15810370728傳到能夠支持主叫號碼透傳的VoIP運營商,從而被叫用戶在接聽電話前能夠顯示一個有意義的電話號碼。
圖3 Asterisk服務(wù)器上AGI的輸入輸出信息
貝高林的Blog
相關(guān)鏈接: