1. Introducción
OpenThread, lanzado por Google, es una implementación de código abierto del protocolo de redes Thread®. Google Nest lanzó OpenThread para que los desarrolladores puedan acceder a la tecnología que se usa en los productos Nest y, así, acelerar el desarrollo de productos para la casa conectada.
La especificación de Thread define un protocolo de comunicación inalámbrico confiable, 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.
Qué aprenderás
- Compilación y escritura de archivos 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
- Comunicación con un RCP a través del daemon de OpenThread y
ot-ctl
- Administra nodos de Thread de forma manual 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 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 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 se diseñó para usar una máquina Linux basada en i386 o x86 como host para un dispositivo de subprocesamiento del 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 Nordic Semiconductor nRF52840
En este codelab, se usan tres placas PDK nRF52840.
Instala SEGGER J-Link
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 los archivos binarios de OpenThread en las placas nRF52840. Instala la compilación adecuada de nRF5x-Command-Line-Tools-<OS> 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 para 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 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 serie que desees.
$ sudo apt-get install screen
3. Clonar 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
Ahora puedes 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 OpenThread nRF52840 con la funcionalidad de Joiner y USB nativa. Un dispositivo usa el rol de Joiner para autenticarse y habilitarse de forma segura en una red de Thread. El USB nativo permite usar USB CDC ACM como transporte serial entre el nRF52840 y el host.
Siempre limpia el repo de compilaciones anteriores primero ejecutando rm -rf build
.
$ 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 del 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 que se encuentra junto al pin de alimentación externa en la placa nRF52840 y, luego, conéctalo a la máquina Linux. Coloca el interruptor de fuente de alimentación nRF de la placa nRF52840 en VDD. Cuando se conecta correctamente, LED5 se enciende.
Si esta es la primera placa conectada a la máquina Linux, aparecerá como el puerto en serie /dev/ttyACM0
(todas las placas nRF52840 usan ttyACM
para el identificador del 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:
Navega a la ubicación de las herramientas de línea de comandos de nRFx y graba el archivo .hex del 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 escritura en la memoria 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 la operación 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 el tablero como "RCP" para que no confundas los roles del tablero más adelante.
Cómo conectarse a USB nativo
Dado que la compilación de RCP de OpenThread permite el uso de CDC ACM USB nativo como transporte serial, 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 programada y, luego, vuelve a conectarlo al puerto micro-USB nRF USB junto al botón RESET. Coloca el interruptor de la fuente de alimentación nRF en USB.
Cómo iniciar el daemon de OpenThread
En el diseño del 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 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 de 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 de RCP) que iniciaste con ot-daemon
:
> state disabled Done
5. Configura las 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). Un dispositivo funciona como comisionado para autenticar y comisionar dispositivos de forma segura en esa red. El otro dispositivo funciona como un dispositivo de unión que el comisionado puede autenticar en la red de Thread.
Compilación y escritura en la memoria flash
Compila el ejemplo de FTD de OpenThread para la plataforma nRF52840, con los roles de Commissioner y Joiner habilitados:
$ cd ~/src/ot-nrf528xx $ rm -rf build $ script/build nrf52840 USB_trans -DOT_JOINER=ON -DOT_COMMISSIONER=ON
Navega al directorio con el ejecutable de la CLI del dispositivo Full Thread (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 que se encuentra junto al pin de alimentación externa en 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 el puerto serie /dev/ttyACM1
(todas las placas nRF52840 usan ttyACM
para el identificador del puerto serie).
$ ls /dev/ttyACM* /dev/ttyACM0 /dev/ttyACM1
Como antes, anota el número de serie de la placa nRF52840 que se usa para la FTD:
Navega a la ubicación de las herramientas de línea de comandos de nRFx y graba el archivo .hex de 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 el tablero como "Comisionado".
Cómo conectarse a USB nativo
Dado que la compilación de FTD de OpenThread permite el uso de CDC ACM USB nativo como transporte serial, 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 programada y, luego, vuelve a conectarlo al puerto micro-USB nRF USB junto al botón RESET. Coloca el interruptor de la fuente de alimentación nRF en USB.
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 la tecla Retorno del teclado varias veces para que aparezca el mensaje >
de la CLI de OpenThread. Activa 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 del comisionado de FTD y volver a la terminal de Linux para que se pueda escribir el siguiente panel en la memoria flash. 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 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 configura el interruptor de fuente de alimentación de nRF en VDD.
Si los otros dos nodos están conectados a la máquina Linux cuando se conecta esta tercera placa, debería aparecer como el puerto serie /dev/ttyACM2
:
$ ls /dev/ttyACM* /dev/ttyACM0 /dev/ttyACM1 /dev/ttyACM2
Etiqueta la placa como "Joiner".
Cuando realices la verificación con Screen, en lugar de crear una instancia nueva de Screen desde la línea de comandos, vuelve a adjuntar 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 símbolo del sistema. Accede a la CLI de OpenThread para el dispositivo FTD Joiner:
$ screen /dev/ttyACM2
En esta nueva ventana, presiona la tecla Retorno del teclado varias veces para que aparezca el mensaje >
de la CLI de OpenThread. Activa 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 está en la misma instancia de Screen que la CLI de FTD Commissioner, puedes cambiar entre ellas con Ctrl+A → n
.
Usa Ctrl + A →
d
en cualquier momento para salir de Screen.
6. Configuración de la ventana de terminal
En el futuro, cambiarás de dispositivos Thread con frecuencia, así que asegúrate de que todos estén activos y sean de fácil acceso. Hasta ahora, usamos 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 que se emiten en otro.
Idealmente, deberías tener cuatro ventanas disponibles:
- Servicio o registros de
ot-daemon
- RCP Joiner a través de
ot-ctl
- Comisionado de FTD a través de la CLI de OpenThread
- FTD Joiner a través de la CLI de OpenThread
Si deseas usar tu propia configuración o herramienta de terminal o puerto serial, puedes omitir el siguiente paso. Configura las ventanas de la terminal para todos los dispositivos de la manera que te resulte más conveniente.
Uso de la pantalla
Para facilitar el uso, inicia solo una sesión de Screen. Ya deberías tener una desde que configuraste ambos FTD.
Todos los comandos dentro de Screen comienzan con Ctrl + A.
Comandos básicos de la pantalla:
Cómo volver a adjuntar a la sesión de Screen (desde la línea de comandos) |
|
Cómo salir de la sesión de Screen | Ctrl + A → |
Crea una ventana nueva dentro de la sesión de Screen. | Ctrl + A → |
Cómo cambiar entre ventanas en la misma sesión de pantalla | Ctrl + A → |
Cerrar la ventana actual en la sesión de Screen | Ctrl + A → |
Pantalla dividida
Con Screen, puedes dividir la terminal en varias ventanas:
Se accede a los comandos en screen
con Ctrl+a. Todos los comandos deben 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 Screen. 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 Screen:
- Ctrl + A →
S
para dividir la ventana horizontalmente - Ctrl + A →
Tab
para mover el cursor a la nueva ventana en blanco - Ctrl+A →
n
para cambiar esa ventana nueva a la siguiente - Si es la misma que la ventana superior, presiona Ctrl+A →
n
de nuevo para ver el otro dispositivo FTD.
Ahora ambas son visibles. Cambia entre ellas con Ctrl + A → Tab
. Se recomienda que cambies el título de 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 RCP Joiner ot-ctl
, esos servicios deben iniciarse dentro de esta misma instancia de Screen. 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 una ventana nueva | Ctrl + A → |
Dividir la ventana verticalmente | Ctrl+A → |
Dividir la ventana horizontalmente | Ctrl + A → |
Ir a la siguiente ventana que se muestra | Ctrl + A → |
Cambiar la ventana mostrada hacia adelante o hacia atrás | Ctrl + A → |
Cambiar el nombre de la ventana actual | Ctrl + A → |
Puedes salir de Screen en cualquier momento con Ctrl + a → d
y volver 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 Thread
Ahora que tienes configuradas todas las ventanas y pantallas de la terminal, vamos a crear nuestra red de Thread. En FTD Commissioner, crea un nuevo conjunto de datos operativos y confirma que sea 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 se usará más adelante.
Confirma este conjunto de datos como el activo:
> dataset commit active Done
Activa la interfaz IPv6:
> ifconfig up Done
Operación del protocolo Start 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 referencias.
## 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 analiza desde otros dispositivos Thread.
En ot-ctl
, en el RCP Joiner, haz lo siguiente:
## RCP Joiner ## ---------------- > scan | PAN | MAC Address | Ch | dBm | LQI | +------+------------------+----+-----+-----+ | c0de | 1ed687a9cb9d4b1d | 11 | -36 | 232 |
Desde la CLI de OpenThread en el FTD Joiner, haz lo siguiente:
## 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 buscarla.
8. Agrega el RCP Joiner
La puesta en servicio de Thread no está activa en la red, lo que significa que tendremos que agregar el dispositivo de unión de RCP a la red de Thread que acabamos de crear con un proceso de puesta en servicio fuera de banda.
En FTD Commissioner, anotamos la clave de red, por ejemplo, 1234c0de7ab51234c0de7ab51234c0de
. Si necesitas volver a buscar la clave de red, ejecuta el siguiente comando en el FTD Commissioner:
## FTD Commissioner ## > dataset networkkey 1234c0de7ab51234c0de7ab51234c0de Done
A continuación, en el RCP Joiner, 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
Inicia Thread para que el dispositivo de unión de RCP se una a la red "codelab". Espera unos segundos, 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 de malla (fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f
aquí), ya que la usarás más adelante.
De vuelta en el FTD Commissioner, verifica las tablas del router y del dispositivo secundario para confirmar que ambos dispositivos forman parte de la misma red. Usa el RLOC16 para identificar al RCP Joiner.
## 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 local de la malla del RCP Joiner (la dirección local de la malla 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 de Thread que consta de dos nodos, como se ilustra en este diagrama de topología:
Diagramas de topología
A medida que avances en 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 los nodos se indican de la siguiente manera:
Los routers siempre son pentágonos y los dispositivos finales siempre son círculos. Los números de cada nodo representan el ID del router o el ID secundario que se muestran en el resultado de la CLI, según el rol y el estado actuales de cada nodo en ese momento.
9. Cómo poner en funcionamiento el FTD Joiner
Ahora, agreguemos el tercer dispositivo Thread a la red "codelab". Esta vez, usaremos el proceso de puesta en servicio integrado más seguro y solo permitiremos que se una el dispositivo 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 FTD Commissioner, inicia el comisionado y especifica el eui64
del dispositivo que puede unirse, junto con la credencial de Joiner, por ejemplo, J01NME
. La credencial de Joiner es una cadena específica del dispositivo que contiene todos los caracteres alfanuméricos en mayúscula (del 0 al 9 y de la A a la Y, excepto 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 FTD Joiner. Inicia el rol de participante con la credencial de participante 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
Inicia Thread para que el dispositivo FTD Joiner se una a la red "codelab" y verifica de inmediato 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 una 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 inmediatamente al FTD Commissioner y verifica el router y las tablas secundarias para confirmar que existen tres dispositivos en la red "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 dispositivo FTD Joiner se conectó a la red como un dispositivo final (secundario). Esta es nuestra topología actualizada:
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 promocionarse de dispositivo final a 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 hasta dos minutos, se promueve automáticamente a router.
Si tenías dos dispositivos secundarios en tu red Thread después de agregar el dispositivo de unión FTD, espera al menos dos minutos y, luego, vuelve a verificar las tablas del router y del dispositivo secundario en el FTD Commissioner:
## FTD Commissioner ## ---------------------- > router table | ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC | +----+--------+----------+-----------+-------+--------+-----+------------------+ | 3 | 0x0c00 | 3 | 0 | 0 | 0 | 50 | 1ed687a9cb9d4b1d | | 46 | 0xb800 | 63 | 0 | 3 | 3 | 1 | e6cdd2d93249a243 | > child table | ID | RLOC16 | Timeout | Age | LQ In | C_VN |R|S|D|N| Extended MAC | +-----+--------+------------+------------+-------+------+-+-+-+-+------------------+ | 1 | 0x0c01 | 240 | 61 | 3 | 89 |1|1|1|1| 1ae529b3a638943b | Done
El FTD Joiner (MAC extendida = e6cdd2d93249a243
) se promovió a 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 pasa de dispositivo final a router, cambian sus valores de ID de router y de ID de hijo, y también el RLOC16.
Confirma el nuevo estado y el RLOC16 en el FTD Joiner:
## FTD Joiner ## ---------------- > state router Done > rloc16 b800 Done
Cómo cambiar a una versión anterior del FTD Joiner
Puedes probar este comportamiento degradando manualmente el 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
De vuelta en FTD Commissioner, el FTD Joiner ahora debería aparecer en la tabla secundaria (ID = 3). Incluso puede estar en ambas 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
.
Cómo quitar al líder
El líder se elige automáticamente entre todos los routers de subprocesos. 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 de Thread:
## FTD Commissioner ## ---------------------- > thread stop Done > ifconfig down Done
En un plazo de dos minutos, el FTD Joiner se convierte en el nuevo líder del subproceso. Verifica el estado y las direcciones IPv6 del FTD Joiner para confirmar 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
Verifica la tabla secundaria. Observa que hay una nueva RLOC16. Este es el dispositivo de unión RCP, como lo indican su ID y su MAC extendida. Para mantener unida la red de Thread, cambió de routers principales, del comisionado FTD al dispositivo de unión FTD. Esto genera 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 el RCP Joiner se adjunte al FTD Joiner como elemento secundario. Verifica el estado y el RLOC16 para confirmar lo siguiente:
## RCP Joiner ## -------------- > state child > rloc16 b801
Cómo volver a conectar 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 un plazo de dos minutos, se vuelve a conectar automáticamente a la red "codelab" como dispositivo final y, luego, se promueve a router.
## FTD Commissioner ## ---------------------- > state router Done
Verifica las tablas del router y del dispositivo secundario en el FTD Joiner para confirmar 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
Nuestra red de Thread consta de tres nodos nuevamente.
11. Solución de problemas
Administrar una red de Thread con varios dispositivos en diferentes ventanas de terminal o de pantalla puede ser complicado. Usa estas sugerencias para "restablecer" el estado de la red o de tu espacio de trabajo si tienes problemas.
Pantalla
Si alguna vez te pierdes en la configuración (demasiadas ventanas de Screen o Screens dentro de Screen), sigue cerrando ventanas de Screen con Ctrl+a → k hasta que no quede ninguna y screen -ls
en la línea de comandos genere No Sockets found
. Luego, vuelve a crear ventanas de Screen para cada dispositivo. Los estados del dispositivo se conservan incluso cuando se cierra la pantalla.
Nodos de subprocesos
Si la topología de la red de Thread no es la que se describe en este codelab o si los nodos se desconectan por algún motivo (quizás porque la máquina Linux que los alimenta entró en modo de suspensión), lo mejor es 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. Uso de la transmisión por multidifusión
La multidifusión se usa para comunicar información a un grupo de dispositivos a la vez. En una red de Thread, se reservan direcciones específicas para el uso de multidifusión con diferentes grupos de dispositivos, según el alcance.
Dirección IPv6 | Alcance | Se entregó a |
| Vínculo local | Todos los FTD y los MED |
| Vínculo local | Todos los FTD y los routers de borde |
| Mesh-Local | Todos los FTD y los MED |
| Mesh-Local | Todos los FTD y los routers de borde |
Como no usamos un Border Router en este codelab, enfoquémonos en las dos direcciones de multidifusión de FTD y MED.
Vínculo local
El alcance de vínculo local abarca 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 de multidifusión ff02::1
.
Ping de ff02::1
del comisionado de la 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 FTD Commissioner solo recibió una respuesta, de la dirección local de vínculo (LLA) del FTD Joiner. Esto significa que el FTD Joiner es el único dispositivo al que el FTD Commissioner puede llegar con un solo salto.
Ahora haz ping a ff02::1
desde el 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! Al verificar 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 dispositivo de unión de RCP.
Esto significa que el FTD Joiner está conectado directamente al FTD Commissioner y al RCP Joiner, lo que confirma nuestra topología.
Mesh-Local
El alcance local de la malla 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
.
Ping de ff03::1
del comisionado de la 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
En esta ocasión, el comisionado de FTD recibió dos respuestas: una del localizador de ruta (RLOC) del dispositivo de unión de FTD (que termina en b800
) y otra del EID local de malla (ML-EID) del dispositivo de unión de RCP (que termina en d55f
), ya que el alcance local de malla abarca toda la red de Thread. Sin importar en qué parte de la red se encuentre un dispositivo, se suscribirá a la dirección ff03::1
.
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
Observa el tiempo de respuesta del RCP Joiner en los dos resultados de ping. El RCP Joiner tardó mucho más en llegar al FTD Commissioner (68 ms) que en llegar al FTD Joiner (23 ms). Esto se debe a que debe dar dos saltos para llegar al comisionado de FTD, en comparación con un salto para el participante de FTD.
También es posible que 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 RCP Joiner para confirmar:
## RCP Joiner ## ---------------- > state child
13. Envía 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 incluye un Border Router).
Los sockets UDP se exponen a través de la CLI de OpenThread. Lo usaremos para pasar mensajes entre los dos FTD.
Obtén la dirección EID local de malla para el FTD Joiner. Usamos esta dirección porque se puede acceder a ella desde cualquier lugar dentro 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 UDP y lo vincula a un socket para cualquier dirección IPv6:
## FTD Joiner ## ---------------- > udp open Done > udp bind :: 1212
Cambia a FTD Commissioner, inicia UDP y conéctate al socket que configuraste en 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 de Thread física!
Ahora ya sabes lo siguiente:
- la diferencia entre los tipos, los roles y los 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 el firmware de la placa FTD Joiner como MTD con el 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 tablas de routers y dispositivos secundarios, junto con pings a las direcciones de multidifusión.
- Usa pyspinel para controlar el NCP
- Convierte el NCP en un router de borde con OpenThread Border Router y conecta tu red de Thread a Internet.
Lecturas adicionales
Consulta openthread.io y GitHub para obtener una variedad de recursos de OpenThread, incluidos los siguientes:
- Plataformas compatibles: Descubre todas las plataformas que admiten OpenThread.
- Cómo compilar OpenThread: Más detalles para compilar y configurar OpenThread
- Thread Primer: Abarca todos los conceptos de Thread que se incluyen en este codelab.
Referencia: