HelperEAFProgramData HelperCompass HelperInfinityQS HelperSerial HelperTCP dotnet_analyzer_diagnostic
281 lines
11 KiB
C#
281 lines
11 KiB
C#
using File_Watcher.Models;
|
|
using System.Diagnostics;
|
|
using System.IO.Ports;
|
|
|
|
namespace File_Watcher.Helpers;
|
|
|
|
internal static partial class HelperSerial
|
|
{
|
|
|
|
private record Record(List<byte> Data,
|
|
string Destination,
|
|
ILogger<Worker> Logger,
|
|
CancellationToken CancellationToken);
|
|
|
|
private static Record? _Record;
|
|
private static SerialPort? _SerialPort;
|
|
|
|
private static void PCLToPDF(string fullPath)
|
|
{
|
|
string ghostPCLFileName = Path.Combine(AppContext.BaseDirectory, "gpcl6win64.exe");
|
|
if (!File.Exists(ghostPCLFileName))
|
|
throw new Exception("Ghost PCL FileName doesn't Exist!");
|
|
string lincPDFCFileName = Path.Combine(AppContext.BaseDirectory, "LincPDFC.exe");
|
|
if (!File.Exists(lincPDFCFileName))
|
|
throw new Exception("Linc PDFC FileName doesn't Exist!");
|
|
string pdfFile;
|
|
string fileName;
|
|
string arguments;
|
|
for (int i = 1; i < 3; i++)
|
|
{
|
|
if (i == 1)
|
|
{
|
|
fileName = ghostPCLFileName;
|
|
pdfFile = $"{fullPath}-ghost.pdf";
|
|
arguments = $"-dSAFER -dBATCH -dNOPAUSE -sOutputFile=\"{pdfFile}\" -sDEVICE=pdfwrite \"{fullPath}\"";
|
|
// arguments = $"-dSAFER -dBATCH -dNOPAUSE -dFIXEDMEDIA -dFitPage -dAutoRotatePages=/All -dDEVICEWIDTHPOINTS=792 -dDEVICEHEIGHTPOINTS=612 -sOutputFile=\"{pdfFile}\" -sDEVICE=pdfwrite \"{fullPath}\"";
|
|
}
|
|
else if (i == 2)
|
|
{
|
|
fileName = lincPDFCFileName;
|
|
pdfFile = $"{fullPath}-linc.pdf";
|
|
arguments = $"-i \"{fullPath}\" -o \"{pdfFile}\"";
|
|
}
|
|
else
|
|
throw new Exception();
|
|
Process process = Process.Start(fileName, arguments);
|
|
long breakAfter = DateTime.Now.AddSeconds(30).Ticks;
|
|
for (short j = 0; j < short.MaxValue; j++)
|
|
{
|
|
if (process.HasExited || process.WaitForExit(500) || DateTime.Now.Ticks > breakAfter)
|
|
break;
|
|
}
|
|
if (!File.Exists(pdfFile))
|
|
throw new Exception("PDF file wasn't created");
|
|
}
|
|
}
|
|
|
|
private static List<byte> GetBytes(List<byte> bytes)
|
|
{
|
|
List<byte> results = [];
|
|
foreach (byte @byte in bytes)
|
|
results.Add(@byte);
|
|
return results;
|
|
}
|
|
|
|
private static void SerialPortWrite(string destination, DateTime dateTime, List<byte> bytes, string v, bool convert)
|
|
{
|
|
if (_SerialPort is null)
|
|
throw new NullReferenceException(nameof(_SerialPort));
|
|
string directory = Path.Combine(destination, _SerialPort.PortName);
|
|
if (!Directory.Exists(destination))
|
|
_ = Directory.CreateDirectory(destination);
|
|
string fileName = Path.Combine(directory, $"{_SerialPort.PortName}-{v}-{dateTime:yyyyMMddHHmmssfff}.pcl");
|
|
File.WriteAllBytes(fileName, bytes.ToArray());
|
|
if (convert)
|
|
PCLToPDF(fileName);
|
|
}
|
|
|
|
private static int? SearchBytes(byte[] haystack, byte[] needle)
|
|
{
|
|
int? result = null;
|
|
int k;
|
|
int len = needle.Length;
|
|
int limit = haystack.Length - len;
|
|
for (int i = 0; i <= limit; i++)
|
|
{
|
|
k = 0;
|
|
for (; k < len; k++)
|
|
{
|
|
if (needle[k] != haystack[i + k])
|
|
break;
|
|
}
|
|
if (k == len)
|
|
{
|
|
result = i;
|
|
break;
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
private static bool Contains()
|
|
{
|
|
if (_Record is null)
|
|
throw new NullReferenceException(nameof(_Record));
|
|
bool result;
|
|
// char endOfLine = '\u001b';
|
|
// lock (_Record)
|
|
// result = _Record.Data.Contains(Convert.ToByte(endOfLine));
|
|
// if (!result)
|
|
// {
|
|
// }
|
|
int? index = null;
|
|
// byte[] pageDelimiter =
|
|
// {
|
|
// Convert.ToByte(27),
|
|
// Convert.ToByte(69)
|
|
// };
|
|
lock (_Record)
|
|
{
|
|
byte[] bytes = _Record.Data.ToArray();
|
|
// index = Array.IndexOf(bytes, pageDelimiter);
|
|
// if (index == -1)
|
|
// {
|
|
// }
|
|
byte[] documentDelimiter =
|
|
[
|
|
Convert.ToByte(32),
|
|
Convert.ToByte(83),
|
|
Convert.ToByte(116),
|
|
Convert.ToByte(97),
|
|
Convert.ToByte(116),
|
|
Convert.ToByte(105),
|
|
Convert.ToByte(115),
|
|
Convert.ToByte(116),
|
|
Convert.ToByte(105),
|
|
Convert.ToByte(99),
|
|
Convert.ToByte(115),
|
|
Convert.ToByte(58)
|
|
];
|
|
index = SearchBytes(bytes, documentDelimiter);
|
|
}
|
|
result = index is not null;
|
|
return result;
|
|
}
|
|
|
|
private static void PinChanged(object sender, SerialPinChangedEventArgs serialPinChangedEventArgs)
|
|
{
|
|
if (_Record is null)
|
|
throw new NullReferenceException(nameof(_Record));
|
|
try
|
|
{ _Record.Logger.LogDebug($"EventType = {serialPinChangedEventArgs.EventType}"); }
|
|
catch (Exception exception) { _Record.Logger.LogError(exception, "Error"); }
|
|
}
|
|
|
|
private static void DataReceived(object? sender, SerialDataReceivedEventArgs dataReceivedEventArgs)
|
|
{
|
|
if (_Record is null)
|
|
throw new NullReferenceException(nameof(_Record));
|
|
if (_SerialPort is null)
|
|
throw new NullReferenceException(nameof(_SerialPort));
|
|
DateTime dateTime = DateTime.Now;
|
|
try
|
|
{
|
|
_Record.Logger.LogDebug($"EventType = {dataReceivedEventArgs.EventType}");
|
|
List<byte>? bytes;
|
|
lock (_Record)
|
|
{
|
|
byte[] buffer = new byte[_SerialPort.BytesToRead];
|
|
int count = _SerialPort.Read(buffer, 0, buffer.Length);
|
|
if (count == 0)
|
|
bytes = null;
|
|
else
|
|
{
|
|
_Record.Data.AddRange(buffer.Take(count));
|
|
bytes = dataReceivedEventArgs.EventType != SerialData.Eof ? null : GetBytes(_Record.Data);
|
|
}
|
|
}
|
|
if (bytes is not null)
|
|
SerialPortWrite(_Record.Destination, dateTime, bytes, nameof(SerialData.Eof), convert: false);
|
|
}
|
|
catch (Exception exception)
|
|
{
|
|
string fileName = Path.Combine(_Record.Destination, _SerialPort.PortName, $"{dateTime:yyyyMMddHHmmssfff}.err");
|
|
File.WriteAllLines(fileName, [exception.Message, Environment.NewLine, Environment.NewLine, string.Concat(exception.StackTrace)]);
|
|
}
|
|
}
|
|
|
|
private static void ErrorReceived(object sender, SerialErrorReceivedEventArgs serialErrorReceivedEventArgs)
|
|
{
|
|
if (_Record is null)
|
|
throw new NullReferenceException(nameof(_Record));
|
|
try
|
|
{ _Record.Logger.LogDebug($"EventType = {serialErrorReceivedEventArgs.EventType}"); }
|
|
catch (Exception exception) { _Record.Logger.LogError(exception, "Error"); }
|
|
}
|
|
|
|
private static void SerialPortWriteConditionally(SerialConfiguration serialConfiguration, ILogger<Worker> logger)
|
|
{
|
|
if (_Record is null)
|
|
throw new NullReferenceException(nameof(_Record));
|
|
DateTime dateTime = DateTime.Now;
|
|
logger.LogDebug($"Worker:Process:SerialPort running at: {dateTime} serial port {serialConfiguration.PortName} status with Length = {_Record.Data.Count}.");
|
|
bool contains = Contains();
|
|
if (contains)
|
|
{
|
|
List<byte> bytes;
|
|
if (_Record is null)
|
|
throw new NullReferenceException(nameof(_Record));
|
|
lock (_Record)
|
|
{
|
|
bytes = GetBytes(_Record.Data);
|
|
_Record.Data.Clear();
|
|
}
|
|
SerialPortWrite(_Record.Destination, dateTime, bytes, nameof(Contains), convert: true);
|
|
}
|
|
}
|
|
|
|
private static void SerialPortClose()
|
|
{
|
|
if (_SerialPort is not null)
|
|
{
|
|
if (_Record is null)
|
|
throw new NullReferenceException(nameof(_Record));
|
|
lock (_Record)
|
|
{
|
|
_SerialPort.Close();
|
|
int length = _Record is null ? 0 : _Record.Data.Count;
|
|
if (_Record is null)
|
|
throw new NullReferenceException(nameof(_Record));
|
|
_Record.Logger.LogDebug($"Serial port {_SerialPort.PortName} closed with Length = {length}.");
|
|
}
|
|
}
|
|
}
|
|
|
|
internal static bool ReadWrite(AppSettings appSettings, ILogger<Worker> logger, CancellationToken cancellationToken)
|
|
{
|
|
_Record ??= new([], appSettings.SerialConfiguration.Destination, logger, cancellationToken);
|
|
if (_SerialPort is null)
|
|
{
|
|
string ghostPCLFileName = Path.Combine(AppContext.BaseDirectory, appSettings.SerialConfiguration.GhostPCLFileName);
|
|
if (!File.Exists(ghostPCLFileName))
|
|
throw new Exception("Ghost PCL FileName doesn't Exist!");
|
|
string lincPDFCFileName = Path.Combine(AppContext.BaseDirectory, appSettings.SerialConfiguration.LincPDFCFileName);
|
|
if (!File.Exists(lincPDFCFileName))
|
|
throw new Exception("Linc PDFC FileName doesn't Exist!");
|
|
_SerialPort = new SerialPort
|
|
{
|
|
PortName = appSettings.SerialConfiguration.PortName,
|
|
// BaudRate = 9600,
|
|
BaudRate = 115200,
|
|
DataBits = 8,
|
|
Parity = Parity.None,
|
|
StopBits = StopBits.One,
|
|
// Handshake = Handshake.None,
|
|
Handshake = Handshake.RequestToSend,
|
|
// DtrEnable = true,
|
|
// RtsEnable = true,
|
|
ReadTimeout = 5000
|
|
};
|
|
string[] portNames = SerialPort.GetPortNames();
|
|
string[] matchPortNames = (from l in portNames where l == appSettings.SerialConfiguration.PortName select l).ToArray();
|
|
if (matchPortNames.Length == 0)
|
|
throw new Exception($"Didn't find matching COM port! {string.Join(Environment.NewLine, portNames)}");
|
|
if (matchPortNames.Length != 1)
|
|
throw new Exception($"Matching count is more than one! {string.Join(Environment.NewLine, portNames)}");
|
|
_SerialPort.Open();
|
|
_SerialPort.DiscardInBuffer();
|
|
_SerialPort.DiscardOutBuffer();
|
|
logger.LogDebug("Waiting for data.");
|
|
_SerialPort.PinChanged += PinChanged;
|
|
_SerialPort.DataReceived += DataReceived;
|
|
_SerialPort.ErrorReceived += ErrorReceived;
|
|
}
|
|
SerialPortWriteConditionally(appSettings.SerialConfiguration, logger);
|
|
if (cancellationToken.IsCancellationRequested)
|
|
SerialPortClose();
|
|
return true;
|
|
}
|
|
|
|
} |