1. Introdução

O OpenThread lançado pelo Google é uma implementação de código aberto do protocolo de rede Thread. O Google Nest lançou o OpenThread para disponibilizar amplamente aos desenvolvedores a tecnologia usada nos produtos Nest e acelerar o desenvolvimento de produtos para a casa conectada.
A especificação Thread define um protocolo de comunicação sem fio confiável, seguro e de baixo consumo de energia entre dispositivos com base em IPv6 para aplicações domésticas. O OpenThread implementa todas as camadas de rede Thread, incluindo IPv6, 6LoWPAN, IEEE 802.15.4 com segurança MAC, estabelecimento de link de malha e roteamento de malha.
Neste codelab, você vai simular uma rede Thread em dispositivos emulados usando o Docker.
O que você vai aprender
- Como configurar a cadeia de ferramentas de build do OpenThread
- Como simular uma rede Thread
- Como autenticar nós do Thread
- Como gerenciar uma rede Thread com o daemon OpenThread
O que é necessário
- Docker
- Conhecimento básico de Linux e roteamento de rede
2. Configurar o Docker
Este codelab foi criado para usar o Docker em uma máquina Linux, Mac OS X ou Windows. O Linux é o ambiente recomendado.
Instalar o Docker
Instale o Docker no SO de sua escolha.
Extrair a imagem do Docker
Depois que o Docker for instalado, abra uma janela do terminal e extraia a imagem Docker openthread/environment. Essa imagem tem o OpenThread e o daemon OpenThread pré-criados e prontos para uso neste codelab.
$ docker pull openthread/environment:latest
Esse processo pode levar alguns minutos para ser concluído.
Em uma janela de terminal, inicie um contêiner do Docker na imagem e conecte-o ao shell bash:
$ docker run --name codelab_otsim_ctnr -it --rm \ --sysctl net.ipv6.conf.all.disable_ipv6=0 \ --cap-add=net_admin openthread/environment bash
A opção --rm exclui o contêiner quando você sai dele. Não use essa opção se não quiser que o contêiner seja excluído.
Observe as flags, que são obrigatórias para este codelab:
--sysctl net.ipv6.conf.all.disable_ipv6=0: ativa o IPv6 no contêiner.--cap-add=net_admin: ativa a capacidade NET_ADMIN, que permite executar operações relacionadas à rede, como adicionar rotas de IP.
Depois de entrar no contêiner, você vai receber um comando semelhante a este:
root@c0f3912a74ff:/#
No exemplo acima, c0f3912a74ff é o ID do contêiner. O ID do contêiner da sua instância do contêiner do Docker será diferente do mostrado nas solicitações deste codelab.
Como usar o Docker
Neste codelab, presumimos que você conhece o básico do uso do Docker. Você precisa permanecer no contêiner do Docker durante todo o codelab.
3. Simular uma rede Thread
O aplicativo de exemplo que você vai usar neste codelab demonstra um aplicativo OpenThread mínimo que expõe as interfaces de configuração e gerenciamento do OpenThread por uma interface de linha de comando (CLI) básica.
Este exercício mostra as etapas mínimas necessárias para fazer ping de um dispositivo Thread emulado para outro.
A figura abaixo descreve uma topologia básica de rede Thread. Neste exercício, vamos emular os dois nós dentro do círculo verde: um líder e um roteador do Thread com uma única conexão entre eles.

Criar a rede
1. Nó de início 1
Se você ainda não fez isso, em uma janela de terminal, inicie o contêiner do Docker e conecte-se ao shell bash dele:
$ docker run --name codelab_otsim_ctnr -it --rm \ --sysctl net.ipv6.conf.all.disable_ipv6=0 \ --cap-add=net_admin openthread/environment bash
No contêiner do Docker, crie o processo da CLI para um dispositivo Thread emulado usando o binário ot-cli-ftd.
root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 1
Observação:se o prompt > não aparecer depois de executar esse comando, pressione enter.
Esse binário implementa um dispositivo OpenThread. O driver de rádio IEEE 802.15.4 é implementado sobre o UDP (os frames IEEE 802.15.4 são transmitidos em payloads UDP).
O argumento de 1 é um descritor do arquivo que representa os bits menos significativos do IEEE EUI-64 "atribuído pela fábrica" para o dispositivo emulado. Esse valor também é usado ao vincular a uma porta UDP para emulação de rádio IEEE 802.15.4 (porta = 9000 + descritor do arquivo). Cada instância de um dispositivo Thread emulado neste codelab vai usar um descritor do arquivo diferente.
Observação:use apenas descritores de arquivo 1 ou superior, conforme observado neste codelab, ao gerar o processo para um dispositivo emulado. Um descritor do arquivo de 0 é reservado para outro uso.
Crie um novo conjunto de dados operacionais e o confirme como o ativo. O conjunto de dados operacional é a configuração da rede Thread que você está criando.
> dataset init new Done > dataset Active Timestamp: 1 Channel: 20 Channel Mask: 07fff800 Ext PAN ID: d6263b6d857647da Mesh Local Prefix: fd61:2344:9a52:ede0/64 Network Key: e4344ca17d1dca2a33f064992f31f786 Network Name: OpenThread-c169 PAN ID: 0xc169 PSKc: ebb4f2f8a68026fc55bcf3d7be3e6fe4 Security Policy: 0, onrcb Done
Faça o commit desse conjunto de dados como o ativo:
> dataset commit active Done
Ative a interface IPv6:
> ifconfig up Done
Iniciar operação do protocolo de conversa:
> thread start Done
Aguarde alguns segundos e verifique se o dispositivo se tornou o líder do Thread. O líder é o dispositivo responsável por gerenciar a atribuição de ID do roteador.
> state leader Done
Confira os endereços IPv6 atribuídos à interface Thread do nó 1 (sua saída será diferente):
> ipaddr fd61:2344:9a52:ede0:0:ff:fe00:fc00 fd61:2344:9a52:ede0:0:ff:fe00:5000 fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6 fe80:0:0:0:94da:92ea:1353:4f3b Done
Observe os tipos específicos de endereços IPv6:
- Começa com
fd= mesh-local - Começa com
fe80= link-local
Os tipos de endereços locais da malha são classificados da seguinte forma:
- Contém
ff:fe00= localizador de roteador (RLOC) - Não contém
ff:fe00= identificador de endpoint (EID)
Identifique o EID na saída do console e anote para usar depois. Na saída de exemplo acima, o EID é:
fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6
2. Nó de início 2
Abra um novo terminal e execute um shell bash no contêiner Docker em execução para usar no Node 2.
$ docker exec -it codelab_otsim_ctnr bash
Nesse novo comando bash, crie o processo da CLI com o argumento 2. Este é o segundo dispositivo Thread emulado:
root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 2
Observação:se o prompt > não aparecer depois de executar esse comando, pressione enter.
Configure a chave de rede Thread e o ID do PAN usando os mesmos valores do conjunto de dados operacionais do nó 1:
> dataset networkkey e4344ca17d1dca2a33f064992f31f786 Done > dataset panid 0xc169 Done
Faça o commit desse conjunto de dados como o ativo:
> dataset commit active Done
Ative a interface IPv6:
> ifconfig up Done
Iniciar operação do protocolo de conversa:
> thread start Done
O dispositivo vai se inicializar como uma criança. Um filho de thread é equivalente a um dispositivo final, que é um dispositivo de thread que transmite e recebe tráfego unicast apenas com um dispositivo pai.
> state child Done
Em até 2 minutos, o estado vai mudar de child para router. Um roteador Thread é capaz de rotear o tráfego entre dispositivos Thread. Ele também é chamado de "Parent".
> state router Done
Verificar a rede
Uma maneira fácil de verificar a rede mesh é consultar a tabela de roteadores.
1. Verificar a conectividade:
No nó 2, receba o RLOC16. O RLOC16 são os últimos 16 bits do endereço IPv6 RLOC do dispositivo.
> rloc16 5800 Done
No nó 1, verifique a tabela de roteamento do RLOC16 do nó 2. Verifique se o nó 2 mudou para o estado do roteador primeiro.
> router table | ID | RLOC16 | Next Hop | Path Cost | LQ In | LQ Out | Age | Extended MAC | +----+--------+----------+-----------+--------+-------+---+--------------------+ | 20 | 0x5000 | 63 | 0 | 0 | 0 | 0 | 96da92ea13534f3b | | 22 | 0x5800 | 63 | 0 | 3 | 3 | 23 | 5a4eb647eb6bc66c |
O RLOC 0x5800 do nó 2 é encontrado na tabela, confirmando que ele está conectado à malha.
2. Pingue o nó 1 do nó 2
Verifique a conectividade entre os dois dispositivos Thread emulados. No nó 2, ping o EID atribuído ao nó 1:
> ping fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6 > 16 bytes from fd61:2344:9a52:ede0:d041:c5ba:a7bc:5ce6: icmp_seq=1 hlim=64 time=12ms
Pressione enter para voltar ao prompt da CLI >.
Testar a rede
Agora que você consegue fazer ping entre dois dispositivos Thread emulados, teste a rede mesh colocando um nó off-line.
Volte ao nó 1 e interrompa a linha de execução:
> thread stop Done
Mude para o nó 2 e verifique o estado. Em até dois minutos, o nó 2 detecta que o líder (nó 1) está off-line, e você vai notar que o nó 2 passa a ser o leader da rede:
> state router Done ... > state leader Done
Depois de confirmar, pare o Thread e faça uma redefinição de fábrica no Node 2 antes de sair e voltar para o comando do Docker bash. A redefinição de fábrica é feita para garantir que as credenciais da rede Thread usadas neste exercício não sejam transferidas para o próximo.
> thread stop Done > factoryreset > > exit root@c0f3912a74ff:/#
Talvez seja necessário pressionar enter algumas vezes para trazer de volta o prompt > depois de um comando factoryreset. Não saia do contêiner do Docker.
Também faça uma redefinição de fábrica e saia do nó 1:
> factoryreset > > exit root@c0f3912a74ff:/#
Consulte a referência da CLI do OpenThread para conferir todos os comandos disponíveis.
4. Autenticar nós com o Commissioning
No exercício anterior, você configurou uma rede Thread com dois dispositivos simulados e verificou a conectividade. No entanto, isso só permite que o tráfego local de link IPv6 não autenticado passe entre dispositivos. Para rotear o tráfego IPv6 global entre eles (e a Internet por um roteador de borda Thread), os nós precisam ser autenticados.
Para autenticar, um dispositivo precisa agir como um comissário. O comissário é o servidor de autenticação eleito no momento para novos dispositivos Thread e o autorizador para fornecer as credenciais de rede necessárias para que os dispositivos entrem na rede.
Neste exercício, vamos usar a mesma topologia de dois nós de antes. Para autenticação, o líder do Thread vai atuar como o comissário, e o roteador do Thread como um participante.

Docker
Para cada nó (janela do terminal) nos exercícios restantes, verifique se você está executando o contêiner Docker com o build do OpenThread. Se você estiver continuando do exercício anterior, ainda terá dois comandos bash no mesmo contêiner do Docker aberto. Caso contrário, consulte a etapa Solução de problemas do Docker ou refaça o exercício Simular uma rede Thread.
1. Criar uma rede
No Node 1, crie o processo da CLI:
root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 1
Observação:se o prompt > não aparecer depois de executar esse comando, pressione enter.
Crie um novo conjunto de dados operacionais, faça commit dele como o ativo e inicie a linha de execução:
> dataset init new Done > dataset Active Timestamp: 1 Channel: 12 Channel Mask: 07fff800 Ext PAN ID: e68d05794bf13052 Mesh Local Prefix: fd7d:ddf7:877b:8756/64 Network Key: a77fe1d03b0e8028a4e13213de38080e Network Name: OpenThread-8f37 PAN ID: 0x8f37 PSKc: f9debbc1532487984b17f92cd55b21fc Security Policy: 0, onrcb Done
Faça o commit desse conjunto de dados como o ativo:
> dataset commit active Done
Ative a interface IPv6:
> ifconfig up Done
Iniciar operação do protocolo de conversa:
> thread start Done
Aguarde alguns segundos e verifique se o dispositivo se tornou um líder do Thread:
> state leader Done
2. Iniciar a função de comissário
Ainda no nó 1, inicie a função de comissário:
> commissioner start Done
Permitir que qualquer participante (usando o caractere curinga *) com a credencial de participante J01NME faça a ativação na rede. Um Joiner é um dispositivo adicionado por um administrador humano a uma rede Thread comissionada.
> commissioner joiner add * J01NME Done
3. Iniciar a função de participante
Em uma segunda janela de terminal, no contêiner do Docker, crie um novo processo de CLI. Este é o nó 2.
root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 2
No nó 2, ative a função de junção usando a credencial de junção J01NME.
> ifconfig up Done > joiner start J01NME Done
... aguarde alguns segundos para confirmação ...
Join success
Como um participante, o dispositivo (Node 2) se autenticou com o comissário (Node 1) e recebeu as credenciais da rede Thread.
Agora que o nó 2 está autenticado, inicie o Thread:
> thread start Done
4. Validar a autenticação de rede
Verifique o state no nó 2 para validar se ele agora faz parte da rede. Em dois minutos, o nó 2 faz a transição de child para router:
> state child Done ... > state router Done
5. Redefinir configuração
Para se preparar para o próximo exercício, redefina a configuração. Em cada nó, pare a Thread, faça uma redefinição de fábrica e saia do dispositivo Thread emulado:
> thread stop Done > factoryreset > > exit root@c0f3912a74ff:/#
Talvez seja necessário pressionar enter algumas vezes para trazer de volta o prompt > depois de um comando factoryreset.
5. Gerenciar a rede com o daemon OpenThread
Para este exercício, vamos simular uma instância da CLI (um único dispositivo SoC Thread incorporado) e uma instância de coprocessador de rádio (RCP, na sigla em inglês).
ot-daemon é um modo do app OpenThread Posix que usa um soquete UNIX como entrada e saída para que o núcleo do OpenThread possa ser executado como um serviço. Um cliente pode se comunicar com esse serviço conectando-se ao soquete usando a CLI OpenThread como protocolo.
O ot-ctl é uma CLI fornecida pelo ot-daemon para gerenciar e configurar o RCP. Com isso, vamos conectar o RCP à rede criada pelo dispositivo Thread.
Docker
Para cada nó (janela do terminal) neste exercício, verifique se você está executando o contêiner do Docker com o build do OpenThread. Se você estiver continuando do exercício anterior, já terá dois prompts bash abertos no mesmo contêiner do Docker. Caso contrário, consulte a etapa Solução de problemas do Docker.
Usar o ot-daemon
Este exercício vai usar três janelas de terminal, correspondentes ao seguinte:
- Instância da CLI do dispositivo Thread simulado (nó 1)
- Processo
ot-daemon - Instância da CLI
ot-ctl
1. Nó de início 1
Na primeira janela do terminal, gere o processo da CLI para o dispositivo Thread emulado:
root@c0f3912a74ff:/# /openthread/build/examples/apps/cli/ot-cli-ftd 1
Observação:se o prompt > não aparecer depois de executar esse comando, pressione enter.
Crie um novo conjunto de dados operacionais, faça commit dele como o ativo e inicie a linha de execução:
> dataset init new Done > dataset Active Timestamp: 1 Channel: 13 Channel Mask: 07fff800 Ext PAN ID: 97d584bcd493b824 Mesh Local Prefix: fd55:cf34:dea5:7994/64 Network Key: ba6e886c7af50598df1115fa07658a83 Network Name: OpenThread-34e4 PAN ID: 0x34e4 PSKc: 38d6fd32c866927a4dfcc06d79ae1192 Security Policy: 0, onrcb Done
Faça o commit desse conjunto de dados como o ativo:
> dataset commit active Done
Ative a interface IPv6:
> ifconfig up Done
Iniciar operação do protocolo de conversa:
> thread start Done
Confira os endereços IPv6 atribuídos à interface Thread do nó 1:
> ipaddr fd55:cf34:dea5:7994:0:ff:fe00:fc00 fd55:cf34:dea5:7994:0:ff:fe00:d000 fd55:cf34:dea5:7994:460:872c:e807:c4ab fe80:0:0:0:9cd8:aab6:482f:4cdc Done >
Conforme explicado na etapa Simular uma rede Thread, um endereço é link-local (fe80) e três são mesh-local (fd). O EID é o endereço mesh-local que não contém ff:fe00 no endereço. Neste exemplo de saída, o EID é fd55:cf34:dea5:7994:460:872c:e807:c4ab.
Identifique o EID específico na saída ipaddr, que será usado para se comunicar com o nó.
2. Iniciar ot-daemon
Na segunda janela de terminal, crie um nó de dispositivo tun e defina permissões de leitura/gravação:
root@c0f3912a74ff:/# mkdir -p /dev/net && mknod /dev/net/tun c 10 200 root@c0f3912a74ff:/# chmod 600 /dev/net/tun
Esse dispositivo é usado para transmissão e recebimento de pacotes em dispositivos virtuais. Você pode receber um erro se o dispositivo já tiver sido criado. Isso é normal e pode ser ignorado.
Inicie o ot-daemon para um nó RCP, que chamaremos de Nó 2. Use a flag detalhada -v para ver a saída do registro e confirmar que ele está em execução:
root@c0f3912a74ff:/# /openthread/build/posix/src/posix/ot-daemon -v \ 'spinel+hdlc+forkpty:///openthread/build/examples/apps/ncp/ot-rcp?forkpty-arg=2'
Quando bem-sucedido, o comando ot-daemon no modo detalhado gera uma saída semelhante a esta:
ot-daemon[31]: Running OPENTHREAD/297a880; POSIX; Feb 1 2022 04:43:39 ot-daemon[31]: Thread version: 3 ot-daemon[31]: Thread interface: wpan0 ot-daemon[31]: RCP version: OPENTHREAD/297a880; SIMULATION; Feb 1 2022 04:42:50
Deixe esse terminal aberto e em execução em segundo plano. Não insira mais comandos nele.
3. Use ot-ctl para participar da rede
Ainda não comissionamos o nó 2 (o ot-daemon RCP) em nenhuma rede Thread. É aí que entra o ot-ctl. O ot-ctl usa a mesma CLI que o app OpenThread CLI. Portanto, é possível controlar os nós ot-daemon da mesma maneira que os outros dispositivos Thread simulados.
Abra uma terceira janela de terminal e execute o contêiner atual:
$ docker exec -it codelab_otsim_ctnr bash
Depois de entrar no contêiner, inicie o ot-ctl:
root@c0f3912a74ff:/# /openthread/build/posix/src/posix/ot-ctl >
Você vai usar ot-ctl nesta terceira janela do terminal para gerenciar o nó 2 (o nó RCP) que você iniciou na segunda janela do terminal com ot-daemon. Verifique o state do nó 2:
> state disabled Done
Receba o eui64 do nó 2 para restringir a junção ao Joiner específico:
> eui64 18b4300000000001 Done
No nó 1 (primeira janela do terminal), inicie o comissário e restrinja a junção apenas a esse eui64:
> commissioner start Done > commissioner joiner add 18b4300000000001 J01NME Done
Na terceira janela do terminal, abra a interface de rede do nó 2 e entre na rede:
> ifconfig up Done > joiner start J01NME Done
... aguarde alguns segundos para confirmação ...
Join success
Como um participante, o RCP (nó 2) se autenticou com o comissário (nó 1) e recebeu as credenciais da rede Thread.
Agora, conecte o nó 2 à rede Thread (de novo, na terceira janela do terminal):
> thread start Done
4. Validar a autenticação de rede
No terceiro terminal, verifique o state no nó 2 para validar se ele entrou na rede. Em dois minutos, o nó 2 faz a transição de child para router:
> state child Done ... > state router Done
5. Validar a conectividade
Na terceira janela do terminal, saia do ot-ctl usando Ctrl+D ou o comando exit e volte para o console bash do contêiner. Nesse console, faça ping no nó 1 usando o EID dele com o comando ping6. Se a instância ot-daemon RCP for associada e se comunicar com a rede Thread, o ping será bem-sucedido:
root@c0f3912a74ff:/# ping6 -c 4 fd55:cf34:dea5:7994:460:872c:e807:c4ab PING fd55:cf34:dea5:7994:460:872c:e807:c4ab (fd55:cf34:dea5:7994:460:872c:e807:c4ab): 56 data bytes 64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=0 ttl=64 time=4.568 ms 64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=1 ttl=64 time=6.396 ms 64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=2 ttl=64 time=7.594 ms 64 bytes from fd55:cf34:dea5:7994:460:872c:e807:c4ab: icmp_seq=3 ttl=64 time=5.461 ms --- fd55:cf34:dea5:7994:460:872c:e807:c4ab ping statistics --- 4 packets transmitted, 4 packets received, 0% packet loss round-trip min/avg/max/stddev = 4.568/6.005/7.594/1.122 ms
6. Solução de problemas do Docker
Se você saiu do contêiner do Docker
bash solicitações, talvez seja necessário verificar se ele está em execução e reiniciar / inserir novamente conforme necessário. Todos os contêineres do Docker criados sem a opção --rm ainda vão existir.
Para mostrar quais contêineres do Docker estão em execução:
$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 505fc57ffc72 environment "bash" 10 minutes ago Up 10 minutes codelab_otsim_ctnr
Para mostrar todos os contêineres do Docker (em execução e interrompidos):
$ docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 505fc57ffc72 environment "bash" 10 minutes ago Up 10 minutes codelab_otsim_ctnr
Se o contêiner codelab_otsim_ctnr não aparecer na saída de nenhum dos comandos docker ps, execute-o novamente:
$ docker run --name codelab_otsim_ctnr -it --rm \ --sysctl net.ipv6.conf.all.disable_ipv6=0 \ --cap-add=net_admin openthread/environment bash
Use a opção --rm apenas se quiser que o contêiner seja excluído ao sair dele.
Se o contêiner estiver parado (listado em docker ps -a, mas não em docker ps), reinicie-o:
$ docker start -i codelab_otsim_ctnr
Se o contêiner do Docker já estiver em execução (listado em docker ps), reconecte-se a ele em cada terminal:
$ docker exec -it codelab_otsim_ctnr bash
Erros "Operação não permitida"
Se você encontrar erros de Operation not permitted ao criar novos nós OpenThread (usando o comando mknod), verifique se você está executando o Docker como o usuário raiz de acordo com os comandos fornecidos neste codelab. Este codelab não oferece suporte à execução do Docker no modo sem raiz.
7. Parabéns!
Você simulou sua primeira rede Thread usando o OpenThread. Incrível!
Neste codelab, você aprendeu a:
- Iniciar e gerenciar o contêiner do Docker de simulação do OpenThread
- Simular uma rede Thread
- Autenticar nós do Thread
- Gerenciar uma rede Thread com o daemon OpenThread
Para saber mais sobre o Thread e o OpenThread, consulte estas referências:
- Introdução ao Thread em openthread.io
- Especificação de thread
- Repositório do OpenThread no GitHub
- Referência da CLI do OpenThread
- Suporte adicional do Docker para OpenThread
Ou tente usar o OpenThread Border Router em um contêiner do Docker.