fix: consume duplicate identity handshake when identity already known via Kotlin callback

When Kotlin provides the identity via callback (from the identity characteristic read),
the address_to_identity mapping gets set BEFORE the 16-byte handshake data arrives
through _data_received_callback. Previously, _handle_identity_handshake would see the
identity already exists and return False, causing the 16-byte handshake data to be
passed to the reassembler where it fails with "Invalid fragment type 0xXX".

The fix checks if received 16-byte data matches the known identity and consumes it
silently if so. This prevents the handshake data from being misinterpreted as a
fragment.

Symptoms fixed:
- BLEReassembler: Invalid fragment type 0xc9 (first byte of peer identity)
- Messages not flowing even though connections appear established

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
torlando-tech 2026-01-18 13:09:56 -05:00
commit 2694192d28

View file

@ -1186,14 +1186,24 @@ class BLEInterface(Interface):
Returns:
True if data was handled as identity handshake, False otherwise
"""
# Identity handshake detection: exactly 16 bytes
if len(data) != 16:
return False # Not a handshake
# Check if we already have peer identity
peer_identity = self.address_to_identity.get(address)
if peer_identity:
return False # Already have identity, not a handshake
# Identity handshake detection: exactly 16 bytes, no existing identity
if len(data) != 16:
return False # Not a handshake
# We already have identity for this address (probably set via Kotlin callback).
# The 16-byte handshake data may still arrive through the data channel.
# Check if it matches the identity we have - if so, consume it silently.
if data == peer_identity:
RNS.log(f"{self} received duplicate identity handshake from {address} (already known via callback)", RNS.LOG_DEBUG)
return True # Consume the data, don't pass to reassembler
else:
# 16 bytes but doesn't match known identity - log warning but still consume
# to avoid passing identity-like data to the reassembler
RNS.log(f"{self} received 16-byte data from {address} that differs from known identity, consuming as handshake", RNS.LOG_WARNING)
return True # Consume to prevent reassembler errors
try:
# Store central's identity