1use std::io::{Error, Result};
2
3use bytes::BytesMut;
4use tokio_util::codec::Encoder;
5
6use crate::codec::{RtuClientCodec, RtuServerCodec, TcpClientCodec};
7use crate::frame::request::*;
8use crate::frame::response::*;
9use crate::frame::response::Response;
10
11use super::TcpServerCodec;
12
13impl Encoder<Request> for RtuClientCodec {
14 type Error = Error;
15
16 fn encode(
17 &mut self,
18 item: Request,
19 dst: &mut BytesMut,
20 ) -> std::result::Result<(), Self::Error> {
21 request_to_bytesmut(item, dst);
22 Ok(())
23 }
24}
25
26impl Encoder<Response> for RtuServerCodec {
27 type Error = Error;
28
29 fn encode(
30 &mut self,
31 item: Response,
32 dst: &mut BytesMut,
33 ) -> std::result::Result<(), Self::Error> {
34 response_to_bytesmut(item, dst);
35 Ok(())
36 }
37}
38
39impl Encoder<Request> for TcpClientCodec {
40 type Error = Error;
41
42 fn encode(&mut self, item: Request, dst: &mut BytesMut) -> Result<()> {
43 request_to_bytesmut(item, dst);
44 Ok(())
45 }
46}
47
48impl Encoder<Response> for TcpServerCodec {
49 type Error = Error;
50
51 fn encode(&mut self, item: Response, dst: &mut BytesMut) -> Result<()> {
52 response_to_bytesmut(item, dst);
53 Ok(())
54 }
55}
56
57#[cfg(test)]
58mod rtu_client_encoder_test {
59 use bytes::BytesMut;
60 use tokio_util::codec::Encoder;
61
62 use crate::codec::RtuClientCodec;
63 use crate::frame::Frame;
64
65 #[test]
66 fn read_coils_request_test() {
67 let mut codec = RtuClientCodec::default();
68 let frame = Frame::rtu();
69 let request = frame.read_coils_request(0x0B, 0x001D, 0x001F);
70 let mut dst = BytesMut::new();
71 let res = codec.encode(request, &mut dst);
72 assert!(res.is_ok());
73 let vec_l = dst.to_vec();
74 let vec_r = vec![0x0B, 0x01, 0x00, 0x1D, 0x00, 0x1F, 0xED, 0x6E];
75 assert_eq!(vec_l, vec_r);
76 }
77
78 #[test]
79 fn read_discrete_inputs_request_test() {
80 let mut codec = RtuClientCodec::default();
81 let frame = Frame::rtu();
82 let request = frame.read_discrete_request(0x0B, 0x007A, 0x001C);
83 let mut dst = BytesMut::new();
84 let res = codec.encode(request, &mut dst);
85 assert!(res.is_ok());
86 let vec_l = dst.to_vec();
87 let vec_r = vec![0x0B, 0x02, 0x00, 0x7A, 0x00, 0x1C, 0x58, 0xB0];
88 assert_eq!(vec_l, vec_r);
89 }
90
91 #[test]
92 fn read_multiple_holding_registers_request_test() {
93 let mut codec = RtuClientCodec::default();
94 let frame = Frame::rtu();
95 let request = frame.read_multiple_holding_registers_request(0x0B, 0x006F, 0x0003);
96 let mut dst = BytesMut::new();
97 let res = codec.encode(request, &mut dst);
98 assert!(res.is_ok());
99 let vec_l = dst.to_vec();
100 let vec_r = vec![0x0B, 0x03, 0x00, 0x6F, 0x00, 0x03, 0x35, 0x7C];
101 assert_eq!(vec_l, vec_r);
102 }
103
104 #[test]
105 fn read_input_registers_request_test() {
106 let mut codec = RtuClientCodec::default();
107 let frame = Frame::rtu();
108 let request = frame.read_input_registers_request(0x0B, 0x000A, 0x0001);
109 let mut dst = BytesMut::new();
110 let res = codec.encode(request, &mut dst);
111 assert!(res.is_ok());
112 let vec_l = dst.to_vec();
113 let vec_r = vec![0x0B, 0x04, 0x00, 0x0A, 0x00, 0x01, 0x11, 0x62];
114 assert_eq!(vec_l, vec_r);
115 }
116
117 #[test]
118 fn write_single_coil_request_test() {
119 let mut codec = RtuClientCodec::default();
120 let frame = Frame::rtu();
121 let request = frame.write_single_coil_request(0x0B, 0x00BF, 0x0000);
122 let mut dst = BytesMut::new();
123 let res = codec.encode(request, &mut dst);
124 assert!(res.is_ok());
125 let vec_l = dst.to_vec();
126 let vec_r = vec![0x0B, 0x05, 0x00, 0xBF, 0x00, 0x00, 0xFC, 0x84];
127 assert_eq!(vec_l, vec_r);
128 }
129
130 #[test]
131 fn write_single_holding_register_request_test() {
132 let mut codec = RtuClientCodec::default();
133 let frame = Frame::rtu();
134 let request = frame.write_single_holding_register_request(0x0B, 0x0004, 0xABCD);
135 let mut dst = BytesMut::new();
136 let res = codec.encode(request, &mut dst);
137 assert!(res.is_ok());
138 let vec_l = dst.to_vec();
139 let vec_r = vec![0x0B, 0x06, 0x00, 0x04, 0xAB, 0xCD, 0x76, 0x04];
140 assert_eq!(vec_l, vec_r);
141 }
142
143 #[test]
144 fn write_multiple_coils_request_test() {
145 let mut codec = RtuClientCodec::default();
146 let frame = Frame::rtu();
147 let request = frame.write_multiple_coils_request(0x0B, 0x001B, 0x0009, vec![0x4D, 0x01]);
148 let mut dst = BytesMut::new();
149 let res = codec.encode(request, &mut dst);
150 assert!(res.is_ok());
151 let vec_l = dst.to_vec();
152 let vec_r = vec![
153 0x0B, 0x0F, 0x00, 0x1B, 0x00, 0x09, 0x02, 0x4D, 0x01, 0x6C, 0xA7,
154 ];
155 assert_eq!(vec_l, vec_r);
156 }
157
158 #[test]
159 fn write_multiple_holding_registers_request_test() {
160 let mut codec = RtuClientCodec::default();
161 let frame = Frame::rtu();
162 let request = frame.write_multiple_holding_registers_request(
163 0x0B,
164 0x0012,
165 vec![0x0B, 0x0A, 0xC1, 0x02],
166 );
167 let mut dst = BytesMut::new();
168 let res = codec.encode(request, &mut dst);
169 assert!(res.is_ok());
170 let vec_l = dst.to_vec();
171 let vec_r = vec![
172 0x0B, 0x10, 0x00, 0x12, 0x00, 0x02, 0x04, 0x0B, 0x0A, 0xC1, 0x02, 0xA0, 0xD5,
173 ];
174 assert_eq!(vec_l, vec_r);
175 }
176}
177
178#[cfg(test)]
179mod tcp_client_decoder_test {
180 use bytes::BytesMut;
181 use tokio_util::codec::Encoder;
182
183 use crate::codec::TcpClientCodec;
184 use crate::frame::Frame;
185
186 #[test]
187 fn read_coils_request_test() {
188 let mut codec = TcpClientCodec::default();
189 let frame = Frame::tcp();
190 let request = frame.read_coils_request(0x01, 0x02, 0x08);
191 let mut dst = BytesMut::new();
192 let res = codec.encode(request, &mut dst);
193 assert!(res.is_ok());
194 let vec_l = dst.to_vec();
195 let vec_r = vec![
196 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x01, 0x00, 0x02, 0x00, 0x08,
197 ];
198 assert_eq!(vec_l, vec_r);
199 }
200
201 #[test]
202 fn read_discrete_inputs_request_test() {
203 let mut codec = TcpClientCodec::default();
204 let frame = Frame::tcp();
205 let request = frame.read_discrete_request(0x01, 0x0000, 0x0012);
206 let mut dst = BytesMut::new();
207 let res = codec.encode(request, &mut dst);
208 assert!(res.is_ok());
209 let vec_l = dst.to_vec();
210 let vec_r = vec![
211 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x02, 0x00, 0x00, 0x00, 0x12,
212 ];
213 assert_eq!(vec_l, vec_r);
214 }
215
216 #[test]
217 fn read_multiple_holding_registers_request_test() {
218 let mut codec = TcpClientCodec::default();
219 let frame = Frame::tcp();
220 let request = frame.read_multiple_holding_registers_request(0x01, 0x0000, 0x0003);
221 let mut dst = BytesMut::new();
222 let res = codec.encode(request, &mut dst);
223 assert!(res.is_ok());
224 let vec_l = dst.to_vec();
225 let vec_r = vec![
226 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x03, 0x00, 0x00, 0x00, 0x03,
227 ];
228 assert_eq!(vec_l, vec_r);
229 }
230
231 #[test]
232 fn read_input_registers_request_test() {
233 let mut codec = TcpClientCodec::default();
234 let frame = Frame::tcp();
235 let request = frame.read_input_registers_request(0x01, 0x0002, 0x0005);
236 let mut dst = BytesMut::new();
237 let res = codec.encode(request, &mut dst);
238 assert!(res.is_ok());
239 let vec_l = dst.to_vec();
240 let vec_r = vec![
241 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x04, 0x00, 0x02, 0x00, 0x05,
242 ];
243 assert_eq!(vec_l, vec_r);
244 }
245
246 #[test]
247 fn write_single_coil_request_test() {
248 let mut codec = TcpClientCodec::default();
249 let frame = Frame::tcp();
250 let request = frame.write_single_coil_request(0x01, 0x0003, 0xFF00);
251 let mut dst = BytesMut::new();
252 let res = codec.encode(request, &mut dst);
253 assert!(res.is_ok());
254 let vec_l = dst.to_vec();
255 let vec_r = vec![
256 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x05, 0x00, 0x03, 0xFF, 0x00,
257 ];
258 assert_eq!(vec_l, vec_r);
259 }
260
261 #[test]
262 fn write_single_holding_register_request_test() {
263 let mut codec = TcpClientCodec::default();
264 let frame = Frame::tcp();
265 let request = frame.write_single_holding_register_request(0x01, 0x0000, 0x000A);
266 let mut dst = BytesMut::new();
267 let res = codec.encode(request, &mut dst);
268 assert!(res.is_ok());
269 let vec_l = dst.to_vec();
270 let vec_r = vec![
271 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x06, 0x00, 0x00, 0x00, 0x0A,
272 ];
273 assert_eq!(vec_l, vec_r);
274 }
275
276 #[test]
277 fn write_multiple_coils_request_test() {
278 let mut codec = TcpClientCodec::default();
279 let frame = Frame::tcp();
280 let request = frame.write_multiple_coils_request(0x01, 0x001B, 0x0009, vec![0x4D, 0x01]);
281 let mut dst = BytesMut::new();
282 let res = codec.encode(request, &mut dst);
283 assert!(res.is_ok());
284 let vec_l = dst.to_vec();
285 let vec_r = vec![
286 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x01, 0x0F, 0x00, 0x1B, 0x00, 0x09, 0x02, 0x4D,
287 0x01,
288 ];
289 assert_eq!(vec_l, vec_r);
290 }
291
292 #[test]
293 fn write_multiple_holding_registers_request_test() {
294 let mut codec = TcpClientCodec::default();
295 let frame = Frame::tcp();
296 let request =
297 frame.write_multiple_holding_registers_request(0x01, 0x0000, vec![0x00, 0x0F]);
298 let mut dst = BytesMut::new();
299 let res = codec.encode(request, &mut dst);
300 assert!(res.is_ok());
301 let vec_l = dst.to_vec();
302 let vec_r = vec![
303 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x01, 0x10, 0x00, 0x00, 0x00, 0x01, 0x02, 0x00,
304 0x0F,
305 ];
306 assert_eq!(vec_l, vec_r);
307 }
308}
309
310#[cfg(test)]
311mod tcp_server_decoder_test {
312 use bytes::BytesMut;
313 use tokio_util::codec::Encoder;
314
315 use crate::{codec::TcpServerCodec, Frame};
316 use crate::frame::{Exception, Function};
317
318 #[test]
319 fn read_coils_response_test() {
320 let mut codec = TcpServerCodec::default();
321 let frame = Frame::tcp();
322 let response = frame.read_coils_response(0x01, vec![0x00, 0x01]);
323 let mut dst = BytesMut::new();
324 let res = codec.encode(response, &mut dst);
325 assert!(res.is_ok());
326 let vec_l = dst.to_vec();
327 let vec_r = vec![
328 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x01, 0x01, 0x02, 0x00, 0x01,
329 ];
330 assert_eq!(vec_l, vec_r);
331 }
332
333 #[test]
334 fn read_discrete_response_test() {
335 let mut codec = TcpServerCodec::default();
336 let frame = Frame::tcp();
337 let response = frame.read_discrete_response(0x01, vec![0x01, 0x04, 0x00]);
338 let mut dst = BytesMut::new();
339 let res = codec.encode(response, &mut dst);
340 assert!(res.is_ok());
341 let vec_l = dst.to_vec();
342 let vec_r = vec![
343 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x02, 0x03, 0x01, 0x04, 0x00,
344 ];
345 assert_eq!(vec_l, vec_r);
346 }
347
348 #[test]
349 fn read_holding_register_response_test() {
350 let mut codec = TcpServerCodec::default();
351 let frame = Frame::tcp();
352 let response =
353 frame.read_holding_register_response(0x01, vec![0x00, 0x21, 0x00, 0x00, 0x00, 0x00]);
354 let mut dst = BytesMut::new();
355 let res = codec.encode(response, &mut dst);
356 assert!(res.is_ok());
357 let vec_l = dst.to_vec();
358 let vec_r = vec![
359 0x00, 0x01, 0x00, 0x00, 0x00, 0x09, 0x01, 0x03, 0x06, 0x00, 0x21, 0x00, 0x00, 0x00,
360 0x00,
361 ];
362 assert_eq!(vec_l, vec_r);
363 }
364
365 #[test]
366 fn read_input_register_response_test() {
367 let mut codec = TcpServerCodec::default();
368 let frame = Frame::tcp();
369 let response = frame.read_input_register_response(
370 0x01,
371 vec![0x00, 0x0C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
372 );
373 let mut dst = BytesMut::new();
374 let res = codec.encode(response, &mut dst);
375 assert!(res.is_ok());
376 let vec_l = dst.to_vec();
377 let vec_r = vec![
378 0x00, 0x01, 0x00, 0x00, 0x00, 0x0D, 0x01, 0x04, 0x0A, 0x00, 0x0C, 0x00, 0x00, 0x00,
379 0x00, 0x00, 0x00, 0x00, 0x00,
380 ];
381 assert_eq!(vec_l, vec_r);
382 }
383
384 #[test]
385 fn write_single_coil_response_test() {
386 let mut codec = TcpServerCodec::default();
387 let frame = Frame::tcp();
388 let response = frame.write_single_coil_response(0x01, 0x0003, 0xFF00);
389 let mut dst = BytesMut::new();
390 let res = codec.encode(response, &mut dst);
391 assert!(res.is_ok());
392 let vec_l = dst.to_vec();
393 let vec_r = vec![
394 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x05, 0x00, 0x03, 0xFF, 0x00,
395 ];
396 assert_eq!(vec_l, vec_r);
397 }
398
399 #[test]
400 fn write_single_holding_register_response_test() {
401 let mut codec = TcpServerCodec::default();
402 let frame = Frame::tcp();
403 let response = frame.write_single_holding_register_response(0x01, 0x0000, 0x000A);
404 let mut dst = BytesMut::new();
405 let res = codec.encode(response, &mut dst);
406 assert!(res.is_ok());
407 let vec_l = dst.to_vec();
408 let vec_r = vec![
409 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x06, 0x00, 0x00, 0x00, 0x0A,
410 ];
411 assert_eq!(vec_l, vec_r);
412 }
413
414 #[test]
415 fn write_multiple_coils_response_test() {
416 let mut codec = TcpServerCodec::default();
417 let frame = Frame::tcp();
418 let response = frame.write_multiple_coils_response(0x01, 0x001B, 0x0009);
419 let mut dst = BytesMut::new();
420 let res = codec.encode(response, &mut dst);
421 assert!(res.is_ok());
422 let vec_l = dst.to_vec();
423 let vec_r = vec![
424 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x0F, 0x00, 0x1B, 0x00, 0x09,
425 ];
426 assert_eq!(vec_l, vec_r);
427 }
428
429 #[test]
430 fn write_multiple_holding_registers_response_test() {
431 let mut codec = TcpServerCodec::default();
432 let frame = Frame::tcp();
433 let response = frame.write_multiple_holding_registers_response(0x01, 0x0000, 0x0001);
434 let mut dst = BytesMut::new();
435 let res = codec.encode(response, &mut dst);
436 assert!(res.is_ok());
437 let vec_l = dst.to_vec();
438 let vec_r = vec![
439 0x00, 0x01, 0x00, 0x00, 0x00, 0x06, 0x01, 0x10, 0x00, 0x00, 0x00, 0x01,
440 ];
441 assert_eq!(vec_l, vec_r);
442 }
443
444 #[test]
445 fn exception_response_test() {
446 let mut codec = TcpServerCodec::default();
447 let frame = Frame::tcp();
448 let response =
449 frame.exception_response(0x0A, Function::ReadCoils, Exception::IllegalDataAddress);
450 let mut dst = BytesMut::new();
451 let res = codec.encode(response, &mut dst);
452 assert!(res.is_ok());
453 let vec_l = dst.to_vec();
454 let vec_r = vec![0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x0A, 0x81, 0x02];
455 assert_eq!(vec_l, vec_r);
456 }
457}
458
459#[cfg(test)]
460mod rtu_server_decoder_test {
461 use bytes::BytesMut;
462 use tokio_util::codec::Encoder;
463
464 use crate::{codec::RtuServerCodec, Frame};
465 use crate::frame::{Exception, Function};
466
467 #[test]
468 fn read_coils_response_test() {
469 let mut codec = RtuServerCodec::default();
470 let frame = Frame::rtu();
471 let response = frame.read_coils_response(0x0B, vec![0xCD, 0x6B, 0xB2, 0x7F]);
472 let mut dst = BytesMut::new();
473 let res = codec.encode(response, &mut dst);
474 assert!(res.is_ok());
475 let vec_l = dst.to_vec();
476 let vec_r = vec![0x0B, 0x01, 0x04, 0xCD, 0x6B, 0xB2, 0x7F, 0x2B, 0xE1];
477 assert_eq!(vec_l, vec_r);
478 }
479
480 #[test]
481 fn read_discrete_response_test() {
482 let mut codec = RtuServerCodec::default();
483 let frame = Frame::rtu();
484 let response = frame.read_discrete_response(0x0B, vec![0xAC, 0xDB, 0xFB, 0x0D]);
485 let mut dst = BytesMut::new();
486 let res = codec.encode(response, &mut dst);
487 assert!(res.is_ok());
488 let vec_l = dst.to_vec();
489 let vec_r = vec![0x0B, 0x02, 0x04, 0xAC, 0xDB, 0xFB, 0x0D, 0x82, 0x7C];
490 assert_eq!(vec_l, vec_r);
491 }
492
493 #[test]
494 fn read_holding_register_response_test() {
495 let mut codec = RtuServerCodec::default();
496 let frame = Frame::rtu();
497 let response =
498 frame.read_holding_register_response(0x0B, vec![0xAE, 0x41, 0x56, 0x52, 0x43, 0x40]);
499 let mut dst = BytesMut::new();
500 let res = codec.encode(response, &mut dst);
501 assert!(res.is_ok());
502 let vec_l = dst.to_vec();
503 let vec_r = vec![
504 0x0B, 0x03, 0x06, 0xAE, 0x41, 0x56, 0x52, 0x43, 0x40, 0xFA, 0xCD,
505 ];
506 assert_eq!(vec_l, vec_r);
507 }
508
509 #[test]
510 fn read_input_register_response_test() {
511 let mut codec = RtuServerCodec::default();
512 let frame = Frame::rtu();
513 let response = frame.read_input_register_response(0x0B, vec![0x10, 0x2F]);
514 let mut dst = BytesMut::new();
515 let res = codec.encode(response, &mut dst);
516 assert!(res.is_ok());
517 let vec_l = dst.to_vec();
518 let vec_r = vec![0x0B, 0x04, 0x02, 0x10, 0x2F, 0x6D, 0x2D];
519 assert_eq!(vec_l, vec_r);
520 }
521
522 #[test]
523 fn write_single_coil_response_test() {
524 let mut codec = RtuServerCodec::default();
525 let frame = Frame::rtu();
526 let response = frame.write_single_coil_response(0x0B, 0x00BF, 0x0000);
527 let mut dst = BytesMut::new();
528 let res = codec.encode(response, &mut dst);
529 assert!(res.is_ok());
530 let vec_l = dst.to_vec();
531 let vec_r = vec![0x0B, 0x05, 0x00, 0xBF, 0x00, 0x00, 0xFC, 0x84];
532 assert_eq!(vec_l, vec_r);
533 }
534
535 #[test]
536 fn write_single_holding_register_response_test() {
537 let mut codec = RtuServerCodec::default();
538 let frame = Frame::rtu();
539 let response = frame.write_single_holding_register_response(0x0B, 0x0004, 0xABCD);
540 let mut dst = BytesMut::new();
541 let res = codec.encode(response, &mut dst);
542 assert!(res.is_ok());
543 let vec_l = dst.to_vec();
544 let vec_r = vec![0x0B, 0x006, 0x000, 0x004, 0x0AB, 0x0CD, 0x076, 0x004];
545 assert_eq!(vec_l, vec_r);
546 }
547
548 #[test]
549 fn write_multiple_coils_response_test() {
550 let mut codec = RtuServerCodec::default();
551 let frame = Frame::rtu();
552 let response = frame.write_multiple_coils_response(0x0B, 0x001B, 0x0009);
553 let mut dst = BytesMut::new();
554 let res = codec.encode(response, &mut dst);
555 assert!(res.is_ok());
556 let vec_l = dst.to_vec();
557 let vec_r = vec![0x0B, 0x0F, 0x00, 0x1B, 0x00, 0x09, 0xE5, 0x60];
558 assert_eq!(vec_l, vec_r);
559 }
560
561 #[test]
562 fn write_multiple_holding_registers_response_test() {
563 let mut codec = RtuServerCodec::default();
564 let frame = Frame::rtu();
565 let response = frame.write_multiple_holding_registers_response(0x0B, 0x0012, 0x0002);
566 let mut dst = BytesMut::new();
567 let res = codec.encode(response, &mut dst);
568 assert!(res.is_ok());
569 let vec_l = dst.to_vec();
570 let vec_r = vec![0x0B, 0x10, 0x00, 0x12, 0x00, 0x02, 0xE1, 0x67];
571 assert_eq!(vec_l, vec_r);
572 }
573
574 #[test]
575 fn exception_response_test() {
576 let mut codec = RtuServerCodec::default();
577 let frame = Frame::rtu();
578 let response =
579 frame.exception_response(0x0A, Function::ReadCoils, Exception::IllegalDataAddress);
580 let mut dst = BytesMut::new();
581 let res = codec.encode(response, &mut dst);
582 assert!(res.is_ok());
583 let vec_l = dst.to_vec();
584 let vec_r = vec![0x0A, 0x81, 0x02, 0xB0, 0x53];
585 assert_eq!(vec_l, vec_r);
586 }
587}