dnp3/
decode.rs

1/// Controls the decoding of transmitted and received data at the application, transport, and link layer
2#[derive(Copy, Clone, Debug, PartialEq, Eq)]
3#[cfg_attr(
4    feature = "serialization",
5    derive(serde::Serialize, serde::Deserialize)
6)]
7pub struct DecodeLevel {
8    /// Controls application layer decoding
9    #[cfg_attr(feature = "serialization", serde(default))]
10    pub application: AppDecodeLevel,
11    /// Controls transport layer decoding
12    #[cfg_attr(feature = "serialization", serde(default))]
13    pub transport: TransportDecodeLevel,
14    /// Controls link layer decoding
15    #[cfg_attr(feature = "serialization", serde(default))]
16    pub link: LinkDecodeLevel,
17    /// Controls the logging of physical layer read/write
18    #[cfg_attr(feature = "serialization", serde(default))]
19    pub physical: PhysDecodeLevel,
20}
21
22/// Controls how transmitted and received application-layer fragments are decoded at the INFO log level
23#[derive(Copy, Clone, Debug, PartialEq, Eq)]
24#[cfg_attr(
25    feature = "serialization",
26    derive(serde::Serialize, serde::Deserialize)
27)]
28pub enum AppDecodeLevel {
29    /// Decode nothing
30    Nothing,
31    /// Decode the header-only
32    Header,
33    /// Decode the header and the object headers
34    ObjectHeaders,
35    /// Decode the header, the object headers, and the object values
36    ObjectValues,
37}
38
39impl Default for AppDecodeLevel {
40    fn default() -> Self {
41        Self::Nothing
42    }
43}
44
45/// Controls how transmitted and received transport segments are decoded at the INFO log level
46#[derive(Copy, Clone, Debug, PartialEq, Eq)]
47#[cfg_attr(
48    feature = "serialization",
49    derive(serde::Serialize, serde::Deserialize)
50)]
51pub enum TransportDecodeLevel {
52    /// Decode nothing
53    Nothing,
54    /// Decode the header
55    Header,
56    /// Decode the header and the raw payload as hexadecimal
57    Payload,
58}
59
60impl Default for TransportDecodeLevel {
61    fn default() -> Self {
62        Self::Nothing
63    }
64}
65
66/// Controls how transmitted and received link frames are decoded at the INFO log level
67#[derive(Copy, Clone, Debug, PartialEq, Eq)]
68#[cfg_attr(
69    feature = "serialization",
70    derive(serde::Serialize, serde::Deserialize)
71)]
72pub enum LinkDecodeLevel {
73    /// Decode nothing
74    Nothing,
75    /// Decode the header
76    Header,
77    /// Decode the header and the raw payload as hexadecimal
78    Payload,
79}
80
81impl Default for LinkDecodeLevel {
82    fn default() -> Self {
83        Self::Nothing
84    }
85}
86
87/// Controls how data transmitted at the physical layer (TCP, serial, etc) is logged
88#[derive(Copy, Clone, Debug, PartialEq, Eq)]
89#[cfg_attr(
90    feature = "serialization",
91    derive(serde::Serialize, serde::Deserialize)
92)]
93pub enum PhysDecodeLevel {
94    /// Log nothing
95    Nothing,
96    /// Log only the length of data that is sent and received
97    Length,
98    /// Log the length and the actual data that is sent and received
99    Data,
100}
101
102impl Default for PhysDecodeLevel {
103    fn default() -> Self {
104        Self::Nothing
105    }
106}
107
108impl DecodeLevel {
109    /// construct a `DecodeLevel` with nothing enabled
110    pub fn nothing() -> Self {
111        Self::default()
112    }
113
114    /// construct a `DecodeLevel` from its fields
115    pub fn new(
116        application: AppDecodeLevel,
117        transport: TransportDecodeLevel,
118        link: LinkDecodeLevel,
119        physical: PhysDecodeLevel,
120    ) -> Self {
121        DecodeLevel {
122            application,
123            transport,
124            link,
125            physical,
126        }
127    }
128}
129
130impl Default for DecodeLevel {
131    fn default() -> Self {
132        Self {
133            application: AppDecodeLevel::Nothing,
134            transport: TransportDecodeLevel::Nothing,
135            link: LinkDecodeLevel::Nothing,
136            physical: PhysDecodeLevel::Nothing,
137        }
138    }
139}
140
141impl From<AppDecodeLevel> for DecodeLevel {
142    fn from(application: AppDecodeLevel) -> Self {
143        Self {
144            application,
145            transport: TransportDecodeLevel::Nothing,
146            link: LinkDecodeLevel::Nothing,
147            physical: PhysDecodeLevel::Nothing,
148        }
149    }
150}
151
152impl AppDecodeLevel {
153    pub(crate) fn enabled(&self) -> bool {
154        self.header()
155    }
156
157    pub(crate) fn header(&self) -> bool {
158        match self {
159            AppDecodeLevel::Nothing => false,
160            AppDecodeLevel::Header => true,
161            AppDecodeLevel::ObjectHeaders => true,
162            AppDecodeLevel::ObjectValues => true,
163        }
164    }
165
166    pub(crate) fn object_headers(&self) -> bool {
167        match self {
168            AppDecodeLevel::Nothing => false,
169            AppDecodeLevel::Header => false,
170            AppDecodeLevel::ObjectHeaders => true,
171            AppDecodeLevel::ObjectValues => true,
172        }
173    }
174
175    pub(crate) fn object_values(&self) -> bool {
176        match self {
177            AppDecodeLevel::Nothing => false,
178            AppDecodeLevel::Header => false,
179            AppDecodeLevel::ObjectHeaders => false,
180            AppDecodeLevel::ObjectValues => true,
181        }
182    }
183}
184
185impl TransportDecodeLevel {
186    pub(crate) fn enabled(&self) -> bool {
187        self.header_enabled()
188    }
189
190    pub(crate) fn header_enabled(&self) -> bool {
191        match self {
192            TransportDecodeLevel::Nothing => false,
193            TransportDecodeLevel::Header => true,
194            TransportDecodeLevel::Payload => true,
195        }
196    }
197
198    pub(crate) fn payload_enabled(&self) -> bool {
199        match self {
200            TransportDecodeLevel::Nothing => false,
201            TransportDecodeLevel::Header => false,
202            TransportDecodeLevel::Payload => true,
203        }
204    }
205}
206
207impl LinkDecodeLevel {
208    pub(crate) fn enabled(&self) -> bool {
209        self.header_enabled()
210    }
211
212    pub(crate) fn header_enabled(&self) -> bool {
213        match self {
214            LinkDecodeLevel::Nothing => false,
215            LinkDecodeLevel::Header => true,
216            LinkDecodeLevel::Payload => true,
217        }
218    }
219
220    pub(crate) fn payload_enabled(&self) -> bool {
221        match self {
222            LinkDecodeLevel::Nothing => false,
223            LinkDecodeLevel::Header => false,
224            LinkDecodeLevel::Payload => true,
225        }
226    }
227}
228
229impl PhysDecodeLevel {
230    pub(crate) fn enabled(&self) -> bool {
231        self.length_enabled()
232    }
233
234    pub(crate) fn length_enabled(&self) -> bool {
235        match self {
236            PhysDecodeLevel::Nothing => false,
237            PhysDecodeLevel::Length => true,
238            PhysDecodeLevel::Data => true,
239        }
240    }
241
242    pub(crate) fn data_enabled(&self) -> bool {
243        match self {
244            PhysDecodeLevel::Nothing => false,
245            PhysDecodeLevel::Length => false,
246            PhysDecodeLevel::Data => true,
247        }
248    }
249}