
Prova de conceito de rede mesh de IoT/Rádio Amador com roteamento global pela internet

Sistema de roteamento mesh que suporta o uso de um proxy OpenDHT como backend, para que os nós possam se comunicar diretamente pela internet. Pré-alfa muito inicial, prova de conceito, pode não funcionar de fato, etc.
Isso é destinado tanto para casos de uso de hobby/HAM quanto para trabalho de IoT mais típico ao consumidor/comercial, mas especificamente não tenta substituir a internet, nem cobrir grandes áreas de alto tráfego com antenas omnidirecionais.
Não possui roteamento de próximo salto no estilo Meshtastic, daí o nome LazyMesh. Se você quiser usá-lo para aplicações do tipo offgrid em uma área densa, provavelmente precisará de antenas direcionais e IDs de rota coordenados manualmente.
No momento, este é o único aplicativo real. Abra o sketch de exemplo Arduino, modifique-o com seu nome de usuário e uma chave de canal secreta que deve ser uma senha forte.
Digite sua mensagem no monitor serial do Arduino e você deverá conseguir conversar com todos os outros dispositivos.
As mensagens devem passar, desde que os nós estejam na mesma rede ou ambos tenham acesso à internet.
Visite o Cliente Web para conversar com o nó via MQTT pela internet. Basta definir um nome de usuário, adicionar um canal e inserir a senha do canal. O nome do canal pode ser qualquer coisa e afeta apenas a rotulagem na interface.
Você também pode experimentar o sketch de exemplo de dados de Leitura/Escrita. Ele expõe o ID de dados 195 como legível e o ID de dados 196 como legível e gravável. Vá ao site, insira os detalhes do seu canal e use a caixa de diálogo de solicitação de dados para solicitar o ID 196 de todos os dispositivos.
Em seguida, clique em "set" (definir) e altere para outro valor, e tente ler novamente.
O Cliente Web atualmente está codificado para usar test.mosquitto.org; isso mudará no futuro.
Os nós precisam de alguma forma de sincronizar o tempo para se comunicar. Atualmente, se nunca receberam tempo de uma fonte confiável, eles definirão seu tempo a partir de qualquer pacote aleatório que virem.
Isso pode ser um risco de segurança que permite ataques de repetição; portanto, dispositivos que precisam de segurança devem ter uma fonte de tempo confiável.
Uma vez que o tempo tenha sido definido inicialmente, o código ajustará o tempo do sistema em até 1 segundo por dia para permanecer sincronizado com outros nós; portanto, a dessincronização não deve ser um grande problema.
No Lazymesh, tudo é um canal; não há mensagens diretas. Se você quiser isso, basta criar um canal privado dedicado.
Os canais são definidos por uma senha; conhecer a senha permite acesso de leitura e escrita.
Existem 256 números de rota. Todo pacote possui um, e os repetidores só repetem se tiverem habilitado um número de rota correspondente. Por padrão, tudo é enviado com o número de rota 0, que está habilitado por padrão.
Isso afeta apenas os repetidores; os nós ouvirão qualquer número de rota mesh se for diretamente para eles.
Os payloads dos pacotes são arrays MessagePack. Eles alternam IDs de dados inteiros e itens de dados. 192-256 são reservados para mensagens específicas do aplicativo.
O ID 32 é para mensagens de texto, que podem ser prefixadas com um nome de usuário e dois-pontos.
O ID 2 é usado para um ID único, que deve ser um inteiro. Muitos aplicativos podem nem precisar disso.
Acrescente um byte de comprimento de metadados e N bytes de metadados.
Para criar o IV, pegue 12 bytes aleatórios para o IV. Em seguida, criptografe tudo. Prefixe o IV e acrescente 4 bytes de tag de autenticação.
Em seguida, pegue os primeiros 8 bytes do hash do ID de rota e converta para hexadecimal.
O tópico MQTT será lazymesh_route_HEX
Observe que usamos um tópico de nível superior. Isso para que você não possa usar curingas para assinar todos os canais lazymesh de uma vez em brokers públicos, o que permitiria um DoS em todos com bastante facilidade.
Apenas os pacotes brutos transmitidos em broadcast em 224.0.0.251:2221
Nada sobre isso está finalizado!!!
All numbers are little-endian.
1 byte header:
2 bit packet type(Either 1 or 2, depending on if we want ACK)
3 bits TTL hops remaining
1 bit allow slow transport(LoRa etc)
1 bit allow global routing
1 bit was already global routed
1 byte header 2:
1 bit first send attempt:
Whenever we create a or recieve a packet, set this bit. After trying to send it,
clear it. This way, as long as we assume packet loss is low-ish, we can count the repeaters in the area
without extra overhead.
1 bit repeater bit:
Marks that this packet should be included when counting repeaters.
Set it if you would repeat the packet or one like it, even if you originated it.
1 bit interest bit:
If this is set, the node who sent it is directly interested in the channel,
not purely just a repeater. If first send is also set, it is treated as an
implicit ack
1 bit location enabled
If this bit is set, repeaters may add location metadata to the packets forwarded to the internet. This metadata must be encrypted with the routing ID as the key,
meaning nearby people could track you for 1 hour after you get out of range.
Not implemented anywhere at the moment.
5 reserved 0 bits
1 byte mesh route number
1 byte path loss accumulated:
5 bits total
3 bits last hop
Every hop is a point of path loss,
plus whatever extra cost heuristic the transport applies.
1 extra point of loss should be roughly the same "badness" as
10dbm extra loss on wifi.
16 bytes routing ID:
Changes every hour, derived from the channel PSK by a hash.
The PSK is just the 16 byte SHA256 of the password.
The routing ID changes hourly, and is the SHA256 of:
The letter 'cr'
The count of hours since 1970 as a 32 bit unsigned int
the PSK
8 Bytes random entropy:
Used as part of the IV for the cipher
4 bytes timestamp:
Also part of the IV, also prevents replay attacks
N bytes ciphertext:
AES-GCM encrypted.
The encryption key changes hourly, and is the SHA256 of:
The letter 'c'
The count of hours since 1970 as a 32 bit unsigned int
the PSK
6 bytes auth tag:
The last 6 bytes are the GCM tag
Algumas implementações podem escolher ignorar isso completamente.
Os ACKs são puramente por salto, a menos que uma camada de protocolo superior queira fazer ACKs de ponta a ponta.
Pacotes ACK não são repetidos, roteados nem nada disso, e também não são autenticados. Cada etapa da repetição mesh tem seu próprio reconhecimento; da perspectiva do remetente original, é "disparar e esquecer".
Como o Meshtastic e a maioria dos outros, o protocolo é "semiconfiável"; há, como em todas as redes, casos extremos que causam falhas.