fix(tcp): reset state on aborted pre-handshake connect

This commit is contained in:
just-stuff-tm
2026-03-10 21:38:35 -04:00
parent 9db79e9d40
commit 2f770bbd53
2 changed files with 59 additions and 12 deletions
+30 -12
View File
@@ -992,6 +992,21 @@ class MeshCoreConnector extends ChangeNotifier {
_setState(MeshCoreConnectionState.connecting);
try {
Future<void> handleTcpConnectAbort({required String message}) async {
_appDebugLogService?.warn(message, tag: 'TCP');
final shouldResetState = shouldResetStateAfterTcpConnectAbort(
state: _state,
activeTransport: _activeTransport,
);
if (shouldResetState) {
await disconnect(manual: false);
return;
}
if (_tcpManager.isConnected) {
await _tcpManager.disconnect();
}
}
await _tcpFrameSubscription?.cancel();
_tcpFrameSubscription = null;
await _tcpManager.connect(host: host, port: port);
@@ -1000,13 +1015,10 @@ class MeshCoreConnector extends ChangeNotifier {
_state != MeshCoreConnectionState.connecting ||
!_tcpManager.isConnected;
if (isTcpConnectCancelled) {
_appDebugLogService?.warn(
'connectTcp aborted before handshake: state=$_state transport=$_activeTransport connected=${_tcpManager.isConnected}',
tag: 'TCP',
await handleTcpConnectAbort(
message:
'connectTcp aborted before handshake: state=$_state transport=$_activeTransport connected=${_tcpManager.isConnected}',
);
if (_tcpManager.isConnected) {
await _tcpManager.disconnect();
}
return;
}
notifyListeners();
@@ -1017,13 +1029,10 @@ class MeshCoreConnector extends ChangeNotifier {
_state != MeshCoreConnectionState.connecting ||
!_tcpManager.isConnected;
if (isTcpConnectCancelledAfterDelay) {
_appDebugLogService?.warn(
'connectTcp aborted after connect delay: state=$_state transport=$_activeTransport connected=${_tcpManager.isConnected}',
tag: 'TCP',
await handleTcpConnectAbort(
message:
'connectTcp aborted after connect delay: state=$_state transport=$_activeTransport connected=${_tcpManager.isConnected}',
);
if (_tcpManager.isConnected) {
await _tcpManager.disconnect();
}
return;
}
_tcpFrameSubscription = _tcpManager.frameStream.listen(
@@ -1091,6 +1100,15 @@ class MeshCoreConnector extends ChangeNotifier {
(activeTransport != MeshCoreTransportType.tcp || !tcpManagerConnected);
}
@visibleForTesting
static bool shouldResetStateAfterTcpConnectAbort({
required MeshCoreConnectionState state,
required MeshCoreTransportType activeTransport,
}) {
return state == MeshCoreConnectionState.connecting &&
activeTransport == MeshCoreTransportType.tcp;
}
Future<void> connect(BluetoothDevice device, {String? displayName}) async {
if (_state == MeshCoreConnectionState.connecting ||
_state == MeshCoreConnectionState.connected) {
@@ -61,4 +61,33 @@ void main() {
expect(result, isFalse);
});
});
group('shouldResetStateAfterTcpConnectAbort', () {
test('returns true when TCP connect is still in connecting state', () {
final result = MeshCoreConnector.shouldResetStateAfterTcpConnectAbort(
state: MeshCoreConnectionState.connecting,
activeTransport: MeshCoreTransportType.tcp,
);
expect(result, isTrue);
});
test('returns false when state is already disconnected', () {
final result = MeshCoreConnector.shouldResetStateAfterTcpConnectAbort(
state: MeshCoreConnectionState.disconnected,
activeTransport: MeshCoreTransportType.tcp,
);
expect(result, isFalse);
});
test('returns false when transport switched away from TCP', () {
final result = MeshCoreConnector.shouldResetStateAfterTcpConnectAbort(
state: MeshCoreConnectionState.connecting,
activeTransport: MeshCoreTransportType.bluetooth,
);
expect(result, isFalse);
});
});
}