Files
mc-webui/docs/meshcore_bluetooth_pairing.md
MarekWo 1fdc2eda93 docs(ble): add troubleshooting section to pairing guide
bluetoothctl info auto-connects to trusted devices, stealing the
connection from Docker — document hcitool as safe alternative and
add connection loop recovery steps.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-03-29 14:07:21 +02:00

4.2 KiB

How to Pair MeshCore/Heltec Devices via Bluetooth on Linux

Pairing Bluetooth Low Energy (BLE) devices like Heltec (running MeshCore or Meshtastic) with a headless Linux server can sometimes be tricky due to security negotiations. Follow this guide to ensure a stable and successful connection for the mc-webui application.

Prerequisites: Device Preparation

Before touching the Linux terminal, you must configure your MeshCore device to use a fixed PIN. This prevents authentication timeouts and makes headless pairing much easier.

  1. Connect to your MeshCore device via the mobile app or web interface.
  2. Go to the Bluetooth Settings.
  3. Set the pairing mode to use a Fixed PIN (Passkey).
  4. Enter a memorable 6-digit PIN (e.g., 123456).
  5. Save the configuration and let the device reboot.

Step 1: Linux Server Preparation

Linux's default Bluetooth stack (BlueZ) needs to be optimized for Bluetooth Low Energy (BLE).

  1. Edit the main Bluetooth configuration file:
    sudo nano /etc/bluetooth/main.conf
    
  2. Find the [General] section and add or modify the following lines to force LE mode and speed up connections:
    ControllerMode = le
    FastConnectable = true
    
  3. Save the file and restart the Bluetooth service:
    sudo systemctl restart bluetooth
    

Note for Proxmox/VM Users: If you are passing a physical USB Bluetooth dongle to a Virtual Machine, do not use USB 3.0 passthrough. It causes packet drops and timeouts (Opcode failed errors). Always force USB 2.0. Example Proxmox command: qm set <VMID> -usb0 host=<VENDOR_ID>:<PRODUCT_ID>,usb3=0


Step 2: The Pairing Process

Use the built-in bluetoothctl tool to discover, pair, and trust your device.

  1. Open the Bluetooth control utility:
    bluetoothctl
    
  2. Enable the keyboard display agent (this tells Linux to ask you for the PIN):
    [bluetooth]# agent KeyboardDisplay
    [bluetooth]# default-agent
    
  3. Turn on the Bluetooth scan to find your device:
    [bluetooth]# scan le
    
  4. Wait until your device appears in the list and note its MAC address (e.g., AC:A7:04:08:66:A1 MeshCore-demo mc-webui).
  5. Initiate the pairing process using the MAC address:
    [bluetooth]# pair AC:A7:04:08:66:A1
    
  6. The terminal will prompt you for the passkey: [agent] Enter passkey (number in 0-999999): Enter the Fixed PIN you configured earlier (e.g., 123456) and press Enter.
  7. You should see Pairing successful.

Step 3: Trusting the Device

This is the most crucial step. You must "trust" the device so that mc-webui can automatically connect to it in the future without requiring the PIN again.

  1. In the bluetoothctl prompt, type:
    [bluetooth]# trust AC:A7:04:08:66:A1
    
  2. You should see trust succeeded.
  3. You can now safely exit the utility:
    [bluetooth]# exit
    

Your MeshCore device is now permanently paired, trusted, and ready to communicate with the mc-webui server!


Troubleshooting

Checking BLE Connection Status

Do NOT use bluetoothctl info <MAC> to check connection state — it auto-connects to trusted devices, which steals the connection from the mc-webui container.

Instead, use hcitool which only reads status without triggering a connection:

hcitool con

Expected output when connected:

Connections:
	< LE AC:A7:04:08:66:A1 handle 65 state 1 lm CENTRAL AUTH ENCRYPT

Container Can't Connect (connection loop)

If mc-webui is stuck in a "Failed to connect to device / Retrying..." loop:

  1. Check if something else holds the connection:
    hcitool con
    
  2. If a connection exists, disconnect it:
    bluetoothctl disconnect AC:A7:04:08:66:A1
    
  3. Restart the container:
    cd ~/mc-webui && docker compose restart mc-webui
    
  4. Verify (wait ~15s for retry):
    hcitool con
    curl -s http://localhost:5000/api/status | python3 -m json.tool
    

Only One BLE Client at a Time

A BLE peripheral can only be connected to one central at a time. If bluetoothctl, another app, or a mobile phone is connected, the container will fail. Always disconnect other clients before starting mc-webui.