//------------------------------------------------------------------------------
// 此代码版权声明为全文件覆盖,如有原作者特别声明,会在下方手动补充
// 此代码版权(除特别声明外的代码)归作者本人Diego所有
// 源代码使用协议遵循本仓库的开源协议及附加协议
// Gitee源代码仓库:https://gitee.com/diego2098/ThingsGateway
// Github源代码仓库:https://github.com/kimdiego2098/ThingsGateway
// 使用文档:https://thingsgateway.cn/
// QQ群:605534569
//------------------------------------------------------------------------------
using ThingsGateway.NewLife;
using TouchSocket.SerialPorts;
namespace ThingsGateway.Foundation;
///
/// 串口通道
///
public class SerialPortChannel : SerialPortClient, IClientChannel
{
public SerialPortChannel(IChannelOptions channelOptions)
{
ChannelOptions = channelOptions;
ResetSign();
}
public override TouchSocketConfig Config => base.Config ?? ChannelOptions.Config;
public void ResetSign(int minSign = 0, int maxSign = ushort.MaxValue)
{
var pool = WaitHandlePool;
WaitHandlePool = new WaitHandlePool(minSign, maxSign);
pool?.CancelAll();
}
///
public ChannelReceivedEventHandler ChannelReceived { get; } = new();
///
public IChannelOptions ChannelOptions { get; }
///
public ChannelTypeEnum ChannelType => ChannelOptions.ChannelType;
///
public ConcurrentList Collects { get; } = new();
///
public DataHandlingAdapter ReadOnlyDataHandlingAdapter => ProtectedDataHandlingAdapter;
private bool logSet;
///
public void SetDataHandlingAdapterLogger(ILog log)
{
if (!logSet && ProtectedDataHandlingAdapter is IDeviceDataHandleAdapter handleAdapter)
{
logSet = true;
handleAdapter.Logger = log;
}
}
///
public void SetDataHandlingAdapter(DataHandlingAdapter adapter)
{
if (adapter is SingleStreamDataHandlingAdapter singleStreamDataHandlingAdapter)
SetAdapter(singleStreamDataHandlingAdapter);
logSet = false;
}
///
public ChannelEventHandler Started { get; } = new();
///
public ChannelEventHandler Starting { get; } = new();
///
public ChannelEventHandler Stoped { get; } = new();
///
public ChannelEventHandler Stoping { get; } = new();
///
/// 等待池
///
public WaitHandlePool WaitHandlePool { get; internal set; } = new(0, ushort.MaxValue);
///
public WaitLock WaitLock => ChannelOptions.WaitLock;
public virtual WaitLock GetLock(string key) => WaitLock;
//private readonly WaitLock _connectLock = new WaitLock();
///
public override async Task CloseAsync(string msg, CancellationToken token)
{
if (Online)
{
try
{
//await _connectLock.WaitAsync().ConfigureAwait(false);
if (Online)
{
PortName = null;
await this.OnChannelEvent(Stoping).ConfigureAwait(false);
var result = await base.CloseAsync(msg, token).ConfigureAwait(false);
if (!Online)
{
await this.OnChannelEvent(Stoped).ConfigureAwait(false);
}
return result;
}
}
finally
{
//_connectLock.Release();
}
}
return Result.Success;
}
///
public override async Task ConnectAsync(CancellationToken token)
{
if (!Online)
{
try
{
//await _connectLock.WaitAsync(token).ConfigureAwait(false);
if (!Online)
{
if (token.IsCancellationRequested) return;
var port = Config?.GetValue(SerialPortConfigExtension.SerialPortOptionProperty);
if (port != null)
PortName = $"{port.PortName}";
await this.OnChannelEvent(Starting).ConfigureAwait(false);
await base.ConnectAsync(token).ConfigureAwait(false);
if (Online)
{
if (token.IsCancellationRequested) return;
await this.OnChannelEvent(Started).ConfigureAwait(false);
}
}
}
finally
{
//_connectLock.Release();
}
}
}
private string PortName { get; set; }
///
public override string? ToString()
{
if (!PortName.IsNullOrEmpty())
return PortName;
var port = Config?.GetValue(SerialPortConfigExtension.SerialPortOptionProperty);
if (port != null)
return $"{port.PortName}";
return base.ToString();
}
protected override Task OnSerialClosed(ClosedEventArgs e)
{
Logger?.Info($"{ToString()} Closed{(e.Message.IsNullOrEmpty() ? string.Empty : $" -{e.Message}")}");
return base.OnSerialClosed(e);
}
///
protected override Task OnSerialClosing(ClosingEventArgs e)
{
Logger?.Trace($"{ToString()} Closing{(e.Message.IsNullOrEmpty() ? string.Empty : $" -{e.Message}")}");
return base.OnSerialClosing(e);
}
///
protected override Task OnSerialConnecting(ConnectingEventArgs e)
{
Logger?.Trace($"{ToString()} Connecting{(e.Message.IsNullOrEmpty() ? string.Empty : $" -{e.Message}")}");
return base.OnSerialConnecting(e);
}
protected override Task OnSerialConnected(ConnectedEventArgs e)
{
Logger?.Debug($"{ToString()} Connected");
return base.OnSerialConnected(e);
}
///
protected override async Task OnSerialReceived(ReceivedDataEventArgs e)
{
await base.OnSerialReceived(e).ConfigureAwait(false);
if (e.Handled)
return;
await this.OnChannelReceivedEvent(e, ChannelReceived).ConfigureAwait(false);
}
///
protected override void SafetyDispose(bool disposing)
{
WaitHandlePool?.CancelAll();
base.SafetyDispose(disposing);
}
}