dvb-simulcrypt 0.5.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
# Changelog

All notable changes to `dvb-simulcrypt` will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

## [0.5.0] - 2026-08-11

### Changed
- MSRV raised to **1.95.0** (issue #949). This removes the workspace's MSRV
  split: `webrtc-runtime`'s optional `media` feature needed rustc 1.88 (via
  `rcgen`), which had grown a dedicated CI job, six `--exclude` lanes and a
  guard script to contain. Adopting let-chains and `is_multiple_of` where the
  1.95 lints require them; no functional or API change.
### Added
- `tests/non_exhaustive_coverage.rs` drift guard (issue #806). No public API
  or behaviour change.

## [0.4.0] - 2026-07-29

### Changed (BREAKING)
- **Requires `broadcast-common` 9** (issue #819). No functional or API change of
  this crate's own.

  Staying on `broadcast-common` 8 was not neutral: this crate's types implement
  `Parse`/`Serialize` from whichever major it links, so a consumer that used it
  alongside a 9-based crate (`transmux` 0.20, `dvb-si` 9, …) got **both majors
  in one graph**, and the trait methods resolved against the wrong one —
  surfacing as `no method named to_bytes found` / `no function named parse
  found` on types that plainly have them, with the compiler pointing at
  `broadcast-common-8.x/src/traits.rs`.

  The 9.0.0 wave originally shipped only the crates needed to publish
  `transmux`/`media-plane`/`multimux`, on the reasoning that everything else
  stayed coherent on its own 8 line. That reasoning was wrong: these crates
  exist to be composed, and the breakage only appears in a consumer that mixes
  them.

## [0.3.0] - 2026-07-03
### Changed
- Rust **edition 2024**; MSRV raised to **1.86**; format-argument modernisation. No functional or API change.

## [0.2.1] — 2026-06-29

### Changed
- Dependency `broadcast-common` bump (renamed from `dvb-common`); no API change.

## [0.2.0] — 2026-06-22

### Added

- C(P)SIG ⇔ (P)SIG interface (TS 103 197 clause 8): `Interface::CpSigPSig`,
  `CpSigMessageType` (22 channel/stream/trigger/table/descriptor/PID-provision
  message types `0x0301``0x0321`), and `CpSigParameterType` (46 parameter
  types from Table 36, `0x000D`/`0x0100``0x012C`/`0x7000``0x7001`), all in
  `registry.rs`. Wired into the unified `MessageType`/`ParameterType` dispatch
  enums. Round-trip drift and message-round-trip tests in `tests/framing.rs`.

## [0.1.0] — 2026-06-21

### Fixed

- Added `tests/label_coverage.rs` drift-guard (issue #204 convention): scans
  every `pub enum` in `src/` and fails if any lacks a `Display` / `name()` impl.
  SKIP = `["Error"]`. Enforces the convention for all 11 public spec enums
  (`Interface`, `EcmgScsMessageType`, `EmmgMuxMessageType`, `MessageType`,
  `EcmgScsParameterType`, `EmmgMuxParameterType`, `ParameterType`, `DataType`,
  `SectionTspktFlag`, `EcmgErrorStatus`, `EmmgErrorStatus`).
- Expanded `error_status_values` test in `tests/framing.rs` into exhaustive
  loop-tables (`ecmg_error_status_values` / `emmg_error_status_values`) covering
  all 23 `EcmgErrorStatus` and 22 `EmmgErrorStatus` named variants with
  `to_u16`/`from_u16` round-trips and `Reserved(v)` pass-through assertions.
- Added `emmg_message_type_reserved_passthrough` test for `EmmgMuxMessageType`
  (mirrors the existing `EcmgScsMessageType` reserved pass-through check).
- Guarded `cpcw.value[0..2]` in `examples/parse_cw_provision.rs` against short
  values — uses `get(0..2)` and prints a graceful message instead of panicking.
- Added `#[cfg(feature = "serde")]` `serde_cw_provision_smoke` test serialising
  a `CW_provision` message to JSON and asserting the expected field names
  (`message_type`, `parameters`, `CwProvision`) are present; puts the existing
  `serde_json` dev-dependency to use.


### Added

- `SimulcryptMessage` — parser+serializer for the DVB SimulCrypt generic
  message (ETSI 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 (no raw passthrough). `parse_on` validates
  the header, the `message_length` bound, and each `parameter_length`.
- `Parameter` — one TLV: a typed `ParameterType` + a borrowed, **opaque**
  `parameter_value` (CW/ECM/EMM/datagram bytes are carried, never interpreted).
- `Interface` — scopes the interface-dependent `message_type`/`parameter_type`
  numeric spaces (the interface is fixed by the TCP connection, supplied as a
  hint to `parse_on`). `EcmgScs` and `EmmgPdgMux` are modelled.
- 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`
  `0x0001``ECM_id` `0x0019`, `error_status` `0x7000`, `error_information`
  `0x7001`), and the Table 6 `EcmgErrorStatus` codes.
- EMMG/PDG⇔MUX (clause 6): `EmmgMuxMessageType` (channel/stream messages,
  `stream_BW_request`/`allocation`, `data_provision` `0x0211`), the Table 7
  `EmmgMuxParameterType` registry, the Table 8 `EmmgErrorStatus` codes, and the
  `DataType` (§6.2.3) and `SectionTspktFlag` value tables.
- Interface-tagged `MessageType` / `ParameterType` enums + per-interface
  `name()` + `impl_spec_display!` labels on every public spec enum.
- A hand-built `CW_provision` fixture (`tests/fixtures/cw_provision.bin`,
  TS 103 197 §5.5.7) with an integration test parsing its fields and byte-exact
  round-tripping it; the CW inside `CP_CW_combination` stays opaque.
- Two runnable examples: `build_channel_setup` (construct + serialize from
  typed fields) and `parse_cw_provision` (read + walk + round-trip the fixture).
- `#![no_std]` + `alloc`; builds with `--no-default-features`.
- `serde` support behind the `serde` feature.