pub struct Driver<D: CaDevice> { /* private fields */ }Implementations§
Source§impl<D: CaDevice> Driver<D>
impl<D: CaDevice> Driver<D>
Sourcepub fn new(device: D) -> Self
pub fn new(device: D) -> Self
New driver over device, single transport connection.
Examples found in repository?
15fn main() -> std::io::Result<()> {
16 // Script a module that accepts the transport connection (C_T_C_Reply).
17 let dev = MockCaDevice::new([vec![tags::C_T_C_REPLY, 0x01, 0x01]]);
18 let mut driver = Driver::new(dev);
19
20 // Bring the interface up: reset + open the transport connection.
21 driver.init()?;
22 println!("init: sent {} device op(s)", driver.device().ops.len());
23
24 // Pump the device. When readable it reads a frame and feeds the stack;
25 // otherwise it advances the EN 50221 poll cadence by the timeout.
26 for step in 0..5 {
27 let read = driver.pump(Duration::from_millis(100))?;
28 println!("pump {step}: processed_frame={read}");
29 }
30
31 // Anything the host application needs to act on surfaces as a Notification.
32 for note in driver.take_notifications() {
33 match note {
34 Notification::CamReady => println!("note: CAM ready — safe to send ca_pmt"),
35 Notification::ApplicationInfo { menu, .. } => {
36 println!("note: application_information menu={menu:?}")
37 }
38 Notification::CaInfo { ca_system_ids } => {
39 println!("note: ca_info system_ids={ca_system_ids:?}")
40 }
41 other => println!("note: {other:?}"),
42 }
43 }
44
45 // The mock records every device op (writes/ioctls) — handy for assertions.
46 println!("total recorded device ops: {}", driver.device().ops.len());
47 Ok(())
48}Sourcepub fn device(&self) -> &D
pub fn device(&self) -> &D
Borrow the underlying device (e.g. to inspect a mock’s recorded ops).
Examples found in repository?
15fn main() -> std::io::Result<()> {
16 // Script a module that accepts the transport connection (C_T_C_Reply).
17 let dev = MockCaDevice::new([vec![tags::C_T_C_REPLY, 0x01, 0x01]]);
18 let mut driver = Driver::new(dev);
19
20 // Bring the interface up: reset + open the transport connection.
21 driver.init()?;
22 println!("init: sent {} device op(s)", driver.device().ops.len());
23
24 // Pump the device. When readable it reads a frame and feeds the stack;
25 // otherwise it advances the EN 50221 poll cadence by the timeout.
26 for step in 0..5 {
27 let read = driver.pump(Duration::from_millis(100))?;
28 println!("pump {step}: processed_frame={read}");
29 }
30
31 // Anything the host application needs to act on surfaces as a Notification.
32 for note in driver.take_notifications() {
33 match note {
34 Notification::CamReady => println!("note: CAM ready — safe to send ca_pmt"),
35 Notification::ApplicationInfo { menu, .. } => {
36 println!("note: application_information menu={menu:?}")
37 }
38 Notification::CaInfo { ca_system_ids } => {
39 println!("note: ca_info system_ids={ca_system_ids:?}")
40 }
41 other => println!("note: {other:?}"),
42 }
43 }
44
45 // The mock records every device op (writes/ioctls) — handy for assertions.
46 println!("total recorded device ops: {}", driver.device().ops.len());
47 Ok(())
48}Sourcepub fn next_timer(&self) -> Option<Duration>
pub fn next_timer(&self) -> Option<Duration>
The poll delay the stack most recently requested, if any.
Sourcepub fn take_notifications(&mut self) -> Vec<Notification>
pub fn take_notifications(&mut self) -> Vec<Notification>
Drain the notifications collected so far.
Examples found in repository?
15fn main() -> std::io::Result<()> {
16 // Script a module that accepts the transport connection (C_T_C_Reply).
17 let dev = MockCaDevice::new([vec![tags::C_T_C_REPLY, 0x01, 0x01]]);
18 let mut driver = Driver::new(dev);
19
20 // Bring the interface up: reset + open the transport connection.
21 driver.init()?;
22 println!("init: sent {} device op(s)", driver.device().ops.len());
23
24 // Pump the device. When readable it reads a frame and feeds the stack;
25 // otherwise it advances the EN 50221 poll cadence by the timeout.
26 for step in 0..5 {
27 let read = driver.pump(Duration::from_millis(100))?;
28 println!("pump {step}: processed_frame={read}");
29 }
30
31 // Anything the host application needs to act on surfaces as a Notification.
32 for note in driver.take_notifications() {
33 match note {
34 Notification::CamReady => println!("note: CAM ready — safe to send ca_pmt"),
35 Notification::ApplicationInfo { menu, .. } => {
36 println!("note: application_information menu={menu:?}")
37 }
38 Notification::CaInfo { ca_system_ids } => {
39 println!("note: ca_info system_ids={ca_system_ids:?}")
40 }
41 other => println!("note: {other:?}"),
42 }
43 }
44
45 // The mock records every device op (writes/ioctls) — handy for assertions.
46 println!("total recorded device ops: {}", driver.device().ops.len());
47 Ok(())
48}Sourcepub fn init(&mut self) -> Result<()>
pub fn init(&mut self) -> Result<()>
Bring the interface up (reset + open the transport connection).
Examples found in repository?
15fn main() -> std::io::Result<()> {
16 // Script a module that accepts the transport connection (C_T_C_Reply).
17 let dev = MockCaDevice::new([vec![tags::C_T_C_REPLY, 0x01, 0x01]]);
18 let mut driver = Driver::new(dev);
19
20 // Bring the interface up: reset + open the transport connection.
21 driver.init()?;
22 println!("init: sent {} device op(s)", driver.device().ops.len());
23
24 // Pump the device. When readable it reads a frame and feeds the stack;
25 // otherwise it advances the EN 50221 poll cadence by the timeout.
26 for step in 0..5 {
27 let read = driver.pump(Duration::from_millis(100))?;
28 println!("pump {step}: processed_frame={read}");
29 }
30
31 // Anything the host application needs to act on surfaces as a Notification.
32 for note in driver.take_notifications() {
33 match note {
34 Notification::CamReady => println!("note: CAM ready — safe to send ca_pmt"),
35 Notification::ApplicationInfo { menu, .. } => {
36 println!("note: application_information menu={menu:?}")
37 }
38 Notification::CaInfo { ca_system_ids } => {
39 println!("note: ca_info system_ids={ca_system_ids:?}")
40 }
41 other => println!("note: {other:?}"),
42 }
43 }
44
45 // The mock records every device op (writes/ioctls) — handy for assertions.
46 println!("total recorded device ops: {}", driver.device().ops.len());
47 Ok(())
48}Sourcepub fn send_ca_pmt(&mut self, ca_pmt: &[u8]) -> Result<()>
pub fn send_ca_pmt(&mut self, ca_pmt: &[u8]) -> Result<()>
Request the module descramble the services in ca_pmt (a serialized
ca_pmt APDU body, e.g. from dvb_ci::build_ca_pmt).
Sourcepub fn descramble(&mut self, pmt_section: &[u8]) -> Result<()>
pub fn descramble(&mut self, pmt_section: &[u8]) -> Result<()>
Descramble the services in a PMT section: the stack filters the PMT’s
CA_descriptors to the CAM’s advertised CAIDs, sends a ca_pmt query,
and auto-sends ok_descrambling once the ca_pmt_reply confirms it.
Drive pump afterwards to exchange the reply; the outcome
surfaces as Notification::CaPmtReply. Call after the CAM is ready and
its ca_info has been received (otherwise no CAID filter is applied).
Answer an MMI menu/list by 1-based choice_ref (0 = back/cancel).
Sourcepub fn mmi_enquiry_answer(&mut self, text: &[u8]) -> Result<()>
pub fn mmi_enquiry_answer(&mut self, text: &[u8]) -> Result<()>
Answer an MMI enquiry with the user’s input (EN 300 468 Annex A bytes).
Sourcepub fn mmi_cancel(&mut self) -> Result<()>
pub fn mmi_cancel(&mut self) -> Result<()>
Abort the current MMI dialogue (answ with answ_id = cancel).
Ask the module to open its MMI menu (enter_menu) — e.g. to read card /
entitlement info from the module’s own menus.
Sourcepub fn pump(&mut self, timeout: Duration) -> Result<bool>
pub fn pump(&mut self, timeout: Duration) -> Result<bool>
One pump step: if the device is readable within timeout, read a frame
and feed it; otherwise advance the stack’s timers by timeout (driving
the poll cadence). Returns whether a frame was processed.
Examples found in repository?
15fn main() -> std::io::Result<()> {
16 // Script a module that accepts the transport connection (C_T_C_Reply).
17 let dev = MockCaDevice::new([vec![tags::C_T_C_REPLY, 0x01, 0x01]]);
18 let mut driver = Driver::new(dev);
19
20 // Bring the interface up: reset + open the transport connection.
21 driver.init()?;
22 println!("init: sent {} device op(s)", driver.device().ops.len());
23
24 // Pump the device. When readable it reads a frame and feeds the stack;
25 // otherwise it advances the EN 50221 poll cadence by the timeout.
26 for step in 0..5 {
27 let read = driver.pump(Duration::from_millis(100))?;
28 println!("pump {step}: processed_frame={read}");
29 }
30
31 // Anything the host application needs to act on surfaces as a Notification.
32 for note in driver.take_notifications() {
33 match note {
34 Notification::CamReady => println!("note: CAM ready — safe to send ca_pmt"),
35 Notification::ApplicationInfo { menu, .. } => {
36 println!("note: application_information menu={menu:?}")
37 }
38 Notification::CaInfo { ca_system_ids } => {
39 println!("note: ca_info system_ids={ca_system_ids:?}")
40 }
41 other => println!("note: {other:?}"),
42 }
43 }
44
45 // The mock records every device op (writes/ioctls) — handy for assertions.
46 println!("total recorded device ops: {}", driver.device().ops.len());
47 Ok(())
48}