pn_dcp/packet/
set_resp.rs1use crate::block::{BlockPadding, BlockResp, BlockTrait};
2use crate::comm::BytesWrap;
3use crate::options::{BlockError, OptionAndSub};
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 PacketSetResp {
13 head: DcpHead,
14 blocks: SetRespBlocks,
15}
16impl Deref for PacketSetResp {
17 type Target = DcpHead;
18
19 fn deref(&self) -> &Self::Target {
20 &self.head
21 }
22}
23#[derive(Default, Debug, Eq, PartialEq, Clone)]
24#[derefmut(0)]
25pub struct SetRespBlocks(pub(crate) Vec<SetRespBlock>);
26
27impl TryFrom<BytesWrap> for SetRespBlocks {
28 type Error = anyhow::Error;
29 fn try_from(value: BytesWrap) -> Result<Self, Self::Error> {
30 let mut index = 0usize;
31 let mut blocks = Vec::<SetRespBlock>::new();
32 while let Ok(tmp) = value.slice(index..) {
33 if tmp.len() == 0 {
34 break;
35 }
36 let option = BlockResp::try_from(tmp.clone())?;
37 let len = option.len();
38 blocks.push(option.into());
39 if len % 2 == 1 {
40 blocks.push(BlockPadding.into());
41 index += 1;
42 }
43 index += len;
44 }
45 Ok(blocks.into())
46 }
47}
48
49impl BlockTrait for SetRespBlocks {
50 fn len(&self) -> usize {
51 let mut len = 0;
52 for block in &self.0 {
53 len += block.len();
54 }
55 len
56 }
57
58 fn payload(&self) -> u16 {
59 unreachable!()
60 }
61
62 fn append_data(&self, data: &mut Vec<u8>) {
63 for block in &self.0 {
64 block.append_data(data)
65 }
66 }
67}
68
69#[derive(Debug, Eq, PartialEq, Clone)]
70pub enum SetRespBlock {
71 Response(BlockResp),
72 Padding(BlockPadding),
73}
74
75impl BlockTrait for SetRespBlock {
76 fn len(&self) -> usize {
77 match self {
78 Self::Response(a) => a.len(),
79 Self::Padding(a) => a.len(),
80 }
81 }
82 fn payload(&self) -> u16 {
83 match self {
84 Self::Response(a) => a.payload(),
85 Self::Padding(a) => a.payload(),
86 }
87 }
88
89 fn append_data(&self, data: &mut Vec<u8>) {
90 match self {
91 Self::Padding(a) => a.append_data(data),
92 Self::Response(a) => a.append_data(data),
93 }
94 }
95}
96
97impl PacketSetResp {
98 pub fn new(source: MacAddr, dest: MacAddr, option: OptionAndSub, error: BlockError) -> Self {
99 let head = DcpHead::new(dest, source, PnDcpTy::SetRespSuc);
100 let blocks = BlockResp(option, error);
101 let mut resp = Self {
102 head,
103 blocks: SetRespBlocks::default(),
104 };
105 resp.append_block(blocks);
106 resp
107 }
108 fn append_block(&mut self, block: impl Into<SetRespBlock>) {
109 let block = block.into();
110 let block_len = block.len();
111 self.blocks.0.push(block);
112 self.head.add_payload_len(block_len);
113 if block_len % 2 == 1 {
114 self.blocks.0.push(SetRespBlock::Padding(BlockPadding));
115 self.head.add_payload_len(1);
116 }
117 }
118
119 pub fn blocks(&self) -> Vec<BlockResp> {
120 let mut blocks = Vec::new();
121 for block in self.blocks.iter() {
122 if let SetRespBlock::Response(common) = block {
123 blocks.push(common.clone());
124 }
125 }
126 blocks
127 }
128
129 pub fn to_vec(&self) -> Vec<u8> {
130 let mut data = Vec::with_capacity(self.head.payload_len + 26);
131 self.head.append_data(&mut data);
132 self.blocks.append_data(&mut data);
133 data
134 }
135}
136
137impl TryFrom<PnDcp> for PacketSetResp {
138 type Error = anyhow::Error;
139
140 fn try_from(dcg: PnDcp) -> Result<Self, Self::Error> {
141 let PnDcp { head, blocks } = dcg;
142 if head.ty != PnDcpTy::SetRespSuc {
143 bail!("the packet is pn-dcp, but not set resp success!");
144 }
145 let blocks = SetRespBlocks::try_from(blocks)?;
146 Ok(Self { blocks, head })
147 }
148}
149
150impl TryFrom<&[u8]> for PacketSetResp {
151 type Error = anyhow::Error;
152
153 fn try_from(value: &[u8]) -> Result<Self, Self::Error> {
154 let dcg = PnDcp::try_from(value)?;
155 PacketSetResp::try_from(dcg)
156 }
157}