rtps_parser/rtps/messages/submessages/
heartbeat.rs

1use crate::rtps::{
2    messages::{
3        overall_structure::{
4            RtpsMap, Submessage, SubmessageHeader, SubmessageHeaderRead, SubmessageHeaderWrite,
5        },
6        submessage_elements::SubmessageElement,
7        types::{Count, SubmessageFlag, SubmessageKind},
8    },
9    types::{EntityId, SequenceNumber},
10};
11
12#[derive(Debug, PartialEq, Eq)]
13pub struct HeartbeatSubmessageRead<'a> {
14    data: &'a [u8],
15}
16
17impl SubmessageHeader for HeartbeatSubmessageRead<'_> {
18    fn submessage_header(&self) -> SubmessageHeaderRead {
19        SubmessageHeaderRead::new(self.data)
20    }
21}
22
23impl<'a> HeartbeatSubmessageRead<'a> {
24    pub fn new(data: &'a [u8]) -> Self {
25        Self { data }
26    }
27
28    pub fn final_flag(&self) -> bool {
29        self.submessage_header().flags()[1]
30    }
31
32    pub fn liveliness_flag(&self) -> bool {
33        self.submessage_header().flags()[2]
34    }
35
36    pub fn _reader_id(&self) -> EntityId {
37        self.map(&self.data[4..])
38    }
39
40    pub fn writer_id(&self) -> EntityId {
41        self.map(&self.data[8..])
42    }
43
44    pub fn first_sn(&self) -> SequenceNumber {
45        self.map(&self.data[12..])
46    }
47
48    pub fn last_sn(&self) -> SequenceNumber {
49        self.map(&self.data[20..])
50    }
51
52    pub fn count(&self) -> Count {
53        self.map(&self.data[28..])
54    }
55}
56#[derive(Debug, PartialEq, Eq)]
57pub struct HeartbeatSubmessageWrite<'a> {
58    final_flag: SubmessageFlag,
59    liveliness_flag: SubmessageFlag,
60    submessage_elements: [SubmessageElement<'a>; 5],
61}
62
63impl HeartbeatSubmessageWrite<'_> {
64    pub fn new(
65        final_flag: SubmessageFlag,
66        liveliness_flag: SubmessageFlag,
67        reader_id: EntityId,
68        writer_id: EntityId,
69        first_sn: SequenceNumber,
70        last_sn: SequenceNumber,
71        count: Count,
72    ) -> Self {
73        Self {
74            final_flag,
75            liveliness_flag,
76            submessage_elements: [
77                SubmessageElement::EntityId(reader_id),
78                SubmessageElement::EntityId(writer_id),
79                SubmessageElement::SequenceNumber(first_sn),
80                SubmessageElement::SequenceNumber(last_sn),
81                SubmessageElement::Count(count),
82            ],
83        }
84    }
85}
86
87impl<'a> Submessage<'a> for HeartbeatSubmessageWrite<'a> {
88    type SubmessageList = &'a [SubmessageElement<'a>];
89
90    fn submessage_header(&self, octets_to_next_header: u16) -> SubmessageHeaderWrite {
91        SubmessageHeaderWrite::new(
92            SubmessageKind::HEARTBEAT,
93            &[self.final_flag, self.liveliness_flag],
94            octets_to_next_header,
95        )
96    }
97
98    fn submessage_elements(&'a self) -> Self::SubmessageList {
99        &self.submessage_elements
100    }
101}
102
103#[cfg(test)]
104mod tests {
105    use super::*;
106    use crate::rtps::{
107        messages::overall_structure::{into_bytes_vec, RtpsSubmessageWriteKind},
108        types::{USER_DEFINED_READER_GROUP, USER_DEFINED_READER_NO_KEY},
109    };
110
111    #[test]
112    fn serialize_heart_beat() {
113        let final_flag = false;
114        let liveliness_flag = true;
115        let reader_id = EntityId::new([1, 2, 3], USER_DEFINED_READER_NO_KEY);
116        let writer_id = EntityId::new([6, 7, 8], USER_DEFINED_READER_GROUP);
117        let first_sn = SequenceNumber::from(5);
118        let last_sn = SequenceNumber::from(7);
119        let count = 2;
120        let submessage = RtpsSubmessageWriteKind::Heartbeat(HeartbeatSubmessageWrite::new(
121            final_flag,
122            liveliness_flag,
123            reader_id,
124            writer_id,
125            first_sn,
126            last_sn,
127            count,
128        ));
129        #[rustfmt::skip]
130        assert_eq!(into_bytes_vec(submessage), vec![
131                0x07_u8, 0b_0000_0101, 28, 0, // Submessage header
132                1, 2, 3, 4, // readerId: value[4]
133                6, 7, 8, 9, // writerId: value[4]
134                0, 0, 0, 0, // firstSN: SequenceNumber: high
135                5, 0, 0, 0, // firstSN: SequenceNumber: low
136                0, 0, 0, 0, // lastSN: SequenceNumberSet: high
137                7, 0, 0, 0, // lastSN: SequenceNumberSet: low
138                2, 0, 0, 0, // count: Count: value (long)
139            ]
140        );
141    }
142
143    #[test]
144    fn deserialize_heart_beat() {
145        let expected_final_flag = false;
146        let expected_liveliness_flag = true;
147        let expected_reader_id = EntityId::new([1, 2, 3], USER_DEFINED_READER_NO_KEY);
148        let expected_writer_id = EntityId::new([6, 7, 8], USER_DEFINED_READER_GROUP);
149        let expected_first_sn = SequenceNumber::from(5);
150        let expected_last_sn = SequenceNumber::from(7);
151        let expected_count = 2;
152        #[rustfmt::skip]
153        let submessage = HeartbeatSubmessageRead::new(&[
154            0x07, 0b_0000_0101, 28, 0, // Submessage header
155            1, 2, 3, 4, // readerId: value[4]
156            6, 7, 8, 9, // writerId: value[4]
157            0, 0, 0, 0, // firstSN: SequenceNumber: high
158            5, 0, 0, 0, // firstSN: SequenceNumber: low
159            0, 0, 0, 0, // lastSN: SequenceNumberSet: high
160            7, 0, 0, 0, // lastSN: SequenceNumberSet: low
161            2, 0, 0, 0, // count: Count: value (long)
162        ]);
163        assert_eq!(expected_final_flag, submessage.final_flag());
164        assert_eq!(expected_liveliness_flag, submessage.liveliness_flag());
165        assert_eq!(expected_reader_id, submessage._reader_id());
166        assert_eq!(expected_writer_id, submessage.writer_id());
167        assert_eq!(expected_first_sn, submessage.first_sn());
168        assert_eq!(expected_last_sn, submessage.last_sn());
169        assert_eq!(expected_count, submessage.count());
170    }
171}