Born to be wired

SMS automatisé – Final round

 8 décembre 2013  Domotique  Aucun commentaire

Maintenant, terminé les enfantillages. Envoyer des SMS en ligne de commande à des gens avec un nom rigolo, c’est très amusant, mais ça montre rapidement ses limites. Pour aller plus loin, il faut mettre en place un système capable de gérer de manière autonome les échanges avec la carte SIM, et de proposer une interface de communication à la fois simple, robuste, et utilisable par un grand nombre d’applications.

La base de données est une interface idéale pour cela, et il existe justement un système qui peut l’utiliser comme backend pour communiquer avec le modem GSM. Ce système, c’est gnokii-smsd.

Gnokii-smsd tourne en tâche de fond, guette les messages insérés en base par des applications tierces pour les envoyer sur le modem GSM, et récupère également les SMS arrivant sur le modem GSM pour les insérer en base. Que demande le peuple ?

Principe

Le mode opératoire de mise en place de gnokii-smsd est très bien décrit dans ce tuto (merci à Mourade pour le lien), je ne m’appesantirai donc pas dessus, mais donnerai plutôt quelques indications complémentaires qui me paraissent utiles pour aboutir aux mêmes fins en levant les doutes qui pourraient se présenter à l’impétueux curieux désirant mettre en place cette solution, tout comme ils se sont présentés à moi.

  • Le tuto indique de démarrer le daemon avec l’argument « -l » suivi du chemin des bibliothèques utilisées pour la base de données. Hors, le chemin présenté n’existe pas sous Debian, et le tuto ne fait pas référence au nom exact attendu pour les libs. Qu’à cela ne tienne, si l’exécutable a été  déployé grâce aux paquets du repository officiel Debian, le programme se débrouille très bien sans avoir à saisir cette valeur. On peut donc ignorer l’argument.
  • Il m’est arrivé, aux premiers lancements, de voir que les SMS restaient stockés sur la SIM après dépilage, et que cela provoquait des doublons dans les logs. Je me suis donc demandé comment éradiquer proprement ces SMS afin d’éviter une saturation de la SIM à terme. Je n’ai pas la réponse : malgré le comportement observé aux premiers lancements, mes SMS reçus sont systématiquement supprimés de la SIM après copie en base de données. J’attribue cela à un probable délai de suppression plus ou moins aléatoire, voire à un mauvais paramétrage aux premiers essais.
  • Le daemon n’est pas livré avec script de démarrage, c’est expliqué dans le tuto. Du coup, il n’est pas livré avec fichier de configuration de purge des logs non plus, puisque le chemin des logs est déclaré dans le script de démarrage. Il convient donc de mettre en place sa propre configuration logrotate. Je détaillerai ce point un peu plus bas.

Voila pour les aspects les plus simples. Je souhaite en détailler quelques autres, légèrement plus complexes :

Problématiques de charsets (1/2)

Avec ma locale usuelle fr_FR.UTF-8, si je lance smsd, que ce soit manuellement ou par script, les messages récupérés de la SIM sont lus en unicode, convertis en UTF-8,  et stockés en base dans un champ texte sous forme de suite d’octets, alors que ma base est déjà au format UTF-8.

Il y a donc une sorte de « double-encodage » à l’écriture. Ce qui fait que tous les caractères accentués se transformeront en caractères accentués (sic) lors de la lecture de la base par l’application tierce. Il conviendra donc d’effectuer logiciellement la conversion de charset adéquate lors de la lecture de la base par une application tierce, ainsi que l’opération inverse lors de l’écriture. Je donnerai plus d’indications à ce sujet un peu plus tard.

Problématiques de verrouillage de carte SIM

On peut vouloir, pour une raison ou une autre, conserver l’accès à la carte SIM par code PIN. Dans ce cas, il est nécessaire que le script de démarrage vérifie si le code PIN doit être entré, et si oui qu’il réalise cette opération.

Malheureusement, gnokii ne communique pas cette information via un code retour. Je dois donc utiliser une indication donnée par un texte sur la sortie standard.  Texte qui est susceptible de varier avec les versions, c’est discutable, mais c’est comme ça. Contactés à ce sujet, les développeurs trouvent cette implémentation normale. Moi pas, mais c’est leur software, libre à chaque mécontent de le forker et de l’adapter. Sans aller jusqu’à cette extrémité, j’ai ajouté une petite vérification sur la sortie textuelle dans le script de démarrage avant lancement du daemon.

Problématiques de charsets (2/2)

J’ai compris un peu tard que la locale de lancement du script au démarrage du système d’exploitation (LANG=C) ne correspond pas à la locale usuelle de mes comptes (LANG=fr_FR.UTF-8). L’effet de bord est que les caractères non-ASCII des SMS ne sont pas stockés en base de la même manière si le script est lancé manuellement par un utilisateur, ou automatiquement au démarrage. J’ai résolu ce problème en forçant également la locale à fr_FR.UTF-8 dans le script de démarrage.

Ajustements périphériques

Il est toujours plus pratique de s’adresser au modem GSM via un lien symbolique (/dev/wavecom dans mon cas) que via un inode générique du type /dev/ttyUSB0, surtout lorsqu’on a plusieurs périphériques USB.

Pour remédier à cela, j’ai laissé le soins à udev de créer le lien symbolique sur la base du Vendor ID et Product ID indiqués par le périphérique. J’ai donc ajouté le contenu suivant dans /etc/udev/rules.d/10-local.rules

# Wavecom Fastrack GSP modem
# lsusb: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port
SUBSYSTEMS=="usb", ATTRS{idVendor}=="067b", ATTRS{idProduct}=="2303", SYMLINK="wavecom"

Résultat des courses

Une archive smsd.tgz contenant mon script de lancement, un exemple de fichier de configuration, et une configuration pour logrotate, est disponible sur la page des téléchargements. Sous Debian, il faut bien sûr utiliser insserv pour installer proprement le script de démarrage.

Exploitation

À partir de là, à chacun de faire comme il l’entend pour gérer ses envois et réceptions à partir de scripts tiers.

À titre d’exemple, j’ai commencé par mettre en place une simple page PHP qui affiche proprement (par proprement j’entends « de manière correctement formatée ») les messages reçus. L’affichage des messages envoyés est extrêmement similaire. Avec un peu de plugin javascript du type DataTables, on obtient un affichage minimaliste et ergonomique, tel que celui-ci :

Le tableau liste l'ensemble des SMS reçus.

Le tableau liste l’ensemble des SMS reçus.

Le transcodage des caractères pour afficher proprement les messages malgré leur stockage en base avec le double-encodage évoqué précédemment, est réalisé grâce au bout de requête SQL qui suit (solution trouvée et expliquée plus en détails ici) :

convert(binary convert(text using latin1) using utf8)

Cet exemple d’affichage complet est également disponible au niveau des téléchargements.

Épilogue

Une de mes premières actions sera de planifier l’envoi d’un simple SMS de ping, 2 fois par an, afin de maintenir le compte associé à la carte SIM actif, comme le prévoient les condition générales d’utilisation (un acte payant par an). À ce propos, il faut savoir que B&You, qui m’a initialement fourni la carte SIM, a transféré la gestion des contrats des cartes prépayées sans durée de validité à Simyo. Ni B&You ni Simyo ne proposent à ce jour l’ouverture de nouveaux contrats similaires. Pour obtenir une carte SIM prépayée sans durée de validité, il faudra peut-être dorénavant fouiller du côté des offres proposées par la grande distribution.

Enfin, je ne saurais résister à l’envie de montrer à quoi ressemble l’installation finalisée :

Serveur, onduleur, et modem GSM.

Serveur, onduleur, et modem GSM.

Même chose, mais angle de vue différent.

Même chose, mais angle de vue différent.

C’est tout pour aujourd’hui. Dans mon prochain article, je présenterai brièvement quelques évolutions menées en profondeur sur ce blog.

Laisser un commentaire