El puente MQTT de Meshtastic
Cómo conectar una malla a MQTT sin inundar a tus vecinos, el ajuste que silenciosamente frena tus paquetes, y las dos cosas que el firmware 2.8 rompió sin avisar.
Cada afirmación de abajo se verificó contra una malla real y el código fuente del firmware.
Contenido
- Qué es MQTT en realidad
- Proxy de cliente vs. gateway
- Uplink, downlink y por qué vienen apagados
- «OK to MQTT» — el asesino silencioso de paquetes
- Tópicos protobuf y JSON
- El firmware 2.8 rompe los DM a través de un gateway
- El firmware 2.8 casi duplica tu tiempo en el aire
- Qué se rompe de verdad entre versiones
- Lista de verificación
1. Qué es MQTT en realidad
MQTT es una oficina de correos para mensajes. Hay un servidor en el medio llamado broker. Cualquiera puede publicar un mensaje en una casilla con nombre —un tópico (topic)— y cualquier otro puede suscribirse a ese tópico y recibir todo lo que se deje en él.
Nada se conecta directamente con nada más. Ese es todo el modelo, y es la razón por la que MQTT le queda bien a Meshtastic: dos mallas separadas por cientos de kilómetros pueden intercambiar paquetes por internet en lugar de por radio, con un broker como punto de encuentro.
2. Proxy de cliente vs. gateway
Ambos aparecen bajo «MQTT» en la app. No son lo mismo, y aquí empieza casi toda la confusión.
Configurar el modo proxy de cliente
Esto es lo que quieres si tu objetivo es ver tus propios nodos en un mapa o alimentar un tablero. Es la configuración segura.
mqtt.enabled = true
mqtt.proxy_to_client_enabled = true
mqtt.address = tu.broker.ejemplo
# deja uplink_enabled / downlink_enabled APAGADOS en cada canal
Tu nodo igual se reporta al broker. No empieza a empujar el tráfico de todos los demás hacia internet.
Configurar el modo gateway
network.wifi_enabled = true
mqtt.enabled = true
mqtt.proxy_to_client_enabled = false
mqtt.tls_enabled = true
mqtt.root = msh/TU_REGION
Apagar proxy_to_client_enabled es el interruptor que dice «yo manejo mi propia
conexión». El nodo ahora habla con el broker haya o no un teléfono presente.
Ser gateway todavía no significa que estés puenteando nada. Por defecto el nodo publica solo sus propios paquetes y nada más. Retransmitir el tráfico de otros nodos es un ajuste aparte.
3. Uplink, downlink y por qué vienen apagados
Estas dos banderas se configuran por canal, en el gateway. Son las que de verdad unen dos mallas.
Por favor, no las enciendas por defecto
El downlink le cuesta tiempo en el aire a tus vecinos. Cada mensaje de la malla lejana se retransmite por tu RF local. En un preset lento, eso es tiempo de canal real que le quitas a todos a tu alrededor.
Tu lista de nodos se inunda de nodos distantes que nunca alcanzarás por radio —y publicas el tráfico de otras personas en un servidor que ellas nunca aceptaron.
Hay una buena razón para encenderlas: tienes dos mallas lejanas y quieres enlazarlas deliberadamente en un canal compartido. Si ese no es tu objetivo, deja ambas apagadas. Vienen apagadas por algo.
Si sí vas a puentear, activa uplink y downlink solo en el canal específico que estás compartiendo —no en tu canal primario, y no en todos.
4. «OK to MQTT» — el asesino silencioso de paquetes
Cada nodo lleva un ajuste llamado lora.config_ok_to_mqtt. Por defecto es false.
Cuando está en false, el nodo marca una bandera dentro de cada paquete que origina que significa «no me pongas en MQTT», y los gateways la respetan. Puedes tener el uplink activado, un broker sano y un gateway que te escucha perfectamente —y tus mensajes aún así nunca se publicarán.
meshtastic --port COM11 --set lora.config_ok_to_mqtt true
# luego confirma que quedó
meshtastic --port COM11 --info | grep configOkToMqtt
En la app está bajo LoRa → Avanzado; el texto cambia entre versiones, así que busca «OK to MQTT» o «MQTT OK». Vuelve a leerlo después de configurarlo, y revísalo otra vez tras una actualización de firmware —a mí se me revirtió a mitad de sesión y perdí veinte minutos echándole la culpa al gateway.
Si recuerdas una sola cosa
«Veo sus mensajes pero ellos no ven los míos» es casi siempre esta bandera —no un desajuste de firmware, no un problema del broker. Revísala primero.
5. Tópicos protobuf y JSON
Bajo tu tópico raíz hay dos ramas, y saber cuál estás mirando explica la mayoría de los reportes de «mi tablero no muestra nada».
Protobuf es el valor por defecto y casi siempre la opción correcta: compacto, cifrado de extremo a extremo, y legible por toda herramienta de Meshtastic. JSON es cómodo para Node-RED o Home Assistant porque no hay que decodificar nada —pero producirlo obliga al gateway a descifrar primero, así que tu texto plano termina en el broker.
En un canal privado
Deja json_enabled apagado. Encenderlo publica exactamente lo que tu PSK de canal
estaba protegiendo. Si quieres datos legibles, suscríbete al tópico protobuf y descífralo
localmente —tú tienes la llave, el broker no la necesita.
6. El firmware 2.8 rompe los DM a través de un gateway
Los mensajes directos van cifrados de extremo a extremo entre dos nodos. Un gateway que transporta el DM de otra persona genuinamente no puede leerlo —el mensaje no está dirigido al gateway.
En 2.7 esto no importaba. El gateway reenviaba el bloque cifrado a MQTT sin leerlo, y el otro extremo lo descifraba. Así cruzaban los DM un puente.
En 2.8 un paquete que el gateway no puede descifrar se clasifica como opaco (opaque), y el tráfico opaco se excluye deliberadamente de MQTT.
El firmware declara la intención sin rodeos, en NextHopRouter.cpp:
// Opaque traffic is never admitted to PacketHistory, NodeDB,
// modules, phone, MQTT, or ACK handling.
Introducido por el PR #10967,
«feat(security): enforce packet authenticity policies». Ningún ajuste de configuración lo
sortea —la opción packet_signature_policy gobierna cómo se reciben los
paquetes y solo aplica al tráfico que el nodo ya puede descifrar. Compatible, Balanced y
Strict toman todos el mismo camino opaco.
Efecto práctico
En 2.8 no puedes mandar un DM a alguien a través de un puente MQTT. Los mensajes de canal siguen funcionando. Los DM al propio gateway siguen funcionando. Un DM que pasa a través, dirigido a un tercer nodo, muere en el gateway sin ningún error en ninguna parte.
Si los DM puenteados te importan, v2.7.26 es el último lanzamiento sin este
comportamiento.
7. El firmware 2.8 casi duplica tu tiempo en el aire
El mismo PR agregó una firma XEdDSA a cada transmisión (broadcast): 64 bytes, más dos bytes de sobrecarga de protobuf, en cada paquete sin importar el largo del mensaje.
La firma solo está condicionada por !pki_encrypted && isBroadcast(to) —no
hay ajuste en tiempo de ejecución. Desactivarla significa una compilación personalizada con
MESHTASTIC_EXCLUDE_XEDDSA. En un canal concurrido, esto conviene saberlo antes de
actualizar una flota.
8. Qué se rompe de verdad entre versiones
Circula la afirmación de que los nodos 2.7 no pueden recibir de nodos 2.8. Yo me la creí,
luego revisé el código fuente —no es cierto. Protobuf está hecho para esto: nanopb llega al
campo de firma desconocido, lo salta y sigue (pb_decode.c, «No match found, skip
data»).
| Escenario | ¿Funciona? | Por qué |
|---|---|---|
| Nodo 2.8 recibe de 2.7 | Sí | Nada raro en el paquete |
| Nodo 2.7 recibe de 2.8 | Sí | El campo de firma desconocido se salta |
| 2.8 recibe de < 2.5.0 | No | Descarte pre-hop; esos paquetes no llevan datos de saltos |
| DM a través de un gateway 2.8 | No | El tráfico opaco se excluye de MQTT |
| Paquete sin firmar de un firmante conocido, bajo Balanced/Strict | No | Se trata como intento de downgrade |
Cualquier nodo sin ok_to_mqtt | No | El gateway respeta la bandera y lo descarta |
Si tu síntoma es «ellos me ven pero yo no los veo», o al revés, la causa abrumadoramente
probable es la bandera ok_to_mqtt o un canal con el uplink desactivado —no un
desajuste de versión.
9. Lista de verificación
- ¿Estás en modo proxy o gateway? Confirma que
proxy_to_client_enabledcoincide con tu intención. - ¿Está
uplink_enabledactivado para el canal específico que estás probando —no solo el primario? - ¿Está
lora.config_ok_to_mqtten true en el nodo que envía? Vuelve a leerlo. - ¿Acabas de cambiar downlink? Reinicia el gateway. Las suscripciones se construyen solo cuando la sesión MQTT se conecta, así que publicar funcionará mientras que recibir, en silencio, nunca lo hará.
- ¿Estás mirando el tópico correcto? El protobuf cae bajo
/2/e/; la rama/2/json/está vacía a menos quejson_enabledesté encendido. - ¿Esperas que un DM cruce el puente? En 2.8 no lo hará. Usa un mensaje de canal, o corre 2.7.26.
- ¿Sigues atascado? Suscríbete tú mismo a
msh/#y observa. Si aparecen los paquetes de tu propio gateway pero no los retransmitidos, es la bandera del paso 3.
Sobre esta guía
Se agradecen correcciones. Las referencias de firmware son a b68de08 (2.8.0) y
v2.7.26.54e0d8d; las cifras de tiempo en el aire están calculadas para
SF11 / BW250 / CR4-5 y variarán en otros presets.