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

À propos de cet atelier de programmation
schedule88 minutes
subjectDernière mise à jour : 24 avril 2025
account_circleRédigé par Jeff Bumgardner

1. Introduction

26b7f4f6b3ea0700.png

OpenThread, publié par Google, est une implémentation Open Source du protocole réseau Thread®. Google Nest a lancé OpenThread pour rendre la technologie utilisée dans les produits Nest largement disponible auprès 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 d'appareil à appareil fiable, sécurisé et basse consommation basé sur l'IPv6 pour les applications domestiques. OpenThread implémente toutes les couches réseau Thread, y compris IPv6, 6LoWPAN, IEEE 802.15.4 avec la sécurité MAC, l'établissement de liaisons en réseau maillé et le routage en réseau 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 des 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 la CLI OpenThread
  • Mise en service sécurisée d'appareils sur un réseau Thread
  • Fonctionnement de la multidiffusion IPv6
  • Transmettre des messages entre des nœuds Thread avec UDP

Prérequis

Matériel :

  • 3 cartes de développement nRF52840 de Nordic Semiconductor
  • 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, nous vous recommandons de suivre l'atelier de programmation de 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 pour servir d'hôte à un appareil Thread RCP (Radio Co-Processor) et pour flasher toutes les cartes de développement Thread. Toutes les étapes ont été testées sur Ubuntu 14.04.5 LTS (Trusty Tahr).

Cartes nRF52840 de Nordic Semiconductor

Cet atelier de programmation utilise trois cartes PDK nRF52840.

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 approprié. 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 le build nRF5x-Command-Line-Tools-<OS> approprié sur votre machine Linux.

Placez le package extrait dans le dossier racine ~/.

Installer la chaîne d'outils GNU ARM

La chaîne d'outils GNU ARM 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. Pour connaître les instructions d'installation, suivez les instructions du fichier readme.txt de l'archive.

Écran d'installation (facultatif)

Screen est un outil simple qui permet d'accéder aux appareils connectés via un port série. Cet atelier de programmation utilise Screen, mais vous pouvez utiliser n'importe quelle 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 s'assurent 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 le joineur RCP

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 l'USB CDC ACM comme transport série entre le nRF52840 et l'hôte.

Commencez toujours par nettoyer 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 binaire RCP OpenThread, puis convertissez-le au format hexadécimal:

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

Connectez le câble USB au port de débogage micro-USB à côté de la broche d'alimentation externe de la carte nRF52840, puis branchez-le sur la machine Linux. Définissez le bouton Source d'alimentation nRF de la carte nRF52840 sur VDD. Lorsque la connexion est correcte, le voyant LED5 est allumé.

20a3b4b480356447.png

S'il s'agit de la première carte connectée à la machine Linux, elle apparaît comme 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, puis flashez le fichier hexadécimal RCP OpenThread 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'affiche, vous indiquant 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

En cas de réussite, le résultat suivant est généré:

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.

Attribuez-lui le libellé "RCP" pour ne pas confondre les rôles du conseil par la suite.

Se connecter à un port USB natif

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

Débranchez 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 (RÉINITIALISATION). Définissez le commutateur Source d'alimentation nRF sur USB.

46e7b670d2464842.png

Démarrer le daemon OpenThread

Dans la conception RCP, utilisez le daemon OpenThread pour communiquer avec l'appareil Thread et le gérer. Démarrez ot-daemon avec l'option -v pour afficher la sortie du journal et vérifier qu'il s'exécute:

$ 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 une sortie semblable à celle-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 afin que les journaux de ot-daemon puissent être consultés.

Utilisez ot-ctl pour communiquer avec le nœud RCP. ot-ctl utilise la même CLI que l'application OpenThread CLI. Par conséquent, vous pouvez 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 l'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). Dans un environnement de production, vous pouvez utiliser wpantund, un pilote d'interface réseau de qualité de production, pour contrôler les instances NCP OpenThread. Toutefois, dans cet atelier de programmation, nous utiliserons ot-ctl, la CLI OpenThread.

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 commissaire peut authentifier sur le réseau Thread.

Compiler et flasher

Créez l'exemple FTD OpenThread pour la plate-forme nRF52840, avec les rôles de commissaire et de participant 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 binaire de la CLI OpenThread FTD (Full Thread Device) 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

Connectez le câble USB au port micro USB à côté de la broche d'alimentation externe de la carte nRF52840, puis branchez-le sur la machine Linux. Si le RCP est toujours connecté à la machine Linux, cette nouvelle carte doit 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, puis flashez le fichier hexadécimal FTD de la CLI OpenThread sur la carte nRF52840 à l'aide du 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

Attribuez le libellé "Commissioner" (Commissaire) à la carte.

Se connecter à un port USB natif

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

Débranchez 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 (RÉINITIALISATION). Définissez le commutateur Source d'alimentation nRF sur USB.

46e7b670d2464842.png

Vérifier la compilation

Vérifiez que la compilation a bien 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 Entrée sur le clavier pour afficher l'invite > de la CLI OpenThread. Affichez l'interface IPv6 et recherchez les adresses:

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

Utilisez Ctrl+a →

d pour vous détacher de l'écran de la CLI du commissaire FTD et revenir au terminal Linux afin de pouvoir flasher la prochaine carte. Pour accéder à nouveau à 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 joineur FTD

Répétez la procédure ci-dessus pour flasher la troisième carte nRF52840 à l'aide du build ot-cli-ftd.hex existant. Lorsque vous avez terminé, veillez à reconnecter la carte au PC à l'aide du port USB nRF et à régler le bouton Source d'alimentation nRF sur VDD.

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

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

Attribuez le libellé "Joineur" à la carte.

Lors de la validation à l'aide de Screen, au lieu de créer une instance de Screen à partir de la ligne de commande, rattachez-vous à l'instance existante et créez-y une nouvelle fenêtre (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 joiner FTD:

$ screen /dev/ttyACM2

Dans cette nouvelle fenêtre, appuyez plusieurs fois sur Entrée sur le clavier pour afficher l'invite > de la CLI OpenThread. Affichez l'interface IPv6 et recherchez les adresses:

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

Maintenant que la CLI du joineur FTD se trouve dans la même instance d'écran que le commissaire FTD, vous pouvez passer de l'un à l'autre à l'aide de la combinaison Ctrl+a → n.

Utilisez Ctrl+a →

d à tout moment pour quitter l'écran.

6. Configuration de 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 d'utiliser l'écran partagé dans la même fenêtre de terminal. Utilisez-la pour voir comment un nœud réagit aux commandes émises sur un autre.

Idéalement, vous devez disposer de quatre fenêtres facilement accessibles:

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

Si vous souhaitez utiliser votre propre configuration ou outil de terminal / port série, passez à l'étape suivante. Configurez les fenêtres de terminal de 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 en avez déjà un depuis que vous avez configuré les deux FTD.

Toutes les commandes de Screen commencent par Ctrl+a.

Commandes d'écran de base:

Se reconnecter à la session Screen (à partir de 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 à une autre dans la même session d'écran

Ctrl+a → n (suivant)Ctrl+a → p (précédent)

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

Pour accéder aux commandes dans screen, appuyez sur Ctrl+a. Chaque commande doit commencer par cette combinaison de clés d'accès.

Si vous avez suivi l'atelier de programmation à la lettre, vous devriez avoir deux fenêtres (FTD Commissioner et FTD Joiner) sur la même instance d'écran. 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. Dans "Écran", procédez comme suit:

  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 nouvelle fenêtre
  4. Si l'information est identique à celle de la fenêtre supérieure, appuyez sur Ctrl+a → n pour afficher l'autre appareil FTD.

Ils sont maintenant tous les deux visibles. Pour passer de l'un à l'autre, appuyez sur 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 ot-ctl du joineur RCP, ces services doivent être démarrés dans cette 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 à l'utilisateur.

Divisez 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

Accéder à la fenêtre affichée suivante

Ctrl+a → Tab

Faire défiler la fenêtre affichée vers l'avant ou vers l'arrière

Ctrl+a → n ou p

Renommer la fenêtre active

Ctrl+a → A

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

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

7. Créer le réseau Thread

Maintenant que toutes vos fenêtres et écrans de terminal sont configurés, créons notre réseau Thread. Sur Commissioner FTD, créez un ensemble de données opérationnel et définissez-le comme actif. L'ensemble de données opérationnel 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 qui sera utilisée ultérieurement.

Validez cet ensemble de données en tant qu'ensemble actif:

> dataset commit active
Done

Activez l'interface IPv6:

> ifconfig up
Done

Démarrez 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 leader. Notez é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 lors de la numérisation à partir d'autres appareils Thread.

Depuis ot-ctl sur le Joineur RCP:

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

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

Dans la CLI OpenThread sur le Joiner FTD:

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

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

Si le réseau "codelab" ne s'affiche pas dans la liste, essayez de le scanner à nouveau.

8. Ajouter le joiner RCP

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

Sur le commissaire FTD, 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, sur le Joineur RCP, définissez sa clé réseau de l'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 l'ensemble de données pour vous assurer qu'il est correctement configuré.

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

> dataset
Network Key: 1234c0de7ab51234c0de7ab51234c0de

Ouvrez le thread pour que le joiner RCP 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). Vous en aurez besoin plus tard.

De retour dans FTD Commissioner, vérifiez les tables du routeur et des enfants pour vous assurer que les deux appareils font partie du même réseau. Utilisez le RLOC16 pour identifier le joineur RCP.

## 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

Envoyez un ping à l'adresse mesh-local du joineur RCP (l'adresse mesh-local obtenue à partir de la sortie ipaddr du joineur 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, illustré par ce diagramme 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 la CLI, en fonction du rôle et de l'état actuels de chaque nœud à ce moment-là.

9. Commissionner le joiner FTD

Ajoutons maintenant le troisième appareil Thread au réseau "atelier de programmation". Cette fois, nous allons utiliser le processus de mise en service en bande plus sécurisé et n'autoriser que le joiner FTD à rejoindre la session.

Sur le Joineur FTD, récupérez le eui64 afin que le commissaire FTD puisse l'identifier:

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

> eui64
2f57d222545271f1
Done

Dans le commissaire FTD, démarrez le commissaire et spécifiez l'eui64 de l'appareil pouvant rejoindre le réseau, ainsi que les identifiants du participant, par exemple J01NME. Les identifiants de l'utilisateur participant sont une chaîne spécifique à l'appareil composée de caractères alphanumériques majuscules (0 à 9 et A à Y, à l'exception des lettres I, O, Q et Z pour une meilleure lisibilité), d'une longueur comprise entre 6 et 32 caractères.

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

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

Passez à l'outil de fusion FTD. Démarrez le rôle de participant avec les identifiants de participant que vous venez de configurer sur le commissaire FTD:

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

> ifconfig up
Done
> joiner start J01NME
Done

Vous recevez une confirmation de l'authentification dans une minute environ:

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

>
Join success

Activez Thread pour que le joiner FTD rejoigne le réseau "atelier de programmation", 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 spécifique à l'anycast qui nécessite un 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'administrateur FTD et vérifiez les tables du routeur et des enfants pour vous assurer 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

D'après le RLOC16, le joiner FTD 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) appelé appareil final éligible au routeur (REED). Cela signifie qu'ils peuvent fonctionner en tant que routeur ou appareil final, et peuvent passer d'un appareil final à un routeur.

Thread peut prendre en charge jusqu'à 32 routeurs, mais tente 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 devient automatiquement un routeur après un délai aléatoire de deux minutes.

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

## 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 joiner FTD (adresse MAC étendue = e6cdd2d93249a243) s'est auto-promu en routeur. Notez que l'adresse RLOC16 est différente (b800 au lieu de 0c02). En effet, elle est basée sur l'ID du routeur et l'ID enfant d'un appareil. Lorsqu'il passe de l'appareil final au 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 Joiner FTD:

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

> state
router
Done
> rloc16
b800
Done

Passer à une version antérieure de l'outil de jointure FTD

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

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

> state child
Done
> rloc16
0c03
Done

otcodelab_top01C_ed02.png

De retour sur la page Commissionnaire FTD, le joineur FTD devrait maintenant apparaître dans le tableau enfant (ID = 3). Il peut même être 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 revient à un routeur avec un RLOC de b800.

otcodelab_top01C.png

Supprimer le dirigeant

Le leader est élu parmi tous les routeurs Thread. Autrement dit, si le leader actuel est supprimé du réseau Thread, l'un des autres routeurs deviendra le nouveau leader.

Sur le commissaire FTD, arrêtez Thread pour le supprimer du réseau Thread:

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

> thread stop
Done
> ifconfig down
Done

Dans un délai de deux minutes, le joineur FTD devient le nouveau leader de Thread. Vérifiez l'état et les adresses IPv6 du joiner FTD pour vérifier les points suivants:

## 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'il y a un nouveau RLOC16. Il s'agit du Joiner RCP, comme indiqué par son ID et son adresse MAC étendue. Pour maintenir le réseau Thread, il a changé de routeur parent, passant du commissaire FTD au joiner FTD. Un nouvel RLOC16 est alors attribué au joineur RCP (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 le joineur RCP s'associe au joineur FTD en tant qu'enfant. Vérifiez l'état et le RLOC16 pour vous assurer que:

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

> state
child
> rloc16
b801

Réattacher le commissaire FTD

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

Sur le commissaire FTD, redémarrez le thread:

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

> ifconfig up
Done
> thread start
Done

Dans un délai de deux minutes, il se reconnecte automatiquement au réseau "codelab" en tant qu'appareil final, puis se transforme en routeur.

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

> state
router
Done

Vérifiez les tables du routeur et des tables enfants sur le Joineur FTD 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 sur différents terminaux ou écrans peut être compliqué. Suivez ces conseils pour "réinitialiser" l'état du réseau ou de votre espace de travail en cas de problème.

Écran

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

Nœuds de thread

Si la topologie du réseau Thread ne correspond pas à celle décrite dans cet atelier de programmation ou si les nœuds se déconnectent pour une raison quelconque (par exemple, parce que la machine Linux qui les alimente est passée en veille), il est préférable de fermer 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 multicast avec différents groupes d'appareils, en fonction de la portée.

Adresse IPv6

Portée

Livraison effectuée à

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.

Le champ d'application de la portée locale comprend toutes les interfaces Thread accessibles par une seule transmission radio ou un seul "saut". La topologie réseau détermine les appareils qui répondent à un ping envoyé à l'adresse de multidiffusion ff02::1.

Émettez un ping sur 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

Il existe deux autres appareils sur le réseau (FTD Joiner et RCP Joiner), mais le commissaire FTD n'a reçu qu'une seule réponse, de l'adresse locale de liaison (LLA) du FTD Joiner. Cela signifie que le joiner FTD est le seul appareil que le commissaire FTD peut atteindre en un seul saut.

otcodelab_top02C_02_LL.png

Envoyez maintenant un ping à ff02::1 depuis le Joiner FTD:

## 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 constatons que la première (se terminant par 4b1d) correspond à l'adresse LLA du commissaire FTD, et que la seconde (se terminant par 943b) correspond à l'adresse LLA du participant RCP.

otcodelab_top02C_02_LL02.png

Cela signifie que le joiner FTD est directement connecté à la fois au commissaire FTD et au joiner RCP, ce qui confirme notre topologie.

Mesh-Local

Le champ d'application "Mesh-Local" comprend toutes les interfaces Thread accessibles au sein du même réseau Thread. Voyons les réponses à un ping envoyé à l'adresse multicast ff03::1.

Émettez un ping sur 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 de l'ID de routage (RLOC, se terminant par b800) du participant FTD et l'autre de l'EID local en réseau maillé (ML-EID, se terminant par d55f) du participant RCP. En effet, la portée locale en réseau maillé comprend l'ensemble du réseau Thread. Quel que soit l'emplacement de l'appareil sur le réseau, il sera abonné à l'adresse ff03::1.

otcodelab_top02C_02_ML.png

Pingez ff03::1 à partir du Joineur FTD pour vérifier que le comportement est identique:

## 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 du joineur RCP dans les deux sorties ping. Le joiner RCP a mis beaucoup plus de temps à atteindre le commissaire FTD (68 ms) qu'à atteindre le joiner FTD (23 ms). En effet, il doit effectuer deux sauts pour atteindre le commissaire FTD, contre un seul pour le joiner FTD.

Vous avez peut-être également remarqué que le ping multicast local du maillage a répondu avec le RLOC uniquement pour les deux FTD, et non pour le joiner RCP. En effet, les FTD sont des routeurs sur le réseau, tandis que le RCP est un dispositif de terminaison.

Vérifiez l'état du joineur RCP pour confirmer:

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

> state
child

13. Envoyer des messages avec UDP

L'un des services d'application fournis par OpenThread est le protocole de datagramme utilisateur (UDP), un protocole de couche 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 dispose d'un routeur de bordure).

Les sockets UDP sont exposés via la CLI OpenThread. Utilisons-le pour transmettre des messages entre les deux FTD.

Obtenez l'adresse EID de maillage local pour le Joiner FTD. 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 associez-le à un socket pour n'importe quelle adresse IPv6:

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

> udp open
Done
> udp bind :: 1212

Passez au commissaire FTD, démarrez UDP et connectez-vous au socket que vous avez configuré sur le joiner FTD à l'aide de 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 de la FTD:

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

> udp send hellothere
Done

Sur le Joiner FTD, 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-ils leurs états au sein du réseau ?
  • comment transmettre des messages simples entre des nœuds à l'aide d'UDP

Étapes suivantes

En complément de cet atelier de programmation, essayez les exercices suivants:

  • Flashez la carte Joiner FTD en tant que MTD à l'aide du binaire ot-cli-mtd, et observez qu'elle ne s'upgrade jamais en routeur ni n'essaie de devenir le leader.
  • Ajoutez d'autres appareils (essayez une autre plate-forme) au réseau et esquissez la topologie à l'aide de tables de routeur et d'enfants, ainsi que de pings sur les adresses multicast.
  • Utiliser pyspinel pour contrôler le NCP
  • Convertir le NCP en routeur de bordure à l'aide du routeur de bordure OpenThread et connecter votre réseau Thread à Internet

Documentation complémentaire

Consultez openthread.io et GitHub pour découvrir diverses ressources OpenThread, y compris les suivantes:

Références :