use super::DatagramRef;
use super::AckGroup;
use super::DATA_FRAME_ID;
use super::DATA_FRAME_MAX_DATAGRAM_COUNT;
use super::DATAGRAM_HEADER_SIZE_MICRO;
use super::DATAGRAM_HEADER_SIZE_SMALL;
use super::DATAGRAM_HEADER_SIZE_LARGE;
use super::ACK_FRAME_ID;
use super::ACK_GROUP_SIZE;
use super::FRAME_CRC_SIZE;
use super::MAX_CHANNELS;
use super::crc;
use crate::packet_id;
pub struct DataFrameBuilder {
buffer: Vec<u8>,
count: usize,
}
impl DataFrameBuilder {
pub const MAX_COUNT: usize = DATA_FRAME_MAX_DATAGRAM_COUNT;
pub fn new(sequence_id: u32, nonce: bool) -> Self {
let header = vec![
DATA_FRAME_ID,
(sequence_id >> 24) as u8,
(sequence_id >> 16) as u8,
(sequence_id >> 8) as u8,
(sequence_id ) as u8,
(nonce as u8) << 7,
];
Self {
buffer: header,
count: 0,
}
}
pub fn add(&mut self, datagram: &DatagramRef) {
debug_assert!((datagram.channel_id as usize) < MAX_CHANNELS);
debug_assert!(packet_id::is_valid(datagram.sequence_id));
debug_assert!(datagram.data.len() <= u16::MAX as usize);
debug_assert!(self.count < DATA_FRAME_MAX_DATAGRAM_COUNT);
let data_len_u16 = datagram.data.len() as u16;
if datagram.fragment_id_last == 0 {
debug_assert!(datagram.fragment_id == 0);
if data_len_u16 < 64 && datagram.window_parent_lead < 128 && datagram.channel_parent_lead < 256 {
let header = [
data_len_u16 as u8 | (datagram.channel_id & 0x10) << 2,
(datagram.sequence_id >> 12) as u8 & 0xF0 | datagram.channel_id & 0x0F,
(datagram.sequence_id >> 8) as u8,
(datagram.sequence_id ) as u8,
datagram.window_parent_lead as u8 | (datagram.channel_id & 0x20) << 2,
datagram.channel_parent_lead as u8,
];
self.buffer.extend_from_slice(&header);
self.buffer.extend_from_slice(&datagram.data);
self.count += 1;
return;
} else if data_len_u16 < 256 {
let header = [
datagram.channel_id | 0x80,
data_len_u16 as u8,
(datagram.sequence_id >> 16) as u8,
(datagram.sequence_id >> 8) as u8,
(datagram.sequence_id ) as u8,
(datagram.window_parent_lead >> 8) as u8,
(datagram.window_parent_lead ) as u8,
(datagram.channel_parent_lead >> 8) as u8,
(datagram.channel_parent_lead ) as u8,
];
self.buffer.extend_from_slice(&header);
self.buffer.extend_from_slice(&datagram.data);
self.count += 1;
return;
}
}
let header = [
datagram.channel_id | 0xC0,
(data_len_u16 >> 8) as u8,
(data_len_u16 ) as u8,
(datagram.sequence_id >> 16) as u8,
(datagram.sequence_id >> 8) as u8,
(datagram.sequence_id ) as u8,
(datagram.window_parent_lead >> 8) as u8,
(datagram.window_parent_lead ) as u8,
(datagram.channel_parent_lead >> 8) as u8,
(datagram.channel_parent_lead ) as u8,
(datagram.fragment_id >> 8) as u8,
(datagram.fragment_id ) as u8,
(datagram.fragment_id_last >> 8) as u8,
(datagram.fragment_id_last ) as u8,
];
self.buffer.extend_from_slice(&header);
self.buffer.extend_from_slice(&datagram.data);
self.count += 1;
}
pub fn build(mut self) -> Box<[u8]> {
debug_assert!(self.count <= DATA_FRAME_MAX_DATAGRAM_COUNT);
let nack_count_offset = 5;
self.buffer[nack_count_offset] |= self.count as u8;
let data_bytes = self.buffer.as_slice();
let crc = crc::compute(&data_bytes);
self.buffer.extend_from_slice(&[
(crc >> 24) as u8,
(crc >> 16) as u8,
(crc >> 8) as u8,
(crc ) as u8,
]);
self.buffer.into_boxed_slice()
}
pub fn count(&self) -> usize {
self.count
}
pub fn size(&self) -> usize {
self.buffer.len() + FRAME_CRC_SIZE
}
pub fn encoded_size(datagram: &DatagramRef) -> usize {
let data_len = datagram.data.len();
if datagram.fragment_id_last == 0 {
if data_len < 64 && datagram.window_parent_lead < 128 && datagram.channel_parent_lead < 256 {
return DATAGRAM_HEADER_SIZE_MICRO + data_len;
} else if data_len < 256 {
return DATAGRAM_HEADER_SIZE_SMALL + data_len;
}
}
return DATAGRAM_HEADER_SIZE_LARGE + data_len;
}
}
pub struct AckFrameBuilder {
buffer: Vec<u8>,
count: u16,
}
impl AckFrameBuilder {
pub fn new(frame_window_base_id: u32, packet_window_base_id: u32) -> Self {
let header = vec![
ACK_FRAME_ID,
(frame_window_base_id >> 24) as u8,
(frame_window_base_id >> 16) as u8,
(frame_window_base_id >> 8) as u8,
(frame_window_base_id ) as u8,
(packet_window_base_id >> 24) as u8,
(packet_window_base_id >> 16) as u8,
(packet_window_base_id >> 8) as u8,
(packet_window_base_id ) as u8,
0,
0
];
Self {
buffer: header,
count: 0,
}
}
pub fn add(&mut self, frame_ack: &AckGroup) {
let header = [
(frame_ack.base_id >> 24) as u8,
(frame_ack.base_id >> 16) as u8,
(frame_ack.base_id >> 8) as u8,
(frame_ack.base_id ) as u8,
(frame_ack.bitfield >> 24) as u8,
(frame_ack.bitfield >> 16) as u8,
(frame_ack.bitfield >> 8) as u8,
(frame_ack.bitfield ) as u8,
frame_ack.nonce as u8,
];
self.buffer.extend_from_slice(&header);
self.count += 1;
}
pub fn build(mut self) -> Box<[u8]> {
let count_offset_0 = 9;
let count_offset_1 = 10;
self.buffer[count_offset_0] = (self.count >> 8) as u8;
self.buffer[count_offset_1] = (self.count ) as u8;
let data_bytes = self.buffer.as_slice();
let crc = crc::compute(&data_bytes);
self.buffer.extend_from_slice(&[
(crc >> 24) as u8,
(crc >> 16) as u8,
(crc >> 8) as u8,
(crc ) as u8,
]);
self.buffer.into_boxed_slice()
}
pub fn size(&self) -> usize {
self.buffer.len() + FRAME_CRC_SIZE
}
pub fn encoded_size(_frame_ack: &AckGroup) -> usize {
ACK_GROUP_SIZE
}
}