Skip to main content

dvb_t2mi/
lib.rs

1//! ETSI TS 102 773 v1.4.1 DVB-T2 Modulator Interface (T2-MI) parser + builder.
2//!
3//! Entry points:
4//! - [`Parse`](dvb_common::Parse) / [`Serialize`](dvb_common::Serialize) — the two
5//!   symmetric contracts every payload type implements.
6//! - [`packet`] — T2-MI packet header and type parsing.
7//! - [`payload`] — BBFrame, L1, FEF, timestamp, and addressing payload types.
8//! - [`payload::PayloadRegistry`] / [`pump::T2miEvent::payload_with`] — register
9//!   private packet types and dispatch through the registry.
10//! - [`payload::AnyPayload::dispatch_with`] — registry-aware dispatch for custom types.
11//! - [`crc`] — CRC-32 per Annex A.
12//!
13//! # RFU policy
14//!
15//! Payload parsers REJECT non-zero reserved (rfu) bits with
16//! `ReservedBitsViolation` and serialize them as 0 — with one deliberate
17//! exception: individual addressing (0x21) PRESERVES its leading rfu byte
18//! verbatim so gateway streams round-trip byte-exact (see
19//! `payload::individual_addressing`).
20//!
21//! # Quickstart: pump a TS, get typed payloads
22//!
23//! [`pump::T2miPump`] filters a TS by PID, reassembles + CRC-validates T2-MI
24//! packets, and hands back events whose [`payload`](pump::T2miEvent::payload)
25//! dispatches to a typed [`payload::AnyPayload`]:
26//!
27//! ```no_run
28//! # #[cfg(feature = "ts")] {
29//! use dvb_t2mi::pump::T2miPump;
30//! use dvb_t2mi::payload::AnyPayload;
31//!
32//! let mut pump = T2miPump::new(0x0006); // T2-MI PID from the PMT
33//! # let ts_packets: Vec<[u8; 188]> = Vec::new();
34//! for packet in &ts_packets {          // each aligned 188-byte TS packet
35//!     for event in pump.feed_ts(packet) {
36//!         if let Ok(AnyPayload::Bbframe(bb)) = event.payload() {
37//!             println!("BBFrame plp_id={}", bb.plp_id);
38//!         }
39//!     }
40//! }
41//! # }
42//! ```
43//!
44//! # The full signal chain
45//!
46//! T2-MI carries DVB-T2 BBFrames, which carry the inner MPEG-TS, which carries
47//! SI. The crates compose end to end — T2-MI here, BBFrame extraction in
48//! [`dvb-bbframe`](https://docs.rs/dvb-bbframe), SI demux in
49//! [`dvb-si`](https://docs.rs/dvb-si):
50//!
51//! ```text
52//! TS (T2-MI PID) ─▶ T2miPump ─▶ AnyPayload::Bbframe
53//!                                   │ bb.bbframe
54//!                                   ▼
55//!                          dvb_bbframe::Bbheader::parse + up_iter
56//!                                   │ inner TS packets
57//!                                   ▼
58//!                          dvb_si::demux::SiDemux ─▶ AnyTableSection
59//! ```
60//!
61//! A complete, working version of this chain (synthetic fixture, every layer
62//! built and asserted) lives in `dvb-t2mi/tests/chain.rs`.
63//!
64//! # Features
65//!
66//! | Feature | Default | Enables |
67//! |---|---|---|
68//! | `ts` | on | [`pump::T2miPump`] — PID-filtered TS reassembly + CRC validation. Off → bring your own complete T2-MI packet bytes. |
69//! | `serde` | on | **Serialize-only** — for display/export (JSON via serde_json); parsing FROM JSON is deliberately unsupported, re-parse from wire bytes. `Serialize` on every packet/payload type. |
70//! | `yoke` | off | [`yoke::Yokeable`] on the zero-copy payload view types — own a parsed T2-MI payload past the input buffer's borrow without re-parsing. |
71//!
72//! # Header-only example
73//!
74//! ```
75//! use dvb_t2mi::packet::Header;
76//! use dvb_common::Parse;
77//! let buf = [0x00u8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
78//! let hdr = Header::parse(&buf[..]).unwrap();
79//! assert_eq!(hdr.payload_len_bits, 0);
80//! ```
81
82#![warn(missing_docs)]
83
84pub mod crc;
85pub mod error;
86pub mod packet;
87pub mod payload;
88pub mod traits;
89
90#[cfg(feature = "ts")]
91pub mod pump;
92
93#[cfg(feature = "ts")]
94pub mod ts;
95
96pub use error::{Error, Result};