La Livebox d'Orange comporte, outre les connexions réseau et Wi-Fi habituelles, une prise FXS à l'arrière conçue pour y brancher un téléphone analogique. Comme je le disais auparavant, il s'agit là d'une des manières les plus simples d'exploiter la ligne fixe fournie avec toute connexion Internet Orange.
Sur la prise FXS et lorsque la Livebox détecte un problème sur la ligne téléphonique, elle substitue à la tonalité un message en boucle comme : « Un problème a été détecté sur votre ligne téléphonique. Veuillez redémarrer la Livebox. Si le problème persiste, veuillez contacter le service client Orange ». Puis la tonalité classique revient lorsque la ligne est à nouveau opérationnelle.
Seulement, dans certaines circonstances, cela allait de pair avec des sonneries intempestives : la première lorsque la ligne était en dérangement et la seconde lorsque le problème disparaissait. De plus, il s’agissait souvent de problèmes transitoires pendant que la Livebox se resynchronisait en PPPoE. Par conséquent, j’ai régulièrement été réveillé à 3 h du matin par cette box.
Étant donné, de plus, que j'avais déjà mis en œuvre Asterisk chez moi et que je supervisais déjà moi-même l'état des services Orange avec Icinga, je considérais donc que je disposais des outils pour filtrer ces sonneries intempestives. Ce billet propose donc de vous montrer comment j'ai fait.
L’idée
Ces sonneries intempestives prennent la forme d’appels anonymes et surviennent seulement lorsque la box considère que la ligne téléphonique est en dérangement. L’idée est donc de programmer Asterisk pour reconnaître ces deux caractéristiques.
Reconnaître un appel masqué dans Asterisk est facile. Déterminer la disponibilité du téléphone du point de vue de la Livebox est en revanche une autre histoire. Heureusement, mes scripts Nagios pour la Livebox remplissent exactement cette fonction ; il est donc possible de l’utiliser dans mon test. Nous allons également nous aider de l’interface AGI pour réaliser ce test.
Le script AGI
AGI, ou Asterisk Gateway Interface, est en effet une interface pour faire
exécuter des scripts par Asterisk. Ces scripts accomplissent des tâches
impossibles ou trop fastidieuses à mettre en œuvre via extensions.conf
ou
extensions.ael
. Le principe est le même que celui de l’interface CGI dans
le monde du Web : on peut utiliser n’importe quel langage de
programmation (C, Perl, Python…) du moment qu’on puisse écrire sur
stdout, lire sur stdin, accepter des arguments de ligne de commande et que le
fichier soit exécutable.
Les scripts AGI doivent être placés dans un répertoire spécifique qui dépend de votre
installation Asterisk. Sous FreeBSD, il faut les placer dans
/usr/local/share/asterisk/agi-bin
et les rendre exécutables avec la commande
chmod +x
. J’ai appelé ce script stfu-livebox.agi
. Voici son code source :
#!/usr/bin/env perl
use strict;
use warnings;
$| = 1;
use Asterisk::AGI;
use LWP::UserAgent;
my $AGI = new Asterisk::AGI;
my %input = $AGI->ReadParse();
my $replacement_name = $ARGV[0];
my $replacement_number = $ARGV[1];
$replacement_name ||= 'Livebox';
$replacement_number ||= 'Livebox';
$AGI->verbose("Run stfu-livebox.agi", 1);
sub is_trunk_alive {
my $ret = system('/usr/local/libexec/nagios/check_livebox_phone', '-H', '192.168.1.1');
$ret >>= 8;
return ($ret == 0);
}
sub is_anon {
return ($input{'callerid'} eq 'unknown');
}
sub main {
if (is_anon() && !is_trunk_alive()) {
$AGI->set_variable('CALLERID(name)', $replacement_name);
$AGI->set_variable('CALLERID(name-pres)', 'allowed_not_screened');
$AGI->set_variable('CALLERID(number)', $replacement_number);
$AGI->set_variable('CALLERID(num-pres)', 'allowed_not_screened');
}
}
main();
Le principe du script est le suivant : à chaque appel anonyme, il exécute le plugin Nagios check_livebox_phone, qui détermine l’état de la ligne téléphonique vue par la Livebox. Si la ligne est hors service, il positionne un numéro et un nom spécifiques.
Le nom et le numéro présentés sont « Livebox » par défaut, mais il est possible d’utiliser autre chose. Par exemple, sur mon installation, je lui fais présenter un numéro qui a peu de chances de m’appeler depuis l’extérieur : mon propre numéro.
Intégration dans le dialplan d’Asterisk
Maintenant que nous avons le script AGI, il ne reste plus qu’à l’appeler depuis
le dialplan d’Asterisk au moyen de l’application AGI
:
AGI(stfu-livebox.agi,Livebox,0199998765);
Il suffit ensuite de préparer le reste du dialplan, et notamment les instructions qui bloquent ces sonneries la nuit. Dans mon installation, j’en ai profité pour renvoyer les appels masqués immédiatement vers la messagerie vocale entre 23 h et 6 h et de complètement bloquer ces sonneries si elles proviennent de la Livebox durant cette même plage horaire. En AEL, cela donne :
Set(ALLOW_RINGING=1);
Set(ALLOW_VOICEMAIL=1);
// Traitement spécifique pour les appels anonymes
if ("${LEN(${CALLERID(number)})}" = "0") {
Set(CALLERID(name-pres)=unavailable);
Set(CALLERID(num-pres)=unavailable);
AGI(stfu-livebox.agi,Livebox,0199998765);
// Autoriser les appels anonymes de 6 h à 23 h seulement
ifTime(06:00-22:59|*|*|*) {
Verbose(1,Appel masqué autorisé le jour);
} else {
Set(ALLOW_RINGING=0);
if ("${CALLERID(name)}" = "Livebox") {
Verbose(1,Sonnerie de la Livebox refusée la nuit);
Set(ALLOW_VOICEMAIL=0);
} else {
Verbose(1,Appel masqué la nuit, renvoi vers répondeur);
}
}
} else {
// Continuer normalement
}
// Faire sonner tous les téléphones
if ("${ALLOW_RINGING}" = "1") {
Dial(${ALL_PHONES},25,xt);
}
// Si non-réponse ou rejeté, rediriger vers le répondeur
if ("${ALLOW_VOICEMAIL}" = "1") {
Answer();
VoiceMail(BoiteCommune);
} else {
Hangup(21);
}
Hangup();
Vous remarquerez que j’utilise deux variables, ALLOW_RINGING
pour déterminer
si l’appel entrant peut accéder aux téléphones chez moi (c’est-à-dire les
faire sonner) et ALLOW_VOICEMAIL
pour déterminer si l’appelant peut
enregistrer un message vocal. Ceci permet de gérer facilement les trois cas
qui se présentent à nous dans ce dialplan.
Conclusion
Ces modifications à Asterisk font exactement ce que je voulais, c’est-à-dire ne plus être réveillé la nuit lorsque la Livebox se resynchronise. En pratique, seule la première des deux sonneries intempestives est effectivement filtrée : au moment où survient la seconde sonnerie, le script check_livebox_phone indique que la ligne téléphonique est à nouveau opérationnelle.
J’aurais pu résoudre ce problème en apportant une petite modification : lorsqu’Asterisk bloque la première de ces deux sonneries, qui est facile à reconnaître, on pourrait positionner une valeur dans la base de données AstDB pour bloquer l’appel anonyme qui suit immédiatement cette première sonnerie.
Mais en pratique, depuis qu’Orange a cessé d’utiliser PPPoE, ces resynchronisations hebdomadaires n’arrivent quasiment plus jamais, donc c’est plus difficile à tester.
Enfin, en cherchant un peu, ma solution était peut-être complètement excessive : d’après une poignée de forums, ces sonneries intempestives seraient dues à la notification visuelle de messages ; une fonction qui est seulement prise en charge par certains téléphones (mais pas Asterisk) et que je suis sûr de ne pas utiliser, parce que mon répondeur est déjà géré par Asterisk. Cela reste néanmoins un bon exercice de programmation AGI que je souhaitais partager.
Commentaires
Poster un commentaire
question
je connais un serveur qui détermine si le numéro d'appelant est du spam ou non. C'est possible de faire le même script agi qui interroge ce serveur? http://api.katia.ch/v1/open/check/00325235554545
★ x0r
Intéressant, je ne connaissais pas cette solution d’« antispam ».
Sur leur page d’accueil ils proposent justement une intégration de leur solution d’« antispam » téléphonique sous Asterisk, mais impossible d’avoir plus d’informations sans les contacter par e-mail. Dans tous les cas, un script AGI qui interrogerait l’API dont vous parlez serait alors relativement facile dans un langage comme Perl.
ly
Je tombe sur cette page, ayant fait un tel système reposant sur un bon vieux modem 56k USB capable de décoder le caller ID. Un service écrit en python accroché sur le serial-usb du modem récupère cela et si pas un utilisateur dans l'annuaire du téléphone accroché en DECT à la livebox (auquel cas le champ NAME du CID est rempli, ce qui permet de gérer les connaissances facilement), je teste selon une blacklist perso (qui permet en plus de filtrer des plages entières de numéros, avec des chiffres de fin variables, souvent vues) en ligne... et au besoin, le modem décroche et raccroche dès la 1ère sonnerie.
Je découvre cette api katia.ch, qui retourne en prime du JSON. Par contre, il y a des quotas un jeu juste niveau journalier... puis tous les numéros que j'essaie on le champ isspam à 1!!?? Les temps de réponse semblent également un peu longs (ca risque de sonner plus longuement avant de filter).
Bizarre.
Actuellement, j'utilise pour ma part: http://www.doisjerepondre.fr/numero-de-telephone/NMBR
avec NMBR = numéro à tester.
Cela marche pas trop mal, mais leur blacklist semble limitée d'une part et en prime il faut parser le 'score' du numéro (et filtrer s'il prends la valeur 'negative') dans le html.
Même si avec python et le module beautifulsoup cela se fait bien, en cas de changement de la page cela risque de ne plus fonctionner.
Au final, aviez vous utilisé katia?
★ x0r
Non, pour le moment je touche du bois et je n’ai pas encore ressenti le besoin de mettre en œuvre un filtrage d’appels de ce genre, donc je n’ai pas encore testé Katia.
Poster un commentaire