modbus_core/codec/rtu/
server.rs1use super::*;
6
7pub fn decode_request(buf: &[u8]) -> Result<Option<RequestAdu<'_>>> {
9 if buf.is_empty() {
10 return Ok(None);
11 }
12 decode(DecoderType::Request, buf)
13 .and_then(|frame| {
14 let Some((DecodedFrame { slave, pdu }, _frame_pos)) = frame else {
15 return Ok(None);
16 };
17 let hdr = Header { slave };
18 let request = Request::try_from(pdu)
22 .map(RequestPdu)
23 .map(|pdu| Some(RequestAdu { hdr, pdu }));
24
25 #[cfg(feature = "log")]
26 if let Err(error) = request {
27 log::error!("Failed to decode request PDU: {error}");
29 }
30 request
31 })
32 .map_err(|_| {
33 unreachable!();
36 })
37}
38
39pub fn encode_response(adu: ResponseAdu<'_>, buf: &mut [u8]) -> Result<usize> {
41 let ResponseAdu { hdr, pdu } = adu;
42 if buf.len() < 2 {
43 return Err(Error::BufferSize);
44 }
45 let len = pdu.encode(&mut buf[1..])?;
46 if buf.len() < len + 3 {
47 return Err(Error::BufferSize);
48 }
49 buf[0] = hdr.slave;
50 let crc = crc16(&buf[0..=len]);
51 BigEndian::write_u16(&mut buf[len + 1..], crc);
52 Ok(len + 3)
53}
54
55#[cfg(test)]
56mod tests {
57 use super::*;
58
59 #[test]
60 fn decode_empty_request() {
61 let req = decode_request(&[]).unwrap();
62 assert!(req.is_none());
63 }
64
65 #[test]
66 fn decode_partly_received_request() {
67 let buf = &[
68 0x12, 0x16, ];
71 let req = decode_request(buf).unwrap();
72 assert!(req.is_none());
73 }
74
75 #[test]
76 fn decode_write_single_register_request() {
77 let buf = &[
78 0x12, 0x06, 0x22, 0x22, 0xAB, 0xCD, 0x9F, 0xBE, ];
87 let adu = decode_request(buf).unwrap().unwrap();
88 let RequestAdu { hdr, pdu } = adu;
89 let RequestPdu(pdu) = pdu;
90 assert_eq!(hdr.slave, 0x12);
91 assert_eq!(FunctionCode::from(pdu), FunctionCode::WriteSingleRegister);
92 }
93
94 #[test]
95 fn encode_write_single_register_response() {
96 let adu = ResponseAdu {
97 hdr: Header { slave: 0x12 },
98 pdu: ResponsePdu(Ok(Response::WriteSingleRegister(0x2222, 0xABCD))),
99 };
100 let buf = &mut [0; 100];
101 let len = encode_response(adu, buf).unwrap();
102 assert_eq!(len, 8);
103 assert_eq!(buf[0], 0x12);
104 assert_eq!(buf[1], 0x06);
105 assert_eq!(buf[2], 0x22);
106 assert_eq!(buf[3], 0x22);
107 assert_eq!(buf[4], 0xAB);
108 assert_eq!(buf[5], 0xCD);
109 assert_eq!(buf[6], 0x9F);
110 assert_eq!(buf[7], 0xBE);
111 }
112}