use zerocopy::byteorder::{BigEndian, LittleEndian, U16, U32};
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
pub const DTX_MAGIC: u32 = 0x795B3D1F;
#[derive(Debug, Clone, Copy, FromBytes, IntoBytes, KnownLayout, Immutable)]
#[repr(C)]
pub struct DtxHeader {
pub magic: U32<BigEndian>,
pub header_length: U32<LittleEndian>,
pub fragment_index: U16<LittleEndian>,
pub fragment_count: U16<LittleEndian>,
pub message_length: U32<LittleEndian>,
pub identifier: U32<LittleEndian>,
pub conversation_idx: U32<LittleEndian>,
pub channel_code: U32<LittleEndian>,
pub expects_reply: U32<LittleEndian>,
}
impl DtxHeader {
pub const SIZE: usize = 32;
pub const HEADER_LENGTH: u32 = 32;
pub fn is_fragment(&self) -> bool {
self.fragment_count.get() > 1
}
pub fn is_first_fragment(&self) -> bool {
self.fragment_index.get() == 0
}
}
#[derive(Debug, Clone, Copy, FromBytes, IntoBytes, KnownLayout, Immutable)]
#[repr(C)]
pub struct DtxPayloadHeader {
pub message_type: U32<LittleEndian>,
pub auxiliary_length: U32<LittleEndian>,
pub total_payload_length: U32<LittleEndian>,
pub flags: U32<LittleEndian>,
}
impl DtxPayloadHeader {
pub const SIZE: usize = 16;
pub fn has_auxiliary(&self) -> bool {
self.auxiliary_length.get() > 0
}
pub fn payload_length(&self) -> u32 {
self.total_payload_length
.get()
.saturating_sub(self.auxiliary_length.get())
}
}
#[derive(Debug, Clone, Copy, FromBytes, IntoBytes, KnownLayout, Immutable)]
#[repr(C)]
pub struct DtxAuxiliaryHeader {
pub buffer_size: U32<LittleEndian>,
pub unknown: U32<LittleEndian>,
pub auxiliary_size: U32<LittleEndian>,
pub unknown2: U32<LittleEndian>,
}
impl DtxAuxiliaryHeader {
pub const SIZE: usize = 16;
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[repr(u32)]
pub enum DtxMessageType {
MethodInvocation = 2,
Response = 3,
Notification = 4,
}