Skip to main content

dvb_si/descriptors/extension/
c2_delivery_system.rs

1//! C2 Delivery System Descriptor — ETSI EN 300 468 §6.4.6.1 (tag_extension 0x0D).
2use super::*;
3
4impl<'a> ExtensionBodyDef<'a> for C2DeliverySystem {
5    const TAG_EXTENSION: u8 = 0x0D;
6    const NAME: &'static str = "C2_DELIVERY_SYSTEM";
7}
8/// C2_delivery_system body (Table 115) — fully typed, fixed 7 bytes.
9#[derive(Debug, Clone, Copy, PartialEq, Eq)]
10#[cfg_attr(feature = "serde", derive(serde::Serialize))]
11pub struct C2DeliverySystem {
12    /// plp_id(8).
13    pub plp_id: u8,
14    /// data_slice_id(8).
15    pub data_slice_id: u8,
16    /// C2_System_tuning_frequency(32).
17    pub c2_system_tuning_frequency: u32,
18    /// C2_System_tuning_frequency_type(2).
19    pub c2_system_tuning_frequency_type: u8,
20    /// active_OFDM_symbol_duration(3).
21    pub active_ofdm_symbol_duration: u8,
22    /// guard_interval(3).
23    pub guard_interval: u8,
24}
25
26impl<'a> Parse<'a> for C2DeliverySystem {
27    type Error = crate::error::Error;
28    fn parse(sel: &'a [u8]) -> Result<Self> {
29        if sel.len() < C2_LEN {
30            return Err(Error::BufferTooShort {
31                need: C2_LEN,
32                have: sel.len(),
33                what: "C2_delivery_system body",
34            });
35        }
36        let packed = sel[6];
37        Ok(C2DeliverySystem {
38            plp_id: sel[0],
39            data_slice_id: sel[1],
40            c2_system_tuning_frequency: u32::from_be_bytes([sel[2], sel[3], sel[4], sel[5]]),
41            c2_system_tuning_frequency_type: packed >> 6,
42            active_ofdm_symbol_duration: (packed >> 3) & 0x07,
43            guard_interval: packed & 0x07,
44        })
45    }
46}
47
48impl Serialize for C2DeliverySystem {
49    type Error = crate::error::Error;
50    fn serialized_len(&self) -> usize {
51        C2_LEN
52    }
53    fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
54        let len = self.serialized_len();
55        if buf.len() < len {
56            return Err(Error::OutputBufferTooSmall {
57                need: len,
58                have: buf.len(),
59            });
60        }
61        buf[0] = self.plp_id;
62        buf[1] = self.data_slice_id;
63        buf[2..6].copy_from_slice(&self.c2_system_tuning_frequency.to_be_bytes());
64        buf[6] = (self.c2_system_tuning_frequency_type << 6)
65            | ((self.active_ofdm_symbol_duration & 0x07) << 3)
66            | (self.guard_interval & 0x07);
67        Ok(len)
68    }
69}
70
71#[cfg(test)]
72mod tests {
73    use super::*;
74    use crate::descriptors::extension::test_support::*;
75    use crate::descriptors::extension::{ExtensionBody, ExtensionDescriptor};
76
77    #[test]
78    fn parse_c2_delivery_system() {
79        let packed = (0x02 << 6) | (0x01 << 3) | 0x01;
80        let sel = [0x05, 0x09, 0x12, 0x34, 0x56, 0x78, packed];
81        let bytes = wrap(0x0D, &sel);
82        let d = ExtensionDescriptor::parse(&bytes).unwrap();
83        match &d.body {
84            ExtensionBody::C2DeliverySystem(b) => {
85                assert_eq!(b.plp_id, 0x05);
86                assert_eq!(b.data_slice_id, 0x09);
87                assert_eq!(b.c2_system_tuning_frequency, 0x1234_5678);
88                assert_eq!(b.c2_system_tuning_frequency_type, 0x02);
89                assert_eq!(b.active_ofdm_symbol_duration, 0x01);
90                assert_eq!(b.guard_interval, 0x01);
91            }
92            other => panic!("expected C2DeliverySystem, got {other:?}"),
93        }
94        round_trip(&d);
95    }
96}