2026-06-03 12:21:01 +08:00
2026-06-03 00:04:05 +08:00
2026-06-03 12:17:03 +08:00
up
2026-06-03 12:19:59 +08:00
up
2026-06-03 12:21:01 +08:00
2026-06-03 12:17:03 +08:00
2026-06-03 11:52:55 +08:00
2026-06-03 11:52:55 +08:00
2026-06-03 11:52:55 +08:00
2026-06-03 11:52:55 +08:00

Meshtastic MQTT Server

本程序启动一个本地 MQTT broker,并在转发客户端发布的消息前校验 Meshtastic MQTT payload。

每条传入的 PUBLISH 都会先进入:

valid, _, record := mqtpp.MQTTPP(topic, payload, key)
  • valid == true:保留原始 topic、payload、QoS、retain 等字段,正常转发给订阅匹配 topic 的客户端
  • valid == false:丢弃该消息,不转发给订阅客户端

当前不桥接到 mqtt.meshtastic.org 等上游 broker。

运行

go run .

默认监听:

  • host0.0.0.0
  • port1883
  • PSKAQ==

也可以指定监听地址和 PSK

go run . --host 127.0.0.1 --port 1883 --psk AQ==

参数

--host  MQTT broker listen host
--port  MQTT broker listen port
--psk   Base64 channel PSK used to try decrypting encrypted packets

转发规则

程序监听所有传入 publish。payload 能被 mqtpp.MQTTPP 解析时,认为 valid == truebroker 会继续把原始 MQTT 消息转发给订阅者;解析失败时,认为 valid == falsebroker 会拒绝并丢弃该 publish。

empty_packet 仍然属于 valid == true,会被转发;只是控制台默认不显示它。

无法解密但能解析的加密包通常会输出为 encrypted_packet,仍然属于 valid == true,因此会被转发。

本地验证

一个终端启动 broker

go run . --host 127.0.0.1 --port 1883 --psk AQ==

另一个终端订阅:

mosquitto_sub -h 127.0.0.1 -p 1883 -t '#'

发布非法 payload

mosquitto_pub -h 127.0.0.1 -p 1883 -t 'msh/US/test' -m 'not protobuf'

订阅端应该收不到该消息。

要验证 valid 消息转发,请使用真实 Meshtastic MQTT payload 发布到本 broker;订阅匹配 topic 的客户端应收到原始消息,broker 控制台会打印解析后的 record

控制台颜色说明

程序会按数据包类型使用不同背景色,方便快速区分消息类型。

背景色 type portnum 含义
绿色 nodeinfo NODEINFO_APP 节点信息包,包含节点 ID、长名称、短名称、硬件型号、角色、公钥等
蓝色 map_report MAP_REPORT_APP 地图报告包,包含节点名称、硬件、固件版本、区域、调制预设、位置等地图信息
紫色 text_message TEXT_MESSAGE_APP 聊天文本消息
青色 position POSITION_APP 位置包,会展开解析经纬度、海拔、时间、定位来源、精度、速度、卫星数等字段
黄色 telemetry TELEMETRY_APP 遥测包,会展开解析设备、电源、环境、空气质量、本地统计、健康、主机和流量管理指标
灰色 routing ROUTING_APP 路由控制包,常见于 ACK、NAK、路由错误等控制信息
灰色 traceroute TRACEROUTE_APP 路径追踪包,用于 mesh 网络路径探测
红色 error record - protobuf 解析失败、payload 解码失败或其他处理错误
无颜色 encrypted_packet - 加密包但当前 PSK/频道 hash 无法解密;这不一定是错误
无颜色 decoded_packet 其他 portnum 已解码/已解密,但程序尚未细分的其他应用包

已展开解析的数据包

position / POSITION_APP

位置包会从 Meshtastic Position payload 中展开常用字段,包括:

  • latitude / longitude:经纬度,已从 latitude_i / longitude_i 转换为浮点角度
  • altitude:海拔,单位米
  • time / timestamp:位置相关时间戳
  • location_source:定位来源,例如 LOC_MANUALLOC_INTERNALLOC_EXTERNAL
  • altitude_source:海拔来源,例如 ALT_MANUALALT_INTERNALALT_BAROMETRIC
  • altitude_hae / altitude_geoidal_separationHAE 海拔和大地水准面分离值
  • pdop / hdop / vdop:定位精度因子,已从 1/100 单位转换为浮点值
  • gps_accuracyGPS 精度,单位 mm
  • ground_speed:地面速度,单位 m/s
  • ground_track:地面航迹角,已从 1/100 度转换为度
  • fix_quality / fix_type / sats_in_view:GPS fix 质量、类型和可见卫星数
  • sensor_id / next_update / seq_number / precision_bits:传感器、更新间隔、序列号和位置精度位数

telemetry / TELEMETRY_APP

遥测包会输出:

  • time:遥测时间戳
  • telemetry_type:具体 telemetry variant
  • metrics:展开后的指标对象

当前支持的 telemetry_type

telemetry_type 含义 常见 metrics
device_metrics 设备状态 battery_levelvoltagechannel_utilizationair_util_txuptime_seconds
environment_metrics 环境传感器 temperaturerelative_humiditybarometric_pressuregas_resistanceluxwind_speedrainfall_1h
air_quality_metrics 空气质量 pm25_standardpm100_standardco2pm_temperaturepm_humiditypm_voc_idx
power_metrics 多通道电源数据 ch1_voltagech1_currentch8_voltagech8_current
local_stats 本地 mesh 统计 num_packets_txnum_packets_rxnum_online_nodesheap_free_bytesnoise_floor
health_metrics 健康数据 heart_bpmspO2temperature
host_metrics Linux/Portduino 主机指标 uptime_secondsfreemem_bytesdiskfree1_bytesload1load5load15user_string
traffic_management_stats 流量管理统计 packets_inspectedposition_dedup_dropsrate_limit_dropsunknown_packet_drops

过滤规则

程序默认不显示 empty_packet

empty_packetMeshPacket 中没有 decodedencrypted payload 的包,只包含类似 fromtoidvia_mqtt 等包头信息。根据固件源码分析,这类包通常不是普通业务数据,更多是 MQTT 回显/隐式 ACK 相关的元信息,对查看节点信息、地图报告和聊天内容价值较低。

输出示例

节点信息包:

{"type":"nodeinfo","portnum":"NODEINFO_APP","from":"!a8dfd867","long_name":"Kabi Matrix 🖥️","short_name":"KaMX","hw_model":"PRIVATE_HW","role":"CLIENT_MUTE"}

地图报告包:

{"type":"map_report","portnum":"MAP_REPORT_APP","from":"!675c9803","long_name":"PaulHome","latitude":42.51043,"longitude":-83.08624999999999,"hw_model":"PORTDUINO"}

聊天消息包:

{"type":"text_message","portnum":"TEXT_MESSAGE_APP","from":"!12345678","text":"hello mesh"}

位置包:

{"type":"position","portnum":"POSITION_APP","from":"!12345678","latitude":42.51043,"longitude":-83.08625,"altitude":192,"location_source":"LOC_INTERNAL","sats_in_view":8}

遥测包:

{"type":"telemetry","portnum":"TELEMETRY_APP","from":"!12345678","telemetry_type":"device_metrics","metrics":{"battery_level":85,"voltage":4.1,"channel_utilization":2.3,"air_util_tx":0.5,"uptime_seconds":12345}}

解密失败的加密包:

{"type":"encrypted_packet","decrypt_success":false,"decrypt_status":"channel hash mismatch","encrypted_len":43}
S
Description
No description provided
Readme MIT
841 KiB
Languages
Go 58%
Vue 31.8%
TypeScript 4%
CSS 3.7%
Python 2%
Other 0.4%