Crea una rete Thread con schede nRF52840 e 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 al fine di accelerare lo sviluppo di prodotti per la casa connessa.

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

In questo codelab programmi OpenThread su hardware reale, creerai e gestirai una rete Thread e passerai messaggi tra nodi.

4806d16a8c137c6d.jpeg

Obiettivi didattici

  • Creare e far lampeggiare i file binari dell'interfaccia a riga di comando OpenThread nelle schede per sviluppatori
  • Creazione di un RCP costituito da una macchina Linux e una scheda di sviluppo
  • Comunicazione con un RCP mediante il daemon OpenThread e ot-ctl
  • Gestione manuale dei nodi Thread con lo schermo GNU e l'interfaccia a riga di comando OpenThread
  • Messa in servizio sicura dei dispositivi su una rete Thread
  • Come funziona il multicast IPv6
  • Passaggio di messaggi tra nodi Thread con UDP

Che cosa ti serve

Articoli di ferramenta:

  • 3 schede di sviluppo nRF52840 di Nordic Semiconductor
  • 3 cavi da USB a micro-USB per collegare le schede
  • Un computer Linux con almeno 3 porte USB

Software:

  • Toolchain GNU
  • Strumenti a riga di comando nordici nRF5x
  • Software Segger J-Link
  • OpenThread
  • Git

2. Per iniziare

Simulazione OpenThread

Prima di iniziare, ti consigliamo di esaminare il codelab sulle simulazioni di OpenThread per acquisire familiarità con i concetti di base di Thread e con l'interfaccia a riga di comando OpenThread.

Terminali della porta seriale

Dovresti sapere come connetterti a una porta seriale tramite un terminale. Questo codelab utilizza GNU Screen e fornisce una panoramica sull'utilizzo, ma è possibile usare qualsiasi altro software terminale.

Macchina Linux

Questo codelab è stato progettato per utilizzare una macchina Linux basata su i386 o x86 come host per un dispositivo Thread Radio Co-Processor (RCP) e per eseguire il flashing di tutte le schede di sviluppo Thread. Tutti i passaggi sono stati testati su Ubuntu 14.04.5 LTS (Trusty Tahr).

Schede nRF52840 di Nordic Semiconductor

Questo codelab utilizza tre schede nRF52840 PDK.

a6693da3ce213856.png

Usiamo SEGGER J-Link per programmare le schede nRF52840, che hanno moduli JTAG integrati. Installa questa app sul tuo computer Linux.

Scarica il pacchetto appropriato per il tuo computer e installalo nella posizione corretta. Su Linux, il valore è /opt/SEGGER/JLink.

Installa gli strumenti a riga di comando nRF5x

Gli strumenti a riga di comando nRF5x consentono di eseguire il flashing dei file binari OpenThread sulle schede nRF52840. Installa il nRF5x-Command-Line-Tools-<OS> appropriato. sul tuo computer Linux.

Inserisci il pacchetto estratto nella cartella principale ~/

Installa la catena di strumenti ARM GNU

La ARM GNU Toolchain viene utilizzata per la creazione.

Ti consigliamo di posizionare l'archivio estratto in /opt/gnu-mcu-eclipse/arm-none-eabi-gcc/ sul tuo computer Linux. Segui le istruzioni nel file readme.txt dell'archivio per istruzioni sull'installazione.

Schermata di installazione (facoltativa)

Lo schermo è uno strumento semplice per accedere ai dispositivi collegati da una porta seriale. Questo codelab utilizza Screen, ma puoi utilizzare qualsiasi applicazione per terminali con porta seriale.

$ sudo apt-get install screen

3. clona i repository

OpenThread

Clona e installa OpenThread. I comandi script/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

Creazione del daemon OpenThread:

$ script/cmake-build posix -DOT_DAEMON=ON

Ora sei pronto per creare e eseguire il flashing di OpenThread sulle schede nRF52840.

4. Configurare il joiner RCP

Creazione e flash

Crea l'esempio OpenThread nRF52840 con Joiner e la funzionalità USB nativa. Un dispositivo utilizza il ruolo Joiner per essere autenticato e messo in servizio in modo sicuro su una rete Thread. L'unità USB nativa consente l'utilizzo di USB CDC ACM come trasporto seriale tra l'nRF52840 e l'host.

Pulisci sempre prima il repository delle build precedenti eseguendo rm -rf build.

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

Passa alla directory con il file binario RCP OpenThread e convertilo in formato esadecimale:

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

Collega il cavo USB alla porta di debug micro-USB accanto al piedino di alimentazione esterno sulla scheda nRF52840, quindi collegalo al computer Linux. Imposta l'interruttore della sorgente di alimentazione nRF sulla scheda nRF52840 su VDD. Se connesso correttamente, il LED5 è acceso.

20a3b4b480356447.png

Se questa è la prima scheda collegata al computer Linux, verrà visualizzata come porta seriale /dev/ttyACM0 (tutte le schede nRF52840 usano ttyACM per l'identificatore della porta seriale).

$ ls /dev/ttyACM*
/dev/ttyACM0

Prendi nota del numero di serie della scheda nRF52840 utilizzata per l'RCP:

c00d519ebec7e5f0.jpeg

Accedi alla posizione degli strumenti a riga di comando nRFx e esegui il flashing del file esadecimale OpenThread RCP sulla scheda nRF52840, utilizzando il numero di serie della scheda. Tieni presente che se ometti il flag --verify, verrà visualizzato un messaggio di avviso che ti informa che il processo Flash può non riuscire senza errori.

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

Se l'operazione riesce, viene generato il seguente output:

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.

Etichetta la scheda "RCP" in modo da non confondere i ruoli del consiglio di amministrazione.

Connetti a USB nativa

Poiché la build RCP OpenThread consente l'uso dell'ACM USB CDC nativa come trasporto seriale, devi utilizzare la porta USB nRF sulla scheda nRF52840 per comunicare con l'host RCP (computer Linux).

Scollega l'estremità micro-USB del cavo USB dalla porta di debug della scheda nRF52840 lampeggiante, quindi ricollegala alla porta nRF USB micro-USB accanto al pulsante REIMPOSTA. Imposta l'opzione della fonte di alimentazione nRF su USB.

46e7b670d2464842.png

Avvia daemon OpenThread

Nel design RCP, utilizza il daemon OpenThread per comunicare con il dispositivo Thread e gestirlo. Avvia ot-daemon con il flag dettagliato -v in modo che tu possa visualizzare l'output del log e confermare che è in esecuzione:

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

Se l'operazione ha 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 aperta questa finestra del terminale in modo che sia possibile visualizzare i log di ot-daemon.

Utilizza ot-ctl per comunicare con il nodo RCP. ot-ctl utilizza la stessa interfaccia a riga di comando dell'app OpenThread CLI. Pertanto, puoi controllare ot-daemon nodi allo stesso modo degli altri dispositivi Thread simulati.

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

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

Controlla state del nodo 2 (il nodo RCP) che hai iniziato con ot-daemon:

> state
disabled
Done

5. Configurare gli FTD

Gli altri due nodi Thread utilizzati in questo codelab sono dispositivi Full Thread (FTD) con design System-on-Chip (SoC) standard. In un'impostazione Produzione, si potrebbe usare wpantund, un driver di interfaccia di rete di livello enterprise, per controllare le istanze OpenThread NCP, ma in questo codelab utilizzeremo ot-ctl, l'interfaccia a riga di comando OpenThread.

Un dispositivo funge da Commissioner, per autenticare e mettere in servizio in modo sicuro i dispositivi su quella rete. L'altro dispositivo funziona come Joiner che il Commissioner può autenticare nella rete Thread.

Creazione e flash

Crea l'esempio FTD OpenThread per la piattaforma nRF52840, con i ruoli Commissioner e Joiner abilitati:

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

Passa alla directory con il file binario dell'interfaccia a riga di comando OpenThread Full Thread Device (FTD) e convertilo in formato esadecimale:

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

Collega il cavo USB alla porta micro-USB accanto al piedino di alimentazione esterno sulla scheda nRF52840, quindi collegalo al computer Linux. Se l'RCP è ancora collegata al computer Linux, questa nuova scheda dovrebbe essere visualizzata come porta seriale /dev/ttyACM1 (tutte le schede nRF52840 usano ttyACM per l'identificatore della porta seriale).

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

Come prima, prendi nota del numero di serie della scheda nRF52840 utilizzata per l'FTD:

c00d519ebec7e5f0.jpeg

Accedi alla posizione degli strumenti a riga di comando nRFx e esegui il flashing del file esadecimale FTD OpenThread CLI sulla scheda nRF52840, utilizzando il numero di serie della scheda:

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

Etichetta il tabellone "Commissioner".

Connetti a USB nativa

Poiché la build FTD OpenThread consente l'uso dell'ACM USB CDC nativa come trasporto seriale, devi utilizzare la porta USB nRF sulla scheda nRF52840 per comunicare con l'host RCP (computer Linux).

Scollega l'estremità micro-USB del cavo USB dalla porta di debug della scheda nRF52840 lampeggiante, quindi ricollegala alla porta nRF USB micro-USB accanto al pulsante REIMPOSTA. Imposta l'opzione della fonte di alimentazione nRF su USB.

46e7b670d2464842.png

Verifica build

Verifica che la build sia riuscita accedendo all'interfaccia a riga di comando OpenThread utilizzando lo schermo GNU da una finestra del terminale. Le schede nRF52840 utilizzano una velocità in baud di 115200.

$ screen /dev/ttyACM1 115200

Nella nuova finestra, premi Invio sulla tastiera alcune volte per visualizzare il prompt > dell'interfaccia a riga di comando OpenThread. Visualizza l'interfaccia IPv6 e verifica gli indirizzi:

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

Utilizza Ctrl+a →

d per scollegarti dalla schermata dell'interfaccia a riga di comando di FTD Commissioner e tornare al terminale Linux in modo che la scheda successiva possa lampeggiare. Per accedere nuovamente all'interfaccia a riga di comando in qualsiasi momento, utilizza screen -r dalla riga di comando. Per visualizzare un elenco delle schermate disponibili, utilizza screen -ls:

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

Configurare il joiner FTD

Ripeti la procedura descritta sopra per eseguire il flashing della terza scheda nRF52840, usando la build ot-cli-ftd.hex esistente. Al termine, assicurati di ricollegare la scheda al PC utilizzando la porta USB nRF e imposta l'interruttore della fonte di alimentazione nRF su VDD.

Se gli altri due nodi sono collegati al computer Linux quando è collegata questa terza scheda, dovrebbero essere visualizzati come porta seriale /dev/ttyACM2:

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

Etichetta la bacheca "Joiner".

Durante la verifica mediante Screen, anziché creare una nuova istanza di Screen dalla riga di comando, ricollegala a quella esistente e crea una nuova finestra al suo interno (che hai utilizzato per il FTD Commissioner):

$ screen -r

Crea la nuova finestra in Schermata con Ctrl+a → c.

Viene visualizzato un nuovo prompt della riga di comando. Accedi all'interfaccia a riga di comando OpenThread per FTD Joiner:

$ screen /dev/ttyACM2 115200

In questa nuova finestra, premi Invio sulla tastiera alcune volte per visualizzare il prompt > dell'interfaccia a riga di comando OpenThread. Visualizza l'interfaccia IPv6 e verifica gli indirizzi:

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

Ora che l'interfaccia a riga di comando di FTD Joiner si trova nella stessa istanza di Schermata di FTD Commissioner, puoi passare da una all'altra utilizzando Ctrl+a → n.

Utilizza Ctrl+a →

d in qualsiasi momento per uscire dalla schermata.

6. Configurazione della finestra del terminale

In futuro passerai frequentemente da un dispositivo Thread a un altro, quindi assicurati che tutti siano in diretta e facilmente accessibili. Finora abbiamo usato Screen per accedere ai due FTD e questo strumento consente anche lo schermo diviso nella stessa finestra del terminale. Usala per vedere come un nodo reagisce ai comandi inviati su un altro nodo.

Idealmente, dovresti avere quattro finestre subito disponibili:

  1. Servizio / log di ot-daemon
  2. Joiner RRC tramite ot-ctl
  3. FTD Commissioner tramite l'interfaccia a riga di comando OpenThread
  4. FTD Joiner tramite l'interfaccia a riga di comando OpenThread

Se vuoi utilizzare il tuo strumento o la tua configurazione di terminale / porta seriale, vai direttamente al passaggio successivo. Configura le finestre del terminale per tutti i dispositivi nel modo che preferisci.

Schermo in uso

Per facilità d'uso, avvia una sola sessione di schermata. Dovresti averne già uno al momento della configurazione dei due FTD.

Tutti i comandi all'interno dello schermo vengono avviati con Ctrl + A.

Comandi di base delle schermate:

Ricollega alla sessione dello schermo (dalla riga di comando)

screen -r

Esci dalla sessione di utilizzo dello schermo

Ctrl+a → d

Crea una nuova finestra nella sessione di schermata

Ctrl+a → c

Passare da una finestra all'altra nella stessa sessione di schermata

Ctrl+A → n (avanti)Ctrl+A → p (indietro)

Termina la finestra corrente nella sessione di schermata

Ctrl+a → k

Schermo diviso

Con lo schermo, puoi dividere il terminale in più finestre:

f1cbf1258cf0a5a.png

Per accedere ai comandi in screen, premi Ctrl + A. Ogni comando deve iniziare con questa combinazione di chiavi di accesso.

Se stai seguendo esattamente il codelab, dovresti avere due finestre (FTD Commissioner, FTD Joiner) sulla stessa istanza Screen. Per dividere lo schermo tra i due, innanzitutto accedi alla sessione di utilizzo attuale:

$ screen -r

Dovresti trovarti su uno dei dispositivi FTD. Segui questi passaggi nella schermata:

  1. Ctrl+a → S per dividere la finestra orizzontalmente
  2. Ctrl+a → Tab per spostare il cursore nella nuova finestra vuota
  3. Ctrl+a → n per passare dalla nuova finestra alla successiva
  4. Se è uguale alla finestra superiore, premi di nuovo Ctrl+a → n per visualizzare l'altro dispositivo FTD

Ora sono entrambi visibili. Passa da uno all'altro utilizzando Ctrl+a → Tab. Si consiglia di cambiare il titolo di ogni finestra con Ctrl+a → A per evitare confusione.

Utilizzo avanzato

Per suddividere ulteriormente lo schermo in quadranti e visualizzare i log ot-daemon e il Joiner RCP ot-ctl, questi servizi devono essere avviati all'interno della stessa istanza di schermata. Per farlo, interrompi ot-daemon, esci da ot-ctl e riavviale in una nuova finestra dello schermo (Ctrl+A → c).

Questa configurazione non è necessaria e viene lasciata come esercizio per l'utente.

Usa i seguenti comandi per dividere e navigare tra le finestre:

Crea nuova finestra

Ctrl+a → c

Dividi la finestra verticalmente

Ctrl+a →

Dividi la finestra orizzontalmente

Ctrl+a → S

Passa alla finestra visualizzata successiva

Ctrl+a → Tab

Sposta la finestra visualizzata avanti o indietro

Ctrl+a → n o p

Rinomina la finestra attuale

Ctrl+a → A

Esci dallo schermo in qualsiasi momento premendo Ctrl+a → d e ricollegalo con screen -r dalla riga di comando.

Per ulteriori informazioni sulla schermata, consulta il riferimento rapido della schermata GNU.

7. Crea la rete Thread

Ora che hai configurato tutte le finestre e le schermate del terminale, creiamo la nostra rete Thread. In FTD Commissioner, crea un nuovo set di dati operativo ed eseguine il commit come attivo. Il set di dati operativo è la configurazione per la rete Thread che stai creando.

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

Prendi nota della chiave di rete 1234c0de7ab51234c0de7ab51234c0de che verrà utilizzata in seguito.

Esegui il commit di questo set di dati come attivo:

> dataset commit active
Done

Visualizza l'interfaccia IPv6:

> ifconfig up
Done

Avvia l'operazione del protocollo Thread:

> thread start
Done

Dopo qualche istante, controlla lo stato del dispositivo. Dovrebbe essere il leader. Richiedi anche il RLOC16 come riferimento futuro.

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

> state
leader
Done
> rloc16
0c00
Done

Controlla gli indirizzi IPv6 del dispositivo:

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

Il "codelab" è ora visibile quando viene analizzata da altri dispositivi Thread.

Da ot-ctl su Joiner RRC:

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

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

Dall'interfaccia a riga di comando OpenThread su FTD Joiner:

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

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

Se il "codelab" non compare nell'elenco, riprova a scansionare.

8. Aggiungi il Joiner RCP

Thread Commissioning non è attivo sulla rete, quindi dovremo aggiungere il Joiner RCP alla rete Thread che abbiamo appena creato utilizzando un processo di messa in servizio fuori banda.

Nel FTD Commissioner, abbiamo preso nota della chiave di rete, ad esempio 1234c0de7ab51234c0de7ab51234c0de. Se devi cercare di nuovo la chiave di rete, esegui questo comando in FTD Commissioner:

## FTD Commissioner ##

> dataset networkkey
1234c0de7ab51234c0de7ab51234c0de
Done

Quindi, in RCP Joiner, imposta la chiave di rete del suo set di dati attivo sulla chiave di rete FTD Commissioner:

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

> dataset networkkey 1234c0de7ab51234c0de7ab51234c0de
Done
> dataset commit active
Done

Controlla il set di dati per assicurarti che sia impostato correttamente.

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

> dataset
Network Key: 1234c0de7ab51234c0de7ab51234c0de

Visualizza Thread per consentire al Joiner RCP di partecipare al "codelab" in ogni rete. Attendi qualche secondo, controlla lo stato, RLOC16 e i relativi indirizzi 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

Prendi nota dell'indirizzo IPv6 mesh locale (qui fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f), lo utilizzerai più tardi.

Torna a FTD Commissioner, controlla le tabelle router e figlio per verificare che entrambi i dispositivi facciano parte della stessa rete. Utilizza RLOC16 per identificare il joiner 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

Invia un ping all'indirizzo mesh-local del Joiner RCP (l'indirizzo mesh-Local ottenuto dall'output ipaddr di RCP Joiner) per verificare la connettività:

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

Ora abbiamo una rete Thread composta da due nodi, illustrata da questo diagramma di topologia:

otcodelab_top01C_2nodes.png

Diagrammi di topologia

Man mano che lavori nella parte restante del codelab, ti mostreremo un nuovo diagramma della topologia Thread ogni volta che lo stato della rete cambia. I ruoli dei nodi sono indicati come segue:

b75a527be4563215.png

I router sono sempre pentagoni e i Dispositivi finali sono sempre cerchi. I numeri su ciascun nodo rappresentano l'ID router o l'ID figlio mostrato nell'output dell'interfaccia a riga di comando, a seconda del ruolo e dello stato correnti di ciascun nodo in quel momento.

9. Commissione il Joiner FTD

Ora aggiungiamo il terzo dispositivo Thread al "codelab" in ogni rete. Questa volta useremo il processo di messa in servizio in banda più sicuro e consentiremo di far partecipare solo l'FTD Joiner.

Richiedi il eui64 su FTD Joiner, in modo che il FTD Commissioner possa identificarlo:

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

> eui64
2f57d222545271f1
Done

Nel FTD Commissioner, avvia il commissario e specifica il eui64 del dispositivo che può partecipare, insieme alla qualifica per il join, ad esempio J01NME. La credenziale Joiner è una stringa specifica del dispositivo di tutti i caratteri alfanumerici maiuscoli (0-9 e A-Y, esclusi I, O, Q e Z per la leggibilità), con una lunghezza compresa tra 6 e 32 caratteri.

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

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

Passa a FTD Joiner. Inizia il ruolo di joiner con la credenziale Joiner che hai appena configurato per FTD Commissioner:

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

> ifconfig up
Done
> joiner start J01NME
Done

Entro un minuto circa, riceverai la conferma dell'avvenuta autenticazione:

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

>
Join success

Apri Thread per consentire a FTD Joiner di unirsi al "codelab" rete e controllare immediatamente lo stato e RLOC16:

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

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

Controlla gli indirizzi IPv6 del dispositivo. Nota che non esiste un ALOC. Questo perché questo dispositivo non è il leader, né ha un ruolo specifico per Anycast che richiede 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)

Passa immediatamente al FTD Commissioner e controlla le tabelle router e figlio per confermare che esistano tre dispositivi nel "codelab" rete:

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

In base alla RLOC16, l'FTD Joiner è collegato alla rete come Dispositivo finale (secondario). Ecco la nostra topologia aggiornata:

otcodelab_top01C_ed01.png

10. Thread in azione

I dispositivi Thread di questo codelab sono un tipo specifico di dispositivo FTD (Full Thread Device), ovvero dispositivo finale idoneo per il router (REED). Ciò significa che possono fungere da router o dispositivo finale e possono promuoversi da dispositivo finale a router.

Thread può supportare fino a 32 router, ma cerca di mantenere il numero di router compreso tra 16 e 23. Se un REED si collega come Dispositivo finale (figlio) e il numero di Router è inferiore a 16, dopo un periodo di tempo casuale entro due minuti si promuove automaticamente a Router.

Se dopo aver aggiunto FTD Joiner nella rete Thread erano presenti due elementi secondari, attendi almeno due minuti, quindi ricontrolla le tabelle router e figlio su FTD Commissioner:

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

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

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

Il FTD Joiner (MAC esteso = e6cdd2d93249a243) si è promosso a router. Tieni presente che RLOC16 è diverso (b800 anziché 0c02). Questo perché RLOC16 si basa sull'ID router e sull'ID secondario di un dispositivo. Quando passa da dispositivo finale a router, i valori dell'ID router e dell'ID secondario cambiano così come il RLOC16.

otcodelab_top01C.png

Conferma il nuovo stato e RLOC16 nel FTD Joiner:

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

> state
router
Done
> rloc16
b800
Done

Eseguire il downgrade del joiner FTD

Puoi testare questo comportamento eseguendo il downgrade manuale del FTD Joiner da router a dispositivo finale. Cambia lo stato in secondario e controlla RLOC16:

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

> state child
Done
> rloc16
0c03
Done

otcodelab_top01C_ed02.png

Tornando a FTD Commissioner, FTD Joiner dovrebbe ora apparire nella tabella figlio (ID = 3). Potrebbe trovarsi anche in entrambe le transizioni:

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

Dopo un po' di tempo, il dispositivo passerà nuovamente a un router con un RLOC di b800.

otcodelab_top01C.png

Rimuovi leader

Il leader è eletto tra tutti i router Thread. Ciò significa che se l'attuale Leader viene rimosso dalla rete Thread, uno degli altri router diventerà il nuovo Leader.

Su FTD Commissioner, arresta Thread per rimuoverlo dalla rete Thread:

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

> thread stop
Done
> ifconfig down
Done

In due minuti, FTD Joiner diventa il nuovo leader di Thread. Controlla lo stato e gli indirizzi IPv6 di FTD Joiner per verificare:

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

Controlla la tabella secondaria. Nota che è disponibile un nuovo RLOC16. Si tratta del Joiner RCP, come indicato dal suo ID e dal suo MAC esteso. Per mantenere unita la rete Thread, ha cambiato router principali, da FTD Commissioner a FTD Joiner. Questo determina un nuovo RLOC16 per il joiner RCP (perché l'ID router è cambiato, passando da 3 a 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

Potresti dover attendere alcuni minuti prima che l'RCP Joiner si colleghi a FTD Joiner da bambino. Controlla lo stato e il RLOC16 per verificare che:

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

> state
child
> rloc16
b801

Allega di nuovo il FTD Commissioner

Una rete Thread con due nodi non è molto divertente. Riportiamo online l'FTD Commissioner.

Su FTD Commissioner, riavvia Thread:

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

> ifconfig up
Done
> thread start
Done

Entro due minuti, viene ricollegato automaticamente al "codelab" rete come Dispositivo finale, quindi si promuoverà a Router.

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

> state
router
Done

Controlla le tabelle router e figlio su FTD Joiner per verificare:

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

La nostra rete Thread è di nuovo composta da tre nodi.

11. Risoluzione dei problemi

Gestire una rete Thread con più dispositivi su diversi terminali o finestre dello schermo può essere complicato. Usa questi suggerimenti per "ripristinare" lo stato della rete o dell'area di lavoro in caso di problemi.

Schermo

Se ti perdi nella configurazione (troppe finestre dello schermo o schermate all'interno dello schermo), continua a chiudere le finestre dello schermo con Ctrl + A → K finché non ne esiste nessuna e screen -ls sulla riga di comando restituisce No Sockets found. Quindi ricrea le finestre dello schermo per ogni dispositivo. Gli stati del dispositivo vengono conservati anche quando lo schermo viene interrotto.

Nodi Thread

Se la topologia della rete Thread non è come descritto in questo codelab o se i nodi si disconnettono per qualche motivo (forse perché la macchina Linux che li alimentava è passata in modalità di sospensione), è meglio disattivare Thread, cancellare le credenziali di rete e ricominciare dal passaggio Crea la rete Thread.

Per reimpostare gli FTD:

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

> thread stop
Done
> ifconfig down
Done
> factoryreset
Done

L'RCP può essere reimpostato nello stesso modo tramite ot-ctl:

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

> thread stop
Done
> ifconfig down
Done
> factoryreset
Done

12. Utilizzo del multicast

Il multicast viene utilizzato per comunicare informazioni a un gruppo di dispositivi contemporaneamente. In una rete Thread, indirizzi specifici sono riservati per l'utilizzo multicast con diversi gruppi di dispositivi, a seconda dell'ambito.

Indirizzo IPv6

Ambito

Consegnato a

ff02::1

Locale del link

Tutti gli FTD e i MED

ff02::2

Locale del link

Tutti i FTD e i router di confine

ff03::1

Mesh locale

Tutti gli FTD e i MED

ff03::2

Mesh locale

Tutti i FTD e i router di confine

Dal momento che in questo codelab non utilizziamo un router di confine, concentriamoci sui due indirizzi multicast FTD e MED.

L'ambito Link-Local comprende tutte le interfacce Thread raggiungibili da una singola trasmissione radio o un singolo "hop". La topologia di rete determina quali dispositivi rispondono a un ping all'indirizzo multicast ff02::1.

Invia un ping a ff02::1 dal FTD Commissioner:

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

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

Nella rete sono presenti altri due dispositivi (FTD Joiner e RCP Joiner), ma l'FTD Commissioner ha ricevuto una sola risposta, ovvero l'indirizzo Link-Local (LLA) di FTD Joiner. Ciò significa che FTD Joiner è l'unico dispositivo che il FTD Commissioner può raggiungere con un singolo hop.

otcodelab_top02C_02_LL.png

Ora esegui il ping di ff02::1 da FTD Joiner:

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

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

Due risposte! Controllando gli indirizzi IPv6 degli altri dispositivi, vediamo che il primo (che termina con 4b1d) è l'LLA di FTD Commissioner, mentre il secondo (che termina con 943b) è l'LLA di RCP Joiner.

otcodelab_top02C_02_LL02.png

Ciò significa che FTD Joiner è collegato direttamente sia al FTD Commissioner che a RCP Joiner, che conferma la nostra topologia.

Mesh locale

L'ambito mesh-locale comprende tutte le interfacce Thread raggiungibili all'interno della stessa rete Thread. Vediamo le risposte a un ping all'indirizzo multicast ff03::1.

Invia un ping a ff03::1 dal FTD Commissioner:

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

Questa volta il commissario FTD ha ricevuto due risposte, una dal Locator del routing (RLOC, che termina con b800) e una dal EID mesh-locale (ML-EID, ML-EID, che termina con d55f) di RCP Joiner. Questo perché l'ambito mesh-locale comprende l'intera rete Thread. Indipendentemente da dove si trova un dispositivo sulla rete, verrà sottoscritto all'indirizzo ff03::1.

otcodelab_top02C_02_ML.png

Invia un ping a ff03::1 da FTD Joiner per confermare lo stesso comportamento:

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

Prendi nota del tempo di risposta per il Joiner RCP in entrambi gli output del ping. RCP Joiner ha impiegato molto più tempo a raggiungere l'FTD Commissioner (68 ms) che a raggiungere l'FTD Joiner (23 ms). Questo perché deve fare due salti per raggiungere FTD Commissioner, rispetto a un salto per l'FTD Joiner.

Potresti anche aver notato che il ping multicast mesh-local ha risposto con l'RLOC solo per i due FTD, non per RCP Joiner. Questo perché i FTD sono router all'interno della rete, mentre gli RCP sono router finali.

Controlla lo stato del joiner RCS per verificare:

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

> state
child

13. Invia messaggi con UDP

Uno dei servizi per le applicazioni offerti da OpenThread è il protocollo UDP (User Datagram Protocol), un protocollo Transport Layer. Un'applicazione basata su OpenThread potrebbe utilizzare l'API UDP per passare messaggi tra i nodi di una rete Thread o ad altri dispositivi in una rete esterna (come internet, se la rete Thread dispone di un router di confine).

I socket UDP vengono esposti tramite l'interfaccia a riga di comando OpenThread. Usiamolo per passare i messaggi tra i due FTD.

Ottieni l'indirizzo EID mesh-locale del FTD Joiner. Stiamo utilizzando questo indirizzo perché è raggiungibile da qualsiasi punto della rete 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

Avvia UDP e associalo a un socket per qualsiasi indirizzo IPv6:

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

> udp open
Done
> udp bind :: 1212

Passa a FTD Commissioner, avvia UDP e connettiti al socket che hai configurato su FTD Joiner utilizzando il relativo ML-EID:

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

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

La connessione UDP deve essere attiva tra i due nodi. Invia un messaggio dal Commissario FTD:

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

> udp send hellothere
Done

Nell'FTD Joiner, il messaggio UDP è stato ricevuto.

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

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

14. Complimenti!

Hai creato una rete Thread fisica.

b915c433e7027cc7.png

Ora sai:

  • la differenza tra tipi di dispositivi, ruoli e ambiti Thread
  • il modo in cui i dispositivi Thread gestiscono i propri stati all'interno della rete
  • come passare semplici messaggi tra nodi utilizzando UDP

Passaggi successivi

Partendo da questo codelab, prova questi esercizi:

  • Rifai il flash della scheda FTD Joiner come MTD utilizzando il file binario ot-cli-mtd e osserva che non si aggiorna mai a Router né cerca di diventare il Leader
  • Aggiungere altri dispositivi alla rete (provare una piattaforma diversa) e delineare la topologia utilizzando tabelle router e figlio, oltre a ping agli indirizzi multicast
  • Usa pyspinel per controllare il NCP
  • Converti il NCP in un router di confine utilizzando un router di confine OpenThread e connetti la tua rete Thread a internet

Per approfondire

Dai un'occhiata a openthread.io e GitHub per trovare una serie di risorse OpenThread, tra cui:

Riferimento: