1use std::io::Error;
2
3const PACKET_MAX_LENGTH: usize = 512;
4const SMALL_PACKET_MAX_LENGTH: usize = 256;
5
6mod buffer;
7pub mod commands;
8mod crc;
9pub mod datatypes;
10
11use datatypes::McValues;
12
13pub fn get_packet<T: commands::Command>(command: T) -> Vec<u8> {
14 let data = command.get_data();
15
16 if data.len() > PACKET_MAX_LENGTH {
17 panic!("Data too long");
18 }
19
20 let mut packet = Vec::new();
21
22 if data.len() >= SMALL_PACKET_MAX_LENGTH {
23 packet.push(0x03);
24 packet.push((data.len() >> 8) as u8);
25 packet.push((data.len() & 0xFF) as u8);
26 } else {
27 packet.push(0x02);
28 packet.push(data.len() as u8);
29 }
30
31 packet.extend(data.clone());
32
33 let crc = crc::crc16(&data);
34 packet.push((crc >> 8) as u8);
35 packet.push((crc & 0xFF) as u8);
36
37 packet.push(0x03);
38 packet
39}
40
41pub enum PacketData {
42 Values(McValues),
43}
44
45pub fn process_packet(buffer: Vec<u8>) -> Result<PacketData, Error> {
46 let mut payload_length = 0;
47 let mut payload_index = 0;
48 let mut payload: Vec<u8> = Vec::new();
49
50 for (index, byte) in buffer.iter().enumerate() {
51 if *byte == 0x02 {
52 payload_length = buffer[index + 1] as usize;
53 payload_index = index + 2;
54 break;
55 }
56
57 if *byte == 0x03 {
58 payload_length = (buffer[index + 2] as usize) << 8 | buffer[index + 1] as usize;
59 payload_index = index + 3;
60 break;
61 }
62 }
63
64 if payload_length == 0 {
65 return Err(Error::new(std::io::ErrorKind::Other, "Invalid packet"));
66 }
67
68 for i in 0..payload_length {
69 payload.push(buffer[payload_index + i]);
70 }
71
72 let crc = crc::crc16(&payload);
73 let crc_received = (buffer[payload_index + payload_length] as u16) << 8
74 | buffer[payload_index + payload_length + 1] as u16;
75
76 if crc != crc_received {
77 return Err(Error::new(std::io::ErrorKind::Other, "CRC error"));
78 }
79
80 Ok(extract_data(payload))
81}
82
83fn extract_data(buffer: Vec<u8>) -> PacketData {
84 let id = buffer[0];
85 match id {
86 4 => {
87 let mut values = McValues {
88 temp_mosfet: 0.0,
89 temp_motor: 0.0,
90 current_motor: 0.0,
91 current_in: 0.0,
92 id: 0.0,
93 iq: 0.0,
94 duty_now: 0.0,
95 rpm: 0.0,
96 v_in: 0.0,
97 amp_hours: 0.0,
98 amp_hours_charged: 0.0,
99 watt_hours: 0.0,
100 watt_hours_charged: 0.0,
101 tachometer: 0,
102 tachometer_abs: 0,
103 fault_code: datatypes::McFaultCode::None,
104 pid_pos: 0.0,
105 vesc_id: 0,
106 };
107
108 println!("{:?}", buffer);
110
111 let mut index = 1;
112 values.temp_mosfet = buffer::get_float16(&buffer, 10.0, &mut index);
113 values.temp_motor = buffer::get_float16(&buffer, 10.0, &mut index);
114 values.current_motor = buffer::get_float32(&buffer, 100.0, &mut index);
115 values.current_in = buffer::get_float32(&buffer, 100.0, &mut index);
116 values.id = buffer::get_float32(&buffer, 100.0, &mut index);
117 values.iq = buffer::get_float32(&buffer, 100.0, &mut index);
118 values.duty_now = buffer::get_float16(&buffer, 1000.0, &mut index);
119 values.rpm = buffer::get_float32(&buffer, 1.0, &mut index);
120 values.v_in = buffer::get_float16(&buffer, 10.0, &mut index);
121 values.amp_hours = buffer::get_float32(&buffer, 10000.0, &mut index);
122 values.amp_hours_charged = buffer::get_float32(&buffer, 10000.0, &mut index);
123 values.watt_hours = buffer::get_float32(&buffer, 10000.0, &mut index);
124 values.watt_hours_charged = buffer::get_float32(&buffer, 10000.0, &mut index);
125 values.tachometer = buffer::get_int32(&buffer, &mut index);
126 values.tachometer_abs = buffer::get_int32(&buffer, &mut index);
127
128 PacketData::Values(values)
129 }
130 _ => panic!("Unknown packet id"),
131 }
132}