Simuler un réseau Thread avec OpenThread

1. Introduction

26b7f4f6b3ea0700.png

OpenThread publié par Google est une implémentation Open Source du protocole de mise en réseau Thread. Google Nest a lancé OpenThread pour permettre aux développeurs d'accéder à la technologie utilisée dans les produits Nest 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 entre appareils de type IPv6 pour les applications à domicile, qui est fiable et sécurisé. OpenThread implémente toutes les couches de mise en réseau Thread, y compris IPv6, 6LoWPAN, IEEE 802.15.4 avec sécurité MAC, Établissement des liens maillés et routage du réseau maillé.

Cet atelier de programmation vous explique comment simuler un réseau Thread sur des appareils simulés.

Points abordés

  • Configurer la chaîne d'outils de compilation OpenThread
  • Simuler un réseau Thread
  • Authentifier les nœuds Thread
  • Gérer un réseau Thread avec OpenThread Daemon

Ce dont vous avez besoin

  • git
  • Connaissances de base sur Linux, routage réseau

2. Configurer le système de compilation

Git

Git est nécessaire pour suivre cet atelier de programmation. Téléchargez-la et installez-la avant de continuer.

Une fois l'application installée, suivez les instructions correspondant à votre système d'exploitation pour télécharger et créer OpenThread.

XCode pour Mac OS X

XCode est nécessaire pour installer et créer OpenThread sur Mac OS X.

Une fois XCode installé, installez les outils de ligne de commande XCode:

$ xcode-select --install

Compiler sous Linux / Mac OS X

Ces instructions d'installation ont été testées sur Ubuntu Server 14.04 LTS et Mac OS X Sierra 10.12.6.

Installez OpenThread. Les commandes bootstrap garantissent 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
$ ./bootstrap

Utiliser Windows

Si vous préférez Windows, nous vous recommandons de tester la version Docker de cet atelier de programmation.

3. Créer les applications OpenThread

Une fois l'installation terminée, créez l'exemple d'application OpenThread. Pour cet atelier de programmation, nous utilisons l'exemple de simulation.

$ cd ~/src/openthread
$ make -f examples/Makefile-simulation

Créez à présent le daemon OpenThread:

$ cd ~/src/openthread
$ make -f src/posix/Makefile-posix DAEMON=1

4. Simuler un réseau Thread

L'exemple d'application que vous allez utiliser pour cet atelier de programmation présente une application OpenThread minimale qui expose les interfaces de configuration et de gestion OpenThread via une interface de ligne de commande (CLI) de base.

Cet exercice vous guide tout au long des étapes minimales requises pour pinguer un appareil Thread simulé à partir d'un autre appareil Thread simulé.

L'illustration ci-dessous décrit la topologie de base du réseau Thread. Pour cet exercice, nous allons simuler les deux nœuds dans le cercle vert: Thread Leader et Thread Router, avec une seule connexion entre eux.

5e3aa07675f902dc.png

Pinguer un nœud

1. Démarrer le nœud 1

Accédez au répertoire openthread et générez le processus CLI pour un appareil Thread simulé à l'aide du binaire ot-cli-ftd.

$ cd ~/src/openthread
$ ./output/simulation/bin/ot-cli-ftd 1

Remarque : Si l'invite > ne s'affiche pas après l'exécution de cette commande, appuyez sur enter.

Ce binaire implémente un appareil OpenThread simulé sur POSIX. Le pilote radio IEEE 802.15.4 est intégré en plus du protocole UDP (IEEE 802.15.4 est transmis dans les charges utiles UDP).

L'argument de 1 est un descripteur de fichier qui représente les bits les moins significatifs de l'IEEE EUI-64 pour l'appareil simulé. Cette valeur est également utilisée lors de la liaison à un port UDP pour l'émulation radio IEEE 802.15.4 (port = 9000 + descripteur de fichier). Chaque instance d'un appareil Thread simulé de cet atelier de programmation utilisera un descripteur de fichier différent.

Remarque : N'utilisez les descripteurs de fichier 1 ou supérieur comme indiqué dans cet atelier de programmation lorsque vous générez le processus pour un appareil simulé. Un descripteur de fichier 0 est réservé à une autre utilisation.

Créer un ensemble de données opérationnel et le valider en tant qu'ensemble actif. L'ensemble de données opérationnel est la configuration du réseau Thread que vous créez.

> dataset init new
Done
> dataset
Active Timestamp: 1
Channel: 20
Channel Mask: 07fff800
Ext PAN ID: d6263b6d857647da
Mesh Local Prefix: fd61:2344:9a52:ede0/64
Network Key: e4344ca17d1dca2a33f064992f31f786
Network Name: OpenThread-c169
PAN ID: 0xc169
PSKc: ebb4f2f8a68026fc55bcf3d7be3e6fe4
Security Policy: 0, onrcb
Done

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

> dataset commit active
Done

Affichez l'interface IPv6:

> ifconfig up
Done

Lancer l'opération de protocole Thread:

> thread start
Done

Patientez quelques secondes, puis vérifiez que l'appareil est bien devenu le fil de discussion. Le responsable est l'appareil responsable de la gestion de l'attribution des ID de routeur.

> state
leader
Done

Affichez les adresses IPv6 attribuées à l'interface Thread de Node 1's (votre résultat sera différent):

> ipaddr
fd61:2344:9a52:ede0:0:ff:fe00:fc00
fd61:2344:9a52:ede0:0:ff:fe00:5000
fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6
fe80:0:0:0:94da:92ea:1353:4f3b
Done

Notez les types d'adresses IPv6 spécifiques:

  • Commence par fd = maillage-local
  • Commence par fe80 = lien local

Les types d'adresses locaux maillés sont encore classés:

  • Contient ff:fe00 = outil de localisation de routeurs (RLOC)
  • Ne contient pas ff:fe00 = Identifiant de point de terminaison (EID)

Identifiez l'EID dans les résultats de votre console, notez-le pour une utilisation ultérieure. Dans l'exemple de résultat ci-dessus, l'EID est:

fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6

2. Démarrer le nœud 2

Ouvrez un nouveau terminal, accédez au répertoire openthread et générez le processus de la CLI. Ceci est votre deuxième appareil Thread simulé:

$ cd ~/src/openthread
$ ./output/simulation/bin/ot-cli-ftd 2

Remarque : Si l'invite > ne s'affiche pas après l'exécution de cette commande, appuyez sur enter.

Configurez la clé réseau et l'ID PAN du réseau Thread, en utilisant les mêmes valeurs que pour l'ensemble de données opérationnel du nœud 1:

> dataset networkkey e4344ca17d1dca2a33f064992f31f786
Done
> dataset panid 0xc169
Done

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

> dataset commit active
Done

Affichez l'interface IPv6:

> ifconfig up
Done

Lancer l'opération de protocole Thread:

> thread start
Done

L'appareil s'initialise en tant qu'enfant. Un enfant Thread est équivalent à un appareil final, c'est-à-dire un appareil Thread qui transmet et reçoit du trafic monocast uniquement avec un appareil parent.

> state
child
Done

Le changement d'état passe de child à router dans deux minutes. Un routeur Thread peut acheminer le trafic entre des appareils Thread. Il est également appelé "Parent".

> state
router
Done

Valider le réseau

Pour vérifier facilement le réseau maillé, consultez la table du routeur.

1. Vérifier la connectivité

Sur le nœud 2, récupérez le RLOC16. Le RLOC16 correspond aux 16 derniers bits de l'adresse IPv6 RLOC de l'appareil.

> rloc16
5800
Done

Sur le nœud 1, vérifiez la table du routeur correspondant au nœud RLOC16 du nœud 2. Assurez-vous que le nœud 2 est passé au statut de routeur.

> router table
| ID | RLOC16 | Next Hop | Path Cost | LQI In | LQI Out | Age | Extended MAC  |
+----+--------+----------+----------+-------+---------+-----+------------------+
| 20 | 0x5000 |       63 |         0 |     0 |      0 |   0 | 96da92ea13534f3b |
| 22 | 0x5800 |       63 |         0 |     3 |      3 |  23 | 5a4eb647eb6bc66c |

Le RLOC de 0xa800 des nœuds 1 et 3 est détecté dans la table, ce qui confirme qu'il est connecté au réseau maillé.

2. Ping du nœud 1 depuis le nœud 2

Vérifiez la connectivité entre les deux appareils Thread simulés. Dans le nœud 2, ping de l'EID attribué au nœud 1:

> ping fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6
> 16 bytes from fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6: icmp_seq=1
hlim=64 time=12ms

Appuyez sur enter pour revenir à l'invite de CLI >.

Tester le réseau

Maintenant que vous pouvez pinguer entre deux appareils Thread simulés, testez le réseau maillé en mettant un nœud hors connexion.

Revenez au nœud 1 et arrêtez le thread:

> thread stop
Done

Basculez vers le nœud 2 et vérifiez l'état. Au bout de deux minutes, le nœud 2 détecte que le nœud principal (Node 1) est hors connexion, et le nœud 2 doit apparaître comme l'élément leader du réseau:

> state
router
Done
...
> state
leader
Done

Après confirmation, arrêtez le thread et rétablissez la configuration d'usine du nœud 2 avant de quitter. Le rétablissement de la configuration d'usine garantit que les identifiants réseau Thread que nous avons utilisés dans cet exercice ne seront pas transférés à l'exercice suivant.

> thread stop
Done
> factoryreset
>
> exit

Rétablissez la configuration d'usine et quittez le nœud 1:

> factoryreset
>
> exit

Consultez la documentation de référence de la CLI OpenThread pour découvrir toutes les commandes de CLI disponibles.

5. Authentifier les nœuds avec la mise en service

Dans l'exercice précédent, vous avez configuré un réseau Thread avec deux appareils simulés et une connectivité vérifiée. Cependant, seul le trafic local de liaison IPv6 non authentifié passe entre les appareils. Pour acheminer le trafic IPv6 mondial entre eux (et Internet via un routeur de bordure Thread), les nœuds doivent être authentifiés.

Pour s'authentifier, un appareil doit agir en tant que commissaire. Le commissaire est le serveur d'authentification actuellement élu pour les nouveaux appareils Thread, et l'outil d'autorisation de fournir les identifiants réseau nécessaires pour qu'ils rejoignent le réseau.

Dans cet exercice, nous allons utiliser la même topologie à deux nœuds. Pour l'authentification, le leader du fil de discussion agit en tant que commissaire, routeur de thread en tant que jointure.

D6a67e8a0d0b5dcb.png

1. Créer un réseau

Si vous continuez, vous devez normalement avoir ouvert deux fenêtres de terminal. Si ce n'est pas le cas, assurez-vous que deux d'entre eux sont ouverts et prêts à l'emploi. L'un sera utilisé en tant que nœud 1, l'autre en tant que nœud 2.

Dans le nœud 1, déclenchez le processus CLI:

$ cd ~/src/openthread
$ ./output/simulation/bin/ot-cli-ftd 1

Remarque : Si l'invite > ne s'affiche pas après l'exécution de cette commande, appuyez sur enter.

Créer un ensemble de données opérationnel, le valider en tant qu'ensemble de données actif, puis démarrer le thread:

> dataset init new
Done
> dataset
Active Timestamp: 1
Channel: 12
Channel Mask: 07fff800
Ext PAN ID: e68d05794bf13052
Mesh Local Prefix: fd7d:ddf7:877b:8756/64
Network Key: a77fe1d03b0e8028a4e13213de38080e
Network Name: OpenThread-8f37
PAN ID: 0x8f37
PSKc: f9debbc1532487984b17f92cd55b21fc
Security Policy: 0, onrcb
Done

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

> dataset commit active
Done

Affichez l'interface IPv6:

> ifconfig up
Done

Lancer l'opération de protocole Thread:

> thread start
Done

Patientez quelques secondes, puis vérifiez que l'appareil est devenu un leader de fil de discussion:

> state
leader
Done

2. Démarrer le rôle du commissaire

Toujours sur le nœud 1, démarrez le rôle de commissaire:

> commissioner start
Done

Autoriser n'importe quel Joiner (à l'aide du caractère générique *) avec les identifiants de jointure J01NME à commission sur le réseau. Un Joiner est un appareil ajouté par un administrateur humain à un réseau Thread commandé.

> commissioner joiner add * J01NME
Done

3. Créer le rôle Joiner

Dans une deuxième fenêtre de terminal, générez un nouveau processus CLI. Il s'agit du nœud 2.

$ cd ~/src/openthread
$ ./output/simulation/bin/ot-cli-ftd 2

Sur le nœud 2, activez le rôle Joiner à l'aide des identifiants de jointure J01NME.

> ifconfig up
Done
> joiner start J01NME
Done

... attendez quelques secondes pour confirmer ...

Join success

En tant que jointure, l'appareil (Node 2) s'est correctement authentifié auprès du Commissaire (Node 1) et a reçu les identifiants réseau Thread.

Maintenant que le nœud 2 est authentifié, démarrez Thread:

> thread start
Done

4. Valider l'authentification réseau

Vérifiez le state du nœud 2 pour vérifier qu'il a désormais rejoint le réseau. Dans un délai de deux minutes, le nœud 2 passe de child à router:

> state
child
Done
...
> state
router
Done

5. Réinitialiser la configuration

Pour préparer l'exercice suivant, réinitialisez la configuration. Sur chaque nœud, arrêtez le thread, rétablissez la configuration d'usine et quittez l'appareil simulé de Thread:

> thread stop
Done
> factoryreset
>
> exit

Vous devrez peut-être appuyer plusieurs fois sur enter pour que l'invite > s'affiche de nouveau après une commande factoryreset.

6. Gérer le réseau avec le Daemon OpenThread

Dans cet exercice, nous allons simuler une instance de CLI (un appareil à thread SoC intégré) et une instance de co-processeur (RCP).

ot-daemon est un mode de l'application OpenThread Posix qui utilise un socket UNIX comme entrée et sortie, de sorte que le cœur OpenThread peut s'exécuter en tant que service. Un client peut communiquer avec ce service en se connectant au socket à l'aide de la CLI OpenThread comme protocole.

ot-ctl est une CLI fournie par ot-daemon pour gérer et configurer le RCP. Cette méthode permet de connecter le système RCP au réseau créé par l'appareil Thread.

Utiliser l'outil ot-daemon

Cet exercice utilise trois fenêtres de terminal, correspondant aux éléments suivants:

  1. Instance CLI de l'appareil Thread simulé (nœud 1)
  2. ot-daemon processus
  3. Instance CLI ot-ctl

Si vous continuez, vous devriez avoir ouvert deux fenêtres de terminal. Ouvrez une troisième fenêtre pour vous assurer que trois fenêtres de terminal sont disponibles pour cet exercice.

1. Démarrer le nœud 1

Dans la première fenêtre de terminal, générez le processus CLI pour votre appareil Thread simulé:

$ cd ~/src/openthread
$ ./output/simulation/bin/ot-cli-ftd 1

Remarque : Si l'invite > ne s'affiche pas après l'exécution de cette commande, appuyez sur enter.

Créer un ensemble de données opérationnel, le valider en tant qu'ensemble de données actif, puis démarrer le thread:

> dataset init new
Done
> dataset
Active Timestamp: 1
Channel: 13
Channel Mask: 07fff800
Ext PAN ID: 97d584bcd493b824
Mesh Local Prefix: fd55:cf34:dea5:7994/64
Network Key: ba6e886c7af50598df1115fa07658a83
Network Name: OpenThread-34e4
PAN ID: 0x34e4
PSKc: 38d6fd32c866927a4dfcc06d79ae1192
Security Policy: 0, onrcb
Done

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

> dataset commit active
Done

Affichez l'interface IPv6:

> ifconfig up
Done

Lancer l'opération de protocole Thread:

> thread start
Done

Consultez les adresses IPv6 attribuées à l'interface Thread de Node 1 et # :

> ipaddr
fd55:cf34:dea5:7994:0:ff:fe00:fc00
fd55:cf34:dea5:7994:0:ff:fe00:d000
fd55:cf34:dea5:7994:460:872c:e807:c4ab
fe80:0:0:0:9cd8:aab6:482f:4cdc
Done
>

Comme expliqué à l'étape Simuler un réseau Thread, l'une est une adresse de liaison locale (fe80) et trois sont d'une adresse réseau local (fd). L'EID est l'adresse locale du réseau maillé qui ne contient pas ff:fe00 dans l'adresse. Dans cet exemple de résultat, l'EID est fd55:cf34:dea5:7994:460:872c:e807:c4ab.

Identifiez l'EID spécifique de votre sortie ipaddr, qui sera utilisé pour communiquer avec le nœud.

2. Démarrer ot-daemon

Dans la seconde fenêtre de terminal, accédez au répertoire openthread et démarrez ot-daemon pour un nœud RCP, que nous appellerons le nœud 2. Utilisez l'indicateur détaillé -v pour afficher la sortie du journal et confirmer son exécution:

$ cd ~/src/openthread
$ ./output/posix/bin/ot-daemon -v \
    'spinel+hdlc+forkpty://output/simulation/bin/ot-rcp?forkpty-arg=2'

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

ot-daemon[228024]: Running OPENTHREAD/20191113-00831-gfb399104; POSIX; Jun 7 2020 18:05:15
ot-daemon[228024]: Thread version: 2
ot-daemon[228024]: RCP version: OPENTHREAD/20191113-00831-gfb399104; SIMULATION; Jun 7 2020 18:06:08

Laissez ce terminal ouvert et exécuté en arrière-plan. Vous n'en saisirez plus.

3. Utiliser ot-ctl pour rejoindre le réseau

Nous n'avons pas encore commandé le nœud 2 (le RCP ot-daemon) à n'importe quel réseau Thread. C'est là que ot-ctl entre en jeu. ot-ctl utilise la même CLI que l'application CLI OpenThread. Vous pouvez donc contrôler ot-daemon nœuds de la même manière que les autres appareils Thread simulés.

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

$ ./output/posix/bin/ot-ctl
>

Vous allez utiliser ot-ctl dans cette troisième fenêtre de terminal pour gérer le nœud 2 (nœud RCP) que vous avez commencé dans la deuxième fenêtre de terminal avec ot-daemon. Vérifiez le state du nœud 2:

> state
disabled
Done

Obtenez le nœud eui64 pour restreindre la connexion à la jointure spécifique:

> eui64
18b4300000000001
Done

Sur le nœud 1 (première fenêtre de terminal), démarrez le commissaire et limitez l'association à cette eui64:

> commissioner start
Done
> commissioner joiner add 18b4300000000001 J01NME
Done

Sur le nœud 2 (troisième fenêtre de terminal), affichez l'interface réseau et rejoignez le réseau:

> ifconfig up
Done
> joiner start J01NME
Done

... attendez quelques secondes pour confirmer ...

Join success

En tant que Joiner, le RCP (Node 2) s'est authentifié auprès du Commissaire (Node 1) et a reçu les identifiants réseau Thread.

Associez le nœud 2 au réseau Thread:

> thread start
Done

4. Valider l'authentification réseau

Vérifiez le state du nœud 2 pour vérifier qu'il a désormais rejoint le réseau. Dans un délai de deux minutes, le nœud 2 passe de child à router :

> state
child
Done
...
> state
router
Done

5. Valider la connectivité

Quittez ot-ctl à l'aide de la commande Ctrl+D ou exit, et sur la ligne de commande de votre machine hôte, pinguez le nœud 1 en utilisant son EID avec la commande ping6. Si l'instance RCP ot-daemon est associée au réseau Thread et communique avec elle, le ping aboutit:

$ ping6 -c 4 fd55:cf34:dea5:7994:460:872c:e807:c4ab
PING fd55:cf34:dea5:7994:460:872c:e807:c4ab (fd55:cf34:dea5:7994:460:872c:e807:c4ab): 56 data bytes
64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=0 ttl=64 time=4.568 ms
64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=1 ttl=64 time=6.396 ms
64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=2 ttl=64 time=7.594 ms
64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=3 ttl=64 time=5.461 ms
--- fd55:cf34:dea5:7994:460:872c:e807:c4ab ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max/stddev = 4.568/6.005/7.594/1.122 ms

7. Félicitations !

Vous avez simulé votre premier réseau Thread à l'aide d'OpenThread. Parfait !

Dans cet atelier de programmation, vous avez appris à :

  • Configurer la chaîne d'outils de compilation OpenThread
  • Simuler un réseau Thread
  • Authentifier les nœuds de thread
  • Gérer un réseau Thread avec OpenThread Daemon

Si vous souhaitez en savoir plus, consultez ces références: