modbus_rtu/common/
request.rs

1use super::{crc, RequestForm, BypassRequestForm};
2
3
4#[derive(Debug)]
5pub struct Request<'a> {
6    modbus_id: u8,
7    form: &'a RequestForm<'a>,
8}
9
10
11impl<'a> Request<'a> {
12    /// Creates a new Modbus RTU request instance.
13    ///
14    /// ---
15    /// # Arguments
16    /// - `modbus_id`: The Modbus slave ID
17    /// - `form`: A reference to the request form
18    ///
19    /// ---
20    /// # Returns
21    /// A new instance of `Request` containing the specified Modbus ID and form
22    /// 
23    /// ---
24    /// # Examples
25    /// ```
26    /// use modbus_rtu::common::{Request, RequestForm};
27    /// 
28    /// let read_value_form = RequestForm::ReadInputRegisters {
29    ///     start_register: 0x0000,
30    ///     registers_count: 12,
31    /// };
32    /// 
33    /// let request = Request::new(0x01, &read_value_form);
34    /// ```
35    ///
36    pub fn new(modbus_id: u8, form: &'a RequestForm) -> Request<'a> {
37        Request { modbus_id, form }
38    }
39
40    /// Writes a Modbus RTU request packet into the provided buffer and returns the corresponding slice.
41    ///
42    /// ---
43    /// # Arguments
44    /// - `buffer`: The buffer into which the packet will be written
45    ///
46    /// ---
47    /// # Returns
48    /// A slice representing the constructed Modbus RTU request packet
49    ///
50    /// ---
51    /// # Examples
52    /// ```
53    /// use modbus_rtu::common::{Request, RequestForm};
54    ///
55    /// let write_datas_form = RequestForm::WriteMultipleRegisters {
56    ///     start_register: 0x0001,
57    ///     datas_to_write: &[0x1234, 0x5678],
58    /// };
59    ///
60    /// let request = Request::new(0x01, &write_datas_form);
61    ///
62    /// let mut buffer: [u8; 256] = [0; 256];
63    /// let packet = request.to_packet(&mut buffer);
64    ///
65    /// assert_eq!(packet, &[0x01, 0x10, 0x00, 0x01, 0x00, 0x02, 0x04, 0x12, 0x34, 0x56, 0x78, 0x49, 0x57]);
66    /// ```
67    /// 
68    pub fn to_packet(&self, buffer: &'a mut [u8; 256]) -> &'a [u8] {
69        // write modbus id
70        buffer[0] = self.modbus_id;
71
72        // write function code
73        buffer[1] = self.form.get_function_code();
74
75        // write data bytes
76        let len: usize = match &self.form {
77            RequestForm::ReadHoldingRegisters { start_register, registers_count } |
78            RequestForm::ReadInputRegisters { start_register, registers_count } => {
79                // write start register address
80                buffer[2..4].copy_from_slice(&start_register.to_be_bytes());
81
82                // write registers count
83                buffer[4..6].copy_from_slice(&registers_count.to_be_bytes());
84
85                // packet length without CRC bytes
86                6
87            },
88            RequestForm::WriteSingleRegister { register_address, data_to_write } => {
89                // write register address
90                buffer[2..4].copy_from_slice(&register_address.to_be_bytes());
91
92                // write data to write
93                buffer[4..6].copy_from_slice(&data_to_write.to_be_bytes());
94
95                // packet length without CRC bytes
96                6
97            },
98            RequestForm::WriteMultipleRegisters { start_register, datas_to_write } => {
99                // write start register address
100                buffer[2..4].copy_from_slice(&start_register.to_be_bytes());
101
102                // write registers count
103                let registers_count: u16 = datas_to_write.len() as u16;
104                buffer[4..6].copy_from_slice(&registers_count.to_be_bytes());
105
106                // write bytes count
107                buffer[6] = (registers_count * 2) as u8;
108
109                // write datas to write
110                for i in 0..registers_count as usize {
111                    buffer[(7 + (i * 2))..=(8 + (i * 2))].copy_from_slice(&datas_to_write[i].to_be_bytes());
112                }
113
114                7 + (registers_count as usize * 2)
115            },
116            #[cfg(feature="bypass")]
117            RequestForm::BypassRequest(req) => {
118                let len = req.to_packet(buffer).len();
119
120                2 + len
121            },
122        };
123
124        let crc_bytes = crc::gen_bytes(&buffer[..len]);
125        buffer[len..(len + 2)].copy_from_slice(&crc_bytes);
126
127        &buffer[..(len + 2)]
128    }
129}
130
131
132#[cfg(feature="bypass")]
133#[derive(Debug)]
134pub struct BypassRequest<'a> {
135    modbus_id: u8,
136    form: &'a BypassRequestForm<'a>,
137}
138
139
140#[cfg(feature="bypass")]
141impl<'a> BypassRequest<'a> {
142    /// Creates a new Modbus RTU request instance.
143    ///
144    /// ---
145    /// # Arguments
146    /// - `modbus_id`: The Modbus slave ID
147    /// - `form`: A reference to the request form
148    ///
149    /// ---
150    /// # Returns
151    /// A new instance of `Request` containing the specified Modbus ID and form
152    /// 
153    /// ---
154    /// # Examples
155    /// ```
156    /// use modbus_rtu::common::{BypassRequest, BypassRequestForm};
157    /// 
158    /// let read_value_form = BypassRequestForm::ReadInputRegisters {
159    ///     start_register: 0x0000,
160    ///     registers_count: 12,
161    /// };
162    /// 
163    /// let request = BypassRequest::new(0x01, &read_value_form);
164    /// ```
165    ///
166    pub fn new(modbus_id: u8, form: &'a BypassRequestForm) -> BypassRequest<'a> {
167        BypassRequest { modbus_id, form }
168    }
169
170    /// Writes a Modbus RTU request packet into the provided buffer and returns the corresponding slice.
171    ///
172    /// ---
173    /// # Arguments
174    /// - `buffer`: The buffer into which the packet will be written
175    ///
176    /// ---
177    /// # Returns
178    /// A slice representing the constructed Modbus RTU request packet
179    ///
180    /// ---
181    /// # Examples
182    /// ```
183    /// use modbus_rtu::common::{BypassRequest, BypassRequestForm};
184    ///
185    /// let write_datas_form = BypassRequestForm::WriteMultipleRegisters {
186    ///     start_register: 0x0001,
187    ///     datas_to_write: &[0x1234, 0x5678],
188    /// };
189    ///
190    /// let request = BypassRequest::new(0x01, &write_datas_form);
191    ///
192    /// let mut buffer: [u8; 256] = [0; 256];
193    /// let packet = request.to_packet(&mut buffer);
194    ///
195    /// assert_eq!(packet, &[0x01, 0x10, 0x00, 0x01, 0x00, 0x02, 0x04, 0x12, 0x34, 0x56, 0x78, 0x49, 0x57]);
196    /// ```
197    /// 
198    pub fn to_packet(&self, buffer: &'a mut [u8; 256]) -> &'a [u8] {
199        // write modbus id
200        buffer[0] = self.modbus_id;
201
202        // write function code
203        buffer[1] = self.form.get_function_code();
204
205        // write data bytes
206        let len: usize = match &self.form {
207            BypassRequestForm::ReadHoldingRegisters { start_register, registers_count } |
208            BypassRequestForm::ReadInputRegisters { start_register, registers_count } => {
209                // write start register address
210                buffer[2..4].copy_from_slice(&start_register.to_be_bytes());
211
212                // write registers count
213                buffer[4..6].copy_from_slice(&registers_count.to_be_bytes());
214
215                // packet length without CRC bytes
216                6
217            },
218            BypassRequestForm::WriteSingleRegister { register_address, data_to_write } => {
219                // write register address
220                buffer[2..4].copy_from_slice(&register_address.to_be_bytes());
221
222                // write data to write
223                buffer[4..6].copy_from_slice(&data_to_write.to_be_bytes());
224
225                // packet length without CRC bytes
226                6
227            },
228            BypassRequestForm::WriteMultipleRegisters { start_register, datas_to_write } => {
229                // write start register address
230                buffer[2..4].copy_from_slice(&start_register.to_be_bytes());
231
232                // write registers count
233                let registers_count: u16 = datas_to_write.len() as u16;
234                buffer[4..6].copy_from_slice(&registers_count.to_be_bytes());
235
236                // write bytes count
237                buffer[6] = (registers_count * 2) as u8;
238
239                // write datas to write
240                for i in 0..registers_count as usize {
241                    buffer[(7 + (i * 2))..=(8 + (i * 2))].copy_from_slice(&datas_to_write[i].to_be_bytes());
242                }
243
244                7 + (registers_count as usize * 2)
245            },
246        };
247
248        let crc_bytes = crc::gen_bytes(&buffer[..len]);
249        buffer[len..(len + 2)].copy_from_slice(&crc_bytes);
250
251        &buffer[..(len + 2)]
252    }
253}