Filtre d'appel téléphonique

11/2011 : j'ai décidé de mettre un terme aux appels téléphoniques publicitaires sur la ligne fixe reliée à la Freebox.

L'idée est qu'un fax décroche le téléphone lorsqu'un numéro masqué appelle et commence une négociation de transmission (tîîîîîî, tûûûûû….). Ainsi les centrales d'appels automatiques détecteront la porteuse du fax et croiront s'être trompées de numéro de téléphone et me rayeront de leurs listes.

Pour se faire, j'ai utilisé un modem configuré en fax et branché sur la sortie téléphonique de la Freebox et en USB sur le serveur. J'ai acheté un modem 56k sur port USB sur un site d'enchères en ligne basé sur un chipset Conexant.

Modem Conexant

Il est automatiquement reconnu par le noyau via le module cdc_acm :

[16675142.359247] usb 1-1: new full-speed USB device number 64 using xhci_hcd
[16675144.974442] usb 1-1: New USB device found, idVendor=0572, idProduct=1329
[16675144.974469] usb 1-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[16675144.974485] usb 1-1: Product: USB Modem
[16675144.974499] usb 1-1: Manufacturer: Conexant
[16675144.974513] usb 1-1: SerialNumber: 24680246
[16675144.977464] cdc_acm 1-1:1.0: ttyACM0: USB ACM device

Le modem branché est reconnu sur /dev/ttyACM0 :

ls -l /dev/ttyACM0
crw-rw---- 1 root dialout 166, 0 Feb 19 00:32 /dev/ttyACM0

Comme l'indique la commande précédente, il faut ajouter l'utilisateur courant au groupe dialout pour pouvoir utiliser ce périphérique.

sudo usermod -a -G dialout <user>

Il est possible d'ajouter une règle udev pour fixer le nom /dev/ttyModem :

/etc/udev/rules.d/10-tty-acm.rules
SUBSYSTEMS=="usb", ATTRS{idVendor}=="0572", ATTRS{idProduct}=="1329",  SYMLINK+="ttyModem"

Après avoir créer ce fichier, il faut recharger les règles :

sudo udevadm control --reload-rules

En deconnectant et reconnectant le modem, cela donne :

ls -l /dev/ttyModem
lrwxrwxrwx 1 root root 7 Feb 19 11:01 /dev/ttyModem -> ttyACM0

Pour vérifier si le port fonctionnel :

sudo stty < /dev/ttyModem
speed 38400 baud; line = 0;
min = 1; time = 0;
-brkint -icrnl -imaxbel
-opost -onlcr
-isig -icanon -iexten -echo -echoe -echok -echoctl -echoke

Pour tester le modem, il faut se connecter avec cu ou minicom et lui envoyer quelques commandes Hayes ou AT AT, ATI0 (ou ATI), ATI1, ATI2, ATI3. La première commande retourne juste OK et les suivantes permettent de récupérer des informations techniques :

cu -l ttyModem
Connected.
AT
OK
ATI
56000
OK
ATI1
OK
ATI2
OK
ATI3
CX93001-EIS_V0.2002-V92

Note : faire ~. pour quitter cu

Le modem nous indique ici sa vitesse ainsi que le nom du chipset et la version du firmware.

Pour utiliser conjointement ce système et le téléphone fixe, j'ai ajouté un dédoubleur RJ11 entre la sortie de la Freebox et le modem, cela me permet de relier le téléphone fixe, le modem ainsi que la sortie téléphone de la freebox.

Dédoubleur RJ11

Voici le shéma de montage de l'ensemble :

Branchement du modem

Lorsque le téléphone sonne, le modem reçoit la notification d'appel. Avec la freebox, le numéro de l'appelant (ou Caller ID, CID) est transmis lors de la 2e sonnerie.

mgetty est utilisé pour configurer le modem pour qu'il écoute en permanence.

/etc/mgetty/mgetty.config
port ttyModem
  debug 4
  speed 38400
  rings 2
  post-init-chat "" AT+VCID=1 OK
  cnd-program /usr/local/bin/repondeur.sh

Configuration du lancement de mgetty

/etc/inittab
...
T3:23:respawn:/sbin/mgetty /dev/ttyModem

Rechargement du fichier de configuration d' init :

sudo init q

Pour vérifier le bon paramétrage, il faut consulter les logs de mgetty présents dans /var/log/mgetty/mg_ttyModem.log :

/var/log/mgetty/mg_ttyModem.log
02/26 15:00:44 dem  mgetty: interim release 1.1.36-Jun15
02/26 15:00:44 dem  check for lockfiles
02/26 15:00:44 dem  locking the line
02/26 15:00:45 dem  WARNING: DSR is off - modem turned off or bad cable?
02/26 15:00:45 dem  lowering DTR to reset Modem
02/26 15:00:46 dem  send: \dATQ0V1H0[0d]
02/26 15:00:46 dem  waiting for ``OK'' ** found **
02/26 15:00:46 dem  send: AT[0d]
02/26 15:00:46 dem  waiting for ``OK'' ** found **
02/26 15:00:46 dem  mdm_send: 'ATI'
02/26 15:00:46 dem  Generic Rockwell modem (56000)
02/26 15:00:46 dem  mdm_send: 'ATI3'
02/26 15:00:46 dem  mdm_send: 'ATI4'
02/26 15:00:46 dem  additional info: ''
02/26 15:00:46 dem  modem quirks: 0004
02/26 15:00:46 dem  mdm_send: 'AT+FCLASS=2' -> ERROR
02/26 15:00:46 dem  mdm_send: 'AT+FCLASS=2.0' -> ERROR
02/26 15:00:46 dem  mdm_send: 'AT+FCLASS=2' -> ERROR
02/26 15:00:46 dem  send: AT+VCID=1[0d]
02/26 15:00:46 dem  waiting for ``OK'' ** found **

Lorsqu'un appel arrive, le script shell /usr/local/bin/repondeur.sh est lancé et reçoit en argument le chemin du périphérique du modem, le numéro de l'appelant et son nom, ce comportement est natif à mgetty.

  • Si le numéro est masqué, la freebox transmet alors O (lettre “o” en majuscule), le script /usr/local/bin/decroche.sh est lancé en tâche de fond et le script sort avec le code retour à 0.
  • Si le numéro de téléphone transmis en 2e argument est différent de O, alors il s'agit d'un appel non masqué et le script sortira avec le code retour à 1 pour que mgetty ne décroche pas.
/usr/local/bin/repondeur.sh
#!/bin/sh
NOW="$(date +"%d-%m-%Y %T")"
TTY="$1"
NUMBER="$2"
NAME="$3"
 
LOG=/var/log/repondeur/appel.log
 
# log
echo "Appel entrant le $NOW de '$NAME' ($NUMBER) sur '$TTY'" >> $LOG
 
if [ "$NUMBER" = "O" ]
then
    echo "Appel filtré" >> $LOG
    nohup /usr/local/bin/decroche.sh $TTY &
    # exit 0 pour que minicom décroche, le script lancé précédemment va raccrocher la ligne 
    exit 0
else
    # sort en erreur pour que mgetty ne décroche pas
    exit 1
fi

Le fichier de log /var/log/repondeur/appel.log est enrichi à chaque appel avec la date de l'appel suivi du numéro de téléphone ou de l'indication que l'appel a été filtré.

Ne pas oublier de créer le dossier et de lui affecter les bon droits :

sudo mkdir /var/log/repondeur/ && sudo chown -R root:dialout /var/log/repondeur/

Le script /usr/local/bin/decroche.sh exécute un ensemble de commandes AT avec minicom indiquant au modem de décrocher, d'envoyer une porteuse de fax puis de raccrocher au bout de 3 secondes :

/usr/local/bin/decroche.sh
#/bin/bash
 
PID=$$
FILE=/tmp/minicom.$PID
DEVICE=/dev/$1
 
echo 'send ATZ
expect {
"OK"
}
send AT+FCLASS=1
expect {
"OK"
}
send ATH1
expect {
"OK"
}
send ATH0
expect {
"OK"
}
send ATZ
expect {
"OK"
}
sleep 3
 
! killall minicom' > $FILE
 
/usr/bin/minicom -D $DEVICE -S $FILE
rm -f $FILE

Pour tester l'ensemble, il faut appeler le téléphone fixe avec un téléphone portable par exemple et consulter les logs.

Cas avec un appel “normal”, numéro non masqué :

02/26 15:00:47 dem  waiting...

02/26 15:03:28 dem  wfr: waiting for ``RING''
02/26 15:03:28 dem  wfr: waiting for ``RING''
02/26 15:03:32 ##### denied caller dev=ttyModem, pid=14263, caller='XXXXXXXXXX'

Note : XXXXXXXXXX est le numéro de téléphone effectivement transmis et reconnu par mgetty

Le message d'erreur ##### denied caller est issue de la sortie en erreur du script /usr/local/bin/repondeur.sh qui a bien detecté un numéro de téléphone valide.

Lors d'un appel avec un numéro masqué, les logs sont de la forme suivante :

02/26 15:22:06 dem  waiting...
02/26 15:22:41 dem  wfr: waiting for ``RING''
02/26 15:22:41 dem  wfr: waiting for ``RING''
02/26 15:22:42 dem  send: ATA[0d]
02/26 15:22:42 dem  waiting for ``CONNECT''
02/26 15:23:35 dem  found action string: ``NO CARRIER''
02/26 15:23:35 ##### failed A_FAIL dev=ttyModem, pid=14263, caller='O', conn='', name=''

La trace send: ATA[0d] indique la transmission de la porteuse d'initialisation du fax.

De plus le fichier /var/log/repondeur/appel.log est enrichit avec les traces des appels :

Appel entrant le 26-02-2017 15:21:53 de '' (XXXXXXXXXX)
Appel entrant le 26-02-2017 15:22:42 de '' (O)
Appel filtré

Finalement, à chaque appel anonyme, le modem décroche et émet une porteuse de fax. Si c'est une centrale d'appel automatique, elle pense que c'est un fax et ne me rappelle plus, je ne suis donc plus embêté =). La fréquence d'appel anonyme a chuté drastiquement.

Une évolution simple serait d'ajouter un filtrage sur numéro, les centres d'appels masquant de moins en moins leurs numéros…