dvb-ci-runtime
Pure-Rust EN 50221 DVB Common Interface runtime — the driver loop over the
dvb-ci wire codecs.
dvb-ci is no_std and owns the wire layer (TPDU / SPDU / APDU
parse+serialize, CA_PMT building, CI Plus extensions). dvb-ci-runtime adds the
runtime: device I/O, the TPDU poll loop, SPDU session management, and the
per-resource state machines that drive a physical CAM (ETSI EN 50221, TS 101 699).
Design
Everything is written against the CaDevice trait, so the runtime runs against
either a real Linux CA device (/dev/dvb/adapterN/caM, the linux feature) or an
in-memory MockCaDevice. The mock makes the state machines testable without
hardware and enables differential testing against an external reference — drive
both with the same scripted mock CAM, assert the emitted write/ioctl byte
sequences match.
Implemented from the EN 50221 specification.
What's implemented
- Transport (TPDU, §A.4):
Create_T_Chandshake, poll cadence,T_SBdata-available →T_RCV,T_Data_More/Lastreassembly, reply timeout. - Session (SPDU, §7.2): session table;
open_session/create_session/close;session_number+ APDU routing. - Resources (§8): Resource Manager handshake →
CamReady, application_information, conditional_access (ca_pmt/ca_pmt_reply), date_time (MJD + BCD), mmi (surfaces module menus/enquiries). - Descramble helper:
Driver::descramble(pmt)/HostRequest::Descrambleruns the fullca_pmtquery → reply →ok_descramblingsequence, filtered to the CAM's advertised CAIDs (fromca_info). - Devices: in-memory
MockCaDevice+MockCiDataDevice; Linux/dev/dvb/adapterN/caM(control plane) andciM(TS data plane,CiDataDevice— scrambled-in / descrambled-out for separate-CI hardware) behind thelinuxfeature (libc). - Diagnostics:
RecordingCaDevicecaptures the link both ways;trace::decode_frame/decode_logannotate a capture (TPDU → SPDU → APDU) for live-CAM debugging. - MMI answering:
Driver::mmi_menu_answer/mmi_enquiry_answer/mmi_cancelsendmenu_answ/answback to the module.
ci-probe — discover and engage an installed CAM
A command-line tool that drives a real Common Interface module end-to-end over a
Linux DVB CA device. It is the reference consumer of this crate: it wires
Driver + LinuxCaDevice + RecordingCaDevice + trace together behind a
clap CLI (the workspace CLI standard — docs/CLI-STANDARD.md).
Build / install
Linux only; gated behind the linux feature (it opens /dev/dvb/... and uses
libc ioctls):
Device access usually needs membership of the video group (or root).
Commands
All device-addressed commands take -a/--adapter <N> and -c/--ca <N> (both
default 0). --help and --version are auto-generated; <command> --help
lists that command's flags.
| Command | What it does |
|---|---|
ci-probe list |
Enumerate /dev/dvb/adapterN/caM and print each slot's number + module_ready. |
ci-probe info [--adapter N] [--ca N] |
Run the EN 50221 handshake and print application_info + the CAM's CA_system_ids. |
ci-probe descramble [--adapter N] [--ca N] --pmt <FILE> |
Read a PMT section (raw bytes), then run the ca_pmt query → reply → ok_descrambling sequence and report the result. |
ci-probe mmi [--adapter N] [--ca N] |
Interactive MMI: display the module's menus / enquiries and send your answers back (menu_answ / answ). |
Append --trace to any command to dump an annotated link trace on exit
(every TPDU/SPDU/APDU both directions) — invaluable for diagnosing a CAM that
won't complete a handshake.
Examples
Discover what's installed:
$ ci-probe list
/dev/dvb/adapter0/ca0 slot 0 module_ready=true
Identify the module and its CA systems:
$ ci-probe info --adapter 0 --ca 0
CAM ready (resource-manager handshake complete)
application_info: type=0x01 manufacturer=0x1234 code=0x5678 menu="Irdeto CAM"
ca_info: 18 CA_system_id(s): 0x0604, 0x0606, 0x0608, ...
Diagnose a stuck handshake (annotated trace):
$ ci-probe info --adapter 0 --ca 0 --trace
...
reset()
slot_info() -> ready=true
W Create_T_C tcid=1
R C_T_C_Reply tcid=1
R T_Data_Last tcid=1 · open_session_request
W T_Data_Last tcid=1 · open_session_response
W T_Data_Last tcid=1 · session 1 · profile_enq (9F8010)
R T_Data_Last tcid=1 · session 1 · profile (9F8011)
...
Request descrambling for a service (PMT extracted with e.g. dvbsnoop or the
dvb-si tools):
$ ci-probe descramble --adapter 0 --ca 0 --pmt service.pmt
CAM ready (resource-manager handshake complete)
ca_info: 18 CA_system_id(s): ...
ca_info received → sending descramble request
ca_pmt_reply: program 1019 descrambling_ok=true
Hardware notes
- The device
read/writeexchange one whole kernel link frame[slot, connection_id, <TPDU + T_SB>]; theLinuxCaDevicehandles that framing. - EN 50221's link is polled half-duplex — one
T_Data_Lastper moduleT_SB. The transport enforces this (a real CAM drops a second block sent before it answers the first — see #337). - If
infotimes out beforeca_info, re-run with--traceand read the last few lines — they show exactly which step the module stopped responding at.
The EN 50221 link is polled half-duplex — the host sends one T_Data_Last per
module T_SB. The transport queues outbound SPDUs and releases one per turn (a
real CAM drops a second block sent before it answers the first — #337).
#![deny(unsafe_code)] — the Linux device leaf is the sole #[allow]; the
sans-IO core is unsafe-free. 27 tests, no hardware required.
Roadmap: the host_control resource, MMI answering (menu_answ/answ), and a
differential test harness against an external reference.
Example
use Duration;
use ;
use tags;
// Script a module that accepts the transport connection.
let dev = new;
let mut driver = new;
driver.init?; // reset + open the transport connection
for _ in 0..4
for note in driver.take_notifications
# Ok::
See examples/ for a runnable version.
License
MIT OR Apache-2.0.