The contact sync streams up to MAX_CONTACTS frames back to back, but
ArduinoSerialInterface never checked whether the stream could take
them: isWriteBusy() returned false unconditionally, so MyMesh's pacing
gate had no effect, and writeFrame() called write() without looking at
availableForWrite(). On ESP32 (HWCDC, 256 byte TX ring) a host that
stalls for a moment makes the driver drop queued bytes silently, which
tears a frame in half - and since the framing is length prefixed with
no checksum and no resync marker, the client stays desynchronised for
the rest of the session. Reported as 'the app disconnects while
syncing contacts' on devices with a large contact list.
Add opt-in flow control: report busy until a whole frame fits, and
drop frames as a unit instead of tearing them. Enable it for the
companion USB interface and give HWCDC a bigger TX buffer with a short
write timeout, mirroring what kiss_modem already does.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
ArduinoSerialInterface::isConnected() always returned true, so any
companion build with a USB interface believes a client is attached from
boot onwards. Two user visible effects:
- new message notifications never fire, because MyMesh only notifies
the UI (display, buzzer) while no client is connected
- on builds that also expose BLE the home screen shows '< Connected >'
instead of the BLE pairing PIN, so a freshly flashed device cannot be
paired at all
Add an optional connection check callback and wire it up per platform:
native USB-CDC (TinyUSB on nRF52/RP2040/ESP32 with USB_MODE=0) exposes
real DTR through (bool)Serial. The ESP32 USB-Serial-JTAG peripheral has
no DTR concept - it reports 'connected' as soon as the host enumerated
the device - so fall back to frame activity there. Plain UARTs keep the
previous assume-connected behaviour.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Introduced consistent preferences for external LoRa FEM RX and TX gain settings in NodePrefs. Updated companion MyMesh to apply these settings during initialization and transmission. Added unit tests to verify the round-trip serialization of these new preferences.
The room server never supported RX boosted gain, while the repeater
does. Three consequences on SX1262/SX1268 boards:
- boosted gain was never applied to the radio at boot, so a room server
ran in power-saving RX mode while an identical repeater ran boosted -
a real receive-sensitivity difference with nothing pointing at it
- _prefs.rx_boosted_gain was never initialised (the prefs are memset to
0 before defaults are set), so it defaulted to off
- 'set radio.rxgain on' replied "Error: unsupported" but CommonCLI had
already written the value to prefs and saved them, so a stale setting
survived reboot and was never applied
Mirror the repeater's implementation: initialise the pref default under
the same USE_SX1262/USE_SX1268 and SX126X_RX_BOOSTED_GAIN guards, apply
it during radio init, and override setRxBoostedGain() so the CLI reports
success and takes effect.
Built Heltec_v3_room_server (SX1262) and LilyGo_T3S3_sx1276_room_server
(guards compile out cleanly).
setTxTimeoutMs() and setTxBufferSize() are HWCDC-only APIs; calling
them on HardwareSerial (UART-bridge boards like T-Beam) fails to compile.
Co-Authored-By: Adam Gessaman <adam@gessaman.com>
Switch ESP32-S3 KISS modem environments to HWCDC and move outbound KISS writes to a non-blocking queued frame path so loop() and TX completion keep progressing when the host reads slowly. Add native backpressure regression tests and correct the native_kiss_modem test filter so this suite runs directly with pio test.