1. Introducción
¿Qué es un router de borde Thread?
Thread es un protocolo de red en malla inalámbrica de bajo consumo basado en IP que permite comunicaciones seguras entre dispositivos y entre dispositivos. Las redes de Thread pueden adaptarse a los cambios de topología para evitar puntos únicos de fallo.
Un router de borde de Thread conecta una red de Thread a otras redes basadas en IP, como Wi-Fi o Ethernet. Una red Thread requiere un router de borde para conectarse a otras redes. Un router de borde de Thread admite mínimamente las siguientes funciones:
- Conectividad IP bidireccional entre redes Thread y Wi-Fi/Ethernet.
- Descubrimiento de servicios bidireccional a través de mDNS (en vínculo Wi-Fi/Ethernet) y SRP (en la red Thread).
- Subproceso sobre la infraestructura que combina particiones de Thread en vínculos basados en IP
- Comisión de Thread externa (por ejemplo, un teléfono celular) para autenticar y unir un dispositivo Thread a una red de Thread.
El router de borde de OpenThread (OTBR) que lanzó Google es una implementación de código abierto del router de borde de Thread.
Qué compilarás
En este codelab, configurarás un router de borde de Thread y conectarás tu teléfono celular a un dispositivo final de Thread a través de él.
Qué aprenderás
- Cómo configurar OTBR
- Cómo formar una red Thread con OTBR
- Cómo compilar un dispositivo de la CLI de OpenThread con la función SRP
- Cómo registrar un servicio en SRP
- Cómo descubrir un dispositivo final de Thread y comunicarse con él
Requisitos
- Un dispositivo Raspberry Pi 3/4 y una tarjeta SD con al menos 8 GB de capacidad.
- 2 placas de desarrollo de Nordic Semiconductor nRF52840.
- Un PA de Wi-Fi sin IPv6 Router Advertising Guard habilitado en el router.
- Un teléfono con iOS 14 (como mínimo) o Android 8.1 (como mínimo).
2. Configurar OTBR
Configurar Raspberry Pi
Configurar un dispositivo Raspberry Pi nuevo con la herramienta rpi-imager
es sencillo. Para ello, sigue las instrucciones de raspberrypi.org (en lugar de usar la versión más reciente del SO Raspberry Pi en la herramienta, descarga 2021-05-07-raspios-buster-armhf-lite). Para completar los pasos para teléfonos celulares de este codelab, debes conectar la placa Raspberry Pi a un punto de acceso de Wi-Fi. Sigue esta guía para configurar la conectividad inalámbrica. Es conveniente acceder a Raspberry Pi con SSH. Obtén instrucciones aquí.
Obtener código OTBR
Accede a Raspberry Pi y clona ot-br-posix
desde GitHub:
$ git clone https://github.com/openthread/ot-br-posix.git --depth 1
Compila e instala OTBR
OTBR tiene dos secuencias de comandos que inician y configuran el router de borde de Thread:
$ cd ot-br-posix $ ./script/bootstrap $ INFRA_IF_NAME=wlan0 ./script/setup
OTBR funciona tanto en una interfaz de Thread como en una interfaz de red de infraestructura (p.ej., Wi-Fi/Ethernet), que se especifica con INFRA_IF_NAME
. OTBR crea la interfaz de Thread y recibe el nombre wpan0
de forma predeterminada. La interfaz de infraestructura tiene un valor predeterminado de wlan0
si INFRA_IF_NAME
no se especifica de forma explícita. Si la placa Raspberry Pi está conectada a través de un cable Ethernet, especifica el nombre de la interfaz Ethernet (p.ej., eth0
):
$ INFRA_IF_NAME=eth0 ./script/setup
Comprueba si OTBR se instaló correctamente:
$ sudo service otbr-agent status ● otbr-agent.service - Border Router Agent Loaded: loaded (/lib/systemd/system/otbr-agent.service; enabled; vendor preset: enabled) Active: activating (auto-restart) (Result: exit-code) since Mon 2021-03-01 05:43:38 GMT; 2s ago Process: 2444 ExecStart=/usr/sbin/otbr-agent $OTBR_AGENT_OPTS (code=exited, status=2) Main PID: 2444 (code=exited, status=2)
Se espera que el servicio otbr-agent
no esté activo, ya que requiere un chip RCP
para ejecutarse.
Reinicia la Raspberry Pi para que se apliquen los cambios.
Compila e instala el firmware RCP
OTBR admite un chip de radio 15.4 en modo Radio Coprocesador (RCP). En este modo, la pila de OpenThread se ejecuta en el lado del host y transmite o recibe fotogramas a través del transceptor IEEE802.15.4.
Sigue el paso 4 del codelab Cómo compilar una red Thread con placas nRF52840 y OpenThread para compilar y escribir en la memoria flash un dispositivo RCP nRF52840:
$ script/build nrf52840 USB_trans
Inicia la OTBR y verifica el estado
Conecta la placa nRF52840 a la placa Raspberry Pi e inicia el servicio otbr-agent
:
$ sudo service otbr-agent restart
Verifica que el servicio otbr-agent
esté activo:
$ sudo service otbr-agent status ● otbr-agent.service - Border Router Agent Loaded: loaded (/lib/systemd/system/otbr-agent.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2021-03-01 05:46:26 GMT; 2s ago Main PID: 2997 (otbr-agent) Tasks: 1 (limit: 4915) CGroup: /system.slice/otbr-agent.service └─2997 /usr/sbin/otbr-agent -I wpan0 -B wlan0 spinel+hdlc+uart:///dev/ttyACM0 Mar 01 05:46:26 raspberrypi otbr-agent[2997]: Stop publishing service Mar 01 05:46:26 raspberrypi otbr-agent[2997]: [adproxy] Stopped Mar 01 05:46:26 raspberrypi otbr-agent[2997]: PSKc is not initialized Mar 01 05:46:26 raspberrypi otbr-agent[2997]: Check if PSKc is initialized: OK Mar 01 05:46:26 raspberrypi otbr-agent[2997]: Initialize OpenThread Border Router Agent: OK Mar 01 05:46:26 raspberrypi otbr-agent[2997]: Border router agent started. Mar 01 05:46:26 raspberrypi otbr-agent[2997]: [INFO]-CORE----: Notifier: StateChanged (0x00038200) [NetData PanId NetName ExtPanId] Mar 01 05:46:26 raspberrypi otbr-agent[2997]: [INFO]-PLAT----: Host netif is down
3. Cómo formar una red Thread
Hay un comando ot-ctl
que se puede usar para controlar el servicio otbr-agent
. ot-ctl
acepta todos los comandos de la CLI de OpenThread. Consulta la Guía de la CLI de OpenThread para obtener más información.
Crea una red Thread con OTBR:
$ sudo ot-ctl dataset init new Done $ sudo ot-ctl dataset commit active Done $ sudo ot-ctl ifconfig up Done $ sudo ot-ctl thread start Done
Espera unos segundos, deberíamos poder ver que OTBR actúa como un leader
de subproceso y hay un prefijo off-mesh-routable
(OMR) en los datos de red de Thread:
$ sudo ot-ctl state leader Done $ sudo ot-ctl netdata show Prefixes: Prefixes: fd76:a5d1:fcb0:1707::/64 paos med 4000 Routes: fd49:7770:7fc5:0::/64 s med 4000 Services: 44970 5d c000 s 4000 44970 01 9a04b000000e10 s 4000 Done $ sudo ot-ctl ipaddr fda8:5ce9:df1e:6620:0:ff:fe00:fc11 fda8:5ce9:df1e:6620:0:0:0:fc38 fda8:5ce9:df1e:6620:0:ff:fe00:fc10 fd76:a5d1:fcb0:1707:f3c7:d88c:efd1:24a9 fda8:5ce9:df1e:6620:0:ff:fe00:fc00 fda8:5ce9:df1e:6620:0:ff:fe00:4000 fda8:5ce9:df1e:6620:3593:acfc:10db:1a8d fe80:0:0:0:a6:301c:3e9f:2f5b Done
4. Configurar dispositivo final del cliente de SRP
Compila e instala en la memoria flash de la CLI de OT
Sigue el paso 5 del codelab Cómo compilar una red Thread con placas nRF52840 y OpenThread para compilar y escribir en la memoria flash un dispositivo final de la CLI de nRF52840.
Pero, en lugar de tener habilitados OT_COMMISSIONER
y OT_JOINER
, el nodo de la CLI requiere las funciones OT_SRP_CLIENT
y OT_ECDSA
.
Por lo tanto, la invocación de compilación completa debería verse de la siguiente manera:
$ script/build nrf52840 USB_trans -DOT_SRP_CLIENT=ON -DOT_ECDSA=ON
Únete a la red OTBR
Para unir la red de Thread que creó el servicio otbr-agent
, necesitamos obtener el conjunto de datos operativo activo del dispositivo OTBR. Regresemos a la línea de comandos de otbr-agent
y obtengamos el conjunto de datos activo:
$ sudo ot-ctl dataset active -x 0e080000000000010000000300001235060004001fffe002083d3818dc1c8db63f0708fda85ce9df1e662005101d81689e4c0a32f3b4aa112994d29692030f4f70656e5468726561642d35326532010252e204103f23f6b8875d4b05541eeb4f9718d2f40c0302a0ff Done
Regresa a la sesión de la pantalla del nodo de cliente de SRP y configura el conjunto de datos activo:
> dataset set active 0e080000000000010000000300001235060004001fffe002083d3818dc1c8db63f0708fda85ce9df1e662005101d81689e4c0a32f3b4aa112994d29692030f4f70656e5468726561642d35326532010252e204103f23f6b8875d4b05541eeb4f9718d2f40c0302a0ff Done
Luego, inicia la interfaz de Thread:
> ifconfig up Done > thread start Done
Espera unos segundos y verifica si te uniste a la red Thread se realizó correctamente:
> state child Done > netdata show Prefixes: fd76:a5d1:fcb0:1707::/64 paos med 4000 Routes: fd49:7770:7fc5:0::/64 s med 4000 Services: 44970 5d c000 s 4000 44970 01 9a04b000000e10 s 4000 Done > ipaddr fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 fda8:5ce9:df1e:6620:0:ff:fe00:4001 fda8:5ce9:df1e:6620:ed74:123:cc5d:74ba fe80:0:0:0:d4a9:39a0:abce:b02e Done
Asegúrate de que los datos de red coincidan con los que están impresos en OTBR. Ahora podemos hacer ping a la dirección OMR de OTBR:
> ping fd76:a5d1:fcb0:1707:f3c7:d88c:efd1:24a9 Done > 16 bytes from fd76:a5d1:fcb0:1707:f3c7:d88c:efd1:24a9: icmp_seq=1 hlim=64 time=49ms
5. Publicación del Servicio en el Dispositivo Final
La mDNS se ha usado ampliamente en la publicación del servicio de DNS-SD en vínculos locales. Sin embargo, los mensajes multidifusión consumen demasiado ancho de banda y agotan la batería de los dispositivos de baja potencia rápidamente. Thread usa el protocolo SRP de unidifusión para registrar sus servicios con el router de borde y depende de este para anunciar los servicios en el vínculo Wi-Fi o Ethernet.
Podemos registrar un servicio con el comando srp client
.
Ve a la sesión de la pantalla del nodo del cliente de SRP y, luego, inicia el cliente de SRP automáticamente:
> srp client autostart enable Done
Establece el nombre de host que se anunciará en el enlace Wi-Fi/Ethernet:
> srp client host name ot-host Done
Para que un dispositivo con el vínculo Wi-Fi/Ethernet llegue a un dispositivo final Thread, se debe anunciar la dirección OMR del dispositivo final:
> srp client host address fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 Done
Al final, registra un servicio _ipps._tcp
falso:
> srp client service add ot-service _ipps._tcp 12345 Done
Espera unos segundos y deberíamos poder ver el servicio registrado:
> srp client service instance:"ot-service", name:"_ipps._tcp", state:Registered, port:12345, priority:0, weight:0 Done
Se completaron todos los trabajos de configuración y se debería haber anunciado el servicio _ipps._tcp
en el vínculo Wi-Fi/Ethernet. Es hora de descubrir y llegar al dispositivo final.
6. Descubre el servicio
Descubre el servicio con un teléfono celular
Usamos la app del Navegador de servicios para descubrir servicios de mDNS con el teléfono Android. También se puede encontrar una app equivalente para dispositivos móviles iOS. Abre la app y debería aparecer el servicio _ipps._tcp
.
Descubre el servicio con un host de Linux
Si quieres descubrir el servicio desde otro host de Linux, puedes usar el comando avahi-browse
.
Instala avahi-daemon
y avahi-utils
:
$ sudo apt-get install -y avahi-daemon avahi-utils
Resuelve el servicio:
$ sudo service avahi-daemon start # Ensure the avahi daemon is started. $ avahi-browse -r _ipps._tcp + wlan0 IPv6 ot-service Secure Internet Printer local = wlan0 IPv6 ot-service Secure Internet Printer local hostname = [ot-host.local] address = [fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927] port = [12345] txt = [] ...
Descubre el servicio con un host de macOS
Puedes usar dns-sd
en macOS para resolver el servicio:
$ dns-sd -Z _ipps._tcp local. Browsing for _ipps._tcp.local. DATE: ---Sun 14 Mar 2021--- 21:31:42.125 ...STARTING... ; To direct clients to browse a different domain, substitute that domain in place of '@' lb._dns-sd._udp PTR @ ; In the list of services below, the SRV records will typically reference dot-local Multicast DNS names. ; When transferring this zone file data to your unicast DNS server, you'll need to replace those dot-local ; names with the correct fully-qualified (unicast) domain name of the target host offering the service. _ipps._tcp PTR ot-service._ipps._tcp ot-service._ipps._tcp SRV 0 0 12345 ot-host.local. ; Replace with unicast FQDN of target host ot-service._ipps._tcp TXT "" ...
7. Haz ping en el dispositivo final
Cómo hacer ping desde un teléfono celular
Tomemos el teléfono Pixel como ejemplo. Podemos buscar la dirección OMR del servicio “OT-service” registrado anteriormente. en la página de detalles de la instancia de servicio en la app del navegador de servicios.
Ahora podemos hacer ping a la dirección OMR con otra app de Network Analyzer.
Lamentablemente, la versión para Android de la app de Network Analyzer no admite consultas de mDNS para la utilidad ping y no podemos hacer ping al nombre de host ot-host.local
directamente (podemos hacer ping al nombre de host con la versión de iOS de la app).
Haz ping desde un host de Linux/macOS
El router de borde de Thread envía anuncios de router ICMPv6 (RA) para anunciar prefijos (mediante la opción de información de prefijo) y rutas (mediante la opción de información de ruta) en el vínculo Wi-Fi/Ethernet.
Preparar host de Linux
Es importante que te asegures de que la RA y el RIO estén habilitados en tu host:
net.ipv6.conf.wlan0.accept_ra
debe ser de al menos1
si el reenvío de IP no está habilitado. De lo contrario, debe ser2
.net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen
no debe ser menor que64
.
El valor predeterminado de accept_ra
es 1
para la mayoría de las distribuciones. Sin embargo, puede haber otros daemons de red que anulen esta opción (por ejemplo, dhcpcd
en Raspberry Pi anulará accept_ra
a 0
). Puedes verificar el valor accept_ra
con lo siguiente:
$ sudo sysctl -n net.ipv6.conf.wlan0.accept_ra 0
Configura el valor en 1
(o 2
en caso de que el reenvío de IP esté habilitado) con lo siguiente:
$ sudo sysctl -w net.ipv6.conf.wlan0.accept_ra=1 Net.ipv6.conf.wlan0.accept_ra = 1
De forma predeterminada, la opción accept_ra_rt_info_max_plen
en la mayoría de las distribuciones de Linux es 0
. Configúrala en 64
con el siguiente comando:
$ sudo sysctl -w net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen=64 net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen = 64
El cambio se perderá después de reiniciar el host. Por ejemplo, agrega los siguientes comandos a /etc/sysctl.conf
para habilitar RIO de forma permanente:
$ net.ipv6.conf.wlan0.accept_ra_rt_info_max_plen = 64
Puede ser demasiado tarde para cambiar esas configuraciones porque el OTBR ya ha estado enviando mensajes RA, y el intervalo entre dos mensajes RA no solicitados podría ser de varios cientos de segundos. Una forma es desconectarse y volver a conectarse al PA de Wi-Fi para enviar mensajes de solicitud de router, de modo que OTBR responda a las RA solicitadas. Otra opción es reiniciar la función de enrutamiento de borde en el router de borde:
$ sudo ot-ctl br disable Done $ sudo ot-ctl br enable Done
Si estás intentando volver a conectar la red Wi-Fi o reiniciar la interfaz Ethernet, asegúrate de que no se use dhcpcd para administrar la red IPv6 de Wi-Fi o Ethernet. dhcpcd siempre anula la opción accept_ra
cada vez que se reinicia la interfaz y se pierde la configuración de accept_ra
. Agrega las siguientes líneas al archivo de configuración dhcpcd (p.ej., /etc/dhcpcd.conf
) para inhabilitar explícitamente IPv6 en dhcpcd:
noipv6 noipv6rs
Debes reiniciar el dispositivo para que se aplique el cambio.
Prepara host de macOS
Ambas opciones de accept_ra*
están habilitadas de forma predeterminada, pero debes actualizar tu sistema a macOS Big Sur, como mínimo.
Haz ping al nombre de host o la dirección IPv6
Ahora, podemos hacer ping al nombre de host ot-host.local
con el comando ping -6
(ping6
para macOS):
$ ping -6 ot-host.local. PING ot-host.local.(fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927)) 56 data bytes 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=1 ttl=63 time=170 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=2 ttl=63 time=64.2 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=3 ttl=63 time=22.8 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=4 ttl=63 time=37.7 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 (fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927): icmp_seq=5 ttl=63 time=28.7 ms ...
Este comando puede fallar en hosts Linux con el error "Name or service not known"
. Esto se debe a que el comando ping
no resuelve el nombre ot-host.local.
con consultas de mDNS. Abre /etc/nsswitch.conf
y agrega mdns6_minimal
a la línea que comienza con hosts
:
hosts: files mdns4_minimal mdns6_minimal dns
Por supuesto, siempre puedes hacer ping directamente a la dirección IPv6:
$ ping -6 fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927 PING fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927(fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927) 56 data bytes 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=1 ttl=63 time=32.9 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=2 ttl=63 time=27.8 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=3 ttl=63 time=29.9 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=4 ttl=63 time=73.5 ms 64 bytes from fd76:a5d1:fcb0:1707:d3dc:26d3:f70b:b927: icmp_seq=5 ttl=63 time=26.4 ms ...
8. Anula la publicación del Servicio para el dispositivo final
Para quitar la dirección y el servicio registrados desde el nodo cliente de SRP, sigue estos pasos:
> srp client host remove Done
No deberías poder descubrir el servicio _ipps._tcp
en este momento.
9. Felicitaciones
Felicitaciones, configuraste correctamente OTBR como router de borde de Thread para proporcionar conectividad IP bidireccional y descubrimiento de servicios para dispositivos finales de Thread.
¿Qué sigue?
Consulta algunos codelabs sobre los siguientes temas: