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(®isters_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(®ister_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(®isters_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(®isters_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(®ister_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(®isters_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}