[asterisk-users] utils.c: fwrite() returned error: Broken pipe how to solve it ???

Tony Mountifield tony at softins.co.uk
Thu Oct 10 06:01:06 CDT 2013


In article <CAE6_NE+DxtsGAdTg0Mp-9JUMnGXGuwo4eXAdM_HrwC8oPUOsew at mail.gmail.com>,
akhilesh chand <omakhileshchand at gmail.com> wrote:
> 
> I want to make call through socket i have set code given below:
> 
> #!/usr/bin/perl -w
> 
> use IO::Socket::INET;
> 
> 
> sub asterisk_command ()
>         {
>         #  my $command=$_[0];
>         my
> $ami=IO::Socket::INET->new(PeerAddr=>'127.0.0.1',PeerPort=>5038,Proto=>'tcp')
> or die "failed to connect to AMI!";
>         print $ami "Action: Login\r\nUsername: lite\r\nSecret:
> 4003\r\n\r\nAction: Logoff\r\n\r\n";
>         }
> &asterisk_command("Channel: DAHDI/27/7702009896\r\nExten: s\r\nContext:
> outbound\r\nCallerID: 20048645\r\nPriority: 1\r\nMaxRetries: 2\r\n");
> 
> Whenever i execute that code i'm get following error
> 
> [Oct 10 15:13:23] ERROR[856]: utils.c:1175 ast_careful_fwrite: fwrite()
> returned error: Broken pipe
> [Oct 10 15:13:23] ERROR[856]: utils.c:1175 ast_careful_fwrite: fwrite()
> returned error: Broken pipe
> [Oct 10 15:13:23] ERROR[856]: utils.c:1175 ast_careful_fwrite: fwrite()
> returned error: Broken pipe
> [Oct 10 15:13:23] ERROR[856]: utils.c:1175 ast_careful_fwrite: fwrite()
> returned error: Broken pipe
> 
> 
> asterisk verison :-  1.6.2.7
> CentOS release 5.3
> kernel version :- 2.6.18-128.el5

AMI is a *two-way* protocol. You mustn't just fire in a bunch of commands
and close the socket!

The reason Asterisk reports the fwrite() error is because you have closed
the socket before it had a chance to send you the responses.

What you need to do is this:

1. Connect to the AMI port.
2. Read the one-line greeting message that Asterisk sends you. It will tell
   you the version of the protocol (which might be of interest if you wanted
   to be compatible with different versions of Asterisk).
3. Send the Login action with username, secret and terminating blank line.
4. Read the response lines from Asterisk until it gives you a blank line.
5. Send whatever command you want it to do, and go back to step 4.
6. When you have done the commands you want, send the Logoff action.
7. *** READ THE RESPONSE TO THE LOGOFF
8. Close the socket.

If it helps. Here is similar piece of code I wrote to query pri spans.
Note carefully the setting of $/ in two places, and the inclusion of
"Events: off" to avoid responses getting confused by asynchronous events.

==================================================================
#!/usr/bin/perl

use IO::Socket;

my $numspans = 4;
my $host = 'localhost';
my $login = "Action: login\r\nUsername: xxxx\r\nSecret: yyyy\r\nEvents: off\r\n\r\n";

$/ = "\r\n";	# <> reads a single line for signon banner

my $s = IO::Socket::INET->new("$host:5038") or die "can't connect to $host: $!\n";
my $banner = <$s>;	# read the banner

#my $line = ('-' x 78)."\n";
#print $banner,$line;

$/ = "\r\n\r\n";	# <> reads a complete response ending in a blank line

print $s $login;
my $resp = <$s>;

#print $resp,$line;

my @spans;

foreach $span (1..$numspans) {
        print $s "Action: Command\r\nCommand: pri show span $span\r\n\r\n";
        $resp = <$s>;
        #print $resp,$line;

        if ($resp =~ /Status: (.*)\n/) {
                $status = $1;
        } else {
                $status = 'Unknown';
        }
        $spans[$span-1] = "Span $span status = $status\n";
}

print $s "Action: Logoff\r\n\r\n";
$resp = <$s>;
#print $resp,$line;

close $s;

# go on to display the results from @spans
==================================================================

Cheers
Tony

-- 
Tony Mountifield
Work: tony at softins.co.uk - http://www.softins.co.uk
Play: tony at mountifield.org - http://tony.mountifield.org



More information about the asterisk-users mailing list