pn_dcp/packet/
set_req.rs

1use crate::block::{BlockPadding, BlockSet, BlockTrait};
2use crate::comm::BytesWrap;
3use crate::options::{BlockQualifier, OptionAndSubValue};
4use crate::packet::{DcpHead, PnDcp, PnDcpTy};
5use anyhow::bail;
6use pn_dcp_macro::derefmut;
7use pnet::datalink::MacAddr;
8use std::ops::{Deref, DerefMut};
9
10#[derive(Debug, Eq, PartialEq, Clone)]
11#[derefmut(head)]
12pub struct PacketSetReq {
13    head: DcpHead,
14    blocks: BlockSet,
15}
16impl Deref for PacketSetReq {
17    type Target = DcpHead;
18
19    fn deref(&self) -> &Self::Target {
20        &self.head
21    }
22}
23impl PacketSetReq {
24    pub fn new(
25        source: MacAddr,
26        dest: MacAddr,
27        option: OptionAndSubValue,
28        qualifier: BlockQualifier,
29    ) -> Self {
30        let mut head = DcpHead::new(dest, source, PnDcpTy::SetReq);
31        let blocks = BlockSet { option, qualifier };
32        head.add_payload_len(blocks.len());
33        Self { head, blocks }
34    }
35
36    pub fn blocks(&self) -> BlockSet {
37        self.blocks.clone()
38    }
39
40    pub fn to_vec(&self) -> Vec<u8> {
41        let mut data = Vec::with_capacity(self.head.payload_len + 26);
42        self.head.append_data(&mut data);
43        self.blocks.append_data(&mut data);
44        data
45    }
46}
47
48impl TryFrom<PnDcp> for PacketSetReq {
49    type Error = anyhow::Error;
50
51    fn try_from(dcg: PnDcp) -> Result<Self, Self::Error> {
52        let PnDcp { head, blocks } = dcg;
53        if head.ty != PnDcpTy::SetReq {
54            bail!("the packet is pn-dcp, but not  set req!");
55        }
56        let blocks = BlockSet::try_from(blocks)?;
57        Ok(Self { blocks, head })
58    }
59}
60
61impl TryFrom<&[u8]> for PacketSetReq {
62    type Error = anyhow::Error;
63
64    fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
65        let dcg = PnDcp::try_from(value)?;
66        PacketSetReq::try_from(dcg)
67    }
68}
69
70#[derive(Debug, Eq, PartialEq)]
71pub enum SetReqBlock {
72    Set(BlockSet),
73    Padding(BlockPadding),
74}
75
76impl BlockTrait for SetReqBlock {
77    fn len(&self) -> usize {
78        match self {
79            Self::Set(a) => a.len(),
80            Self::Padding(a) => a.len(),
81        }
82    }
83    fn payload(&self) -> u16 {
84        match self {
85            Self::Set(a) => a.payload(),
86            Self::Padding(a) => a.payload(),
87        }
88    }
89
90    fn append_data(&self, data: &mut Vec<u8>) {
91        match self {
92            Self::Padding(a) => a.append_data(data),
93            Self::Set(a) => a.append_data(data),
94        }
95    }
96}
97
98#[derive(Debug, Eq, PartialEq, Default)]
99#[derefmut(0)]
100pub struct SetReqBlocks(pub(crate) Vec<SetReqBlock>);
101
102impl TryFrom<BytesWrap> for SetReqBlocks {
103    type Error = anyhow::Error;
104    fn try_from(value: BytesWrap) -> Result<Self, Self::Error> {
105        let mut index = 0usize;
106        let mut blocks = Vec::<SetReqBlock>::new();
107        while let Ok(tmp) = value.slice(index..) {
108            if tmp.len() == 0 {
109                break;
110            }
111            let block = BlockSet::try_from(tmp)?;
112            let len = block.len();
113            blocks.push(block.into());
114            if len % 2 == 1 {
115                blocks.push(BlockPadding.into());
116                index += 1;
117            }
118            index += len;
119        }
120        Ok(blocks.into())
121    }
122}