Crea una red Thread con placas nRF52840 y OpenThread

1. Introducción

26b7f4f6b3ea0700.png

OpenThread, que lanzó 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 los productos Nest esté ampliamente disponible para los desarrolladores y así acelerar el desarrollo de productos para el hogar conectado.

La especificación de Thread define un protocolo de comunicación inalámbrica entre dispositivos confiable, seguro y de bajo consumo basado en IPv6 para aplicaciones domésticas. OpenThread implementa todas las capas de redes 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 Thread, y pasarás mensajes entre nodos.

4806d16a8c137c6d.jpeg

Qué aprenderás

  • Cómo compilar y escribir en memoria flash objetos binarios de la CLI de OpenThread en placas de desarrollo
  • Cómo compilar un RCP que consta de una máquina Linux y una placa de desarrollo
  • Cómo comunicarse con un RCP con el daemon de OpenThread y ot-ctl
  • Cómo administrar manualmente los nodos Thread con GNU Screen y la CLI de OpenThread
  • Puesta en marcha segura de dispositivos en una red Thread
  • Cómo funciona la multidifusión IPv6
  • Cómo pasar mensajes entre nodos Thread con UDP

Requisitos

Hardware:

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

Software:

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

2. Cómo comenzar

Simulación de OpenThread

Antes de comenzar, te recomendamos que realices 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. En este codelab, se usa GNU Screen y se proporciona una descripción general de uso, pero se puede usar cualquier otro software de la terminal.

Máquina Linux

Este Codelab fue diseñado para usar una máquina con Linux basada en i386 o x86 que funcione como host de un dispositivo Thread de coprocesador de radio (RCP) y para 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 nRF52840 de Nordic Semiconductor

En este codelab, se usan tres placas PDK nRF52840.

a6693da3ce213856.png

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

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

Instala las herramientas de línea de comandos de nRF5x

Las herramientas de línea de comandos de nRF5x te permiten escribir en la memoria flash los objetos binarios de OpenThread en las placas nRF52840. Instala la compilación nRF5x-Command-Line-Tools-<OS> adecuada en tu máquina Linux.

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

Instala la cadena de herramientas de GNU para ARM

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

Te recomendamos que coloques 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 del archivo para instalarlo.

Pantalla de instalación (opcional)

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

$ sudo apt-get install screen

3. Cómo clonar repositorios

OpenThread

Clona e instala OpenThread. Los comandos script/bootstrap se aseguran de que la cadena de herramientas esté instalada y 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 está todo listo para compilar y escribir OpenThread en las placas nRF52840.

4. Configura el RCP Joiner

Compilación y escritura en la memoria flash

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

Siempre ejecuta rm -rf build para limpiar el repositorio de 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 de RCP de OpenThread y conviértelo al 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 de la placa nRF52840 y, luego, conéctalo a la máquina Linux. Establece el interruptor de fuente de alimentación de nRF en la placa nRF52840 en VDD. Cuando se conecta correctamente, el LED5 está encendido.

20a3b4b480356447.png

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

$ ls /dev/ttyACM*
/dev/ttyACM0

Anota 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 de 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 de 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 realiza correctamente, 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 tabla como “RCP” para que no confundas los roles de la tabla más adelante.

Cómo conectarse a USB nativo

Dado que la compilación de RCP de OpenThread habilita el uso de ACM CDC USB nativo como transporte serie, debes usar el puerto nRF USB en la placa nRF52840 para comunicarte con el host de RCP (máquina Linux).

Desconecta el extremo micro-USB del cable USB del puerto de depuración de la placa nRF52840 con la actualización y, luego, vuelve a conectarlo al puerto nRF USB micro-USB junto al botón RESET. Establece el interruptor de fuente de alimentación de nRF en USB.

46e7b670d2464842.png

Inicia el daemon de OpenThread

En el diseño de RCP, usa el daemon de OpenThread 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=460800'

Cuando se ejecuta de forma correcta, ot-daemon en 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 esta ventana de la terminal abierta 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 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 Thread que se usan en este codelab son dispositivos Thread completos (FTD) en el diseño estándar de sistema en chip (SoC). En un entorno de producción, se puede usar wpantund, un controlador de interfaz de red de grado de producción, para controlar 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 comisionar dispositivos de forma segura en esa red. El otro dispositivo funciona como un conector que el comisionado puede autenticar en la red Thread.

Compilación y escritura en la memoria flash

Compila el ejemplo de FTD de OpenThread para la plataforma nRF52840, con los roles de comisionado y participante habilitados:

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

Navega al directorio con el binario de la CLI del dispositivo de Thread completo (FTD) de OpenThread 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 de la placa nRF52840 y, luego, enchúfalo a la máquina Linux. Si el RCP aún está conectado a la máquina Linux, esta nueva placa debería aparecer como puerto serie /dev/ttyACM1 (todas las placas nRF52840 usan ttyACM para el identificador de puerto serie).

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

Al igual que antes, anota el número de serie de la placa nRF52840 que se usa para el FTD:

c00d519ebec7e5f0.jpeg

Navega a la ubicación de las herramientas de línea de comandos de 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 tabla como “Comisario”.

Cómo conectarse a USB nativo

Debido a que la compilación de FTD de OpenThread habilita el uso de ACM CDC USB nativo como transporte serie, debes usar el puerto nRF USB en 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 con la actualización y, luego, vuelve a conectarlo al puerto nRF USB micro-USB junto al botón RESET. Establece el interruptor de fuente de alimentación de nRF en USB.

46e7b670d2464842.png

Verifica la compilación

Para verificar que la compilación se realizó correctamente, accede a la CLI de OpenThread con GNU Screen desde una ventana de terminal.

$ screen /dev/ttyACM1

En la ventana nueva, presiona Intro en el teclado varias veces para que aparezca el mensaje > de la CLI de OpenThread. Abre la interfaz IPv6 y busca 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 volver a la terminal de Linux para que se pueda actualizar 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 las pantallas disponibles, usa screen -ls:

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

Configura el FTD Joiner

Repite el proceso anterior para escribir en 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 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 serie /dev/ttyACM2:

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

Etiqueta la tabla 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 conectarte a la existente y crea una ventana nueva dentro de ella (la que usaste para el Comisionado de FTD):

$ screen -r

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

Aparecerá un nuevo mensaje de línea de comandos. Accede a la CLI de OpenThread para el conector FTD:

$ screen /dev/ttyACM2

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

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

Ahora que la CLI de FTD Joiner está en la misma instancia de Screen que el Comisionado de FTD, puedes alternar 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

En el futuro, cambiarás de dispositivo Thread con frecuencia, así que asegúrate de que todos estén activos y sean de fácil acceso. Hasta ahora, hemos estado usando Screen para acceder a los dos FTD, y esta herramienta también permite la pantalla dividida en la misma ventana de la terminal. Úsalo para ver cómo reacciona un nodo a los comandos emitidos en otro.

Idealmente, deberías tener cuatro ventanas disponibles:

  1. servicio / registros de ot-daemon
  2. RCP Joiner a través de ot-ctl
  3. Comisionado de FTD a través de la CLI de OpenThread
  4. Conector de FTD a través de la CLI de OpenThread

Si deseas usar tu propia configuración o herramienta de terminal o puerto serie, puedes omitir el siguiente paso. Configura las ventanas de la terminal para todos los dispositivos de la forma que más te convenga.

Cómo usar la pantalla

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

Todos los comandos de Screen comienzan con Ctrl + a.

Comandos básicos de la pantalla:

Cómo volver a conectarte a la sesión de Screen (desde la línea de comandos)

screen -r

Sal de la sesión de Screen

Ctrl + a → d

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

Ctrl + a → c

Cómo cambiar entre ventanas en la misma sesión de pantalla

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

Cómo finalizar la ventana actual en 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 de screen, usa Ctrl + a. Cada comando debe comenzar con esta combinación de teclas de acceso.

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

$ screen -r

Debes estar en 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 esa ventana nueva a la siguiente
  4. Si es igual que la ventana superior, vuelve a presionar Ctrl + a → n para ver el otro dispositivo FTD.

Ahora ambas son visibles. Cambia entre ellos con Ctrl + a → Tab. Para evitar confusiones, te recomendamos que cambies el nombre de cada ventana con Ctrl + a → A.

Uso avanzado

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

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

Divide y navega entre ventanas con los siguientes comandos:

Crear ventana nueva

Ctrl + a → c

Cómo dividir la ventana verticalmente

Ctrl + a →

Cómo dividir la ventana horizontalmente

Ctrl + a → S

Ir a la siguiente ventana que se muestra

Ctrl + a → Tab

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

Ctrl + a → n o p

Cambia el nombre de la ventana actual

Ctrl + a → A

Sal de Screen en cualquier momento con Ctrl + a → d y vuelve a conectarte 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 Thread

Ahora que tienes configuradas todas las ventanas y pantallas de la terminal, vamos a crear nuestra red Thread. En el Comisionado de FTD, crea un nuevo conjunto de datos operacional y confírmalo como el activo. El conjunto de datos operativos 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

Anota la clave de red 1234c0de7ab51234c0de7ab51234c0de que se usará más adelante.

Confirma este conjunto de datos como el activo:

> dataset commit active
Done

Muestra la interfaz IPv6:

> ifconfig up
Done

Inicia la operación del protocolo Thread:

> thread start
Done

Después de un momento, verifica el estado del dispositivo. Debe ser el líder. También obtén el RLOC16 para futuras consultas.

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

La red "codelab" ahora es visible cuando se escanea desde otros dispositivos Thread.

Desde ot-ctl en el vinculador de RCP:

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

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

Desde la CLI de OpenThread en el conjuntor de FTD:

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

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

Si la red "codelab" no aparece en la lista, vuelve a escanear.

8. Agrega el conector de RCP

La comisión de Thread no está activa en la red, lo que significa que tendremos que agregar el conector RCP a la red de Thread que acabamos de crear mediante un proceso de comisión fuera de banda.

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

## FTD Commissioner ##

> dataset networkkey
1234c0de7ab51234c0de7ab51234c0de
Done

A continuación, en el vinculador de RCP, establece la clave de red del conjunto de datos activo en la clave de red del comisionado de FTD:

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

> dataset networkkey 1234c0de7ab51234c0de7ab51234c0de
Done
> dataset commit active
Done

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

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

> dataset
Network Key: 1234c0de7ab51234c0de7ab51234c0de

Abre Thread para que el RCP Joiner se una a la red de "codelab". Espera unos segundos y verifica el estado, el 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

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

En FTD Commissioner, verifica el router y las tablas secundarias para confirmar que ambos dispositivos formen parte de la misma red. Usa el RLOC16 para identificar el conector 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

Realiza un ping a la dirección de malla local del RCP Joiner (la dirección de malla local que se obtiene del resultado de ipaddr del 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 avances en el resto del codelab, te mostraremos un nuevo diagrama de topología de Thread cada vez que cambie el estado de la red. Los roles de los nodos se indican de la siguiente manera:

b75a527be4563215.png

Los routers siempre son pentágonos y los dispositivos finales siempre son 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 el rol y el estado actuales de cada nodo en ese momento.

9. Cómo encargar el Joiner de FTD

Ahora, agreguemos el tercer dispositivo Thread a la red del "codelab". Esta vez, usaremos el proceso de comisión en banda más seguro y solo permitiremos que se una el FTD Joiner.

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

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

> eui64
2f57d222545271f1
Done

En el Comisionado de FTD, inicia el comisionado y especifica el eui64 del dispositivo que se puede unir, junto con la credencial del participante, por ejemplo, J01NME. La credencial de unión es una cadena específica del dispositivo de todos los caracteres alfanuméricos en mayúsculas (del 0 al 9 y de la A a la 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 al Joiner de FTD. Inicia el rol de persona que se une con la credencial de persona que se une que acabas de configurar en el Comisionado de FTD:

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

> ifconfig up
Done
> joiner start J01NME
Done

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

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

>
Join success

Abre Thread para que el conector de FTD se una a la red del "codelab" y verifica inmediatamente el estado y el RLOC16:

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

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

Comprueba las direcciones IPv6 del dispositivo. Observa que no hay ALOC. Esto se debe a que este dispositivo no es el líder ni tiene un rol específico de Anycast que requiera 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 Comisionado de FTD y revisa el router y las tablas secundarias para confirmar que haya tres dispositivos en la red del "codelab":

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

Según el RLOC16, el conector 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 Thread completo (FTD) llamado dispositivo final apto para router (REED). Esto significa que pueden funcionar como router o dispositivo final, y pueden ascender 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 promociona automáticamente a router.

Si tenías dos subredes en tu red Thread después de agregar el conector FTD, espera al menos dos minutos y, luego, 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 FTD (MAC extendido = e6cdd2d93249a243) se promocionó a un router. Ten en cuenta que el RLOC16 es diferente (b800 en lugar de 0c02). Esto se debe a que el RLOC16 se basa en el ID del router y el ID secundario de un dispositivo. Cuando realiza la transición 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 estado nuevo y el RLOC16 en el vinculador de FTD:

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

> state
router
Done
> rloc16
b800
Done

Cómo cambiar a una versión inferior del conector de FTD

Para probar este comportamiento, cambia manualmente la versión del FTD Joiner de un router a un dispositivo 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 estar en ambos mientras se produce 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 cambiar a un router con un RLOC de b800.

otcodelab_top01C.png

Cómo quitar al líder

El líder se elige 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 dos minutos, el FTD Joiner se convierte en el nuevo líder de Thread. Verifica el estado y las direcciones IPv6 del FTD Joiner 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 RLOC16 nuevo. Este es el conector RCP, como lo indican su ID y su MAC extendido. Para mantener la red Thread unida, cambió los routers superiores, del comisionado de FTD al conector de FTD. Esto genera un nuevo RLOC16 para el conector RCP (porque cambió su ID de router, 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 el vinculador de RCP se conecte al vinculador de FTD como elemento secundario. Verifica el estado y el RLOC16 para confirmar lo siguiente:

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

> state
child
> rloc16
b801

Vuelve a conectar el comisionado de FTD

Una red Thread con dos nodos no es muy divertida. Volvamos a conectar el comisionado de FTD.

En el Comisionado de FTD, reinicia Thread:

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

> ifconfig up
Done
> thread start
Done

En un plazo de dos minutos, se vuelve a conectar automáticamente a la red del "codelab" como dispositivo final y, luego, se promociona a un router.

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

> state
router
Done

Verifica 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 vuelve a constar de tres nodos.

11. Solución de problemas

La administración de una red Thread con varios dispositivos en diferentes terminales o ventanas de la pantalla puede ser complicada. Sigue estas sugerencias para "restablecer" el estado de la red o tu espacio de trabajo si tienes problemas.

Pantalla

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

Nodos de Thread

Si la topología de la red 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 Linux que los alimenta se suspendió), lo mejor es cerrar Thread, borrar las credenciales de red y comenzar de nuevo desde el paso Crea la red 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 multicast

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

Dirección IPv6

Alcance

Se entregó en

ff02::1

Vinculado a la red local

Todos los FTD y MED

ff02::2

Vinculado a la red local

Todos los FTD y routers de borde

ff03::1

Mesh-Local

Todos los FTD y MED

ff03::2

Mesh-Local

Todos los FTD y routers de borde

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

El alcance de vínculo local comprende todas las interfaces de Thread a las que se puede acceder con 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 Comisionado de FTD:

## 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 local de vínculo (LLA) del FTD Joiner. Esto significa que el conector de FTD es el único dispositivo al que el comisionado de FTD puede llegar con un solo salto.

otcodelab_top02C_02_LL.png

Ahora, haz ping a ff02::1 desde el Unión de 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

Dos respuestas Si revisamos las direcciones IPv6 de los otros dispositivos, podemos ver que la primera (que termina en 4b1d) es la LLA del comisionado de FTD y la segunda (que termina en 943b) es la LLA del conectador de RCP.

otcodelab_top02C_02_LL02.png

Esto significa que el conector de FTD está conectado directamente al comisionado de FTD y al conector de RCP, lo que confirma nuestra topología.

Mesh-Local

El alcance de malla local comprende 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 multicast ff03::1.

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

Esta vez, el comisionado de FTD recibió dos respuestas, una del localizador de enrutamiento (RLOC, que termina en b800) del conector de FTD y una del EID de malla local (ML-EID, que termina en d55f) del conector de RCP. Esto se debe a que el alcance de malla local abarca toda la red de Thread. Sin importar dónde se encuentre el dispositivo en la red, se suscribirá a la dirección ff03::1.

otcodelab_top02C_02_ML.png

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

Ten en cuenta el tiempo de respuesta del RCP Joiner en ambos resultados de ping. El RCP Joiner tardó mucho más en llegar al comisionado de FTD (68 ms) que en llegar al FTD Joiner (23 ms). Esto se debe a que debe realizar dos saltos para llegar al comisionado de FTD, en comparación con un salto para el conector de FTD.

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

Verifica el estado del vinculador de RCP para confirmar:

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

> state
child

13. Cómo enviar mensajes con UDP

Uno de los servicios de aplicación que proporciona OpenThread es el protocolo de datagramas de usuario (UDP), 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 Thread tiene un router de borde).

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

Obtén la dirección EID de malla local para el vinculador de FTD. Usamos esta dirección porque se puede acceder a ella desde cualquier lugar de la red 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 UDP y vincúlalo a un socket para cualquier dirección IPv6:

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

> udp open
Done
> udp bind :: 1212

Cambia al Comisionado de FTD, inicia UDP y conéctate al socket que configuraste en el FTD Joiner con 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 la 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 física de Thread!

b915c433e7027cc7.png

Ahora sabes lo siguiente:

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

Próximos pasos

A partir de este codelab, prueba los siguientes ejercicios:

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

Lecturas adicionales

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

Referencia: