dis_rs/common/transmitter/
writer.rs

1use crate::common::model::length_padded_to_num;
2use crate::common::transmitter::model::{
3    BeamAntennaPattern, CryptoKeyId, CryptoMode, ModulationType, SpreadSpectrum, Transmitter,
4    VariableTransmitterParameter, BASE_VTP_RECORD_LENGTH, BEAM_ANTENNA_PATTERN_OCTETS,
5};
6use crate::common::{Serialize, SerializePdu, SupportedVersion};
7use crate::constants::{EIGHT_OCTETS, ZERO_OCTETS};
8use bytes::{BufMut, BytesMut};
9
10impl SerializePdu for Transmitter {
11    fn serialize_pdu(&self, _version: SupportedVersion, buf: &mut BytesMut) -> u16 {
12        self.radio_reference_id.serialize(buf);
13        buf.put_u16(self.radio_number);
14        self.radio_type.serialize(buf);
15        buf.put_u8(self.transmit_state.into());
16        buf.put_u8(self.input_source.into());
17        buf.put_u16(self.variable_transmitter_parameters.len() as u16);
18        self.antenna_location.serialize(buf);
19        self.relative_antenna_location.serialize(buf);
20        buf.put_u16(self.antenna_pattern_type.into());
21        if self.antenna_pattern.is_some() {
22            buf.put_u16(BEAM_ANTENNA_PATTERN_OCTETS);
23        } else {
24            buf.put_u16(ZERO_OCTETS as u16);
25        }
26        buf.put_u64(self.frequency);
27        buf.put_f32(self.transmit_frequency_bandwidth);
28        buf.put_f32(self.power);
29        self.modulation_type.serialize(buf);
30        buf.put_u16(self.crypto_system.into());
31        self.crypto_key_id.serialize(buf);
32        if let Some(modulation_parameters) = &self.modulation_parameters {
33            buf.put_u8(modulation_parameters.len() as u8);
34        } else {
35            buf.put_u8(ZERO_OCTETS as u8);
36        }
37        buf.put_u8(0u8);
38        buf.put_u16(0u16);
39
40        let modulation_parameters_bytes =
41            if let Some(modulation_parameters) = &self.modulation_parameters {
42                modulation_parameters
43                    .iter()
44                    .map(|field| {
45                        buf.put_u8(*field);
46                        1u16
47                    })
48                    .sum::<u16>()
49            } else {
50                0u16
51            };
52
53        let antenna_pattern_bytes = if let Some(antenna_pattern) = &self.antenna_pattern {
54            antenna_pattern.serialize(buf);
55            BEAM_ANTENNA_PATTERN_OCTETS
56        } else {
57            ZERO_OCTETS as u16
58        };
59
60        let vtp_bytes = self
61            .variable_transmitter_parameters
62            .iter()
63            .map(|vtp| vtp.serialize(buf))
64            .sum::<u16>();
65
66        92 + modulation_parameters_bytes + antenna_pattern_bytes + vtp_bytes
67    }
68}
69
70impl Serialize for ModulationType {
71    fn serialize(&self, buf: &mut BytesMut) -> u16 {
72        let spread_spectrum_bytes = self.spread_spectrum.serialize(buf);
73        let (major_modulation, detail) = self.major_modulation.to_bytes_with_detail();
74        buf.put_u16(major_modulation);
75        buf.put_u16(detail);
76        buf.put_u16(self.radio_system.into());
77
78        spread_spectrum_bytes + 6
79    }
80}
81
82impl Serialize for SpreadSpectrum {
83    fn serialize(&self, buf: &mut BytesMut) -> u16 {
84        buf.put_u16(u16::from(self));
85        2
86    }
87}
88
89impl Serialize for CryptoKeyId {
90    fn serialize(&self, buf: &mut BytesMut) -> u16 {
91        let field = self.pseudo_crypto_key << 1;
92        let field = match self.crypto_mode {
93            CryptoMode::Baseband => field,
94            CryptoMode::Diphase => field + 1,
95        };
96        buf.put_u16(field);
97        2
98    }
99}
100
101impl Serialize for BeamAntennaPattern {
102    fn serialize(&self, buf: &mut BytesMut) -> u16 {
103        self.beam_direction.serialize(buf);
104        buf.put_f32(self.azimuth_beamwidth);
105        buf.put_f32(self.elevation_beamwidth);
106        buf.put_u8(self.reference_system.into());
107        buf.put_u8(0u8);
108        buf.put_u16(0u16);
109        buf.put_f32(self.e_z);
110        buf.put_f32(self.e_x);
111        buf.put_f32(self.phase);
112        buf.put_u32(0u32);
113
114        BEAM_ANTENNA_PATTERN_OCTETS
115    }
116}
117
118impl Serialize for VariableTransmitterParameter {
119    fn serialize(&self, buf: &mut BytesMut) -> u16 {
120        let record_padded_lengths = length_padded_to_num(
121            BASE_VTP_RECORD_LENGTH as usize + self.fields.len(),
122            EIGHT_OCTETS,
123        );
124        let record_length_bytes = record_padded_lengths.record_length as u16;
125
126        buf.put_u32(self.record_type.into());
127        buf.put_u16(record_length_bytes);
128        buf.put(&*self.fields);
129        buf.put_bytes(0u8, record_padded_lengths.padding_length);
130
131        record_length_bytes
132    }
133}