Skip to main content

statime_wire/messages/
announce.rs

1use crate::{
2    Error,
3    common::{ClockIdentity, ClockQuality, TimeSource, Timestamp},
4};
5
6/// The body of an announce message
7#[derive(Debug, Clone, Copy, PartialEq, Eq)]
8pub struct AnnounceMessage {
9    /// Timestamp this announce was generated on the remote.
10    pub origin_timestamp: Timestamp,
11    /// Current offset between UTC and TAI.
12    pub current_utc_offset: i16,
13    /// Grandmaster priority 1 as used in the BMCA.
14    pub grandmaster_priority_1: u8,
15    /// Quality of the grandmaster clock.
16    pub grandmaster_clock_quality: ClockQuality,
17    /// Grandmaster priority 2 as used in the BMCA.
18    pub grandmaster_priority_2: u8,
19    /// Identity of the Grandmaster clock
20    pub grandmaster_identity: ClockIdentity,
21    /// Number of steps in the synchronization graph between sender
22    /// of the announce message and the Grandmaster clock.
23    pub steps_removed: u16,
24    /// Type of time source used by the grandmaster clock.
25    pub time_source: TimeSource,
26}
27
28impl AnnounceMessage {
29    pub(crate) fn content_size(&self) -> usize {
30        30
31    }
32
33    pub(crate) fn serialize_content(&self, buffer: &mut [u8]) -> Result<(), Error> {
34        if buffer.len() < 30 {
35            return Err(Error::BufferTooShort);
36        }
37
38        self.origin_timestamp.serialize(&mut buffer[0..10])?;
39        buffer[10..12].copy_from_slice(&self.current_utc_offset.to_be_bytes());
40        buffer[13] = self.grandmaster_priority_1;
41        self.grandmaster_clock_quality
42            .serialize(&mut buffer[14..18])?;
43        buffer[18] = self.grandmaster_priority_2;
44        self.grandmaster_identity.serialize(&mut buffer[19..27])?;
45        buffer[27..29].copy_from_slice(&self.steps_removed.to_be_bytes());
46        buffer[29] = self.time_source.to_primitive();
47
48        Ok(())
49    }
50
51    pub(crate) fn deserialize_content(buffer: &[u8]) -> Result<Self, Error> {
52        if buffer.len() < 30 {
53            return Err(Error::BufferTooShort);
54        }
55
56        Ok(Self {
57            origin_timestamp: Timestamp::deserialize(&buffer[0..10])?,
58            current_utc_offset: i16::from_be_bytes(buffer[10..12].try_into().unwrap()),
59            grandmaster_priority_1: buffer[13],
60            grandmaster_clock_quality: ClockQuality::deserialize(&buffer[14..18])?,
61            grandmaster_priority_2: buffer[18],
62            grandmaster_identity: ClockIdentity::deserialize(&buffer[19..27])?,
63            steps_removed: u16::from_be_bytes(buffer[27..29].try_into().unwrap()),
64            time_source: TimeSource::from_primitive(buffer[29]),
65        })
66    }
67}
68
69#[cfg(test)]
70mod tests {
71    use super::*;
72    use crate::common::ClockAccuracy;
73
74    #[test]
75    fn announce_wireformat() {
76        let representations = [(
77            [
78                0x00, 0x00, 0x45, 0xb1, 0x11, 0x5a, 0x0a, 0x73, 0x46, 0x60, 0x00, 0x00, 0x00, 0x60,
79                0x00, 0x00, 0x00, 0x80, 0x63, 0xff, 0xff, 0x00, 0x09, 0xba, 0xf8, 0x21, 0x00, 0x00,
80                0x80, 0x80,
81            ],
82            AnnounceMessage {
83                origin_timestamp: Timestamp::new(1_169_232_218, 175_326_816).unwrap(),
84                current_utc_offset: 0,
85                grandmaster_priority_1: 96,
86                grandmaster_clock_quality: ClockQuality {
87                    clock_class: 0,
88                    clock_accuracy: ClockAccuracy::Reserved,
89                    offset_scaled_log_variance: 128,
90                },
91                grandmaster_priority_2: 99,
92                grandmaster_identity: ClockIdentity([
93                    0xff, 0xff, 0x00, 0x09, 0xba, 0xf8, 0x21, 0x00,
94                ]),
95                steps_removed: 128,
96                time_source: TimeSource::Reserved(0x80),
97            },
98        )];
99
100        for (byte_representation, object_representation) in representations {
101            // Test the serialization output
102            let mut serialization_buffer = [0; 30];
103            object_representation
104                .serialize_content(&mut serialization_buffer)
105                .unwrap();
106            assert_eq!(serialization_buffer, byte_representation);
107
108            // Test the deserialization output
109            let deserialized_data =
110                AnnounceMessage::deserialize_content(&byte_representation).unwrap();
111            assert_eq!(deserialized_data, object_representation);
112        }
113    }
114}