tbf/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/IperlHatProtocol/IperlHatFrameBuilder.cs

157 lines
5.3 KiB
C#

using System;
using System.Collections.Generic;
using TBF.Rig.TestMethods.iPerlCommunication.communication.C4.diagnosticLed;
using TBF.Rig.TestMethods.iPerlCommunication.communication.C4.protocolCommons;
namespace TBF.Rig.TestMethods.iPerlCommunication.communication.C4.IperlHatProtocol
{
public sealed class IperlHatFrameBuilder
{
private byte _direction;
private readonly List<byte> _commandBytes = new List<byte>();
private readonly List<byte> _payload = new List<byte>();
public IperlHatFrameBuilder RequestResponse(bool enabled)
{
_direction = enabled ? TestMethods.iPerlCommunication.communication.C4.IperlHatProtocol.IperlHatProtocolConstants.Write : TestMethods.iPerlCommunication.communication.C4.IperlHatProtocol.IperlHatProtocolConstants.Read;
return this;
}
public IperlHatFrameBuilder AddCommand(ProtocolCommand command)
{
_commandBytes.Add((byte)command);
return this;
}
public IperlHatFrameBuilder AddSubCommand(ProtocolCommand subCommand)
{
if (_commandBytes.Count == 0 ||
_commandBytes[0] != (byte)ProtocolCommand.DeviceSpecific)
throw new InvalidOperationException(
"Sub-command is only valid for DeviceSpecific (0xFD) commands.");
_commandBytes.Add((byte)subCommand);
return this;
}
public IperlHatFrameBuilder AddSubCommand(ProtocolStatuses subCommand)
{
if (_commandBytes.Count == 0 ||
_commandBytes[0] != (byte)ProtocolCommand.SetState)
throw new InvalidOperationException(
"Sub-command is only valid for SetState (0xA1) commands.");
_commandBytes.Add((byte)subCommand);
return this;
}
public IperlHatFrameBuilder AddDeviceCommand(
ProtocolDeviceSubCommand subCommand)
{
_commandBytes.Add((byte)ProtocolCommand.DeviceSpecific);
_commandBytes.Add((byte)subCommand);
return this;
}
public IperlHatFrameBuilder SetVersionCommand()
{
_commandBytes.Add((byte)ProtocolCommand.Question);
_payload.AddRange(TestMethods.iPerlCommunication.communication.C4.IperlHatProtocol.IperlHatProtocolConstants.Version);
return this;
}
public IperlHatFrameBuilder AddPayload(byte[] payload)
{
if (payload != null)
_payload.AddRange(payload);
return this;
}
public IperlHatFrameBuilder AddPayload(DiagnosticLedState state)
{
_payload.Add((byte)state);
return this;
}
public IperlHatFrameBuilder AddPayload(byte payload)
{
_payload.Add(payload);
return this;
}
public IperlHatFrameBuilder AddDiagnosticLedState(DiagnosticLedState state)
{
RequestResponse(true);
AddDeviceCommand(ProtocolDeviceSubCommand.SetDiagnosticLEDState);
AddPayload((byte)state);
return this;
}
public IperlHatFrameBuilder AddNullTerminatedAscii(string text)
{
if (!string.IsNullOrEmpty(text))
_commandBytes.AddRange(
System.Text.Encoding.ASCII.GetBytes(text));
_commandBytes.Add(0x00);
return this;
}
public IperlHatFrame BuildFrame()
{
if (_commandBytes.Count == 0)
throw new InvalidOperationException("No command specified.");
byte length = (byte)(4 + _commandBytes.Count + _payload.Count); // 4 = START + dirrection + LEN + END
return new IperlHatFrame(
TestMethods.iPerlCommunication.communication.C4.IperlHatProtocol.IperlHatProtocolConstants.Start,
_direction,
length,
_commandBytes.ToArray(),
_payload.ToArray(),
TestMethods.iPerlCommunication.communication.C4.IperlHatProtocol.IperlHatProtocolConstants.End);
}
public byte[] BuildBytes()
{
IperlHatFrame frame = BuildFrame();
if (frame.CommandInformation.Length > 0 && frame.CommandInformation[0] == TestMethods.iPerlCommunication.communication.C4.IperlHatProtocol.IperlHatProtocolConstants.Question)
{
var bytes = new List<byte>
{
frame.Start,
frame.Direction,
};
bytes.AddRange(frame.CommandInformation);
bytes.AddRange(frame.Payload);
bytes.Add(frame.End);
return bytes.ToArray();
}
else
{
var bytes = new List<byte>
{
frame.Start,
frame.Direction,
frame.Length,
};
bytes.AddRange(frame.CommandInformation);
bytes.AddRange(frame.Payload);
bytes.Add(frame.End);
return bytes.ToArray();
}
}
}
}