Handle potentially invalid received serial commands without crashing

master
LeapwardKoex 2025-03-15 22:40:38 +13:00
parent 6e8500a479
commit f12494faf3
1 changed files with 40 additions and 36 deletions

View File

@ -5,7 +5,7 @@ namespace WpfMaiTouchEmulator.Managers;
internal class MaiTouchComConnector(MaiTouchSensorButtonStateManager buttonState, MainWindowViewModel viewModel) internal class MaiTouchComConnector(MaiTouchSensorButtonStateManager buttonState, MainWindowViewModel viewModel)
{ {
private static SerialPort? serialPort; private static SerialPort? serialPort;
private bool isActiveMode; private bool _isActiveMode;
private bool _connected; private bool _connected;
private CancellationTokenSource? _tokenSource; private CancellationTokenSource? _tokenSource;
private Thread? _pollThread; private Thread? _pollThread;
@ -39,7 +39,7 @@ internal class MaiTouchComConnector(MaiTouchSensorButtonStateManager buttonState
if (!_connected && _shouldReconnect) if (!_connected && _shouldReconnect)
{ {
Logger.Info("Trying to connect to COM port..."); Logger.Info("Trying to connect to COM port...");
var virtualPort = "COM23"; // Adjust as needed var virtualPort = "COM23";
try try
{ {
OnConnectStatusChange?.Invoke(_viewModel.TxtComPortConnecting); OnConnectStatusChange?.Invoke(_viewModel.TxtComPortConnecting);
@ -86,10 +86,10 @@ internal class MaiTouchComConnector(MaiTouchSensorButtonStateManager buttonState
{ {
while (!token.IsCancellationRequested) while (!token.IsCancellationRequested)
{ {
if (isActiveMode) if (_isActiveMode)
{ {
SendTouchscreenState(); SendTouchscreenState();
Thread.Sleep(1); Thread.Sleep(10);
} }
else else
{ {
@ -139,48 +139,52 @@ internal class MaiTouchComConnector(MaiTouchSensorButtonStateManager buttonState
void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e) void SerialPort_DataReceived(object sender, SerialDataReceivedEventArgs e)
{ {
var recievedData = serialPort?.ReadExisting(); var recievedData = serialPort?.ReadExisting();
var commands = recievedData?.Split(new[] { '}' }, StringSplitOptions.RemoveEmptyEntries); var commands = recievedData?.Split(['}'], StringSplitOptions.RemoveEmptyEntries);
if (commands != null)
if (commands is null)
{ {
foreach (var command in commands) return;
}
foreach (var command in commands)
{
var cleanedCommand = command.TrimStart('{');
Logger.Info($"Received serial data: '{cleanedCommand}'");
OnDataRecieved?.Invoke(cleanedCommand);
if (cleanedCommand == "STAT")
{
_isActiveMode = true;
}
else if (cleanedCommand == "RSET")
{ {
var cleanedCommand = command.TrimStart('{');
Logger.Info($"Received serial data: {cleanedCommand}");
OnDataRecieved?.Invoke(cleanedCommand);
if (cleanedCommand == "STAT") }
{ else if (cleanedCommand == "HALT")
isActiveMode = true; {
} _isActiveMode = false;
else if (cleanedCommand == "RSET") }
{ else if (cleanedCommand.Length >= 4 &&
(cleanedCommand[2] == 'r' || cleanedCommand[2] == 'k'))
{
var leftOrRight = cleanedCommand[0];
var sensor = cleanedCommand[1];
var ratio = cleanedCommand[3];
} var newString = $"({leftOrRight}{sensor}{cleanedCommand[2]}{ratio})";
else if (cleanedCommand == "HALT") serialPort?.Write(newString);
{ OnDataSent?.Invoke(newString);
isActiveMode = false; }
} else
else if (cleanedCommand[2] == 'r' || cleanedCommand[2] == 'k') {
{ Logger.Warn($"Unhandled serial data command '{cleanedCommand}'");
var leftOrRight = cleanedCommand[0];
var sensor = cleanedCommand[1];
var ratio = cleanedCommand[3];
var newString = $"({leftOrRight}{sensor}{cleanedCommand[2]}{ratio})";
serialPort?.Write(newString);
OnDataSent?.Invoke(newString);
}
else
{
Logger.Warn($"Unhandled serial data command {cleanedCommand}");
}
} }
} }
} }
void SendTouchscreenState() void SendTouchscreenState()
{ {
if (_connected) if (_connected && _isActiveMode)
{ {
var currentState = _buttonState.GetCurrentState(); var currentState = _buttonState.GetCurrentState();
try try