use alloc::string::String;
use alloc::vec::Vec;
use core::fmt::Write as _;
use crate::ast::Protocol;
use crate::reverse::{ProtocolDissection, sd};
use super::{checked_be_u16, checked_be_u32};
pub(crate) fn dissect_rtp(payload: &[u8]) -> Option<ProtocolDissection> {
if payload.len() < 12 || payload[0] != 0x80 {
return None;
}
let marker = (payload[1] >> 7) & 0x01;
let pt = payload[1] & 0x7F;
let seq = checked_be_u16(payload, 2)?;
let timestamp = checked_be_u32(payload, 4)?;
let ssrc = checked_be_u32(payload, 8)?;
let audio = payload.get(12..)?;
let mut tokens = String::from("rtp");
if pt != 0 {
let _ = write!(tokens, " pt {pt}");
}
if seq != 1 {
let _ = write!(tokens, " seq {seq}");
}
if timestamp != 160 {
let _ = write!(tokens, " timestamp {timestamp}");
}
if ssrc != 0x12345678 {
let _ = write!(tokens, " ssrc 0x{ssrc:08x}");
}
if marker != 0 {
let _ = write!(tokens, " marker {marker}");
}
let residual = if audio == [0u8; 160] {
Vec::new()
} else {
audio.to_vec()
};
Some(sd(Protocol::Rtp, tokens, residual))
}