Crea una red Thread con placas nRF52840 y OpenThread

1. Introducción

26b7f4f6b3ea0700.png

OpenThread lanzada por Google es una implementación de código abierto del protocolo de red Thread®. Google Nest lanzó OpenThread para que la tecnología que se usa en sus productos esté ampliamente disponible para los desarrolladores con el objetivo de acelerar el desarrollo de productos para el hogar conectado.

La especificación de Thread define un protocolo de comunicación de dispositivo a dispositivo inalámbrico, seguro y de bajo consumo basado en IPv6 para aplicaciones domésticas. OpenThread implementa todas las capas de red de Thread, incluidas IPv6, 6LoWPAN, IEEE 802.15.4 con seguridad MAC, establecimiento de vínculos de malla y enrutamiento de malla.

En este codelab, programarás OpenThread en hardware real, crearás y administrarás una red de Thread, y pasarás mensajes entre nodos.

4806d16a8c137c6d.jpeg

Qué aprenderás

  • Cómo compilar y escribir en la memoria flash objetos binarios de la CLI de OpenThread en las placas de desarrollo
  • Cómo compilar un RCP que consta de una máquina Linux y una placa de desarrollo
  • Comunicación con un RCP a través de OpenThread Daemon y ot-ctl
  • Cómo administrar nodos de Thread de forma manual con GNU Screen y la CLI de OpenThread
  • Puesta en servicio segura de dispositivos en una red Thread
  • Cómo funciona la multidifusión IPv6
  • Pasa mensajes entre nodos de subprocesos con UDP

Requisitos

Hardware:

  • 3 placas de desarrollo Nordic Semiconductor nRF52840
  • 3 cables USB a micro USB para conectar las placas
  • Una máquina Linux con al menos 3 puertos USB

Software:

  • Cadena de herramientas GNU
  • Herramientas de línea de comandos nRF5x nórdicas
  • Software de Segger J-Link
  • OpenThread
  • Git

2. Cómo comenzar

Simulación de OpenThread

Antes de comenzar, es posible que quieras ejecutar el Codelab de simulación de OpenThread para familiarizarte con los conceptos básicos de Thread y la CLI de OpenThread.

Terminales de puerto en serie

Debes estar familiarizado con el modo de conexión a un puerto en serie a través de una terminal. Este codelab usa GNU Screen y proporciona una descripción general de uso, pero se puede usar cualquier otro software de terminal.

Máquina Linux

Este codelab se diseñó para usar una máquina Linux basada en i386 o x86 para que funcione como host de un dispositivo Thread de coprocesador de radio (RCP) y escribir en la memoria flash todas las placas de desarrollo de Thread. Todos los pasos se probaron en Ubuntu 14.04.5 LTS (Trusty Tahr).

Placas Nordic Semiconductor nRF52840

En este codelab, se usan tres placas de PDK nRF52840.

a6693da3ce213856.png

Usamos SEGGER J-Link para programar las placas nRF52840, que tienen módulos JTAG integrados. Instálalo en tu máquina Linux.

Descarga el paquete adecuado para tu máquina y, luego, instálalo en la ubicación adecuada. En Linux, es /opt/SEGGER/JLink.

Instala las herramientas de línea de comandos nRF5x

Las herramientas de línea de comandos nRF5x te permiten escribir en la memoria flash de los objetos binarios de OpenThread en las placas nRF52840. Instala las herramientas de línea de comandos nRF5x-<OS> adecuadas. compilar en tu máquina Linux.

Coloca el paquete extraído en la carpeta raíz ~/.

Instala la cadena de herramientas ARM GNU

La cadena de herramientas ARM GNU se usa para la compilación.

Recomendamos colocar el archivo extraído en /opt/gnu-mcu-eclipse/arm-none-eabi-gcc/ en tu máquina Linux. Sigue las instrucciones del archivo readme.txt para obtener las instrucciones de instalación.

Pantalla de instalación (opcional)

La pantalla es una herramienta simple para acceder a dispositivos conectados por un puerto en serie. En este codelab, se usa Screen, pero puedes usar cualquier aplicación de terminal de puerto en serie que desees.

$ sudo apt-get install screen

3. Clona repositorios

OpenThread

Clona e instala OpenThread. Los comandos script/bootstrap garantizan que la cadena de herramientas esté instalada y que el entorno esté configurado correctamente:

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

Compila el daemon de OpenThread:

$ script/cmake-build posix -DOT_DAEMON=ON

Ya tienes todo listo para compilar y escribir en la memoria flash OpenThread en las placas nRF52840.

4. Cómo configurar la unión de RCP

Compila y escribe en la memoria flash

Compila el ejemplo de OpenThread nRF52840 con la funcionalidad de Joiner y USB nativa. Un dispositivo usa el rol de Unión para autenticar y solicitar de forma segura en una red Thread. El USB nativo permite el uso de USB CDC ACM como transporte en serie entre el nRF52840 y el host.

Siempre ejecuta rm -rf build para limpiar el repositorio de las compilaciones anteriores.

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

Navega al directorio con el objeto binario RCP de OpenThread y conviértelo en formato hexadecimal:

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

Conecta el cable USB al puerto de depuración Micro-USB junto al pin de alimentación externo en la placa nRF52840 y conéctalo a la máquina Linux. Establece el interruptor de la fuente de alimentación de nRF de la placa nRF52840 en VDD. Cuando se conecta correctamente, la luz LED5 se enciende.

20a3b4b480356447.png

Si es la primera placa conectada a la máquina Linux, aparecerá como puerto en serie /dev/ttyACM0 (todas las placas nRF52840 usan ttyACM para el identificador de puerto en serie).

$ ls /dev/ttyACM*
/dev/ttyACM0

Ten en cuenta el número de serie de la placa nRF52840 que se usa para el RCP:

c00d519ebec7e5f0.jpeg

Navega a la ubicación de las herramientas de línea de comandos nRFx y escribe el archivo hexadecimal RCP de OpenThread en la placa nRF52840 con el número de serie de la placa. Ten en cuenta que si omites la marca --verify, verás un mensaje de advertencia que te indicará que el proceso Flash puede fallar sin errores.

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

Si se ejecuta de forma correcta, se genera el siguiente resultado:

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.

Etiqueta la placa como “RCP” para no confundir luego los roles de la junta.

Conectar a USB nativo

Debido a que la compilación del RCP de OpenThread permite usar el ACM de los CDC de USB nativo como un transporte en serie, debes usar el puerto nRF USB de la placa nRF52840 para comunicarte con el host RCP (máquina Linux).

Desconecta el extremo micro-USB del cable USB del puerto de depuración de la placa nRF52840 en la memoria flash y vuelve a conectarla al puerto micro-USB nRF USB que se encuentra junto al botón RESTABLECER. Establece el interruptor de la fuente de alimentación de nRF en USB.

46e7b670d2464842.png

Inicia el daemon de OpenThread

En el diseño de RCP, usa OpenThread Daemon para comunicarte con el dispositivo Thread y administrarlo. Inicia ot-daemon con la marca detallada -v para que puedas ver el resultado del registro y confirmar que se esté ejecutando:

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

Cuando se ejecuta de forma correcta, ot-daemon en el modo detallado genera un resultado similar al siguiente:

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

Deja abierta esta ventana de la terminal para que se puedan ver los registros de ot-daemon.

Usa ot-ctl para comunicarte con el nodo RCP. ot-ctl usa la misma CLI que la app de la CLI de OpenThread. Por lo tanto, puedes controlar los nodos ot-daemon de la misma manera que los otros dispositivos Thread simulados.

En una segunda ventana de terminal, inicia ot-ctl:

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

Verifica el state del Nodo 2 (el nodo RCP) que iniciaste con ot-daemon:

> state
disabled
Done

5. Configura los FTD

Los otros dos nodos de subprocesos que se usan en este codelab son dispositivos de subprocesos completos (FTD) en el diseño estándar de sistema en chip (SoC). En una configuración de producción, es posible usar wpantund, un controlador de interfaz de red de nivel de producción, para controlar las instancias de NCP de OpenThread, pero en este codelab usaremos ot-ctl, la CLI de OpenThread.

Un dispositivo funciona como el comisionado para autenticar y asignar dispositivos de forma segura a esa red. El otro dispositivo funciona como un Unión que el Comisionado puede autenticar en la red Thread.

Compila y escribe en la memoria flash

Compila el ejemplo de FTD de OpenThread para la plataforma nRF52840 con las funciones Commissioner y Joiner habilitadas:

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

Navega al directorio con el objeto binario de la CLI de OpenThread Full Thread Device (FTD) y conviértelo al formato hexadecimal:

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

Conecta el cable USB al puerto micro USB junto al pin de alimentación externo en la placa nRF52840 y conéctalo a la máquina Linux. Si el RCP sigue conectado a la máquina Linux, esta placa nueva debería aparecer como puerto en serie /dev/ttyACM1 (todas las placas nRF52840 usan ttyACM para el identificador de puerto en serie).

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

Como antes, ten en cuenta el número de serie de la placa nRF52840 que se usa para el FTD:

c00d519ebec7e5f0.jpeg

Dirígete a la ubicación de las herramientas de línea de comandos nRFx y escribe el archivo hexadecimal FTD de la CLI de OpenThread en la placa nRF52840 con el número de serie de la placa:

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

Etiqueta la junta como "Comisionado".

Conectar a USB nativo

Debido a que la compilación del FTD de OpenThread permite usar el ACM de los CDC de USB nativo como un transporte en serie, debes usar el puerto nRF USB de la placa nRF52840 para comunicarte con el host RCP (máquina Linux).

Desconecta el extremo micro-USB del cable USB del puerto de depuración de la placa nRF52840 en la memoria flash y vuelve a conectarla al puerto micro-USB nRF USB que se encuentra junto al botón RESTABLECER. Establece el interruptor de la fuente de alimentación de nRF en USB.

46e7b670d2464842.png

Verifica la compilación

Verifica una compilación exitosa accediendo a la CLI de OpenThread con GNU Screen desde una ventana de terminal. Las placas nRF52840 usan una tasa de baudios de 115200.

$ screen /dev/ttyACM1 115200

En la ventana nueva, presiona Intro en el teclado algunas veces para que aparezca el mensaje > de la CLI de OpenThread. Abre la interfaz IPv6 y verifica las direcciones:

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

Usa Ctrl+a →

d para desconectarte de la pantalla de la CLI de FTD Commissioner y regresar a la terminal de Linux para poder escribir en la memoria flash de la siguiente placa. Para volver a ingresar a la CLI en cualquier momento, usa screen -r desde la línea de comandos. Para ver una lista de pantallas disponibles, usa screen -ls:

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

Cómo configurar la unión de FTD

Repite el proceso anterior para escribir en la memoria flash la tercera placa nRF52840 con la compilación ot-cli-ftd.hex existente. Cuando termines, asegúrate de volver a conectar la placa a la PC con el puerto USB de nRF y establece el interruptor de la fuente de alimentación de nRF en VDD.

Si los otros dos nodos están conectados a la máquina de Linux cuando se conecta esta tercera placa, debería aparecer como puerto en serie /dev/ttyACM2:

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

Etiqueta el tablero como "Unión".

Cuando realices la verificación con Screen, en lugar de crear una instancia nueva de Screen desde la línea de comandos, vuelve a conectarla a la existente y crea una ventana nueva dentro de ella (la que usaste para FTD Commissioner):

$ screen -r

Crea la nueva ventana dentro de Screen con Ctrl+a → c.

Aparecerá un nuevo símbolo del sistema de la línea de comandos. Accede a la CLI de OpenThread para la unión FTD:

$ screen /dev/ttyACM2 115200

En esta ventana nueva, presiona Intro en el teclado algunas veces para que aparezca el mensaje > de la CLI de OpenThread. Abre la interfaz IPv6 y verifica las direcciones:

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

Ahora que la CLI de FTD Joiner se encuentra en la misma instancia de Screen que el comisionado de FTD, puedes cambiar entre ellas con Ctrl + a → n.

Usa Ctrl+a →

d en cualquier momento para salir de la pantalla

6. Configuración de la ventana de la terminal

De ahora en adelante, cambiarás dispositivos Thread con frecuencia, así que asegúrate de que todos estén activos y de fácil acceso. Hasta ahora, usamos Screen para acceder a los dos FTD, y esta herramienta también permite dividir la pantalla en la misma ventana de la terminal. Úsalos para ver cómo reacciona un nodo a los comandos emitidos en otro.

Lo ideal sería tener cuatro ventanas disponibles:

  1. Servicio / registros ot-daemon
  2. Unión de RCP a través de ot-ctl
  3. Comisionado de FTD a través de la CLI de OpenThread
  4. FTD Joiner a través de la CLI de OpenThread

Si deseas usar tu propia herramienta o configuración de terminal o puerto en serie, no dudes en continuar con el siguiente paso. Configura las ventanas de terminal para todos los dispositivos de la manera que te resulte más conveniente.

Uso de la pantalla

Para facilitar su uso, solo inicia una sesión de Screen. Ya deberías tener uno cuando configuraste ambos FTD.

Todos los comandos dentro de Pantalla comienzan con Ctrl+a.

Comandos básicos de la pantalla:

Vuelve a conectarte a la sesión Screen (desde la línea de comandos).

screen -r

Salir de la sesión de Screen

Ctrl+a → d

Crear una ventana nueva dentro de la sesión de Screen

Ctrl+a → c

Alternar entre ventanas en la misma sesión de pantalla

Ctrl+a → n (adelante)Ctrl+a → p (atrás)

Cierra la ventana actual de la sesión de pantalla

Ctrl+a → k

Pantalla dividida

Con Screen, puedes dividir la terminal en varias ventanas:

f1cbf1258cf0a5a.png

Para acceder a los comandos en screen, usa Ctrl + a. Cada comando debería comenzar con esta combinación de claves de acceso.

Si seguiste el codelab exactamente, deberías tener dos ventanas (FTD Commissioner, FTD Joiner) en la misma instancia de Screen. Para dividir la pantalla entre ambas, primero ingresa a tu sesión de pantalla existente:

$ screen -r

Debes usar uno de los dispositivos FTD. Sigue estos pasos en Pantalla:

  1. Ctrl+a → S para dividir la ventana horizontalmente
  2. Ctrl+a → Tab para mover el cursor a la nueva ventana en blanco
  3. Ctrl+a → n para cambiar la ventana nueva a la siguiente
  4. Si es la misma que la ventana superior, presiona Ctrl+a → n de nuevo para ver el otro dispositivo de FTD.

Ahora ambos están visibles. Para pasar de una a otra, presiona Ctrl + a → Tab. Se recomienda volver a nombrar cada ventana con Ctrl+a → A para evitar confusiones.

Uso avanzado

Para dividir aún más la pantalla en cuadrantes y ver los registros de ot-daemon y el ot-ctl de la unión de RCP, esos servicios deben iniciarse en esta misma instancia de Screen. Para hacerlo, detén ot-daemon, sal de ot-ctl y reinícialo en nuevas ventanas de pantalla (Ctrl+a → c).

Esta configuración no es obligatoria y se deja como un ejercicio para el usuario.

Divide las ventanas y navega entre ellas con los siguientes comandos:

Crear ventana nueva

Ctrl+a → c

Dividir ventana verticalmente

Ctrl+a →

Dividir ventana horizontal

Ctrl+a → S

Pasar a la siguiente ventana que se muestra

Ctrl+a → Tab

Mueve la ventana que se muestra hacia adelante o hacia atrás

Ctrl+a → n o p

Cambiar el nombre de la ventana actual

Ctrl+a → A

Sal de la pantalla en cualquier momento con Ctrl+a → d y vuelve a adjuntarlo con screen -r desde la línea de comandos.

Para obtener más información sobre Screen, consulta la referencia rápida de GNU Screen.

7. Crea la red de Thread

Ahora que tienes configuradas todas las ventanas y pantallas de la terminal, creemos nuestra red Thread. En el Comisionado de FTD, crea un conjunto de datos operativo nuevo y confírmalo como el activo. El conjunto de datos operativo es la configuración de la red Thread que estás 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

Toma nota de la clave de red 1234c0de7ab51234c0de7ab51234c0de que usarás más adelante.

Confirmar este conjunto de datos como el activo:

> dataset commit active
Done

Abre la interfaz IPv6:

> ifconfig up
Done

Inicia la operación del protocolo Thread:

> thread start
Done

Después de un momento, revisa el estado del dispositivo. Debe ser el líder. Además, obtén el RLOC16 para consultarlo en el futuro.

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

> state
leader
Done
> rloc16
0c00
Done

Verifica las direcciones 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)

El “codelab” ahora es visible cuando se escanea desde otros dispositivos Thread.

Desde ot-ctl en el Unión de RCP:

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

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

Desde la CLI de OpenThread en FTD Joiner, haz lo siguiente:

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

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

Si el "codelab" red no aparece en la lista, intenta buscar nuevamente.

8. Agrega el Unión de RCP

La puesta en marcha de subprocesos no está activa en la red, por lo que tendremos que agregar la unión de RCP a la red de Thread que acabamos de crear con un proceso de comisión fuera de banda.

En el FTD Commissioner, tomamos nota de la clave de red, por ejemplo, 1234c0de7ab51234c0de7ab51234c0de. Si necesitas volver a buscar la clave de red, ejecuta el siguiente comando en FTD Commissioner:

## FTD Commissioner ##

> dataset networkkey
1234c0de7ab51234c0de7ab51234c0de
Done

A continuación, en RCP Joiner, establece su clave de red del conjunto de datos activo en la clave de red FTD Commissioner:

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

> dataset networkkey 1234c0de7ab51234c0de7ab51234c0de
Done
> dataset commit active
Done

Revisa el conjunto de datos para asegurarte de que esté configurado correctamente.

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

> dataset
Network Key: 1234c0de7ab51234c0de7ab51234c0de

Abre Thread para que el Unión de RCP se una al "codelab" en cada red. Espera unos segundos y comprueba el estado, RLOC16 y sus direcciones 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

Toma nota de la dirección IPv6 local de malla (aquí fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f), ya que la usarás más adelante.

Vuelve al FTD Commissioner, comprueba el router y las tablas secundarias para confirmar que ambos dispositivos formen parte de la misma red. Usa RLOC16 para identificar el Unión 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

Haz ping a la dirección de malla local del RCP Joiner (la dirección de malla local obtenida del resultado ipaddr de RCP Joiner) para verificar la conectividad:

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

Ahora tenemos una red Thread que consta de dos nodos, como se ilustra en este diagrama de topología:

otcodelab_top01C_2nodes.png

Diagramas de topología

A medida que trabajes con el resto del codelab, mostraremos un nuevo diagrama de topología de Thread cada vez que cambie el estado de la red. Los roles de nodo se indican de la siguiente manera:

b75a527be4563215.png

Los routers siempre son pentágonos y los dispositivos finales son siempre círculos. Los números de cada nodo representan el ID de router o el ID secundario que se muestra en el resultado de la CLI, según la función y el estado actuales de cada nodo en ese momento.

9. Encargo a la empresa de unión de FTD

Ahora, agreguemos el tercer dispositivo Thread al “codelab” en cada red. Esta vez, usaremos el proceso de comisión en banda, que es más seguro, y solo permitiremos que se una el FTD Joiner.

En el FTD Joiner, obtén el eui64 para que el FTD Commissioner pueda identificarlo:

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

> eui64
2f57d222545271f1
Done

En el Comisionado de FTD, inicia el comisionado y especifica el eui64 del dispositivo que puede unirse, junto con la credencial de unión, por ejemplo, J01NME. La credencial de unión es una cadena específica del dispositivo de todos los caracteres alfanuméricos en mayúsculas (0-9 y A-Y, sin incluir I, O, Q y Z para facilitar la lectura), con una longitud de entre 6 y 32 caracteres.

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

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

Cambia a FTD Joiner. Comienza la función de Unión con la credencial de unión que acabas de configurar en el comisionado de FTD:

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

> ifconfig up
Done
> joiner start J01NME
Done

En un plazo aproximado de un minuto, recibirás la confirmación de que la autenticación se realizó correctamente:

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

>
Join success

Abre Thread para que el FTD Joiner se una al "codelab" y verifica de inmediato el estado y RLOC16:

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

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

Verifica las direcciones IPv6 del dispositivo. Observa que no hay ningún ALOC. Esto se debe a que este dispositivo no es el líder ni tiene una función específica de Anycast que requiere 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)

Cambia de inmediato al FTD Commissioner y revisa el router y las tablas secundarias para confirmar que existan tres dispositivos en el "codelab" red:

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

En función del RLOC16, el Unión de FTD se conectó a la red como dispositivo final (secundario). Esta es nuestra topología actualizada:

otcodelab_top01C_ed01.png

10. Conversación en acción

Los dispositivos Thread de este codelab son un tipo específico de dispositivo de Thread completo (FTD) llamado dispositivo final apto para router (REED). Esto significa que pueden funcionar como router o dispositivo final, y pueden pasar de un dispositivo final a un router.

Thread puede admitir hasta 32 routers, pero intenta mantener la cantidad de routers entre 16 y 23. Si un REED se conecta como dispositivo final (secundario) y la cantidad de routers es inferior a 16, después de un período aleatorio de dos minutos, se convierte automáticamente en un router.

Si tenías dos elementos secundarios en tu red de Thread después de agregar la unión de FTD, espera al menos dos minutos y vuelve a verificar el router y las tablas secundarias en el Comisionado de 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

El conector de FTD (MAC extendido = e6cdd2d93249a243) se ascendió a un router. Ten en cuenta que RLOC16 es diferente (b800 en lugar de 0c02). Esto se debe a que RLOC16 se basa en el ID de router y el ID secundario de un dispositivo. Cuando pasa del dispositivo final al router, cambian los valores de su ID de router y de ID secundario, al igual que el RLOC16.

otcodelab_top01C.png

Confirma el nuevo estado y RLOC16 en la FTD Joiner:

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

> state
router
Done
> rloc16
b800
Done

Cambiar la unión de FTD a una versión inferior

Para probar este comportamiento, cambia manualmente el FTD Joiner de un router a uno final. Cambia el estado a secundario y verifica el RLOC16:

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

> state child
Done
> rloc16
0c03
Done

otcodelab_top01C_ed02.png

En FTD Commissioner, el FTD Joiner ahora debería aparecer en la tabla secundaria (ID = 3). Incluso puede aparecer en ambos durante la transición:

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

Después de un tiempo, volverá a un router con un RLOC de b800.

otcodelab_top01C.png

Quita al líder

El líder es autoelegido entre todos los routers Thread. Esto significa que, si se quita el líder actual de la red Thread, uno de los otros routers se convertirá en el nuevo líder.

En el FTD Commissioner, cierra Thread para quitarlo de la red:

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

> thread stop
Done
> ifconfig down
Done

En un plazo de dos minutos, FTD Joiner se convierte en el nuevo líder de subprocesos. Comprueba el estado y las direcciones IPv6 de la unión de FTD para comprobar lo siguiente:

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

Verifica la tabla secundaria. Observa que hay un nuevo RLOC16. Este es el RCP Joiner, como lo indican su ID y MAC extendido. Para mantener juntas la red Thread, los routers principales cambiaron de la función de comisionado de FTD a la de Unión de FTD. Esto da como resultado un nuevo RLOC16 para el RCP Joiner (porque su ID de router cambió de 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

Es posible que debas esperar unos minutos para que RCP Joiner se conecte al FTD Joiner como elemento secundario. Verifica el estado y el RLOC16 para confirmar lo siguiente:

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

> state
child
> rloc16
b801

Vuelva a adjuntar el comisionado de FTD

Una red Thread con dos nodos no es muy divertida. Volvamos a poner en línea al comisionado de FTD.

En el FTD Commissioner, reinicia Thread:

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

> ifconfig up
Done
> thread start
Done

En dos minutos, se vuelve a conectar automáticamente al "codelab" red como un Dispositivo Final y se convierte en un router.

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

> state
router
Done

Revisa el router y las tablas secundarias en el FTD Joiner para comprobar lo siguiente:

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

Nuestra red de Thread, nuevamente, consta de tres nodos.

11. Soluciona problemas

Administrar una red Thread con varios dispositivos en diferentes terminales o ventanas de pantalla puede ser complicado. Sigue estas sugerencias para "restablecer" el estado de la red o tu lugar de trabajo si tienes problemas.

Pantalla

Si alguna vez te pierdes en tu configuración (demasiadas ventanas o pantallas dentro de Pantalla), sigue finalizando las ventanas de pantalla con Ctrl + a → k hasta que no exista ninguna y screen -ls en la línea de comandos muestre un resultado No Sockets found. Luego, vuelve a crear las ventanas de pantalla para cada dispositivo. Los estados del dispositivo se conservan incluso cuando se cierra la pantalla.

Nodos de subprocesos

Si la topología de red de Thread no es como se describe en este codelab o si los nodos se desconectan por algún motivo (tal vez porque la máquina de Linux que los suministra se suspendió), es mejor desactivar Thread, borrar las credenciales de la red y volver a comenzar desde el paso Crea la red de Thread.

Para restablecer los FTD, haz lo siguiente:

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

> thread stop
Done
> ifconfig down
Done
> factoryreset
Done

El RCP se puede restablecer de la misma manera a través de ot-ctl:

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

> thread stop
Done
> ifconfig down
Done
> factoryreset
Done

12. Cómo usar la multidifusión

La multidifusión se usa para comunicar información a un grupo de dispositivos a la vez. En una red Thread, las direcciones específicas se reservan para el uso de multidifusión con diferentes grupos de dispositivos, según el alcance.

Dirección IPv6

Alcance

Se envió a

ff02::1

Vínculo local

Todos los FTD y MED

ff02::2

Vínculo local

Todos los FTD y los routers de borde

ff03::1

Malla-local

Todos los FTD y MED

ff03::2

Malla-local

Todos los FTD y los routers de borde

Como no usamos un router de borde en este codelab, enfoquémonos en las dos direcciones multicast FTD y MED.

El alcance Link-Local abarca todas las interfaces de Thread a las que se puede acceder mediante una sola transmisión de radio o un solo “salto”. La topología de red determina qué dispositivos responden a un ping a la dirección multicast ff02::1.

Haz ping a ff02::1 desde el 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

Hay otros dos dispositivos en la red (FTD Joiner y RCP Joiner), pero el Comisionado de FTD solo recibió una respuesta, de la dirección de vínculo local (LLA) del Joiner de FTD. Esto significa que el FTD Joiner es el único dispositivo al que puede llegar el FTD Commissioner con un solo salto.

otcodelab_top02C_02_LL.png

Ahora haz ping a ff02::1 desde 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

¡Dos respuestas! Verificando las direcciones IPv6 de los otros dispositivos, podemos ver que el primero (que termina en 4b1d) es el LLA del comisionado de FTD y que el segundo (que termina en 943b) es el LLA de la Unión RCP.

otcodelab_top02C_02_LL02.png

Esto significa que FTD Joiner está directamente conectado al FTD Commissioner y RCP Joiner, lo que confirma nuestra topología.

Malla-local

El permiso Mesh-Local abarca todas las interfaces de Thread a las que se puede acceder dentro de la misma red de Thread. Veamos las respuestas a un ping a la dirección de multidifusión ff03::1.

Haz ping a ff03::1 desde el 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

Esta vez, el comisionado de FTD recibió dos respuestas, una del localizador de enrutamiento de la unión de FTD (RLOC, que termina en b800) y otra del EID local de la malla (ML-EID, que termina en d55f) del Joiner de RCP. Esto se debe a que el alcance local de malla abarca toda la red de Thread. Sin importar en qué lugar de la red se encuentre un dispositivo, estará suscrito a la dirección ff03::1.

otcodelab_top02C_02_ML.png

Haz ping a ff03::1 desde FTD Joiner para confirmar el mismo comportamiento:

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

Anota el tiempo de respuesta de la unión de RCP en ambas salidas del ping. El RCP Joiner tardó mucho más tiempo en llegar al Comisionado de FTD (68 ms) que en llegar al Comisionado de FTD (23 ms). Eso se debe a que tiene que dar dos saltos para llegar al Comisionado de FTD, en comparación con un salto para el Joiner de FTD.

Es posible que también hayas notado que el ping de multidifusión local de malla respondió con el RLOC solo para los dos FTD, no para el RCP Joiner. Esto se debe a que los FTD son routers dentro de la red, mientras que el RCP es un dispositivo final.

Verifica el estado de la Unión de RCP para confirmar lo siguiente:

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

> state
child

13. Envía mensajes con UDP

Uno de los servicios de aplicaciones que proporciona OpenThread es el protocolo de datagramas de usuario (UDP), que es un protocolo de capa de transporte. Una aplicación compilada en OpenThread podría usar la API de UDP para pasar mensajes entre nodos en una red Thread o a otros dispositivos en una red externa (como Internet, si la red de Thread cuenta con un router de borde).

Los sockets UDP se exponen a través de la CLI de OpenThread. Vamos a usarlo para pasar mensajes entre los dos FTD.

Obtén la dirección del EID de Mesh-Local para el FTD Joiner. Usamos esta dirección porque se puede acceder a ella desde cualquier parte de la red de 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

Inicia el UDP y vincúlalo a un socket para cualquier dirección IPv6:

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

> udp open
Done
> udp bind :: 1212

Cambia al FTD Commissioner, inicia UDP y conéctate al socket que configuraste en el FTD Joiner, mediante su ML-EID:

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

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

La conexión UDP debe estar activa entre los dos nodos. Envía un mensaje del Comisionado de FTD:

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

> udp send hellothere
Done

En el FTD Joiner, se recibió el mensaje UDP.

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

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

14. ¡Felicitaciones!

Creaste una red Thread física.

b915c433e7027cc7.png

Ahora sabes lo siguiente:

  • la diferencia entre los tipos de dispositivos, los roles y los permisos de Thread
  • Cómo administran los estados de los dispositivos Thread dentro de la red
  • cómo pasar mensajes simples entre nodos con UDP

Próximos pasos

A partir de este codelab, realiza los siguientes ejercicios:

  • Vuelve a escribir la placa de unión de FTD como un MTD con el objeto binario ot-cli-mtd y observa que nunca se actualiza a un router ni intenta convertirse en líder.
  • Agrega más dispositivos (prueba con una plataforma diferente) a la red y esboza la topología con el router y las tablas secundarias, junto con pings a las direcciones de multidifusión
  • Usa pyspinel para controlar el NCP
  • Convierte el NCP en un router de borde con el router de borde OpenThread y conecta tu red de Thread a Internet.

Lecturas adicionales

Consulta openthread.io y GitHub para ver una variedad de recursos de OpenThread, incluidos los siguientes:

Referencia: