Créer un réseau Thread avec des cartes nRF52840 et OpenThread

1. Introduction

26b7f4f6b3ea0700.png

OpenThread, publié par Google, est une implémentation Open Source du protocole réseau Thread®. Google Nest a publié OpenThread pour mettre la technologie utilisée dans les produits Nest à la disposition des développeurs afin d'accélérer le développement de produits pour la maison connectée.

La spécification Thread définit un protocole de communication sans fil fiable, sécurisé et basse consommation basé sur IPv6 pour les applications domestiques. OpenThread implémente toutes les couches réseau Thread, y compris IPv6, 6LoWPAN, IEEE 802.15.4 avec sécurité MAC, établissement de liens maillés et routage maillé.

Dans cet atelier de programmation, vous allez programmer OpenThread sur du matériel réel, créer et gérer un réseau Thread, et transmettre des messages entre les nœuds.

4806d16a8c137c6d.jpeg

Points abordés

  • Compiler et flasher les binaires de la CLI OpenThread sur des cartes de développement
  • Créer un RCP composé d'une machine Linux et d'une carte de développement
  • Communiquer avec un RCP à l'aide du daemon OpenThread et de ot-ctl
  • Gérer manuellement les nœuds Thread avec GNU Screen et l'interface de ligne de commande OpenThread
  • Configuration sécurisée des appareils sur un réseau Thread
  • Fonctionnement de la multidiffusion IPv6
  • Transmettre des messages entre les nœuds Thread avec UDP

Prérequis

Matériel :

  • 3 cartes de développement Nordic Semiconductor nRF52840
  • 3 câbles USB vers micro USB pour connecter les cartes
  • Une machine Linux avec au moins trois ports USB

Logiciels :

  • Chaîne d'outils GNU
  • Outils de ligne de commande Nordic nRF5x
  • Logiciel Segger J-Link
  • OpenThread
  • Git

2. Premiers pas

Simulation OpenThread

Avant de commencer, vous pouvez parcourir l'atelier de programmation sur la simulation OpenThread pour vous familiariser avec les concepts de base de Thread et la CLI OpenThread.

Terminaux de port série

Vous devez savoir comment vous connecter à un port série via un terminal. Cet atelier de programmation utilise GNU Screen et offre un aperçu de l'utilisation, mais vous pouvez utiliser n'importe quel autre logiciel de terminal.

Machine Linux

Cet atelier de programmation a été conçu pour une utilisation sur une machine Linux i386 ou x86 afin de servir d'hôte à un appareil Thread Radio Co-Processor (RCP) et de flasher toutes les cartes de développement Thread. Toutes les étapes ont été testées sur Ubuntu 14.04.5 LTS (Trusty Tahr).

Cartes Nordic Semiconductor nRF52840

Cet atelier de programmation utilise trois cartes nRF52840 PDK.

a6693da3ce213856.png

Nous utilisons SEGGER J-Link pour programmer les cartes nRF52840, qui disposent de modules JTAG intégrés. Installez-le sur votre machine Linux.

Téléchargez le package approprié pour votre machine et installez-le à l'emplacement adéquat. Sous Linux, il s'agit de /opt/SEGGER/JLink.

Installer les outils de ligne de commande nRF5x

Les outils de ligne de commande nRF5x vous permettent de flasher les binaires OpenThread sur les cartes nRF52840. Installez la version appropriée de nRF5x-Command-Line-Tools-<OS> sur votre machine Linux.

Placez le package extrait dans le dossier racine ~/.

Installer la chaîne d'outils ARM GNU

La chaîne d'outils ARM GNU est utilisée pour la compilation.

Nous vous recommandons de placer l'archive extraite dans /opt/gnu-mcu-eclipse/arm-none-eabi-gcc/ sur votre machine Linux. Suivez les instructions d'installation figurant dans le fichier readme.txt de l'archive.

Installer Screen (facultatif)

Screen est un outil simple permettant d'accéder aux appareils connectés par un port série. Cet atelier de programmation utilise Screen, mais vous pouvez utiliser l'application de terminal de port série de votre choix.

$ sudo apt-get install screen

3. Cloner des dépôts

OpenThread

Clonez et installez OpenThread. Les commandes script/bootstrap permettent de s'assurer que la chaîne d'outils est installée et que l'environnement est correctement configuré :

$ mkdir -p ~/src
$ cd ~/src
$ git clone --recursive https://github.com/openthread/openthread.git
$ cd openthread
$ ./script/bootstrap

Créez le daemon OpenThread :

$ script/cmake-build posix -DOT_DAEMON=ON

Vous êtes maintenant prêt à compiler et à flasher OpenThread sur les cartes nRF52840.

4. Configurer RCP Joiner

Compiler et flasher

Créez l'exemple OpenThread nRF52840 avec Joiner et la fonctionnalité USB native. Un appareil utilise le rôle de Joiner pour être authentifié et mis en service de manière sécurisée sur un réseau Thread. L'USB natif permet d'utiliser USB CDC ACM comme transport série entre le nRF52840 et l'hôte.

Nettoyez toujours le dépôt des builds précédents en exécutant rm -rf build.

$ cd ~/src
$ git clone --recursive https://github.com/openthread/ot-nrf528xx.git
$ cd ot-nrf528xx
$ script/build nrf52840 USB_trans

Accédez au répertoire contenant le fichier binaire OpenThread RCP, puis convertissez-le au format hexadécimal :

$ cd ~/src/ot-nrf528xx/build/bin
$ arm-none-eabi-objcopy -O ihex ot-rcp ot-rcp.hex

Branchez le câble USB au port de débogage micro-USB situé à côté du connecteur d'alimentation externe sur la carte nRF52840, puis branchez-le sur la machine Linux. Réglez le commutateur Source d'alimentation nRF sur la carte nRF52840 sur VDD. Lorsque le câble est correctement branché, la LED5 est allumée.

20a3b4b480356447.png

Si c'est la première carte connectée à la machine Linux, elle apparaît sous le port série /dev/ttyACM0 (toutes les cartes nRF52840 utilisent ttyACM comme identifiant de port série).

$ ls /dev/ttyACM*
/dev/ttyACM0

Notez le numéro de série de la carte nRF52840 utilisée pour le RCP :

c00d519ebec7e5f0.jpeg

Accédez à l'emplacement des outils de ligne de commande nRFx et flashez le fichier hexadécimal OpenThread RCP sur la carte nRF52840 à l'aide du numéro de série de la carte. Notez que si vous omettez l'indicateur --verify, un message d'avertissement s'affichera pour vous indiquer que le processus de flashage peut échouer sans erreur.

$ cd ~/nrfjprog/
$ ./nrfjprog -f nrf52 -s 683704924  --verify --chiperase --program \
       ~/src/ot-nrf528xx/build/bin/ot-rcp.hex --reset

Le résultat suivant est généré en cas de succès :

Parsing hex file.
Erasing user available code and UICR flash areas.
Applying system reset.
Checking that the area to write is not protected.
Programing device.
Applying system reset.
Run.

Nommez le tableau "RCP" pour ne pas confondre les rôles de tableau par la suite.

Se connecter à l'USB natif

Étant donné que la compilation OpenThread RCP permet d'utiliser le protocole USB CDC ACM natif comme transport série, vous devez utiliser le port nRF USB sur la carte nRF52840 pour communiquer avec l'hôte RCP (machine Linux).

Détachez l'extrémité micro-USB du câble USB du port de débogage de la carte nRF52840 flashée, puis rebranchez-la au port micro-USB nRF USB à côté du bouton RESET. Définissez le commutateur Source d'alimentation nRF sur USB.

46e7b670d2464842.png

Démarrer le daemon OpenThread

Dans la conception RCP, utilisez OpenThread Daemon pour communiquer avec l'appareil Thread et le gérer. Démarrez ot-daemon avec l'option verbose -v pour afficher la sortie du journal et confirmer qu'il est en cours d'exécution :

$ cd ~/src/openthread
$ sudo ./build/posix/src/posix/ot-daemon -v \
    'spinel+hdlc+uart:///dev/ttyACM0?uart-baudrate=460800'

Si l'opération réussit, ot-daemon en mode verbeux génère un résultat semblable à celui-ci :

ot-daemon[12463]: Running OPENTHREAD/thread-reference-20200818-1938-g0f10480ed; POSIX; Aug 30 2022 10:55:05
ot-daemon[12463]: Thread version: 4
ot-daemon[12463]: Thread interface: wpan0
ot-daemon[12463]: RCP version: OPENTHREAD/thread-reference-20200818-1938-g0f10480ed; SIMULATION; Aug 30 2022 10:54:10

Laissez cette fenêtre de terminal ouverte pour pouvoir consulter les journaux de ot-daemon.

Utilisez ot-ctl pour communiquer avec le nœud RCP. ot-ctl utilise la même CLI que l'application OpenThread CLI. Vous pouvez donc contrôler les nœuds ot-daemon de la même manière que les autres appareils Thread simulés.

Dans une deuxième fenêtre de terminal, démarrez ot-ctl :

$ sudo ./build/posix/src/posix/ot-ctl
>

Vérifiez le state du nœud 2 (nœud RCP) que vous avez démarré avec ot-daemon :

> state
disabled
Done

5. Configurer les FTD

Les deux autres nœuds Thread utilisés dans cet atelier de programmation sont des appareils Thread complets (FTD) sur la conception standard du système sur puce (SoC). Un appareil fonctionne en tant que commissaire pour authentifier et mettre en service de manière sécurisée les appareils sur ce réseau. L'autre appareil fonctionne comme un Joiner que le Commissioner peut authentifier sur le réseau Thread.

Compiler et flasher

Créez l'exemple OpenThread FTD pour la plate-forme nRF52840, avec les rôles "Commissaire" et "Joiner" activés :

$ cd ~/src/ot-nrf528xx
$ rm -rf build
$ script/build nrf52840 USB_trans -DOT_JOINER=ON -DOT_COMMISSIONER=ON

Accédez au répertoire contenant le fichier binaire CLI OpenThread Full Thread Device (FTD) et convertissez-le au format hexadécimal :

$ cd ~/src/ot-nrf528xx/build/bin
$ arm-none-eabi-objcopy -O ihex ot-cli-ftd ot-cli-ftd.hex

Branchez le câble USB au port micro-USB situé à côté du connecteur d'alimentation externe sur la carte nRF52840, puis branchez-le sur la machine Linux. Si le RCP est toujours connecté à la machine Linux, cette nouvelle carte devrait apparaître en tant que port série /dev/ttyACM1 (toutes les cartes nRF52840 utilisent ttyACM comme identifiant de port série).

$ ls /dev/ttyACM*
/dev/ttyACM0  /dev/ttyACM1

Comme précédemment, notez le numéro de série de la carte nRF52840 utilisée pour le FTD :

c00d519ebec7e5f0.jpeg

Accédez à l'emplacement des outils de ligne de commande nRFx et flashez le fichier hexadécimal FTD de la CLI OpenThread sur la carte nRF52840, en utilisant le numéro de série de la carte :

$ cd ~/nrfjprog/
$ ./nrfjprog -f nrf52 -s 683704924 --verify --chiperase --program \
       ~/src/ot-nrf528xx/build/bin/ot-cli-ftd.hex --reset

Nommez le tableau "Commissaire".

Se connecter à l'USB natif

Étant donné que la compilation OpenThread FTD permet d'utiliser le port USB CDC ACM natif comme transport série, vous devez utiliser le port nRF USB sur la carte nRF52840 pour communiquer avec l'hôte RCP (machine Linux).

Détachez l'extrémité micro-USB du câble USB du port de débogage de la carte nRF52840 flashée, puis rebranchez-la au port micro-USB nRF USB à côté du bouton RESET. Définissez le commutateur Source d'alimentation nRF sur USB.

46e7b670d2464842.png

Vérifier la compilation

Vérifiez que la compilation a réussi en accédant à la CLI OpenThread à l'aide de GNU Screen depuis une fenêtre de terminal.

$ screen /dev/ttyACM1

Dans la nouvelle fenêtre, appuyez plusieurs fois sur la touche Retour du clavier pour afficher l'invite > de l'interface de ligne de commande OpenThread. Affichez l'interface IPv6 et recherchez des adresses :

> ifconfig up
Done
> ipaddr
fe80:0:0:0:1cd6:87a9:cb9d:4b1d
Done

Utiliser Ctrl+a →

d : pour vous déconnecter de l'écran de la CLI FTD Commissioner et revenir au terminal Linux afin de pouvoir flasher la carte suivante. Pour revenir à la CLI à tout moment, utilisez screen -r à partir de la ligne de commande. Pour afficher la liste des écrans disponibles, utilisez screen -ls :

$ screen -ls
There is a screen on:
        74182.ttys000.mylinuxmachine        (Detached)
1 Socket in /tmp/uscreens/S-username.

Configurer le joiner FTD

Répétez la procédure ci-dessus pour flasher la troisième carte nRF52840, en utilisant le build ot-cli-ftd.hex existant. Une fois l'opération terminée, veillez à reconnecter la carte au PC à l'aide du port USB nRF et à régler le commutateur nRF power source sur VDD.

Si les deux autres nœuds sont associés à la machine Linux lorsque cette troisième carte est associée, elle devrait apparaître comme port série /dev/ttyACM2 :

$ ls /dev/ttyACM*
/dev/ttyACM0  /dev/ttyACM1  /dev/ttyACM2

Nommez le tableau "Joiner".

Lorsque vous effectuez la validation à l'aide de Screen, au lieu de créer une instance de Screen à partir de la ligne de commande, rattachez-vous à celle existante et créez une fenêtre dans celle-ci (celle que vous avez utilisée pour le commissaire FTD) :

$ screen -r

Créez la nouvelle fenêtre dans Screen avec Ctrl+a → c.

Une nouvelle invite de ligne de commande s'affiche. Accédez à la CLI OpenThread pour le FTD Joiner :

$ screen /dev/ttyACM2

Dans cette nouvelle fenêtre, appuyez plusieurs fois sur la touche Retour du clavier pour afficher l'invite de ligne de commande OpenThread >. Affichez l'interface IPv6 et recherchez des adresses :

> ifconfig up
Done
> ipaddr
fe80:0:0:0:6c1e:87a2:df05:c240
Done

Maintenant que la CLI FTD Joiner se trouve dans la même instance de Screen que FTD Commissioner, vous pouvez passer de l'une à l'autre à l'aide de Ctrl+a → n.

Utiliser Ctrl+a →

d à tout moment pour quitter l'écran.

6. Configurer la fenêtre du terminal

À l'avenir, vous passerez fréquemment d'un appareil Thread à un autre. Assurez-vous donc qu'ils sont tous actifs et facilement accessibles. Jusqu'à présent, nous avons utilisé Screen pour accéder aux deux FTD. Cet outil permet également de partager l'écran dans la même fenêtre de terminal. Utilisez cette option pour voir comment un nœud réagit aux commandes émises sur un autre.

Idéalement, vous devriez disposer de quatre fenêtres :

  1. Service ot-daemon / journaux
  2. RCP Joiner via ot-ctl
  3. Commissaire FTD via la CLI OpenThread
  4. FTD Joiner via la CLI OpenThread

Si vous souhaitez utiliser votre propre configuration ou outil de port série / terminal, vous pouvez passer à l'étape suivante. Configurez les fenêtres de terminal pour tous les appareils de la manière qui vous convient le mieux.

Utiliser l'écran

Pour plus de simplicité, ne démarrez qu'une seule session Screen. Vous devriez déjà en avoir un depuis la configuration des deux FTD.

Toutes les commandes de Screen commencent par Ctrl+a.

Commandes de base pour l'écran :

Rattacher à la session Screen (depuis la ligne de commande)

screen -r

Quitter la session Screen

Ctrl+a → d

Créer une fenêtre dans la session Screen

Ctrl+a → c

Passer d'une fenêtre à l'autre dans la même session Screen

Ctrl+a → n (avant)Ctrl+a → p (arrière)

Fermer la fenêtre actuelle dans la session Screen

Ctrl+a → k

Écran partagé

Avec Screen, vous pouvez diviser le terminal en plusieurs fenêtres :

f1cbf1258cf0a5a.png

Les commandes de screen sont accessibles à l'aide de Ctrl+a. Chaque commande doit commencer par cette combinaison de touches d'accès.

Si vous avez suivi exactement l'atelier de programmation, vous devriez avoir deux fenêtres (FTD Commissioner, FTD Joiner) sur la même instance Screen. Pour partager l'écran entre les deux, commencez par accéder à votre session Screen existante :

$ screen -r

Vous devez vous trouver sur l'un des appareils FTD. Procédez comme suit dans Screen :

  1. Ctrl+a → S pour diviser la fenêtre horizontalement
  2. Ctrl+a → Tab pour déplacer le curseur vers la nouvelle fenêtre vide
  3. Ctrl+a → n pour passer à la fenêtre suivante
  4. Si elle est identique à la fenêtre supérieure, appuyez à nouveau sur Ctrl+a → n pour afficher l'autre appareil FTD.

Les deux sont désormais visibles. Pour passer de l'un à l'autre, utilisez Ctrl+a → Tab. Nous vous recommandons de renommer chaque fenêtre avec Ctrl+a → A pour éviter toute confusion.

Utilisation avancée

Pour diviser davantage l'écran en quadrants et afficher les journaux ot-daemon et le RCP Joiner ot-ctl, ces services doivent être démarrés dans la même instance d'écran. Pour ce faire, arrêtez ot-daemon et quittez ot-ctl, puis redémarrez-les dans de nouvelles fenêtres Screen (Ctrl+a → c).

Cette configuration n'est pas obligatoire et est laissée à la discrétion de l'utilisateur.

Répartissez les fenêtres et naviguez entre elles à l'aide des commandes suivantes :

Créer une fenêtre

Ctrl+a → c

Diviser la fenêtre verticalement

Ctrl+a →

Diviser la fenêtre horizontalement

Ctrl+a → S

Passer à la fenêtre affichée suivante

Ctrl+a → Tab

Passer à la fenêtre affichée suivante ou précédente

Ctrl+a → n ou p

Renommer la fenêtre actuelle

Ctrl+a → A

Quittez Screen à tout moment avec Ctrl+a → d et rattachez-vous avec screen -r depuis la ligne de commande.

Pour en savoir plus sur Screen, consultez la documentation de référence rapide de GNU Screen.

7. Créer le réseau Thread

Maintenant que vous avez configuré toutes vos fenêtres et tous vos écrans de terminal, créons notre réseau Thread. Sur le commissaire FTD, créez un ensemble de données opérationnelles et validez-le comme ensemble de données actif. L'ensemble de données opérationnelles correspond à la configuration du réseau Thread que vous créez.

## FTD Commissioner ##
----------------------

> dataset init new
Done
> dataset
Active Timestamp: 1
Channel: 11
Channel Mask: 07fff800
Ext PAN ID: c0de7ab5c0de7ab5
Mesh Local Prefix: fdc0:de7a:b5c0/64
Network Key: 1234c0de7ab51234c0de7ab51234c0de
Network Name: OpenThread-c0de
PAN ID: 0xc0de
PSKc: ebb4f2f8a68026fc55bcf3d7be3e6fe4
Security Policy: 0, onrcb
Done

Notez la clé réseau 1234c0de7ab51234c0de7ab51234c0de, car vous en aurez besoin ultérieurement.

Validez cet ensemble de données comme actif :

> dataset commit active
Done

Activez l'interface IPv6 :

> ifconfig up
Done

Démarrer l'opération du protocole Thread :

> thread start
Done

Après quelques instants, vérifiez l'état de l'appareil. Il doit s'agir du responsable. Obtenez également le RLOC16 pour référence ultérieure.

## FTD Commissioner ##
----------------------

> state
leader
Done
> rloc16
0c00
Done

Vérifiez les adresses IPv6 de l'appareil :

## FTD Commissioner ##
----------------------

> ipaddr
fdc0:de7a:b5c0:0:0:ff:fe00:fc00        # Leader Anycast Locator (ALOC)
fdc0:de7a:b5c0:0:0:ff:fe00:c00         # Routing Locator (RLOC)
fdc0:de7a:b5c0:0:6394:5a75:a1ad:e5a    # Mesh-Local EID (ML-EID)
fe80:0:0:0:1cd6:87a9:cb9d:4b1d         # Link-Local Address (LLA)

Le réseau "codelab" est désormais visible lorsqu'il est analysé à partir d'autres appareils Thread.

Depuis ot-ctl sur RCP Joiner :

## RCP Joiner ##
----------------

> scan
| PAN  | MAC Address      | Ch | dBm | LQI |
+------+------------------+----+-----+-----+
| c0de | 1ed687a9cb9d4b1d | 11 | -36 | 232 |

Depuis la CLI OpenThread sur le FTD Joiner :

## FTD Joiner ##
----------------

> scan
| PAN  | MAC Address      | Ch | dBm | LQI |
+------+------------------+----+-----+-----+
| c0de | 1ed687a9cb9d4b1d | 11 | -38 | 229 |

Si le réseau "codelab" n'apparaît pas dans la liste, essayez de scanner à nouveau.

8. Ajouter le RCP Joiner

La mise en service Thread n'est pas active sur le réseau. Nous devons donc ajouter le RCP Joiner au réseau Thread que nous venons de créer à l'aide d'un processus de mise en service hors bande.

Sur le FTD Commissioner, nous avons noté la clé réseau, par exemple 1234c0de7ab51234c0de7ab51234c0de. Si vous devez rechercher à nouveau la clé réseau, exécutez la commande suivante sur le commissaire FTD :

## FTD Commissioner ##

> dataset networkkey
1234c0de7ab51234c0de7ab51234c0de
Done

Ensuite, dans RCP Joiner, définissez la clé réseau de son ensemble de données actif sur la clé réseau du commissaire FTD :

## RCP Joiner ##
----------------

> dataset networkkey 1234c0de7ab51234c0de7ab51234c0de
Done
> dataset commit active
Done

Vérifiez que l'ensemble de données est correctement défini.

## RCP Joiner ##
----------------

> dataset
Network Key: 1234c0de7ab51234c0de7ab51234c0de

Affichez Thread pour que le RCP Joiner rejoigne le réseau "codelab". Patientez quelques secondes, puis vérifiez l'état, le RLOC16 et ses adresses IPv6 :

## RCP Joiner ##
----------------

> ifconfig up
Done
> thread start
Done
> state
child
Done
> rloc16
0c01
Done
> ipaddr
fdc0:de7a:b5c0:0:0:ff:fe00:0c01         # Routing Locator (RLOC)
fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f    # Mesh-Local EID (ML-EID)
fe80:0:0:0:18e5:29b3:a638:943b          # Link-Local Address (LLA)
Done

Notez l'adresse IPv6 locale du réseau maillé (fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f ici), car vous en aurez besoin plus tard.

De retour sur la page FTD Commissioner, vérifiez les tables du routeur et de l'enfant pour confirmer que les deux appareils font partie du même réseau. Utilisez le RLOC16 pour identifier le RCP Joiner.

## FTD Commissioner ##
----------------------

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |
+----+--------+----------+-----------+-------+--------+-----+------------------+
|  3 | 0x0c00 |        3 |         0 |     0 |      0 |  35 | 1ed687a9cb9d4b1d |

Done
> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|VER| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+---+------------------+
|   1 | 0x0c01 |        240 |         25 |     3 |   89 |1|1|1|  2| 1ae529b3a638943b |
Done

Effectuez un ping sur l'adresse locale du réseau du nœud de raccordement RCP (adresse locale du réseau obtenue à partir de la sortie ipaddr du nœud de raccordement RCP) pour vérifier la connectivité :

## FTD Commissioner ##
----------------------

> ping fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f
> 8 bytes from fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f: icmp_seq=1 hlim=64 time=40ms

Nous disposons à présent d'un réseau Thread composé de deux nœuds, comme l'illustre ce schéma de topologie :

otcodelab_top01C_2nodes.png

Diagrammes de topologie

Au fur et à mesure que vous progresserez dans l'atelier de programmation, nous afficherons un nouveau diagramme de topologie Thread chaque fois que l'état du réseau changera. Les rôles de nœud sont indiqués comme suit :

b75a527be4563215.png

Les routeurs sont toujours des pentagones et les appareils finaux sont toujours des cercles. Les chiffres de chaque nœud représentent l'ID du routeur ou l'ID de l'enfant affiché dans la sortie de l'interface de ligne de commande, en fonction du rôle et de l'état actuels de chaque nœud à ce moment-là.

9. Commander le Joiner FTD

Ajoutons maintenant le troisième appareil Thread au réseau "codelab". Cette fois, nous allons utiliser le processus de mise en service intégré plus sécurisé et n'autoriser que le FTD Joiner à rejoindre le réseau.

Sur le FTD Joiner, obtenez le eui64 afin que le commissaire FTD puisse l'identifier :

## FTD Joiner ##
----------------

> eui64
2f57d222545271f1
Done

Sur le commissaire FTD, démarrez le commissaire et spécifiez le eui64 de l'appareil pouvant rejoindre le réseau, ainsi que les identifiants de l'intégrateur, par exemple J01NME. L'identifiant de l'appareil est une chaîne de caractères alphanumériques (0-9 et A-Y, à l'exclusion de I, O, Q et Z pour une meilleure lisibilité) en majuscules, d'une longueur comprise entre 6 et 32 caractères.

## FTD Commissioner ##
----------------------

> commissioner start
Done
> commissioner joiner add 2f57d222545271f1 J01NME
Done

Passez à FTD Joiner. Démarrez le rôle de membre avec les identifiants de membre que vous venez de configurer sur le commissaire FTD :

## FTD Joiner ##
----------------

> ifconfig up
Done
> joiner start J01NME
Done

Au bout d'une minute environ, vous recevez une confirmation de l'authentification :

## FTD Joiner ##
----------------

>
Join success

Lancez Thread pour que le Joiner FTD rejoigne le réseau "codelab", puis vérifiez immédiatement l'état et le RLOC16 :

## FTD Joiner ##
----------------

> thread start
Done
> state
child
Done
> rloc16
0c02
Done

Vérifiez les adresses IPv6 de l'appareil. Notez qu'il n'y a pas d'ALOC. En effet, cet appareil n'est pas le leader et ne détient pas de rôle Anycast spécifique nécessitant une ALOC.

## FTD Joiner ##
----------------

> ipaddr
fdc0:de7a:b5c0:0:0:ff:fe00:c02         # Routing Locator (RLOC)
fdc0:de7a:b5c0:0:3e2e:66e:9d41:ebcd    # Mesh-Local EID (ML-EID)
fe80:0:0:0:e4cd:d2d9:3249:a243         # Link-Local Address (LLA)

Passez immédiatement à l'outil de mise en service FTD et vérifiez les tables de routeur et enfant pour confirmer que trois appareils existent dans le réseau "codelab" :

## FTD Commissioner ##
----------------------

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |
+----+--------+----------+-----------+-------+--------+-----+------------------+
|  3 | 0x0c00 |        3 |         0 |     0 |      0 |  50 | 1ed687a9cb9d4b1d |

> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|N| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+-+------------------+
|   1 | 0x0c01 |        240 |         25 |     3 |   89 |1|1|1|1| 1ae529b3a638943b |
|   2 | 0x0c02 |        240 |         15 |     3 |   44 |1|1|1|1| e6cdd2d93249a243 |
Done

Sur la base du RLOC16, le FTD Joiner s'est connecté au réseau en tant qu'appareil final (enfant). Voici notre topologie mise à jour :

otcodelab_top01C_ed01.png

10. Fil de discussion en action

Les appareils Thread de cet atelier de programmation sont un type spécifique d'appareil Thread complet (FTD, Full Thread Device) appelé "Router Eligible End Device" (REED). Cela signifie qu'ils peuvent fonctionner comme routeur ou comme appareil final, et qu'ils peuvent passer d'un appareil final à un routeur.

Thread peut prendre en charge jusqu'à 32 routeurs, mais essaie de maintenir le nombre de routeurs entre 16 et 23. Si un REED se connecte en tant qu'appareil final (enfant) et que le nombre de routeurs est inférieur à 16, il se promeut automatiquement en routeur après une période aléatoire de deux minutes.

Si vous aviez deux enfants dans votre réseau Thread après avoir ajouté le FTD Joiner, attendez au moins deux minutes, puis vérifiez à nouveau les tables de routeur et d'enfant sur le FTD Commissioner :

## FTD Commissioner ##
----------------------

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |
+----+--------+----------+-----------+-------+--------+-----+------------------+
|  3 | 0x0c00 |        3 |         0 |     0 |      0 |  50 | 1ed687a9cb9d4b1d |
| 46 | 0xb800 |       63 |         0 |     3 |      3 |   1 | e6cdd2d93249a243 |

> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|N| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+-+------------------+
|   1 | 0x0c01 |        240 |         61 |     3 |   89 |1|1|1|1| 1ae529b3a638943b |
Done

Le FTD Joiner (Extended MAC = e6cdd2d93249a243) s'est promu au rôle de routeur. Notez que le RLOC16 est différent (b800 au lieu de 0c02). En effet, le RLOC16 est basé sur l'ID du routeur et l'ID enfant d'un appareil. Lorsqu'il passe d'un appareil final à un routeur, ses valeurs d'ID de routeur et d'ID enfant changent, tout comme le RLOC16.

otcodelab_top01C.png

Vérifiez le nouvel état et le RLOC16 sur le FTD Joiner :

## FTD Joiner ##
----------------

> state
router
Done
> rloc16
b800
Done

Rétrograder le joiner FTD

Vous pouvez tester ce comportement en rétrogradant manuellement le FTD Joiner d'un routeur à un appareil final. Définissez l'état sur "enfant" et vérifiez le RLOC16 :

## FTD Joiner ##
----------------

> state child
Done
> rloc16
0c03
Done

otcodelab_top01C_ed02.png

De retour dans FTD Commissioner, le FTD Joiner devrait maintenant apparaître dans le tableau enfant (ID = 3). Il peut même être présent dans les deux pendant la transition :

## FTD Commissioner ##
----------------------

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |
+----+--------+----------+-----------+-------+--------+-----+------------------+
|  3 | 0x0c00 |        3 |         0 |     0 |      0 |  50 | 1ed687a9cb9d4b1d |
| 46 | 0xb800 |       63 |         0 |     3 |      3 |   1 | e6cdd2d93249a243 |

> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|N| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+-+------------------+
|   1 | 0x0c01 |        240 |         61 |     3 |   89 |1|1|1|1| 1ae529b3a638943b |
|   3 | 0x0c03 |        240 |         16 |     3 |   94 |1|1|1|1| e6cdd2d93249a243 |
Done

Au bout d'un certain temps, il repassera à un routeur avec un RLOC de b800.

otcodelab_top01C.png

Supprimer le responsable

Le leader est auto-élu parmi tous les routeurs Thread. Cela signifie que si le leader actuel est supprimé du réseau Thread, l'un des autres routeurs deviendra le nouveau leader.

Sur le commissaire FTD, désactivez Thread pour le supprimer du réseau Thread :

## FTD Commissioner ##
----------------------

> thread stop
Done
> ifconfig down
Done

Au bout de deux minutes, le FTD Joiner devient le nouveau leader Thread. Vérifiez l'état et les adresses IPv6 du FTD Joiner pour confirmer :

## FTD Joiner ##
----------------

> state
leader
Done
> ipaddr
fdc0:de7a:b5c0:0:0:ff:fe00:fc00       # Now it has the Leader ALOC!
fdc0:de7a:b5c0:0:0:ff:fe00:b800
fdc0:de7a:b5c0:0:3e2e:66e:9d41:ebcd
fe80:0:0:0:e4cd:d2d9:3249:a243
Done

otcodelab_top02C_01.png

Vérifiez la table enfant. Notez qu'un nouveau RLOC16 est disponible. Il s'agit du RCP Joiner, comme l'indiquent son ID et son adresse MAC étendue. Pour que le réseau Thread reste cohérent, il a changé de routeur parent, passant du FTD Commissioner au FTD Joiner. Cela entraîne un nouveau RLOC16 pour le RCP Joiner (car son ID de routeur est passé de 3 à 46).

## FTD Joiner ##
----------------

> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|N| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+-+------------------+
|   1 | 0xb801 |        240 |         27 |     3 |  145 |1|1|1|1| 1ae529b3a638943b |
Done

Vous devrez peut-être attendre quelques minutes pour que RCP Joiner s'associe à FTD Joiner en tant qu'enfant. Vérifiez l'état et le RLOC16 pour confirmer que :

## RCP Joiner ##
--------------

> state
child
> rloc16
b801

Rattacher le commissaire FTD

Un réseau Thread avec deux nœuds n'est pas très amusant. Remettons le commissaire FTD en ligne.

Sur le commissaire FTD, redémarrez Thread :

## FTD Commissioner ##
----------------------

> ifconfig up
Done
> thread start
Done

En moins de deux minutes, il se rattache automatiquement au réseau "codelab" en tant qu'appareil final, puis se promeut en routeur.

## FTD Commissioner ##
----------------------

> state
router
Done

Vérifiez les tables de routeur et enfant sur le FTD Joiner pour vérifier les points suivants :

## FTD Joiner ##
----------------

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC     |
+----+--------+----------+-----------+-------+--------+-----+------------------+
|  3 | 0x0c00 |       63 |         0 |     3 |      3 |   0 | 1ed687a9cb9d4b1d |
| 46 | 0xb800 |       46 |         0 |     0 |      0 |  15 | e6cdd2d93249a243 |

> child table
| ID  | RLOC16 | Timeout    | Age        | LQ In | C_VN |R|S|D|N| Extended MAC     |
+-----+--------+------------+------------+-------+------+-+-+-+-+------------------+
|   1 | 0xb801 |        240 |        184 |     3 |  145 |1|1|1|1| 1ae529b3a638943b |
Done

otcodelab_top02C_02.png

Notre réseau Thread se compose à nouveau de trois nœuds.

11. Dépannage

Gérer un réseau Thread avec plusieurs appareils dans différentes fenêtres de terminal ou d'écran peut être compliqué. Utilisez ces conseils pour "réinitialiser" l'état du réseau ou de votre espace de travail si vous rencontrez des problèmes.

Écran

Si vous vous perdez dans votre configuration (trop de fenêtres Screen ou de Screens dans Screen), continuez à fermer les fenêtres Screen avec Ctrl+a → k jusqu'à ce qu'il n'y en ait plus et que screen -ls sur la ligne de commande affiche No Sockets found. Recréez ensuite les fenêtres Screen pour chaque appareil. Les états de l'appareil sont conservés même lorsque l'écran est désactivé.

Nœuds Thread

Si la topologie du réseau Thread ne correspond pas à celle décrite dans cet atelier de programmation ou si des nœuds se déconnectent pour une raison quelconque (par exemple, parce que la machine Linux qui les alimente s'est mise en veille), il est préférable de désactiver Thread, d'effacer les identifiants réseau et de recommencer à l'étape Créer le réseau Thread.

Pour réinitialiser les FTD :

## FTD Commissioner or FTD Joiner ##
------------------------------------

> thread stop
Done
> ifconfig down
Done
> factoryreset
Done

Le RCP peut être réinitialisé de la même manière via ot-ctl :

## RCP Joiner ##
----------------

> thread stop
Done
> ifconfig down
Done
> factoryreset
Done

12. Utiliser le multicast

Le multicast permet de communiquer des informations à un groupe d'appareils à la fois. Dans un réseau Thread, des adresses spécifiques sont réservées à l'utilisation du multicast avec différents groupes d'appareils, en fonction du champ d'application.

Adresse IPv6

Portée

Livré à

ff02::1

Liaison locale

Tous les FTD et MED

ff02::2

Liaison locale

Tous les FTD et routeurs de bordure

ff03::1

Mesh-Local

Tous les FTD et MED

ff03::2

Mesh-Local

Tous les FTD et routeurs de bordure

Comme nous n'utilisons pas de routeur de bordure dans cet atelier de programmation, concentrons-nous sur les deux adresses multicast FTD et MED.

La portée Link-Local comprend toutes les interfaces Thread accessibles par une seule transmission radio ou un seul "saut". La topologie du réseau détermine les appareils qui répondent à un ping à l'adresse de multidiffusion ff02::1.

Envoyez un ping à ff02::1 depuis le commissaire FTD :

## FTD Commissioner ##
----------------------

> ping ff02::1
> 8 bytes from fe80:0:0:0:e4cd:d2d9:3249:a243: icmp_seq=2 hlim=64 time=9ms

Deux autres appareils sont présents sur le réseau (FTD Joiner et RCP Joiner), mais le FTD Commissioner n'a reçu qu'une seule réponse, provenant de l'adresse Link-Local (LLA) du FTD Joiner. Cela signifie que le FTD Joiner est le seul appareil que le FTD Commissioner peut atteindre en un seul saut.

otcodelab_top02C_02_LL.png

Émettez un ping vers ff02::1 depuis le FTD Joiner :

## FTD Joiner ##
----------------

> ping ff02::1
> 8 bytes from fe80:0:0:0:1cd6:87a9:cb9d:4b1d: icmp_seq=1 hlim=64 time=11ms
8 bytes from fe80:0:0:0:18e5:29b3:a638:943b: icmp_seq=1 hlim=64 time=24ms

Deux réponses ! En vérifiant les adresses IPv6 des autres appareils, nous pouvons voir que la première (se terminant par 4b1d) est l'adresse LLA du commissaire FTD, et que la seconde (se terminant par 943b) est l'adresse LLA du RCP Joiner.

otcodelab_top02C_02_LL02.png

Cela signifie que le Joiner FTD est directement connecté au Commissioner FTD et au Joiner RCP, ce qui confirme notre topologie.

Mesh-Local

La portée Mesh-Local comprend toutes les interfaces Thread accessibles au sein du même réseau Thread. Examinons les réponses à un ping envoyé à l'adresse de multidiffusion ff03::1.

Envoyez un ping à ff03::1 depuis le commissaire FTD :

## FTD Commissioner ##
----------------------

> ping ff03::1
> 8 bytes from fdc0:de7a:b5c0:0:0:ff:fe00:b800: icmp_seq=3 hlim=64 time=9ms
8 bytes from fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f: icmp_seq=3 hlim=64 time=68ms

Cette fois, le commissaire FTD a reçu deux réponses : l'une du localisateur de routage (RLOC, qui se termine par b800) du nœud de raccordement FTD et l'autre de l'EID (ML-EID, qui se termine par d55f) du nœud de raccordement RCP. En effet, la portée locale du réseau maillé comprend l'ensemble du réseau Thread. Quel que soit l'emplacement d'un appareil dans le réseau, il sera abonné à l'adresse ff03::1.

otcodelab_top02C_02_ML.png

Pinguez ff03::1 à partir de FTD Joiner pour confirmer le même comportement :

## FTD Joiner ##
----------------

> ping ff03::1
> 8 bytes from fdc0:de7a:b5c0:0:0:ff:fe00:c00: icmp_seq=2 hlim=64 time=11ms
8 bytes from fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f: icmp_seq=2 hlim=64 time=23ms

otcodelab_top02C_02_LL02.png

Notez le temps de réponse pour le participant RCP dans les deux sorties ping. Le RCP Joiner a mis beaucoup plus de temps à atteindre le FTD Commissioner (68 ms) qu'à atteindre le FTD Joiner (23 ms). En effet, il doit effectuer deux sauts pour atteindre le commissaire FTD, contre un seul pour le participant FTD.

Vous avez peut-être également remarqué que le ping multicast local au réseau maillé répondait avec le RLOC uniquement pour les deux FTD, et non pour le RCP Joiner. En effet, les FTD sont des routeurs au sein du réseau, tandis que le RCP est un appareil final.

Vérifiez l'état de RCP Joiner pour confirmer :

## RCP Joiner ##
----------------

> state
child

13. Envoyer des messages avec UDP

Le protocole UDP (User Datagram Protocol) est l'un des services d'application fournis par OpenThread. Il s'agit d'un protocole de couche de transport. Une application basée sur OpenThread peut utiliser l'API UDP pour transmettre des messages entre les nœuds d'un réseau Thread ou à d'autres appareils d'un réseau externe (comme Internet, si le réseau Thread comporte un routeur de bordure).

Les sockets UDP sont exposés via l'interface de ligne de commande OpenThread. Utilisons-le pour transmettre des messages entre les deux FTD.

Obtenez l'adresse EID locale du réseau maillé pour le FTD Joiner. Nous utilisons cette adresse, car elle est accessible depuis n'importe quel point du réseau Thread.

## FTD Joiner ##
----------------

> ipaddr
fdc0:de7a:b5c0:0:0:ff:fe00:fc00        # Leader Anycast Locator (ALOC)
fdc0:de7a:b5c0:0:0:ff:fe00:b800        # Routing Locator (RLOC)
fe80:0:0:0:e4cd:d2d9:3249:a243         # Link-Local Address (LLA)
fdc0:de7a:b5c0:0:3e2e:66e:9d41:ebcd    # Mesh-Local EID (ML-EID)
Done

Démarrez UDP et liez-le à un socket pour n'importe quelle adresse IPv6 :

## FTD Joiner ##
----------------

> udp open
Done
> udp bind :: 1212

Passez à FTD Commissioner, démarrez UDP et connectez-vous au socket que vous avez configuré sur FTD Joiner, en utilisant son ML-EID :

## FTD Commissioner ##
----------------------

> udp open
Done
> udp connect fdc0:de7a:b5c0:0:3e2e:66e:9d41:ebcd 1212
Done

La connexion UDP doit être active entre les deux nœuds. Envoyer un message du commissaire FTD :

## FTD Commissioner ##
----------------------

> udp send hellothere
Done

Sur le FTD Joiner, le message UDP a été reçu.

## FTD Joiner ##
----------------

> 10 bytes from fdc0:de7a:b5c0:0:0:ff:fe00:c00 49153 hellothere

14. Félicitations !

Vous avez créé un réseau Thread physique !

b915c433e7027cc7.png

Vous savez maintenant :

  • la différence entre les types, les rôles et les portées des appareils Thread ;
  • comment les appareils Thread gèrent leurs états au sein du réseau ;
  • comment transmettre des messages simples entre les nœuds à l'aide d'UDP

Étapes suivantes

En complément de cet atelier de programmation, faites ces exercices :

  • Flashez à nouveau la carte FTD Joiner en tant que MTD à l'aide du binaire ot-cli-mtd et observez qu'elle ne se met jamais à niveau en tant que routeur ni n'essaie de devenir le leader.
  • Ajoutez d'autres appareils (essayez une autre plate-forme) au réseau et esquissez la topologie en utilisant des tables de routeur et d'enfant, ainsi que des pings aux adresses multicast.
  • Utiliser pyspinel pour contrôler le NCP
  • Convertissez le NCP en routeur de bordure à l'aide d'OpenThread Border Router et connectez votre réseau Thread à Internet.

Documentation complémentaire

Consultez openthread.io et GitHub pour accéder à diverses ressources OpenThread, y compris :

Références :