Retrouvez cet article dans : Linux Magazine 86
Dans un précédent numéro de GLMF, nous vous avions proposé de rendre vos serveurs plus communicants en leur permettant l’accès à un téléphone mobile pour l’envoi et la réception de SMS. La solution proposée dispose d’une extension logicielle facilitant l’utilisation en production.
Rappel
De nombreux téléphones mobiles GSM/GPRS/3G permettent une connexion à un ordinateur. Ainsi, la machine peut prendre le contrôle du téléphone pour " passer des coups de fil " ou utiliser des services d’envoi de SMS ou MMS. Du moins, en théorie, car aucun logiciel ne semble proposer de solution MMS pour l’instant.
Des adaptateurs mobiles PCMCIA, comme la carte Vodafone 3G/GPRS, permettent de faire de même, offrant ainsi une solution intégrable facilement dans un ordinateur portable. Il s’agit en fait d’un modem mobile, comme il en existe beaucoup pour l’analogique.
La plupart de ces périphériques peuvent être commandés via un jeu de commandes Hayes assez similaire à ceux que l’on trouve pour les modems. D’autres mobiles, comme ceux fabriqués par Nokia, disposent de leur propre langage, mais la popularité de la marque auprès des fournisseurs de téléphonie mobile et des utilisateurs a motivé le développement de solutions.
La connexion de l’appareil avec le PC (ou le Mac) peut se faire via plusieurs méthodes en fonction des caractéristiques du téléphone :
- Le port série. C’est sans doute la solution la plus simple et la plus économique. Cela exige l’achat ou la confection d’un câble spécifique et, bien sûr, la disponibilité d’un port série sur la machine. Ports qui ont une fâcheuse tendance à disparaître des configurations récentes, mais qui pourront être ajoutés via une carte PCI au besoin. Les data cables se trouvent facilement dans les boutiques de téléphonie proposant coques, façades et accessoires. Ils servent habituellement à personnaliser le téléphone ou à le délocker de manière à ce qu’il accepte d’autres cartes SIM que celle de l’opérateur qui vend le téléphone. Bien entendu, ceci sort du cadre du présent article. Ces câbles ne contiennent que peu d’électronique, mais il ne s’agit pas de simples connexions. Un convertisseur de tension permet habituellement de faire la liaison RS232/téléphone.
- Le port USB. Il ne s’agit souvent que de simples convertisseurs USB/série. C’est le cas, par exemple, des câbles DCU-10 ou DCU-11 pour Sony-Ericsson. Il faudra vous assurer de la prise en charge de ce périphérique USB par Linux avant achat. Ce n’est pas chose aisée, puisque les boutiquiers ont une fâcheuse tendance à ignorer complètement notre cher système d’exploitation au bénéfice d’une certaine plate-forme nommée Windows. Dans le cas du DCU-1x, il s’agit d’une puce pl2303 prise en charge par le module du même nom. Personnellement, après quelques mois d’utilisation de ce câble, je me suis rabattu sur une version série suite à quelques problèmes de fonctionnement avec le module (oups à répétition lors du déchargement du module).
- IrDA. Certains téléphones disposent d’un émetteur/récepteur infrarouge permettant, par exemple, de synchroniser le répertoire téléphonique ou l’agenda intégré au téléphone. Il faut alors disposer d’un adaptateur IrDA sur la machine. S’il s’agit d’un serveur, on évitera, bien sûr, ce type de connexions, puisqu’il vous faudra acquérir, de toute façon, un adaptateur IrDA USB ou série. Je ne parle même pas de la facilité avec laquelle le signal infrarouge peut être parasité ou dont le téléphone peut subitement disparaître. Un téléphone physiquement lié à la machine (fixation sur le boîtier) et communiquant via IrDA aurait, en effet, quelque chose de comique.
- Bluetooth. Disponible avec des téléphones relativement coûteux, le Bluetooth nécessitera l’installation et la configuration d’une pile Bluetooth dans votre système GNU/Linux (voir GLMF 78 – décembre 2005). L’immobilisation d’un téléphone Bluetooth de la sorte ne se fera pas sans une très bonne raison. De plus, les mêmes commentaires ne s’appliquent que pour la solution IrDA.
Comme vous l’aurez sans doute compris, je recommande l’utilisation d’un téléphone compatible Hayes ou listé sur
http://www.gnokii.org/faq.shtml#models et utilisé via un câble série. La plate-forme de test, comme pour l’article précédent, est un Sony-Ericsson T230i qui n’est pas listé dans FAQ, mais fonctionne tout comme le T290i.
Gnokii
Gnokii est le nom d’un utilitaire permettant de contrôler le téléphone mobile à peu de frais. Il se configure très simplement, via le fichier
/etc/gnokiirc où l’on renseigne sur le type de téléphone (
model = AT), le type de connexion (
connection = serial) ou encore le port à utiliser (
port = /dev/ttyS0) et la vitesse (serial_baudrate = 9600).
Dans le présent article, l’outil en ligne de commande nous permettra de tester le bon fonctionnement de la liaison, de la configuration et du téléphone. Vous pourrez, par exemple, envoyer un SMS avec l’option
echo "mon message" | gnokii --sendsms XXXXXXXX où les
X représentent le numéro du destinataire.
Vous pourrez également vérifier le bon fonctionnement en réception avec
--getsms, suivi du type de mémoire à inspecter et du numéro du SMS ou une plage d’emplacements (
1 10 par exemple). Le type de mémoire dépend de votre téléphone et de la manière dont il gère les SMS. En temps normal, ce sera
ME pour la mémoire de l’équipement ou
SM pour celle de la carte SIM. Enfin, sachez qu’avec certains Nokia la mémoire de réception sera
IN. N’hésitez pas à consulter la page de manuel.
Après quelques essais, vous remarquerez plusieurs éléments gênants. L’un d’eux est le fait d’avoir en mémoire plusieurs SMS dans des emplacements fixes. Ainsi, si sous effacez l’emplacement 1 (
gnokii --deletesms ME 1), les autres ne changent pas. Il est alors nécessaire, à intervalles réguliers, de lister une vaste plage d’emplacement pour trouver les nouveaux messages, etc. Avec un peu d’insistance et une bonne maîtrise des scripts Shell, il est néanmoins possible de passer outre ces limitations. Mais il y a une solution plus simple.
smsd
Gnokii est également la bibliothèque
libgnokii2 et la possibilité de créer des applications et des outils qui reposent sur le travail du projet. Vous pouvez donc développer votre propre solution d’émission et réception de SMS et d’accès aux mobiles. Mais
libgnokii2 est également la base d’un autre développement intéressant : le démon
smsd.
Ce démon, qui est proposé sous la forme d’un paquet Debian
gnokii-smsd, utilise soit une base de données (MySQL ou PostgreSQL), soit un fichier texte pour stocker les SMS reçus et envoyés. C’est
smsd qui se chargera de la communication avec le téléphone via la configuration placée dans
/etc/gnokiirc.
Préparation
Bien qu’il soit possible de n’utiliser qu’un fichier texte, il est fortement conseillé d’utiliser le support d’une base de données. L’accès se fait par l’intermédiaire de plugins placés, avec Debian, dans
/usr/share/smsd. Il faudra installer le paquet
gnokii-smsd-mysql pour reposer sur MySQL et ainsi installer
libmysql.so en plus de
libfile.so. Notez l’emplacement peu orthodoxe de ces plugins.
La première étape consiste à créer la base de données permettant d’accueillir les SMS:
|
|
mysqladmin -uYYYYY -pXXXXX create smsd |
Le nom de la base n’a aucune importance. Elle sera passée en argument au démon. La création des tables dans la base est facilitée par la mise à disposition d’un fichier SQL. Il suffira alors d’utiliser la commande suivante pour construire le tout :
|
|
mysql smsd < /usr/share/doc/\
gnokii-smsd-mysql/sms.tables.mysql.sql |
Deux tables sont créées. La première
inbox contiendra les messages reçus par le téléphone. On y retrouve les informations sous une forme plus lisible qu’en évaluant la sortie de
gnokii --getsms. Il devient aisé de récupérer les éléments comme la date SMS, le message ou encore le numéro de l’expéditeur. On notera le champ
processed permettant de marquer un message comme traité par vos scripts.
La table
outbox sert à l’émission de SMS. Il suffira, une fois le démon en route, d’insérer un enregistrement et le message sera émis par le téléphone. Là encore, on trouve un champ
processed, mis à jour cette fois par le démon, confirmant ainsi le traitement du SMS. Le champ
processed_date place l’évènement dans le temps. En guise de retour d’information, nous avons également le champ
error qui contiendra le code d’erreur (voir
gnokii/error.h) en cas de problème.
Enfin, il est possible de retarder l’envoi du SMS en plaçant 1 dans le champ
dreport et en spécifiant une heure dans
not_before et/ou
not_after. Nous reparlerons du champ
phone plus loin
Intégration Système
smsd n’utilise pas de fichier de configuration concernant les paramètres qui lui sont propres. Il faut donc tout passer en argument au binaire. Ceci pose un petit problème, car le paquet Debian ne contient pas de script d’init correspondant. Il faudra donc en créer un sur la base du fichier
/etc/init.d/skeleton.
Parmi les options à passer à smsd, nous avons :
- -l /usr/share/smsd : le chemin où trouver les bibliothèques plugins permettant la connexion aux bases de donnée.
- -m mysql : le module de base de données à utiliser ici MySQL.
- -d smsd : le nom de la base contenant les tables inbox et outbox.
- -u YYYYY : le nom d’utilisateur pour la connexion à la base.
- -p XXXXX : le mot de passe correspondant à l’utilisateur.
- -f /var/log/smsd.log : le fichier journal permettant un suivi des opérations.
- -b ME : le type de mémoire à utiliser. Ici, celle de l’appareil.
Le reste de la configuration est tiré de
gnokiirc. Lancer le démon en ligne de commande est donc quelque chose de relativement facile. Mais nous devons pousser l’intégration afin d’automatiser la gestion de ce qui va devenir un service contrôlé par le système classique de scripts d’Init. Avec Debian, ce script n’existe pas, contrairement à ce qu’on peut trouver, par exemple, dans le paquet RPM
gnokii-smsd d’une FC6 (notez également que Debian propose la version 0.6.8 alors que la 0.6.12 est disponible depuis longtemps).
La construction du script d’init est relativement simple via l’utilisation de
start-stop-daemon. On commence par définir quelques variables et on teste la présence du binaire :
|
|
#!/bin/sh
set -e
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC=“Gnokii SMS daemon“
NAME=smsd
DAEMON=/usr/sbin/$NAME
PIDFILE=/var/run/$NAME.pid
SCRIPTNAME=/etc/init.d/$NAME
test -x $DAEMON || exit 0 |
Nous définissons ensuite deux fonctions procédant au démarrage et à l’arrêt du démon. Pour nous faciliter la vie, nous nous reposons sur
start-stop-daemon qui se chargera d’exécuter le binaire, tuer le processus, enregistrer le numéro de processus dans un fichier spécifique, etc. La fonction
d_start() ne présente pas vraiment de difficultés, toutes les options sont documentées dans la page de manuel de
start-stop-daemon. Remarquez toutefois l’utilisation de
-- permettant, selon la syntaxe GNU standard mais méconnue, de signaler la fin des options et le début des arguments génériques. Tout ce qui suit
-- est destiné à
smsd et non à
start-stop-daemon :
|
|
d_start() {
start-stop-daemon --start --quiet \
-m --pidfile $PIDFILE -b \
--exec $DAEMON -- -u root \
-p viviane -d smsd -m mysql \
-f /var/log/smsd.log -i 30 \
-b ME -l /usr/share/smsd \
|| echo -n “ already running”
} |
Il en va de même pour l’arrêt du démon qui est simplissime. L’option
--stop permet d’envoyer le signal 15 par défaut (
SIGTERM). Avec
smsd, en cas de problème de communication avec le périphérique mobile, le processus peut rester en attente d’un évènement et ne pas obtempérer. Dans ce cas, il peut être intéressant d’ajouter l’option
--signal 9 permettant d’utiliser le signal
SIGKILL, plus radical.
|
|
d_stop() {
start-stop-daemon --stop \
--quiet --pidfile $PIDFILE \
--name $NAME \
|| echo -n " not running"
} |
Il ne nous reste, plus, les éléments de
/etc/init.d/skeleton :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
|
case "$1" in
start)
echo -n "Starting $DESC: $NAME"
d_start
echo “.”
;;
stop)
echo -n “Stopping $DESC: $NAME”
d_stop
echo “.”
;;
restart|force-reload)
echo -n “Restarting $DESC: $NAME”
d_stop
sleep 1
d_start
echo “.”
;;
*)
echo “Usage: $SCRIPTNAME {start|stop|”\
“restart|force-reload}” >&2
exit 1
;;
esac
exit 0 |
Il ne nous reste, plus, enfin, qu’à lancer le script pour en vérifier le fonctionnement :
|
|
% /etc/init.d/smsd start
Starting Gnokii SMS daemon: smsd.
% ps x | grep smsd
32149 ? Ssl 0:00 /usr/sbin/smsd -u xxxx
-p xxxxxxx -d xxxx -m mysql
-f /var/log/smsd.log -i 30
-b ME -l /usr/share/smsd |
Utilisation
Une fois le démon en marche, il va régulièrement vérifier le périphérique GSM ainsi que le contenu de la base de données (l’intervalle peut être réglé avec l’option
-i). Essayez d’envoyer un message depuis un autre téléphone sur celui connecté au PC et suivez le traitement dans de fichier
smsd.log :
|
|
1 Jun 2006 10:26:36: Inserting sms from
+3367344XXXX successful. |
On retrouve ensuite, dans la table
inbox, l’enregistrement :
|
|
+----+--------------+---------------------+---------------------+--------------+-------+-----------+
| id | number | smsdate | insertdate | text | phone | processed |
+----+--------------+---------------------+---------------------+--------------+-------+-----------+
| 0 | +3367344XXXX | 2006-06-01 10:25:09 | 2006-06-01 15:56:58 | Wazaaaaaaaa | NULL | 0 |
+----+--------------+---------------------+---------------------+--------------+-------+-----------+
1 row in set (0.00 sec) |
On remarquera ici une différence importante entre le contenu de
smsdate (date et heure transmise dans l’en-tête du SMS) et de
insertdate. Dans ce cas précis, il s’agit d’une erreur de manipulation électrique. Le téléphone mobile étant alimenté via un montage secteur tenant lieu de batterie, le fait de le débrancher éteint le téléphone. Malheureusement, rétablir l’alimentation ne le rallume pas. Une autre source d’erreur peut être l’indisponibilité du SGBD. Dans ce cas,
smsd laisse le SMS dans la mémoire du téléphone jusqu’à pouvoir le copier dans la table. Je laisse au lecteur le soin de juger de la pertinence du SMS enregistré dans le champ
text.
L’avantage découlant de l’utilisation d’une base de données est ici évidente. L’écriture d’un script Perl, Python ou Bash dépilant les enregistrements non traités (
processed=0) est un jeu d’enfants. La provenance du SMS peut être vérifiée grâce au champ
number, tout comme la validité du message dans le temps, grâce aux deux dates et heures enregistrées. Je ne saurais vous dire, cependant, si le numéro d’expéditeur peut être falsifié ou non par une personne malintentionnée et compétente. Pour un utilisateur en production, mieux vaut donc prévoir une méthode d’authentification complémentaire, comme un mot de passe à usage unique. L’envoi de SMS pourra se faire via différentes méthodes. Il est bien sûr possible d’écrire un script permettant l’insertion d’un enregistrement dans la table
outbox, mais une simple ligne de commande pourra faire l’affaire :
|
|
echo ‘insert into outbox (number,text) value’\
(“0673448035”, “’<code>uptime</code>’”);’ \
| mysql -uroot -pviviane smsd |

Illus. 1 : Réception de la sortie de la commande uptime sur un Tréo600
Plusieurs téléphones
smsd est capable d’utiliser plusieurs téléphones. C’est la raison d’être du champ phone des tables inbox et outbox. Plusieurs choses sont nécessaires.
Tout d’abord, il faut modifier le fichier de configuration de manière à spécifier les différents appareils à votre disposition dans des sections [phone_n] où n est le numéro du périphérique, par exemple :
|
|
[phone_1]
port = /dev/ttyS0
model = 6110
initlength = default
connection = serial
use_locking = no
serial_baudrate = 38400 |
Dès lors, en lançant
smsd avec l’option
-t 1, le démon utilisera le Nokia 6110 sur
ttyS0. Cela signifie également que
1 sera placé dans tous les enregistrements placés dans
inbox. D’autre part, cette instance du démon ne surveillera que les éventuels enregistrements de
outbox dont le champ
phone sera à
1. On imagine sans peine la facilité avec laquelle on peut ainsi traiter les SMS d’un parc complet de téléphones connectés au serveur (et la facture d’abonnement qui s’en suit !).
Retrouvez cet article dans : Linux Magazine 86