Merge PR #3214: companion USB connection and flow control

Preserve the newer terminal and mOTA passthrough paths while adding real USB client detection and whole-frame transmit pacing.
This commit is contained in:
mikecarper committed 2026-08-17 23:55:40 -07:00
commit a92215fd07
3 files changed
+75 -4

No files matched your search

+20 -1
View File
@@ -66,7 +66,8 @@ void ArduinoSerialInterface::disable() {
resetReceiveState();
}
bool ArduinoSerialInterface::isConnected() const {
bool ArduinoSerialInterface::isConnected() const {
if (_conn_check) return _conn_check();
return true; // no way of knowing, so assume yes
}
@@ -75,6 +76,12 @@ bool ArduinoSerialInterface::isReadBusy() const {
}
bool ArduinoSerialInterface::isWriteBusy() const {
if (_passthroughMode) return false;
if (_flow_ctl && isConnected()) {
return const_cast<Stream*>(_serial)->availableForWrite() < (int)(MAX_FRAME_SIZE + 3);
}
// while nobody drains the port the TX buffer stays full, so never report
// busy in that case: it would stall the paced streams on all interfaces
return false;
}
@@ -84,6 +91,17 @@ size_t ArduinoSerialInterface::writeFrame(const uint8_t src[], size_t len) {
return 0;
}
if (_passthroughMode) return len;
if (_flow_ctl) {
if (!isConnected()) {
return len; // nobody is listening, drop instead of filling the TX buffer
}
if (_serial->availableForWrite() < (int)(len + 3)) {
// a short write would tear the length prefixed framing, and as there is
// neither a checksum nor a resync marker the receiver would stay out of
// sync forever - so drop the whole frame instead
return 0;
}
}
uint8_t hdr[3];
hdr[0] = '>';
@@ -133,6 +151,7 @@ size_t ArduinoSerialInterface::checkRecvFrame(uint8_t dest[]) {
if (_frame_len > MAX_FRAME_SIZE) _frame_len = MAX_FRAME_SIZE; // truncate
memcpy(dest, rx_buf, _frame_len);
_state = RECV_STATE_IDLE; // reset state, for next frame
_last_frame_ms = millis(); // a real client is talking to us
return _frame_len;
}
}