use crate::csa;
use crate::error::Error;
use crate::key::ControlWord;
pub fn scramble_ts_packet(cw: &ControlWord, packet: &mut [u8; 188]) -> Result<(), Error> {
let payload = ts_payload_mut(packet)?;
csa::scramble(cw, payload);
packet[3] = (packet[3] & 0x3f) | 0x80;
Ok(())
}
pub fn descramble_ts_packet(cw: &ControlWord, packet: &mut [u8; 188]) -> Result<(), Error> {
let payload = ts_payload_mut(packet)?;
csa::descramble(cw, payload);
packet[3] &= 0x3f;
Ok(())
}
fn ts_payload_mut(packet: &mut [u8; 188]) -> Result<&mut [u8], Error> {
let adaptation_field_control = (packet[3] >> 4) & 0x03;
let has_adaptation = adaptation_field_control & 0x02 != 0;
let has_payload = adaptation_field_control & 0x01 != 0;
if !has_payload {
return Err(Error::BufferTooShort { need: 1, have: 0 });
}
let mut payload_start = 4;
if has_adaptation {
let af_len = packet[4] as usize;
payload_start += 1 + af_len; }
if payload_start >= 188 {
return Err(Error::BufferTooShort { need: 1, have: 0 });
}
Ok(&mut packet[payload_start..188])
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn roundtrip_ts_packet() {
let cw = ControlWord::from_bytes([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]);
let mut packet = [0u8; 188];
packet[0] = 0x47; packet[1] = 0x41; packet[2] = 0x00; packet[3] = 0x10; for i in 0..184 {
packet[4 + i] = (i % 256) as u8;
}
let original = packet;
scramble_ts_packet(&cw, &mut packet).unwrap();
assert_ne!(packet[4..], original[4..]);
assert_eq!(packet[3] & 0xc0, 0x80);
descramble_ts_packet(&cw, &mut packet).unwrap();
assert_eq!(packet[4..], original[4..]);
assert_eq!(packet[3] & 0xc0, 0x00); }
}