From 9d1660270272180cd71147d6ddd53d1382643d2e Mon Sep 17 00:00:00 2001
From: wenxiangchao <wenxiangchao@ihengxin.com.cn>
Date: 星期一, 02 十一月 2026 18:00:14 +0800
Subject: [PATCH] merge: 并入远程 Initial commit 作为历史根节点

---
 CanSimulator/CanFrame.cs |  130 +++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 130 insertions(+), 0 deletions(-)

diff --git a/CanSimulator/CanFrame.cs b/CanSimulator/CanFrame.cs
new file mode 100644
index 0000000..c70b60c
--- /dev/null
+++ b/CanSimulator/CanFrame.cs
@@ -0,0 +1,130 @@
+using System;
+
+namespace CanSimulator
+{
+    /// <summary>
+    /// CAN 甯ф牸寮忕被鍨�
+    /// </summary>
+    public enum CanFrameFormat
+    {
+        /// <summary>鏍囧噯甯� (11-bit ID)</summary>
+        Standard,
+        /// <summary>鎵╁睍甯� (29-bit ID)</summary>
+        Extended
+    }
+
+    /// <summary>
+    /// CAN 甯х被鍨�
+    /// </summary>
+    public enum CanFrameType
+    {
+        /// <summary>鏁版嵁甯�</summary>
+        Data,
+        /// <summary>杩滅▼甯�</summary>
+        Remote
+    }
+
+    /// <summary>
+    /// CAN 鎬荤嚎甯ф暟鎹粨鏋�
+    /// </summary>
+    public sealed class CanFrame
+    {
+        /// <summary>
+        /// 甯� ID锛堟爣鍑嗗抚 11-bit锛屾墿灞曞抚 29-bit锛�
+        /// </summary>
+        public uint FrameId { get; set; }
+
+        /// <summary>
+        /// 甯ф牸寮忥紙鏍囧噯/鎵╁睍锛�
+        /// </summary>
+        public CanFrameFormat Format { get; set; } = CanFrameFormat.Standard;
+
+        /// <summary>
+        /// 甯х被鍨嬶紙鏁版嵁甯�/杩滅▼甯э級
+        /// </summary>
+        public CanFrameType Type { get; set; } = CanFrameType.Data;
+
+        /// <summary>
+        /// 鏁版嵁璐熻浇锛堟渶澶� 8 瀛楄妭锛孋AN FD 鍙揪 64 瀛楄妭锛�
+        /// </summary>
+        public byte[] Data { get; set; } = Array.Empty<byte>();
+
+        /// <summary>
+        /// 鏃堕棿鎴�
+        /// </summary>
+        public DateTime Timestamp { get; set; } = DateTime.Now;
+
+        /// <summary>
+        /// 鍙戦�佽妭鐐规爣璇�
+        /// </summary>
+        public string SourceNodeId { get; set; } = string.Empty;
+
+        /// <summary>
+        /// DLC (Data Length Code)
+        /// </summary>
+        public int Dlc => Data.Length;
+
+        /// <summary>
+        /// 灏嗗抚 ID 鏍煎紡鍖栦负鍗佸叚杩涘埗瀛楃涓�
+        /// </summary>
+        public string FrameIdHex => Format == CanFrameFormat.Extended
+            ? $"0x{FrameId:X8}"
+            : $"0x{FrameId:X3}";
+
+        /// <summary>
+        /// 灏嗘暟鎹牸寮忓寲涓哄崄鍏繘鍒跺瓧绗︿覆
+        /// </summary>
+        public string DataHex => BitConverter.ToString(Data).Replace("-", " ");
+
+        /// <summary>
+        /// 浠庡崄鍏繘鍒跺瓧绗︿覆瑙f瀽甯� ID
+        /// </summary>
+        public static uint ParseFrameId(string frameIdStr)
+        {
+            if (string.IsNullOrWhiteSpace(frameIdStr))
+                throw new ArgumentException("甯� ID 涓嶈兘涓虹┖", nameof(frameIdStr));
+
+            if (frameIdStr.StartsWith("0x", StringComparison.OrdinalIgnoreCase))
+            {
+                if (!uint.TryParse(frameIdStr.Substring(2), System.Globalization.NumberStyles.HexNumber, null, out uint id))
+                    throw new ArgumentException($"鏃犳硶瑙f瀽甯� ID: {frameIdStr}");
+                return id;
+            }
+            else
+            {
+                if (!uint.TryParse(frameIdStr, out uint id))
+                    throw new ArgumentException($"鏃犳硶瑙f瀽甯� ID: {frameIdStr}");
+                return id;
+            }
+        }
+
+        /// <summary>
+        /// 浠庡崄鍏繘鍒跺瓧绗︿覆瑙f瀽鏁版嵁
+        /// </summary>
+        public static byte[] ParseData(string dataStr)
+        {
+            if (string.IsNullOrWhiteSpace(dataStr))
+                return Array.Empty<byte>();
+
+            try
+            {
+                var parts = dataStr.Split(new[] { ' ', '-', ',' }, StringSplitOptions.RemoveEmptyEntries);
+                var bytes = new byte[parts.Length];
+                for (int i = 0; i < parts.Length; i++)
+                {
+                    bytes[i] = byte.Parse(parts[i], System.Globalization.NumberStyles.HexNumber);
+                }
+                return bytes;
+            }
+            catch (Exception ex)
+            {
+                throw new ArgumentException($"鏃犳硶瑙f瀽鏁版嵁瀛楃涓�: {dataStr}, 閿欒: {ex.Message}");
+            }
+        }
+
+        public override string ToString()
+        {
+            return $"[{Timestamp:HH:mm:ss.fff}] {FrameIdHex} [{Dlc}] {DataHex} (from {SourceNodeId})";
+        }
+    }
+}

--
Gitblit v1.9.1