Skip to content

Commit

Permalink
Port stability detection added and more (#24)
Browse files Browse the repository at this point in the history
* SerialPort in SerialPortShell disposed when GUI "port" is closed.
* SerialReceiver disposable
* Background thread is monitoring SerialPort.IsOpen every 1 sec. This detects when an open port USB cable is disconnected.
* Changed to general log file instead of just errors.
* Logging more events
  • Loading branch information
jdahlblom authored Mar 28, 2024
1 parent 0e6dc55 commit a1ab86d
Show file tree
Hide file tree
Showing 11 changed files with 167 additions and 55 deletions.
2 changes: 1 addition & 1 deletion src/DCSBIOSBridge/Interfaces/ISerialReceiver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ namespace DCSBIOSBridge.Interfaces;
internal interface ISerialReceiver
{
SerialPort SerialPort { get; set; }
void Release();
void Dispose();
void ReceiveTextOverSerial(object sender, SerialDataReceivedEventArgs e);
}
2 changes: 1 addition & 1 deletion src/DCSBIOSBridge/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@
<MenuItem Header="Save" Name="MenuItemSave" Click="MenuItemSave_OnClick"/>
<MenuItem Header="Save As.." Name="MenuItemSaveAs" Click="MenuItemSaveAs_OnClick" />
<Separator />
<MenuItem Name ="MenuItemErrorLog" Header="Open error log" Click="MenuItemErrorLog_OnClick" />
<MenuItem Name ="MenuItemLogFile" Header="Open log" Click="MenuItemLogFile_OnClick" />
<Separator />
<MenuItem Header="Exit" Name="MenuItemExit" Click="MenuItemExit_OnClick" />
</MenuItem>
Expand Down
6 changes: 3 additions & 3 deletions src/DCSBIOSBridge/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ private void Dispose(bool disposing)
_dcsBios?.Dispose();

DBEventManager.BroadCastSerialPortUserControlStatus(SerialPortUserControlStatus.DoDispose);
_serialPortService.CleanUp();
_serialPortService.Dispose();
DBEventManager.DetachSerialPortStatusListener(this);
DBEventManager.DetachWindowsSerialPortEventListener(this);
DBEventManager.DetachSerialPortUserControlListener(this);
Expand Down Expand Up @@ -613,9 +613,9 @@ private void CreateDCSBIOS()
}
}

private void MenuItemErrorLog_OnClick(object sender, RoutedEventArgs e)
private void MenuItemLogFile_OnClick(object sender, RoutedEventArgs e)
{
Common.TryOpenLogFileWithTarget("error_logfile");
Common.TryOpenLogFileWithTarget("logfile");
}

public void OnSettingsDirty(SettingsDirtyEventArgs args)
Expand Down
6 changes: 3 additions & 3 deletions src/DCSBIOSBridge/NLog.config
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,13 @@
throwConfigExceptions="true">

<targets>
<target name="error_logfile"
<target name="logfile"
type="File"
fileName="${basedir}error_log.txt"
fileName="${basedir}dcsbiosbridge_log.txt"
layout="${longdate}|${level}|${message}|${exception:format=Message,StackTrace}${newline}"/>
</targets>

<rules>
<logger name="*" minlevel="Error" writeTo="error_logfile" />
<logger name="*" minlevel="Info" writeTo="logfile" />
</rules>
</nlog>
84 changes: 73 additions & 11 deletions src/DCSBIOSBridge/SerialPortClasses/SerialPortService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,28 @@
using System.IO.Ports;
using System.Management;
using DCSBIOSBridge.Events;
using DCSBIOSBridge.Events.Args;
using DCSBIOSBridge.Interfaces;
using DCSBIOSBridge.misc;
using NLog;
using Theraot.Collections;

namespace DCSBIOSBridge.SerialPortClasses
{


//Creds to : http://stackoverflow.com/questions/4199083/detect-serial-port-insertion-removal
public class SerialPortService
public class SerialPortService : ISerialPortStatusListener, IDisposable
{
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
private string[] _serialPorts;
private List<string> _serialPorts;
private ManagementEventWatcher _managementEventWatchArrival;
private ManagementEventWatcher _managementEventWatchRemoval;

public SerialPortService()
{
_serialPorts = Common.GetSerialPortNames();
DBEventManager.AttachSerialPortStatusListener(this);
MonitorDeviceChanges();
}
/// <summary>
Expand All @@ -35,10 +39,12 @@ public SerialPortService()
/// at System.Management.ManagementEventWatcher.Finalize()
///InnerException:
/// </summary>
public void CleanUp()

public void Dispose()
{
_managementEventWatchArrival.Stop();
_managementEventWatchRemoval.Stop();
DBEventManager.DetachSerialPortStatusListener(this);
_managementEventWatchArrival?.Dispose();
_managementEventWatchRemoval?.Dispose();
}

private void MonitorDeviceChanges()
Expand Down Expand Up @@ -68,25 +74,30 @@ private void RaisePortsChangedIfNecessary(WindowsSerialPortEventType eventType)
{
lock (_serialPorts)
{
Debug.WriteLine($"_serialPorts = {string.Join(", ", _serialPorts)}");
var availableSerialPorts = Common.GetSerialPortNames();
Debug.WriteLine($"Available ports = {string.Join(", ", availableSerialPorts)}");

if (availableSerialPorts.Except(_serialPorts).ToArray().Length == 0)
{
Logger.Info($"No port changes detected. SerialPorts = {string.Join(", ", _serialPorts)}");
return;
}

Logger.Info($"Earlier ports = {string.Join(", ", _serialPorts)}, available ports = {string.Join(", ", availableSerialPorts)}");

switch (eventType)
{
case WindowsSerialPortEventType.Insertion:
{
var addedPorts = availableSerialPorts.Except(_serialPorts).ToArray();
Debug.WriteLine($"Added ports = {string.Join(", ", addedPorts)}");
if (addedPorts.Length == 0) break;
Logger.Info($"Added ports = {string.Join(", ", addedPorts)}");

DBEventManager.BroadCastWindowsPortEvent(null, addedPorts, eventType);
break;
}
case WindowsSerialPortEventType.Removal:
{
var removedPorts = _serialPorts.Except(availableSerialPorts).ToArray();
Debug.WriteLine($"Removed ports = {string.Join(", ", removedPorts)}");
if (removedPorts.Length == 0) break;
Logger.Info($"Removed ports = {string.Join(", ", removedPorts)}");

DBEventManager.BroadCastWindowsPortEvent(null, removedPorts, eventType);
break;
Expand All @@ -110,6 +121,57 @@ private void RaisePortsChangedIfNecessary(WindowsSerialPortEventType eventType)
}
}
*/
public void OnSerialPortStatusChanged(SerialPortStatusEventArgs e)
{
switch (e.SerialPortStatus)
{
case SerialPortStatus.Opened:
break;
case SerialPortStatus.Closed:
break;
case SerialPortStatus.Open:
break;
case SerialPortStatus.Close:
break;
case SerialPortStatus.Added:
break;
case SerialPortStatus.Hidden:
break;
case SerialPortStatus.None:
break;
case SerialPortStatus.Ok:
break;
case SerialPortStatus.Error:
break;
case SerialPortStatus.IOError:
break;
case SerialPortStatus.Critical:
{
/*
* Critical here is used when:
* - port is open
* - USB cable is removed
*
* Windows SerialPort.GetPortNames() list is not updated when this
* happens.
*/
_serialPorts.RemoveWhere(o => o == e.SerialPortName);
break;
}
case SerialPortStatus.TimeOutError:
break;
case SerialPortStatus.BytesWritten:
break;
case SerialPortStatus.BytesRead:
break;
case SerialPortStatus.DCSBIOSCommandCalled:
break;
case SerialPortStatus.Settings:
break;
default:
throw new ArgumentOutOfRangeException();
}
}
}


Expand Down
6 changes: 1 addition & 5 deletions src/DCSBIOSBridge/SerialPortClasses/SerialPortSetting.cs
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ public static SerialPortSetting ParseSetting(string portSetting)
LineSignalRts = bool.Parse(list[9])
};
result.LineSignalRts = bool.Parse(list[9]);
result.Connected = list[10].Equals(Constants.ProfileOpenKeyword);
return result;
}

Expand All @@ -47,8 +46,7 @@ public string ExportSetting()
WriteTimeout + "|" +
ReadTimeout + "|" +
LineSignalDtr + "|" +
LineSignalRts + "|" +
(Connected ? Constants.ProfileOpenKeyword : Constants.ProfileClosedKeyword) + "}");
LineSignalRts);
return result.ToString();
}

Expand All @@ -71,7 +69,5 @@ public string ExportSetting()
public bool LineSignalDtr { get; set; } = true;

public bool LineSignalRts { get; set; }

public bool Connected { get; set; }
}
}
Loading

0 comments on commit a1ab86d

Please sign in to comment.