1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// socketcan/src/timestamp.rs
//
// Timestamp types and helpers for SocketCAN sockets.
//
// This file is part of the Rust 'socketcan-rs' library.
//
// Licensed under the MIT license:
// <LICENSE or http://opensource.org/licenses/MIT>
// This file may not be copied, modified, or distributed except according
// to those terms.
//! Timestamp support for SocketCAN sockets.
//!
//! Timestamps are delivered atomically with the frame data via `recvmsg()`
//! and ancillary control messages, avoiding the two-syscall race of the old
//! `SIOCGSTAMPNS` approach.
//!
//! # Usage
//!
//! 1. Enable the desired timestamp mode on the socket with
//! [`SocketOptions::set_recv_timestamp`] or [`SocketOptions::set_timestamping`].
//! 2. Call the corresponding read method on the socket.
//!
//! [`SocketOptions::set_recv_timestamp`]: crate::SocketOptions::set_recv_timestamp
//! [`SocketOptions::set_timestamping`]: crate::SocketOptions::set_timestamping
use ;
// --------------------------------------------------------------------------
// SOF_TIMESTAMPING_* flags
// TODO: These should be PR'd into libc
/// Hardware transmit timestamp, generated by the network adapter at packet departure.
pub const SOF_TIMESTAMPING_TX_HARDWARE: u32 = 1 << 0;
/// Software transmit timestamp, generated when the packet leaves the network stack.
pub const SOF_TIMESTAMPING_TX_SOFTWARE: u32 = 1 << 1;
/// Hardware receive timestamp.
pub const SOF_TIMESTAMPING_RX_HARDWARE: u32 = 1 << 2;
/// Software receive timestamp, generated when the packet enters the network stack.
pub const SOF_TIMESTAMPING_RX_SOFTWARE: u32 = 1 << 3;
/// Report software timestamps in the ancillary data (distinct from `RX_SOFTWARE`,
/// which selects when the timestamp is taken).
pub const SOF_TIMESTAMPING_SOFTWARE: u32 = 1 << 4;
/// Report the raw hardware clock value (not wall-clock time).
pub const SOF_TIMESTAMPING_RAW_HARDWARE: u32 = 1 << 6;
/// Deliver `SO_TIMESTAMPING` timestamps via a control message on receive.
///
/// Required for RX timestamps to actually appear in the ancillary data
/// returned by `recvmsg()`.
pub const SOF_TIMESTAMPING_OPT_CMSG: u32 = 1 << 10;
// --------------------------------------------------------------------------
// ethtool constants / structs
// TODO: These should be PR'd into libc
pub const ETHTOOL_GET_TS_INFO: u32 = 0x0000_0041;
/// Mirror of `ethtool_ts_info` from `<linux/ethtool.h>`.
pub
// ===== Private conversion helpers =====
/// Convert a `libc::timespec` to a `SystemTime`.
///
/// Assumes the timespec is a non-negative UNIX timestamp, which is always
/// the case for kernel-generated socket timestamps.
pub
/// Convert a `libc::timespec` to a `Duration`.
///
/// Used for hardware timestamps, which are reported in the adapter's own
/// clock domain rather than as wall-clock time. Negative `tv_sec` or
/// `tv_nsec` values (which the kernel should never produce here) are
/// clamped to zero so the function never panics on `Duration::new`.
pub
/////////////////////////////////////////////////////////////////////////////
/// Timestamps associated with a received CAN frame.
///
/// Each field is `None` when the corresponding timestamp mode was not enabled
/// on the socket before the frame was read.
///
/// Enable socket-layer timestamps with [`SocketOptions::set_recv_timestamp`]
/// and network-stack / hardware timestamps with [`SocketOptions::set_timestamping`].
///
/// # Limitation
///
/// The kernel reports each unrequested timestamp source as all-zero rather
/// than omitting it from the cmsg. This implementation treats an exactly-zero
/// `sw` or `hw` value as "not delivered" and reports it as `None`, which
/// collapses three otherwise-distinct cases: the source was disabled, the
/// kernel returned zero, or (for `hw` only) the adapter's clock genuinely
/// read zero. In practice this is only ambiguous in the first nanosecond
/// after a hardware clock starts up.
///
/// [`SocketOptions::set_recv_timestamp`]: crate::SocketOptions::set_recv_timestamp
/// [`SocketOptions::set_timestamping`]: crate::SocketOptions::set_timestamping