Je cherche à ecrire un script Perl se connectant au manager API d'Asterisk. On s'y connecte "humainement" avet un simple telnet sur le port 5038. Ensuite on peut envoyer des commandes à Asterisk qui se présentent sous cette forme:
action: login\n
username: office\n
secret: welcome\n
\n
et lui même nous envoie des élément de la même forme:
Event: PeerStatus
Privilege: system,all
Peer: SIP/103
PeerStatus: Registered
Mon but est de me coonecter à cet API et évidemment de pouvoir envoyer et recevoir ces différents bloc. J'ai commencé par utiliser une connexion Telnet:
#!/usr/bin/perl -w
use Net::Telnet ();
#Variables de connexion
$USER='offi';
$SECRET='*****';
$SERVER_IP='10.0.0.1';
#initialisation de la connection Telnet au manager d asterisk
$tn = new Net::Telnet (
Port => 5038,
Prompt => '/.*[\$%#>] $/',
Output_record_separator => '',
Errmode => 'return',
Telnetmode => 'off'
);
sub connectAM{
#connection
$tn->open("$SERVER_IP");
$tn->waitfor('/0\n$/');
#log
$tn->print("Action: Login\nUsername: $USER\nSecret: $SECRET\n\n");
$tn->waitfor('/Authentication accept*/')
or die "Asterisk Manager Interface login failed, verify username and password: ", $tn->lastline;
}
sub deconnectAM{
$tn->print("Action: Logoff\n\n");
}
sub listeExten{
$tn->print("Action: command\ncommand: sip show peers\n\n");
@z = $tn->getlines(Timeout => 2);
for($i=0;$i<$#z;$i++){
print "$z[$i]\n";
}
#print "$e\n";
}
connectAM();
print "Connexion effectuee\n";
listeExten();
deconnectAM();
J'arrive à créer la connection et à me logger malheuresement je n'arrive pas à récupérer le contenu du buffer Telnet. En désespoir de cause je me suis tourné ver les sockets pour essayer de résoudre mon problème (solution qui a maintenant techniquement ma préférence). J'arrive bien à me connecter sur le port car je récupère le message d'accueil. Mais manifestement je n'arrive pas à envoyer de données sur le socket car ensuite je ne récupère jamais rien :'(
#!/usr/bin/perl -w
use LWP::Socket;
$socket = new LWP::Socket;
$socket->connect('10.0.0.1', 5038); # echo
$socket->read(\$buffer);
print \$buffer."\n";
$quote = "action: login\nusername: office\nsecret: welcome\n\n";
$socket->write($quote);
$socket->read(\$buf);
print $buf."\n";
$socket = undef; # close
J'ai bien sûr testé avec IO::Socket et IO::Socket::INET mais même résultat... :(
Pour résumer voici ce que j'aimerais faire:
- Une connection par Socket qui ecoute tout ce que renvoie l'API d'Asterisk (dans le but de stocker dans mysql), et qui nécessite une d'abord une authentification, donc envoie de données (action: login\n ....).
- Une connection Telnet qui me servirais uniquement à envoyer des commandes (ça j'y arrive déjà)...
Pour info je programme depuis plusieurs années mais j'ai commencé le Perl cette semaine :) . Mon code est donc sans aucun doute améliorable.
Les modules IO::Pty et POE::Component::Client::Asterisk::Manager m'ont semblé intéressant mais je n'y ai pas capté grand chose
Merci d'avance,
Gorby
# La solution pour le TCP
Posté par Flavien . Évalué à 1.
#!/usr/bin/perl
use IO::Socket::INET ;
my $EOL = "\015\012";
my $BLANK = $EOL x 2;
my $socket = IO::Socket::INET -> new (
PeerAddr => '10.0.0.1' ,
PeerPort => 5038 ,
Proto => 'tcp' ,
Type => SOCK_STREAM
);
$socket->autoflush(1);
$socket -> recv ( $message , 128 ) ;
print $message ;
print $socket "Action: Login${EOL}Username: offi${EOL}Secret: *****$BLANK";
while(1){
$socket -> recv ( $message , 128 ) ;
print $message ;
}
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.