Mir:ror mon beau Mir:ror…Comment puis-je te comprendre ?

mirorDans mon précédent article, je présentais mir:ror, le petit lecteur RFID commercialisé par la société Violet.  Après avoir survolé leur application « Mirware » et mis en évidence les limites de son utilisation, je vais mettre « les mains dans le cambouis » pour essayer de comprendre comment communiquer avec Mir:ror.  L’idée étant de pouvoir coder de petits outils capables de réagir à des tags RFID.

D’un point de vu système, Mir:ror est directement reconnu sous Linux et accessible via le handler de périphérique /dev/hidrawX (où X est le numéro de périphérique, normalement « 0″ si c’est le premier appareil du genre connecté).

La petite application « discover-device« , fournie avec Mirware, permet de le détecter automatiquement :

discover-device

Attention tout de même aux droits, le périphérique n’est par défaut accessible que par root, il faudra lui changer les droits ou utiliser le script « installer.sh » pour le faire, avant de pouvoir l’exploiter avec un utilisateur standard.

Commençons par voir ce qu’il se passe avec un simple « cat » du fichier :

cat-miror

Des hiéroglyphes s’affichent lorsque nous approchons ou retirons un tag… C’est plutôt bon signe, et visiblement c’est binaire ! Nous devrions y voir plus clair avec un affichage en hexadécimal.  Hexdump est idéal pour ça !

hexdump

La première ligne (0000 0000 0000 0000 0000 0000 0000 0000 *) nous indique que tant qu’il ne se passe rien, on lit des zéros… Où…Qu’on lit des zéros tant qu’il ne se passe rien ! (c’est plutôt normal).
Les deux lignes suivantes (0102 0000 d008 1a02 5303 4202 00d2 0000 – 0000 0000 0000 0000 0000 0000 0000 0000) s’affichent lorsqu’un tag est approché, les deux dernières ( 0202 0000 d008 1a02 5303 4202 00d2 0000 – 0000 0000 0000 0000 0000 0000 0000 0000 ) lorsqu’on éloigne le tag.

Après plusieurs tests, j’en déduis assez facilement que les deux premiers octets (0102 ou 0202) codent l’évènement. J’en ai repéré 4 types :

  • 0×0102 : Tag rfid détecté,
  • 0×0202 : Tag rfid retiré,
  • 0×0501 : Le mir:ror est mis à l’envert,
  • 0×0401 : Le mir:ror est remis à l’endroit.

Les 12 octets suivants semblent identifier la puce RFID.

A titre de test, écrivons rapidement un petit bout de code C, prenant le device en paramètre et affichant les évènements et le tag associé :

// Jopa - Petit test du Mir:ror : test_mirror.c
#include <stdio.h>
#include <stdlib.h>
 
int main(int argc, char *argv[]) {
  FILE *mirror;
  short unsigned int block;
  short unsigned int event;
  char tag[25];
  int i;
 
  //Vérification du paramètre (device)
  if (argc!=2) {
        printf ("Usage : %s mirror_device 

",argv[0]);
        exit(-1);
  }
 
  // Ouverture du fichier device
  mirror = fopen(argv[1],"rb");
  if (!mirror) {
        printf("Accès à  %s impossible !
",argv[1]);
        exit(-1);
  }
 
  // Boucle en lecture
  while (1) {
     fread(&event,2,1,mirror);
     if (event!=0) {
        // Evenement detecté, lecture de l'ID
        for (i=0;i<6;i++) {
            fread(&block,2,1,mirror);
            sprintf(&tag[i*4],"%04X",block);
        }
 
 //Affichage en fonction de l'événement
        switch (event) {
            // Tag On
            case 0x102 :
                printf("%s : ON
",tag);
                break;
 
             //Tag Off
             case 0x202 :
                 printf("%s : OFF
",tag);
                 break;
 
             //Mirror envers
             case 0x501 :
                 printf("MIR:ROR ENVERS
");
                 break;
 
             //Mirror endroit
             case 0x401 :
                   printf("MIR:ROR ENDROIT
");
                    break;
 
             //Default
             default :
                   printf("Evénement inconnu
");
        } //switch
      } //if (event
   } //while (1)
} // main()

En quelques lignes, nous ouvrons le périphérique dont le handler est passé en paramètre et bouclons sur sa lecture, 2 octets par 2 octets.
Quand autre chose que « 0″ est détecté, c’est forcément un changement d’état. Nous lisons ensuite l’identifiant de la puce RFID.
La dernière partie affiche un message en fonction de l’évènement détecté.

Il ne reste plus qu’à le compiler et le tester :
$ gcc test_mirror.c -o test_mirror
$ ./test_mirror

test_mirror

Pour compléter l’exemple, nous pouvons rajouter l’exécution d’un script associé au tag et à son approche ou son éloignement. Les scripts pourraient être stockés dans le répertoire de l’utilisateur et porter l’<id>-on.sh ou l’<id>-off.sh comme nom. Pour l’exemple :

  • 0000D0081A025303420200D2-on.sh : Lancement de Firefox sur le blog de Jopa
#!/bin/sh
firefox http://www.jopa.fr
  • 0000D0081A025303420200D2-off.sh : Lancement de Thunderbird
#!/bin/sh
thunderbird

$ chmod +x ~/0000D0081A025303420200D2-*.sh

Adaptons un peu le code en ajoutant une variable pour le nom du script et une commande « system » dans le « switch/case ».

   // Jopa - Test Mir:ror
 
#include <stdio.h>
#include <stdlib.h>
 
int main(int argc, char *argv[]) {
  FILE *mirror;
  short unsigned int block;
  short unsigned int event;
  char tag[25];
  // Ajout d'un variable script
  char script[256];
  int i;
 
  //Vérification du paramètre (device)
  if (argc!=2) {
        printf ("Usage : %s mirror_device 

",argv[0]);
        exit(-1);
  }
 
  // Ouverture du fichier device
  mirror = fopen(argv[1],"rb");
  if (!mirror) {
        printf("Accès à  %s impossible !
",argv[1]);
        exit(-1);
  }
 
  // Boucle en lecture
  while (1) {
     fread(&event,2,1,mirror);
     if (event!=0) {
        // Evenement detecté, lecture de l'ID
        for (i=0;i<6;i++) {
            fread(&block,2,1,mirror);
            sprintf(&tag[i*4],"%04X",block);
        }
 
 //Affichage en fonction de l'événement
        switch (event) {
            // Tag On
            case 0x102 :
                printf("%s : ON
",tag);
                //Construction du nom de script et exécution
                sprintf(script,"./%s-on.sh",tag);
                system(script);
                break;
 
             //Tag Off
             case 0x202 :
                 printf("%s : OFF
",tag);
                 //Construction du nom de script et exécution
                 sprintf(script,"./%s-off.sh",tag);
                 system(script);
                 break;
 
             //Mirror envers
             case 0x501 :
                 printf("MIR:ROR ENVERS
");
                 break;
 
             //Mirror endroit
             case 0x401 :
                   printf("MIR:ROR ENDROIT
");
                    break;
 
             //Default
             default :
                   printf("Evénement inconnu");
        } //switch
      } //if (event
   } //while (1)
} // main()

Ceci n’est bien entendu qu’un exemple, écrit rapidement et pas forcément très propre. Mais il permet de mettre en évidence la simplicité avec laquelle il est possible d’accéder à des informations RFID et ouvre la porte sur des développements qui peuvent être rapidement prometteurs.

Vus : 389
Publié par Jopa : 29