MeshCore Packet Capture (Companion Node Listener)¶
Purpose:
This guide explains how to install and run MeshCore Packet Capture on a Debian-based system (Raspberry Pi OS, Ubuntu, etc.) to stream packets from a dedicated MeshCore companion node to the MeshCore Packet Analyzer.
Scope:
This setup covers packet capture from companion nodes only.
Packet capture for repeaters and room servers is supported by MeshCore but not yet documented here.
Requirements¶
- A Debian-based OS (Raspberry Pi OS, Ubuntu, etc.)
- A dedicated MeshCore companion node connected via USB or TCP
- Internet access for forwarding packet data
Companion Configuration¶
- Before installation, ensure your companion node is named using the Ottawa MeshCore naming standard:
YOW_<LOCATION>
Examples:
YOW_BarrhavenYOW_CentretownYOW_Orleans
This ensures the Packet Analyzer correctly identifies which area each listener represents.
Packet Capture system configuration¶
1. Install Dependencies¶
sudo apt update
sudo apt install -y python3 curl git
sudo apt install -y python3.12-venv
2. Install the MeshCore Decoder (Required for Auth)¶
meshcore-decoder is required for authentication when sending packets to the Analyzer.
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
source ~/.bashrc
nvm install --lts
npm install -g @michaelhart/meshcore-decoder
3. Verify installation¶
which meshcore-decoder
4. Run the Packet Capture Installer¶
bash <(curl -fsSL https://raw.githubusercontent.com/agessaman/meshcore-packet-capture/main/install.sh)
5. During installation, you will select your connection method¶
1) Bluetooth Low Energy (BLE)
- Recommended for T1000
- Wireless
- Works with MeshCore T1000e and compatible devices
2) Serial Connection
- For USB/serial devices
- Most reliable for 24/7 capture
3) TCP Connection
- Works with ser2net or other serial-over-TCP bridges
- Useful for remote nodes
Example Installer Output¶
Below is an example of a successful installation:
═══════════════════════════════════════════════════
MeshCore Packet Capture Installer v1.1.1
═══════════════════════════════════════════════════
Installation directory [/home/user/.meshcore-packet-capture]:
ℹ Installation directory: /home/user/.meshcore-packet-capture
═══════════════════════════════════════════════════
Installing Files
═══════════════════════════════════════════════════
✓ Files downloaded and verified
═══════════════════════════════════════════════════
Checking Dependencies
═══════════════════════════════════════════════════
✓ Python 3 found: Python 3.12.3
✓ Virtual environment created
✓ Python dependencies installed
✓ meshcore-decoder found: /home/user/.nvm/versions/node/v24.11.0/bin/meshcore-decoder
═══════════════════════════════════════════════════
Device Connection Configuration
═══════════════════════════════════════════════════
Select connection type [1-3] [1]: 3
ℹ Selected: TCP Connection
TCP host/address [localhost]: 192.168.1.201
TCP port [5000]:
✓ TCP connection configured: 192.168.1.201:5000
Enter your IATA code (3 letters): YOW
✓ IATA code set to: YOW
═══════════════════════════════════════════════════
MQTT Broker Configuration
═══════════════════════════════════════════════════
Enable the MeshCore Packet Analyzer (US + EU servers) for redundancy? [Y/n]: Y
✓ MeshCore Packet Analyzer brokers enabled
═══════════════════════════════════════════════════
Installation Method
═══════════════════════════════════════════════════
Choose installation method [1-3] [1]: 1
ℹ Installing systemd service...
✓ Service enabled
✓ Systemd service installed
═══════════════════════════════════════════════════
Installation Complete!
═══════════════════════════════════════════════════
Installation directory: /home/user/.meshcore-packet-capture
Configuration file: /home/user/.meshcore-packet-capture/.env.local
✓ Installation complete!
If you see:
✗ Service failed to start
It usually means the companion node wasn’t reachable.
Fix the connection and restart the service:
sudo systemctl restart meshcore-capture
Managing the System Service¶
sudo systemctl start meshcore-capture
sudo systemctl stop meshcore-capture
sudo systemctl status meshcore-capture
sudo journalctl -u meshcore-capture -f
If it fails to start, confirm:
- The companion node is powered and reachable
- TCP/Serial settings in:
/home/<user>/.meshcore-packet-capture/.env.local
Verifying Connection¶
Open:
https://analyzer.letsme.sh/status/observers
Use the All Regions dropdown and select YOW.
If your listener appears and shows green status, it is forwarding packets correctly.
Logs and Troubleshooting¶
View live logs:
sudo journalctl -u meshcore-capture -f
Common Issues¶
- Connection refused: TCP host/port incorrect
meshcore-decodernot found: Re-run installation from Step 2- No packets: Ensure node is on correct channel/frequency
Next Steps¶
Future documentation will include:
- Packet capture for repeaters
- Packet capture for room servers
Example Configuration (.env.local)¶
# MeshCore Packet Capture Configuration
# Local overrides to .env defaults
PACKETCAPTURE_UPDATE_REPO=agessaman/meshcore-packet-capture
PACKETCAPTURE_UPDATE_BRANCH=main
PACKETCAPTURE_CONNECTION_TYPE=tcp
PACKETCAPTURE_ADVERT_INTERVAL_HOURS=24
PACKETCAPTURE_TCP_HOST=192.168.1.201
PACKETCAPTURE_TCP_PORT=5000
PACKETCAPTURE_IATA=YOW
PACKETCAPTURE_ADVERT_INTERVAL_HOURS=11
PACKETCAPTURE_LOG_LEVEL=INFO
# MQTT Broker 1 (US)
PACKETCAPTURE_MQTT1_ENABLED=true
PACKETCAPTURE_MQTT1_SERVER=mqtt-us-v1.letsmesh.net
PACKETCAPTURE_MQTT1_PORT=443
PACKETCAPTURE_MQTT1_TRANSPORT=websockets
PACKETCAPTURE_MQTT1_USE_TLS=true
PACKETCAPTURE_MQTT1_USE_AUTH_TOKEN=true
PACKETCAPTURE_MQTT1_TOKEN_AUDIENCE=mqtt-us-v1.letsmesh.net
PACKETCAPTURE_MQTT1_KEEPALIVE=120
# MQTT Broker 2 (EU)
PACKETCAPTURE_MQTT2_ENABLED=true
PACKETCAPTURE_MQTT2_SERVER=mqtt-eu-v1.letsmesh.net
PACKETCAPTURE_MQTT2_PORT=443
PACKETCAPTURE_MQTT2_TRANSPORT=websockets
PACKETCAPTURE_MQTT2_USE_TLS=true
PACKETCAPTURE_MQTT2_USE_AUTH_TOKEN=true
PACKETCAPTURE_MQTT2_TOKEN_AUDIENCE=mqtt-eu-v1.letsmesh.net
PACKETCAPTURE_MQTT2_KEEPALIVE=120
# Topic format
PACKETCAPTURE_MQTT1_TOPIC_STATUS=meshcore/{IATA}/{PUBLIC_KEY}/status
PACKETCAPTURE_MQTT1_TOPIC_PACKETS=meshcore/{IATA}/{PUBLIC_KEY}/packets