using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using log4net;
namespace CanSimulator
{
///
/// 接收滤波器配置
///
public sealed class AcceptanceFilter
{
///
/// 滤波器 ID(匹配值)
///
public uint FilterId { get; set; }
///
/// 掩码(为 1 的位参与比较)
///
public uint Mask { get; set; } = 0x7FF; // 默认标准帧全匹配
///
/// 是否为扩展帧滤波器
///
public bool IsExtended { get; set; }
///
/// 检查给定帧 ID 是否通过此滤波器
///
public bool Accepts(uint frameId, bool isExtended)
{
if (IsExtended != isExtended) return false;
return (frameId & Mask) == (FilterId & Mask);
}
}
///
/// 虚拟 CAN 节点
/// 模拟一个 CAN 通讯卡的端点,具有发送和接收功能
///
public sealed class CanNode
{
private static readonly ILog Log = LogManager.GetLogger(typeof(CanNode));
///
/// 节点唯一标识
///
public string NodeId { get; }
///
/// 节点名称(可选描述)
///
public string Name { get; set; }
///
/// 节点是否已激活(连接到总线)
///
public bool IsActive { get; private set; }
///
/// 接收滤波器列表
///
private readonly List _filters = new();
///
/// 接收邮箱(FIFO 队列)
///
private readonly ConcurrentQueue _receiveMailbox = new();
///
/// 发送历史记录
///
private readonly ConcurrentQueue _sendHistory = new();
///
/// 最大邮箱容量
///
public int MaxMailboxSize { get; set; } = 1000;
///
/// 最大历史记录容量
///
public int MaxHistorySize { get; set; } = 500;
///
/// 接收帧计数器
///
public long RxCount { get; private set; }
///
/// 发送帧计数器
///
public long TxCount { get; private set; }
///
/// 错误计数器
///
public long ErrorCount { get; private set; }
///
/// 是否启用自动响应模式(收到帧后原封不动回复)
///
public bool AutoResponseEnabled { get; set; }
///
/// 自动响应延迟(毫秒)- 模拟真实设备响应时间
///
public int AutoResponseDelayMs { get; set; } = 0;
///
/// 自动响应事件(用于日志/监控)
///
public event EventHandler? AutoResponseSent;
///
/// 帧接收事件
///
public event EventHandler? FrameReceived;
///
/// 帧发送事件
///
public event EventHandler? FrameSent;
public CanNode(string nodeId, string? name = null)
{
NodeId = nodeId ?? throw new ArgumentNullException(nameof(nodeId));
Name = name ?? nodeId;
}
///
/// 激活节点(连接到总线)
///
public void Activate()
{
IsActive = true;
Log.Info($"[CanNode] 节点 {NodeId} ({Name}) 已激活");
}
///
/// 停用节点(从总线断开)
///
public void Deactivate()
{
IsActive = false;
Log.Info($"[CanNode] 节点 {NodeId} ({Name}) 已停用");
}
///
/// 添加接收滤波器
///
public void AddFilter(AcceptanceFilter filter)
{
lock (_filters)
{
_filters.Add(filter);
}
Log.Debug($"[CanNode] 节点 {NodeId} 添加滤波器: ID=0x{filter.FilterId:X3}, Mask=0x{filter.Mask:X3}");
}
///
/// 清除所有滤波器
///
public void ClearFilters()
{
lock (_filters)
{
_filters.Clear();
}
Log.Debug($"[CanNode] 节点 {NodeId} 清除所有滤波器");
}
///
/// 设置通配符滤波器(接收所有帧)
///
public void SetPromiscuousMode()
{
lock (_filters)
{
_filters.Clear();
_filters.Add(new AcceptanceFilter { FilterId = 0, Mask = 0, IsExtended = false });
_filters.Add(new AcceptanceFilter { FilterId = 0, Mask = 0, IsExtended = true });
}
Log.Debug($"[CanNode] 节点 {NodeId} 设置为混杂模式(接收所有帧)");
}
///
/// 检查帧是否通过滤波器
///
internal bool AcceptsFrame(CanFrame frame)
{
lock (_filters)
{
// 如果没有设置滤波器,默认拒绝
if (_filters.Count == 0) return false;
// 任一滤波器匹配即接受
return _filters.Any(f => f.Accepts(frame.FrameId, frame.Format == CanFrameFormat.Extended));
}
}
///
/// 接收帧(由总线调用)
///
internal void ReceiveFrame(CanFrame frame)
{
if (!IsActive) return;
if (!AcceptsFrame(frame)) return;
// 入队接收邮箱
while (_receiveMailbox.Count >= MaxMailboxSize)
{
_receiveMailbox.TryDequeue(out _); // 丢弃最旧的帧
}
_receiveMailbox.Enqueue(frame);
RxCount++;
// 触发事件
FrameReceived?.Invoke(this, frame);
Log.Debug($"[CanNode] 节点 {NodeId} 接收帧: {frame}");
}
///
/// 发送帧
///
public void SendFrame(CanFrame frame)
{
if (!IsActive)
{
ErrorCount++;
throw new InvalidOperationException($"节点 {NodeId} 未激活,无法发送帧");
}
frame.SourceNodeId = NodeId;
frame.Timestamp = DateTime.Now;
// 记录发送历史
while (_sendHistory.Count >= MaxHistorySize)
{
_sendHistory.TryDequeue(out _);
}
_sendHistory.Enqueue(frame);
TxCount++;
// 触发事件(由总线处理路由)
FrameSent?.Invoke(this, frame);
Log.Debug($"[CanNode] 节点 {NodeId} 发送帧: {frame}");
}
///
/// 从接收邮箱中取出一帧
///
public bool TryDequeueReceived(out CanFrame? frame)
{
return _receiveMailbox.TryDequeue(out frame);
}
///
/// 查看接收邮箱中的所有帧(不移除)
///
public List PeekReceiveMailbox()
{
return _receiveMailbox.ToList();
}
///
/// 清空接收邮箱
///
public void ClearReceiveMailbox()
{
while (_receiveMailbox.TryDequeue(out _)) { }
Log.Debug($"[CanNode] 节点 {NodeId} 清空接收邮箱");
}
///
/// 获取发送历史
///
public List GetSendHistory()
{
return _sendHistory.ToList();
}
///
/// 清空发送历史
///
public void ClearSendHistory()
{
while (_sendHistory.TryDequeue(out _)) { }
}
///
/// 重置节点统计
///
public void ResetCounters()
{
RxCount = 0;
TxCount = 0;
ErrorCount = 0;
}
///
/// 获取节点状态摘要
///
public string GetStatusSummary()
{
return $"Node={NodeId}, Active={IsActive}, Rx={RxCount}, Tx={TxCount}, Err={ErrorCount}, Mailbox={_receiveMailbox.Count}";
}
}
}