tbf/TBF/Rig/RegisterReaders/iPerlASICReader/communication/C4/TouchReadFrameBuilder.cs

115 lines
3.2 KiB
C#

using System;
using System.Collections.Generic;
namespace TBF.Rig.RegisterReaders.iPerlASICReader.communication.C4
{
public sealed class TouchReadFrameBuilder
{
private const byte START = 0x0D;
private byte _control;
private readonly List<byte> _information = new List<byte>();
public TouchReadFrameBuilder RequestResponse(bool enabled)
{
_control = enabled ? (byte)0x08 : (byte)0x00;
return this;
}
public TouchReadFrameBuilder AddCommand(TouchReadCommand command)
{
_information.Add((byte)command);
return this;
}
public TouchReadFrameBuilder AddSubCommand(TouchReadDeviceSubCommand subCommand)
{
if (_information.Count == 0 ||
_information[0] != (byte)TouchReadCommand.DeviceSpecific)
throw new InvalidOperationException(
"Sub-command is only valid for DeviceSpecific (0xFD) commands.");
_information.Add((byte)subCommand);
return this;
}
public TouchReadFrameBuilder AddDeviceCommand(
TouchReadDeviceSubCommand subCommand)
{
_information.Add((byte)TouchReadCommand.DeviceSpecific);
_information.Add((byte)subCommand);
return this;
}
public TouchReadFrameBuilder AddPayload(byte[] payload)
{
if (payload != null)
_information.AddRange(payload);
return this;
}
public TouchReadFrameBuilder AddNullTerminatedAscii(string text)
{
if (!string.IsNullOrEmpty(text))
_information.AddRange(
System.Text.Encoding.ASCII.GetBytes(text));
_information.Add(0x00);
return this;
}
public TouchReadFrame BuildFrame()
{
if (_information.Count == 0)
throw new InvalidOperationException("No command specified.");
byte length = (byte)(1 + _information.Count + 2);
var raw = new List<byte>
{
START,
length,
_control
};
raw.AddRange(_information);
ushort checksum = CalculateChecksum(raw);
raw.Add((byte)(checksum >> 8));
raw.Add((byte)(checksum & 0xFF));
return new TouchReadFrame(
START,
length,
_control,
_information.ToArray(),
checksum);
}
public byte[] BuildBytes()
{
TouchReadFrame frame = BuildFrame();
var bytes = new List<byte>
{
frame.Start,
frame.Length,
frame.Control
};
bytes.AddRange(frame.Information);
bytes.Add((byte)(frame.Checksum >> 8));
bytes.Add((byte)(frame.Checksum & 0xFF));
return bytes.ToArray();
}
private static ushort CalculateChecksum(IEnumerable<byte> data)
{
ushort sum = 0;
foreach (var b in data)
sum += b;
return sum;
}
}
}