dvb_simulcrypt/lib.rs
1//! DVB SimulCrypt — head-end CA message framing (ETSI TS 103 197 V1.5.1).
2//!
3//! The DVB SimulCrypt head-end carries control/response messages between its
4//! conditional-access components over TCP. This crate is a **codec for those
5//! messages** — it does not open sockets. It implements the generic message
6//! structure and the two CA-bearing interfaces:
7//!
8//! - [`SimulcryptMessage`] — the generic `generic_message` (TS 103 197 §4.4.1,
9//! Table 1b): a 5-byte header (`protocol_version` + `message_type` +
10//! `message_length`, big-endian) followed by an ordered list of TLV
11//! [`Parameter`]s (`parameter_type` + `parameter_length` + value).
12//! `message_length` and every `parameter_length` are **recomputed on
13//! serialize** from the typed fields — there is no raw passthrough.
14//! - **ECMG ⇔ SCS** (clause 5): [`EcmgScsMessageType`] (channel/stream setup,
15//! test, status, close, error, plus `CW_provision` `0x0201` and
16//! `ECM_response` `0x0202`) and the Table 5 [`EcmgScsParameterType`] registry
17//! (`Super_CAS_id` `0x0001` … `ECM_id` `0x0019`, `error_status` `0x7000`,
18//! `error_information` `0x7001`) + [`EcmgErrorStatus`] (Table 6).
19//! - **EMMG/PDG ⇔ MUX** (clause 6): [`EmmgMuxMessageType`] (channel/stream
20//! messages, `stream_BW_request`/`allocation`, `data_provision` `0x0211`) and
21//! the Table 7 [`EmmgMuxParameterType`] registry + [`EmmgErrorStatus`]
22//! (Table 8), plus the [`DataType`] (§6.2.3) and [`SectionTspktFlag`] value
23//! tables.
24//!
25//! # Interface scoping
26//!
27//! The 16-bit `message_type`/`parameter_type` spaces are **interface-scoped**:
28//! the same value means different things on different interfaces, and the
29//! interface is not on the wire — it is fixed by which TCP connection the
30//! message arrived on (analogous to a resource scope). So
31//! [`SimulcryptMessage::parse_on`] takes an [`Interface`] hint and decodes the
32//! raw values into the matching interface-tagged [`MessageType`] /
33//! [`ParameterType`] enums.
34//!
35//! # Signalling only — no crypto
36//!
37//! The control words in `CP_CW_combination`/`CW_encryption`, the ECMs in
38//! `ECM_datagram`, and the EMM/private data in `datagram` are carried as
39//! **opaque borrowed bytes**. This crate frames and parses them; it never
40//! decrypts or interprets them. The non-implemented interfaces (C(P)SIG⇔(P)SIG,
41//! EIS⇔SCS, (P)SIG⇔MUX, ACG⇔EIS, SIMCOMP⇔MUXCONFIG) share the same framing but
42//! are not modelled.
43//!
44//! `#![no_std]` + `alloc`; depends only on `dvb-common`.
45//!
46//! # Examples
47//!
48//! Build an ECMG⇔SCS `channel_setup` from typed fields and round-trip it:
49//!
50//! ```
51//! use dvb_simulcrypt::{
52//! EcmgScsMessageType, EcmgScsParameterType, Interface, MessageType, Parameter,
53//! ParameterType, SimulcryptMessage,
54//! };
55//! use dvb_common::traits::{Parse, Serialize};
56//!
57//! let ecm_channel_id = [0x00, 0x2A]; // 0x002A
58//! let super_cas_id = [0x00, 0x01, 0x00, 0x02]; // CA_system_id | subsystem_id
59//! let msg = SimulcryptMessage::new(
60//! Interface::EcmgScs.protocol_version(),
61//! MessageType::EcmgScs(EcmgScsMessageType::ChannelSetup),
62//! vec![
63//! Parameter::new(
64//! ParameterType::EcmgScs(EcmgScsParameterType::EcmChannelId),
65//! &ecm_channel_id,
66//! ),
67//! Parameter::new(
68//! ParameterType::EcmgScs(EcmgScsParameterType::SuperCasId),
69//! &super_cas_id,
70//! ),
71//! ],
72//! );
73//!
74//! let mut buf = vec![0u8; msg.serialized_len()];
75//! msg.serialize_into(&mut buf).unwrap();
76//! assert_eq!(SimulcryptMessage::parse_on(Interface::EcmgScs, &buf).unwrap(), msg);
77//! ```
78#![no_std]
79#![cfg_attr(docsrs, feature(doc_cfg))]
80#![warn(missing_docs)]
81// Runnable examples, embedded so they render on docs.rs and stay in sync with
82// the actual `examples/*.rs` files (shown, not compiled).
83#![doc = "\n## Runnable examples\n"]
84#![doc = "Run with `cargo run -p dvb-simulcrypt --example <name>`.\n"]
85#![doc = "\n### `build_channel_setup`\n\n```rust,ignore"]
86#![doc = include_str!("../examples/build_channel_setup.rs")]
87#![doc = "```\n\n### `parse_cw_provision`\n\n```rust,ignore"]
88#![doc = include_str!("../examples/parse_cw_provision.rs")]
89#![doc = "```"]
90
91extern crate alloc;
92
93mod error;
94mod message;
95mod registry;
96
97pub use error::{Error, Result};
98pub use message::{Parameter, SimulcryptMessage, HEADER_LEN, PARAMETER_HEADER_LEN};
99pub use registry::{
100 DataType, EcmgErrorStatus, EcmgScsMessageType, EcmgScsParameterType, EmmgErrorStatus,
101 EmmgMuxMessageType, EmmgMuxParameterType, Interface, MessageType, ParameterType,
102 SectionTspktFlag,
103};