1use std::u8;
10
11use bytes::{BytesMut, BufMut, Buf};
12use chrono::{Utc, Timelike};
13use num_derive::FromPrimitive;
14
15#[derive(Copy, Clone, Debug, PartialEq)]
16pub struct PDUHeaderRecord {
18 pub protocol_version: ProtocolVersion,
19 pub exercise_id: u8,
20 pub pdu_type: PDUType,
21 pub protocol_family: ProtocolFamily,
22 pub timestamp: u32,
23 pub length: u16,
24 pub padding: u16
25}
26
27impl PDUHeaderRecord {
28 pub fn new(pdu_type: PDUType, protocol_family: ProtocolFamily, exercise_id: u8, length: u16,) -> Self {
31 PDUHeaderRecord {
32 protocol_version: ProtocolVersion::DIS_PDUv2_Fourth_Draft_Revised,
33 exercise_id,
34 pdu_type,
35 protocol_family,
36 timestamp: PDUHeaderRecord::calculate_dis_timestamp() as u32,
37 length: length as u16,
38 padding: 0 as u16
39 }
40 }
41
42 pub fn default(pdu_type: PDUType, protocol_family: ProtocolFamily, length: u16,) -> Self {
45 PDUHeaderRecord {
46 protocol_version: ProtocolVersion::DIS_PDUv2_Fourth_Draft_Revised,
47 exercise_id: 1,
48 pdu_type,
49 protocol_family,
50 timestamp: PDUHeaderRecord::calculate_dis_timestamp() as u32,
51 length: length as u16,
52 padding: 0 as u16
53 }
54 }
55
56 pub fn calculate_dis_timestamp() -> u32 {
58 let current_minute = ((Utc::now().minute() * 60) * 1e6 as u32) as u64 ;
59 let current_second = (Utc::now().second() * 1e6 as u32) as u64;
60 let current_nanos = (Utc::now().nanosecond() / 1000) as u64;
61 let dis_units = (current_second + current_minute + current_nanos) as f32 / 1.68;
62 dis_units as u32
63 }
64
65 pub fn serialize(&self, buf: &mut BytesMut) {
68 buf.put_u8(self.protocol_version as u8);
69 buf.put_u8(self.exercise_id as u8);
70 buf.put_u8(self.pdu_type as u8);
71 buf.put_u8(self.protocol_family as u8);
72 buf.put_u32(self.timestamp as u32);
73 buf.put_u16(self.length as u16);
74 buf.put_u16(self.padding as u16);
75 }
76
77 fn decode_protocol_version(data: u8) -> ProtocolVersion {
78 match data {
79 1 => ProtocolVersion::DIS_PDUv1,
80 2 => ProtocolVersion::IEEE1278,
81 3 => ProtocolVersion::DIS_PDUv2_Third_Draft,
82 4 => ProtocolVersion::DIS_PDUv2_Fourth_Draft_Revised,
83 5 => ProtocolVersion::IEEE1278_1,
84 _ => ProtocolVersion::Other
85 }
86 }
87
88 pub fn decode(buf: &mut BytesMut) -> PDUHeaderRecord {
89 PDUHeaderRecord {
90 protocol_version: PDUHeaderRecord::decode_protocol_version(buf.get_u8()),
91 exercise_id: buf.get_u8(),
92 pdu_type: PDUHeaderRecord::decode_pdu_type(buf.get_u8()),
93 protocol_family: PDUHeaderRecord::decode_protocol_family(buf.get_u8()),
94 timestamp: buf.get_u32(),
95 length: buf.get_u16(),
96 padding: buf.get_u16()
97 }
98 }
99
100 fn decode_pdu_type(data: u8) -> PDUType {
101 match data {
102 1 => PDUType::EntityState,
103 2 => PDUType::Fire,
104 3 => PDUType::Detonation,
105 4 => PDUType::Collision,
106 5 => PDUType::ServiceRequest,
107 6 => PDUType::ResupplyOffer,
108 7 => PDUType::ResupplyReceived,
109 8 => PDUType::ResupplyCancel,
110 9 => PDUType::RepairComplete,
111 10 => PDUType::RepairRepsonse,
112 11 => PDUType::CreateEntity,
113 12 => PDUType::RemoveEntity,
114 13 => PDUType::StartResume,
115 14 => PDUType::StopFreeze,
116 15 => PDUType::Acknowledge,
117 16 => PDUType::ActionRequest,
118 17 => PDUType::ActionReponse,
119 18 => PDUType::DataQuery,
120 19 => PDUType::SetData,
121 20 => PDUType::Data,
122 21 => PDUType::EventReport,
123 22 => PDUType::Comment,
124 23 => PDUType::ElectromagneticEmission,
125 24 => PDUType::Designator,
126 25 => PDUType::Transmitter,
127 26 => PDUType::Signal,
128 27 => PDUType::Recevier,
129 _ => PDUType::Other
131 }
132 }
133
134 fn decode_protocol_family(data: u8) -> ProtocolFamily {
135 match data {
136 1 => ProtocolFamily::EntityInformation,
137 2 => ProtocolFamily::Warfare,
138 3 => ProtocolFamily::Logistics,
139 4 => ProtocolFamily::RadioCommunications,
140 5 => ProtocolFamily::SimulationManagement,
141 6 => ProtocolFamily::DistributedEmissionRegeneration,
142 _ => ProtocolFamily::Other
143 }
144 }
145
146}
147
148
149#[derive(Copy, Clone, Debug, FromPrimitive, PartialEq)]
150pub enum ProtocolFamily {
152 Other = 0,
153 EntityInformation = 1,
154 Warfare = 2,
155 Logistics = 3,
156 RadioCommunications = 4,
157 SimulationManagement = 5,
158 DistributedEmissionRegeneration = 6
159}
160
161#[derive(Copy, Clone, Debug, FromPrimitive, PartialEq)]
162#[allow(non_camel_case_types)]
163pub enum ProtocolVersion {
165 Other = 0,
166 DIS_PDUv1 = 1,
167 IEEE1278 = 2,
168 DIS_PDUv2_Third_Draft = 3,
169 DIS_PDUv2_Fourth_Draft_Revised = 4,
170 IEEE1278_1 = 5
171}
172
173#[derive(Copy, Clone, Debug, FromPrimitive, PartialEq)]
174pub enum PDUType {
176 Other = 0,
177 EntityState = 1,
178 Fire = 2,
179 Detonation = 3,
180 Collision = 4,
181 ServiceRequest = 5,
182 ResupplyOffer = 6,
183 ResupplyReceived = 7,
184 ResupplyCancel = 8,
185 RepairComplete = 9,
186 RepairRepsonse = 10,
187 CreateEntity = 11,
188 RemoveEntity = 12,
189 StartResume = 13,
190 StopFreeze = 14,
191 Acknowledge = 15,
192 ActionRequest = 16,
193 ActionReponse = 17,
194 DataQuery = 18,
195 SetData = 19,
196 Data = 20,
197 EventReport = 21,
198 Comment = 22,
199 ElectromagneticEmission = 23,
200 Designator = 24,
201 Transmitter = 25,
202 Signal = 26,
203 Recevier = 27,
204 }