feat: 更新通信协议

This commit is contained in:
2025-07-16 20:25:43 +08:00
parent 822091243e
commit d551cbe793
4 changed files with 227 additions and 141 deletions

View File

@@ -1,3 +1,4 @@
using Common;
using DotNext;
using Newtonsoft.Json;
@@ -35,32 +36,32 @@ namespace WebProtocol
/// 突发类型
/// </summary>
/// <example>0</example>
public BurstType BurstType { get; set; }
public required BurstType BurstType { get; set; }
/// <summary>
/// 任务ID
/// </summary>
/// <example>1</example>
public byte CommandID { get; set; }
public required byte CommandID { get; set; }
/// <summary>
/// 标识写入还是读取
/// </summary>
/// <example>true</example>
public bool IsWrite { get; set; }
public required bool IsWrite { get; set; }
/// <summary>
/// 突发长度0是32bits255是32bits x 256
/// </summary>
/// <example>255</example>
public byte BurstLength { get; set; }
public required byte BurstLength { get; set; }
/// <summary>
/// 目标地址
/// </summary>
/// <example>0</example>
public UInt32 Address { get; set; }
public required UInt32 Address { get; set; }
/// <summary>
/// 转换为Json格式字符串
@@ -84,23 +85,29 @@ namespace WebProtocol
WriteResp
};
/// <summary>
/// 时间戳
/// </summary>
/// <example>1234567</example>
public required UInt32 Timestamp { get; set; }
/// <summary>
/// 数据包类型
/// </summary>
/// <example>0</example>
public PackType Type { get; set; }
public required PackType Type { get; set; }
/// <summary>
/// Task ID
/// </summary>
/// <example>0</example>
public byte CommandID { get; set; }
public required byte CommandID { get; set; }
/// <summary>
/// Whether is succeed to finish command
/// </summary>
/// <example>true</example>
public bool IsSuccess { get; set; }
public required bool IsSuccess { get; set; }
/// <summary>
/// Return Data
@@ -214,12 +221,14 @@ namespace WebProtocol
/// <returns> 字符串 </returns>
public override string ToString()
{
var opts = new SendAddrPackOptions();
opts.BurstType = (BurstType)(commandType >> 6);
opts.CommandID = Convert.ToByte((commandType >> 4) & 0b0011);
opts.IsWrite = Convert.ToBoolean(commandType & 0x01);
opts.BurstLength = burstLength;
opts.Address = address;
var opts = new SendAddrPackOptions()
{
BurstType = (BurstType)(commandType >> 6),
CommandID = Convert.ToByte((commandType >> 4) & 0b0011),
IsWrite = Convert.ToBoolean(commandType & 0x01),
BurstLength = burstLength,
Address = address,
};
return JsonConvert.SerializeObject(opts);
}
@@ -297,8 +306,9 @@ namespace WebProtocol
}
/// <summary> FPGA->Server 读响应包 </summary>
public struct RecvDataPackage
public class RecvDataPackage
{
readonly UInt32 timestamp;
readonly byte sign = (byte)PackSign.RecvData;
readonly byte commandID;
readonly byte resp;
@@ -309,11 +319,13 @@ namespace WebProtocol
/// FPGA->Server 读响应包
/// 构造函数
/// </summary>
/// <param name="timestamp"> 时间戳 </param>
/// <param name="commandID"> 任务ID号 </param>
/// <param name="resp"> 读响应包响应 </param>
/// <param name="bodyData"> 数据 </param>
public RecvDataPackage(byte commandID, byte resp, byte[] bodyData)
public RecvDataPackage(UInt32 timestamp, byte commandID, byte resp, byte[] bodyData)
{
this.timestamp = timestamp;
this.commandID = commandID;
this.resp = resp;
this.bodyData = bodyData;
@@ -322,26 +334,13 @@ namespace WebProtocol
_ = this._reserved;
}
/// <summary>
/// FPGA->Server 读响应包
/// 构造函数
/// </summary>
/// <param name="commandID"> 任务ID号 </param>
/// <param name="isSuccess">是否读取成功</param>
/// <param name="bodyData"> 数据 </param>
public RecvDataPackage(byte commandID, bool isSuccess, byte[] bodyData)
{
this.commandID = commandID;
this.resp = Convert.ToByte(isSuccess);
this.bodyData = bodyData;
}
/// <summary>
/// 通过接受包选项构建读响应包
/// </summary>
/// <param name="opts">接收包(读响应包和写响应包)选项</param>
public RecvDataPackage(RecvPackOptions opts)
{
this.timestamp = opts.Timestamp;
this.commandID = opts.CommandID;
this.resp = Convert.ToByte(opts.IsSuccess ? 0b10 : 0b00);
this.bodyData = opts.Data ?? (byte[])[0, 0, 0, 0];
@@ -354,11 +353,14 @@ namespace WebProtocol
{
get
{
var opts = new RecvPackOptions();
opts.Type = RecvPackOptions.PackType.ReadResp;
opts.CommandID = commandID;
opts.IsSuccess = Convert.ToBoolean((resp >> 1) == 0b01 ? false : true);
opts.Data = bodyData;
var opts = new RecvPackOptions()
{
Timestamp = this.timestamp,
Type = RecvPackOptions.PackType.ReadResp,
CommandID = this.commandID,
IsSuccess = Convert.ToBoolean((resp >> 1) == 0b01 ? false : true),
Data = this.bodyData,
};
return opts;
}
@@ -369,7 +371,7 @@ namespace WebProtocol
/// </summary>
public bool IsSuccessful
{
get { return Convert.ToBoolean((resp >> 1) == 0b01 ? false : true); }
get { return Convert.ToBoolean((this.resp >> 1) == 0b01 ? false : true); }
}
/// <summary>
@@ -379,12 +381,16 @@ namespace WebProtocol
/// <returns>读响应包</returns>
public static Result<RecvDataPackage> FromBytes(byte[] bytes)
{
if (bytes[0] != (byte)PackSign.RecvData)
if (bytes[4] != (byte)PackSign.RecvData)
return new(new ArgumentException(
$"The sign of bytes is not RecvData Package, Sign: 0x{BitConverter.ToString([bytes[0]])}",
nameof(bytes)
));
return new RecvDataPackage(bytes[1], bytes[2], bytes[4..]);
return new RecvDataPackage(
Number.BytesToUInt32(bytes[..4]).Value,
bytes[5],
bytes[6],
bytes[8..]);
}
/// <summary>
@@ -394,13 +400,16 @@ namespace WebProtocol
public byte[] ToBytes()
{
var bodyDataLen = bodyData.Length;
var arr = new byte[4 + bodyDataLen];
var arr = new byte[8 + bodyDataLen];
arr[0] = this.sign;
arr[1] = this.commandID;
arr[2] = this.resp;
Buffer.BlockCopy(
Number.UInt32ArrayToBytes([this.timestamp]).Value, 0, arr, 0, 4);
arr[4] = this.sign;
arr[5] = this.commandID;
arr[6] = this.resp;
arr[7] = this.resp;
Array.Copy(bodyData, 0, arr, 4, bodyDataLen);
Array.Copy(bodyData, 0, arr, 8, bodyDataLen);
return arr;
}
@@ -408,8 +417,9 @@ namespace WebProtocol
}
/// <summary> 写响应包 </summary>
public struct RecvRespPackage
public class RecvRespPackage
{
readonly UInt32 timestamp;
readonly byte sign = (byte)PackSign.RecvResp;
readonly byte commandID;
readonly byte resp;
@@ -418,10 +428,12 @@ namespace WebProtocol
/// <summary>
/// 构建写响应包
/// </summary>
/// <param name="timestamp">时间戳</param>
/// <param name="commandID">任务ID</param>
/// <param name="resp">写响应</param>
public RecvRespPackage(byte commandID, byte resp)
public RecvRespPackage(UInt32 timestamp, byte commandID, byte resp)
{
this.timestamp = timestamp;
this.commandID = commandID;
this.resp = resp;
@@ -429,23 +441,13 @@ namespace WebProtocol
_ = this._reserved;
}
/// <summary>
/// 构建写响应包
/// </summary>
/// <param name="commandID">任务ID</param>
/// <param name="isSuccess">是否写成功</param>
public RecvRespPackage(byte commandID, bool isSuccess)
{
this.commandID = commandID;
this.resp = Convert.ToByte(isSuccess);
}
/// <summary>
/// 通过接受包选项构建写响应包
/// </summary>
/// <param name="opts">接收包(读响应包和写响应包)选项</param>
public RecvRespPackage(RecvPackOptions opts)
{
this.timestamp = opts.Timestamp;
this.commandID = opts.CommandID;
this.resp = Convert.ToByte(opts.IsSuccess ? 0b10 : 0b00);
}
@@ -457,11 +459,14 @@ namespace WebProtocol
{
get
{
var opts = new RecvPackOptions();
opts.Type = RecvPackOptions.PackType.WriteResp;
opts.CommandID = commandID;
opts.IsSuccess = Convert.ToBoolean((resp >> 1) == 0b01 ? false : true);
opts.Data = null;
var opts = new RecvPackOptions()
{
Timestamp = this.timestamp,
Type = RecvPackOptions.PackType.WriteResp,
CommandID = commandID,
IsSuccess = Convert.ToBoolean((resp >> 1) == 0b01 ? false : true),
Data = null,
};
return opts;
}
@@ -472,7 +477,7 @@ namespace WebProtocol
/// </summary>
public bool IsSuccessful
{
get { return Convert.ToBoolean((resp >> 1) == 0b01 ? false : true); }
get { return Convert.ToBoolean((this.resp >> 1) == 0b01 ? false : true); }
}
/// <summary>
@@ -482,12 +487,13 @@ namespace WebProtocol
/// <returns>写响应包</returns>
public static Result<RecvRespPackage> FromBytes(byte[] bytes)
{
if (bytes[0] != (byte)PackSign.RecvResp)
if (bytes[4] != (byte)PackSign.RecvResp)
return new(new ArgumentException(
$"The sign of bytes is not RecvResp Package, Sign: 0x{BitConverter.ToString([bytes[0]])}",
$"The sign of bytes is not RecvResp Package, Sign: 0x{BitConverter.ToString([bytes[4]])}",
nameof(bytes)
));
return new RecvRespPackage(bytes[1], bytes[2]);
var timestamp = Number.BytesToUInt32(bytes[..4]).Value;
return new RecvRespPackage(timestamp, bytes[5], bytes[6]);
}
/// <summary>
@@ -496,11 +502,13 @@ namespace WebProtocol
/// <returns>字节数组</returns>
public byte[] ToBytes()
{
var arr = new byte[4];
arr[0] = this.sign;
arr[1] = this.commandID;
arr[2] = this.resp;
var arr = new byte[8];
Buffer.BlockCopy(
Number.UInt32ArrayToBytes([this.timestamp]).Value, 0, arr, 0, 4);
arr[4] = this.sign;
arr[5] = this.commandID;
arr[6] = this.resp;
arr[7] = this._reserved;
return arr;
}