use core::convert::TryInto;
use serde::Serialize;
use crate::errors::Error;
use crate::Layer;
use crate::layers::sctp;
pub const PROTO_M3UA: u32 = 3u32;
pub(crate) fn register_defaults() -> Result<(), Error> {
sctp::register_datachunk_protocol(PROTO_M3UA, M3UA::creator)
}
#[derive(Debug, Default, Serialize)]
pub struct M3UA {
version: u8,
reserved: u8,
msg_class: u8,
msg_type: u8,
msg_length: u32,
#[serde(serialize_with = "hex::serde::serialize")]
msg_data: Vec<u8>,
}
impl M3UA {
pub fn creator() -> Box<dyn Layer + Send> {
Box::new(M3UA::default())
}
}
impl Layer for M3UA {
fn decode_bytes(
&mut self,
bytes: &[u8],
) -> Result<(Option<Box<dyn Layer + Send>>, usize), Error> {
if bytes.len() < 8 {
return Err(Error::TooShort);
}
let mut start = 0;
self.version = bytes[start];
start += 1;
self.reserved = bytes[start];
start += 1;
self.msg_class = bytes[start];
start += 1;
self.msg_type = bytes[start];
start += 1;
eprintln!(
"start: {}, byte: {:x}, len: {}",
start,
bytes[start],
bytes.len()
);
self.msg_length = u32::from_be_bytes(bytes[start..start + 4].try_into().unwrap());
if bytes.len() < self.msg_length as usize {
return Err(Error::TooShort);
}
let data_len = self.msg_length - 8;
self.msg_data = bytes[start..start + data_len as usize].try_into().unwrap();
Ok((None, self.msg_length as usize))
}
fn name(&self) -> &'static str {
"M3UA"
}
fn short_name(&self) -> &'static str {
"m3ua"
}
}