Add protocolCommons classes and enhance RadioService with support for CalibrationFactor, VersionType, ReadingUnits, and FlipMode operations. Add corresponding unit tests for validation. Update project files.
592 lines
19 KiB
C#
592 lines
19 KiB
C#
using System;
|
|
using System.Text;
|
|
using System.Text.RegularExpressions;
|
|
using log4net;
|
|
using TBF.Rig.TestMethods.iPerlCommunication.communication.C4.diagnosticLed;
|
|
using TBF.Rig.TestMethods.iPerlCommunication.communication.C4.IperlHatProtocol;
|
|
using TBF.Rig.TestMethods.iPerlCommunication.communication.C4.protocolCommons;
|
|
using TBF.Rig.TestMethods.iPerlCommunication.communication.C4.wiredProtocol;
|
|
using TBF.Rig.TestMethods.iPerlCommunication.communication.Utils;
|
|
using TBF.Rig.TestMethods.iPerlCommunication.iPerlHead;
|
|
|
|
namespace TBF.Rig.TestMethods.iPerlCommunication.communication
|
|
{
|
|
public class RadioService
|
|
{
|
|
private static readonly ILog log = LogManager.GetLogger(typeof(RadioService));
|
|
|
|
static string okResponse = "Command complete, no errors";
|
|
static string errorResponse = "Unable to execute";
|
|
|
|
private ISerialDriver serialDriver;
|
|
public RadioService(SerialDriver serialDriver)
|
|
{
|
|
this.serialDriver = serialDriver;
|
|
log.Debug("RadioService created with serialDriver= " + serialDriver + "");
|
|
}
|
|
|
|
public RadioService(ISerialDriver serialDriver)
|
|
{
|
|
this.serialDriver = serialDriver;
|
|
log.Debug("RadioService created with serialDriver= " + serialDriver + "");
|
|
}
|
|
|
|
public string ReadRequest_PCB(ref IperlHead iHead)
|
|
{
|
|
if (!serialDriver.IsOpen())
|
|
{
|
|
serialDriver.Open();
|
|
}
|
|
|
|
var request = new IperlHatFrameBuilder()
|
|
.RequestResponse(true)
|
|
.AddCommand(ProtocolCommand.ViewFactoryId)
|
|
.BuildBytes();
|
|
|
|
|
|
byte[] rawData = serialDriver.SendAndWait(request, 10000);
|
|
if (rawData == null)
|
|
return null;
|
|
|
|
// parse rawData
|
|
var parser = new IperlHatFrameParser();
|
|
IperlHatResponse decoded = parser.Parse(rawData);
|
|
if (decoded.IsOk)
|
|
{
|
|
string asciiPayload = decoded.GetAsciiPayload();
|
|
if (iHead.ConfigStruct != null) // store mechanism
|
|
{
|
|
iHead.ConfigStruct.PCBNumberString = asciiPayload;
|
|
}
|
|
return asciiPayload;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
public ProtocolStatuses GetActivityStatusMode(IperlHead iHead)
|
|
{
|
|
if (!serialDriver.IsOpen())
|
|
serialDriver.Open();
|
|
|
|
var request = new IperlHatFrameBuilder()
|
|
.RequestResponse(true)
|
|
.AddCommand(ProtocolCommand.ViewState)
|
|
.BuildBytes();
|
|
|
|
byte[] rawData = serialDriver.SendAndWait(request, 10000);
|
|
if (rawData == null)
|
|
return ProtocolStatuses.Unknown;
|
|
|
|
var parser = new IperlHatFrameParser();
|
|
IperlHatResponse decoded = parser.Parse(rawData);
|
|
|
|
if (!decoded.IsOk)
|
|
return ProtocolStatuses.Unknown;
|
|
|
|
ProtocolStatuses statusMode = decoded.GetResponse<ProtocolStatuses>(out bool isOK);
|
|
|
|
if (!isOK)
|
|
return ProtocolStatuses.Unknown; // wrong payload
|
|
|
|
return statusMode;
|
|
}
|
|
|
|
public DiagnosticLedState SetOptoStatusMode(IperlHead iHead, DiagnosticLedState opthoStatusMode)
|
|
{
|
|
if (!serialDriver.IsOpen())
|
|
serialDriver.Open();
|
|
|
|
var request = new IperlHatFrameBuilder()
|
|
.RequestResponse(true)
|
|
.AddDeviceCommand(ProtocolDeviceSubCommand.SetDiagnosticLEDState)
|
|
.AddPayload(opthoStatusMode)
|
|
.BuildBytes();
|
|
|
|
byte[] rawData = serialDriver.SendAndWait(request, 10000);
|
|
if (rawData == null)
|
|
return DiagnosticLedState.StatusUnknown;
|
|
|
|
var parser = new IperlHatFrameParser();
|
|
IperlHatResponse decoded = parser.Parse(rawData);
|
|
|
|
log.Debug("SetOptoStatusMode isOK: " + decoded.IsOk);
|
|
// if is response ok - it set it correctly
|
|
if (!decoded.IsOk)
|
|
return DiagnosticLedState.StatusUnknown;
|
|
|
|
return opthoStatusMode;
|
|
}
|
|
|
|
|
|
private static ushort SafeIntToUShort(int value)
|
|
{
|
|
if (value < ushort.MinValue || value > ushort.MaxValue)
|
|
return 0xFD; // your error code
|
|
|
|
return (ushort)value;
|
|
}
|
|
|
|
|
|
public string GetVersion(IperlHead iHead)
|
|
{
|
|
if (!serialDriver.IsOpen())
|
|
{
|
|
serialDriver.Open();
|
|
}
|
|
|
|
byte[] request = new IperlHatFrameBuilder()
|
|
.RequestResponse(true)
|
|
.AddCommand(ProtocolCommand.Question)
|
|
.AddPayload(IperlHatProtocolConstants.Version)
|
|
.BuildBytes();
|
|
|
|
|
|
byte[] rawData = serialDriver.SendAndWait(request, 10000);
|
|
if (rawData == null)
|
|
return "";
|
|
|
|
// parse rawData
|
|
var parser = new IperlHatFrameParser();
|
|
IperlHatResponse decoded = parser.Parse(rawData);
|
|
log.Debug("GetVersion isOK: " + decoded.IsOk);
|
|
if (decoded.IsOk)
|
|
{
|
|
return decoded.GetAsciiPayload();
|
|
}
|
|
|
|
return "";
|
|
}
|
|
|
|
|
|
public VersionTypeResult SetViewVersionAndType(IperlHead iHead)
|
|
{
|
|
if (!serialDriver.IsOpen())
|
|
{
|
|
serialDriver.Open();
|
|
}
|
|
|
|
byte[] request = new IperlHatFrameBuilder()
|
|
.RequestResponse(true)
|
|
.AddCommand(ProtocolCommand.ViewVersionAndType)
|
|
.BuildBytes();
|
|
|
|
byte[] rawData = serialDriver.SendAndWait(request, 5000);
|
|
|
|
if (rawData == null || rawData.Length == 0)
|
|
{
|
|
log.Warn("SetViewVersionAndType: No response received.");
|
|
return null;
|
|
}
|
|
|
|
try
|
|
{
|
|
var parser = new IperlHatFrameParser();
|
|
IperlHatResponse decoded = parser.Parse(rawData);
|
|
|
|
log.Debug("SetViewVersionAndType isOK: " + decoded.IsOk);
|
|
|
|
if (!decoded.IsOk)
|
|
{
|
|
log.Warn("SetViewVersionAndType: Device returned NOK response.");
|
|
return null;
|
|
}
|
|
|
|
if (decoded.Payload == null || decoded.Payload.Length == 0)
|
|
{
|
|
log.Warn("SetViewVersionAndType: Response payload is empty.");
|
|
return null;
|
|
}
|
|
|
|
string payloadText = Encoding.ASCII
|
|
.GetString(decoded.Payload)
|
|
.Trim('\0', '\r', '\n', ' ');
|
|
|
|
log.Debug("SetViewVersionAndType payload: " + payloadText);
|
|
|
|
VersionTypeResult result = VersionTypeResult.ParseVersionTypePayload(payloadText);
|
|
|
|
if (result == null)
|
|
{
|
|
log.Warn(
|
|
"SetViewVersionAndType: Unable to parse response payload: " +
|
|
payloadText);
|
|
|
|
return null;
|
|
}
|
|
|
|
log.Debug("SetViewVersionAndType result: " + result);
|
|
|
|
return result;
|
|
}
|
|
catch (FormatException ex)
|
|
{
|
|
log.Error("SetViewVersionAndType: Invalid response frame.", ex);
|
|
return null;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("SetViewVersionAndType failed.", ex);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public ReadingUnits? ViewReadingUnits(IperlHead iHead)
|
|
{
|
|
if (!serialDriver.IsOpen())
|
|
{
|
|
serialDriver.Open();
|
|
}
|
|
|
|
byte[] request = new IperlHatFrameBuilder()
|
|
.RequestResponse(true)
|
|
.AddCommand(ProtocolCommand.ViewReadingUnits)
|
|
.BuildBytes();
|
|
|
|
byte[] rawData = serialDriver.SendAndWait(request, 5000);
|
|
|
|
if (rawData == null || rawData.Length == 0)
|
|
{
|
|
log.Warn("ViewReadingUnits: No response received.");
|
|
return null;
|
|
}
|
|
|
|
try
|
|
{
|
|
var parser = new IperlHatFrameParser();
|
|
IperlHatResponse decoded = parser.Parse(rawData);
|
|
|
|
log.Debug("ViewReadingUnits isOK: " + decoded.IsOk);
|
|
|
|
if (!decoded.IsOk)
|
|
{
|
|
log.Warn("ViewReadingUnits: Device returned NOK response.");
|
|
return null;
|
|
}
|
|
|
|
ReadingUnits readingUnits =
|
|
decoded.GetResponse<ReadingUnits>(out bool responseOk);
|
|
|
|
if (!responseOk)
|
|
{
|
|
string payload = BitConverter.ToString(decoded.Payload);
|
|
|
|
log.Warn(
|
|
"ViewReadingUnits: Invalid response payload. Payload=" +
|
|
payload);
|
|
|
|
return null;
|
|
}
|
|
|
|
log.Debug(
|
|
$"ViewReadingUnits: {readingUnits} " +
|
|
$"(0x{Convert.ToByte(readingUnits):X2})");
|
|
|
|
return readingUnits;
|
|
}
|
|
catch (FormatException ex)
|
|
{
|
|
log.Error("ViewReadingUnits: Invalid response frame.", ex);
|
|
return null;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("ViewReadingUnits failed.", ex);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public FlipMode? ViewFlipMode(IperlHead iHead)
|
|
{
|
|
if (!serialDriver.IsOpen())
|
|
{
|
|
serialDriver.Open();
|
|
}
|
|
|
|
byte[] request = new TouchReadFrameBuilder()
|
|
.RequestResponse(true)
|
|
.AddDeviceCommand(ProtocolDeviceSubCommand.ViewFlipMode)
|
|
.BuildBytes();
|
|
|
|
byte[] rawData = serialDriver.SendAndWait(request, 5000);
|
|
|
|
if (rawData == null || rawData.Length == 0)
|
|
{
|
|
log.Warn("ViewFlipMode: No response received.");
|
|
return null;
|
|
}
|
|
|
|
try
|
|
{
|
|
var parser = new IperlHatFrameParser();
|
|
IperlHatResponse decoded = parser.Parse(rawData);
|
|
|
|
log.Debug("ViewFlipMode isOK: " + decoded.IsOk);
|
|
|
|
if (!decoded.IsOk)
|
|
{
|
|
log.Warn("ViewFlipMode: Device returned NOK response.");
|
|
return null;
|
|
}
|
|
|
|
FlipMode flipMode =
|
|
decoded.GetResponse<FlipMode>(out bool responseOk);
|
|
|
|
if (!responseOk)
|
|
{
|
|
log.Warn(
|
|
"ViewFlipMode: Invalid payload. Expected one byte " +
|
|
"with value 0x00 or 0x01. Payload=" +
|
|
BitConverter.ToString(decoded.Payload));
|
|
|
|
return null;
|
|
}
|
|
|
|
log.Debug(
|
|
$"ViewFlipMode: {flipMode} " +
|
|
$"(0x{(byte)flipMode:X2})");
|
|
|
|
return flipMode;
|
|
}
|
|
catch (FormatException ex)
|
|
{
|
|
log.Error("ViewFlipMode: Invalid response frame.", ex);
|
|
return null;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("ViewFlipMode failed.", ex);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public CalibrationFactorResult ViewCalibration(IperlHead iHead)
|
|
{
|
|
if (!serialDriver.IsOpen())
|
|
{
|
|
serialDriver.Open();
|
|
}
|
|
|
|
byte[] request = new TouchReadFrameBuilder()
|
|
.RequestResponse(true)
|
|
.AddDeviceCommand(ProtocolDeviceSubCommand.ViewCalibration)
|
|
.BuildBytes();
|
|
|
|
byte[] rawData = serialDriver.SendAndWait(request, 5000);
|
|
|
|
if (rawData == null || rawData.Length == 0)
|
|
{
|
|
log.Warn("ViewCalibration: No response received.");
|
|
return null;
|
|
}
|
|
|
|
try
|
|
{
|
|
var parser = new IperlHatFrameParser();
|
|
IperlHatResponse decoded = parser.Parse(rawData);
|
|
|
|
log.Debug("ViewCalibration isOK: " + decoded.IsOk);
|
|
|
|
if (!decoded.IsOk)
|
|
{
|
|
log.Warn("ViewCalibration: Device returned NOK response.");
|
|
return null;
|
|
}
|
|
|
|
ushort calibrationFactor = decoded.GetUInt16LittleEndian(out bool responseOk);
|
|
|
|
if (!responseOk)
|
|
{
|
|
log.Warn( "ViewCalibration: Invalid payload. Expected uint16 little-endian value. Payload=" + BitConverter.ToString(decoded.Payload));
|
|
return null;
|
|
}
|
|
|
|
double percentage = calibrationFactor * 100.0 / 4096.0;
|
|
|
|
var result = new CalibrationFactorResult
|
|
{
|
|
RawValue = calibrationFactor,
|
|
Percentage = percentage,
|
|
CorrectionPercentage = percentage - 100.0
|
|
};
|
|
|
|
log.Debug("ViewCalibration result: " + result);
|
|
|
|
return result;
|
|
}
|
|
catch (FormatException ex)
|
|
{
|
|
log.Error("ViewCalibration: Invalid response frame.", ex);
|
|
return null;
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
log.Error("ViewCalibration failed.", ex);
|
|
return null;
|
|
}
|
|
}
|
|
|
|
// ----------------------
|
|
|
|
|
|
public bool SetActivityMode_Active(IperlHead iHead)
|
|
{
|
|
if (!serialDriver.IsOpen())
|
|
{
|
|
serialDriver.Open();
|
|
}
|
|
|
|
//Set State to Active 02
|
|
byte[] request = new IperlHatFrameBuilder()
|
|
.RequestResponse(true)
|
|
.AddCommand(ProtocolCommand.SetState)
|
|
.AddSubCommand(ProtocolStatuses.Active) // Active
|
|
.BuildBytes();
|
|
|
|
byte[] rawData = serialDriver.SendAndWait(request, 5000);
|
|
if (rawData == null)
|
|
return false;
|
|
|
|
|
|
// parse rawData
|
|
var parser = new IperlHatFrameParser();
|
|
IperlHatResponse decoded = parser.Parse(rawData);
|
|
log.Debug("SetActivityMode_Active isOK: " + decoded.IsOk);
|
|
if (decoded.IsOk && iHead.ConfigStruct != null)
|
|
{
|
|
iHead.ConfigStruct.StatusMode = ProtocolStatuses.Active;
|
|
}
|
|
return decoded.IsOk;
|
|
}
|
|
|
|
public bool SetActivityMode_Idle(IperlHead iHead)
|
|
{
|
|
if (!serialDriver.IsOpen())
|
|
{
|
|
serialDriver.Open();
|
|
}
|
|
|
|
//Set Activity State Idle 01
|
|
byte[] request = new IperlHatFrameBuilder()
|
|
.RequestResponse(true)
|
|
.AddCommand(ProtocolCommand.SetState)
|
|
.AddSubCommand(ProtocolStatuses.Idle)
|
|
.BuildBytes();
|
|
|
|
byte[] rawData = serialDriver.SendAndWait(request, 5000);
|
|
if (rawData == null)
|
|
return false;
|
|
|
|
|
|
// parse rawData
|
|
var parser = new IperlHatFrameParser();
|
|
IperlHatResponse decoded = parser.Parse(rawData);
|
|
log.Debug("SetActivityMode_Idle isOK: " + decoded.IsOk);
|
|
if (decoded.IsOk && iHead.ConfigStruct != null)
|
|
{
|
|
iHead.ConfigStruct.StatusMode = ProtocolStatuses.Idle;
|
|
}
|
|
return decoded.IsOk;
|
|
}
|
|
|
|
public bool SetOptTestMode(IperlHead iHead)
|
|
{
|
|
if (!serialDriver.IsOpen())
|
|
{
|
|
serialDriver.Open();
|
|
}
|
|
|
|
//Set LED to state 7
|
|
var request = new IperlHatFrameBuilder()
|
|
.RequestResponse(true)
|
|
.AddDeviceCommand(ProtocolDeviceSubCommand.SetDiagnosticLEDState)
|
|
.AddPayload(DiagnosticLedState.State7)
|
|
.BuildBytes();
|
|
|
|
byte[] rawData = serialDriver.SendAndWait(request, 5000);
|
|
if (rawData == null)
|
|
return false;
|
|
|
|
|
|
// parse rawData
|
|
var parser = new IperlHatFrameParser();
|
|
IperlHatResponse decoded = parser.Parse(rawData);
|
|
bool isOk = decoded.IsOk;
|
|
log.Debug("SetOptTestMode isOK: " + isOk);
|
|
if (decoded.IsOk && iHead.ConfigStruct != null)
|
|
{
|
|
iHead.ConfigStruct.OpthoStatusMode = DiagnosticLedState.State7;
|
|
}
|
|
return isOk;
|
|
|
|
}
|
|
|
|
/// <summary>
|
|
/// stop data streaming by LED
|
|
/// </summary>
|
|
/// <param name="iHead"></param>
|
|
/// <returns></returns>
|
|
public bool SetOptActiveMode(IperlHead iHead)
|
|
{
|
|
if (!serialDriver.IsOpen())
|
|
{
|
|
serialDriver.Open();
|
|
}
|
|
|
|
//Set LED to state 1
|
|
var request = new IperlHatFrameBuilder()
|
|
.RequestResponse(true)
|
|
.AddDeviceCommand(ProtocolDeviceSubCommand.SetDiagnosticLEDState)
|
|
.AddPayload(DiagnosticLedState.StateOFF)
|
|
.BuildBytes();
|
|
|
|
byte[] rawData = serialDriver.SendAndWait(request, 5000);
|
|
if (rawData == null)
|
|
return false;
|
|
|
|
|
|
// parse rawData
|
|
var parser = new IperlHatFrameParser();
|
|
IperlHatResponse decoded = parser.Parse(rawData);
|
|
log.Debug("SetOptActiveMode isOK: " + decoded.IsOk);
|
|
if (decoded.IsOk && iHead.ConfigStruct != null)
|
|
{
|
|
iHead.ConfigStruct.OpthoStatusMode = DiagnosticLedState.StateOFF;
|
|
}
|
|
return decoded.IsOk;
|
|
}
|
|
|
|
public string GetUnit(IperlHead iperlHead)
|
|
{
|
|
if (!serialDriver.IsOpen())
|
|
{
|
|
serialDriver.Open();
|
|
}
|
|
|
|
var request = new IperlHatFrameBuilder()
|
|
.RequestResponse(true)
|
|
.AddCommand(ProtocolCommand.ViewFactoryId)
|
|
.BuildBytes();
|
|
|
|
|
|
byte[] rawData = serialDriver.SendAndWait(request, 10000);
|
|
if (rawData == null)
|
|
return null;
|
|
|
|
// parse rawData
|
|
var parser = new IperlHatFrameParser();
|
|
IperlHatResponse decoded = parser.Parse(rawData);
|
|
if (decoded.IsOk)
|
|
{
|
|
string asciiPayload = decoded.GetAsciiPayload();
|
|
if (iperlHead.ConfigStruct != null) // store mechanism
|
|
{
|
|
iperlHead.ConfigStruct.Unit = asciiPayload;
|
|
}
|
|
return asciiPayload;
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
} |