pub mod ack;
pub mod control;
pub mod data;
pub mod handshake;
pub mod key_material;
pub mod misc;
pub mod nak;
pub use ack::{AckCif, AckPacket};
pub use control::{ControlPacket, ControlType, UserDefinedPacket};
pub use data::{DataPacket, EncryptionKeyField, PacketPosition};
pub use handshake::{
EncryptionField, ExtensionType, GroupFlags, GroupMembershipExtension, GroupType,
HandshakeExtensionBlock, HandshakeExtensionFlags, HandshakeExtensionMessageFlags,
HandshakeExtensions, HandshakePacket, HandshakeType, HsExtMessage,
};
pub use key_material::{Cipher, KeyMaterial, KmAuth, KmKeyFlag, StreamEncapsulation};
pub use misc::{
AckAckPacket, CongestionWarningPacket, DropReqPacket, KeepAlivePacket, PeerErrorPacket,
ShutdownPacket,
};
pub use nak::{LossListEntry, NakPacket};
use crate::error::{Error, Result};
pub const SRT_HEADER_LEN: usize = 16;
pub(crate) const F_BIT: u32 = 0x8000_0000;
pub(crate) const SEQ_NUMBER_MASK: u32 = 0x7FFF_FFFF;
#[derive(Debug, Clone, PartialEq)]
#[cfg_attr(feature = "serde", derive(serde::Serialize))]
#[non_exhaustive]
pub enum SrtPacket<'a> {
Data(DataPacket<'a>),
Control(ControlPacket<'a>),
}
impl<'a> SrtPacket<'a> {
pub fn parse(bytes: &'a [u8]) -> Result<Self> {
if bytes.len() < SRT_HEADER_LEN {
return Err(Error::BufferTooShort {
need: SRT_HEADER_LEN,
have: bytes.len(),
what: "SRT header",
});
}
let word0 = be32(bytes, 0);
if word0 & F_BIT != 0 {
Ok(SrtPacket::Control(ControlPacket::parse(bytes)?))
} else {
Ok(SrtPacket::Data(DataPacket::parse(bytes)?))
}
}
pub fn serialized_len(&self) -> usize {
match self {
SrtPacket::Data(d) => d.serialized_len(),
SrtPacket::Control(c) => c.serialized_len(),
}
}
pub fn serialize_into(&self, buf: &mut [u8]) -> Result<usize> {
match self {
SrtPacket::Data(d) => d.serialize_into(buf),
SrtPacket::Control(c) => c.serialize_into(buf),
}
}
}
pub(crate) fn be32(bytes: &[u8], off: usize) -> u32 {
u32::from_be_bytes([bytes[off], bytes[off + 1], bytes[off + 2], bytes[off + 3]])
}
pub(crate) fn put_be32(buf: &mut [u8], off: usize, value: u32) {
buf[off..off + 4].copy_from_slice(&value.to_be_bytes());
}
pub(crate) fn be16(bytes: &[u8], off: usize) -> u16 {
u16::from_be_bytes([bytes[off], bytes[off + 1]])
}
pub(crate) fn put_be16(buf: &mut [u8], off: usize, value: u16) {
buf[off..off + 2].copy_from_slice(&value.to_be_bytes());
}