open_dis_rust/common/
live_entity_pdu_header.rs1use bytes::{Buf, BufMut, BytesMut};
8use chrono::{Timelike, Utc};
9
10use crate::common::{
11 GenericHeader, SerializedLength,
12 enums::{DISLiveEntitySubprotocolNumber, PduType, ProtocolFamily, ProtocolVersion},
13};
14
15#[derive(Copy, Clone, Debug, PartialEq, Eq)]
16pub struct LiveEntityPduHeader {
17 pub protocol_version: ProtocolVersion,
19 pub exercise_id: u8,
21 pub pdu_type: PduType,
23 pub protocol_family: ProtocolFamily,
25 pub timestamp: u32,
27 pub length: u16,
29 pub subprotocol_number: DISLiveEntitySubprotocolNumber,
31 padding: u8,
33}
34
35impl Default for LiveEntityPduHeader {
36 fn default() -> Self {
37 Self {
38 protocol_version: ProtocolVersion::IEEE1278_1_2012,
39 exercise_id: 1,
40 pdu_type: PduType::default(),
41 protocol_family: ProtocolFamily::default(),
42 timestamp: Self::calculate_dis_timestamp(),
43 length: 0,
44 subprotocol_number: DISLiveEntitySubprotocolNumber::default(),
45 padding: 0,
46 }
47 }
48}
49
50impl GenericHeader for LiveEntityPduHeader {
51 fn pdu_type(&self) -> PduType {
52 self.pdu_type
53 }
54
55 fn set_pdu_type(&mut self, value: PduType) {
56 self.pdu_type = value;
57 }
58
59 fn protocol_family(&self) -> ProtocolFamily {
60 self.protocol_family
61 }
62
63 fn set_protocol_family(&mut self, value: ProtocolFamily) {
64 self.protocol_family = value;
65 }
66
67 fn length(&self) -> u16 {
68 self.length
69 }
70
71 fn set_length(&mut self, value: u16) {
72 self.length = value;
73 }
74
75 fn serialize(&self, buf: &mut BytesMut) {
76 buf.put_u8(self.protocol_version as u8);
77 buf.put_u8(self.exercise_id);
78 buf.put_u8(self.pdu_type as u8);
79 buf.put_u8(self.protocol_family as u8);
80 buf.put_u32(self.timestamp);
81 buf.put_u16(self.length);
82 buf.put_u8(self.subprotocol_number as u8);
83 buf.put_u8(self.padding);
84 }
85
86 fn deserialize<B: Buf>(buf: &mut B) -> Self {
87 Self {
88 protocol_version: ProtocolVersion::deserialize(buf),
89 exercise_id: buf.get_u8(),
90 pdu_type: PduType::deserialize(buf),
91 protocol_family: ProtocolFamily::deserialize(buf),
92 timestamp: buf.get_u32(),
93 length: buf.get_u16(),
94 subprotocol_number: DISLiveEntitySubprotocolNumber::deserialize(buf),
95 padding: buf.get_u8(),
96 }
97 }
98}
99
100impl LiveEntityPduHeader {
101 #[must_use]
102 pub fn new(
103 pdu_type: PduType,
104 protocol_family: ProtocolFamily,
105 exercise_id: u8,
106 length: u16,
107 ) -> Self {
108 Self {
109 protocol_version: ProtocolVersion::IEEE1278_1_2012,
110 exercise_id,
111 pdu_type,
112 protocol_family,
113 timestamp: Self::calculate_dis_timestamp(),
114 length,
115 ..Default::default()
116 }
117 }
118
119 #[must_use]
121 #[allow(
122 clippy::cast_precision_loss,
123 clippy::cast_possible_truncation,
124 clippy::cast_sign_loss
125 )]
126 pub fn calculate_dis_timestamp() -> u32 {
127 let minute_curr = u64::from((Utc::now().minute() * 60) * 1_000_000);
128 let second_curr = u64::from(Utc::now().second() * 1_000_000);
129 let nanosecond_curr = u64::from(Utc::now().nanosecond() / 1000);
130 let dis_time = (second_curr + minute_curr + nanosecond_curr) as f32 / 1.68;
131 dis_time as u32
132 }
133}
134
135impl SerializedLength for LiveEntityPduHeader {
136 const LENGTH: usize = 12;
137}