1use crate::builder::*;
2use crate::error::*;
3pub use crate::packet::{ConnectComm, CoptFrame, DtData, Parameter, PduType, TpduSize};
4use bytes::{Buf, BufMut, BytesMut};
5use std::fmt::Debug;
6use tokio_util::codec::{Decoder, Encoder};
7
8pub mod builder;
9pub mod error;
10mod packet;
11
12#[derive(Default)]
13pub struct CoptEncoder<E>(pub E);
14pub struct CoptDecoder<D>(pub D);
15
16impl<F: Debug + Eq + PartialEq, E: Encoder<F>> Encoder<CoptFrame<F>> for CoptEncoder<E>
17where
18 <E as Encoder<F>>::Error: ToCoptError + Send + Sync + 'static,
19{
20 type Error = Error;
21
22 fn encode(
23 &mut self,
24 item: CoptFrame<F>,
25 dst: &mut BytesMut,
26 ) -> std::result::Result<(), Self::Error> {
27 dst.put_u8(item.length());
28 match item.pdu_type {
29 PduType::ConnectRequest(conn) => {
30 dst.put_u8(0xe0);
31 conn.encode(dst);
32 Ok(())
33 }
34 PduType::ConnectConfirm(conn) => {
35 dst.put_u8(0xd0);
36 conn.encode(dst);
37 Ok(())
38 }
39 PduType::DtData(conn) => {
40 dst.put_u8(0xf0);
41 let merge =
42 conn.tpdu_number >> 1 | if conn.last_data_unit { 0b1000_0000 } else { 0 };
43 dst.put_u8(merge);
44 Ok(self.0.encode(conn.payload, dst)?)
45 }
46 }
47 }
48}
49
50impl<F: Debug + Eq + PartialEq, D: Decoder<Item = F>> Decoder for CoptDecoder<D>
51where
52 <D as Decoder>::Error: ToCoptError + Send + Sync + 'static,
53{
54 type Item = CoptFrame<F>;
55 type Error = Error;
56
57 fn decode(
58 &mut self,
59 src: &mut BytesMut,
60 ) -> std::result::Result<Option<Self::Item>, Self::Error> {
61 let (Some(length), Some(pdu_type)) = (src.get(0), src.get(1)) else {
62 return Ok(None)
63 };
64 let length = *length as usize + 1;
65 if src.len() < length || length < 2 {
66 return Ok(None);
67 };
68 match *pdu_type {
69 0xe0 => {
71 let mut src = src.split_to(length).split_off(2);
72 Ok(Some(CoptFrame {
73 pdu_type: PduType::ConnectRequest(ConnectComm::decode(&mut src)?),
74 }))
75 }
76 0xd0 => {
77 let mut src = src.split_to(length).split_off(2);
78 Ok(Some(CoptFrame {
79 pdu_type: PduType::ConnectConfirm(ConnectComm::decode(&mut src)?),
80 }))
81 }
82 0xf0 => {
83 let mut sub_src = src.clone().split_off(length);
84 let pre_length = sub_src.len();
85 let Some(f) = self.0.decode(&mut sub_src)? else {
86 return Err(Error::Error("decode fail".to_string()));
87
88 };
89 let sub_length = pre_length - sub_src.len();
90 let mut src = src.split_to(length + sub_length).split_off(2);
91 let merge = src.get_u8();
92 let tpdu_number = merge & 0b0111_1111;
93 let last_data_unit = merge & 0b1000_0000 > 0;
94 Ok(Some(CoptFrame {
95 pdu_type: PduType::DtData(DtData {
96 tpdu_number,
97 last_data_unit,
98 payload: f,
99 }),
100 }))
101 }
102 _ => {
103 return Err(Error::Error(format!("not support pdu type: {}", pdu_type)));
104 }
105 }
106 }
107}