1use crate::dto::{CanFrameDto, DecodedSignalDto};
4use dbc_rs::Dbc;
5
6pub enum DecodeResult {
8 Signals(Vec<DecodedSignalDto>),
9 Error(String),
10}
11
12pub fn decode_frame(frame: &CanFrameDto, dbc: &Dbc) -> DecodeResult {
14 let decoded = match dbc.decode(frame.can_id, &frame.data, frame.is_extended) {
15 Ok(signals) => signals,
16 Err(e) => {
17 let msg = format!(
18 "Frame 0x{:X}: {} (DLC={}, data={} bytes)",
19 frame.can_id,
20 e,
21 frame.dlc,
22 frame.data.len()
23 );
24 log::warn!("Decode error: {}", msg);
25 return DecodeResult::Error(msg);
26 }
27 };
28
29 let message_name = dbc
31 .messages()
32 .find_by_id(if frame.is_extended {
33 frame.can_id | 0x80000000
34 } else {
35 frame.can_id
36 })
37 .map(|m| m.name())
38 .unwrap_or("Unknown");
39
40 DecodeResult::Signals(
41 decoded
42 .iter()
43 .map(|sig| DecodedSignalDto::from_dbc_signal(sig, frame.timestamp, message_name))
44 .collect(),
45 )
46}