using System;
using System.Runtime.InteropServices;
namespace CapMachine.Wpf.CanDrive.ZlgCan
{
///
/// 供 DBC 编解码/Marshal 使用的原生 CAN 帧结构(与 zlgcan can_frame 二进制布局兼容)。
///
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct ZlgNativeCanFrame
{
public uint can_id;
public byte can_dlc;
public byte __pad;
public byte __res0;
public byte __res1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 8)]
public byte[] data;
///
/// 创建 CAN 帧。
///
/// can_id(包含扩展帧等标志位)。
/// 数据(0~8)。
/// 是否请求发送回显。
/// 原生 CAN 帧。
public static ZlgNativeCanFrame Create(uint canId, byte[] payload, bool requestTxEcho)
{
var len = Math.Min(8, payload?.Length ?? 0);
var frame = new ZlgNativeCanFrame
{
can_id = canId,
can_dlc = (byte)len,
__pad = 0,
__res0 = 0,
__res1 = 0,
data = new byte[8]
};
if (len > 0 && payload != null)
{
Array.Copy(payload, frame.data, len);
}
if (requestTxEcho)
{
frame.__pad |= 0x20;
}
return frame;
}
}
///
/// 供 DBC 编解码/Marshal 使用的原生 CANFD 帧结构(与 zlgcan canfd_frame 二进制布局兼容)。
///
[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct ZlgNativeCanFdFrame
{
public uint can_id;
public byte len;
public byte flags;
public byte __res0;
public byte __res1;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 64)]
public byte[] data;
///
/// 创建 CANFD 帧。
///
/// can_id(包含扩展帧等标志位)。
/// 数据(0~64)。
/// 是否请求发送回显。
/// 原生 CANFD 帧。
public static ZlgNativeCanFdFrame Create(uint canId, byte[] payload, bool requestTxEcho)
{
var len = Math.Min(64, payload?.Length ?? 0);
var frame = new ZlgNativeCanFdFrame
{
can_id = canId,
len = (byte)len,
flags = 0,
__res0 = 0,
__res1 = 0,
data = new byte[64]
};
if (len > 0 && payload != null)
{
Array.Copy(payload, frame.data, len);
}
if (requestTxEcho)
{
frame.flags |= 0x20;
}
return frame;
}
}
}