Remove GitHub workflow documentation as it was specific to personal infrastructure setup and not relevant for general users of the BLE interface.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Host pre-built dbus_fast wheel on GitHub Releases to significantly speed
up installation on 32-bit ARM devices like Raspberry Pi Zero W.
Changes:
- Created GitHub Release (armv6l-wheels-v1) with dbus_fast 2.44.5 wheel
- Python 3.13 on ARMv6l architecture
- 874KB wheel file saves ~20 minutes of compilation on Pi Zero W
- Release URL: https://github.com/torlando-tech/ble-reticulum/releases/tag/armv6l-wheels-v1
- Modified install.sh to auto-download pre-built wheels:
- Detects Python 3.13 on 32-bit ARM (armhf/armv6l/armv7l)
- Downloads dbus_fast wheel from GitHub Releases
- Falls back gracefully to source build if download fails
- Saves ~20 minutes installation time on Pi Zero W
- Updated README.md with comprehensive documentation:
- Added "Pre-built Wheels for Raspberry Pi Zero W" section
- Documented automatic installation behavior
- Provided manual installation instructions
- Explained why pre-built wheels matter for low-power devices
- Added quick reference in automated installation section
Time savings on Pi Zero W:
- Before: 15-30 minutes (compile dbus_fast C extensions from source)
- After: < 10 seconds (download and install pre-built wheel)
The installer now transparently optimizes for Pi Zero W while maintaining
compatibility with all other platforms.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Implements comprehensive connection state tracking to prevent "Operation
already in progress" errors and connection retry storms.
BLE Interface changes:
- Record connection attempts before calling driver.connect()
- Add 5-second rate limiting between attempts to same peer
- Skip connections already in progress via _connecting_peers check
- Downgrade expected race conditions to DEBUG level
- Auto-blacklist MAC addresses on connection failures
- Add diagnostic logging for concurrent connection tracking
BLE Driver changes:
- Add _connecting_peers set to track in-progress connections
- Prevent concurrent connection attempts to same address
- Attach cleanup callbacks to connection Futures
- Add defense-in-depth cleanup in finally blocks
- Detailed logging for connection state debugging
Documentation updates:
- Add deployment workflow documentation to README.md
- Update .github/workflows/README.md with CD workflow details
- Document containerized runner SSH configuration
- Update reference documentation (CLAUDE.md, BLE_PROTOCOL, etc.)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixes "Failed to register advertisement" error (BlueZ error 0x03) caused by
device name exceeding 31-byte BLE advertisement packet limit.
Changes:
- Make device_name optional (default: None) to save advertisement space
- Remove auto-generation of long identity-based names (RNS-{32-hex-identity})
- Update driver to handle None device names when creating peripheral
- Use full 16-byte identity (32 hex chars) for fragmenter keys to avoid collisions
- Update documentation to reflect device name is optional and discovery is UUID-based
Discovery is based on service UUID matching only. Identity is obtained from
the Identity GATT characteristic after connection, not from device name.
Tested on Raspberry Pi Zero W with BlueZ 5.82 - advertisement now registers
successfully (ActiveInstances: 1).
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Addresses the common "Not Powered" error where Bluetooth adapters are
powered off, preventing BLE operations. This issue is particularly common
on Raspberry Pi after boot or system updates.
Changes:
1. README.md - Added comprehensive troubleshooting section
- New section: "Bluetooth adapter not powered"
- Documented symptoms, causes, and 4 solution methods
- Instructions for automatic power-on at boot
- Cross-referenced from other sections
2. BLEInterface.py - Enhanced error handling in _discover_peers()
- Detect "Not Powered" errors specifically
- Show clear, actionable error messages instead of stack traces
- Provide direct solution commands
- Link to troubleshooting documentation
- Gracefully handle error without crashing
3. install.sh - Automatic power state checking
- New "Step 5B: Bluetooth Adapter Power State" section
- Check if adapter is powered using `bluetoothctl show`
- Automatically power on adapter if needed
- Verify operation succeeded
- Provide troubleshooting steps if power-on fails
- Check for rfkill blocks
4. examples/bluetooth-power-on.service - New systemd service
- Ensures Bluetooth is powered on at boot
- Optional but recommended for production
- Includes installation instructions in README
5. examples/config_example.toml - Added troubleshooting entry #7
- Documents power state issue in config comments
- Cross-references systemd service example
- Notes that installer (v1.x+) handles this automatically
Impact:
- Users get clear guidance instead of cryptic stack traces
- Installer automatically fixes the issue during setup
- Reduces support burden for common power state errors
- Enables automatic recovery at boot via systemd service
Fixes: "Not Powered" / "No powered Bluetooth adapters found" errors
Tested on: Raspberry Pi Zero 2 W with Raspberry Pi OS Lite 64-bit
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Fixes#3
BlueZ experimental mode is required for proper BLE connectivity. Without it,
BlueZ attempts Classic Bluetooth (BR/EDR) connections instead of BLE (LE)
connections, causing connection errors like "br-connection-profile-unavailable"
and immediate disconnections after pairing.
Changes:
- install.sh: Automatically enables BlueZ experimental mode during installation
- Detects BlueZ version (requires >= 5.49)
- Creates systemd override to add -E flag to bluetoothd
- Checks if already enabled to avoid duplicate configuration
- Shows strong warning if user skips with --skip-experimental flag
- Added --skip-experimental flag to opt-out (not recommended)
- Updated help text to document new flag
- tests/test_installer.sh: Added tests for experimental mode configuration
- README.md: Documented BlueZ experimental mode in installation sections
- Added to automated installation description
- Added as required step in manual installation
- Added troubleshooting section for BR/EDR connection errors
- examples/config_example.toml: Added troubleshooting entry for BR/EDR errors
The installer now:
1. Detects BlueZ version >= 5.49 (required for experimental mode)
2. Checks if already enabled (graceful skip)
3. Enables experimental mode by default unless --skip-experimental is used
4. Shows prominent warning if skipped (may cause BLE to break)
5. Handles edge cases (no systemd, old BlueZ, container environments)
This addresses the root cause reported in issue #3 where devices were
connecting then immediately disconnecting with BR/EDR profile errors.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
PyGObject compilation on Arch requires gobject-introspection package
which provides the development files and .pc files needed by meson.
Error was: Dependency 'gobject-introspection-1.0' is required but not found.
Changes:
- install.sh: Add gobject-introspection to Arch system dependencies
- install.sh: Add comment explaining it's needed for PyGObject compilation
- README.md: Document gobject-introspection requirement for Arch
This completes the Arch Linux dependency chain for PyGObject compilation.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Arch Linux has PyGObject 3.54.5 in python-gobject package, but bluezero
requires PyGObject <3.52.0, causing pip to fail when trying to replace
the system version.
Solution: Don't install python-gobject system package on Arch. Let pip
compile the compatible PyGObject version (3.50.2) instead.
Changes:
- install.sh: Remove python-gobject from Arch pacman install
- install.sh: Add explanatory warning about PyGObject compilation
- tests/test_installer.sh: Don't check for python-gobject on Arch
- tests/test_installer.sh: Add comment explaining why it's skipped
- tests/test_installer.sh: Update summary for Arch (PyGObject compiled)
- README.md: Remove python-gobject from Arch instructions
- README.md: Explain version incompatibility and compilation requirement
Result:
- Debian/Ubuntu: All system packages, zero compilation (~1 min)
- Arch Linux: System packages + PyGObject compilation (~2-3 min)
Trade-off accepted: Arch users get longer install time in exchange for
compatibility with bluezero's PyGObject version requirement.
Fixes: error: uninstall-no-record-file (PyGObject 3.54.5 conflict)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Arch Linux has unique pip/system package integration where pip doesn't
recognize system python-gobject as satisfying PyGObject dependency,
causing bluezero to try compiling PyGObject from source.
Solution: Install base-devel on Arch to provide build tools (gcc, make, meson)
Changes:
- install.sh: Add base-devel to Arch system dependencies
- install.sh: Add note explaining why build tools needed on Arch
- install.sh: Use --needed flag to skip already installed packages
- README.md: Document base-devel requirement for Arch users
- README.md: Explain Arch vs Debian/Ubuntu compilation differences
- tests/test_installer.sh: Expect build tools on Arch (verify base-devel installed)
- tests/test_installer.sh: Update summary to reflect Arch compilation
Rationale:
- AUR python-bluezero is outdated (v0.9.0 vs pip v0.9.1)
- AUR package has 0 votes (rarely used by community)
- base-devel commonly installed on Arch systems anyway
- Keeps latest bluezero version
- Simpler than full AUR integration
Impact:
- Debian/Ubuntu: No compilation (< 1 min install)
- Arch Linux: Some compilation (~3 min install)
- Still faster than compiling everything on Debian
Fixes Arch Linux CI failure: "Unknown compiler(s): gcc not found"
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Strategy 1: Use pre-compiled system packages instead of building from source
- install.sh: Add python3-gi, python3-cairo to apt-get install
- install.sh: Add python-gobject, python-cairo to pacman install
- install.sh: Install only bleak and bluezero via pip (skip compiled packages)
- README.md: Update dependency instructions with system packages
- README.md: Add explanation of why system packages are preferred
Strategy 2: Add CI integration test for fresh Debian/Ubuntu systems
- tests/test_installer.sh: New integration test script
- .github/workflows/test.yml: Add installer-test job with matrix for Debian 12, Ubuntu 22.04, 24.04
- Tests reproduce real user experience and catch missing dependencies
Benefits:
- Zero compilation time (seconds vs minutes)
- No build tools needed (meson, cmake)
- No dev headers needed (libglib2.0-dev, libcairo2-dev, etc.)
- Faster installation on resource-constrained devices (Raspberry Pi)
- Prevents future dependency documentation issues
Fixes#4🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The install.sh script now supports an optional --config flag to specify
a custom Reticulum config directory during installation.
Changes:
- Add command-line argument parsing for --config flag
- Add --help flag to display usage information
- Update installation path logic to use custom or default directory
- Update final instructions to show correct rnsd command with --config flag
- Document the new --config flag in README.md
Usage:
./install.sh # Install to ~/.reticulum (default)
./install.sh --config /custom/path # Install to custom directory
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
The BLE interface now dynamically resolves the interface directory
by checking RNS.Reticulum.configdir when loaded via exec() by Reticulum.
This allows users to specify custom config directories using the
--config flag without encountering import errors.
Changes:
- Update BLEInterface.py to use RNS.Reticulum.configdir when available
- Add fallback to default ~/.reticulum/interfaces for backward compatibility
- Add comprehensive test coverage for config directory resolution
- Update documentation to mention custom config directory support
Fixes#2🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>