use crate::util::*;
pub fn do_payload_checks<T: RDH, C: ChecksOpt + FilterOpt + CustomChecksOpt>(
cdp: (&T, &[u8], u64),
stats_send_chan: &flume::Sender<StatType>,
cdp_validator: &mut CdpRunningValidator<T, C>,
) -> Result<(), flume::SendError<StatType>> {
let (rdh, payload, rdh_mem_pos) = cdp;
cdp_validator.set_current_rdh(rdh, rdh_mem_pos);
match preprocess_payload(payload) {
Ok(gbt_word_chunks) => gbt_word_chunks.for_each(|gbt_word| {
cdp_validator.check(&gbt_word[..10]); }),
Err(e) => {
stats_send_chan.send(StatType::Error(
format!("{rdh_mem_pos:#X}: Payload error following RDH at this location: {e}")
.into(),
))?;
cdp_validator.reset_fsm();
}
}
Ok(())
}
#[allow(non_camel_case_types)] #[derive(Debug, Clone, Copy)]
pub enum ItsPayloadWord {
IHW,
IHW_continuation,
TDH,
TDH_continuation,
TDH_after_packet_done,
TDT,
CDW,
DataWord,
DDW0,
}
impl ItsPayloadWord {
pub fn from_id(word_id: u8) -> Result<Self, String> {
match word_id {
0x20..=0x28 | 0x40..=0x46 | 0x48..=0x4E | 0x50..=0x56 | 0x58..=0x5E => {
Ok(ItsPayloadWord::DataWord)
}
Tdh::ID => Ok(ItsPayloadWord::TDH),
Tdt::ID => Ok(ItsPayloadWord::TDT),
Ihw::ID => Ok(ItsPayloadWord::IHW),
Ddw0::ID => Ok(ItsPayloadWord::DDW0),
Cdw::ID => Ok(ItsPayloadWord::CDW),
_ => Err("Unknown ITS Payload Word ID".to_string()),
}
}
}
#[cfg(test)]
mod tests {
use super::*;
use alice_protocol_reader::prelude::test_data::CORRECT_RDH_CRU_V7;
static CFG_TEST_DO_PAYLOAD_CHECKS: OnceLock<MockConfig> = OnceLock::new();
#[test]
fn test_do_payload_checks_bad_payload() {
let mut mock_config = MockConfig::new();
mock_config.check = Some(CheckCommands::All(CheckModeArgs {
target: Some(System::ITS),
..Default::default()
}));
CFG_TEST_DO_PAYLOAD_CHECKS.set(mock_config).unwrap();
let (stats_send_chan, stats_recv_chan) = flume::unbounded();
let mut cdp_validator: CdpRunningValidator<RdhCru, MockConfig> = CdpRunningValidator::new(
CFG_TEST_DO_PAYLOAD_CHECKS.get().unwrap(),
stats_send_chan.clone(),
);
let rdh = CORRECT_RDH_CRU_V7;
let payload = vec![0x3D; 100];
let rdh_mem_pos = 0;
let cdp_slice = (&rdh, payload.as_slice(), rdh_mem_pos);
do_payload_checks(cdp_slice, &stats_send_chan, &mut cdp_validator).unwrap();
while let Ok(stats) = stats_recv_chan.try_recv() {
assert!(stats.to_string().contains("3D"));
println!("Stats: {stats:?}")
}
}
}