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 per gli sviluppatori al fine di accelerare lo sviluppo di prodotti per la casa connessa a internet.

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

In questo Codelab, programmerai OpenThread su hardware reale, creerai e gestirai una rete Thread e passerai messaggi tra i nodi.

4806d16a8c137c6d.jpeg

Obiettivi didattici

  • Compilazione e aggiornamento dei file binari dell'interfaccia a riga di comando OpenThread sulle schede di sviluppo
  • Creazione di un RCP composto da una macchina Linux e una scheda di sviluppo
  • Comunicazione con un RCP utilizzando OpenThread Daemon e ot-ctl
  • Gestione manuale dei nodi Thread con GNU Screen e la CLI OpenThread
  • Messa in servizio sicura dei dispositivi su una rete Thread
  • Come funziona il multicast IPv6
  • Trasmissione di messaggi tra i nodi Thread con UDP

Che cosa ti serve

Hardware:

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

Software:

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

2. Per iniziare

Simulazione OpenThread

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

Terminali delle porte seriali

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

Macchina Linux

Questo Codelab è stato progettato per utilizzare una macchina Linux basata su i386 o x86 come host di 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 Nordic Semiconductor nRF52840

Questo codelab utilizza tre schede PDK nRF52840.

a6693da3ce213856.png

Utilizziamo SEGGER J-Link per programmare le schede nRF52840, che dispongono di moduli JTAG integrati. Installalo sulla tua macchina Linux.

Scarica il pacchetto appropriato per la tua macchina e installalo nella posizione corretta. Su Linux è /opt/SEGGER/JLink.

Installa gli strumenti a riga di comando nRF5x

Gli strumenti a riga di comando nRF5x ti consentono di eseguire il flashing dei binari OpenThread sulle schede nRF52840. Installa la build nRF5x-Command-Line-Tools-<OS> appropriata sulla tua macchina Linux.

Inserisci il pacchetto estratto nella cartella principale ~/

Installa la suite GNU Toolchain per ARM

Per la compilazione viene utilizzata la suite di strumenti GNU ARM.

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

Schermata di installazione (facoltativa)

Screen è uno strumento semplice per accedere ai dispositivi connessi tramite una porta seriale. Questo codelab utilizza Screen, ma puoi usare qualsiasi applicazione di terminale della porta seriale che preferisci.

$ sudo apt-get install screen

3. Clonare 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

Compila il daemon OpenThread:

$ script/cmake-build posix -DOT_DAEMON=ON

Ora è tutto pronto per compilare e eseguire il flashing di OpenThread sulle schede nRF52840.

4. Configurare il Joiner RCP

Crea e esegui il flashing

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

Pulisci sempre prima il repo 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

Vai 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 pin di alimentazione esterna sulla scheda nRF52840 e poi alla macchina Linux. Imposta l'opzione Alimentazione nRF sulla scheda nRF52840 su VDD. Se è collegato correttamente, il LED5 è acceso.

20a3b4b480356447.png

Se è la prima scheda collegata alla macchina Linux, viene visualizzata come porta seriale /dev/ttyACM0 (tutte le schede nRF52840 utilizzano ttyACM per l'identificatore della porta seriale).

$ ls /dev/ttyACM*
/dev/ttyACM0

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

c00d519ebec7e5f0.jpeg

Vai alla posizione degli strumenti a riga di comando nRFx e esegui il flashing del file esadecimale RCP OpenThread sulla scheda nRF52840 utilizzando il numero di serie della scheda. Tieni presente che se non includi il flag --verify, viene visualizzato un messaggio di avviso che ti informa che il processo di 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 è riuscita, 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 come "RCP" per non confondere i ruoli della scheda in un secondo momento.

Connettiti a USB nativa

Poiché la compilazione RCP di OpenThread consente l'utilizzo dell'ACM CDC USB nativo come trasporto seriale, devi utilizzare la porta nRF USB sulla scheda nRF52840 per comunicare con l'host RCP (macchina Linux).

Scollega l'estremità micro USB del cavo USB dalla porta di debug della scheda nRF52840 con il firmware, quindi ricollegala alla porta micro USB nRF USB accanto al pulsante RESET. Imposta l'opzione Alimentazione nRF su USB.

46e7b670d2464842.png

Avvia il daemon OpenThread

Nel design RCP, utilizza OpenThread Daemon per comunicare con il dispositivo Thread e gestirlo. Avvia ot-daemon con il flag -v verbose per visualizzare l'output del log e verificare che sia in esecuzione:

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

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 aperta questa finestra del terminale in modo da poter 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 i nodi ot-daemon nello stesso modo in cui controlli gli altri dispositivi Thread simulati.

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

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

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

> state
disabled
Done

5. Configura i FTD

Gli altri due nodi Thread utilizzati in questo Codelab sono dispositivi Full Thread (FTD) con il design standard System-on-Chip (SoC). In un ambiente di produzione, puoi utilizzare wpantund, un driver di interfaccia di rete di produzione, per controllare le istanze NCP OpenThread, ma in questo codelab utilizzeremo ot-ctl, l'interfaccia a riga di comando OpenThread.

Un dispositivo funge da commissario per autenticare e mettere in servizio in modo sicuro i dispositivi sulla rete. L'altro dispositivo funge da Joiner che il commissario può autenticare nella rete Thread.

Compila e esegui il flashing

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

Vai alla directory con il file binario dell'interfaccia a riga di comando del dispositivo Thread completo (FTD) OpenThread 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 pin di alimentazione esterna sulla scheda nRF52840 e poi alla macchina Linux. Se la RCP è ancora collegata alla macchina Linux, questa nuova scheda dovrebbe essere visualizzata come porta seriale /dev/ttyACM1 (tutte le schede nRF52840 utilizzano 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

Vai alla posizione degli strumenti a riga di comando nRFx e esegui il flashing del file esadecimale FTD della CLI OpenThread 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 la scheda come "Commissioner".

Connettiti a USB nativa

Poiché la compilazione FTD di OpenThread consente l'utilizzo dell'ACM CDC USB nativo come trasporto seriale, devi utilizzare la porta nRF USB sulla scheda nRF52840 per comunicare con l'host RCP (macchina Linux).

Scollega l'estremità micro USB del cavo USB dalla porta di debug della scheda nRF52840 con il firmware, quindi ricollegala alla porta micro USB nRF USB accanto al pulsante RESET. Imposta l'opzione Alimentazione nRF su USB.

46e7b670d2464842.png

Verifica la compilazione

Verifica che la build sia andata a buon fine accedendo alla CLI di OpenThread utilizzando GNU Screen da una finestra del terminale.

$ screen /dev/ttyACM1

Nella nuova finestra, premi Invio sulla tastiera alcune volte per visualizzare il prompt > della CLI OpenThread. Attiva l'interfaccia IPv6 e controlla gli indirizzi:

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

Utilizza Ctrl+A →

d per scollegarti dalla CLI del commissario FTD e tornare al terminale Linux in modo da poter eseguire il flashing della scheda successiva. Per accedere di nuovo all'interfaccia a riga di comando in qualsiasi momento, utilizza screen -r dalla riga di comando. Per visualizzare un elenco delle schermate disponibili, usa 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 precedente per eseguire il flashing della terza scheda nRF52840 utilizzando la build ot-cli-ftd.hex esistente. Al termine, assicurati di ricollegare la scheda al PC utilizzando la porta USB nRF e imposta l'opzione Alimentazione nRF su VDD.

Se gli altri due nodi sono collegati alla macchina Linux quando è collegata questa terza scheda, dovrebbe essere visualizzata come porta seriale /dev/ttyACM2:

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

Etichetta la tavola con "Mastro".

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

$ screen -r

Crea la nuova finestra in Screen con Ctrl+A → c.

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

$ screen /dev/ttyACM2

In questa nuova finestra, premi Invio sulla tastiera alcune volte per visualizzare il prompt > della CLI OpenThread. Attiva l'interfaccia IPv6 e controlla gli indirizzi:

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

Ora che la CLI di Joiner FTD si trova nella stessa istanza di Screen del Commissioner FTD, 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 spesso da un dispositivo Thread all'altro, quindi assicurati che tutti siano attivi e facilmente accessibili. Finora abbiamo utilizzato Screen per accedere ai due FTD e questo strumento consente anche lo schermo diviso nella stessa finestra del terminale. Utilizzalo per vedere come un nodo reagisce ai comandi emessi su un altro.

Idealmente, dovresti avere quattro finestre subito disponibili:

  1. ot-daemon service / logs
  2. Joiner RCP tramite ot-ctl
  3. Commissionario FTD tramite interfaccia a riga di comando OpenThread
  4. FTD Joiner tramite interfaccia a riga di comando OpenThread

Se vuoi utilizzare la tua configurazione o il tuo strumento per terminali / porte seriali, puoi andare al passaggio successivo. Configura le finestre del terminale per tutti i dispositivi nel modo più adatto alle tue esigenze.

Utilizzare lo schermo

Per semplicità d'uso, avvia una sola sessione di Screen. Dovresti già averne uno dalla configurazione di entrambi gli FTD.

Tutti i comandi in Screen iniziano con Ctrl+A.

Comandi di base della schermata:

Ricollegarsi alla sessione Screen (dalla riga di comando)

screen -r

Uscire dalla sessione dello schermo

Ctrl+A → d

Creare una nuova finestra all'interno della sessione dello schermo

Ctrl+A → c

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

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

Uccidere la finestra corrente nella sessione Screen

Ctrl+A → k

Schermo diviso

Con Screen, puoi suddividere il terminale in più finestre:

f1cbf1258cf0a5a.png

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

Se hai seguito esattamente il Codelab, dovresti avere due finestre (FTD Commissioner, FTD Joiner) nella stessa istanza di Screen. Per suddividere lo schermo tra i due, accedi prima alla sessione Screen esistente:

$ screen -r

Dovresti utilizzare 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 alla nuova finestra successiva
  4. Se è uguale alla finestra in alto, premi di nuovo Ctrl+A → n per visualizzare l'altro dispositivo FTD.

Ora sono entrambi visibili. Passa da una all'altra utilizzando Ctrl+A → Tab. Per evitare confusione, ti consigliamo di rinominare ogni finestra con Ctrl+A → A.

Utilizzo avanzato

Per suddividere ulteriormente lo schermo in quadranti e visualizzare i log di ot-daemon e RCP Joiner ot-ctl, questi servizi devono essere avviati nella stessa istanza di Screen. Per farlo, interrompi ot-daemon ed esci da ot-ctl, quindi riavviali in nuove finestre di Screen (Ctrl+A → c).

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

Suddividi e passa da una finestra all'altra con i seguenti comandi:

Crea nuova finestra

Ctrl+A → c

Dividere la finestra in verticale

Ctrl+A →

Dividere la finestra in orizzontale

Ctrl+A → S

Passa alla finestra visualizzata successiva

Ctrl+A → Tab

Passare alla finestra visualizzata precedente o successiva

Ctrl+A → n o p

Rinominare la finestra corrente

Ctrl+A → A

Esci da Screen in qualsiasi momento con Ctrl+a → d e ricollega con screen -r dalla riga di comando.

Per ulteriori informazioni su Screen, consulta la guida rapida di GNU Screen.

7. Crea la rete Thread

Ora che hai configurato tutte le finestre e le schermate del terminale, crea la tua rete Thread. In FTD Commissioner, crea un nuovo set di dati operativo e esegui il commit come set attivo. Il set di dati operativo è la configurazione della 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

Attiva l'interfaccia IPv6:

> ifconfig up
Done

Avvia l'operazione del protocollo Thread:

> thread start
Done

Dopo un istante, controlla lo stato del dispositivo. Dovrebbe essere il leader. Prendi nota anche dell'RLOC16 per 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)

La rete "codelab" è ora visibile quando viene scansionata da altri dispositivi Thread.

Da ot-ctl nel joiner RCP:

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

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

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

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

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

Se la rete "codelab" non è presente nell'elenco, riprova a eseguire la ricerca.

8. Aggiungi il joiner RCP

La messa in servizio di Thread non è attiva sulla rete, il che significa che dovremo aggiungere il Joiner RCP alla rete Thread che abbiamo appena creato utilizzando una procedura di messa in servizio out-of-band.

Nel Commissioner FTD abbiamo preso nota della Network Key, ad esempio 1234c0de7ab51234c0de7ab51234c0de. Se devi cercare di nuovo la chiave di rete, esegui il seguente comando su FTD Commissioner:

## FTD Commissioner ##

> dataset networkkey
1234c0de7ab51234c0de7ab51234c0de
Done

Successivamente, nel Joiner RCP, imposta la chiave di rete del set di dati attivo sulla chiave di rete del commissario FTD:

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

Apri il thread in modo che il Joiner RCP si unisca alla rete "codelab". 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 locale del mesh (fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f qui), lo utilizzerai in seguito.

Torna in FTD Commissioner, controlla le tabelle del router e del dispositivo secondario per verificare che entrambi i dispositivi appartengano alla stessa rete. Utilizza l'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 locale del Joiner RCP (l'indirizzo mesh locale ottenuto dall'output ipaddr del Joiner RCP) 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

Mentre svolgi il resto del codelab, mostreremo un nuovo diagramma della topologia di Thread ogni volta che cambia lo stato della rete. 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 ogni nodo rappresentano l'ID router o l'ID secondario mostrato nell'output della CLI, a seconda del ruolo e dello stato attuali di ciascun nodo in quel momento.

9. Messa in servizio del joiner FTD

Ora aggiungiamo il terzo dispositivo Thread alla rete "codelab". Questa volta utilizzeremo la procedura di messa in servizio in banda più sicura e consentiremo solo l'unione del Joiner FTD.

Sul codice fiscale del partecipante al programma, ottieni il eui64 in modo che il commissario del programma FTD possa identificarlo:

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

> eui64
2f57d222545271f1
Done

In FTD Commissioner, avvia il commissioner e specifica il eui64 del dispositivo che può partecipare, insieme alla credenziale del partecipante, ad esempio J01NME. La credenziale Joiner è una stringa specifica del dispositivo composta da tutti i caratteri alfanumerici maiuscoli (0-9 e A-Y, esclusi I, O, Q e Z per 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. Avvia il ruolo di partecipante con le credenziali del partecipante che hai appena configurato nel commissario FTD:

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

> ifconfig up
Done
> joiner start J01NME
Done

Entro un minuto circa, riceverai una conferma dell'autenticazione riuscita:

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

>
Join success

Apri il thread in modo che il Joiner FTD si colleghi alla rete "codelab" e controlla immediatamente lo stato e l'RLOC16:

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

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

Controlla gli indirizzi IPv6 del dispositivo. Tieni presente che non è presente alcun ALOC. Questo perché il dispositivo non è il leader né ha un ruolo Anycast specifico 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 a FTD Commissioner e controlla le tabelle del router e dei dispositivi secondari per verificare che nella rete "codelab" esistano tre dispositivi:

## 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 all'RLOC16, il Joiner FTD si è connesso alla rete come dispositivo finale (secondario). Ecco la nostra topologia aggiornata:

otcodelab_top01C_ed01.png

10. Thread in azione

I dispositivi Thread in questo Codelab sono un tipo specifico di dispositivo Full Thread (FTD) chiamato dispositivo di destinazione idoneo per il router (REED). Ciò significa che possono funzionare come router o come dispositivo di destinazione e possono essere promossi da un dispositivo di destinazione a un 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 connette come dispositivo di destinazione (secondario) e il numero di router è inferiore a 16, dopo un periodo di tempo casuale di massimo due minuti si promuove automaticamente a router.

Se nella tua rete Thread erano presenti due nodi secondari dopo l'aggiunta del Joiner FTD, attendi almeno due minuti e poi ricontrolla le tabelle del router e dei nodi secondari nel Commissioner FTD:

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

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

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

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

otcodelab_top01C.png

Conferma il nuovo stato e l'RLOC16 sul Joiner FTD:

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

> state
router
Done
> rloc16
b800
Done

Esegui il downgrade del Joiner FTD

Puoi testare questo comportamento eseguendo manualmente il downgrade del Joiner FTD da un router a un dispositivo di destinazione. Modifica lo stato in secondario e controlla il valore RLOC16:

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

> state child
Done
> rloc16
0c03
Done

otcodelab_top01C_ed02.png

Tornando a FTD Commissioner, l'operatore di join FTD dovrebbe ora essere visualizzato nella tabella secondaria (ID = 3). Potrebbe anche essere in entrambe durante la transizione:

## 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, tornerà a un router con un RLOC di b800.

otcodelab_top01C.png

Rimuovi il leader

Il leader viene eletto autonomamente 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.

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

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

> thread stop
Done
> ifconfig down
Done

Entro due minuti, il Joiner FTD diventa il nuovo Thread leader. Controlla lo stato e gli indirizzi IPv6 del Joiner FTD 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. Tieni presente che è presente un nuovo RLOC16. Si tratta del Joiner RCP, come indicato dall'ID e dall'indirizzo MAC esteso. Per mantenere unita la rete Thread, ha cambiato router principale, dal Commissioner FTD al Joiner FTD. Il risultato è un nuovo RLOC16 per il Joiner RCP (in quanto l'ID router è cambiato 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 qualche minuto prima che il joiner RCP si colleghi al joiner FTD come elemento secondario. Controlla lo stato e l'RLOC16 per verificare che:

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

> state
child
> rloc16
b801

Ricollega il commissario FTD

Una rete Thread con due nodi non è molto divertente. Riportiamo online il commissario FTD.

In FTD Commissioner, riavvia il thread:

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

> ifconfig up
Done
> thread start
Done

Entro due minuti, si ricollega automaticamente alla rete "codelab" come dispositivo di destinazione e poi si promuove a router.

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

> state
router
Done

Controlla le tabelle del router e secondarie nell'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

La gestione di una rete Thread con più dispositivi su terminali o finestre dello schermo diversi può essere complicata. Utilizza questi suggerimenti per "reimpostare" lo stato della rete o dello spazio di lavoro in caso di problemi.

Schermo

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

Nodi Thread

Se la topologia di rete Thread non è come descritta in questo Codelab o i nodi si disconnettono per qualche motivo (ad esempio perché la macchina Linux che li alimenta è andata in sospensione), è meglio arrestare Thread, cancellare le credenziali di rete e ricominciare dal passaggio Creare la rete Thread.

Per reimpostare i 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 all'utilizzo multicast con diversi gruppi di dispositivi, a seconda dell'ambito.

Indirizzo IPv6

Ambito

Consegnato a

ff02::1

Link-local

Tutti gli FTD e gli MED

ff02::2

Link-local

Tutti gli FTD e i router di confine

ff03::1

Mesh-local

Tutti gli FTD e gli MED

ff03::2

Mesh-local

Tutti gli FTD e i router di confine

Poiché 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 da un singolo "hop". La topologia di rete determina quali dispositivi rispondono a un ping all'indirizzo multicast ff02::1.

Ping ff02::1 del commissario FTD:

## 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 il commissario FTD ha ricevuto una sola risposta, dall'indirizzo link-local (LLA) del FTD Joiner. Ciò significa che il Joiner FTD è l'unico dispositivo che il Commissioner FTD può raggiungere con un solo hop.

otcodelab_top02C_02_LL.png

Ora esegui un ping a ff02::1 dal Joiner FTD:

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

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

Due risposte. Controllando gli indirizzi IPv6 degli altri dispositivi, possiamo vedere che il primo (che termina con 4b1d) è l'LLA del commissario FTD e il secondo (che termina con 943b) è l'LLA del joiner RCP.

otcodelab_top02C_02_LL02.png

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

Mesh-local

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

Ping ff03::1 del commissario FTD:

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

> ping ff03::1
> 8 bytes from fdc0:de7a:b5c0:0:0:ff:fe00:b800: icmp_seq=3 hlim=64 time=9ms
8 bytes from fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f: icmp_seq=3 hlim=64 time=68ms

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

otcodelab_top02C_02_ML.png

Esegui un ping a ff03::1 dal Joiner FTD per verificare 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. Il Joiner RCP ha impiegato molto più tempo per raggiungere il Commissioner FTD (68 ms) rispetto al Joiner FTD (23 ms). Questo perché deve effettuare due hop per raggiungere il Commissioner FTD, rispetto a un solo hop per il Joiner FTD.

Potresti anche aver notato che il ping multicast locale del mesh ha risposto con l'RLOC solo per i due FTD, non per il Joiner RCP. Questo perché gli FTD sono router all'interno della rete, mentre l'RCP è un dispositivo di destinazione.

Controlla lo stato del joiner RCP per confermare:

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

> state
child

13. Inviare messaggi con UDP

Uno dei servizi di applicazione forniti da OpenThread è il protocollo User Datagram Protocol (UDP), un protocollo del livello di trasporto. Un'applicazione basata su OpenThread potrebbe utilizzare l'API UDP per trasmettere messaggi tra i nodi di una rete Thread o ad altri dispositivi di una rete esterna (ad esempio internet, se la rete Thread dispone di un router di confine).

Le socket UDP sono esposte tramite la CLI OpenThread. Utilizziamolo per trasmettere i messaggi tra i due FTD.

Ottieni l'indirizzo EID locale mesh per il Joiner FTD. Utilizziamo 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 una socket per qualsiasi indirizzo IPv6:

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

> udp open
Done
> udp bind :: 1212

Passa al commissario FTD, avvia UDP e connettiti alla socket configurata sul Joiner FTD 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 della FTD:

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

> udp send hellothere
Done

Sul Joiner FTD, 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, ruoli e ambiti dei dispositivi Thread
  • Come i dispositivi Thread gestiscono i propri stati all'interno della rete
  • come trasmettere messaggi semplici tra i nodi utilizzando UDP

Passaggi successivi

A partire da questo codelab, prova i seguenti esercizi:

  • Esegui il reflash della scheda Joiner FTD come MTD utilizzando il file binario ot-cli-mtd e osserva che non esegue mai l'upgrade a un router o non tenta di diventare il leader
  • Aggiungi altri dispositivi (prova una piattaforma diversa) alla rete e abbozza la topologia utilizzando le tabelle router e secondarie, oltre ai ping agli indirizzi multicast
  • Utilizza pyspinel per controllare il NCP
  • Converti il NCP in un router di confine utilizzando OpenThread Border Router e connetti la rete Thread a internet

Per approfondire

Visita openthread.io e GitHub per una serie di risorse OpenThread, tra cui:

Riferimento: