dvb-simulcrypt 0.4.0

DVB SimulCrypt head-end CA message framing (ETSI TS 103 197): the generic TLV message structure plus the ECMG⇔SCS and EMMG/PDG⇔MUX message_type / parameter_type registries. Signalling only — CW/ECM/EMM/datagram payloads are opaque.
Documentation

dvb-simulcrypt

Crates.io docs.rs

DVB SimulCrypt head-end CA message framing — ETSI TS 103 197. A codec for the messages the head-end carries over TCP between its conditional-access components; this crate does not open sockets.

Implements:

  • SimulcryptMessage — the generic generic_message (TS 103 197 §4.4.1, Table 1b): a 5-byte header (protocol_version + message_type + message_length, big-endian) followed by an ordered list of TLV **Parameter**s (parameter_type + parameter_length + value). message_length and every parameter_length are recomputed on serialize from the typed fields — there is no raw passthrough.
  • ECMG ⇔ SCS (clause 5): EcmgScsMessageType (channel/stream setup/test/status/close/error, CW_provision 0x0201, ECM_response 0x0202) + the Table 5 EcmgScsParameterType registry (Super_CAS_id 0x0001ECM_id 0x0019, error_status 0x7000, error_information 0x7001) + EcmgErrorStatus (Table 6).
  • EMMG/PDG ⇔ MUX (clause 6): EmmgMuxMessageType (channel/stream messages, stream_BW_request/allocation, data_provision 0x0211) + the Table 7 EmmgMuxParameterType registry + EmmgErrorStatus (Table 8), plus the DataType (§6.2.3) and SectionTspktFlag value tables.

Interface scoping

The 16-bit message_type / parameter_type spaces are interface-scoped: the same value means different things on different interfaces, and the interface is not on the wire — it is fixed by which TCP connection a message arrived on. So SimulcryptMessage::parse_on takes an Interface hint and decodes the raw values into the matching interface-tagged MessageType / ParameterType enums.

Signalling only — no crypto

The control words in CP_CW_combination / CW_encryption, the ECMs in ECM_datagram, and the EMM / private data in datagram are carried as opaque borrowed bytes. This crate frames and parses them; it never decrypts or interprets them. The non-implemented interfaces (C(P)SIG⇔(P)SIG, EIS⇔SCS, (P)SIG⇔MUX, ACG⇔EIS, SIMCOMP⇔MUXCONFIG) share the same framing but are not modelled.

#![no_std] + alloc; depends only on broadcast-common.

Quick start

use dvb_simulcrypt::{
    EcmgScsMessageType, EcmgScsParameterType, Interface, MessageType, Parameter,
    ParameterType, SimulcryptMessage,
};
use broadcast_common::traits::{Parse, Serialize};

let ecm_channel_id = [0x00, 0x2A];
let super_cas_id = [0x00, 0x01, 0x00, 0x02];
let msg = SimulcryptMessage::new(
    Interface::EcmgScs.protocol_version(),
    MessageType::EcmgScs(EcmgScsMessageType::ChannelSetup),
    vec![
        Parameter::new(
            ParameterType::EcmgScs(EcmgScsParameterType::EcmChannelId),
            &ecm_channel_id,
        ),
        Parameter::new(
            ParameterType::EcmgScs(EcmgScsParameterType::SuperCasId),
            &super_cas_id,
        ),
    ],
);

let mut buf = vec![0u8; msg.serialized_len()];
msg.serialize_into(&mut buf).unwrap();
assert_eq!(SimulcryptMessage::parse_on(Interface::EcmgScs, &buf).unwrap(), msg);

Examples

cargo run -p dvb-simulcrypt --example build_channel_setup
cargo run -p dvb-simulcrypt --example parse_cw_provision

Features

Feature Default Description
std yes Link the standard library. Without it the crate is #![no_std] + alloc.
serde no serde::Serialize derives on public types.

Minimum Supported Rust Version

1.86

License

MIT OR Apache-2.0