A Bluetooth Low Energy (BLE) interface for [Reticulum Network Stack](https://reticulum.network), enabling mesh networking over BLE without additional hardware on Linux devices.
**⚠️ Platform**: Linux-only (requires BlueZ 5.x for GATT server functionality)
**✅ Tested on**: Raspberry Pi Zero W
## Features
- **Zero dongle requirements**: Works with built-in BLE radios (Raspberry Pi, Linux laptops, etc.)
- **Auto-discovery**: Automatically finds and connects to nearby Reticulum BLE nodes
- **Multi-peer mesh**: Supports up to 7 simultaneous connections for mesh networking (may support more, untested)
- **Dual mode operation**: Acts as both central (scanner/client) and peripheral (advertiser/server)
- **Connection prioritization**: RSSI-based smart peer selection with connection history tracking
- **Packet fragmentation**: Handles BLE MTU limitations (20-512 bytes) transparently
- **Power management**: Three power modes (aggressive/balanced/saver) for battery efficiency or CPU limitations. Saver mode tested on Raspberry Pi Zero W.
5. ✓ Enable BlueZ experimental mode (required for proper BLE connectivity)
6. ✓ Optionally set up Bluetooth permissions
**BlueZ Experimental Mode**: The installer automatically enables BlueZ experimental mode, which is required for proper BLE connectivity. This allows the BLE interface to use LE-specific connection methods instead of defaulting to Classic Bluetooth (BR/EDR), preventing connection errors like "br-connection-profile-unavailable".
**Pi Zero W Optimization**: The installer automatically detects Raspberry Pi Zero W (32-bit ARM with Python 3.13) and downloads pre-built wheels for packages with C extensions. This saves ~20 minutes of compilation time compared to building from source. See [Pre-built Wheels](#pre-built-wheels-for-raspberry-pi-zero-w) for details.
**Note for Arch users:** PyGObject is intentionally NOT installed as a system package on Arch due to version incompatibility (Arch has 3.54.5, but bluezero requires <3.52.0). Instead, pip will compile the compatible PyGObject version (3.50.2) during installation. This adds ~2 minutes to installation time but ensures compatibility.
**Note:** The system packages (python3-gi, python3-dbus, python3-cairo) provide PyGObject, dbus-python, and pycairo, eliminating the need for lengthy compilation from source.
BlueZ experimental mode is required for proper BLE connectivity. Without it, BlueZ may attempt Classic Bluetooth (BR/EDR) connections instead of BLE (LE) connections, causing connection failures.
### Option C: pipx Installation (RNS installed via pipx)
If you installed Reticulum via `pipx install rns`, the BLE interface requires additional setup because pipx creates isolated virtual environments that cannot access system-installed packages.
**Note:** The automated installation script (Option A: `./install.sh`) now detects and handles pipx installations automatically. The instructions below are for manual installation or troubleshooting.
**Enable JustWorksRepairing for Automatic Pairing:**
Edit `/etc/bluetooth/main.conf` and add to the `[General]` section:
```ini
[General]
JustWorksRepairing = always
```
This enables automatic pairing for peer-initiated connections, which is required for zero-touch mesh networking. Reticulum provides its own cryptographic security on top of the BLE transport.
**Custom Config Directory**: If you use a custom Reticulum config directory with `--config`, the BLE interface will automatically use that directory to find its companion modules. No additional configuration needed!
The BLE interface supports extensive configuration options. See [`examples/config_example.toml`](examples/config_example.toml) for a fully documented example with all available options.
- If logs show "Operation already in progress" errors, this is handled automatically in v2.2.1+ with connection state tracking and rate limiting (see [BLE_PROTOCOL_v2.2.md](BLE_PROTOCOL_v2.2.md) § Troubleshooting for details)
These errors occur when BlueZ attempts Classic Bluetooth (BR/EDR) connections instead of BLE (LE) connections. This is the most common BLE connection issue.
Enable BlueZ experimental mode (see Installation → Manual Installation → step 4). If you used the automated installer, re-run it without `--skip-experimental`.
### BLE pairing failures / "JustWorksRepairing: never" warning
The BLE interface logs a warning that BlueZ's JustWorksRepairing is set to "never", which may cause pairing failures in the mesh network.
**Symptoms:**
- Warning: `BlueZ JustWorksRepairing: never (default - may cause pairing failures)`
- Recommendation message: `Set JustWorksRepairing=always in /etc/bluetooth/main.conf`
- Intermittent connection failures with peer devices
- Pairing requests rejected by BlueZ
**Cause:**
BlueZ's default `JustWorksRepairing` setting is "never", which blocks automatic pairing for peer-initiated connections. This breaks zero-touch mesh networking.
**Solution:**
Enable JustWorksRepairing in BlueZ configuration (see Installation → Manual Installation → step 5). If you used the automated installer, this is configured automatically. To verify or fix manually:
```bash
# Edit BlueZ configuration
sudo nano /etc/bluetooth/main.conf
# Add to [General] section:
JustWorksRepairing = always
# Restart Bluetooth service
sudo systemctl restart bluetooth
# Verify the setting
grep JustWorksRepairing /etc/bluetooth/main.conf
```
**Note:** Just Works pairing provides unauthenticated BLE encryption. This is acceptable because Reticulum provides its own cryptographic security on top of the BLE transport layer.
### pipx: ModuleNotFoundError for dbus, gi, or bluezero
If you installed RNS via pipx and get import errors like `ModuleNotFoundError: No module named 'dbus'`, `No module named 'gi'`, or `No module named 'bluezero'`:
**Cause:** pipx creates isolated environments that don't access system packages.
**Solution:** Follow the [pipx installation instructions](#option-c-pipx-installation-rns-installed-via-pipx) to inject the required dependencies:
```bash
pipx inject rns bleak==1.1.1 bluezero dbus-python
```
**Verification:** Test if the modules are accessible:
To speed up installation on 32-bit ARM devices (Raspberry Pi Zero W, Pi 1, Pi 2), we provide pre-built wheels for packages with C extensions that would otherwise require lengthy compilation from source.
### Automatic Installation
The `install.sh` script **automatically detects** 32-bit ARM architecture with Python 3.13 and downloads pre-built wheels from [GitHub Releases](https://github.com/torlando-tech/ble-reticulum/releases/tag/armv6l-wheels-v1).
**Time savings:** ~20 minutes on Pi Zero W (avoids compiling C extensions)
# The wheel will be saved in the current directory
# You can then share it or install it on other devices
```
### Why Pre-built Wheels?
Python packages with C extensions (like `dbus_fast`) must be compiled from source when installing via pip if no compatible wheel is available on PyPI. On low-powered devices like the Pi Zero W:
- **Without pre-built wheel:** 15-30 minutes of compilation
- **With pre-built wheel:** < 10 seconds download and install
The automated installer makes this transparent - it "just works" faster on supported platforms.