1use crate::port_handler::PortHandler;
2use crate::values::*;
3
4pub struct ProtocolPacketHandler<'a> {
5 port_handler: &'a mut PortHandler,
6 sts_end: u8,
7}
8
9impl<'a> ProtocolPacketHandler<'a> {
10 pub fn new(port_handler: &'a mut PortHandler) -> Self {
11 Self {
12 port_handler,
13 sts_end: 0,
14 }
15 }
16
17 pub fn sts_makeword(&self, a: u8, b: u8) -> u16 {
19 if self.sts_end == 0 {
20 (a as u16) | ((b as u16) << 8)
21 } else {
22 (b as u16) | ((a as u16) << 8)
23 }
24 }
25
26 pub fn sts_makedword(&self, a: u16, b: u16) -> u32 {
27 (a as u32) | ((b as u32) << 16)
28 }
29
30 pub fn sts_lobyte(&self, w: u16) -> u8 {
31 if self.sts_end == 0 {
32 (w & 0xFF) as u8
33 } else {
34 ((w >> 8) & 0xFF) as u8
35 }
36 }
37
38 pub fn sts_hibyte(&self, w: u16) -> u8 {
39 if self.sts_end == 0 {
40 ((w >> 8) & 0xFF) as u8
41 } else {
42 (w & 0xFF) as u8
43 }
44 }
45
46 pub fn sts_loword(&self, l: u32) -> u16 {
47 (l & 0xFFFF) as u16
48 }
49
50 pub fn sts_hiword(&self, h: u32) -> u16 {
51 ((h >> 16) & 0xFFFF) as u16
52 }
53
54 pub fn sts_tohost(&self, a: u16, b: u8) -> i16 {
55 if (a & (1 << b)) != 0 {
56 -((a & !(1 << b)) as i16)
57 } else {
58 a as i16
59 }
60 }
61
62 pub fn tx_packet(&mut self, txpacket: &mut Vec<u8>) -> CommResult {
64 let total_packet_length = txpacket[PKT_LENGTH] as usize + 4;
65
66 if self.port_handler.is_using {
67 return CommResult::PortBusy;
68 }
69 self.port_handler.is_using = true;
70
71 if total_packet_length > TXPACKET_MAX_LEN {
72 self.port_handler.is_using = false;
73 return CommResult::TxError;
74 }
75
76 txpacket[PKT_HEADER_0] = 0xFF;
78 txpacket[PKT_HEADER_1] = 0xFF;
79
80 let mut checksum: u8 = 0;
82 for i in 2..total_packet_length - 1 {
83 checksum = checksum.wrapping_add(txpacket[i]);
84 }
85 txpacket[total_packet_length - 1] = !checksum;
86
87 let _ = self.port_handler.clear_port();
89 match self.port_handler.write_port(&txpacket[..total_packet_length]) {
90 Ok(written) if written == total_packet_length => CommResult::Success,
91 _ => {
92 self.port_handler.is_using = false;
93 CommResult::TxFail
94 }
95 }
96 }
97
98 pub fn rx_packet(&mut self) -> (Vec<u8>, CommResult) {
100 let mut rxpacket = Vec::new();
101 let mut wait_length = 6;
102
103 loop {
104 match self.port_handler.read_port(wait_length - rxpacket.len()) {
105 Ok(mut data) => rxpacket.append(&mut data),
106 Err(_) => break,
107 }
108
109 let rx_length = rxpacket.len();
110 if rx_length >= wait_length {
111 let mut idx = 0;
113 for i in 0..rx_length - 1 {
114 if rxpacket[i] == 0xFF && rxpacket[i + 1] == 0xFF {
115 idx = i;
116 break;
117 }
118 }
119
120 if idx == 0 {
121 if rx_length >= PKT_LENGTH + 1 {
122 let id = rxpacket[PKT_ID];
123 let length = rxpacket[PKT_LENGTH];
124 let error = rxpacket[PKT_ERROR];
125
126 if id > 0xFD || length as usize > RXPACKET_MAX_LEN || error > 0x7F {
127 rxpacket.remove(0);
128 continue;
129 }
130
131 let new_wait_length = length as usize + PKT_LENGTH + 1;
132 if wait_length != new_wait_length {
133 wait_length = new_wait_length;
134 continue;
135 }
136
137 if rx_length < wait_length {
138 if self.port_handler.is_packet_timeout() {
139 self.port_handler.is_using = false;
140 return (
141 rxpacket,
142 if rx_length == 0 {
143 CommResult::RxTimeout
144 } else {
145 CommResult::RxCorrupt
146 },
147 );
148 }
149 continue;
150 }
151
152 let mut checksum: u8 = 0;
154 for i in 2..wait_length - 1 {
155 checksum = checksum.wrapping_add(rxpacket[i]);
156 }
157 checksum = !checksum;
158
159 self.port_handler.is_using = false;
160 if rxpacket[wait_length - 1] == checksum {
161 return (rxpacket, CommResult::Success);
162 } else {
163 return (rxpacket, CommResult::RxCorrupt);
164 }
165 }
166 } else {
167 rxpacket.drain(0..idx);
168 }
169 } else {
170 if self.port_handler.is_packet_timeout() {
171 self.port_handler.is_using = false;
172 return (
173 rxpacket,
174 if rx_length == 0 {
175 CommResult::RxTimeout
176 } else {
177 CommResult::RxCorrupt
178 },
179 );
180 }
181 }
182 }
183
184 self.port_handler.is_using = false;
185 (rxpacket, CommResult::RxFail)
186 }
187
188 pub fn tx_rx_packet(&mut self, txpacket: &mut Vec<u8>) -> (Option<Vec<u8>>, CommResult, u8) {
190 let result = self.tx_packet(txpacket);
191 if !result.is_success() {
192 return (None, result, 0);
193 }
194
195 if txpacket[PKT_ID] == BROADCAST_ID {
196 self.port_handler.is_using = false;
197 return (None, result, 0);
198 }
199
200 if txpacket[PKT_INSTRUCTION] == INST_READ {
202 self.port_handler
203 .set_packet_timeout(txpacket[PKT_PARAMETER0 + 1] as usize + 6);
204 } else {
205 self.port_handler.set_packet_timeout(6);
206 }
207
208 loop {
209 let (rxpacket, rx_result) = self.rx_packet();
210 if !rx_result.is_success() || rxpacket.get(PKT_ID) == Some(&txpacket[PKT_ID]) {
211 let error = if rx_result.is_success() && !rxpacket.is_empty() {
212 rxpacket[PKT_ERROR]
213 } else {
214 0
215 };
216 return (Some(rxpacket), rx_result, error);
217 }
218 }
219 }
220
221 pub fn ping(&mut self, sts_id: u8) -> (u16, CommResult, u8) {
223 if sts_id >= BROADCAST_ID {
224 return (0, CommResult::NotAvailable, 0);
225 }
226
227 let mut txpacket = vec![0u8; 6];
228 txpacket[PKT_ID] = sts_id;
229 txpacket[PKT_LENGTH] = 2;
230 txpacket[PKT_INSTRUCTION] = INST_PING;
231
232 let (_rxpacket, result, error) = self.tx_rx_packet(&mut txpacket);
233
234 if result.is_success() {
235 let (data, read_result, read_error) = self.read_tx_rx(sts_id, 3, 2);
236 if read_result.is_success() && data.len() >= 2 {
237 let model_number = self.sts_makeword(data[0], data[1]);
238 return (model_number, read_result, read_error);
239 }
240 }
241
242 (0, result, error)
243 }
244
245 pub fn read_tx_rx(&mut self, sts_id: u8, address: u8, length: u8) -> (Vec<u8>, CommResult, u8) {
247 if sts_id >= BROADCAST_ID {
248 return (Vec::new(), CommResult::NotAvailable, 0);
249 }
250
251 let mut txpacket = vec![0u8; 8];
252 txpacket[PKT_ID] = sts_id;
253 txpacket[PKT_LENGTH] = 4;
254 txpacket[PKT_INSTRUCTION] = INST_READ;
255 txpacket[PKT_PARAMETER0] = address;
256 txpacket[PKT_PARAMETER0 + 1] = length;
257
258 let (rxpacket, result, error) = self.tx_rx_packet(&mut txpacket);
259
260 if result.is_success() {
261 if let Some(packet) = rxpacket {
262 let start = PKT_PARAMETER0;
263 let end = PKT_PARAMETER0 + length as usize;
264 if packet.len() >= end {
265 return (packet[start..end].to_vec(), result, error);
266 }
267 }
268 }
269
270 (Vec::new(), result, error)
271 }
272
273 pub fn read_1byte_tx_rx(&mut self, sts_id: u8, address: u8) -> (u8, CommResult, u8) {
274 let (data, result, error) = self.read_tx_rx(sts_id, address, 1);
275 let data_read = if result.is_success() && !data.is_empty() {
276 data[0]
277 } else {
278 0
279 };
280 (data_read, result, error)
281 }
282
283 pub fn read_2byte_tx_rx(&mut self, sts_id: u8, address: u8) -> (u16, CommResult, u8) {
284 let (data, result, error) = self.read_tx_rx(sts_id, address, 2);
285 let data_read = if result.is_success() && data.len() >= 2 {
286 self.sts_makeword(data[0], data[1])
287 } else {
288 0
289 };
290 (data_read, result, error)
291 }
292
293 pub fn write_tx_rx(
295 &mut self,
296 sts_id: u8,
297 address: u8,
298 data: &[u8],
299 ) -> (CommResult, u8) {
300 let length = data.len();
301 let mut txpacket = vec![0u8; length + 7];
302
303 txpacket[PKT_ID] = sts_id;
304 txpacket[PKT_LENGTH] = (length + 3) as u8;
305 txpacket[PKT_INSTRUCTION] = INST_WRITE;
306 txpacket[PKT_PARAMETER0] = address;
307
308 txpacket[PKT_PARAMETER0 + 1..PKT_PARAMETER0 + 1 + length].copy_from_slice(data);
309
310 let (_, result, error) = self.tx_rx_packet(&mut txpacket);
311 (result, error)
312 }
313
314 pub fn write_tx_only(&mut self, sts_id: u8, address: u8, data: &[u8]) -> CommResult {
315 let length = data.len();
316 let mut txpacket = vec![0u8; length + 7];
317
318 txpacket[PKT_ID] = sts_id;
319 txpacket[PKT_LENGTH] = (length + 3) as u8;
320 txpacket[PKT_INSTRUCTION] = INST_WRITE;
321 txpacket[PKT_PARAMETER0] = address;
322
323 txpacket[PKT_PARAMETER0 + 1..PKT_PARAMETER0 + 1 + length].copy_from_slice(data);
324
325 let result = self.tx_packet(&mut txpacket);
326 self.port_handler.is_using = false;
327 result
328 }
329
330 pub fn write_1byte_tx_only(&mut self, sts_id: u8, address: u8, data: u8) -> CommResult {
331 self.write_tx_only(sts_id, address, &[data])
332 }
333
334 pub fn write_1byte_tx_rx(&mut self, sts_id: u8, address: u8, data: u8) -> (CommResult, u8) {
335 self.write_tx_rx(sts_id, address, &[data])
336 }
337
338 pub fn write_2byte_tx_only(&mut self, sts_id: u8, address: u8, data: u16) -> CommResult {
339 let bytes = [self.sts_lobyte(data), self.sts_hibyte(data)];
340 self.write_tx_only(sts_id, address, &bytes)
341 }
342
343 pub fn write_2byte_tx_rx(&mut self, sts_id: u8, address: u8, data: u16) -> (CommResult, u8) {
344 let bytes = [self.sts_lobyte(data), self.sts_hibyte(data)];
345 self.write_tx_rx(sts_id, address, &bytes)
346 }
347
348 pub fn sync_write_tx_only(
350 &mut self,
351 start_address: u8,
352 data_length: u8,
353 param: &[u8],
354 ) -> CommResult {
355 let param_length = param.len();
356 let mut txpacket = vec![0u8; param_length + 8];
357
358 txpacket[PKT_ID] = BROADCAST_ID;
359 txpacket[PKT_LENGTH] = (param_length + 4) as u8;
360 txpacket[PKT_INSTRUCTION] = INST_SYNC_WRITE;
361 txpacket[PKT_PARAMETER0] = start_address;
362 txpacket[PKT_PARAMETER0 + 1] = data_length;
363
364 txpacket[PKT_PARAMETER0 + 2..PKT_PARAMETER0 + 2 + param_length].copy_from_slice(param);
365
366 let (_, result, _) = self.tx_rx_packet(&mut txpacket);
367 result
368 }
369
370 pub fn sync_read_tx(
372 &mut self,
373 start_address: u8,
374 data_length: u8,
375 param: &[u8],
376 ) -> CommResult {
377 let param_length = param.len();
378 let mut txpacket = vec![0u8; param_length + 8];
379
380 txpacket[PKT_ID] = BROADCAST_ID;
381 txpacket[PKT_LENGTH] = (param_length + 4) as u8;
382 txpacket[PKT_INSTRUCTION] = INST_SYNC_READ;
383 txpacket[PKT_PARAMETER0] = start_address;
384 txpacket[PKT_PARAMETER0 + 1] = data_length;
385
386 txpacket[PKT_PARAMETER0 + 2..PKT_PARAMETER0 + 2 + param_length].copy_from_slice(param);
387
388 self.tx_packet(&mut txpacket)
389 }
390
391 pub fn sync_read_rx(&mut self, data_length: usize, param_length: usize) -> (CommResult, Vec<u8>) {
392 let wait_length = (6 + data_length) * param_length;
393 self.port_handler.set_packet_timeout(wait_length);
394
395 let mut rxpacket = Vec::new();
396
397 loop {
398 match self.port_handler.read_port(wait_length - rxpacket.len()) {
399 Ok(mut data) => rxpacket.append(&mut data),
400 Err(_) => break,
401 }
402
403 let rx_length = rxpacket.len();
404 if rx_length >= wait_length {
405 self.port_handler.is_using = false;
406 return (CommResult::Success, rxpacket);
407 } else {
408 if self.port_handler.is_packet_timeout() {
409 self.port_handler.is_using = false;
410 return (
411 if rx_length == 0 {
412 CommResult::RxTimeout
413 } else {
414 CommResult::RxCorrupt
415 },
416 rxpacket,
417 );
418 }
419 }
420 }
421
422 self.port_handler.is_using = false;
423 (CommResult::RxFail, rxpacket)
424 }
425}