1use crate::csa;
6use crate::error::Error;
7use crate::key::ControlWord;
8
9pub fn scramble_ts_packet(cw: &ControlWord, packet: &mut [u8; 188]) -> Result<(), Error> {
14 let payload = ts_payload_mut(packet)?;
15 csa::scramble(cw, payload);
16 packet[3] = (packet[3] & 0x3f) | 0x80;
18 Ok(())
19}
20
21pub fn descramble_ts_packet(cw: &ControlWord, packet: &mut [u8; 188]) -> Result<(), Error> {
26 let payload = ts_payload_mut(packet)?;
27 csa::descramble(cw, payload);
28 packet[3] &= 0x3f;
30 Ok(())
31}
32
33fn ts_payload_mut(packet: &mut [u8; 188]) -> Result<&mut [u8], Error> {
36 let adaptation_field_control = (packet[3] >> 4) & 0x03;
37 let has_adaptation = adaptation_field_control & 0x02 != 0;
38 let has_payload = adaptation_field_control & 0x01 != 0;
39
40 if !has_payload {
41 return Err(Error::BufferTooShort { need: 1, have: 0 });
42 }
43
44 let mut payload_start = 4; if has_adaptation {
47 let af_len = packet[4] as usize;
48 payload_start += 1 + af_len; }
50
51 if payload_start >= 188 {
52 return Err(Error::BufferTooShort { need: 1, have: 0 });
53 }
54
55 Ok(&mut packet[payload_start..188])
56}
57
58#[cfg(test)]
59mod tests {
60 use super::*;
61
62 #[test]
63 fn roundtrip_ts_packet() {
64 let cw = ControlWord::from_bytes([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]);
65 let mut packet = [0u8; 188];
67 packet[0] = 0x47; packet[1] = 0x41; packet[2] = 0x00; packet[3] = 0x10; for i in 0..184 {
73 packet[4 + i] = (i % 256) as u8;
74 }
75
76 let original = packet;
77 scramble_ts_packet(&cw, &mut packet).unwrap();
78 assert_ne!(packet[4..], original[4..]);
79 assert_eq!(packet[3] & 0xc0, 0x80); descramble_ts_packet(&cw, &mut packet).unwrap();
82 assert_eq!(packet[4..], original[4..]);
84 assert_eq!(packet[3] & 0xc0, 0x00); }
86}