Mise en place d'un réseau de capteurs sans fil (2019)

De Ensiwiki
Révision de 26 janvier 2020 à 10:59 par Mugnijea (discussion | contributions) (Avantages et inconvénients)

Aller à : navigation, rechercher


Project schedule.png
Titre du projet Communication de capteurs sans fils
Cadre Projets Réseaux Mobiles et Avancés

Équipe Lucas Peirone, Valderane Potong,Michel Yoeung, Jean-Charles Mugnier,
Encadrants Franck Rousseau


Introduction

Le "Réseau de capteur sans fil" est un projet que l'on peut considérer comme "fil rouge" dans le contexte de ce projet Réseaux Mobiles et Avancés. Si le but de la manipulation, établir une communication entre un groupe de capteurs, est commun, une liberté sur le contexte d'exécution, ainsi que sur le protocole mis en place, est laissé aux élèves, permettant une multitude de réponse pour ce qui pourrait être considéré comme un problème unique.

Dans le cadre de ce projet, nous avons essayé de mettre au point une communication permettant l'entrée et la sortie de capteurs du réseau crée. Plutôt que les performances, une des priorités du projet est d'essayer de consommer le moins d'énergie possible, à notre sens une des motivations principales pour ne pas simplement utiliser une connection Internet "normale".

Les grandes étapes du développement sont alors de mettre en place l'environnement, de théoriser le protocole, et enfin d'implanter une PoC tendant vers notre solution théorique.

Mise en place de l'environnement

S'appuyant sur le travail des précédents projets, la mise en place de l'environnement était censée être rapide et facile.

Seulement voilà. N'ayant pas nos stations personnelles de disponibles, nous nous sommes attelés à faire fonctionner cet environnement sur les PCs de l'Ensimag .

Cette étape rapide et facile s'est alors rapidement transformée en une chasse à la fonctionnalité pour trouver un moyen de passer par delà les contraintes imposées sur ces stations, transformant alors cette trivialité en véritable sous-projet.

Dans la suite de cette section, les contraintes et essais seront détaillés, afin de faciliter le travail pour de potentiels prochains groupes. Si vous ne cherchez qu'à faire fonctionner l'environnement, vous pouvez aller direction à la solution.

Les besoins

Pour que l'environnement fonctionne, il y a en réalité besoin que d'assez peu de conditions:

  • Les droits super utilisateur
  • L'accès aux ports USB de la machine (physiquement et logiquement)

Les droits super utilisateur nous permettent d'installer les logiciels requis, ainsi que de "réserver" un port USB pour le flash/debug. Des droits corrects sur les utilisateurs normaux pourraient aussi nous le permettre, mais il ne sont pas accordés aux élèves.

L'accès au port USB, pour des capteurs USB, paraît probablement être une évidence. Puisqu'en effet, ça l'est. Est-ce pourtant une garantie ? Non, nous allons le voir.

Les essais

La première idée que nous avons eu est d'essayer de simplement faire une installation utilisateur des logiciels requis. Après tout, de nombreux logiciels sous Linux ne requièrent des droits privilégiés que dans l'unique but de s'installer dans un répertoire système. Changer le répertoire d'installation pourrait alors être une solution simple. Mais mspdebug et l'installation du compilateur ne vont pas dans ce sens, impossible de tout installer/exécuter sans les droits su, y compris en changeant les paramètres.

Bien entendu, il n'y avait que peu d'espoirs que cette première solution naïve fonctionne. Mais, si ce n'est qu'un problème d'accès, des solutions de virtualisation comme Vagrant ou Docker sont idéales. Docker n'étant pas (encore ?) installé sur les stations de l'école, nous essayons alors Vagrant.

Un Vagrantfile est alors crée avec toutes les dispositions nécessaires. Tous les logiciels s'installent correctement. Seulement, le logiciel de flashing des cartes ne détecte aucune cartes. En effet, le backend du Vagrant installé est VirualBox. Ce dernier ne partage pas par défaut les périphériques USBs avec la VM. Dans une installation normale, il s'agit juste d'un setting à changer, pour autoriser le passthrough d'un périphérique.

Mais, probablement pour des raisons obscures de sécurité et de normes, ce réglage ne peut pas être modifié par un utilisateur normal. Cette seconde version disposait alors d'un environnement parfaitement fonctionnel... Mais qui ne pouvait pas être utilisé sur les capteurs.

Reste Docker, un conteneur n'étant pas une VM, ce blocage induit par VirtualBox ne devrait pas s'appliquer. Seulement, comme dit précédemment, Docker n'est pas installé sur les PCs, et son accès passe par une commande "lance-vm-5MMSSI.sh". C'est à dire par une VM. Lancée par VirtualBox. Cette troisième solution a donc également été un échec.

Abandonnant l'idée de faire fonctionner la solution sur CentOS, nous nous sommes ensuite dirigés vers FreeBSD, un système d'exploitation alternatif préinstallé sur les stations. Les outils de développement n'étant pas prévus pour ce système, nous essayons de contourner ce problème avec Docker ou Vagrant. Mais ces outils ne sont pas non plus nativement compatibles avec cet OS, et après quelques essais, il est devenu évident que cette quatrième solution n'était pas non plus la bonne.

Il restait alors encore un système d'exploitation alternatif : Windows. En effet, sur Windows (7, Windows 10 plante au démarrage), nous disposons des droits d'administrateurs. Nous pouvons alors installer les outils. Nous avons également accès aux ports USB. Il semble, dans la version utilisée de mspdebug, qu'il y ait une présence d'un bug sur certaines méthodes. Si ce n'est pas confirmé cette fois, nous sommes directement passé par la virtualisation.

Or, à ce stade du développement, nous utilisions un conteneur Docker pour travailler sur nos machines (fixes) personnelles. Nous avons donc voulu utiliser Docker sur Windows pour avoir un environnement cohérent. Pour avoir accès aux ports USB de la machine physique, un conteneur a besoin d'être privilégié. C'est une option accessible dans docker run. Malheureusement, sous Windows, à cause de la manière dont Docker est implémenté (via une machine virtuelle), cette option n'est pas disponible. Cette sixième tentative a néanmoins ouvert la voie pour la solution trouvée.

La solution

Après tous ces essais, nous avons finalement décidé d'installer VirtualBox sur Windows et d'installer Ubuntu sur une VM (Vagrant ou autre). Ayant les droits d'administrateur sur Windows, il nous a été possible de simplement configurer le passthrough USB pour que la machine virtuelle Ubuntu ait accès aux capteurs. Installant ensuite Docker sur cette machine virtuelle, nous avons enfin pu faire fonctionner le conteneur en mode privilégié et pu programmer les capteurs.

Voici le Dockerfile utilisé. Le dépot Gitlab contenant les différentes archives utilisées est disponible dans les sources

La méthode suivie par ce DockerFile est celle-ci. Les dépendances sont pré-récupérées sous forme d'archive pour fixer les versions et être certain d'avoir un environnement stable (certains logiciels ne sont pas versionnés au téléchargement). La seule section vraiment remarquable est l'installation du compilateur.

En effet, l'installation est par défaut graphique, ce qui est très embêtant dans notre contexte. Même en mode "textuel", avec l'option --text, des interactions utilisateurs sont demandées. Ce problème est contourné par l'utilisateur de yes, une commande qui répond y à chaque question (beaucoup de questions demandées sont des questions fermées). Cela nous permet d'installer le logiciel, mais avec un effet de bord : une des questions est le chemin d'installation. Le logiciel est donc installé dans le répertoire "y". La ligne suivante corrige donc ce problème.

L'inconvénient de cette solution est qu'elle requiert de toujours utiliser le même PC. En effet, les actions sur Windows sont propres à l'ordinateur et non à l'utilisateur. Heureusement, nous avons toujours été dans la même salle pour les séances encadrées. Il devient néanmoins plus compliqué de travailler à l'ENSIMAG sur son temps libre, puisque notre salle était souvent utilisée pour d'autres cours.

Les ports USB des machines sont scellés. Nous avons utilisé un hub USB pour nous permettre de brancher un capteur sans devoir sacrifier le clavier ou la souris.

Les partitions Windows des machines ont un espace disque très limité. Si vous rencontrez des problèmes liés à cela, nous vous conseillons de désinstaller des logiciels (Visual Studio Code, par exemple) ou de vider le dossier Téléchargement.

Pour information, nous sommes arrivés à cette solution à l'issue de l'avant dernière séance encadrée.

Le protocole

Le protocole que nous implémentons se base grossomodo sur un protocole existant permettant d'établir un réseau de communication pair-à-pair : Gnutella (imaginé en 2000 par Tom Pepper).

Détails du protocole

Sur chaque ping et pong, on instaure un TTL (Time To Live) de 15 pour éviter les boucles infinies, qui sera décrémenté à chaque arrivée dans un nœud.
Sur chaque ping et pong, on instaure également un GUID (Globally Unique IDentifier) pour les identifier de façon unique.

Les 5 requêtes existantes sont :

  • Ping (ping GUID_1 : je suis le nœud d'adresse A_1)
  • Pong (pong GUID_2 : je réponds au ping GUID_1 et je suis le nœud d'adresse A_2)
  • Query (requête sur le réseau en broadcast)
  • Query-hit (celui qui peut répondre à la requête fait un pong vers le client de la requête)
  • Query-push (demande de ressource au nœud pouvant répondre à la requête, comme un HTTP GET)

Arrivé d'un nouveau nœud dans le réseau pair à pair

  1. Le nouveau nœud (considéré comme le client) va envoyer des pings (avec son adresse MAC en payload) tous les t temps jusqu'à qu'une réponse pong lui parvienne.
  2. Si un noeud reçoit un ping, il décrémente le TTL de 1.
    • Si le TTL vaut 0, il jette le ping.
    • Sinon, si l'adresse MAC source du ping n'appartient pas à ses adresses connues (pour éviter les boucles), ce dernier va propager le même ping aux voisins.
  3. Ce dernier va ensuite envoyer un pong retour (avec son adresse MAC en payload) vers l'adresse source du ping.

Lancement et réponse d'une requête unicast dans le réseau

  1. Un nœud d'adresse MAC A_1 veut envoyer un message à un autre nœud d'adresse A_2. Il va envoyer le message en ping avec son adresse MAC et l'adresse MAC destination.
  2. Si un noeud reçoit le ping, il décrémente le TTL de 1.
    • Si le TTL vaut 0, il jette le ping.
    • Sinon
      • Si l'adresse MAC destination correspond à son adresse MAC, il lit le message et envoi une requête unicast pong retour vers l'adresse MAC source.
      • Sinon, ce dernier va propager le même ping aux voisins.

Optimisations possibles

Le réseau pair-à-pair est constitué de plusieurs nœuds et on désigne parmi ces nœuds, un nœud d'amorçage appelé Bootstrap Node (BN).
Le BN va posséder en mémoire une liste qui est censée contenir les adresses MAC de tous les nœuds du réseau pair-à-pair.
Le BN va donc se comporter comme un serveur.

Arrivé d'un nouveau nœud dans le réseau pair à pair

  1. Ce nouveau nœud (client) va envoyer une requête au BN avec un unicast pour obtenir la liste des adresses MAC de tous les nœuds (cela va permettre d'éviter d'inonder le réseau).
  2. Le BN va lui répondre en mettant dans le payload la liste des adresses MAC de tous les nœuds.
  3. Le nouveau nœud va ensuite envoyer un ping à chacun des nœuds de la liste jusqu'à recevoir le premier pong, ce qui marquera le début de la propagation de pair en pair de son adresse MAC pour tous les autres nœuds du réseau (ainsi, tous les nœuds du réseau vont pouvoir connaître ce nouveau nœud).

Pour identifier les nœuds qui ont crash, à intervalles réguliers T temps, le BN va mettre à jour sa liste des nœuds

  1. Pour chaque adresse des nœuds du réseau, envoyer un ping à chacun pour savoir si les nœuds sont vivants.
  2. Après un timeout t (avec t < T), si le BN n'a pas reçu le pong de la part d'un nœud, il va le considérer comme mort durant la session en cours (de période T).
  3. Si jamais le BN reçoit le pong d'un noeud précédemment considéré comme mort, alors le BN va attendre la prochaine session (de période T) pour mettre à jour sa liste des nœuds et le reconsidérer comme vivant.

Avantages et inconvénients

Avantages

Simplicité : le protocole est relativement simple à comprendre et à mettre en place.

Economie d'énergie : possibilité d'utiliser une version "Slotted" de ce protocole afin de désactiver les antennes de communication la plupart du temps.

Inconvénient

Sécurité : étant donné le fonctionnement par flooding de ce protocole, il devient difficile d'assurer une confidentialité dans ce réseau.

Performance : le fonctionnement par flooding solicite beaucoup les canaux de communication.

L'implémentation

Pour pouvoir identifier les capteurs entre eux, nous avions besoin de récupérer un identifiant unique. Dans un réseau classique, c'est une adresse unique à un matériel et attribuée par le fabricant. Nous pouvons émuler ce fonctionnement en allant chercher une valeur pré-flashée dans chaque capteur à l'adresse 0x10F0. Il est possible que certains capteurs n'aient pas d'adresse Mac directement associée, dans ce cas, il est possible de d'utiliser cet utilitaire pour flasher les cartes.

Récupération de l'adresse Mac

Sources