use crate::{
frame::{carrier::modes, generate::pad_aux_data, parse, FrameGenerator, FrameParser},
types::{Address, Ident32, Recipient, SequenceIdV1},
EncodingError, Result,
};
use chrono::{DateTime, Utc};
use nom::IResult;
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash)]
pub enum CarrierFrameHeader {
V1(CarrierFrameHeaderV1),
}
impl CarrierFrameHeader {
pub fn new_anycast_probe_frame(sender: Address, recipient: Recipient) -> Self {
Self::V1(CarrierFrameHeaderV1 {
modes: modes::NAMESPACE_ANYCAST,
sender,
recipient: Some(recipient),
seq_id: None,
auxiliary_data: None,
signature_data: None,
payload_length: 0,
})
}
pub fn new_anycast_reply_frame(
sender: Address,
recipient: Recipient,
timestamp: DateTime<Utc>,
) -> Result<Self> {
let mut timestamp_data = vec![];
timestamp.generate(&mut timestamp_data)?;
Ok(Self::V1(CarrierFrameHeaderV1 {
modes: modes::NAMESPACE_ANYCAST,
sender,
recipient: Some(recipient),
seq_id: None,
auxiliary_data: Some(pad_aux_data(timestamp_data)),
signature_data: None,
payload_length: 0,
}))
}
pub fn new_netmodproto_frame(modes: u16, router_addr: Address, payload_length: u16) -> Self {
Self::V1(CarrierFrameHeaderV1 {
modes,
sender: router_addr,
recipient: None,
seq_id: None,
auxiliary_data: None,
signature_data: None,
payload_length,
})
}
pub fn new_blockdata_frame(
sender: Address,
recipient: Recipient,
seq_id: SequenceIdV1,
payload_length: u16,
) -> Self {
Self::V1(CarrierFrameHeaderV1 {
modes: modes::DATA,
sender,
recipient: Some(recipient),
seq_id: Some(seq_id),
auxiliary_data: None,
signature_data: None,
payload_length,
})
}
pub fn new_blockmanifest_frame(
sender: Address,
recipient: Recipient,
seq_id: SequenceIdV1,
payload_length: u16,
) -> Self {
Self::V1(CarrierFrameHeaderV1 {
modes: modes::MANIFEST,
sender,
recipient: Some(recipient),
seq_id: Some(seq_id),
auxiliary_data: None,
signature_data: None,
payload_length,
})
}
pub fn new_announce_frame(sender: Address, payload_length: u16) -> Self {
Self::V1(CarrierFrameHeaderV1 {
modes: modes::ANNOUNCE,
sender,
recipient: None,
seq_id: Some(SequenceIdV1 {
hash: Ident32::random(),
num: 0,
max: 0,
}),
auxiliary_data: None,
signature_data: None,
payload_length,
})
}
pub fn get_blockdata_size(sender: Address, recipient: Recipient) -> usize {
CarrierFrameHeader::new_blockdata_frame(
sender,
recipient,
SequenceIdV1 {
hash: Ident32::random(),
num: 0,
max: 0,
},
0,
)
.get_size()
}
pub fn get_size(&self) -> usize {
match self {
Self::V1(header) => {
let modes_size = core::mem::size_of_val(&header.modes);
let payload_len_size = core::mem::size_of_val(&header.payload_length);
let sender_size = core::mem::size_of_val(&header.sender);
let recipient_size = match header.recipient {
Some(ref r) => core::mem::size_of_val(r),
None => 1,
};
let seq_id_size = match header.seq_id {
Some(ref seq_id) => 1 + core::mem::size_of_val(seq_id),
None => 1,
};
let aux_data_size = match header.auxiliary_data {
Some(_) => 64,
None => 1,
};
let sign_data_size = match header.auxiliary_data {
Some(_) => 64,
None => 1,
};
1 + modes_size
+ sender_size
+ recipient_size
+ seq_id_size
+ aux_data_size
+ sign_data_size
+ payload_len_size
}
}
}
pub fn get_modes(&self) -> u16 {
match self {
Self::V1(inner) => inner.modes,
}
}
pub fn get_sender(&self) -> Address {
match self {
Self::V1(inner) => inner.sender,
}
}
pub fn get_recipient(&self) -> Option<Recipient> {
match self {
Self::V1(inner) => inner.recipient,
}
}
pub fn get_seq_id(&self) -> Option<SequenceIdV1> {
match self {
Self::V1(inner) => inner.seq_id,
}
}
pub fn get_payload_length(&self) -> usize {
match self {
Self::V1(inner) => inner.payload_length as usize,
}
}
pub fn get_auxiliary_data(&self) -> Option<[u8; 64]> {
match self {
Self::V1(inner) => inner.auxiliary_data,
}
}
}
impl FrameParser for CarrierFrameHeader {
type Output = Result<Self>;
fn parse(input: &[u8]) -> IResult<&[u8], Self::Output> {
let (input, version) = parse::take(1 as usize)(input)?;
match version[0] {
1 => {
let (input, modes) = parse::take_u16(input)?;
let (input, sender) = parse::take_address(input)?;
let (input, recipient) = Option::<Recipient>::parse(input)?;
let (input, seq_id) = SequenceIdV1::parse(input)?;
let (input, auxiliary_data) = parse::maybe::<64>(input)?;
let (input, signature_data) = parse::maybe::<64>(input)?;
let (input, payload_length) = parse::take_u16(input)?;
Ok((
input,
Ok(CarrierFrameHeader::V1(CarrierFrameHeaderV1 {
modes,
sender,
recipient,
seq_id,
auxiliary_data,
signature_data,
payload_length,
})),
))
}
unknown_version => Ok((
input,
Err(EncodingError::InvalidVersion(unknown_version).into()),
)),
}
}
}
impl FrameGenerator for CarrierFrameHeader {
fn generate(self, buf: &mut Vec<u8>) -> Result<()> {
match self {
Self::V1(inner) => {
buf.push(1); inner.modes.generate(buf)?;
inner.sender.generate(buf)?;
inner.recipient.generate(buf)?;
inner.seq_id.generate(buf)?;
inner.auxiliary_data.generate(buf)?;
inner.signature_data.generate(buf)?;
inner.payload_length.generate(buf)?;
}
}
Ok(())
}
}
#[derive(Copy, Clone, Debug, PartialEq, PartialOrd, Eq, Ord, Hash)]
pub struct CarrierFrameHeaderV1 {
modes: u16,
sender: Address,
recipient: Option<Recipient>,
seq_id: Option<SequenceIdV1>,
auxiliary_data: Option<[u8; 64]>,
signature_data: Option<[u8; 64]>,
payload_length: u16,
}
impl CarrierFrameHeaderV1 {
pub fn new(
modes: u16,
sender: Address,
recipient: Option<Recipient>,
seq_id: Option<SequenceIdV1>,
auxiliary_data: Option<[u8; 64]>,
signature_data: Option<[u8; 64]>,
payload_length: u16,
) -> Self {
Self {
modes,
sender,
recipient,
seq_id,
auxiliary_data,
signature_data,
payload_length,
}
}
}
#[repr(C)]
pub enum AuxiliaryData {
Nonce([u8; 12]),
Signature([u8; 64]),
Sent(DateTime<Utc>),
}