darra-ethercat-master 2.0.7

商业 EtherCAT 主站协议栈 · 实时内核驱动 · 抖动 1µs · Windows + Linux · 多编程语言 · 全协议 · 支持复杂拓扑 + 热插拔 · ethercat.darra.xyz · Commercial EtherCAT Master protocol stack · Real-time kernel driver · 1µs jitter · Multi-platform · Multi-language · Complex topology + hot-plug.
//! 邮箱统计快照 (对齐 C 层 ec_mbx_stats_t / C# MailboxStatistics)

use std::time::SystemTime;

/// 邮箱统计快照 (对齐 C# `MailboxStatistics`).
///
/// 表示单个协议实例在会话内的累计计数, 通过
/// [`crate::utils::ffi::mbx_get_stats_by_master`] 从 DLL 获取.
#[derive(Debug, Clone, Default)]
pub struct MailboxStatistics {
    /// 累计发送事务数
    pub total_sent: u64,
    /// 累计收到响应数 (含错误帧)
    pub total_received: u64,
    /// 累计超时次数
    pub total_timeout: u64,
    /// 累计收到邮箱错误帧数 (对端主动返回 MBX ERROR 或 SDO Abort 等)
    pub total_mailbox_error: u64,
    /// 累计协议错误次数 (类型不匹配 / counter 不匹配 / WKC 失败)
    pub total_protocol_error: u64,
    /// 累计被取消的事务数
    pub total_cancelled: u64,
    /// 最近一次错误码 (协议相关, 0 表示无)
    pub last_error_code: u32,
    /// 最近一次错误时刻 (UTC); 无错误则为 None
    pub last_error_time: Option<SystemTime>,
    /// 平均事务延迟 (微秒)
    pub average_latency_us: f64,
}

impl MailboxStatistics {
    /// 空统计快照 (全 0), 对齐 C# `MailboxStatistics.Empty`
    pub fn empty() -> Self { Self::default() }
}

// C 结构 `EcMbxStatsC` 在 `crate::utils::ffi` 中定义 (与 FFI 声明同文件).
// 此处 re-export 以保证两处语义一致, 不重复定义.
pub(crate) use crate::utils::ffi::EcMbxStatsC;

impl From<EcMbxStatsC> for MailboxStatistics {
    fn from(c: EcMbxStatsC) -> Self {
        let avg = if c.total_received > 0 {
            c.total_latency_us as f64 / c.total_received as f64
        } else {
            0.0
        };

        let last_err_time = if c.last_error_time_us > 0 {
            use std::time::{Duration, UNIX_EPOCH};
            Some(UNIX_EPOCH + Duration::from_micros(c.last_error_time_us))
        } else {
            None
        };

        Self {
            total_sent: c.total_sent,
            total_received: c.total_received,
            total_timeout: c.total_timeout,
            total_mailbox_error: c.total_mbx_error,
            total_protocol_error: c.total_proto_error,
            total_cancelled: c.total_cancelled,
            last_error_code: c.last_error_code,
            last_error_time: last_err_time,
            average_latency_us: avg,
        }
    }
}