Atelier réseau (coronavirus)Julien Forget & Xavier Redon |
Le but de ces travaux pratiques est de programmer un embryon de pile TCP/IP sur un micro-contrôleur. Le micro-contrôleur doit analyser et générer des paquets UDP. Pour illuster le propos la pile TCP/IP contrôle LED et boutons d’une plateforme Arduino.
Pour cause de confinement vous n’avez pas accès à la plateforme Arduino, sauf si vous en disposez chez vous. Si c’est le cas ne vous privez pas de réaliser le TP classique (basculez sur le sujet habituel).
Pour ceux sans matériel, ce sujet vous permet de réaliser la majeure partie du travail au travers d’un nano-simulateur Arduino en C. Si vous ne disposez pas d’une machine avec une distribution Linux sérieuse vous savez utiliser les machines de projets Zabeth.
Un petit programme vous est fourni pour simuler un Arduino connecté à un port série de votre PC. Les sources sont disponibles ici : http://rex.plil.fr/Enseignement/Reseau/TP.Reseau.GIS3-covid/SimArduino.tgz.
Comme dans l’IDE Arduino vous avez la possibilité d’écrire votre programme dans les fonctions setup et loop (voir le fichier main.c).
Pour vous simplifier la vie, tout ce qui est port série est configuré pour vous, vous avez juste à remplir la fonction serialInHandler pour traiter les octets reçus par le simili-Arduino et à utiliser la fonction serialSend pour envoyer des octets (voir le fichier arduino.h pour les prototypes).
Votre Arduino est livré avec 4 boutons et 6 LED que vous pouvez gérer via les fonctions led et button (prototypes dans arduino.h). Dans ces fonctions vous précisez le numéro de la LED ou du bouton et vous imposez l’état (0 ou 1) pour la LED ou vous recevez l’état pour le bouton.
Vous avez même accès à une fonction millis qui retourne le nombre de millisecondes depuis un instant fixe. Grâce à cette fonction vous pouvez éviter des programmes avec des attentes actives qui sont autorisés en systèmes embarqués mais qui ne le sont pas sur un système multi-utilisateur.
N’utilisez pas d’attente avec la fonction sleep dans la fonction loop sinon le simulateur ne pourra pas fonctionner (gestion du port série et de l’entrée standard dans la boucle principale de la fonction main que vous trouverez dans arduino.c).
Quand le simulateur tourne, l’état des LED est représenté assez primitivement en ASCII et vous pouvez changer l’état des boutons (a à d pour les relacher, A à Z pour les enfoncer).
Ecrivez un petit programme dans main.c pour réaliser un chenillard sur les 6 LED de votre simili-Arduino. Faites en sorte que le chenillard démarre sur appui du premier bouton et se termine sur appui d’un bouton quelconque.
Pour compiler le programme vous avez juste à taper la commande make dans votre répertoire SimArduino. N’hésitez pas à sauver régulièrement votre programme dans votre archive GIT.
Lancez le simulateur dans une fenêtre en mode utilisateur. Notez le nom du port série créé par le simulateur, de la forme /dev/pts/XY.
Vous pouvez créer l’interface réseau sl0 avec l’utilitaire slattach ci-dessous dans un autre terminal en mode administateur :
slattach -Ldv -p slip -s 9600 /dev/pts/XY
Utilisez ensuite l’utilitaire ip, dans encore un autre terminal en mode administrateur, avec la syntaxe ci-dessous pour configurer les adresses IPv4 de votre interface sl0.
ip link set sl0 up ip address add dev sl0 <@IP1> peer <@IP2>
Vous pouvez utiliser des adresses IPv4 dans le réseau 192.168.0.0/24.
Pour tester votre connexion utilisez l’utilitaire ping sur l’adresse IPv4 de votre plateforme micro-contrôleur. Vérifiez que des octets arrivent sur le port série de votre simulateur.
Vous allez programmer votre simulateur piur analyser les paquets TCP/IP reçus et en générer d’autres. Sauvez votre main.c du chenillard dans un sous-répertoire, repartez d’un fichier main.c vierge. N’oubliez pas d’ajouter votre sous-répertoire dans votre archive GIT.
L’utilitaire slattach est configuré pour utiliser le protocole SLIP. Ce protocole permet de marquer la fin des paquets avec l’octet de valeur 0xc0.
A remarquer que le protocole SLIP de Linux met un 0xc0 aussi en début de paquet. Vous pouvez donc tomber sur deux 0xc0 de suite. Dans ce cas il ne faut pas penser avoir reçu un paquet vide.
Si ce caractère est présent dans le paquet lui-même, il est remplacé par les deux caractères 0xdb et 0xdc. Si le caractère d’échappement 0xdb est présent dans le paquet il est remplacé par les deux caractères 0xdb et 0xdd.
Commencez par mettre en place dans la fonction SerialInHandler, le décodage des paquets SLIP reçus, en suivant le protocole inverse de celui que nous venons d’expliquer. Affichez le contenu et la taille des paquets après décodage (vous pouvez utilisez le format %02x de printf pour afficher chaque octet). Vérifiez à l’aide de l’utilitaire ping. La taille indiquée après décodage doit correspondre à celle indiquée par ping (typiquement 84 octets).
Une fois le protocole SLIP géré, il faut traiter le paquet IPv4, contenant lui même un paquet UDP. Les premiers octets du paquet décodé contiennent donc les entêtes IPv4, viennent ensuite les entêtes UDP, puis enfin les données du paquet UDP.
Pour contrôler les LEDs de la plateforme nous allons nous baser sur ces données UDP.
Commencez par vérifier que le paquet reçu est un paquet UDP vous concernant :
Si le paquet est le paquet UDP attendu, prenez les octets de données et effectuez l’action correspondante sur les LEDs.
Vous pouvez tester votre programme en utilisant la commande Unix ci-dessous :
echo -en "\xff" | nc -q0 -u <adresse IP plateforme> <port UDP>
Sur réception d’un paquet UDP particulier, par exemple sur un second port UDP, votre plateforme doit renvoyer un paquet UDP sur le même port avec comme données l’état des boutons de la plateforme.
Vous devez donc constituer un paquet IPv4 contenant un paquet UDP contenant les données. Ce paquet doit être envoyé sur le port série en utilisant le protocole SLIP. N’oubliez pas de calculer la somme de contrôle IPv4 et éventuellement la somme de contrôle UDP.
Vous pouvez tester votre programme en utilisant la commande Unix ci-dessous :
nc -u -l -p <port UDP> | od -tx1 -w1
Vous pouvez écrire une petite application Web PHP pour gérer votre simulateur d’Arduino. Ne vous plongez pas dans une programmation bas niveau pour lequel vous n’avez pas eu de cours, utilisez simplement les fonctions fsockopen, fputs et fgets.
Prévoyez un formulaire HTML permettant de donner l’état des LED et un fichier PHP associé effectuant l’envoi UDP.
Le formulaire HTML est réduit à l’essentiel : un bouton de validation. Le fichier PHP associé fait l’envoi UDP et récupère le paquet UDP qui doit survenir dans la foulée. L’affichage de l’état des boutons se fait en HTML.
Il n’est pas interdit de rajouter des feuilles de styles pour améliorer l’esthétique de votre application Web. Il n’est pas non plus interdit d’ajouter du javascript pour rendre l’application plus dynamique : modification de l’état des LED par simple clic, affichage automatiquement mis à jour de l’état des boutons.
Ce document a été traduit de LATEX par HEVEA