行,
我必须创建一个C#库,它可以向设备发送命令并通过串行端口(或其他通信方法)处理命令特定的响应和广播。由于某些设备实现扩展命令集,库还必须能够处理其他库中保存的请求和响应扩展,但必须可以选择是否使用这些扩展命令(我想在客户端应用程序中使用反射)。我创建了一个类型的Packet类,它能够创建数据包并添加其有效负载,计算其校验和并将数据包写入流。
public class Packet
{
internal PacketHeaderType Header { get; private set; }
internal List<byte> Payload { get; private set; }
protected int PayloadLength { get { return Payload.Count; } }
protected byte HeaderByte { get { return (byte)((Convert.ToByte(Header) << 4) | PayloadLength); } } //we need to add the packet length to the lower nibble of the header before sending
public Packet(PacketHeaderType header, List<byte> payload)
{
this.Header = header;
this.Payload = new List<byte>(payload);
}
public Packet(PacketHeaderType headerByte)
{
this.Header = headerByte;
this.Payload = new List<byte>();
}
internal byte XorByte
{
get
{
Byte xorByte = Convert.ToByte(HeaderByte);
for (int i = 0; i < PayloadLength; i++)
xorByte ^= Payload.ToArray()[i];
return xorByte;
}
}
public async Task WriteAsync(Stream stream, bool flush = true, CancellationToken token = default(CancellationToken))
{
var buffer = new List<byte>();
buffer.Add(HeaderByte);
if (Payload != null && PayloadLength > 0)
{
buffer.AddRange(Payload);
}
buffer.Add(XorByte);
await stream.WriteAsync(buffer.ToArray(), 0, buffer.Count);
if (flush)
{
await stream.FlushAsync();
}
}
}
我还创建了为每个有效命令实现Type数据包的子类。 最后,我还创建了一个类型的PacketHandler类,它能够从流中读取字节并将其创建为数据包对象。
我设想使用该库的方式如下:
public async string GetCmdStnSoftwareVersion()
{
var msgReq = new CmdStnSoftwareVersionReqMessage();
await msgReq.WriteAsync(sPort.BaseStream);
await var response = msgReq.GetResponse(5); //5 = timeout in seconds!
return String.Format("{0}.{1}", response.Major, response.Minor);
}
我所坚持的是处理响应的良好模式和/或示例实现,这与实现扩展库兼容。任何人都可以提供意见吗?