132 lines
3.9 KiB
C#
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);
|
|
}
|
|
}
|