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//! - [`crc`] — CRC-32 per Annex A.
9//!
10//! # RFU policy
11//!
12//! Payload parsers REJECT non-zero reserved (rfu) bits with
13//! `ReservedBitsViolation` and serialize them as 0 — with one deliberate
14//! exception: individual addressing (0x21) PRESERVES its leading rfu byte
15//! verbatim so gateway streams round-trip byte-exact (see
16//! `payload::individual_addressing`).
17//!
18//! # Quickstart: pump a TS, get typed payloads
19//!
20//! [`pump::T2miPump`] filters a TS by PID, reassembles + CRC-validates T2-MI
21//! packets, and hands back events whose [`payload`](pump::T2miEvent::payload)
22//! dispatches to a typed [`payload::AnyPayload`]:
23//!
24//! ```no_run
25//! use dvb_t2mi::pump::T2miPump;
26//! use dvb_t2mi::payload::AnyPayload;
27//!
28//! let mut pump = T2miPump::new(0x0006); // T2-MI PID from the PMT
29//! # let ts_packets: Vec<[u8; 188]> = Vec::new();
30//! for packet in &ts_packets { // each aligned 188-byte TS packet
31//! for event in pump.feed_ts(packet) {
32//! if let Ok(AnyPayload::Bbframe(bb)) = event.payload() {
33//! println!("BBFrame plp_id={}", bb.plp_id);
34//! }
35//! }
36//! }
37//! ```
38//!
39//! # The full signal chain
40//!
41//! T2-MI carries DVB-T2 BBFrames, which carry the inner MPEG-TS, which carries
42//! SI. The crates compose end to end — T2-MI here, BBFrame extraction in
43//! [`dvb-bbframe`](https://docs.rs/dvb-bbframe), SI demux in
44//! [`dvb-si`](https://docs.rs/dvb-si):
45//!
46//! ```text
47//! TS (T2-MI PID) ─▶ T2miPump ─▶ AnyPayload::Bbframe
48//! │ bb.bbframe
49//! ▼
50//! dvb_bbframe::Bbheader::parse + up_iter
51//! │ inner TS packets
52//! ▼
53//! dvb_si::demux::SiDemux ─▶ AnyTable
54//! ```
55//!
56//! A complete, working version of this chain (synthetic fixture, every layer
57//! built and asserted) lives in `dvb-t2mi/tests/chain.rs`.
58//!
59//! # Features
60//!
61//! | Feature | Default | Enables |
62//! |---|---|---|
63//! | `ts` | on | [`pump::T2miPump`] — PID-filtered TS reassembly + CRC validation. Off → bring your own complete T2-MI packet bytes. |
64//! | `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. |
65//! | `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. |
66//!
67//! # Header-only example
68//!
69//! ```
70//! use dvb_t2mi::packet::Header;
71//! use dvb_common::Parse;
72//! let buf = [0x00u8, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00];
73//! let hdr = Header::parse(&buf[..]).unwrap();
74//! assert_eq!(hdr.payload_len_bits, 0);
75//! ```
76
77#![warn(missing_docs)]
78
79pub mod crc;
80pub mod error;
81pub mod packet;
82pub mod payload;
83pub mod traits;
84
85#[cfg(feature = "ts")]
86pub mod pump;
87
88#[cfg(feature = "ts")]
89pub mod ts;
90
91pub use error::{Error, Result};