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

chore/offband-rebrand
just-stuff-tm 4 months ago
parent 9db79e9d40
commit 2f770bbd53

@ -992,6 +992,21 @@ class MeshCoreConnector extends ChangeNotifier {
_setState(MeshCoreConnectionState.connecting); _setState(MeshCoreConnectionState.connecting);
try { 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(); await _tcpFrameSubscription?.cancel();
_tcpFrameSubscription = null; _tcpFrameSubscription = null;
await _tcpManager.connect(host: host, port: port); await _tcpManager.connect(host: host, port: port);
@ -1000,13 +1015,10 @@ class MeshCoreConnector extends ChangeNotifier {
_state != MeshCoreConnectionState.connecting || _state != MeshCoreConnectionState.connecting ||
!_tcpManager.isConnected; !_tcpManager.isConnected;
if (isTcpConnectCancelled) { if (isTcpConnectCancelled) {
_appDebugLogService?.warn( await handleTcpConnectAbort(
'connectTcp aborted before handshake: state=$_state transport=$_activeTransport connected=${_tcpManager.isConnected}', message:
tag: 'TCP', 'connectTcp aborted before handshake: state=$_state transport=$_activeTransport connected=${_tcpManager.isConnected}',
); );
if (_tcpManager.isConnected) {
await _tcpManager.disconnect();
}
return; return;
} }
notifyListeners(); notifyListeners();
@ -1017,13 +1029,10 @@ class MeshCoreConnector extends ChangeNotifier {
_state != MeshCoreConnectionState.connecting || _state != MeshCoreConnectionState.connecting ||
!_tcpManager.isConnected; !_tcpManager.isConnected;
if (isTcpConnectCancelledAfterDelay) { if (isTcpConnectCancelledAfterDelay) {
_appDebugLogService?.warn( await handleTcpConnectAbort(
'connectTcp aborted after connect delay: state=$_state transport=$_activeTransport connected=${_tcpManager.isConnected}', message:
tag: 'TCP', 'connectTcp aborted after connect delay: state=$_state transport=$_activeTransport connected=${_tcpManager.isConnected}',
); );
if (_tcpManager.isConnected) {
await _tcpManager.disconnect();
}
return; return;
} }
_tcpFrameSubscription = _tcpManager.frameStream.listen( _tcpFrameSubscription = _tcpManager.frameStream.listen(
@ -1091,6 +1100,15 @@ class MeshCoreConnector extends ChangeNotifier {
(activeTransport != MeshCoreTransportType.tcp || !tcpManagerConnected); (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 { Future<void> connect(BluetoothDevice device, {String? displayName}) async {
if (_state == MeshCoreConnectionState.connecting || if (_state == MeshCoreConnectionState.connecting ||
_state == MeshCoreConnectionState.connected) { _state == MeshCoreConnectionState.connected) {

@ -61,4 +61,33 @@ void main() {
expect(result, isFalse); 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);
});
});
} }

Loading…
Cancel
Save

Powered by TurnKey Linux.