From e473a00e91b4d9342feb1725f3834b64f97a750b Mon Sep 17 00:00:00 2001 From: torlando-tech Date: Fri, 31 Oct 2025 17:43:10 -0400 Subject: [PATCH] feat: Add connection handshake to trigger peripheral callbacks Sends empty WRITE to RX characteristic immediately after connection to guarantee remote side's on_central_connected callback fires. Problem: Peripheral callback triggered by WRITE events, not connections. When central connects and only READs (Identity characteristic), the peripheral's on_central_connected never fires, preventing peer interface spawning on the peripheral side. Solution: After reading Identity, write empty bytes to RX characteristic. This triggers the WRITE callback which calls _handle_central_connected(), ensuring bidirectional peer interface spawning. Benefits: - Works for Pi-to-Pi (ensures both sides spawn interfaces) - Works for Android-to-Pi (Pi spawns interface when Android connects) - Minimal overhead (single empty GATT write) - Backwards compatible (empty write is harmless) Implementation: - Added after Identity read in _connect_to_peer() - Uses write_gatt_char() with response=True for reliability - Non-critical failure (logged as warning, doesn't block connection) - TODO comment for future handshake protocol enhancements This solves the asymmetric peer spawning issue seen in testing where only the central side had a peer interface. Tested: Enables bidirectional data flow for single-direction discoveries. --- src/RNS/Interfaces/BLEInterface.py | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/RNS/Interfaces/BLEInterface.py b/src/RNS/Interfaces/BLEInterface.py index 66509ad..f41dc55 100644 --- a/src/RNS/Interfaces/BLEInterface.py +++ b/src/RNS/Interfaces/BLEInterface.py @@ -1445,6 +1445,16 @@ class BLEInterface(Interface): RNS.log(f"{self} failed to read identity from {peer.name}: {type(e).__name__}: {e}", RNS.LOG_DEBUG) # Continue without identity + # Send connection handshake to trigger peripheral callback + # Write empty bytes to RX characteristic to ensure remote's on_central_connected fires + # This guarantees bidirectional peer interface spawning even when only one side discovers + # TODO: Consider sending handshake packet with protocol version/capabilities/flags + try: + await client.write_gatt_char(self.CHARACTERISTIC_RX_UUID, b'', response=True) + RNS.log(f"{self} sent connection handshake to {peer.name}", RNS.LOG_DEBUG) + except Exception as e: + RNS.log(f"{self} handshake write failed (non-critical): {e}", RNS.LOG_WARNING) + # Get negotiated MTU try: # For BlueZ backend, acquire MTU first to avoid warning