6.7 KiB
Packet Capture Service
Captures packets from the MeshCore network and publishes them to MQTT brokers.
Quick Start
- Configure Bot - Edit
config.ini:
[PacketCapture]
enabled = true
# Owner info for JWT auth -- these are optional
owner_public_key = YOUR_COMPANION_PUBLIC_KEY_HERE
owner_email = your.email@example.com
# IATA code for topic routing
iata = LOC
# MQTT Broker (Let's Mesh Analyzer)
mqtt1_enabled = true
mqtt1_server = mqtt-us-v1.letsmesh.net
mqtt1_port = 443
mqtt1_transport = websockets
mqtt1_use_tls = true
mqtt1_use_auth_token = true
mqtt1_token_audience = mqtt-us-v1.letsmesh.net
mqtt1_topic_status = meshcore/{IATA}/{PUBLIC_KEY}/status
mqtt1_topic_packets = meshcore/{IATA}/{PUBLIC_KEY}/packets
- Restart Bot - The service starts automatically
Configuration
Basic Settings
[PacketCapture]
enabled = true # Enable packet capture
output_file = packets.json # Optional: save to file
verbose = false # Detailed packet logging
debug = false # Debug mode
Authentication
Option 1: On-Device Signing (Recommended)
auth_token_method = device # Use device's built-in signing
# No private key file needed
Option 2: Python Signing
auth_token_method = python # Use Python signing
private_key_path = /path/to/key.txt # Path to private key file
MQTT Brokers
Configure multiple brokers using mqttN_* pattern:
# Broker 1
mqtt1_enabled = true
mqtt1_server = mqtt-us-v1.letsmesh.net
mqtt1_port = 443
mqtt1_transport = websockets # tcp or websockets
mqtt1_use_tls = true
mqtt1_use_auth_token = true
mqtt1_topic_status = meshcore/{IATA}/{PUBLIC_KEY}/status
mqtt1_topic_packets = meshcore/{IATA}/{PUBLIC_KEY}/packets
# Broker 2
mqtt2_enabled = true
mqtt2_server = your.broker.com
mqtt2_port = 1883
mqtt2_transport = tcp
mqtt2_username = user
mqtt2_password = pass
Filtering by packet type
You can limit which packet types are uploaded to each broker with mqttN_upload_packet_types. Use a comma-separated list of type numbers; if unset or empty, all packet types are uploaded.
# Only upload text messages and adverts to this broker
mqtt1_upload_packet_types = 2, 4
# Broker 2 gets everything (default)
# mqtt2_upload_packet_types =
Packet type reference:
| Type | Name | Description |
|---|---|---|
| 0 | REQ | Request |
| 1 | RESPONSE | Response |
| 2 | TXT_MSG | Text message |
| 3 | ACK | Acknowledgment |
| 4 | ADVERT | Advertisement |
| 5 | GRP_TXT | Group text |
| 6 | GRP_DATA | Group data |
| 7 | ANON_REQ | Anonymous request |
| 8 | PATH | Path |
| 9 | TRACE | Trace |
| 10 | MULTIPART | Multipart |
| 11–15 | Type11–RAW_CUSTOM | Other types |
Packets that are excluded by this filter are still written to the output file (if configured) and still counted; they are only skipped for MQTT upload to that broker. Debug logs will show "Skipping" for those packets.
Topic Templates
Placeholders:
{IATA}- Your IATA code (e.g., SEA){iata}- Lowercase IATA code{PUBLIC_KEY}- Device public key (uppercase){public_key}- Device public key (lowercase)
Status Publishing
stats_in_status_enabled = true # Include device stats in status
stats_refresh_interval = 300 # Publish status every 5 minutes
jwt_renewal_interval = 86400 # Renew JWT every 24 hours
Packet Format
Packet Message
{
"origin": "MyBot",
"origin_id": "ABCD1234...",
"timestamp": "2026-01-04T12:34:56",
"type": "PACKET",
"direction": "rx",
"len": "42",
"packet_type": "2",
"route": "D",
"payload_len": "32",
"raw": "DEADBEEF...",
"SNR": "8.5",
"RSSI": "-42",
"hash": "ABC123..."
}
Status Message
{
"status": "online",
"timestamp": "2026-01-04T12:34:56",
"origin": "MyBot",
"origin_id": "ABCD1234...",
"model": "Heltec V3",
"firmware_version": "v3.1.2",
"radio": "915000000,250,9,8",
"client_version": "meshcore-bot/1.0.0",
"stats": {
"rx_packets": 1234,
"tx_packets": 567
}
}
Troubleshooting
Service Not Starting
Check logs:
tail -f meshcore_bot.log | grep PacketCapture
Common issues:
enabled = falsein config- Missing
paho-mqttlibrary:pip install paho-mqtt
MQTT Not Connecting
- Check broker settings - Verify hostname and port
- Test connection manually:
mosquitto_pub -h mqtt-us-v1.letsmesh.net -p 443 -t test -m "test" - Check authentication - Verify JWT token generation
- Check logs - Look for connection errors
No Packets Being Published
- Verify MQTT connection - Check logs for "Connected to MQTT broker"
- Check packet count - Service logs "Captured packet #N" (or "Skipping packet #N" when filtered) for each packet
- Verify topics - Ensure topics match broker expectations
- Check upload filter - If
mqttN_upload_packet_typesis set, only those types are uploaded. DEBUG Logs show "packet type X not in [Y, Z]" when a packet is skipped
Advanced
Multiple Brokers
Configure up to 10 brokers (mqtt1_* through mqtt10_*). Each broker has independent connection tracking and auto-reconnection.
Health Monitoring
health_check_interval = 30 # Check connection every 30s
health_check_grace_period = 2 # Allow 2 failures before warning
JWT Authentication
Tokens are valid for 24 hours and auto-renewed. The service tries on-device signing first (if auth_token_method = device), then falls back to Python signing.
Token Format:
{
"iat": 1234567890,
"exp": 1234654290,
"aud": "mqtt-us-v1.letsmesh.net",
"publicKey": "DEVICE_PUBLIC_KEY",
"owner": "OWNER_PUBLIC_KEY",
"email": "your@email.com",
"iata": "SEA"
}
FAQ
Q: Do I need to provide a private key?
A: Not if using on-device signing (auth_token_method = device). The service will fetch the key from your device automatically.
Q: Can I publish to my own MQTT broker?
A: Yes. Set mqtt1_use_auth_token = false and provide mqtt1_username and mqtt1_password.
Q: What's the difference between TCP and WebSockets? A: WebSockets work through firewalls better (uses HTTPS port 443). TCP is lighter but may be blocked.
Q: How do I disable packet capture but keep status publishing? A: You can't disable just packet capture - it's all or nothing. Consider filtering on the broker side.
Q: Can I capture TX (outgoing) packets? A: Currently only RX (incoming) packets are captured.