Simulare una rete Thread con OpenThread

1. Introduzione

26b7f4f6b3ea0700.png

OpenThread rilasciato da Google è un'implementazione open source del protocollo di rete Thread. Google Nest ha rilasciato OpenThread per rendere la tecnologia utilizzata nei prodotti Nest ampiamente disponibile agli sviluppatori, in modo da accelerare lo sviluppo di prodotti per la casa connessa.

La specifica Thread definisce un protocollo di comunicazione wireless affidabile, sicuro e a basso consumo basato su IPv6 per le applicazioni domestiche. OpenThread implementa tutti i livelli di rete Thread, inclusi IPv6, 6LoWPAN, IEEE 802.15.4 con sicurezza MAC, Mesh Link Establishment e Mesh Routing.

Questo codelab ti guida nella simulazione di una rete Thread su dispositivi simulati.

Obiettivi didattici

  • Come configurare la toolchain di compilazione OpenThread
  • Come simulare una rete Thread
  • Come autenticare i nodi Thread
  • Come gestire una rete Thread con OpenThread Daemon

Che cosa ti serve

  • git
  • Conoscenza di base di Linux e del routing di rete

2. Configurare il sistema di build

Git

Per completare questo codelab è necessario Git. Scaricalo e installalo prima di continuare.

Una volta installato, segui le istruzioni per il tuo sistema operativo specifico per scaricare e creare OpenThread.

XCode per Mac OS X

XCode è necessario per installare e creare OpenThread su Mac OS X.

Dopo aver installato Xcode, installa gli strumenti a riga di comando di Xcode:

$ xcode-select --install

Compilare su Linux / Mac OS X

Queste istruzioni di installazione sono state testate su Ubuntu Server 14.04 LTS e Mac OS X Sierra 10.12.6.

Installa OpenThread. I comandi bootstrap assicurano che la toolchain sia installata e che l'ambiente sia configurato correttamente:

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

Utilizzo di Windows

Se preferisci Windows, ti consigliamo di provare la versione Docker di questo codelab.

3. Crea le applicazioni OpenThread

Una volta completata l'installazione, crea l'applicazione OpenThread di esempio. Per questo Codelab utilizziamo l'esempio di simulazione.

$ cd ~/src/openthread
$ ./script/cmake-build simulation

Ora crea il daemon OpenThread:

$ ./script/cmake-build posix -DOT_DAEMON=ON

4. Simulare una rete Thread

L'applicazione di esempio che utilizzerai per questo codelab mostra un'applicazione OpenThread minima che espone le interfacce di configurazione e gestione di OpenThread tramite un'interfaccia a riga di comando (CLI) di base.

Questo esercizio ti guida attraverso i passaggi minimi necessari per eseguire il ping di un dispositivo Thread simulato da un altro dispositivo Thread simulato.

La figura seguente descrive una topologia di rete Thread di base. Per questo esercizio, simuleremo i due nodi all'interno del cerchio verde: un leader Thread e un router Thread con una singola connessione tra loro.

6e3aa07675f902dc.png

Ping di un nodo

1. Avvia nodo 1

Vai alla directory openthread e genera il processo CLI per un dispositivo Thread simulato utilizzando il binario ot-cli-ftd.

$ cd ~/src/openthread
$ ./build/simulation/examples/apps/cli/ot-cli-ftd 1

Nota:se non vedi il prompt > dopo aver eseguito questo comando, premi enter.

Questo binario implementa un dispositivo OpenThread simulato su POSIX. Il driver radio IEEE 802.15.4 è implementato sopra UDP (i frame IEEE 802.15.4 vengono passati all'interno dei payload UDP).

L'argomento di 1 è un descrittore di file che rappresenta i bit meno significativi dell'EUI-64 IEEE "assegnato dalla fabbrica" per il dispositivo simulato. Questo valore viene utilizzato anche per il binding a una porta UDP per l'emulazione della radio IEEE 802.15.4 (porta = 9000 + descrittore di file). Ogni istanza di un dispositivo Thread simulato in questo Codelab utilizzerà un descrittore di file diverso.

Nota:utilizza solo i descrittori di file 1 o superiori, come indicato in questo codelab, quando generi il processo per un dispositivo simulato. Un descrittore di file di 0 è riservato per altri usi.

Crea un nuovo set di dati operativo e eseguine il commit come attivo. Il set di dati operativo è la configurazione della rete Thread che stai creando.

> 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

Esegui il commit di questo set di dati come quello attivo:

> dataset commit active
Done

Visualizza l'interfaccia IPv6:

> ifconfig up
Done

Avvia l'operazione del protocollo Thread:

> thread start
Done

Attendi qualche secondo e verifica che il dispositivo sia diventato il leader della rete Thread. Il leader è il dispositivo responsabile della gestione dell'assegnazione dell'ID router.

> state
leader
Done

Visualizza gli indirizzi IPv6 assegnati all'interfaccia Thread del nodo 1 (l'output sarà diverso):

> 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

Prendi nota dei tipi di indirizzi IPv6 specifici:

  • Inizia con fd = mesh-local
  • Inizia con fe80 = locale rispetto al collegamento

I tipi di indirizzi locali della mesh sono ulteriormente classificati:

  • Contiene ff:fe00 = Router Locator (RLOC)
  • Non contiene ff:fe00 = Endpoint Identifier (EID)

Identifica l'EID nell'output della console e annotalo per utilizzarlo in un secondo momento. Nell'output di esempio riportato sopra, l'EID è:

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

2. Avvio nodo 2

Apri un nuovo terminale, vai alla directory openthread e genera il processo CLI. Questo è il secondo dispositivo Thread simulato:

$ cd ~/src/openthread
$ ./build/simulation/examples/apps/cli/ot-cli-ftd 2

Nota:se non vedi il prompt > dopo aver eseguito questo comando, premi enter.

Configura la chiave di rete Thread e l'ID PAN utilizzando gli stessi valori del set di dati operativo del nodo 1:

> dataset networkkey e4344ca17d1dca2a33f064992f31f786
Done
> dataset panid 0xc169
Done

Esegui il commit di questo set di dati come quello attivo:

> dataset commit active
Done

Visualizza l'interfaccia IPv6:

> ifconfig up
Done

Avvia l'operazione del protocollo Thread:

> thread start
Done

Il dispositivo verrà inizializzato come dispositivo per bambini. Un nodo secondario Thread è equivalente a un dispositivo finale, ovvero un dispositivo Thread che trasmette e riceve traffico unicast solo con un dispositivo principale.

> state
child
Done

Entro 2 minuti dovresti vedere lo stato passare da child a router. Un router Thread è in grado di instradare il traffico tra i dispositivi Thread. È anche chiamato genitore.

> state
router
Done

Verificare la rete

Un modo semplice per verificare la rete mesh è esaminare la tabella del router.

1. Verifica la connettività

Sul nodo 2, recupera RLOC16. RLOC16 sono gli ultimi 16 bit dell'indirizzo IPv6 RLOC del dispositivo.

> rloc16
5800
Done

Sul nodo 1, controlla la tabella del router per l'RLOC16 del nodo 2. Assicurati che il nodo 2 sia passato allo stato di router.

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

L'RLOC di 0xa800 del nodo 1 si trova nella tabella, a conferma che è connesso alla mesh.

2. Esegui il ping del nodo 1 dal nodo 2

Verifica la connettività tra i due dispositivi Thread simulati. Nel nodo 2, ping l'EID assegnato al nodo 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

Premi enter per tornare al prompt della CLI >.

Testare la rete

Ora che puoi eseguire il ping correttamente tra due dispositivi Thread simulati, testa la rete mesh mettendo offline un nodo.

Torna al nodo 1 e interrompi il thread:

> thread stop
Done

Passa al nodo 2 e controlla lo stato. Entro due minuti, il nodo 2 rileva che il leader (nodo 1) è offline e dovresti vedere il nodo 2 diventare il leader della rete:

> state
router
Done
...
> state
leader
Done

Una volta confermato, interrompi Thread e ripristina i dati di fabbrica di Node 2 prima di uscire. Il ripristino dei dati di fabbrica viene eseguito per garantire che le credenziali di rete Thread utilizzate in questo esercizio non vengano trasferite all'esercizio successivo.

> thread stop
Done
> factoryreset
>
> exit

Ripristina i dati di fabbrica ed esci dal nodo 1:

> factoryreset
>
> exit

Consulta la documentazione di riferimento per l'interfaccia a riga di comando di OpenThread per esplorare tutti i comandi CLI disponibili.

5. Autenticare i nodi con il provisioning

Nell'esercizio precedente hai configurato una rete Thread con due dispositivi simulati e verificato la connettività. Tuttavia, ciò consente solo il passaggio del traffico link-local IPv6 non autenticato tra i dispositivi. Per instradare il traffico IPv6 globale tra loro (e internet tramite un router di confine Thread), i nodi devono essere autenticati.

Per l'autenticazione, un dispositivo deve fungere da commissario. Il commissario è il server di autenticazione attualmente eletto per i nuovi dispositivi Thread e l'autorizzatore per la fornitura delle credenziali di rete necessarie per consentire ai dispositivi di accedere alla rete.

In questo esercizio, utilizzeremo la stessa topologia a due nodi di prima. Per l'autenticazione, il leader Thread fungerà da commissario, il router Thread da joiner.

d6a67e8a0d0b5dcb.png

1. Crea una rete

Se continui dall'esercizio precedente, dovresti avere già due finestre del terminale aperte. In caso contrario, assicurati che due siano aperti e pronti all'uso. Uno fungerà da nodo 1, l'altro da nodo 2.

Nel nodo 1, genera il processo CLI:

$ cd ~/src/openthread
$ ./build/simulation/examples/apps/cli/ot-cli-ftd 1

Nota:se non vedi il prompt > dopo aver eseguito questo comando, premi enter.

Crea un nuovo set di dati operativi, eseguine il commit come attivo e avvia il 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

Esegui il commit di questo set di dati come quello attivo:

> dataset commit active
Done

Visualizza l'interfaccia IPv6:

> ifconfig up
Done

Avvia l'operazione del protocollo Thread:

> thread start
Done

Attendi qualche secondo e verifica che il dispositivo sia diventato un leader Thread:

> state
leader
Done

2. Avviare il ruolo di Commissario

Mentre ti trovi ancora sul nodo 1, avvia il ruolo di Commissario:

> commissioner start
Done

Consenti a qualsiasi tecnico (utilizzando il carattere jolly *) con la credenziale di tecnico J01NME di ricevere commissioni sulla rete. Un Joiner è un dispositivo aggiunto da un amministratore umano a una rete Thread commissionata.

> commissioner joiner add * J01NME
Done

3. Avviare il ruolo di Joiner

In una seconda finestra del terminale, genera un nuovo processo CLI. Questo è il nodo 2.

$ cd ~/src/openthread
$ ./build/simulation/examples/apps/cli/ot-cli-ftd 2

Sul nodo 2, attiva il ruolo Joiner utilizzando la credenziale Joiner J01NME.

> ifconfig up
Done
> joiner start J01NME
Done

... attendi qualche secondo per la conferma…

Join success

In qualità di dispositivo di unione, il dispositivo (nodo 2) si è autenticato correttamente con il commissario (nodo 1) e ha ricevuto le credenziali della rete Thread.

Ora che il nodo 2 è autenticato, avvia Thread:

> thread start
Done

4. Convalida l'autenticazione di rete

Controlla state sul nodo 2 per verificare che sia stato aggiunto alla rete. Entro due minuti, il nodo 2 passa da child a router:

> state
child
Done
...
> state
router
Done

5. Reimposta configurazione

Per prepararti all'esercizio successivo, reimposta la configurazione. Su ogni nodo, arresta Thread, esegui un ripristino dei dati di fabbrica ed esci dal dispositivo Thread simulato:

> thread stop
Done
> factoryreset
>
> exit

Potresti dover premere enter alcune volte per visualizzare di nuovo il prompt > dopo un comando factoryreset.

6. Gestire la rete con OpenThread Daemon

Per questo esercizio, simuleremo un'istanza CLI (un singolo dispositivo SoC Thread incorporato) e un'istanza RCP (Radio Co-Processor).

ot-daemon è una modalità dell'app OpenThread Posix che utilizza un socket UNIX come input e output, in modo che il core di OpenThread possa essere eseguito come servizio. Un client può comunicare con questo servizio connettendosi al socket utilizzando la CLI OpenThread come protocollo.

ot-ctl è una CLI fornita da ot-daemon per gestire e configurare RCP. In questo modo, collegheremo il RCP alla rete creata dal dispositivo Thread.

Utilizzare ot-daemon

Questo esercizio utilizzerà tre finestre del terminale, corrispondenti a quanto segue:

  1. Istanza CLI del dispositivo Thread simulato (nodo 1)
  2. Processo ot-daemon
  3. Istanza della CLI ot-ctl

Se continui dall'esercizio precedente, dovresti avere già due finestre del terminale aperte. Apri una terza finestra per assicurarti di avere tre finestre del terminale disponibili per questo esercizio.

1. Avvia nodo 1

Nella prima finestra del terminale, genera il processo CLI per il dispositivo Thread simulato:

$ cd ~/src/openthread
$ ./build/simulation/examples/apps/cli/ot-cli-ftd 1

Nota:se non vedi il prompt > dopo aver eseguito questo comando, premi enter.

Crea un nuovo set di dati operativi, eseguine il commit come attivo e avvia il 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

Esegui il commit di questo set di dati come quello attivo:

> dataset commit active
Done

Visualizza l'interfaccia IPv6:

> ifconfig up
Done

Avvia l'operazione del protocollo Thread:

> thread start
Done

Visualizza gli indirizzi IPv6 assegnati all'interfaccia Thread del nodo 1:

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

Come spiegato nel passaggio Simula una rete Thread, un indirizzo è link-local (fe80) e tre sono mesh-local (fd). L'EID è l'indirizzo mesh-local che non contiene ff:fe00. In questo output di esempio, l'EID è fd55:cf34:dea5:7994:460:872c:e807:c4ab.

Identifica l'EID specifico dall'output di ipaddr, che verrà utilizzato per comunicare con il nodo.

2. Avvia ot-daemon

Nella seconda finestra del terminale, vai alla directory openthread e avvia ot-daemon per un nodo RCP, che chiameremo Nodo 2. Utilizza il flag dettagliato -v per visualizzare l'output del log e confermare che è in esecuzione. Assicurati di utilizzare sudo:

$ cd ~/src/openthread
$ sudo ./build/posix/src/posix/ot-daemon -v \
    'spinel+hdlc+forkpty://build/simulation/examples/apps/ncp/ot-rcp?forkpty-arg=2'

In caso di esito positivo, ot-daemon in modalità dettagliata genera un output simile al seguente:

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

Lascia il terminale aperto e in esecuzione in background. Non inserirai altri comandi.

3. Utilizzare ot-ctl per connettersi alla rete

Non abbiamo ancora messo in servizio il nodo 2 (il ot-daemon RCP) su alcuna rete Thread. È qui che entra in gioco ot-ctl. ot-ctl utilizza la stessa CLI dell'app CLI OpenThread. Pertanto, puoi controllare i nodi ot-daemon nello stesso modo degli altri dispositivi Thread simulati.

In una terza finestra del terminale, avvia ot-ctl:

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

Nota:se non vedi il prompt > dopo aver eseguito questo comando, premi enter.

Utilizzerai ot-ctl in questa terza finestra del terminale per gestire il nodo 2 (il nodo RCP) che hai avviato nella seconda finestra del terminale con ot-daemon. Controlla state del nodo 2:

> state
disabled
Done

Ottieni il eui64 del nodo 2 per limitare l'unione al partecipante specifico:

> eui64
18b4300000000001
Done

Sul nodo 1 (prima finestra del terminale), avvia il commissario e limita l'accesso solo a questo eui64:

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

Sul nodo 2 (terza finestra del terminale), visualizza l'interfaccia di rete e unisciti alla rete:

> ifconfig up
Done
> joiner start J01NME
Done

... attendi qualche secondo per la conferma…

Join success

In qualità di Joiner, l'RCP (nodo 2) si è autenticato correttamente con il Commissioner (nodo 1) e ha ricevuto le credenziali della rete Thread.

Ora connetti il nodo 2 alla rete Thread:

> thread start
Done

4. Convalida l'autenticazione di rete

Controlla state sul nodo 2 per verificare che sia stato aggiunto alla rete. Entro due minuti, il nodo 2 passa da child a router:

> state
child
Done
...
> state
router
Done

5. Convalida la connettività

Esci da ot-ctl utilizzando Ctrl+D o il comando exit e, nella riga di comando della macchina host, esegui il ping del nodo 1 utilizzando il relativo EID con il comando ping6. Se l'istanza ot-daemon RCP è stata unita correttamente alla rete Thread e comunica con quest'ultima, il ping ha esito positivo:

$ 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. Complimenti!

Hai simulato correttamente la tua prima rete Thread utilizzando OpenThread. Fantastico!

In questo Codelab hai imparato a:

  • Configura la toolchain di build di OpenThread
  • Simulare una rete Thread
  • Autenticare i nodi Thread
  • Gestire una rete Thread con OpenThread Daemon

Se vuoi saperne di più, consulta questi riferimenti: