1use std::fmt;
2use std::fmt::Formatter;
3
4use bytes::{BufMut, BytesMut};
5
6use crate::frame::{Exception, Version};
7use crate::frame::Version::Rtu;
8use crate::util::crc;
9
10use super::{Head, Length};
11
12#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
13pub enum Response {
14 ReadCoils(Head, ReadCoilsResponse),
15 ReadDiscreteInputs(Head, ReadDiscreteInputsResponse),
16 ReadMultipleHoldingRegisters(Head, ReadMultipleHoldingRegistersResponse),
17 ReadInputRegisters(Head, ReadInputRegistersResponse),
18 WriteSingleCoil(Head, WriteSingleCoilResponse),
19 WriteSingleHoldingRegister(Head, WriteSingleHoldingRegisterResponse),
20 WriteMultipleCoils(Head, WriteMultipleCoilsResponse),
21 WriteMultipleHoldingRegisters(Head, WriteMultipleHoldingRegistersResponse),
22 Exception(Head, ExceptionResponse),
23}
24
25impl fmt::Display for Response {
26 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
27 let mut buf = BytesMut::with_capacity(64);
28 response_to_bytesmut(self.clone(), &mut buf);
29 let mut first = true;
30 for byte in buf {
31 if !first {
32 write!(f, " ")?;
33 }
34 write!(f, "{:02X}", byte)?;
35 first = false;
36 }
37 Ok(())
38 }
39}
40
41#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
43pub struct ReadCoilsResponse {
44 pub(crate) bytes_number: u8,
46
47 pub(crate) values: Vec<u8>,
53}
54
55impl Length for ReadCoilsResponse {
56 fn len(&self) -> u16 {
57 1 + self.values.len() as u16
58 }
59}
60
61impl ReadCoilsResponse {
62 pub(crate) fn new(values: Vec<u8>) -> ReadCoilsResponse {
63 let bytes_number = values.len() as u8;
64 ReadCoilsResponse {
65 bytes_number,
66 values,
67 }
68 }
69
70 pub fn get_bytes_number(&self) -> &u8 {
71 &self.bytes_number
72 }
73
74 pub fn get_values(&self) -> &Vec<u8> {
75 &self.values
76 }
77}
78
79#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
81pub struct ReadDiscreteInputsResponse {
82 pub(crate) bytes_number: u8,
84
85 pub(crate) values: Vec<u8>,
92}
93
94impl Length for ReadDiscreteInputsResponse {
95 fn len(&self) -> u16 {
96 1 + self.values.len() as u16
97 }
98}
99
100impl ReadDiscreteInputsResponse {
101 pub(crate) fn new(values: Vec<u8>) -> ReadDiscreteInputsResponse {
102 ReadDiscreteInputsResponse {
103 bytes_number: values.len() as u8,
104 values,
105 }
106 }
107
108 pub fn get_bytes_number(&self) -> &u8 {
109 &self.bytes_number
110 }
111
112 pub fn get_values(&self) -> &Vec<u8> {
113 &self.values
114 }
115}
116
117#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
119pub struct ReadMultipleHoldingRegistersResponse {
120 pub(crate) bytes_number: u8,
122
123 pub(crate) values: Vec<u8>,
125}
126
127impl Length for ReadMultipleHoldingRegistersResponse {
128 fn len(&self) -> u16 {
129 1 + self.values.len() as u16
130 }
131}
132
133impl ReadMultipleHoldingRegistersResponse {
134 pub(crate) fn new(values: Vec<u8>) -> ReadMultipleHoldingRegistersResponse {
135 let bytes_number = values.len() as u8;
136 ReadMultipleHoldingRegistersResponse {
137 bytes_number,
138 values,
139 }
140 }
141
142 pub fn get_bytes_number(&self) -> &u8 {
143 &self.bytes_number
144 }
145
146 pub fn get_values(&self) -> &Vec<u8> {
147 &self.values
148 }
149}
150
151#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
153pub struct ReadInputRegistersResponse {
154 pub(crate) bytes_number: u8,
156
157 pub(crate) values: Vec<u8>,
159}
160
161impl Length for ReadInputRegistersResponse {
162 fn len(&self) -> u16 {
163 1 + self.values.len() as u16
164 }
165}
166
167impl ReadInputRegistersResponse {
168 pub(crate) fn new(values: Vec<u8>) -> ReadInputRegistersResponse {
169 let bytes_number = values.len() as u8;
170 ReadInputRegistersResponse {
171 bytes_number,
172 values,
173 }
174 }
175
176 pub fn get_bytes_number(&self) -> &u8 {
177 &self.bytes_number
178 }
179
180 pub fn get_values(&self) -> &Vec<u8> {
181 &self.values
182 }
183}
184
185#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
187pub struct WriteSingleCoilResponse {
188 pub(crate) coil_address: u16,
190
191 pub(crate) value: u16,
195}
196
197impl Length for WriteSingleCoilResponse {
198 fn len(&self) -> u16 {
199 4
200 }
201}
202
203impl WriteSingleCoilResponse {
204 pub(crate) fn new(coil_address: u16, value: u16) -> WriteSingleCoilResponse {
205 WriteSingleCoilResponse {
206 coil_address,
207 value,
208 }
209 }
210
211 pub fn get_coil_address(&self) -> &u16 {
212 &self.coil_address
213 }
214
215 pub fn get_value(&self) -> &u16 {
216 &self.value
217 }
218}
219
220#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
222pub struct WriteSingleHoldingRegisterResponse {
223 pub(crate) register_address: u16,
225
226 pub(crate) value: u16,
228}
229
230impl Length for WriteSingleHoldingRegisterResponse {
231 fn len(&self) -> u16 {
232 4
233 }
234}
235
236impl WriteSingleHoldingRegisterResponse {
237 pub(crate) fn new(register_address: u16, value: u16) -> WriteSingleHoldingRegisterResponse {
238 WriteSingleHoldingRegisterResponse {
239 register_address,
240 value,
241 }
242 }
243
244 pub fn get_register_address(&self) -> &u16 {
245 &self.register_address
246 }
247
248 pub fn get_value(&self) -> &u16 {
249 &self.value
250 }
251}
252
253#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
255pub struct WriteMultipleCoilsResponse {
256 pub(crate) first_address: u16,
258
259 pub(crate) coils_number: u16,
261}
262
263impl Length for WriteMultipleCoilsResponse {
264 fn len(&self) -> u16 {
265 4
266 }
267}
268
269impl WriteMultipleCoilsResponse {
270 pub(crate) fn new(first_address: u16, coils_number: u16) -> WriteMultipleCoilsResponse {
271 WriteMultipleCoilsResponse {
272 first_address,
273 coils_number,
274 }
275 }
276
277 pub fn get_first_address(&self) -> &u16 {
278 &self.first_address
279 }
280
281 pub fn get_coils_number(&self) -> &u16 {
282 &self.coils_number
283 }
284}
285
286#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
288pub struct WriteMultipleHoldingRegistersResponse {
289 pub(crate) first_address: u16,
291
292 pub(crate) registers_number: u16,
294}
295
296impl Length for WriteMultipleHoldingRegistersResponse {
297 fn len(&self) -> u16 {
298 4
299 }
300}
301
302impl WriteMultipleHoldingRegistersResponse {
303 pub(crate) fn new(
304 first_address: u16,
305 registers_number: u16,
306 ) -> WriteMultipleHoldingRegistersResponse {
307 WriteMultipleHoldingRegistersResponse {
308 first_address,
309 registers_number,
310 }
311 }
312
313 pub fn get_first_address(&self) -> &u16 {
314 &self.first_address
315 }
316
317 pub fn get_registers_number(&self) -> &u16 {
318 &self.registers_number
319 }
320}
321
322#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
323pub struct ExceptionResponse {
324 pub(crate) exception: Exception,
325}
326
327impl Length for ExceptionResponse {
328 fn len(&self) -> u16 {
329 1
330 }
331}
332
333impl ExceptionResponse {
334 pub(crate) fn new(exception: Exception) -> Self {
335 ExceptionResponse { exception }
336 }
337
338 pub fn get_exception(&self) -> &Exception {
339 &self.exception
340 }
341}
342
343impl From<ReadCoilsResponse> for BytesMut {
344 fn from(response: ReadCoilsResponse) -> Self {
345 let mut buf = BytesMut::new();
346 buf.put_u8(response.bytes_number);
347 buf.put_slice(response.values.as_slice());
348 buf
349 }
350}
351
352impl From<ReadDiscreteInputsResponse> for BytesMut {
353 fn from(response: ReadDiscreteInputsResponse) -> Self {
354 let mut buf = BytesMut::new();
355 buf.put_u8(response.bytes_number);
356 buf.put_slice(response.values.as_slice());
357 buf
358 }
359}
360
361impl From<ReadMultipleHoldingRegistersResponse> for BytesMut {
362 fn from(response: ReadMultipleHoldingRegistersResponse) -> Self {
363 let mut buf = BytesMut::new();
364 buf.put_u8(response.bytes_number);
365 buf.put_slice(response.values.as_slice());
366 buf
367 }
368}
369
370impl From<ReadInputRegistersResponse> for BytesMut {
371 fn from(response: ReadInputRegistersResponse) -> Self {
372 let mut buf = BytesMut::new();
373 buf.put_u8(response.bytes_number);
374 buf.put_slice(response.values.as_slice());
375 buf
376 }
377}
378
379impl From<WriteSingleCoilResponse> for BytesMut {
380 fn from(response: WriteSingleCoilResponse) -> Self {
381 let mut buf = BytesMut::new();
382 buf.put_u16(response.coil_address);
383 buf.put_u16(response.value);
384 buf
385 }
386}
387
388impl From<WriteSingleHoldingRegisterResponse> for BytesMut {
389 fn from(response: WriteSingleHoldingRegisterResponse) -> Self {
390 let mut buf = BytesMut::new();
391 buf.put_u16(response.register_address);
392 buf.put_u16(response.value);
393 buf
394 }
395}
396
397impl From<WriteMultipleCoilsResponse> for BytesMut {
398 fn from(response: WriteMultipleCoilsResponse) -> Self {
399 let mut buf = BytesMut::new();
400 buf.put_u16(response.first_address);
401 buf.put_u16(response.coils_number);
402 buf
403 }
404}
405
406impl From<WriteMultipleHoldingRegistersResponse> for BytesMut {
407 fn from(response: WriteMultipleHoldingRegistersResponse) -> Self {
408 let mut buf = BytesMut::new();
409 buf.put_u16(response.first_address);
410 buf.put_u16(response.registers_number);
411 buf
412 }
413}
414
415impl From<ExceptionResponse> for BytesMut {
416 fn from(response: ExceptionResponse) -> Self {
417 let mut buf = BytesMut::new();
418 buf.put_u8(response.exception.to_code());
419 buf
420 }
421}
422
423impl From<Head> for BytesMut {
424 fn from(head: Head) -> Self {
425 let mut buf = BytesMut::new();
426
427 let function_code = if head.is_exception {
428 head.function.to_code() + 0x80
429 } else {
430 head.function.to_code()
431 };
432
433 if head.version == Version::Tcp {
434 buf.put_u16(head.tid);
435 buf.put_u16(head.pid);
436 buf.put_u16(head.length);
437 }
438 buf.put_u8(head.uid);
439 buf.put_u8(function_code);
440 buf
441 }
442}
443
444pub(crate) fn response_to_bytesmut(item: Response, dst: &mut BytesMut) {
445 let version;
446 match item {
447 Response::ReadCoils(head, body) => {
448 version = head.version.clone();
449 dst.put(BytesMut::from(head));
450 dst.put(BytesMut::from(body));
451 }
452 Response::ReadDiscreteInputs(head, body) => {
453 version = head.version.clone();
454 dst.put(BytesMut::from(head));
455 dst.put(BytesMut::from(body));
456 }
457 Response::ReadMultipleHoldingRegisters(head, body) => {
458 version = head.version.clone();
459 dst.put(BytesMut::from(head));
460 dst.put(BytesMut::from(body));
461 }
462 Response::ReadInputRegisters(head, body) => {
463 version = head.version.clone();
464 dst.put(BytesMut::from(head));
465 dst.put(BytesMut::from(body));
466 }
467 Response::WriteSingleCoil(head, body) => {
468 version = head.version.clone();
469 dst.put(BytesMut::from(head));
470 dst.put(BytesMut::from(body));
471 }
472 Response::WriteSingleHoldingRegister(head, body) => {
473 version = head.version.clone();
474 dst.put(BytesMut::from(head));
475 dst.put(BytesMut::from(body));
476 }
477 Response::WriteMultipleCoils(head, body) => {
478 version = head.version.clone();
479 dst.put(BytesMut::from(head));
480 dst.put(BytesMut::from(body));
481 }
482 Response::WriteMultipleHoldingRegisters(head, body) => {
483 version = head.version.clone();
484 dst.put(BytesMut::from(head));
485 dst.put(BytesMut::from(body));
486 }
487 Response::Exception(head, body) => {
488 version = head.version.clone();
489 dst.put(BytesMut::from(head));
490 dst.put(BytesMut::from(body));
491 }
492 };
493 if Rtu == version {
494 dst.put_u16(crc::compute(&dst.to_vec()));
495 }
496}
497
498#[cfg(test)]
499mod response_test {
500 use crate::frame::{Exception, Length};
501 use crate::frame::response::*;
502
503 #[test]
504 fn test_read_coils_response() {
505 let response_l =
506 ReadCoilsResponse::new(vec![0b1100_1101, 0b0110_1011, 0b1011_0010, 0b0111_1111]);
507 let response_r = ReadCoilsResponse {
508 bytes_number: 0x04,
509 values: vec![0b1100_1101, 0b0110_1011, 0b1011_0010, 0b0111_1111],
510 };
511 assert_eq!(response_l, response_r);
512 assert_eq!(response_l.len(), 5);
513 }
514
515 #[test]
516 fn test_read_discrete_inputs_response() {
517 let response_l =
518 ReadDiscreteInputsResponse::new(vec![0b1010_1100, 0b1101_1011, 0b1111_1011, 0b0000_1101]);
519 let response_r = ReadDiscreteInputsResponse {
520 bytes_number: 0x04,
521 values: vec![0b1010_1100, 0b1101_1011, 0b1111_1011, 0b0000_1101],
522 };
523 assert_eq!(response_l, response_r);
524 assert_eq!(response_l.len(), 5);
525 }
526
527
528 #[test]
529 fn test_read_multiple_holding_registers_response() {
530 let response_l =
531 ReadMultipleHoldingRegistersResponse::new(vec![0xAE, 0x41, 0x56, 0x52, 0x43, 0x40]);
532 let response_r = ReadMultipleHoldingRegistersResponse {
533 bytes_number: 0x06,
534 values: vec![0xAE, 0x41, 0x56, 0x52, 0x43, 0x40],
535 };
536 assert_eq!(response_l, response_r);
537 assert_eq!(response_l.len(), 7);
538 }
539
540 #[test]
541 fn test_read_input_register_response() {
542 let response_l = ReadInputRegistersResponse::new(vec![0x0C, 0x00, 0x00, 0x00]);
543 let response_r = ReadInputRegistersResponse {
544 bytes_number: 0x04,
545 values: vec![0x0C, 0x00, 0x00, 0x00],
546 };
547 assert_eq!(response_l, response_r);
548 assert_eq!(response_l.len(), 5);
549 }
550
551 #[test]
552 fn test_write_single_coils_response() {
553 let response_l = WriteSingleCoilResponse::new(0x00, 0xFF);
554 let response_r = WriteSingleCoilResponse {
555 coil_address: 0x00,
556 value: 0xFF,
557 };
558 assert_eq!(response_l, response_r);
559 assert_eq!(response_l.len(), 4);
560 }
561
562 #[test]
563 fn test_write_single_holding_register_response() {
564 let response_l = WriteSingleHoldingRegisterResponse::new(0x01, 0xABCD);
565 let response_r = WriteSingleHoldingRegisterResponse {
566 register_address: 0x01,
567 value: 0xABCD,
568 };
569 assert_eq!(response_l, response_r);
570 assert_eq!(response_l.len(), 4);
571 }
572
573 #[test]
574 fn test_write_multiple_coils_response() {
575 let response_l = WriteMultipleCoilsResponse::new(0x00, 0x09);
576 let response_r = WriteMultipleCoilsResponse {
577 first_address: 0x00,
578 coils_number: 0x09,
579 };
580 assert_eq!(response_l, response_r);
581 assert_eq!(response_l.len(), 4);
582 }
583
584 #[test]
585 fn test_multiple_holding_registers_response() {
586 let response_l = WriteMultipleHoldingRegistersResponse::new(0x00, 0x02);
587 let response_r = WriteMultipleHoldingRegistersResponse {
588 first_address: 0x00,
589 registers_number: 0x02,
590 };
591 assert_eq!(response_l, response_r);
592 assert_eq!(response_l.len(), 4);
593 }
594
595 #[test]
596 fn test_exception_response() {
597 let response_l = ExceptionResponse::new(Exception::IllegalDataAddress);
598 let response_r = ExceptionResponse {
599 exception: Exception::IllegalDataAddress,
600 };
601 assert_eq!(response_l, response_r);
602 assert_eq!(response_l.len(), 1);
603 }
604}