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}