Reusable module boundary
The com.wildonionlabs.qrhs Android library exposes lifecycle and message operations, configuration, states, events, participant/candidate handles, and reason/result types. BLE addresses, GATT objects, UUIDs, MTU, advertisements, and scan results remain internal.
App-supplied configuration
Capacity is explicit (2–16, including Host). Invitation expiry, inactivity timeout, hard expiry policy, required/automatic approval, optional sanitized label, optional 512-byte opaque metadata, and 1–32 character app compatibility version belong to the parent.
Native BLE/GATT transport
The Host is a connectable peripheral/GATT server; Guests are central/GATT clients. The implementation filters by a public session marker, negotiates MTU, discovers and subscribes, fragments bounded frames, serializes GATT operations, times out incomplete frames, and retries acknowledgements finitely.
Host authority and participants
The Host admits candidates and owns capacity. Each admitted Guest gets a random session-scoped ParticipantId and per-peer key, independent from display labels and Bluetooth addresses.
Reconnect and resync
Membership survives a transport disconnect. Separate per-participant credential, sequence, dedupe, connection, and reconnect state lets one Guest recover without tearing down others; advertising continues for admitted-member reconnect after admission closes.
Compatibility
Both the QRHS wire-protocol version and parent application compatibility version are checked. A mismatch rejects the invitation cleanly rather than attempting an ambiguous session.
Message integrity
SecureRandom creates secrets and IDs. HMAC-SHA-256 authenticates invitation-stage and per-peer messages; receive state persists before delivery, duplicates may be re-acknowledged but are not emitted twice.
Local recovery
Active recovery state is encrypted with Android Keystore AES-GCM and excluded from app backup. End, leave, inactivity, and hard-expiry policies clean up session-scoped material.
Connectivity policy
The user’s settings remain authoritative. QRHS reports required permissions or disabled Bluetooth; it never silently enables Bluetooth or launches settings. It creates no permanent bond, pairing dialog, PIN, or numeric comparison.
No unnecessary cloud
No Wi-Fi, LAN negotiation, Internet relay, backend, account, certificate authority, or permanent identity is required. Native BLE/GATT is the intentionally single transport.
Security scope
The module authenticates low-risk nearby-session messages but does not claim radio confidentiality. A copied live QR can race admission, which is why optional human Host approval is an explicit policy.
Known limitation
An intermittent first-attempt scan/GATT readiness timeout remains instrumented with a finite retry path. Android/OEM BLE callbacks and long background survival remain platform-dependent; no foreground service is hidden inside the library.
What the parent app still owns
Product UI, identity meaning, player/application state, payload schema, participant policy, labels, metadata, compatibility, and session lifetime decisions. QRHS supplies transport, temporary trust, membership, recovery, and generic delivery—not an opinionated application framework.