dis_rs/common/iff/
writer.rs

1use crate::common::iff::model::{
2    ChangeOptionsRecord, DamageStatus, DapSource, DapValue, EnabledStatus, EnhancedMode1Code,
3    FundamentalOperationalData, Iff, IffDataRecord, IffDataSpecification,
4    IffFundamentalParameterData, IffLayer2, IffLayer3, IffLayer4, IffLayer5, IffPresence,
5    InformationLayers, LatLonAltSource, LayerHeader, LayersPresenceApplicability,
6    MalfunctionStatus, Mode5BasicData, Mode5InterrogatorBasicData, Mode5InterrogatorStatus,
7    Mode5MessageFormats, Mode5TransponderBasicData, Mode5TransponderStatus,
8    Mode5TransponderSupplementalData, ModeSAltitude, ModeSBasicData, ModeSInterrogatorBasicData,
9    ModeSInterrogatorStatus, ModeSLevelsPresent, ModeSTransponderBasicData, ModeSTransponderStatus,
10    OnOffStatus, OperationalStatus, ParameterCapable, SquitterStatus, SystemId, SystemSpecificData,
11    SystemStatus,
12};
13use crate::common::model::length_padded_to_num;
14use crate::common::{Serialize, SerializePdu, SupportedVersion};
15use crate::constants::{
16    EIGHT_OCTETS, FOUR_OCTETS, ONE_OCTET, SIX_OCTETS, THREE_OCTETS, TWO_OCTETS,
17};
18use crate::DisError;
19use bytes::{BufMut, BytesMut};
20
21impl SerializePdu for Iff {
22    fn serialize_pdu(&self, _version: SupportedVersion, buf: &mut BytesMut) -> u16 {
23        let entity_id_bytes = self.emitting_entity_id.serialize(buf);
24        let event_id_bytes = self.event_id.serialize(buf);
25        let antenna_location_bytes = self.relative_antenna_location.serialize(buf);
26        let system_id_bytes = self.system_id.serialize(buf);
27        buf.put_u8(self.system_designator);
28        buf.put_u8(self.system_specific_data);
29        let fundamental_data_bytes = self.fundamental_operational_data.serialize(buf);
30
31        let layer_2_bytes = if let Some(layer_2) = &self.layer_2 {
32            layer_2.serialize(buf)
33        } else {
34            0
35        };
36        let layer_3_bytes = if let Some(layer_3) = &self.layer_3 {
37            layer_3.serialize(buf)
38        } else {
39            0
40        };
41        let layer_4_bytes = if let Some(layer_4) = &self.layer_4 {
42            layer_4.serialize(buf)
43        } else {
44            0
45        };
46        let layer_5_bytes = if let Some(layer_5) = &self.layer_5 {
47            layer_5.serialize(buf)
48        } else {
49            0
50        };
51
52        entity_id_bytes
53            + event_id_bytes
54            + antenna_location_bytes
55            + system_id_bytes
56            + 2
57            + fundamental_data_bytes
58            + layer_2_bytes
59            + layer_3_bytes
60            + layer_4_bytes
61            + layer_5_bytes
62    }
63}
64
65impl Serialize for IffLayer2 {
66    fn serialize(&self, buf: &mut BytesMut) -> u16 {
67        let layer_header_bytes = self.layer_header.serialize(buf);
68        let beam_data_bytes = self.beam_data.serialize(buf);
69        buf.put_u8(self.operational_parameter_1);
70        buf.put_u8(self.operational_parameter_2);
71        buf.put_u16(self.iff_fundamental_parameters.len() as u16);
72        let params_bytes: u16 = self
73            .iff_fundamental_parameters
74            .iter()
75            .map(|param| param.serialize(buf))
76            .sum();
77
78        layer_header_bytes + beam_data_bytes + 4 + params_bytes
79    }
80}
81
82impl Serialize for IffLayer3 {
83    fn serialize(&self, buf: &mut BytesMut) -> u16 {
84        let layer_header_bytes = self.layer_header.serialize(buf);
85        let reporting_simulation_bytes = self.reporting_simulation.serialize(buf);
86        let basic_data_bytes = match &self.mode_5_basic_data {
87            Mode5BasicData::Interrogator(data) => data.serialize(buf),
88            Mode5BasicData::Transponder(data) => data.serialize(buf),
89        };
90        buf.put_u16(0u16);
91        let iff_data_specification_bytes = self.data_records.serialize(buf);
92
93        layer_header_bytes
94            + reporting_simulation_bytes
95            + basic_data_bytes
96            + 2
97            + iff_data_specification_bytes
98    }
99}
100
101impl Serialize for IffLayer4 {
102    fn serialize(&self, buf: &mut BytesMut) -> u16 {
103        let layer_header_bytes = self.layer_header.serialize(buf);
104        let reporting_simulation_bytes = self.reporting_simulation.serialize(buf);
105        let basic_data_bytes = match &self.mode_s_basic_data {
106            ModeSBasicData::Interrogator(data) => data.serialize(buf),
107            ModeSBasicData::Transponder(data) => data.serialize(buf),
108        };
109        buf.put_u16(0u16);
110        let iff_data_records_bytes = self.data_records.serialize(buf);
111
112        layer_header_bytes
113            + reporting_simulation_bytes
114            + basic_data_bytes
115            + 2
116            + iff_data_records_bytes
117    }
118}
119
120impl Serialize for IffLayer5 {
121    fn serialize(&self, buf: &mut BytesMut) -> u16 {
122        let layer_header_bytes = self.layer_header.serialize(buf);
123        let reporting_simulation_bytes = self.reporting_simulation.serialize(buf);
124        buf.put_u16(0u16);
125        let applicable_layers_bytes = self.applicable_layers.serialize(buf);
126        buf.put_u8(self.data_category.into());
127        buf.put_u16(0u16);
128        let data_records_bytes = self.data_records.serialize(buf);
129
130        layer_header_bytes
131            + reporting_simulation_bytes
132            + 2
133            + applicable_layers_bytes
134            + 3
135            + data_records_bytes
136    }
137}
138
139impl Serialize for ChangeOptionsRecord {
140    fn serialize(&self, buf: &mut BytesMut) -> u16 {
141        let byte: u8 = self.into();
142        buf.put_u8(byte);
143
144        ONE_OCTET as u16
145    }
146}
147
148impl Serialize for FundamentalOperationalData {
149    fn serialize(&self, buf: &mut BytesMut) -> u16 {
150        let system_status_bytes = self.system_status.serialize(buf);
151        buf.put_u8(self.data_field_1);
152        let information_layers_bytes = self.information_layers.serialize(buf);
153        buf.put_u8(self.data_field_2);
154        buf.put_u16(self.parameter_1);
155        buf.put_u16(self.parameter_2);
156        buf.put_u16(self.parameter_3);
157        buf.put_u16(self.parameter_4);
158        buf.put_u16(self.parameter_5);
159        buf.put_u16(self.parameter_6);
160
161        system_status_bytes + information_layers_bytes + 14
162    }
163}
164
165impl From<&ParameterCapable> for u8 {
166    fn from(value: &ParameterCapable) -> Self {
167        match value {
168            ParameterCapable::Capable => 0,
169            ParameterCapable::NotCapable => 1,
170        }
171    }
172}
173
174impl From<&OperationalStatus> for u8 {
175    fn from(value: &OperationalStatus) -> Self {
176        match value {
177            OperationalStatus::Operational => 0,
178            OperationalStatus::SystemFailed => 1,
179        }
180    }
181}
182
183impl From<&LayersPresenceApplicability> for u8 {
184    fn from(value: &LayersPresenceApplicability) -> Self {
185        match value {
186            LayersPresenceApplicability::NotPresentApplicable => 0,
187            LayersPresenceApplicability::PresentApplicable => 1,
188        }
189    }
190}
191
192impl Serialize for IffDataRecord {
193    fn serialize(&self, buf: &mut BytesMut) -> u16 {
194        let padded_record_lengths =
195            length_padded_to_num(SIX_OCTETS + self.record_specific_fields.len(), FOUR_OCTETS);
196        let record_length_bytes = padded_record_lengths.record_length as u16;
197
198        buf.put_u32(self.record_type.into());
199        buf.put_u16(record_length_bytes);
200        buf.put(&*self.record_specific_fields);
201        buf.put_bytes(0u8, padded_record_lengths.padding_length);
202
203        record_length_bytes
204    }
205}
206
207impl Serialize for IffDataSpecification {
208    fn serialize(&self, buf: &mut BytesMut) -> u16 {
209        buf.put_u16(self.iff_data_records.len() as u16);
210        let records_bytes: u16 = self
211            .iff_data_records
212            .iter()
213            .map(|record| record.serialize(buf))
214            .sum();
215
216        2 + records_bytes
217    }
218}
219
220impl Serialize for InformationLayers {
221    fn serialize(&self, buf: &mut BytesMut) -> u16 {
222        let byte = u8::from(self);
223        buf.put_u8(byte);
224
225        ONE_OCTET as u16
226    }
227}
228
229impl Serialize for IffFundamentalParameterData {
230    fn serialize(&self, buf: &mut BytesMut) -> u16 {
231        buf.put_f32(self.erp);
232        buf.put_f32(self.frequency);
233        buf.put_f32(self.pgrf);
234        buf.put_f32(self.pulse_width);
235        buf.put_f32(self.burst_length);
236        buf.put_u8(self.applicable_modes.into());
237        let system_specific_data_bytes = self.system_specific_data.serialize(buf);
238
239        21 + system_specific_data_bytes
240    }
241}
242
243impl Serialize for LayerHeader {
244    fn serialize(&self, buf: &mut BytesMut) -> u16 {
245        buf.put_u8(self.layer_number);
246        buf.put_u8(self.layer_specific_information);
247        buf.put_u16(self.length);
248
249        FOUR_OCTETS as u16
250    }
251}
252
253impl Serialize for SystemSpecificData {
254    fn serialize(&self, buf: &mut BytesMut) -> u16 {
255        buf.put_u8(self.part_1);
256        buf.put_u8(self.part_2);
257        buf.put_u8(self.part_3);
258
259        THREE_OCTETS as u16
260    }
261}
262
263impl Serialize for SystemId {
264    fn serialize(&self, buf: &mut BytesMut) -> u16 {
265        buf.put_u16(self.system_type.into());
266        buf.put_u16(self.system_name.into());
267        buf.put_u8(self.system_mode.into());
268        let _ = self.change_options.serialize(buf);
269
270        SIX_OCTETS as u16
271    }
272}
273
274impl Serialize for DapSource {
275    fn serialize(&self, buf: &mut BytesMut) -> u16 {
276        let indicated_air_speed = u8::from(&self.indicated_air_speed) << 7;
277        let mach_number = u8::from(&self.mach_number) << 6;
278        let ground_speed = u8::from(&self.ground_speed) << 5;
279        let magnetic_heading = u8::from(&self.magnetic_heading) << 4;
280        let track_angle_rate = u8::from(&self.track_angle_rate) << 3;
281        let true_track_angle = u8::from(&self.true_track_angle) << 2;
282        let true_airspeed = u8::from(&self.true_airspeed) << 1;
283        let vertical_rate = u8::from(&self.vertical_rate);
284
285        buf.put_u8(
286            indicated_air_speed
287                | mach_number
288                | ground_speed
289                | magnetic_heading
290                | track_angle_rate
291                | true_track_angle
292                | true_airspeed
293                | vertical_rate,
294        );
295
296        ONE_OCTET as u16
297    }
298}
299
300impl From<&DapValue> for u8 {
301    fn from(value: &DapValue) -> Self {
302        match value {
303            DapValue::ComputeLocally => 0,
304            DapValue::DataRecordAvailable => 1,
305        }
306    }
307}
308
309impl Serialize for EnhancedMode1Code {
310    fn serialize(&self, buf: &mut BytesMut) -> u16 {
311        let bytes = u16::from(self);
312        buf.put_u16(bytes);
313
314        TWO_OCTETS as u16
315    }
316}
317
318impl Serialize for Mode5InterrogatorBasicData {
319    fn serialize(&self, buf: &mut BytesMut) -> u16 {
320        let _status_bytes = self.status.serialize(buf);
321        buf.put_u8(0u8);
322        buf.put_u16(0u16);
323        let _formats_present_bytes = self.mode_5_message_formats_present.serialize(buf);
324        let _entity_id_bytes = self.interrogated_entity_id.serialize(buf);
325        buf.put_u16(0u16);
326
327        16
328    }
329}
330
331impl Serialize for Mode5InterrogatorStatus {
332    fn serialize(&self, buf: &mut BytesMut) -> u16 {
333        let byte = u8::from(self);
334        buf.put_u8(byte);
335
336        ONE_OCTET as u16
337    }
338}
339
340impl Serialize for Mode5MessageFormats {
341    fn serialize(&self, buf: &mut BytesMut) -> u16 {
342        let value = u32::from(self);
343        buf.put_u32(value);
344
345        4
346    }
347}
348
349impl Serialize for Mode5TransponderBasicData {
350    fn serialize(&self, buf: &mut BytesMut) -> u16 {
351        let status_bytes = self.status.serialize(buf);
352        buf.put_u16(self.pin);
353        let formats_present_bytes = self.mode_5_message_formats_present.serialize(buf);
354        let enhanced_mode_1_bytes = self.enhanced_mode_1.serialize(buf);
355        buf.put_u16(self.national_origin);
356        let sd_bytes = self.supplemental_data.serialize(buf);
357        buf.put_u8(self.navigation_source.into());
358        buf.put_u8(self.figure_of_merit);
359        buf.put_u8(0u8);
360
361        status_bytes + formats_present_bytes + enhanced_mode_1_bytes + sd_bytes + 7
362    }
363}
364
365impl From<&OnOffStatus> for u8 {
366    fn from(value: &OnOffStatus) -> Self {
367        match value {
368            OnOffStatus::Off => 0,
369            OnOffStatus::On => 1,
370        }
371    }
372}
373
374impl From<&DamageStatus> for u8 {
375    fn from(value: &DamageStatus) -> Self {
376        match value {
377            DamageStatus::NoDamage => 0,
378            DamageStatus::Damaged => 1,
379        }
380    }
381}
382
383impl From<&MalfunctionStatus> for u8 {
384    fn from(value: &MalfunctionStatus) -> Self {
385        match value {
386            MalfunctionStatus::NoMalfunction => 0,
387            MalfunctionStatus::Malfunction => 1,
388        }
389    }
390}
391
392impl From<&EnabledStatus> for u8 {
393    fn from(value: &EnabledStatus) -> Self {
394        match value {
395            EnabledStatus::NotEnabled => 0,
396            EnabledStatus::Enabled => 1,
397        }
398    }
399}
400
401impl From<&LatLonAltSource> for u8 {
402    fn from(value: &LatLonAltSource) -> Self {
403        match value {
404            LatLonAltSource::ComputeLocally => 0,
405            LatLonAltSource::TransponderLocationDataRecordPresent => 1,
406        }
407    }
408}
409
410impl Serialize for Mode5TransponderSupplementalData {
411    fn serialize(&self, buf: &mut BytesMut) -> u16 {
412        let byte = u8::from(self);
413        buf.put_u8(byte);
414
415        ONE_OCTET as u16
416    }
417}
418
419impl Serialize for Mode5TransponderStatus {
420    fn serialize(&self, buf: &mut BytesMut) -> u16 {
421        buf.put_u16(self.into());
422
423        TWO_OCTETS as u16
424    }
425}
426
427impl Serialize for ModeSAltitude {
428    fn serialize(&self, buf: &mut BytesMut) -> u16 {
429        buf.put_u16(self.into());
430
431        TWO_OCTETS as u16
432    }
433}
434
435impl Serialize for ModeSInterrogatorBasicData {
436    fn serialize(&self, buf: &mut BytesMut) -> u16 {
437        const PAD_168_BITS_IN_OCTETS: usize = 21;
438        let _status_bytes = self.mode_s_interrogator_status.serialize(buf);
439        buf.put_u8(0u8);
440        let _levels_present_bytes = self.mode_s_levels_present.serialize(buf);
441        buf.put_bytes(0u8, PAD_168_BITS_IN_OCTETS);
442
443        24
444    }
445}
446
447impl Serialize for ModeSInterrogatorStatus {
448    fn serialize(&self, buf: &mut BytesMut) -> u16 {
449        buf.put_u8(self.into());
450
451        ONE_OCTET as u16
452    }
453}
454
455impl Serialize for ModeSLevelsPresent {
456    fn serialize(&self, buf: &mut BytesMut) -> u16 {
457        buf.put_u8(self.into());
458
459        ONE_OCTET as u16
460    }
461}
462
463impl From<&IffPresence> for u32 {
464    fn from(value: &IffPresence) -> Self {
465        match value {
466            IffPresence::NotPresent => 0,
467            IffPresence::Present => 1,
468        }
469    }
470}
471
472impl From<&IffPresence> for u8 {
473    fn from(value: &IffPresence) -> Self {
474        match value {
475            IffPresence::NotPresent => 0,
476            IffPresence::Present => 1,
477        }
478    }
479}
480
481impl Serialize for ModeSTransponderBasicData {
482    fn serialize(&self, buf: &mut BytesMut) -> u16 {
483        let _status_bytes = self.status.serialize(buf);
484        let _levels_present_bytes = self.levels_present.serialize(buf);
485        buf.put_u8(self.aircraft_present_domain.into());
486        let _aircraft_id = if let Ok(bytes) =
487            put_ascii_string_with_length(buf, &self.aircraft_identification, 8)
488        {
489            bytes
490        } else {
491            buf.put_bytes(0u8, EIGHT_OCTETS);
492            EIGHT_OCTETS as u16
493        };
494        buf.put_u32(self.aircraft_address);
495        buf.put_u8(self.aircraft_identification_type.into());
496        self.dap_source.serialize(buf);
497        self.altitude.serialize(buf);
498        buf.put_u8(self.capability_report.into());
499
500        24
501    }
502}
503
504fn put_ascii_string_with_length(
505    buf: &mut BytesMut,
506    value: &str,
507    length: usize,
508) -> Result<u16, DisError> {
509    if value.len() > length {
510        Err(DisError::StringTooLongError)
511    } else if !value.is_ascii() {
512        Err(DisError::StringNotAsciiError)
513    } else {
514        buf.put_slice(value.as_bytes());
515        buf.put_bytes(0u8, length - value.len());
516        Ok(length as u16)
517    }
518}
519
520impl Serialize for ModeSTransponderStatus {
521    fn serialize(&self, buf: &mut BytesMut) -> u16 {
522        let squitter_status: u8 = u8::from(&self.squitter_status) << 7;
523        let squitter_type: u8 = u8::from(self.squitter_type) << 4;
524        let squitter_record_source: u8 = u8::from(self.squitter_record_source) << 3;
525        let airborne_pos_ri: u8 = u8::from(&self.airborne_position_report_indicator) << 2;
526        let airborne_vel_ri: u8 = u8::from(&self.airborne_velocity_report_indicator) << 1;
527        let surface_pos_ri: u8 = u8::from(&self.surface_position_report_indicator);
528        buf.put_u8(
529            squitter_status
530                | squitter_type
531                | squitter_record_source
532                | airborne_pos_ri
533                | airborne_vel_ri
534                | surface_pos_ri,
535        );
536
537        let ident_ri: u8 = u8::from(&self.identification_report_indicator) << 7;
538        let event_driven_ri: u8 = u8::from(&self.event_driven_report_indicator) << 6;
539        let on_off_status: u8 = u8::from(&self.on_off_status) << 2;
540        let damage_status: u8 = u8::from(&self.damage_status) << 1;
541        let malfunction_status: u8 = u8::from(&self.malfunction_status);
542        buf.put_u8(ident_ri | event_driven_ri | on_off_status | damage_status | malfunction_status);
543
544        TWO_OCTETS as u16
545    }
546}
547
548impl From<&SquitterStatus> for u8 {
549    fn from(value: &SquitterStatus) -> Self {
550        match value {
551            SquitterStatus::Off => 0,
552            SquitterStatus::On => 1,
553        }
554    }
555}
556
557impl Serialize for SystemStatus {
558    fn serialize(&self, buf: &mut BytesMut) -> u16 {
559        let byte = u8::from(self);
560        buf.put_u8(byte);
561
562        ONE_OCTET as u16
563    }
564}