use crate::crc_any::CRC;
use crate::msg::message::Message;
use crate::rtcm_error::RtcmError;
pub struct MessageFrame<'a> {
frame_data: &'a [u8],
data: &'a [u8],
crc: u32,
message_number: Option<u16>,
}
impl<'a> MessageFrame<'a> {
pub fn new(frame_data: &'a [u8]) -> Result<Self, RtcmError> {
if frame_data.len() < 6 {
return Err(RtcmError::Incomplete);
}
if frame_data[0] != 0xd3 {
return Err(RtcmError::NotValid);
}
let length: usize = ((frame_data[1] as usize & 0b11) << 8) | (frame_data[2] as usize);
if frame_data.len() < length + 6 {
return Err(RtcmError::Incomplete);
}
let mut crc24 = CRC::crc24lte_a();
crc24.digest(&frame_data[0..length + 3]);
let msg_crc = ((frame_data[length + 3] as u32) << 16)
| ((frame_data[length + 4] as u32) << 8)
| (frame_data[length + 5] as u32);
if msg_crc != crc24.get_crc() as u32 {
return Err(RtcmError::NotValid);
}
let message_number: Option<u16> = if frame_data.len() >= 8 {
Some(((frame_data[3] as u16) << 4) | ((frame_data[4] as u16) >> 4))
} else {
None
};
Ok(MessageFrame {
frame_data: &frame_data[..length + 6],
data: &frame_data[3..length + 3],
crc: msg_crc,
message_number,
})
}
pub fn data(&'a self) -> &'a [u8] {
&*self.data
}
pub fn frame_data(&'a self) -> &'a [u8] {
&*self.frame_data
}
pub fn data_len(&self) -> usize {
self.data.len()
}
pub fn frame_len(&self) -> usize {
self.frame_data.len()
}
pub fn crc(&self) -> u32 {
self.crc
}
pub fn message_number(&self) -> Option<u16> {
self.message_number
}
pub fn get_message(&self) -> Message {
Message::from_message_frame(self)
}
}