feat(ui): detect USB-CDC connection for Auto mute (BLE or USB)

USB client presence IS detectable on nRF52 after all: (bool)Serial ==
tud_cdc_n_connected() (DTR — a host has the CDC port open). Add
isClientConnected() = BLE-bonded OR USB-CDC-open; DualSerialInterface
overrides it, base defaults to isConnected() (single-transport unchanged).

Wire it so each consumer gets the right signal:
- hasConnection() ← isClientConnected(): Auto buzzer mute + message-wake now
  trigger on BLE or an open USB port (PR #14's intent, done correctly), but
  not on charging-only (no host → DTR low).
- BT status indicator + pairing PIN stay on isBLEConnected() (BLE-specific).

Caveat: a plain serial monitor also asserts DTR, so it counts as connected.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
Jakub
2026-06-05 12:36:49 +02:00
parent 4ea67ee950
commit 3b795f7abc
4 changed files with 16 additions and 7 deletions

View File

@@ -18,6 +18,12 @@ public:
// isConnected(); override in dual-interface wrappers that always report
// isConnected()=true but still need to distinguish BLE from USB state.
virtual bool isBLEConnected() const { return isConnected(); }
// True when a companion app is actually connected over *any* transport
// (BLE bonded or a host holding the USB-CDC port open). Distinct from
// isConnected(), which a dual interface hardcodes true as a send fallback.
// Used for app-connected UI (Auto buzzer mute, message-wake). Default =
// isConnected() so single-transport interfaces are unchanged.
virtual bool isClientConnected() const { return isConnected(); }
virtual bool isWriteBusy() const = 0;
virtual size_t writeFrame(const uint8_t src[], size_t len) = 0;