# Gate 2B: BLEPeerSessionManager Native Tests Date: 2026-05-18 14:45 America/Los_Angeles Scope: C++ native skeleton and pure native unit tests only. ## Summary Gate 2B implemented a standalone C++ `BLEPeerSessionManager` skeleton under `migration/protocol_core` with no pybind11 bindings and no integration into live Python BLE behavior. Files added: - `migration/protocol_core/BLEPeerSessionManager.h` - `migration/protocol_core/BLEPeerSessionManager.cpp` - `migration/tests/native/test_ble_peer_session_manager.cpp` - `migration/sql/mark_gate2b_protocol_session_native_tests_20260518_1445.sql` `BLEInterface.py` was not modified. No BlueZ, Bleak, DBus, `RNS.Transport`, `BLEPeerInterface`, ESP32 BLE APIs, or live BLE tests were used. ## Implemented C++ Surface Implemented types and enums: - `PeerIdentity` - `LocalRole` - `InputDecision` - `SessionActionType` - `ConnectionId` - `ConnectionSnapshot` - `SessionAction` - `HandshakeResult` - `PeerSessionView` - `BLEPeerSessionManager` Implemented helpers: - `isIdentityHandshakePayload` - `identityFromPayload` - `computeIdentityKey` - `computeFragmenterKey` Implemented session methods: - `handleIdentityHandshake` - `markConnected` - `markDisconnected` - `markMtu` - `markPendingIdentity` - `removePendingIdentity` - `expiredPendingIdentities` - `sessionByAddress` - `sessionByIdentity` ## Behavior Covered The C++ skeleton covers the Gate 2B reference cases: | Case | Result | |---|---| | non-16-byte payload | `PassToReassembler`, `consumed=false` | | new 16-byte identity | `AcceptedNewIdentity`, `consumed=true`, `accepted=true`, keys set | | known identity duplicate same | `ConsumedDuplicateSameIdentity`, `consumed=true` | | known identity duplicate mismatch | `ConsumedDuplicateMismatchedIdentity`, `Warn`, `consumed=true` | | duplicate identity active elsewhere | `RejectedDuplicateIdentity`, `DisconnectCurrentPeer` | | duplicate identity with stale/pending detach | accept new identity, `CleanupOldAddress`, `UpdatePeerAddress` | | duplicate identity with zombie old connection | accept new identity, `DisconnectOldPeer`, `CleanupOldAddress` | | MTU provided | result/session MTU equals provided value | | MTU missing | MTU falls back to `23` | | pending identity timeout | expired connection IDs returned without platform calls | | peer address update | session address changes, fragmenter key is unchanged | | identity key helper | first 8 bytes as 16 lowercase hex chars | | fragmenter key helper | full 16 bytes as 32 lowercase hex chars | | invalid identity payload | `identityFromPayload` throws `std::invalid_argument` | ## Build And Test Instructions Build: ```sh g++ -std=c++17 -Wall -Wextra -Werror -Imigration/protocol_core migration/protocol_core/BLEPeerSessionManager.cpp migration/tests/native/test_ble_peer_session_manager.cpp -o /tmp/test_ble_peer_session_manager ``` Run: ```sh /tmp/test_ble_peer_session_manager ``` Observed result: ```text BLEPeerSessionManager native tests passed ``` ## Notes The manager currently uses standard containers for native/Linux development. Gate 2G should decide whether the ESP32/microReticulum build uses the same public API with fixed-size pools internally. The core returns adapter actions only. It does not log, disconnect peers, create Python interfaces, touch Reticulum transport state, or call BLE platform APIs. ## SQL Companion SQL: `migration/sql/mark_gate2b_protocol_session_native_tests_20260518_1445.sql` The SQL marks `_handle_identity_handshake` as `NATIVE_TESTED` for phase `2_ble_protocol_session_manager` because the native tests passed. It does not mark anything `FIELD_ACCEPTED` and does not alter Phase 1 field-accepted rows.