1. Introdução
O OpenThread (link em inglês) 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 a tecnologia usada nos produtos Nest de forma ampla para os desenvolvedores acelerarem o desenvolvimento de produtos para a casa conectada.
A especificação Thread define um protocolo de comunicação entre dispositivos sem fio, confiável, seguro e de baixo consumo energético baseado em IPv6 para aplicativos domésticos. 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 programar o OpenThread em hardware real, criar e gerenciar uma rede Thread e transmitir mensagens entre nós.
O que você vai aprender
- Como criar e atualizar binários da CLI do OpenThread em placas de desenvolvimento
- Como criar um RCP que consiste em uma máquina Linux e uma placa de desenvolvimento
- Como se comunicar com um RCP usando o daemon do OpenThread e o
ot-ctl
- Gerenciar manualmente nós de linha de execução com o GNU Screen e a CLI do OpenThread
- Comissionamento seguro de dispositivos em uma rede Thread
- Como o multicast IPv6 funciona
- Como transmitir mensagens entre nós de linha de execução com UDP
O que é necessário
Hardware:
- 3 placas de desenvolvimento nRF52840 da Nordic Semiconductor
- Três cabos USB para micro USB para conectar as placas
- Uma máquina Linux com pelo menos três portas USB
Software:
- Conjunto de ferramentas do GNU
- Ferramentas de linha de comando nRF5x da Nordic
- Software Segger J-Link
- OpenThread
- Git
2. Primeiros passos
Simulação do OpenThread
Antes de começar, recomendamos que você faça o Codelab de simulação do OpenThread para se familiarizar com os conceitos básicos de linha de execução e a CLI do OpenThread.
Terminais de porta serial
Você precisa saber se conectar a uma porta serial usando um terminal. Este codelab usa o GNU Screen e apresenta uma visão geral do uso, mas é possível usar qualquer outro software de terminal.
Máquina Linux
Este codelab foi criado para usar uma máquina Linux baseada em i386 ou x86 como host de um dispositivo Thread de coprocessador de rádio (RCP) e atualizar todas as placas de desenvolvimento Thread. Todas as etapas foram testadas no Ubuntu 14.04.5 LTS (Trusty Tahr).
Placas nRF52840 da Nordic Semiconductor
Este codelab usa três placas PDK nRF52840.
Instalar o SEGGER J-Link
Usamos o SEGGER J-Link para programar as placas nRF52840, que têm módulos JTAG integrados. Instale o pacote na sua máquina Linux.
Faça o download do pacote adequado para sua máquina e instale-o no local correto. No Linux, ele é /opt/SEGGER/JLink
.
Instalar as ferramentas de linha de comando nRF5x
As ferramentas de linha de comando nRF5x permitem que você faça o flash dos binários do OpenThread nas placas nRF52840. Instale o build apropriado do nRF5x-Command-Line-Tools-<OS> na sua máquina Linux.
Coloque o pacote extraído na pasta raiz ~/
Instalar a cadeia de ferramentas GNU do ARM
A cadeia de ferramentas GNU ARM é usada para criar.
Recomendamos colocar o arquivo extraído em /opt/gnu-mcu-eclipse/arm-none-eabi-gcc/
na máquina Linux. Siga as instruções no arquivo readme.txt
do arquivo para instalação.
Tela de instalação (opcional)
O Screen é uma ferramenta simples para acessar dispositivos conectados por uma porta serial. Este codelab usa o Screen, mas você pode usar qualquer aplicativo de terminal de porta serial que quiser.
$ sudo apt-get install screen
3. Clonar repositórios
OpenThread
Clone e instale o OpenThread. Os comandos script/bootstrap
garantem que a cadeia de ferramentas esteja instalada e que o ambiente esteja configurado corretamente:
$ mkdir -p ~/src $ cd ~/src $ git clone --recursive https://github.com/openthread/openthread.git $ cd openthread $ ./script/bootstrap
Crie o daemon do OpenThread:
$ script/cmake-build posix -DOT_DAEMON=ON
Agora está tudo pronto para criar e atualizar o OpenThread para as placas nRF52840.
4. Configurar o RCP Joiner
Criar e atualizar
Crie o exemplo do OpenThread nRF52840 com o Joiner e a funcionalidade USB nativa. Um dispositivo usa o papel de participante para ser autenticado e comissionado com segurança em uma rede Thread. O USB nativo permite o uso do USB CDC ACM como um transporte serial entre o nRF52840 e o host.
Sempre limpe o repositório de builds anteriores primeiro executando rm -rf build
.
$ cd ~/src $ git clone --recursive https://github.com/openthread/ot-nrf528xx.git $ cd ot-nrf528xx $ script/build nrf52840 USB_trans
Navegue até o diretório com o binário RCP do OpenThread e converta-o para o formato hexadecimal:
$ cd ~/src/ot-nrf528xx/build/bin $ arm-none-eabi-objcopy -O ihex ot-rcp ot-rcp.hex
Conecte o cabo USB à porta de depuração micro USB ao lado do pino de alimentação externo na placa nRF52840 e, em seguida, conecte-o à máquina Linux. Defina a chave Fonte de alimentação do nRF na placa nRF52840 como VDD. Quando conectado corretamente, o LED5 fica aceso.
Se esta for a primeira placa conectada à máquina Linux, ela vai aparecer como porta serial /dev/ttyACM0
. Todas as placas nRF52840 usam ttyACM
como identificador da porta serial.
$ ls /dev/ttyACM* /dev/ttyACM0
Observe o número de série da placa nRF52840 usada para o RCP:
Navegue até o local das ferramentas de linha de comando nRFx e faça o flash do arquivo hexadecimal RCP do OpenThread na placa nRF52840 usando o número de série dela. Se você não incluir a flag --verify
, vai receber uma mensagem de aviso informando que o processo de flash pode falhar sem erros.
$ cd ~/nrfjprog/ $ ./nrfjprog -f nrf52 -s 683704924 --verify --chiperase --program \ ~/src/ot-nrf528xx/build/bin/ot-rcp.hex --reset
A saída a seguir é gerada após o sucesso:
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.
Marque o quadro como "RCP" para não confundir as funções do conselho.
Conectar ao USB nativo
Como o build do RCP do OpenThread permite o uso do USB CDC ACM nativo como um transporte serial, é necessário usar a porta nRF USB na placa nRF52840 para se comunicar com o host do RCP (máquina Linux).
Desconecte a extremidade micro USB do cabo USB da porta de depuração da placa nRF52840 piscada e conecte-a novamente à porta micro USB nRF USB ao lado do botão RESET. Defina a Fonte de alimentação nRF como USB.
Iniciar o daemon do OpenThread
No design do RCP, use o OpenThread Daemon para se comunicar e gerenciar o dispositivo Thread. Inicie o ot-daemon
com a flag detalhada -v
para conferir a saída do registro e confirmar que ele está em execução:
$ cd ~/src/openthread $ sudo ./build/posix/src/posix/ot-daemon -v \ 'spinel+hdlc+uart:///dev/ttyACM0?uart-baudrate=460800'
Quando bem-sucedido, o ot-daemon
no modo detalhado gera uma saída semelhante a esta:
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
Deixe esta janela do terminal aberta para que os registros do ot-daemon
possam ser visualizados.
Use ot-ctl
para se comunicar com o nó RCP. O ot-ctl
usa a mesma CLI do app CLI do OpenThread. Portanto, é possível controlar nós ot-daemon
da mesma maneira que os outros dispositivos Thread simulados.
Em uma segunda janela de terminal, inicie ot-ctl
:
$ sudo ./build/posix/src/posix/ot-ctl >
Verifique o state
do nó 2 (o nó RCP) que você iniciou com ot-daemon
:
> state disabled Done
5. Configurar os FTDs
Os outros dois nós da Thread usados neste codelab são dispositivos de thread completa (FTDs, na sigla em inglês) no design padrão do sistema em chip (SoC). Em uma configuração de produção, é possível usar o wpantund
, um driver de interface de rede de produção, para controlar instâncias de NCP do OpenThread. No entanto, neste codelab, vamos usar o ot-ctl
, a CLI do OpenThread.
Um dispositivo funciona como o comissário, para autenticar e comissionar dispositivos com segurança nessa rede. O outro dispositivo funciona como um participante que o comissário pode autenticar na rede Thread.
Criar e atualizar
Crie o exemplo de FTD do OpenThread para a plataforma nRF52840, com as funções de comissionamento e de participante ativadas:
$ cd ~/src/ot-nrf528xx $ rm -rf build $ script/build nrf52840 USB_trans -DOT_JOINER=ON -DOT_COMMISSIONER=ON
Navegue até o diretório com o binário da CLI do dispositivo de thread completo (FTD) do OpenThread e converta-o para o formato hexadecimal:
$ cd ~/src/ot-nrf528xx/build/bin $ arm-none-eabi-objcopy -O ihex ot-cli-ftd ot-cli-ftd.hex
Conecte o cabo USB à porta micro USB ao lado do pino de alimentação externo na placa nRF52840 e conecte-o à máquina Linux. Se o RCP ainda estiver conectado à máquina Linux, essa nova placa vai aparecer como porta serial /dev/ttyACM1
. Todas as placas nRF52840 usam ttyACM
como identificador da porta serial.
$ ls /dev/ttyACM* /dev/ttyACM0 /dev/ttyACM1
Como antes, anote o número de série da placa nRF52840 usada para o FTD:
Navegue até o local das ferramentas de linha de comando nRFx e faça o flash do arquivo hexadecimal FTD da CLI do OpenThread na placa nRF52840 usando o número de série dela:
$ cd ~/nrfjprog/ $ ./nrfjprog -f nrf52 -s 683704924 --verify --chiperase --program \ ~/src/ot-nrf528xx/build/bin/ot-cli-ftd.hex --reset
Nomeie o quadro como "Comissário".
Conectar ao USB nativo
Como o build do OpenThread FTD permite o uso do USB CDC ACM nativo como um transporte serial, use a porta nRF USB na placa nRF52840 para se comunicar com o host RCP (máquina Linux).
Desconecte a extremidade micro USB do cabo USB da porta de depuração da placa nRF52840 piscada e conecte-a novamente à porta micro USB nRF USB ao lado do botão RESET. Defina a Fonte de alimentação nRF como USB.
Verificar build
Para verificar se o build foi bem-sucedido, acesse a CLI do OpenThread usando o GNU Screen em uma janela de terminal.
$ screen /dev/ttyACM1
Na nova janela, pressione "Return" no teclado algumas vezes para abrir a solicitação >
da CLI do OpenThread. Abra a interface IPv6 e verifique os endereços:
> ifconfig up Done > ipaddr fe80:0:0:0:1cd6:87a9:cb9d:4b1d Done
Use Ctrl+a →
d
para se desconectar da tela da CLI do FTD Commissioner e retornar ao terminal do Linux para que a próxima placa possa ser atualizada. Para entrar novamente na CLI a qualquer momento, use screen -r
na linha de comando. Para conferir uma lista das telas disponíveis, use screen -ls
:
$ screen -ls There is a screen on: 74182.ttys000.mylinuxmachine (Detached) 1 Socket in /tmp/uscreens/S-username.
Configurar o FTD Joiner
Repita o processo acima para atualizar a terceira placa nRF52840, usando o build ot-cli-ftd.hex
. Quando terminar, reconecte a placa ao PC usando a porta USB do nRF e defina a chave Fonte de energia do nRF como VDD.
Se os outros dois nós estiverem conectados à máquina Linux quando o terceiro for conectado, ele vai aparecer como porta serial /dev/ttyACM2
:
$ ls /dev/ttyACM* /dev/ttyACM0 /dev/ttyACM1 /dev/ttyACM2
Nomeie o tabuleiro como "Joiner".
Ao verificar usando a tela, em vez de criar uma nova instância de tela na linha de comando, reconecte-se à instância existente e crie uma nova janela nela (que você usou para o comissário de FTD):
$ screen -r
Crie a nova janela no screen com Ctrl + a → c
.
Um novo prompt de linha de comando vai aparecer. Acesse a CLI do OpenThread para o Joiner do FTD:
$ screen /dev/ttyACM2
Nessa nova janela, pressione "Return" no teclado algumas vezes para abrir a solicitação >
da CLI do OpenThread. Abra a interface IPv6 e verifique os endereços:
> ifconfig up Done > ipaddr fe80:0:0:0:6c1e:87a2:df05:c240 Done
Agora que a CLI do FTD Joiner está na mesma instância de tela que o FTD Commissioner, é possível alternar entre eles usando Ctrl+a → n
.
Use Ctrl+a →
d
a qualquer momento para sair da tela.
6. Configuração da janela do terminal
Você vai alternar entre os dispositivos Thread com frequência, então verifique se todos estão ativos e facilmente acessíveis. Até agora, usamos a tela para acessar os dois FTDs, e essa ferramenta também permite a tela dividida na mesma janela do terminal. Use isso para saber como um nó reage a comandos emitidos em outro.
O ideal é ter quatro janelas disponíveis:
ot-daemon
serviço / registros- RCP Joiner por
ot-ctl
- Comissão de FTD pela CLI do OpenThread
- FTD Joiner usando a CLI do OpenThread
Se você quiser usar sua própria configuração ou ferramenta de terminal / porta serial, pule para a próxima etapa. Configure as janelas do terminal para todos os dispositivos da maneira que funcionar melhor para você.
Como usar a tela
Para facilitar o uso, inicie apenas uma sessão de tela. Você já deve ter um deles quando configurou os dois FTDs.
Todos os comandos no Screen começam com Ctrl+a.
Comandos básicos da tela:
Retornar à sessão de tela (na linha de comando) |
|
Sair da sessão de tela | Ctrl+a → |
Criar uma nova janela na sessão de tela | Ctrl+a → |
Alternar entre janelas na mesma sessão de tela | Ctrl+a → |
Encerrar a janela atual na sessão de tela | Ctrl+a → |
Tela dividida
Com a tela, você pode dividir o terminal em várias janelas:
Os comandos em screen
são acessados usando Ctrl+a. Todos os comandos precisam começar com essa combinação de chave de acesso.
Se você seguiu o codelab exatamente, deve ter duas janelas (comissário e participante do FTD) na mesma instância de tela. Para dividir a tela entre os dois, primeiro entre na sessão de tela atual:
$ screen -r
Você precisa estar em um dos dispositivos FTD. Siga estas etapas na tela:
- Ctrl+a →
S
para dividir a janela horizontalmente - Ctrl+a →
Tab
para mover o cursor para a nova janela em branco - Ctrl+a →
n
para alternar entre as janelas - Se for o mesmo que a janela de cima, pressione Ctrl+a →
n
novamente para ver o outro dispositivo FTD.
Agora, elas estão visíveis. Alterne entre eles usando Ctrl + a → Tab
. Recomendamos que você renomeie cada janela com Ctrl+a → A
para evitar confusão.
Uso avançado
Para dividir a tela em quadrantes e conferir os registros de ot-daemon
e o ot-ctl
do RCP Joiner, esses serviços precisam ser iniciados nessa mesma instância de tela. Para isso, pare ot-daemon
e saia de ot-ctl
e reinicie em novas janelas do Screen (Ctrl+a → c
).
Essa configuração não é obrigatória e é deixada como um exercício para o usuário.
Divida e navegue entre as janelas com os seguintes comandos:
Criar nova janela | Ctrl+a → |
Dividir a janela verticalmente | Ctrl+a → |
Dividir a janela horizontalmente | Ctrl+a → |
Ir para a próxima janela exibida | Ctrl+a → |
Mudar a janela exibida para frente ou para trás | Ctrl+a → |
Renomear a janela atual | Ctrl+a → |
Saia do screen a qualquer momento com Ctrl+a → d
e reconecte com screen -r
na linha de comando.
Para mais informações sobre o Screen, consulte a Referência rápida do GNU Screen.
7. Criar a rede Thread
Agora que você configurou todas as janelas e telas do terminal, vamos criar nossa rede Thread. No Comissário de FTD, crie um novo conjunto de dados operacionais e confirme como ativo. O conjunto de dados operacional é a configuração da rede Thread que você está criando.
## 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
Anote a chave de rede 1234c0de7ab51234c0de7ab51234c0de
, que será usada mais tarde.
Confirme esse conjunto de dados como ativo:
> dataset commit active Done
Ative a interface IPv6:
> ifconfig up Done
Iniciar a operação do protocolo de linha de execução:
> thread start Done
Após um momento, verifique o estado do dispositivo. Ele precisa ser o líder. Também receba o RLOC16 para referência futura.
## FTD Commissioner ## ---------------------- > state leader Done > rloc16 0c00 Done
Verifique os endereços IPv6 do 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)
A rede "codelab" agora fica visível quando é verificada em outros dispositivos Thread.
Em ot-ctl
no RCP Joiner:
## RCP Joiner ## ---------------- > scan | PAN | MAC Address | Ch | dBm | LQI | +------+------------------+----+-----+-----+ | c0de | 1ed687a9cb9d4b1d | 11 | -36 | 232 |
Na CLI do OpenThread no FTD Joiner:
## FTD Joiner ## ---------------- > scan | PAN | MAC Address | Ch | dBm | LQI | +------+------------------+----+-----+-----+ | c0de | 1ed687a9cb9d4b1d | 11 | -38 | 229 |
Se a rede "codelab" não aparecer na lista, tente fazer a verificação novamente.
8. Adicionar o Joiner do RCP
A ativação do Thread não está ativa na rede, o que significa que precisamos adicionar o Joiner RCP à rede Thread que acabamos de criar usando um processo de ativação fora da banda.
No comissário da FTD, fizemos uma anotação da chave de rede, por exemplo, 1234c0de7ab51234c0de7ab51234c0de
. Se você precisar procurar a chave de rede novamente, execute o seguinte comando no comissário do FTD:
## FTD Commissioner ## > dataset networkkey 1234c0de7ab51234c0de7ab51234c0de Done
Em seguida, no RCP Joiner, defina a chave de rede do conjunto de dados ativo como a chave de rede do comissário de FTD:
## RCP Joiner ## ---------------- > dataset networkkey 1234c0de7ab51234c0de7ab51234c0de Done > dataset commit active Done
Verifique se o conjunto de dados está configurado corretamente.
## RCP Joiner ## ---------------- > dataset Network Key: 1234c0de7ab51234c0de7ab51234c0de
Abra a linha de execução para que o Joiner do RCP se conecte à rede "codelab". Aguarde alguns segundos, verifique o estado, o RLOC16 e os endereços 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
Anote o endereço IPv6 local de malha (fdc0:de7a:b5c0:0:66bf:99b9:24c0:d55f
aqui), porque você vai usá-lo mais tarde.
No Comissário de FTD, verifique as tabelas de roteador e filho para confirmar se os dois dispositivos fazem parte da mesma rede. Use o RLOC16 para identificar o Joiner do 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
Faça ping no endereço local da malha do RCP Joiner (o endereço local da malha obtido da saída ipaddr
do RCP Joiner) para verificar a conectividade:
## 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
Agora temos uma rede Thread com dois nós, ilustrada neste diagrama de topologia:
Diagramas de topologia
À medida que você trabalha no resto do codelab, vamos mostrar um novo diagrama de topologia de linha sempre que o estado da rede mudar. Os papéis do nó são indicados da seguinte maneira:
Os roteadores são sempre pentágonos, e os dispositivos finais são sempre círculos. Os números em cada nó representam o ID do roteador ou do filho mostrado na saída da CLI, dependendo da função e do estado atuais de cada nó naquele momento.
9. Comissionar o Joiner da FTD
Agora vamos adicionar o terceiro dispositivo Thread à rede "codelab". Desta vez, vamos usar o processo de comissionamento na banda mais seguro e permitir apenas que o participante do FTD participe.
No FTD Joiner, receba o eui64
para que o comissário do FTD possa identificá-lo:
## FTD Joiner ## ---------------- > eui64 2f57d222545271f1 Done
No Comissário do FTD, inicie o comissário e especifique o eui64
do dispositivo que pode participar, junto com a credencial do participante, por exemplo, J01NME
. A credencial do participante é uma string específica do dispositivo com todos os caracteres alfanuméricos em maiúsculas (0 a 9 e A a Y, excluindo I, O, Q e Z para facilitar a leitura), com um comprimento entre 6 e 32 caracteres.
## FTD Commissioner ## ---------------------- > commissioner start Done > commissioner joiner add 2f57d222545271f1 J01NME Done
Mude para o FTD Joiner. Inicie a função de participante com a credencial de participante que você acabou de configurar no comissário de FTD:
## FTD Joiner ## ---------------- > ifconfig up Done > joiner start J01NME Done
Em cerca de um minuto, você vai receber uma confirmação de autenticação:
## FTD Joiner ## ---------------- > Join success
Acesse a Thread para que o Joiner FTD se conecte à rede "codelab" e verifique imediatamente o estado e o RLOC16:
## FTD Joiner ## ---------------- > thread start Done > state child Done > rloc16 0c02 Done
Verifique os endereços IPv6 do dispositivo. Não há ALOC. Isso ocorre porque esse dispositivo não é o líder nem tem um papel específico de anycast que exija um 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)
Mude imediatamente para o Comissário de FTD e verifique as tabelas de roteador e filha para confirmar se três dispositivos existem na rede "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
Com base no RLOC16, o Joiner FTD foi conectado à rede como um dispositivo final (filho). Confira nossa topologia atualizada:
10. Conversa em ação
Os dispositivos Thread neste codelab são um tipo específico de dispositivo completo do Thread (FTD, na sigla em inglês), chamado de dispositivo final qualificado para roteador (REED, na sigla em inglês). Isso significa que eles podem funcionar como um roteador ou dispositivo final e podem ser promovidos de um dispositivo final para um roteador.
O Thread pode oferecer suporte a até 32 roteadores, mas tenta manter o número de roteadores entre 16 e 23. Se um REED for conectado como um dispositivo final (filho) e o número de roteadores for inferior a 16, após um período aleatório de até dois minutos, ele será promovido automaticamente a um roteador.
Se você tiver duas crianças na rede Thread após adicionar o participante FTD, aguarde pelo menos dois minutos e verifique novamente as tabelas de roteador e filho no comissário 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
O Joiner FTD (MAC estendido = e6cdd2d93249a243
) foi promovido a um roteador. O RLOC16 é diferente (b800
em vez de 0c02
). Isso ocorre porque o RLOC16 é baseado no ID do roteador e no ID filho de um dispositivo. Quando a transição do dispositivo final para o roteador acontece, os valores do ID do roteador e do ID filho mudam, assim como o RLOC16.
Confirme o novo estado e o RLOC16 no FTD Joiner:
## FTD Joiner ## ---------------- > state router Done > rloc16 b800 Done
Fazer downgrade do Joiner da FTD
Para testar esse comportamento, faça o downgrade manual do FTD Joiner de um roteador para um dispositivo final. Mude o estado para "filho" e verifique o RLOC16:
## FTD Joiner ## ---------------- > state child Done > rloc16 0c03 Done
Voltando ao Comissário de FTD, o participante de FTD agora vai aparecer na tabela filha (ID = 3). Ele pode estar em ambos durante a transição:
## 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
Depois de algum tempo, ele voltará para um roteador com um RLOC de b800
.
Remover o líder
O líder é eleito entre todos os roteadores Thread. Isso significa que, se o líder atual for removido da rede Thread, um dos outros roteadores vai se tornar o novo líder.
No FTD Commissioner, desative o Thread para removê-lo da rede:
## FTD Commissioner ## ---------------------- > thread stop Done > ifconfig down Done
Em dois minutos, o FTD Joiner se torna o novo líder da linha de execução. Verifique o estado e os endereços IPv6 do Joiner de FTD para verificar:
## 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
Confira a tabela filha. Há um novo RLOC16. Esse é o Joiner do RCP, conforme indicado pelo ID e pelo MAC estendido. Para manter a rede Thread unida, ele trocou os roteadores principais, do comissário do FTD para o Joiner do FTD. Isso resulta em um novo RLOC16 para o Joiner RCP porque o ID do roteador mudou de 3 para 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
Talvez seja necessário aguardar alguns minutos para que o RCP Joiner seja anexado ao FTD Joiner como uma criança. Verifique o estado e o RLOC16 para confirmar que:
## RCP Joiner ## -------------- > state child > rloc16 b801
Reconecte o comissário de FTD
Uma rede Thread com dois nós não é muito divertida. Vamos colocar o comissário da FTD de volta on-line.
Na Comissão de FTD, reinicie a linha de execução:
## FTD Commissioner ## ---------------------- > ifconfig up Done > thread start Done
Em dois minutos, ele se reconecta automaticamente à rede "codelab" como um dispositivo final e depois se promove a um roteador.
## FTD Commissioner ## ---------------------- > state router Done
Verifique as tabelas do roteador e filhas no FTD Joiner para verificar:
## 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
Nossa rede Thread consiste em três nós novamente.
11. Solução de problemas
Gerenciar uma rede Thread com vários dispositivos em diferentes terminais ou janelas de tela pode ser complicado. Use estas dicas para "redefinir" o estado da rede ou do seu espaço de trabalho se você encontrar problemas.
Tela
Se você se perder na configuração (muitas janelas de tela ou telas dentro de telas), continue matando as janelas de tela com Ctrl+a → k até que nenhuma exista e screen -ls
na linha de comando gere No Sockets found
. Em seguida, recrie as janelas de tela para cada dispositivo. Os estados do dispositivo são mantidos mesmo quando a tela é encerrada.
Nós de linha de execução
Se a topologia da rede Thread não estiver como descrito neste codelab ou se os nós se desconectarem por algum motivo (talvez porque a máquina Linux que os alimenta tenha entrado em suspensão), é melhor desativar a Thread, limpar as credenciais de rede e começar de novo na etapa Criar a rede Thread.
Para redefinir os FTDs:
## FTD Commissioner or FTD Joiner ## ------------------------------------ > thread stop Done > ifconfig down Done > factoryreset Done
O RCP pode ser redefinido da mesma forma pelo ot-ctl
:
## RCP Joiner ## ---------------- > thread stop Done > ifconfig down Done > factoryreset Done
12. Usar multicast
O multicast é usado para comunicar informações a um grupo de dispositivos de uma só vez. Em uma rede Thread, endereços específicos são reservados para uso multicast com diferentes grupos de dispositivos, dependendo do escopo.
Endereço IPv6 | Escopo | Entregue para |
| Link-local | Todos os FTDs e MEDs |
| Link-local | Todos os FTDs e roteadores de borda |
| Mesh-local | Todos os FTDs e MEDs |
| Mesh-local | Todos os FTDs e roteadores de borda |
Como não estamos usando um roteador de borda neste codelab, vamos nos concentrar nos dois endereços multicast FTD e MED.
Link-local
O escopo de link local compreende todas as interfaces Thread alcançáveis por uma única transmissão de rádio ou um único "salto". A topologia da rede determina quais dispositivos respondem a um ping para o endereço multicast ff02::1
.
Faça um ping em ff02::1
do comissário da FTD:
## FTD Commissioner ## ---------------------- > ping ff02::1 > 8 bytes from fe80:0:0:0:e4cd:d2d9:3249:a243: icmp_seq=2 hlim=64 time=9ms
Há outros dois dispositivos na rede (FTD Joiner e RCP Joiner), mas o comissário FTD só recebeu uma resposta, do endereço local de link (LLA) do FTD Joiner. Isso significa que o participante do FTD é o único dispositivo que o comissário do FTD pode alcançar com um único salto.
Agora, faça um ping de ff02::1
no 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
Duas respostas! Ao verificar os endereços IPv6 dos outros dispositivos, podemos ver que o primeiro (que termina em 4b1d
) é o LLA do comissário do FTD, e o segundo (que termina em 943b
) é o LLA do participante do RCP.
Isso significa que o FTD Joiner está conectado diretamente ao FTD Commissioner e ao RCP Joiner, o que confirma nossa topologia.
Mesh-local
O escopo "Mesh-Local" inclui todas as interfaces Thread acessíveis na mesma rede Thread. Vamos conferir as respostas a um ping para o endereço de multicast ff03::1
.
Faça um ping de ff03::1
do comissário da 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
Dessa vez, o comissário de FTD recebeu duas respostas, uma do RLOC do participante de FTD (terminando em b800
) e outra do EID local de malha do participante de RCP (ML-EID, terminando em d55f
). Isso ocorre porque o escopo local de malha compreende toda a rede Thread. Não importa onde o dispositivo está na rede, ele será inscrito no endereço ff03::1
.
Faça um ping em ff03::1
no FTD Joiner para confirmar o mesmo comportamento:
## 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
Anote o tempo de resposta do RCP Joiner nas duas saídas de ping. O Joiner de RCP demorou muito mais para alcançar o Comissário de FTD (68 ms) do que para alcançar o Joiner de FTD (23 ms). Isso ocorre porque ele precisa fazer dois saltos para chegar ao comissário do FTD, em comparação com um salto para o participante do FTD.
Você também pode ter notado que o ping de multicast local de malha respondeu com o RLOC apenas para os dois FTDs, e não para o Joiner de RCP. Isso ocorre porque os FTDs são roteadores na rede, enquanto o RCP é um dispositivo final.
Verifique o estado do RCP Joiner para confirmar:
## RCP Joiner ## ---------------- > state child
13. Enviar mensagens com UDP
Um dos serviços de aplicativo que o OpenThread oferece é o protocolo de datagramas do usuário (UDP), um protocolo da camada de transporte. Um aplicativo criado com o OpenThread pode usar a API UDP para transmitir mensagens entre nós em uma rede Thread ou para outros dispositivos em uma rede externa (como a Internet, se a rede Thread tiver um roteador de borda).
Os soquetes UDP são expostos pela CLI do OpenThread. Vamos usá-lo para transmitir mensagens entre os dois FTDs.
Receba o endereço EID de rede local para o FTD Joiner. Estamos usando esse endereço porque ele pode ser acessado de qualquer lugar na rede 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
Inicie o UDP e vincule-o a um socket para qualquer endereço IPv6:
## FTD Joiner ## ---------------- > udp open Done > udp bind :: 1212
Mude para o Comissão de FTD, inicie o UDP e conecte-se ao soquete configurado no FTD Joiner usando o ML-EID:
## FTD Commissioner ## ---------------------- > udp open Done > udp connect fdc0:de7a:b5c0:0:3e2e:66e:9d41:ebcd 1212 Done
A conexão UDP precisa estar ativa entre os dois nós. Enviar uma mensagem do comissário da FTD:
## FTD Commissioner ## ---------------------- > udp send hellothere Done
No FTD Joiner, a mensagem UDP foi recebida.
## FTD Joiner ## ---------------- > 10 bytes from fdc0:de7a:b5c0:0:0:ff:fe00:c00 49153 hellothere
14. Parabéns!
Você criou uma rede Thread física.
Agora você sabe:
- a diferença entre tipos, papéis e escopos de dispositivos Thread
- como os dispositivos Thread gerenciam os estados deles na rede
- como transmitir mensagens simples entre nós usando UDP;
Próximas etapas
Com base neste codelab, faça os exercícios a seguir:
- Refaça o flash da placa Joiner do FTD como um MTD usando o binário
ot-cli-mtd
e observe que ela nunca se atualiza para um roteador nem tenta se tornar o líder. - Adicione mais dispositivos (tente usar uma plataforma diferente!) à rede e desenhe a topologia usando tabelas filho e de roteador, além de pings para os endereços multicast.
- Use o pyspinel para controlar o NCP.
- Converta o NCP em um roteador de borda usando o OpenThread Border Router e conecte sua rede Thread à Internet.
Leitura adicional
Confira openthread.io e GitHub para conferir uma variedade de recursos do OpenThread, incluindo:
- Plataformas compatíveis: descubra todas as plataformas compatíveis com o OpenThread.
- Criar o OpenThread: mais detalhes sobre como criar e configurar o OpenThread
- Noções básicas de linhas de execução: abrange todos os conceitos de linhas de execução apresentados neste codelab.
Referência: