st3215/
protocol_packet_handler.rs

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    // Fonctions utilitaires de manipulation de bytes
18    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    // Transmission de paquet
63    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        // En-tête de paquet
77        txpacket[PKT_HEADER_0] = 0xFF;
78        txpacket[PKT_HEADER_1] = 0xFF;
79
80        // Calcul de la somme de contrôle
81        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        // Envoi du paquet
88        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    // Réception de paquet
99    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                // Recherche de l'en-tête du paquet
112                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                        // Vérification de la somme de contrôle
153                        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    // Transmission et réception
189    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        // Définition du délai d'attente
201        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    // Ping
222    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    // Lecture
246    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    // Écriture
294    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    // Sync Write
349    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    // Sync Read
371    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}