- Register Reader Poseidon works - Smart Form - wrong functionality - refactoring
247 lines
8.1 KiB
C#
247 lines
8.1 KiB
C#
using System;
|
|
using System.Text.RegularExpressions;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using NfcC7_DLL.NfcHandler.Protocols;
|
|
using NfcC7_DLL.NfcHandler.Utils;
|
|
|
|
namespace NfcC7_DLL.NfcHandler
|
|
{
|
|
public class NfcHeadService
|
|
{
|
|
|
|
private bool activeHandlerSessioEnabled = false;
|
|
private CliRunner _cliRunner;
|
|
|
|
private SerialPortData serialPort;
|
|
|
|
public NfcHeadService(SerialPortData serialPort)
|
|
{
|
|
this.serialPort = serialPort;
|
|
this._cliRunner = null;
|
|
ValidateCliFileExistence(true);
|
|
}
|
|
|
|
private CliRunner CliRunner
|
|
{
|
|
get { return (_cliRunner != null ? _cliRunner : (_cliRunner = new CliRunner(CliLogging))); }
|
|
}
|
|
|
|
private bool CliLogging
|
|
{
|
|
get { return false; }
|
|
}
|
|
|
|
private static readonly Regex OpticalDataModeRegex = new Regex(
|
|
@"(?im)(?:" +
|
|
@"^\s*OpticalDataMode\s*Id\s*:\s*([^\r\n]+)\s*$" + // old format
|
|
@"|" +
|
|
@"""OpticalDataMode""\s*:\s*""?(0x[0-9A-Fa-f]+|\d+)""?" + // JSON format (handles hex and decimal)
|
|
@")",
|
|
RegexOptions.Compiled);
|
|
|
|
public bool TryGetOpticalDataMode(string result, out string s)
|
|
{
|
|
s = null;
|
|
if (string.IsNullOrEmpty(result))
|
|
return false;
|
|
|
|
var m = OpticalDataModeRegex.Match(result);
|
|
if (!m.Success)
|
|
return false;
|
|
|
|
// one of the groups will be filled
|
|
s = !string.IsNullOrEmpty(m.Groups[1].Value)
|
|
? m.Groups[1].Value.Trim()
|
|
: m.Groups[2].Value.Trim();
|
|
return true;
|
|
}
|
|
|
|
private static readonly Regex DeviceIdRegex = new Regex(
|
|
@"(?im)(?:" +
|
|
@"^\s*Device\s*Id\s*:\s*([^\r\n]+)\s*$" + // old format
|
|
@"|" +
|
|
@"""DeviceId""\s*:\s*""?([0-9]+)""?" + // JSON format
|
|
@")",
|
|
RegexOptions.Compiled);
|
|
|
|
public bool TryGetDeviceId(string result, out string s)
|
|
{
|
|
s = null;
|
|
if (string.IsNullOrEmpty(result))
|
|
return false;
|
|
|
|
var m = DeviceIdRegex.Match(result);
|
|
if (!m.Success)
|
|
return false;
|
|
|
|
// one of the groups will be filled
|
|
s = !string.IsNullOrEmpty(m.Groups[1].Value)
|
|
? m.Groups[1].Value.Trim()
|
|
: m.Groups[2].Value.Trim();
|
|
return true;
|
|
}
|
|
|
|
|
|
private void ValidateCliFileExistence(bool showErrorIfMissing)
|
|
{
|
|
if (serialPort != null)
|
|
{
|
|
if (!serialPort.CliExists)
|
|
{
|
|
throw new Exception("CLI file " + serialPort.SerialPortCmdClientPath +
|
|
" does not exist! Current path: " + Environment.CurrentDirectory);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// ////////////
|
|
/// </summary>
|
|
public string GetSerialNr()
|
|
{
|
|
if (serialPort == null)
|
|
throw new Exception("Serial port not initialized");
|
|
|
|
|
|
Task optoheadDeviceIdTask = CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.DeviceId);
|
|
var timeOut = CliRunner.AddTimeOut(5000);
|
|
var doneTask = CliRunner.WaitAnyFinished(optoheadDeviceIdTask, timeOut);
|
|
if (timeOut == doneTask)
|
|
{
|
|
throw new Exception("Timeout");
|
|
}
|
|
else
|
|
{
|
|
if (optoheadDeviceIdTask is Task<string>)
|
|
{
|
|
string serialNr;
|
|
if (optoheadDeviceIdTask.Status == TaskStatus.Faulted)
|
|
throw new Exception("Error TaskStatus.Faulted");
|
|
string result = (optoheadDeviceIdTask as Task<string>).Result;
|
|
if (TryGetDeviceId(result, out serialNr))
|
|
{
|
|
return serialNr;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
return null;
|
|
}
|
|
|
|
public async Task<string> GetSerialNrAsync()
|
|
{
|
|
if (serialPort == null)
|
|
throw new Exception("Serial port not initialized");
|
|
|
|
var cts = new CancellationTokenSource(); // we own the token
|
|
var sendTask = CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.DeviceId, cts.Token);
|
|
|
|
string output;
|
|
try
|
|
{
|
|
output = await CliRunner.WithTimeout(sendTask, TimeSpan.FromSeconds(15), cts);
|
|
}
|
|
catch (TimeoutException)
|
|
{
|
|
throw new Exception("Timeout");
|
|
}
|
|
|
|
if (TryGetDeviceId(output, out var serialNr))
|
|
return serialNr;
|
|
|
|
throw new Exception("Failed to parse DeviceId from output.");
|
|
}
|
|
|
|
public OptoHeadStatus SetTestingMode(OptoHeadStatus status)
|
|
{
|
|
if (serialPort == null)
|
|
throw new Exception("Serial port not initialized");
|
|
|
|
|
|
Task optoheadMode =
|
|
CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.Optohead, $"0x{((byte)status):X2}");
|
|
var timeOut = CliRunner.AddTimeOut(5000);
|
|
var doneTask = CliRunner.WhenAny();
|
|
if (timeOut == doneTask)
|
|
{
|
|
throw new Exception("Timeout");
|
|
}
|
|
else
|
|
{
|
|
if (optoheadMode is Task<string>)
|
|
{
|
|
string strOpticalDataMode;
|
|
if (optoheadMode.Status == TaskStatus.Faulted)
|
|
throw new Exception("Error TaskStatus.Faulted");
|
|
string result = (optoheadMode as Task<string>).Result;
|
|
if (TryGetOpticalDataMode(result, out strOpticalDataMode))
|
|
{
|
|
byte value;
|
|
|
|
if (strOpticalDataMode.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
|
|
value = Convert.ToByte(strOpticalDataMode, 16); // interpret as hex
|
|
else
|
|
value = Convert.ToByte(strOpticalDataMode); // interpret as decimal
|
|
|
|
OptoHeadStatus optoheadStatus = (OptoHeadStatus)value;
|
|
return optoheadStatus;
|
|
}
|
|
}
|
|
}
|
|
|
|
return OptoHeadStatus.Unknown;
|
|
}
|
|
|
|
public OptoHeadStatus GetTestingMode()
|
|
{
|
|
if (serialPort == null)
|
|
throw new Exception("Serial port not initialized");
|
|
|
|
|
|
Task optoheadMode = CliRunner.AddSendAsync(serialPort, SerialPortData.EMeterArg.Optohead);
|
|
var timeOut = CliRunner.AddTimeOut(5000);
|
|
var doneTask = CliRunner.WhenAny();
|
|
if (timeOut == doneTask)
|
|
{
|
|
throw new Exception("Timeout");
|
|
}
|
|
else
|
|
{
|
|
if (optoheadMode is Task<string>)
|
|
{
|
|
string strOpticalDataMode;
|
|
if (optoheadMode.Status == TaskStatus.Faulted)
|
|
throw new Exception("Error TaskStatus.Faulted");
|
|
string result = (optoheadMode as Task<string>).Result;
|
|
if (TryGetOpticalDataMode(result, out strOpticalDataMode))
|
|
{
|
|
byte value;
|
|
|
|
if (strOpticalDataMode.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
|
|
value = Convert.ToByte(strOpticalDataMode, 16); // interpret as hex
|
|
else
|
|
value = Convert.ToByte(strOpticalDataMode); // interpret as decimal
|
|
|
|
OptoHeadStatus optoheadStatus = (OptoHeadStatus)value;
|
|
return optoheadStatus;
|
|
}
|
|
}
|
|
}
|
|
|
|
return OptoHeadStatus.Unknown;
|
|
}
|
|
|
|
private void SendCommand()
|
|
{
|
|
|
|
}
|
|
|
|
private string RawDataAnswer()
|
|
{
|
|
return "";
|
|
}
|
|
}
|
|
} |