Skip to main content

dvb_si/collect/
sdt.rs

1use crate::descriptors::DescriptorRegistry;
2use crate::tables::sdt;
3use crate::tables::RunningStatus;
4use alloc::vec::Vec;
5
6use super::{CompleteSectionSet, ParsedDescriptorLoop};
7
8/// Service entry in a complete SDT.
9#[derive(Debug)]
10#[non_exhaustive]
11pub struct CompleteSdtService<'a> {
12    /// service_id.
13    pub service_id: u16,
14    /// EIT schedule flag.
15    pub eit_schedule_flag: bool,
16    /// EIT present/following flag.
17    pub eit_present_following_flag: bool,
18    /// 3-bit running status (EN 300 468 Table 6).
19    pub running_status: RunningStatus,
20    /// free_CA_mode.
21    pub free_ca_mode: bool,
22    /// Typed descriptor loop for this service.
23    pub descriptors: ParsedDescriptorLoop<'a>,
24}
25
26/// Complete logical Service Description Table.
27#[derive(Debug)]
28#[non_exhaustive]
29pub struct CompleteSdt<'a> {
30    /// Variant discriminator.
31    pub kind: sdt::SdtKind,
32    /// transport_stream_id of the described TS.
33    pub transport_stream_id: u16,
34    /// 5-bit version_number.
35    pub version_number: u8,
36    /// current_next_indicator bit.
37    pub current_next_indicator: bool,
38    /// original_network_id of the described TS.
39    pub original_network_id: u16,
40    /// Services from all sections in wire order.
41    pub services: Vec<CompleteSdtService<'a>>,
42}
43
44impl<'a> CompleteSdt<'a> {
45    pub(crate) fn parse(
46        set: &'a CompleteSectionSet,
47        registry: Option<&'a DescriptorRegistry>,
48    ) -> crate::Result<Self> {
49        let sections: Vec<sdt::SdtSection<'a>> = set.parse_sections()?;
50        let first = sections.first().ok_or(crate::Error::BufferTooShort {
51            need: 1,
52            have: 0,
53            what: "CompleteSdt sections",
54        })?;
55        let mut services = Vec::new();
56        for section in &sections {
57            services.extend(section.services.iter().map(|svc| CompleteSdtService {
58                service_id: svc.service_id,
59                eit_schedule_flag: svc.eit_schedule_flag,
60                eit_present_following_flag: svc.eit_present_following_flag,
61                running_status: svc.running_status,
62                free_ca_mode: svc.free_ca_mode,
63                descriptors: ParsedDescriptorLoop::parse(svc.descriptors, registry),
64            }));
65        }
66        Ok(Self {
67            kind: first.kind,
68            transport_stream_id: first.transport_stream_id,
69            version_number: first.version_number,
70            current_next_indicator: first.current_next_indicator,
71            original_network_id: first.original_network_id,
72            services,
73        })
74    }
75}