Asterisk AGI PHP 脚本调试

编写 AGI 脚本与 Asterisk 交互时,一旦脚本出错,在控制台(asterisk -crvvvvvvvvvvvv)上又看不出错误,只能把 stdin 改为具体的变量,在直接调用脚本,但这样很不方便。趟过几次坑之后,把调试的步骤记录下来,以便后来者规避此坑。

首先,配置 php.ini 的 display_error 和 error_log

display_error = off
error_log = /var/log/mylogfile

其次,在脚本里记录日志,同时脚本必须具有执行权限

#!/usr/bin/php -q
<?php

function write_log($data)
{
    global $config;
    file_put_contents('/var/log/' . date('Ymd') . '.log', $data . PHP_EOL, FILE_APPEND);
}

$stdin = fopen('php://stdin', 'r');
$stdout = fopen('php://stdout', 'w');

while (!feof($stdin))
{
    $temp = fgets($stdin);
    if (strpos($temp, ':') === false)
        break;
    // Strip off any new-line characters
    $temp = str_replace("\n", "", $temp);
    write_log("stdin:" . $temp);
    $s = explode(":", $temp);
    $agivar[$s[0]] = trim($s[1]);
}

function execute_agi($command)
{
    global $stdin, $stdout;
    fputs($stdout, $command . "\n");
    fflush($stdout);
    $result = fgets($stdin, 4096);
    write_log('agi result: ' . $result);
    return $result;
}

$flag = 'debug demo';
execute_agi("SET VARIABLE FLAG \"$flag\"");

以下为日志信息

stdin:agi_request: judge.php
stdin:agi_channel: SIP/siptrunk-00000081
stdin:agi_language: en
stdin:agi_type: SIP
stdin:agi_uniqueid: 1531906486.129
stdin:agi_version: 11.25.1
stdin:agi_callerid: 11111111111
stdin:agi_calleridname: unknown
stdin:agi_callingpres: 0
stdin:agi_callingani2: 0
stdin:agi_callington: 0
stdin:agi_callingtns: 0
stdin:agi_dnid: 22222222
stdin:agi_rdnis: unknown
stdin:agi_context: incoming
stdin:agi_extension: 22222222
stdin:agi_priority: 1
stdin:agi_enhanced: 0.0
stdin:agi_accountcode:
stdin:agi_threadid: 140502522619648
stdin:agi_arg_1: 11111111111
stdin:agi_arg_2: SIP/siptrunk-00000081
agi result: 200 result=1

可以看到日志最后的那行记录 agi result: 200 result=1,是 AGI 脚本与 Asterisk 交互返回的结果,这点很重要,关系着拨号计划能否按照指定规则走下去,具体返回状态如下

Code Example result text
200 result=1
510 Invalid or unknown command
511 Command Not Permitted on a dead channel
520 End of proper usage

注意,在 write_log 方法中,写入的字符串,因此如果要把数组转为字符串需用 var_export($array, 1),注意一定得加上 1 参数,把数组转为字符串,否则会是个数组的,在执行 execute_agi 方法里的 fflush 时会把整个数组的字符串形式及命令直接传给 Asterisk,这时返回值便是 510 Invalid or unknown command。下面可以测试下

var_export([1,2,3,4,5]); echo 1; $stdout = fopen('php://stdout', 'w'); fflush($stdout);

执行打印的信息如下

array (
  0 => 1,
  1 => 2,
  2 => 3,
  3 => 4,
  4 => 5,
)1

猜你喜欢

转载自blog.csdn.net/molaifeng/article/details/81102906