dis_rust/warfare/
fire_pdu.rs1use std::any::{Any};
10
11use crate::common::{entity_id_record::EntityIDRecord, event_id_record::EventIDRecord, pdu::PDU, pdu_header_record::{PDUHeaderRecord, PDUType, ProtocolFamily}, velocity_vector_record::VelocityVectorRecord, world_coordinate_record::WorldCoordinateRecord, dis_error::DISError};
12use bytes::{BytesMut, BufMut, Buf};
13
14use super::burst_descriptor_record::BurstDescriptorRecord;
15
16#[derive(Copy, Clone, Debug)]
17pub struct FirePDU {
19 pub pdu_header_record: PDUHeaderRecord,
20 pub firing_entity_id_record: EntityIDRecord,
21 pub target_entity_id_record: EntityIDRecord,
22 pub munition_id_record: EntityIDRecord,
23 pub event_id_record: EventIDRecord,
24 pub fire_mission_index_field: u32,
25 pub location_in_world_record: WorldCoordinateRecord,
26 pub burst_descriptor_record: BurstDescriptorRecord,
27 pub velocity_record: VelocityVectorRecord,
28 pub range_field: f32
29}
30
31impl FirePDU {
32 pub fn default() -> Self {
50 FirePDU {
51 pdu_header_record: PDUHeaderRecord::default(PDUType::Fire, ProtocolFamily::Warfare, 96),
52 firing_entity_id_record: EntityIDRecord::default(1),
53 target_entity_id_record: EntityIDRecord::default(1),
54 munition_id_record: EntityIDRecord::default(1),
55 event_id_record: EventIDRecord::default(1),
56 fire_mission_index_field: 0,
57 location_in_world_record: WorldCoordinateRecord::new(0.0, 0.0, 0.0),
58 burst_descriptor_record: BurstDescriptorRecord::default(),
59 velocity_record: VelocityVectorRecord::new(0.0, 0.0, 0.0),
60 range_field: 0.0
61 }
62 }
63}
64
65impl PDU for FirePDU {
66 fn serialise(&self, buf: &mut BytesMut) {
69 self.pdu_header_record.serialize(buf);
70 self.firing_entity_id_record.serialize(buf);
71 self.target_entity_id_record.serialize(buf);
72 self.munition_id_record.serialize(buf);
73 self.event_id_record.serialize(buf);
74 buf.put_u32(self.fire_mission_index_field);
75 self.location_in_world_record.serialize(buf);
76 self.burst_descriptor_record.serialize(buf);
77 self.velocity_record.serialize(buf);
78 buf.put_f32(self.range_field);
79 }
80
81 fn deserialise(mut buffer: BytesMut) -> Result<Self, crate::common::dis_error::DISError> where Self: Sized {
82 let pdu_header = PDUHeaderRecord::decode(&mut buffer);
83 if pdu_header.pdu_type == PDUType::Fire {
84 let firing_entity_id = EntityIDRecord::decode(&mut buffer);
85 let target_entity_id = EntityIDRecord::decode(&mut buffer);
86 let munition_entity_id = EntityIDRecord::decode(&mut buffer);
87 let event_id = EventIDRecord::decode(&mut buffer);
88 let fire_mission = buffer.get_u32();
89 let location = WorldCoordinateRecord::decode(&mut buffer);
90 let burst_descriptor = BurstDescriptorRecord::decode(&mut buffer);
91 let velocity = VelocityVectorRecord::decode(&mut buffer);
92 let range = buffer.get_f32();
93 return Ok(FirePDU {
94 pdu_header_record: pdu_header,
95 firing_entity_id_record: firing_entity_id,
96 target_entity_id_record: target_entity_id,
97 munition_id_record: munition_entity_id,
98 event_id_record: event_id,
99 fire_mission_index_field: fire_mission,
100 location_in_world_record: location,
101 burst_descriptor_record: burst_descriptor,
102 velocity_record: velocity,
103 range_field: range,
104 })
105 } else {
106 Err(DISError::InvalidDISHeader)
107 }
108 }
109
110 fn as_any(&self) -> &dyn Any {
111 self
112 }
113
114 fn deserialise_without_header(mut buffer: BytesMut, pdu_header: PDUHeaderRecord) -> Result<Self, DISError> where Self: Sized {
115 let firing_entity_id = EntityIDRecord::decode(&mut buffer);
116 let target_entity_id = EntityIDRecord::decode(&mut buffer);
117 let munition_entity_id = EntityIDRecord::decode(&mut buffer);
118 let event_id = EventIDRecord::decode(&mut buffer);
119 let fire_mission = buffer.get_u32();
120 let location = WorldCoordinateRecord::decode(&mut buffer);
121 let burst_descriptor = BurstDescriptorRecord::decode(&mut buffer);
122 let velocity = VelocityVectorRecord::decode(&mut buffer);
123 let range = buffer.get_f32();
124 return Ok(FirePDU {
125 pdu_header_record: pdu_header,
126 firing_entity_id_record: firing_entity_id,
127 target_entity_id_record: target_entity_id,
128 munition_id_record: munition_entity_id,
129 event_id_record: event_id,
130 fire_mission_index_field: fire_mission,
131 location_in_world_record: location,
132 burst_descriptor_record: burst_descriptor,
133 velocity_record: velocity,
134 range_field: range,
135 })
136 }
137}
138
139#[cfg(test)]
140mod tests {
141 use bytes::BytesMut;
142
143 use crate::{common::{pdu_header_record::{PDUHeaderRecord, PDUType, ProtocolFamily}, pdu::PDU}, warfare::fire_pdu::FirePDU};
144
145 #[test]
146 fn header_creation() {
147 let firing_pdu = FirePDU::default();
148 let header = PDUHeaderRecord::default(PDUType::Fire, ProtocolFamily::Warfare, 768/8);
149 assert_eq!(header.protocol_version, firing_pdu.pdu_header_record.protocol_version);
150 assert_eq!(header.exercise_id, firing_pdu.pdu_header_record.exercise_id);
151 assert_eq!(header.pdu_type, firing_pdu.pdu_header_record.pdu_type);
152 assert_eq!(header.protocol_family, firing_pdu.pdu_header_record.protocol_family);
153 assert_eq!(header.timestamp, firing_pdu.pdu_header_record.timestamp);
154 assert_eq!(header.length, firing_pdu.pdu_header_record.length);
155 assert_eq!(header.padding, firing_pdu.pdu_header_record.padding);
156 }
157
158 #[test]
159 fn header_deserialise() {
160 let fire_pdu = FirePDU::default();
161 let mut buffer = BytesMut::new();
162 fire_pdu.serialise(&mut buffer);
163
164 let new_fire_pdu = FirePDU::deserialise(buffer).unwrap();
165 assert_eq!(new_fire_pdu.pdu_header_record, fire_pdu.pdu_header_record);
166 }
167}