common/Hardware/Common.Hardware.SIRT/SIRTHub.cs
2026-04-23 17:50:07 +02:00

132 lines
3.9 KiB
C#

namespace Common.Hardware.SIRT
{
using Common.Hardware.SIRT.Tasks;
using System;
using System.Collections.Concurrent;
using System.Linq;
using System.Threading;
public class SIRTHub
{
private static readonly ConcurrentDictionary<string, SIRTBroadcaster> broadcasters = new ConcurrentDictionary<string, SIRTBroadcaster>();
private readonly bool log_RX_TX;
public SIRTHub(bool log_RX_TX = true)
=> this.log_RX_TX = log_RX_TX;
public event Action<SIRTBroadcaster> Connected;
public event Action<SIRTBroadcaster> Disconnected;
public event Action<SIRTMessage> MessageReceived;
public void CloseAll()
{
foreach (var broadcaster in broadcasters.Values.ToArray())
{
try
{
this.Close(broadcaster.PortName);
}
catch (Exception e)
{
this.LogMessage(e);
}
}
try
{
broadcasters.Clear();
}
catch (Exception e)
{
this.LogMessage(e);
}
}
public void Close(string portName)
{
if (broadcasters.TryRemove(portName, out var broadcaster))
{
var disconnectedEvent = new ManualResetEventSlim();
void SIRTBroadcaster_Disconnected(SIRTBroadcaster _broadcaster)
{
this.Disconnected?.Invoke(_broadcaster);
disconnectedEvent.Set();
}
broadcaster.Disconnected += SIRTBroadcaster_Disconnected;
broadcaster.Close();
disconnectedEvent.Wait(3000);
broadcaster.Disconnected -= SIRTBroadcaster_Disconnected;
}
}
public bool Start(SIRTTask task)
{
var started = false;
foreach (var broadcaster in broadcasters.Values)
{
if (broadcaster.Start(task))
{
started = true;
break;
}
}
return started;
}
public bool TryOpen(string portName, out string hexId, out int frequency)
{
hexId = default(string);
frequency = default(int);
var connectedEvent = new ManualResetEventSlim();
var broadcaster = new SIRTBroadcaster(portName, this.log_RX_TX);
void SIRTBroadcasterConnected(SIRTBroadcaster _broadcaster)
{
_broadcaster.MessageReceived += this.OnSIRTMessageReceived;
broadcasters.AddOrUpdate(portName, _broadcaster, (_, _1) => _broadcaster);
this.Connected?.Invoke(_broadcaster);
connectedEvent.Set();
}
void SIRTBroadcasterDisconnected(SIRTBroadcaster _broadcaster)
{
_broadcaster.MessageReceived -= this.OnSIRTMessageReceived;
broadcasters.TryRemove(portName, out var _);
this.Disconnected?.Invoke(_broadcaster);
connectedEvent.Set();
}
broadcaster.Connected += SIRTBroadcasterConnected;
broadcaster.Disconnected += SIRTBroadcasterDisconnected;
broadcaster.Open();
connectedEvent.Wait();
hexId = broadcaster.Id;
frequency = broadcaster.Frequency;
broadcaster.Connected -= SIRTBroadcasterConnected;
broadcaster.Disconnected -= SIRTBroadcasterDisconnected;
return broadcaster.IsOpen;
}
private void LogMessage(object message)
=> SIRTLogger.LogMessage($"{nameof(SIRTHub)}|{message}");
private void OnSIRTMessageReceived(SIRTMessage message)
=> this.MessageReceived?.Invoke(message);
}
}