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>
## Problem
The identity handshake handler called `self.driver.get_peer_mtu(address)`,
but this method didn't exist, causing:
```
[Error] BLEInterface[BLE Interface] failed to process identity handshake from dev:B8:27:EB:A8:A7:22: 'LinuxBluetoothDriver' object has no attribute 'get_peer_mtu'
```
## Solution
Added `get_peer_mtu(address)` method to LinuxBluetoothDriver that:
1. Checks central connections (self._peers) for MTU when we're the central
2. Checks peripheral connections (gatt_server.connected_centrals) for MTU when we're the peripheral
3. Returns None if peer not found in either
This mirrors the existing `get_peer_role()` pattern and provides
thread-safe access to MTU information for both connection types.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
## Problem
The central device was timing out when trying to read the identity
characteristic from peripheral devices, causing connection failures:
```
ERROR: Error reading characteristic ...28e6 from B8:27:EB:10:28:CD: TimeoutError
```
Root cause: The driver already reads the identity during connection setup
(line 806 in _connect_to_peer), but then BLEInterface tried to read it
AGAIN in _device_connected_callback. The second read consistently timed
out, likely due to BlueZ/D-Bus caching issues or characteristic state.
## Solution
Changed the `on_device_connected` callback signature to pass the peer
identity directly, following the established pattern of other callbacks
like `on_data_received(address, data)` and `on_mtu_negotiated(address, mtu)`.
### Changes
1. **Driver Interface** (bluetooth_driver.py)
- Updated callback: `on_device_connected(str, Optional[bytes])`
- Identity is None for peripheral connections (arrives via handshake)
2. **PeerConnection** (linux_bluetooth_driver.py)
- Added `peer_identity: Optional[bytes]` field
- Store identity read during connection setup
3. **Connection Flow** (linux_bluetooth_driver.py)
- Central: Pass identity to callback after reading it
- Peripheral: Pass None (identity comes later via handshake)
4. **BLEInterface** (BLEInterface.py)
- Updated callback signature to accept peer_identity parameter
- Removed buggy `read_characteristic()` call
- Use passed identity directly for central connections
- Added typing.Optional import
## Benefits
- ✅ Eliminates redundant GATT read operation
- ✅ Fixes timeout bug for central connections
- ✅ More efficient: reuses identity already read by driver
- ✅ Cleaner architecture: follows callback pattern consistency
- ✅ Explicit about identity availability by connection role
## Testing
Tested on Raspberry Pi Zero W devices with BlueZ 5.82:
- Central connections now receive identity immediately
- Peripheral connections correctly wait for handshake
- No more timeout errors
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
This commit addresses a timeout issue where a central device would fail
to read the identity characteristic from the peripheral.
The root cause is suspected to be a race condition in the underlying
BlueZ/D-Bus stack, where the `read_callback` for the characteristic
was not firing reliably, causing the central's read request to hang
and time out.
To make this process more robust and less dependent on timing, the
GATT server implementation has been hardened:
1. The identity characteristic is now initialized with a 16-byte
placeholder value. This ensures the D-Bus object is created with
the correct data length from the start.
2. When the asynchronous RNS identity becomes available, the server now
proactively pushes the identity to the characteristic using
`set_value()`. This no longer relies exclusively on the fragile
`read_callback` mechanism.
Additionally, error logging within the driver has been improved to
include the exception type, aiding future diagnostics.
This commit addresses two critical issues that prevented the BLE
interface from functioning correctly after the driver abstraction
refactor.
1. **Fix `exec()` Startup Error:**
The interface failed to load via `rnsd` due to a `KeyError: '__name__'`
caused by using relative imports (`from . import ...`). The `exec()`
environment used by Reticulum does not preserve package context,
breaking these imports. This is fixed by reverting to absolute
imports (`from bluetooth_driver import ...`) which work correctly
with the existing `sys.path` manipulation logic.
2. **Fix Connection Role Logic:**
Connections were failing because the interface would always attempt
to read the peer's identity, even when acting as the peripheral.
This caused a `Can only read characteristics in central mode` error.
The fix introduces role-aware logic into the connection callback:
- A `get_peer_role()` method was added to the driver interface.
- `BLEInterface` now checks the role on connection.
- If central, it reads the identity characteristic.
- If peripheral, it waits for the identity handshake packet,
preventing the invalid operation.