P17 Sécurité de l'internet des objets : Différence entre versions

De Wiki de Projets IMA
m (Semaine 20 Feb 2017)
(Semaine 27 Feb 2017)
 
(4 révisions intermédiaires par le même utilisateur non affichées)
Ligne 36 : Ligne 36 :
 
: Emetteur non-officiel
 
: Emetteur non-officiel
  
; <span style="color: darkorange;">Étape 5 </span>- Analyse de consommation
+
; <span style="color: green;">Étape 5 </span>- Analyse de consommation
 
: Consommation énergétique d'une fenêtre d'écoute sur l'émetteur
 
: Consommation énergétique d'une fenêtre d'écoute sur l'émetteur
 
: Prévision long terme d'une consommation décuplée
 
: Prévision long terme d'une consommation décuplée
 +
 +
; <span style="color: green;">Étape 6 </span>- Rapport de PFE & soutenance
 +
: Rédaction rapport
 +
: Création de présentation
  
 
<br>
 
<br>
Ligne 289 : Ligne 293 :
 
[[Fichier:Lora_consommation.jpg|400px|thumb|Maquette d'analyse de consommation]]
 
[[Fichier:Lora_consommation.jpg|400px|thumb|Maquette d'analyse de consommation]]
  
J'ai choisis d'analyser dans un premier temps la requête ''join_request'' car le comportement est très similaire à un paquet normal. Les seules différences sont les délais entre les fenêtres d'écoute et le changement de fréquence.
+
J'ai choisis d'analyser dans un premier temps la requête ''join_request'' car le comportement est très similaire à un paquet normal. Les seules différences sont les délais entre les fenêtres d'écoute et le changement de fréquence. Les fenêtres d'écoute ont donc le même temps et sont transmise avec la même énergie. Voici un tableau réunissant des captures d'écran de l'analyseur de puissance Agilent pour une unique transmission (émission + 2 fenêtres d'écoute).
  
 
{| class="wikitable alternance centre"
 
{| class="wikitable alternance centre"
Ligne 309 : Ligne 313 :
  
 
[[Fichier:Lora_worst.gif|400px|thumb|Émission LoRa la plus couteuse]]
 
[[Fichier:Lora_worst.gif|400px|thumb|Émission LoRa la plus couteuse]]
Semtech recommande fortement dans la spécification LoRaWAN (''18.4 - Data-Rate Adaptation during Message Retransmissions'') d'adopter un schéma de re-transmission en cas d'échec de communication. Dans la pire situation, avec les paramètres de base et en suivant ces recommandations, la consommation d'énergie s'additionne très vite. Pour réaliser la transmission réussie la plus couteuse, on peut se placer dans le pire de cas :
+
Semtech recommande fortement dans la spécification LoRaWAN (''18.4 - Data-Rate Adaptation during Message Retransmissions'') d'adopter un schéma de re-transmission en cas d'échec de communication. Lors de ces retransmission, le message sera retransmis sur une autre fréquence parmi celles données la gateway lors de la procédure d'activation. De même, les taux d'encodages varient. Comme la gateway ''écoute'' sur toutes les fréquences qu'elle a autorisées et que le data-rate est indiqué dans l'entête de la trame, l'émetteur peut choisir aléatoirement ces paramètres. Ceci rend LoRa encore plus résistant aux interférences et au brouillage. On peut imaginer à l’extrême qu'une passerelle écoute sur des fréquences de bande ISM 868MHz '''et''' d'une autre bande, 433MHz par exemple.
* 8 tentatives d'émission
+
 
* 8 petites fenêtres d'écoute ratées
+
Dans la pire situation, avec les paramètres de base et en suivant ces recommandations, la consommation d'énergie s'additionne très vite. Pour réaliser la transmission réussie la plus couteuse, on se place dans le pire de cas :
* 7 grandes fenêtres d'écoute ratées
+
* Spreading factor maximum (SF 12) - temps d'émission le plus long
* Spreading factor maximum (SF 12)
 
 
* bande passante maximum (500kHz)
 
* bande passante maximum (500kHz)
 
* Maximum autorisée en émission en europe : 14dbm
 
* Maximum autorisée en émission en europe : 14dbm
 +
* 7 tentatives d'émission
 +
* 7 petites fenêtres d'écoute ratées
 +
* 7 grandes fenêtres d'écoute ratées
 +
* 8ème émission réussie
 +
* 8ème petite fenêtre d'écoute ratée
 +
* 8ème grande fenêtre d'écoute réussie
  
 
== Semaine 27 Feb 2017 ==
 
== Semaine 27 Feb 2017 ==
 +
 +
'''Rendu de fichier'''
 +
 +
L'intégralité du code source être trouvable à l'adresse suivante :
 +
 +
https://archives.plil.fr/u/jdenecha
 +
 +
Le rapport est déposé ici :
 +
 +
[[Fichier:Denechaud Rapport.pdf]]

Version actuelle datée du 1 mars 2017 à 11:55

Informations générales

Étudiants : Jérémie Denéchaud

Tuteurs : Alexandre Boé / Xavier Redon / Thomas Vantroys

Présentation du projet

Objectifs

L'Internet des objets est un secteur en plein accroissement. De nouveaux objets connectés sont disponibles tous les jours. Cependant, cette rapidité de mise en oeuvre se fait souvent au détriment de la sécurité. Les objectifs de ce projet sont de :

  • Effectuer un état de l'art sur les protocoles LoRa (Long Range) et LoRaWAN (Long Range Wide-area network ou Réseau étendu à longue portée)
  • Concevoir et réaliser une plate-forme d'analyse et de tests du comportement d'objets connectés selon l'ANSSI.

Étapes du projet

Étape 1 - Etat de l'art V1
Prise en main des protocoles
Description du fonctionnement global

Fichier:Etat Art LoRa V0.1.pdf

Étape 2 - Etude des risques V1
Détail du fonctionnement
Revue des menaces

Fichier:Lora Scénarios Menace.pdf

Étape 3 - LoRa ping-pong
Implémenter sur les board NUCELO le protocole LoRa
Faire communiquer les deux boards
Pas de surcouche LoRaWAN
Étape 4 - Gateway sur Raspberry Pi
Implémentation non-officielle d'une gateway
Emetteur non-officiel
Étape 5 - Analyse de consommation
Consommation énergétique d'une fenêtre d'écoute sur l'émetteur
Prévision long terme d'une consommation décuplée
Étape 6 - Rapport de PFE & soutenance
Rédaction rapport
Création de présentation


Matériel

Produit Quantité
Radio LoRa SX1276 2
Board ST NUCLEO (FE401RE) 2
Raspberry Pi B+ (+ carte SD 8Gb) 1

Avancée du projet

Semaine 16 Jan 2017

Prise de contact avec les tuteurs de projet. Définition des attentes et discussion sur le projet. Dans un premier temps, il est nécessaire de fournir un état de l'art sur la technologie LoRa et LoRaWAN. J'ai donc débuté la rédaction d'un document, en m'aidant des sources suivantes :

Référence 802.15.4: http://www.ieee802.org/15/pub/TG4.html

Guide du développeur et retour d'expérience d'Orange https://partner.orange.com/wp-content/uploads/2016/04/LoRa-Device-Developer-Guide-Orange.pdf

LoRa Application Note (quasiment le seul document technique sur la couche physique LoRa) http://www.semtech.com/images/datasheet/an1200.22.pdf

LoRaWAN Specifications (couche liaison) https://www.lora-alliance.org/portals/0/specs/LoRaWAN%20Specification%201R0.pdf

LoRa Design Guide https://www.semtech.com/images/datasheet/LoraDesignGuide_STD.pdf

Etudes déjà réalisées sur LoRa par reverse-engineering https://revspace.nl/DecodingLora

Matt Knight full reverse-engineering https://github.com/matt-knight/research/tree/master/2016_12_29_ccc-33c3

Ceci m'a permis d'avoir une première prise en main du protocole et de son inscription dans le marché concurrentiel qu'est l'IoT.

Semaine 23 Jan 2017

Réception du matériel :

Première version de l'état de l'art :
Fichier:Etat Art LoRa V0.1.pdf

J'ai commencé la rédaction d'une spécification technique autour de la sécurité des protocoles : limites, risques, menaces etc. Comme il est difficile de trouver des documentations assez précises et fiables, je me base sur le code source officiel : https://github.com/Lora-net

J'ai également commencé à prendre en main les boards programmables. Pour un hello-world basique à travers un port série par USB, j'ai rencontré quelques soucis de compatibilité (USB2.0 != USB3.0). Je programme et je compile dans l'IDE mbed prévu à cet effet.

Semaine 30 Jan 2017

USB2.0 != USB3.0

Voici le détail et et la résolution du problème USB2.0 / USB3.0. Le module noyau en charge d'allouer les terminaux tty détachait régulièrement (toutes les 3 à 5 sec) le périphérique NUCLEO. Voici les messages de log du noyau :

[13966.109866] usb 3-9: new full-speed USB device number 22 using xhci_hcd
[13966.239940] usb 3-9: New USB device found, idVendor=0483, idProduct=374b
[13966.239946] usb 3-9: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[13966.239950] usb 3-9: Product: STM32 STLink
[13966.239952] usb 3-9: Manufacturer: STMicroelectronics
[13966.239955] usb 3-9: SerialNumber: 0670FF575056805087031133
[13966.240229] usb 3-9: ep 0x84 - rounding interval to 1024 microframes, ep desc says 2040 microframes
[13966.295683] usb-storage 3-9:1.1: USB Mass Storage device detected
[13966.295954] scsi16 : usb-storage 3-9:1.1
[13966.296267] cdc_acm 3-9:1.2: This device cannot do calls on its own. It is not a modem.
[13966.296287] cdc_acm 3-9:1.2: ttyACM2: USB ACM device
[13967.295646] scsi 16:0:0:0: Direct-Access     MBED     microcontroller  1.0  PQ: 0 ANSI: 2
[13967.296255] sd 16:0:0:0: Attached scsi generic sg2 type 0
[13967.296562] sd 16:0:0:0: [sdb] 1072 512-byte logical blocks: (548 kB/536 KiB)
[13967.296841] sd 16:0:0:0: [sdb] Write Protect is off
[13967.296847] sd 16:0:0:0: [sdb] Mode Sense: 03 00 00 00
[13967.297101] sd 16:0:0:0: [sdb] No Caching mode page found
[13967.297107] sd 16:0:0:0: [sdb] Assuming drive cache: write through
[13967.304706]  sdb:
[13967.307414] sd 16:0:0:0: [sdb] Attached SCSI removable disk
[13984.989018] cdc_acm 3-9:1.2: failed to set dtr/rts
[13999.024323] cdc_acm 3-9:1.2: failed to set dtr/rts
[14016.061852] cdc_acm 3-9:1.2: failed to set dtr/rts
[14017.951574] usb 3-9: reset full-speed USB device number 22 using xhci_hcd

Lorsqu'on branche la carte programmable, le noyau la reconnaît bien et lui attribue un téléscripteur (ttyACMX). Cependant la dernière ligne indique que le module du noyau responsable de l'USB3.0 xhci_hcd a reset la connexion. La carte se reconnecte sous peu mais le problème est toujours le même. Lorsque la limite du nombre d'ACMX à allouer est atteinte (31) le module n'en n'alloue plus.

[10095.392845] cdc_acm 3-1:1.2: no more free acm devices
[10096.391780] scsi 12:0:0:0: Direct-Access     MBED     microcontroller  1.0  PQ: 0 ANSI: 2
[10096.392246] sd 12:0:0:0: Attached scsi generic sg2 type 0

Aucun soucis une fois passé sur un port USB2.0. C'est le module ehci_pci qui est alors utilisé. Il me semble possible de forcer l'utilisation de ce module sur un port USB donné.

Test de l'émission LoRa

J'ai pu ensuite rassembler les sources autour du protocole LoRaWAN et trier les sources officielles du code indépendant. Mbed possède un IDE en ligne qui permet d'écrire et de compiler rapidement du code pour les boards utilisées. Cependant, l'IDE n'est pas toujours explicite sur les erreurs de compilation. Parfois même on obtient une erreur interne sans aucun détail ou des timeout après plusieurs minutes de compilations. J'ai donc cloné mes projets localement et j'alterne entre différents environnements. L'IDE permet également de parcourir beaucoup plus facilement les librairies officielles de Semtech. Ceci a été très utile pour parcourir les très nombreuses primitives de la couche MAC du protocole.

Spectre LoRa montrant les chirp
Paquet join_request

Le code d'un end-device s'intègre parfaitement sur la radio SX1276, prévue à cet effet. J'ai pu donc effectuer mes premiers essais d'émission. A gauche, on a le spectre observé à l'aide d'une radio logicielle pour les paramètres suivants :

Fréquence : 868.1MHz
Spreading factor : 12
Coding rate : 4/5
Bande passante : 125kHz
activation : On-The-Air Activation

Ce paquet correspond à un join_request. Je n'ai pas réussis à contourner la procédure d'activation avec la procédure ABP (activation by personnalization) pour directement émettre des messages chiffrés. D'autres paramètres n'améliorent pas significativement la qualité visuelle du spectre. La faible qualité de ma radio ne me permet pas de distinguer les chirps caractéristiques du protocole LoRa (échantillonnage limité). A droite est représenté un exemple de spectre que l'on pourrait obtenir avec un radio de meilleure qualité.





Semaine 6 Feb 2017

Recherche

Les modules LoRa SX125x et SX127x sont prévus pour être des end-devices au sein d'un réseau LoRa. Le dépot github officiel de LoRaWAN distribue donc tout le code nécessaire pour des end-device avec ces radios. Cependant le code officiel fournis par Semtech pour une gateway n'est compatible (out of the box) qu'avec un chip SX1301. Je me suis donc renseigner sur les alternatives possibles et j'ai recherché du code existant qui se rapprochait le plus de ce que je voulais. Voici une liste non exhaustive des projets indépendants que j'ai trouvés :

Aucune des gateway présentée n'implémente le protocole LoRaWAN à proprement parlé. J'ai choisis de m'inspirer de ces exemples ainsi que des exemples et librairies officielles (Mbed & LoRaWAN) pour réaliser un premier programme simple pour tester la connectivité entre les deux radios.


Ping / Pong

Schéma des protocoles utilisés pour le ping/pong

Une carte programmable NUCLEO contrôle la puce LoRa SX1276 à travers une interface SPI. Une librairie existe déjà pour définir les constantes pour écrire / lire dans ces registres. J'ai donc ré-utilisé un exemple de communication entre deux radios LoRa pour rediriger les informations à travers une connexion série. Le schéma ci-dessous représente la maquette réalisée. Ce programme écoute le trafic LoRa en boucle sur une fréquence spécifique, avec des paramètres très spécifiques (spreading factor, bande passante, taille de buffer ...). Dès que l'on reçoit une trame, on regarde le contenu (ping ou pong) et cela va dicter la réponse à envoyer, toujours selon les mêmes paramètres radios.

Port série sur les deux radios

Ce mode de dialogue volontairement simpliste donne les résultats suivants :

  • On envoie un ping toutes les 3 secondes
  • La seconde radio accuse la réception, et renvoie un pong
  • Accusé de réception de la première radio, et renvoi toute de suite (10ms) d'un ping
  • ...

Les messages onRxDone et onTxDone sont affichés à des fins de debug. A l'aide d'une radio logicielle j'ai confirmation de l'échange entre les deux radios. On y voit bien les échanges de message et on devine l'allure des chirps. La fréquence est fixée à 867.1MHz et la bande passante est de 125kHz (spreading factor = 12). Pour distinguer les message des deux radios, j'ai enlevé l'antenne HF de l'une des deux. On peut ainsi facilement distinguer les radios juste à partir du spectre et de la puissance du signal reçu :

Lora ping pong2.jpg.png


Semaine 13 Feb 2017

Analyse des risques

Première version de l'analyse des risques du protocole LoRa : Fichier:Lora Scénarios Menace.pdf

En résumé, voici un schéma réunissant les principaux risques :

Principaux risques LoRa

Ping / Pong

A partir du ping/pong simple, j'ai essayé de réceptionner un join_request d'un end-device officiel. J'ai parcouru les primitives MAC afin de donner plus d'informations sur la transmission. Ces informations peuvent s'avérer très utiles pour debug.

Lora rssi.png

Grace a ces modifications, je peux communiquer n'importe quel message en utilisant la modulation LoRa. La taille du buffer à la réception doit simplement être supérieur au buffer de l'émetteur. J'ai ainsi pu faire communiquer le ping / pong dans des conditions difficiles et observer l'impact des interférences. En effet, très occasionnellement la radio réceptionnait un message erroné ('PONM' à la place de 'PONG', par exemple) car le CRC était désactivé. L'étape suivante est de paramétré très précisément les deux radios pour réceptionner le join_request.

La couche MAC implémentée officiellement par LoRaWAN est très dense et complexe. Elle se décompose ainsi :

  • MCPS - MAC Common Part Sublayer
  • MLME - MAC layer management entity
  • MIB - MAC information base

Pour configurer le récepteur et l'émetteur, les fonctions essentielles à appérer sont : SetRxConfig et SetTxConfig

/*!
    * @brief Sets the reception parameters
    *
    * @param [IN] modem        Radio modem to be used [0: FSK, 1: LoRa]
    * @param [IN] bandwidth    Sets the bandwidth
    *                          FSK : >= 2600 and <= 250000 Hz
    *                          LoRa: [0: 125 kHz, 1: 250 kHz,
    *                                 2: 500 kHz, 3: Reserved]
    * @param [IN] datarate     Sets the Datarate
    *                          FSK : 600..300000 bits/s
    *                          LoRa: [6: 64, 7: 128, 8: 256, 9: 512,
    *                                10: 1024, 11: 2048, 12: 4096  chips]
    * @param [IN] coderate     Sets the coding rate ( LoRa only )
    *                          FSK : N/A ( set to 0 )
    *                          LoRa: [1: 4/5, 2: 4/6, 3: 4/7, 4: 4/8]
    * @param [IN] bandwidthAfc Sets the AFC Bandwidth ( FSK only )
    *                          FSK : >= 2600 and <= 250000 Hz
    *                          LoRa: N/A ( set to 0 )
    * @param [IN] preambleLen  Sets the Preamble length ( LoRa only )
    *                          FSK : N/A ( set to 0 )
    *                          LoRa: Length in symbols ( the hardware adds 4 more symbols )
    * @param [IN] symbTimeout  Sets the RxSingle timeout value ( LoRa only )
    *                          FSK : N/A ( set to 0 )
    *                          LoRa: timeout in symbols
    * @param [IN] fixLen       Fixed length packets [0: variable, 1: fixed]
    * @param [IN] payloadLen   Sets payload length when fixed lenght is used
    * @param [IN] crcOn        Enables/Disables the CRC [0: OFF, 1: ON]
    * @param [IN] freqHopOn    Enables disables the intra-packet frequency hopping  [0: OFF, 1: ON] (LoRa only)
    * @param [IN] hopPeriod    Number of symbols bewteen each hop (LoRa only)
    * @param [IN] iqInverted   Inverts IQ signals ( LoRa only )
    *                          FSK : N/A ( set to 0 )
    *                          LoRa: [0: not inverted, 1: inverted]
    * @param [IN] rxContinuous Sets the reception in continuous mode
    *                          [false: single mode, true: continuous mode]
    */
   virtual void SetRxConfig ( RadioModems_t modem, uint32_t bandwidth,
                              uint32_t datarate, uint8_t coderate,
                              uint32_t bandwidthAfc, uint16_t preambleLen,
                              uint16_t symbTimeout, bool fixLen,
                              uint8_t payloadLen,
                              bool crcOn, bool freqHopOn, uint8_t hopPeriod,
                              bool iqInverted, bool rxContinuous ) = 0;

Même en changeant tous les paramètres à notre disposition, il a été impossible de réceptionner un join_request.

Semaine 20 Feb 2017

RPi Gateway

Afin d'avoir une maquette pour effectuer des mesures de consommation, il est nécessaire d'implémenter une passerelle LoRaWAN. La solution la plus pratique est d'utiliser une adaptation non-officielle du code pour une raspberry Pi. Le code officiel se trouve sur github et l'adaptation choisie a été réalisée par un néerlandais très impliqué dans le développement de LoRA : Thomas Telkamp. Une fois la Raspberry Pi installée et configurée correctement, j'ai essayé de capter un message join_request produit par un end-device (avec un code officiel). Voici le résultat :

Raspberry Pi contrôlant une radio LoRa
root@raspberrypi:/home/pi/single_chan_pkt_fwd # ./single_chan_pkt_fwd 
SX1276 detected, starting.
Gateway ID: b8:27:eb:ff:ff:2b:cb:30
Listening at SF7 on 868.100000 Mhz.
------------------
stat update: {"stat":{"time":"2016-11-27 18:06:41 GMT","lati":0.00000,"long":0.00000,"alti":0,"rxnb":0,"rxok":0,"rxfw":0,"ackr":0.0,"dwnb":0,
"txnb":0,"pfrm":"Single Channel Gateway","mail":"","desc":""}}
Packet RSSI: -64, RSSI: -109, SNR: 9, Length: 23
rxpk update: {"rxpk":[{"tmst":936035195,"chan":0,"rfch":0,"freq":868.100000,"stat":1,"modu":"LORA","datr":"SF7BW125","codr":"4/5",
"lsnr":9,"rssi":-64,"size":23,"data":"AAAAAAAAAAAAiHdmVUQzIhH2ZPzi8XU="}]}

On peut ensuite regarder le message transmis et l'analyser :

denechaud@2xs8:~$ base64 -d <<< AAAAAAAAAAAAiHdmVUQzIhH2ZPzi8XU= |hexdump -C
00000000  00 00 00 00 00 00 00 00  00 88 77 66 55 44 33 22  |..........wfUD3"|
00000010  11 f6 64 fc e2 f1 75                              |..d...u|
00000017

Le message correspond au PHY payload décrit dans la spécification. Pour un message join-request dans une version LoRaWAN R1, le MHDR vaut bien 00. On retrouve ensuite les données indiquée pour le provisionnement de l'end-device :

#define LORAWAN_APPLICATION_EUI                     { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }
#define LORAWAN_DEVICE_EUI                          { 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88 }

Les deux octets f6 64 correspondent au DevNonce. On a effectivement ce champ qui est aléatoirement généré à chaque nouveau join_request (après reset, pas re-transmission) Les quatre dernier octets fc e2 f1 75 correspondent au MIC, calculé à partir des valeurs précédentes.

Mesures de consommation

Une fois la gateway réalisée et fonctionnelle, on peut brancher l'émetteur LoRa sur un analyseur de puissance pour étudier la consommation.

Maquette d'analyse de consommation

J'ai choisis d'analyser dans un premier temps la requête join_request car le comportement est très similaire à un paquet normal. Les seules différences sont les délais entre les fenêtres d'écoute et le changement de fréquence. Les fenêtres d'écoute ont donc le même temps et sont transmise avec la même énergie. Voici un tableau réunissant des captures d'écran de l'analyseur de puissance Agilent pour une unique transmission (émission + 2 fenêtres d'écoute).

Fenêtre d'émission Fenêtre de réception n°1 Fenêtre de réception n°2
Lora transmit.gif Lora listen1.gif Lora listen2.gif
364mW de puissance moyenne pendant 61ms 36mW de puissance moyenne pendant 10ms 36mW de puissance moyenne pendant 164ms

Interprétation

Émission LoRa la plus couteuse

Semtech recommande fortement dans la spécification LoRaWAN (18.4 - Data-Rate Adaptation during Message Retransmissions) d'adopter un schéma de re-transmission en cas d'échec de communication. Lors de ces retransmission, le message sera retransmis sur une autre fréquence parmi celles données la gateway lors de la procédure d'activation. De même, les taux d'encodages varient. Comme la gateway écoute sur toutes les fréquences qu'elle a autorisées et que le data-rate est indiqué dans l'entête de la trame, l'émetteur peut choisir aléatoirement ces paramètres. Ceci rend LoRa encore plus résistant aux interférences et au brouillage. On peut imaginer à l’extrême qu'une passerelle écoute sur des fréquences de bande ISM 868MHz et d'une autre bande, 433MHz par exemple.

Dans la pire situation, avec les paramètres de base et en suivant ces recommandations, la consommation d'énergie s'additionne très vite. Pour réaliser la transmission réussie la plus couteuse, on se place dans le pire de cas :

  • Spreading factor maximum (SF 12) - temps d'émission le plus long
  • bande passante maximum (500kHz)
  • Maximum autorisée en émission en europe : 14dbm
  • 7 tentatives d'émission
  • 7 petites fenêtres d'écoute ratées
  • 7 grandes fenêtres d'écoute ratées
  • 8ème émission réussie
  • 8ème petite fenêtre d'écoute ratée
  • 8ème grande fenêtre d'écoute réussie

Semaine 27 Feb 2017

Rendu de fichier

L'intégralité du code source être trouvable à l'adresse suivante :

https://archives.plil.fr/u/jdenecha

Le rapport est déposé ici :

Fichier:Denechaud Rapport.pdf