[Asterisk-Dev] Asterisk 1.0.5 AGI bug, problem?
Moises Silva
moises.silva at gmail.com
Thu Mar 24 13:01:36 MST 2005
I have already put this message in the users list, but i think is
better here since has some implications with the version and the
Asterisk Code
i have a problem with AGI in Asterisk 1.0.5, the problem occurs either
with PHP or C AGI scripts/programs. Well, its simple,
either asterisk is not sending correctly the command responses to the
standard output, or for some unknown reason to me the
scripts/programs are not able to read it from standard input.
I have the next C test program for AGI:
#include <stdio.h>
main()
{
char line[80];
setlinebuf(stdout);
setlinebuf(stderr);
while (1)
{
fgets(line,80,stdin);
if ( strlen(line) <= 1 )
{
break;
}
}
printf("SAY NUMBER 55 \"\"\n");
fgets(line,80,stdin);
printf("SAY NUMBER 66 \"\"\n");
fgets(line,80,stdin);
}
I currently have 2 servers with Asterisk. The problematic one, as i
said is running Asterisk 1.0.5, the other server
is running Asterisk 1.0.0, and it ran the C test perfectly, the
problematic one just run the first command, never reach
the secondth command (SAY NUMBER 66).
I have a PHP test a little bit more meaningfull, because it says a
lot of things of what is going on, besides im PHP programmer
not C one, so i feel more comfortable with it. The test code is:
<?php
include_once '/var/www/localhost/htdocs/ivsadmin/apps/pavoz/classes/AgiTest.php';
$agi = new AgiTest();
die();
?>
i guess the code before doesnt say anything :p , the class AgiTest code is:
<?php
class AgiTest
{
private $read_bytes = 80;
private $asterisk_environment_variables = array();
private $log_stream = null;
public function __construct()
{
$this->log_stream = fopen('/var/log/pavoz/asterisk','w');
//reading asterisk initial variables and writing them to log
$this->ReceiveAsteriskEnvironmentVariables();
//now we try to execute a command, and track the point of error
$command = "SAY NUMBER 55 \"\"";
$this->ExecuteCommand($command);
$command = "SAY NUMBER 66 \"\"";
$this->ExecuteCommand($command);
return true;
}
public function __destruct()
{
fclose($this->log_stream);
}
private function WriteLog($Message)
{
return fwrite($this->log_stream, $Message."\n");
}
private function ReadStdin($Bytes = null)
{
$Bytes = $Bytes === null ? $this->read_bytes : $Bytes;
$this->WriteLog("\nReading {$Bytes} bytes response from Asterisk...");
$response = fgets(STDIN, $Bytes);
$this->WriteLog("Received response: {$response}");
return $response;
}
private function WriteStdout($String)
{
$escaped_string = str_replace("\n", '\n', $String);
$this->WriteLog("\nSending string {$escaped_string} to Asterisk...");
$bytes = fwrite(STDOUT, $String);
fflush(STDOUT);
$this->WriteLog("Wroten bytes to STDOUT: {$bytes}");
return $bytes;
}
private function ReceiveAsteriskEnvironmentVariables()
{
do
{
$asterisk_string = $this->ReadStdin();
if ( $asterisk_string != "\n" )
{
$delimiter_position =
strpos($asterisk_string,':');
$data_name =
substr($asterisk_string, 0, $delimiter_position);
$data_value =
substr($asterisk_string, $delimiter_position + 1);
$this->asterisk_environment_variables[$data_name] = trim($data_value);
}
} while ( $asterisk_string != "\n" );
return true;
}
public function GetAsteriskEnvironmentVariable($VariableName)
{
if ( array_key_exists($VariableName,$this->asterisk_environment_variables) )
{
return $this->asterisk_environment_variables[$VariableName];
}
else
{
return false;
}
}
public function ExecuteCommand($Command)
{
$Command .= "\n";
$bytes = $this->WriteStdout($Command);
$response = $this->ReadStdin();
return $response;
}
}
?>
As you can see, the test is exactly the same, in fact, the output to
the asterisk console is the same, but here i can log the communication
between Asterisk and my PHP script. The log output in the file defined
in the script is:
Reading 80 bytes response from Asterisk...
Received response: agi_request: agi_cdr.php
Reading 80 bytes response from Asterisk...
Received response: agi_channel: SIP/12-d91b
Reading 80 bytes response from Asterisk...
Received response: agi_language: en
Reading 80 bytes response from Asterisk...
Received response: agi_type: SIP
Reading 80 bytes response from Asterisk...
Received response: agi_uniqueid: 1111659738.1
Reading 80 bytes response from Asterisk...
Received response: agi_callerid: "Moises Silva" <12>
Reading 80 bytes response from Asterisk...
Received response: agi_dnid: 10
Reading 80 bytes response from Asterisk...
Received response: agi_rdnis: unknown
Reading 80 bytes response from Asterisk...
Received response: agi_context: macro-root
Reading 80 bytes response from Asterisk...
Received response: agi_extension: s
Reading 80 bytes response from Asterisk...
Received response: agi_priority: 4
Reading 80 bytes response from Asterisk...
Received response: agi_enhanced: 0.0
Reading 80 bytes response from Asterisk...
Received response: agi_accountcode:
Reading 80 bytes response from Asterisk...
Received response:
Sending string SAY NUMBER 55 ""\n to Asterisk...
Wroten bytes to STDOUT: 17
Reading 80 bytes response from Asterisk...
Received response:
Sending string SAY NUMBER 66 ""\n to Asterisk...
Wroten bytes to STDOUT: 0
Reading 80 bytes response from Asterisk...
Received response:
As we can see, the initial data is received well by the script, but,
after executing a command, is not possible to read the response. But
even worse, the script hangs until i hangup the phone. It stays in the
same point, the line where i attempt to read with fread(); the
response from Asterisk.
this is the output with the same script in the server that is running correctly
Reading 80 bytes response from Asterisk...
Received response: agi_request: agi_test.php
Reading 80 bytes response from Asterisk...
Received response: agi_channel: SIP/13-b3d1
Reading 80 bytes response from Asterisk...
Received response: agi_language: en
Reading 80 bytes response from Asterisk...
Received response: agi_type: SIP
Reading 80 bytes response from Asterisk...
Received response: agi_uniqueid: 1111686414.65
Reading 80 bytes response from Asterisk...
Received response: agi_callerid: "Andrew" <13>
Reading 80 bytes response from Asterisk...
Received response: agi_dnid: 21
Reading 80 bytes response from Asterisk...
Received response: agi_rdnis: unknown
Reading 80 bytes response from Asterisk...
Received response: agi_context: macro-root
Reading 80 bytes response from Asterisk...
Received response: agi_extension: s
Reading 80 bytes response from Asterisk...
Received response: agi_priority: 4
Reading 80 bytes response from Asterisk...
Received response: agi_enhanced: 0.0
Reading 80 bytes response from Asterisk...
Received response: agi_accountcode:
Reading 80 bytes response from Asterisk...
Received response:
Sending string SAY NUMBER 55 ""\n to Asterisk...
Wroten bytes to STDOUT: 17
Reading 80 bytes response from Asterisk...
Received response: 200 result=0
Sending string SAY NUMBER 66 ""\n to Asterisk...
Wroten bytes to STDOUT: 17
Reading 80 bytes response from Asterisk...
Received response: 200 result=0
I was tired of looking for errors in the script, but the fact that the
script in PHP and the C test program runs perfectly in the other
server is very annoying :( , So, i started to look out in the Asterisk
C code. I checked out mainly the file res/agi_res.c
well, once here i checked the function 'static void setup_env' that
function sends the initial environment variables, uses
the function fdprintf, that appears to be a redefinition of
printf_to_agi_result_buffer function,to send data to the AGI script.
I assume that since i receive correctly the initial data, then the
function fdprintf works fine. Then i checked out the function
that handles the command SAY_NUMBER, this function is called
handle_saynumber, i put some extra ast_log warnings to verify that the
function is doing all well, and in effect, it does.
The output in the asterisk console when i try to execute the agi_script is:
-- Executing Macro("SIP/12-dec6", "root|sipextens") in new stack
-- Executing GotoIf("SIP/12-dec6", "1 ? 2 : 5") in new stack
-- Goto (macro-root,s,2)
-- Executing SetVar("SIP/12-dec6", "dialed=10") in new stack
-- Executing SetVar("SIP/12-dec6", "authtype=sipextens") in new stack
-- Executing AGI("SIP/12-dec6", "agi_cdr.php") in new stack
-- Launched AGI Script /var/lib/asterisk/agi-bin/agi_cdr.php
Mar 24 05:06:18 WARNING[2911]: res_agi.c:376
printf_to_agi_result_buffer: Valid buffer!
Mar 24 05:06:18 WARNING[2911]: res_agi.c:376
printf_to_agi_result_buffer: Valid buffer!
Mar 24 05:06:18 WARNING[2911]: res_agi.c:376
printf_to_agi_result_buffer: Valid buffer!
Mar 24 05:06:18 WARNING[2911]: res_agi.c:376
printf_to_agi_result_buffer: Valid buffer!
Mar 24 05:06:18 WARNING[2911]: res_agi.c:376
printf_to_agi_result_buffer: Valid buffer!
Mar 24 05:06:18 WARNING[2911]: res_agi.c:376
printf_to_agi_result_buffer: Valid buffer!
Mar 24 05:06:18 WARNING[2911]: res_agi.c:376
printf_to_agi_result_buffer: Valid buffer!
Mar 24 05:06:18 WARNING[2911]: res_agi.c:376
printf_to_agi_result_buffer: Valid buffer!
Mar 24 05:06:18 WARNING[2911]: res_agi.c:376
printf_to_agi_result_buffer: Valid buffer!
Mar 24 05:06:18 WARNING[2911]: res_agi.c:376
printf_to_agi_result_buffer: Valid buffer!
Mar 24 05:06:18 WARNING[2911]: res_agi.c:376
printf_to_agi_result_buffer: Valid buffer!
Mar 24 05:06:18 WARNING[2911]: res_agi.c:376
printf_to_agi_result_buffer: Valid buffer!
Mar 24 05:06:18 WARNING[2911]: res_agi.c:376
printf_to_agi_result_buffer: Valid buffer!
Mar 24 05:06:18 WARNING[2911]: res_agi.c:376
printf_to_agi_result_buffer: Valid buffer!
Mar 24 05:06:18 WARNING[2911]: res_agi.c:579 handle_saynumber:
Entering function handle_saynumber!
Mar 24 05:06:18 WARNING[2911]: res_agi.c:586 handle_saynumber: About
to execute ast_say_number_full function!
-- Playing 'digits/50' (language 'en')
-- Playing 'digits/5' (language 'en')
Mar 24 05:06:20 WARNING[2911]: res_agi.c:588 handle_saynumber:
Executed function, return value is 0!
Mar 24 05:06:20 WARNING[2911]: res_agi.c:591 handle_saynumber:
returning value to AGI with fdprintf!
Mar 24 05:06:20 WARNING[2911]: res_agi.c:376
printf_to_agi_result_buffer: Valid buffer!
Mar 24 05:06:20 WARNING[2911]: res_agi.c:594 handle_saynumber:
returning succes to asterisk!
after i hangup the call then:
== Spawn extension (macro-root, s, 4) exited non-zero on
'SIP/12-dec6' in macro 'root'
== Spawn extension (localplans.some, 10, 1) exited non-zero on 'SIP/12-dec6'
the warnings are messages set by me to check that the buffer where
asterisk is written are valid and
some other info inside the handle_saynumber function.
The information of the Servers and the software installed in them is:
Server Running Correctly:
Gnu/Linux Distro: Gentoo
uname: Linux intervoip1 2.6.9-ivsol1 #2 Thu Nov 25 08:25:32 CST 2004
i686 Intel(R) Pentium(R) 4 CPU 2.40GHz GenuineIntel GNU/Linux
Compiler: GCC Version 3.4.3
Glibc: Version 2.3.4.20041021
Asterisk: Version 1.0.0
Server Running With Bugs:
Gnu/Linux Distro: Gentoo
uname: Linux hq 2.6.9-ivsol1 #1 Fri Nov 19 22:37:46 CST 2004 i686 AMD
Athlon(tm) XP 2400+ AuthenticAMD GNU/Linux
Gcc: Version 3.4.3
Glibc: Version 2.3.4.20041102
Asterisk: Version 1.0.5
The main difference is the Asterisk version and the Glibc version.
I appreciate any help with this. Sorry if i omit information that may
be important, but that was all i thought it was.
More information about the asterisk-dev
mailing list