Simulazione di 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 disponibile agli sviluppatori la tecnologia utilizzata nei prodotti Nest per accelerare lo sviluppo di prodotti per la casa connessa.

La specifica Thread definisce un protocollo di comunicazione wireless tra dispositivi affidabile, sicuro e a basso consumo basato su IPv6 per le applicazioni di casa. OpenThread implementa tutti i livelli di networking Thread inclusi IPv6, 6LoWPAN, IEEE 802.15.4 con sicurezza MAC, Mesh Link ment e il routing della rete mesh.

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

Obiettivi didattici

  • Come configurare la catena di strumenti di build 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, routing della rete

2. Configura il sistema di compilazione

Git

Git è necessario per completare questo codelab. Scaricala e installala prima di continuare.

Una volta installata, segui le istruzioni relative al 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 XCode:

$ xcode-select --install

Crea 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
$ ./bootstrap

Su Windows

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

3. Creare le applicazioni OpenThread

Al termine dell'installazione, crea l'applicazione OpenThread di esempio. Per questo codelab utilizziamo l'esempio di simulazione.

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

Ora crea l'oggetto Daemon OpenThread:

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

4. Simula una rete Thread

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

Questo esercizio ti consente di svolgere i passaggi minimi necessari per inviare un ping a un dispositivo Thread simulato da un altro dispositivo Thread simulato.

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

6e3aa07675f902dc.png

Invia un ping a un nodo

1. Avvia nodo 1

Vai alla directory openthread e genera il processo dell'interfaccia a riga di comando per un dispositivo Thread simulato utilizzando il programma binario ot-cli-ftd.

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

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

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

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

Nota: utilizza i descrittori dei file pari o superiori a 1 come indicato in questo codelab quando generi il processo per un dispositivo simulato. Un descrittore di file 0 è riservato a qualsiasi altro utilizzo.

Creare un nuovo set di dati operativi e eseguirne il commit come quello attivo. Il set di dati operativo è la configurazione per la 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 attivo:

> dataset commit active
Done

Visualizza l'interfaccia IPv6:

> ifconfig up
Done

Avvia operazione sul protocollo Thread:

> thread start
Done

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

> state
leader
Done

Visualizza gli indirizzi IPv6 assegnati all'interfaccia Thread del nodo 1 e 3 (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 indirizzo IPv6 specifici:

  • Inizia con fd = mesh-local
  • Inizia con fe80 = link-local

I tipi di indirizzo locale in mesh sono classificati ulteriormente:

  • Contiene ff:fe00 = Router Locator (RLOC)
  • Non contiene ff:fe00 = identificatore di endpoint (EID)

Identifica l'EID nell'output della console e prendine nota per utilizzarlo in seguito. Nell'output di esempio riportato sopra, l'EID è:

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

2. Avvia nodo 2

Apri un nuovo terminale e vai alla directory openthread, quindi genera il processo dell'interfaccia a riga di comando. Questo è il secondo dispositivo Thread simulato:

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

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

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

> dataset networkkey e4344ca17d1dca2a33f064992f31f786
Done
> dataset panid 0xc169
Done

Esegui il commit di questo set di dati come attivo:

> dataset commit active
Done

Visualizza l'interfaccia IPv6:

> ifconfig up
Done

Avvia operazione sul protocollo Thread:

> thread start
Done

Il dispositivo si inizializza come bambino. Un Thread secondario equivale a un dispositivo finale, che è un dispositivo Thread che trasmette e riceve traffico comunicativo solo con un dispositivo principale.

> state
child
Done

Entro 2 minuti dovresti vedere il passaggio dello stato da child a router. Un router Thread è in grado di instradare il traffico tra dispositivi Thread. Denominati anche genitori.

> state
router
Done

Verifica la rete

Un modo semplice per verificare la rete mesh consiste nell'esaminare la tabella del router.

1. Controlla connettività

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

> rloc16
5800
Done

Sul nodo 1, controlla la tabella RLOC16 del nodo 2 nella tabella del router. Assicurati che il nodo 2 sia passato prima allo stato del 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 |

La tabella RLOC di 0xa800 del nodo 1 si trova nella tabella, a conferma del collegamento alla rete mesh.

2. Ping del nodo 1 del nodo 2

Verificare 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 dell'interfaccia a riga di comando di >.

Prova la rete

Ora che puoi inviare un ping tra due dispositivi Thread simulati, verifica la rete mesh portando un nodo offline.

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 la transizione del nodo 2 come leader della rete:

> state
router
Done
...
> state
leader
Done

Una volta confermato, interrompi il thread e ripristina i nodi 2 prima di uscire. Il ripristino dei dati di fabbrica assicura che le credenziali della rete Thread che abbiamo utilizzato in questo esercizio non vengano trasferite all'esercizio successivo.

> thread stop
Done
> factoryreset
>
> exit

Ripristina i dati di fabbrica e esci dal nodo 1:

> factoryreset
>
> exit

Consulta la pagina di riferimento sull'interfaccia a riga di comando Open per esplorare tutti i comandi dell'interfaccia a riga di comando disponibili.

5. Autenticare i nodi con Commissioning

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

Per eseguire l'autenticazione, un dispositivo deve fungere da Commissioner. Il Commissioner è attualmente il server di autenticazione eletto per i nuovi dispositivi Thread e l'autore dell'autorizzazione a fornire le credenziali di rete necessarie ai dispositivi per collegarsi alla rete.

In questo esercizio utilizzeremo la stessa topologia a due nodi di prima. Per l'autenticazione, il leader del thread fungerà da Commissioner, il router Thread come Joiner.

d6a67e8a0d0b5dcb.png

1. Crea una rete

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

Nel nodo 1, genera il processo dell'interfaccia a riga di comando:

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

Nota: se non visualizzi 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 attivo:

> dataset commit active
Done

Visualizza l'interfaccia IPv6:

> ifconfig up
Done

Avvia operazione sul protocollo Thread:

> thread start
Done

Attendi qualche secondo e verifica che il dispositivo sia diventato un leader per i thread:

> state
leader
Done

2. Avviare il ruolo Commissione

Mentre sei ancora nel nodo 1, avvia il ruolo Commissione:

> commissioner start
Done

Consenti la commissione alla rete a qualsiasi joiner (utilizzando il carattere jolly *) con la credenziale Joiner J01NME. Un joiner è un dispositivo aggiunto da un amministratore umano a una rete Thread commissionata.

> commissioner joiner add * J01NME
Done

3. Avviare il ruolo Collaboratore

In una seconda finestra di terminale, genera un nuovo processo dell'interfaccia a riga di comando. Questo è il nodo 2.

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

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

> ifconfig up
Done
> joiner start J01NME
Done

... attendi qualche secondo per la conferma ...

Join success

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

Ora che il nodo 2 è autenticato, avvia Thread:

> thread start
Done

4. Convalida autenticazione di rete

Controlla il state sul nodo 2 per verificare che sia entrato a far parte della rete. Entro due minuti, il nodo 2 passa da child a router:

> state
child
Done
...
> state
router
Done

5. Reimposta configurazione

Per prepararti al prossimo esercizio, reimposta la configurazione. Su ogni nodo, interrompi il thread, ripristina i dati di fabbrica e esci dal dispositivo Thread simulato:

> thread stop
Done
> factoryreset
>
> exit

Potresti dover premere enter volte alcune volte per ripristinare il prompt > dopo un comando factoryreset.

6. Gestire la rete con OpenThread Daemon

Per questo esercizio, simuleremo un'istanza dell'interfaccia a riga di comando (un singolo dispositivo SoC Thread incorporato) e un'istanza di RCP (Radio Co-Processor).

ot-daemon è una modalità dell'app OpenThread Posix che utilizza un socket UNIX per l'input e l'output, in modo che il core OpenThread possa essere eseguito come servizio. Un client può comunicare con questo servizio connettendosi al socket tramite l'interfaccia a riga di comando OpenThread.

ot-ctl è un'interfaccia a riga di comando fornita da ot-daemon per gestire e configurare la RCP. In questo modo collegheremo il RCP alla rete creata dal dispositivo Thread.

Usa ot-daemon

Questo esercizio utilizzerà tre finestre di terminale, corrispondenti alle seguenti:

  1. Istanza dell'interfaccia a riga di comando del dispositivo Thread simulato (nodo 1)
  2. Procedura di ot-daemon
  3. ot-ctl istanza dell'interfaccia a riga di comando

Se continui dall'esercizio precedente, dovresti già avere due finestre del terminale aperte. Apri un terzo per assicurarti di avere tre finestre di terminale per questo esercizio.

1. Avvia nodo 1

Nella prima finestra del terminale, genera il processo dell'interfaccia a riga di comando per il dispositivo Thread simulato:

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

Nota: se non visualizzi 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 attivo:

> dataset commit active
Done

Visualizza l'interfaccia IPv6:

> ifconfig up
Done

Avvia operazione sul 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 è locale su link (fe80) e tre sono localizzati su mesh (fd). L'EID è l'indirizzo locale che non contiene ff:fe00. In questo output di esempio, l'EID è fd55:cf34:dea5:7994:460:872c:e807:c4ab.

Identifica l'EID specifico dell'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 chiamiamo Nodo 2. Utilizza il flag dettagliato di -v per controllare l'output del log e verificare che sia in esecuzione:

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

Se l'operazione ha esito positivo, ot-daemon in modalità dettagliata genera un output simile al seguente:

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

Lascia questo terminale aperto e in esecuzione in background. Non inserirai ulteriori comandi al suo interno.

3. Usa kubectl per accedere alla rete

Non abbiamo ancora commissionato il nodo 2 (il RCP ot-daemon) a nessuna rete Thread. Ecco dove arriva ot-ctl. ot-ctl utilizza lo stesso interfaccia a riga di comando dell'app Interfaccia a riga di comando OpenOpen. Pertanto, puoi controllare i nodi ot-daemon come faresti con gli altri dispositivi Thread simulati.

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

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

Userai 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. Verifica gli elementi state del nodo 2:

> state
disabled
Done

Recupera la proprietà eui64 del nodo 2 per limitare l'unione a una persona di join specifica:

> eui64
18b4300000000001
Done

Nel nodo 1 (prima finestra del terminale), avvia il Commissioner e limita l'unione solo a questa eui64:

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

Nel nodo 2 (terza finestra del terminale), apri l'interfaccia di rete e unisci la rete:

> ifconfig up
Done
> joiner start J01NME
Done

... attendi qualche secondo per la conferma ...

Join success

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

A questo punto, unisci il nodo 2 alla rete Thread:

> thread start
Done

4. Convalida autenticazione di rete

Controlla il state sul nodo 2 per verificare che sia entrato a far parte della rete. Entro due minuti, il nodo 2 passa da child a router:

> state
child
Done
...
> state
router
Done

5. Convalida connettività

Esci da ot-ctl utilizzando Comando + D o exit e nella riga di comando della macchina host, inviando un ping al nodo 1, utilizzando il relativo EID con il comando ping6. Se l'istanza RCP ot-daemon viene unita e comunica con la rete Thread, 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 build Tool di OpenThread
  • Simula una rete Thread
  • Autentica i nodi Thread
  • Gestire una rete Thread con OpenThread Daemon

Per scoprire di più, consulta questi riferimenti: