peak_can/
log.rs

1use crate::channel::Channel;
2use crate::error::{CanError, CanOkError};
3use crate::peak_lib;
4use crate::peak_can;
5use std::ffi::c_void;
6use std::path::{Path, PathBuf};
7
8/* TRACE LOCATION traits */
9
10pub(crate) trait HasTraceLocation {}
11
12pub trait TraceLocation {
13    fn trace_location(&self) -> Result<PathBuf, CanError>;
14}
15
16impl<T: HasTraceLocation + Channel> TraceLocation for T {
17    fn trace_location(&self) -> Result<PathBuf, CanError> {
18        let mut data = [0u8; peak_can::MAX_LENGTH_VERSION_STRING as usize];
19        let code = unsafe {
20            peak_lib()?.CAN_GetValue(
21                self.channel(),
22                peak_can::PEAK_TRACE_LOCATION as u8,
23                data.as_mut_ptr() as *mut c_void,
24                data.len() as u32,
25            )
26        };
27
28        match CanOkError::try_from(code) {
29            Ok(CanOkError::Ok) => match std::str::from_utf8(&data) {
30                Ok(s) => {
31                    let s = s.trim_matches(char::from(0));
32                    Ok(PathBuf::from(s))
33                }
34                Err(_) => Err(CanError::Unknown),
35            },
36            Ok(CanOkError::Err(err)) => Err(err),
37            Err(_) => Err(CanError::Unknown),
38        }
39    }
40}
41
42pub(crate) trait HasSetTraceLocation {}
43
44pub trait SetTraceLocation {
45    fn set_trace_location<P: AsRef<Path>>(&self, path: P) -> Result<(), CanError>;
46}
47
48impl<T: HasSetTraceLocation + Channel> SetTraceLocation for T {
49    fn set_trace_location<P: AsRef<Path>>(&self, path: P) -> Result<(), CanError> {
50        let mut data = match path.as_ref().to_str() {
51            None => {
52                return Err(CanError::Unknown);
53            }
54            Some(s) => String::from(s),
55        };
56        let code = unsafe {
57            peak_lib()?.CAN_SetValue(
58                self.channel(),
59                peak_can::PEAK_TRACE_LOCATION as u8,
60                data.as_mut_ptr() as *mut c_void,
61                data.len() as u32,
62            )
63        };
64
65        match CanOkError::try_from(code) {
66            Ok(CanOkError::Ok) => Ok(()),
67            Ok(CanOkError::Err(err)) => Err(err),
68            Err(_) => Err(CanError::Unknown),
69        }
70    }
71}
72
73pub fn set_default_trace_location<T: SetTraceLocation>(value: &T) -> Result<(), CanError> {
74    value.set_trace_location(" ")
75}
76
77/* TRACE STATUS traits */
78
79pub(crate) trait HasTraceStatus {}
80
81pub trait TraceStatus {
82    fn is_tracing(&self) -> Result<bool, CanError>;
83}
84
85impl<T: HasTraceStatus + Channel> TraceStatus for T {
86    fn is_tracing(&self) -> Result<bool, CanError> {
87        let mut data = [0u8; 4];
88        let code = unsafe {
89            peak_lib()?.CAN_GetValue(
90                self.channel(),
91                peak_can::PEAK_TRACE_STATUS as u8,
92                data.as_mut_ptr() as *mut c_void,
93                data.len() as u32,
94            )
95        };
96
97        match CanOkError::try_from(code) {
98            Ok(CanOkError::Ok) => {
99                let code = u32::from_le_bytes(data);
100                if code == peak_can::PEAK_PARAMETER_ON {
101                    Ok(true)
102                } else if code == peak_can::PEAK_PARAMETER_OFF {
103                    Ok(false)
104                } else {
105                    Err(CanError::Unknown)
106                }
107            }
108            Ok(CanOkError::Err(err)) => Err(err),
109            Err(_) => Err(CanError::Unknown),
110        }
111    }
112}
113
114pub(crate) trait HasSetTraceStatus {}
115
116pub trait SetTraceStatus {
117    fn set_tracing(&self, enable: bool) -> Result<(), CanError>;
118}
119
120impl<T: HasSetTraceStatus + Channel> SetTraceStatus for T {
121    fn set_tracing(&self, enable: bool) -> Result<(), CanError> {
122        let mut data = match enable {
123            true => peak_can::PEAK_PARAMETER_ON.to_le_bytes(),
124            false => peak_can::PEAK_PARAMETER_OFF.to_le_bytes(),
125        };
126        let code = unsafe {
127            peak_lib()?.CAN_SetValue(
128                self.channel(),
129                peak_can::PEAK_TRACE_STATUS as u8,
130                data.as_mut_ptr() as *mut c_void,
131                data.len() as u32,
132            )
133        };
134
135        match CanOkError::try_from(code) {
136            Ok(CanOkError::Ok) => Ok(()),
137            Ok(CanOkError::Err(err)) => Err(err),
138            Err(_) => Err(CanError::Unknown),
139        }
140    }
141}
142
143/* TRACE SIZE traits */
144
145pub(crate) trait HasTraceSize {}
146
147pub trait TraceSize {
148    fn trace_size(&self) -> Result<u8, CanError>;
149}
150
151impl<T: HasTraceSize + Channel> TraceSize for T {
152    fn trace_size(&self) -> Result<u8, CanError> {
153        let mut data = [0u8; 4];
154        let code = unsafe {
155            peak_lib()?.CAN_GetValue(
156                self.channel(),
157                peak_can::PEAK_TRACE_SIZE as u8,
158                data.as_mut_ptr() as *mut c_void,
159                data.len() as u32,
160            )
161        };
162
163        match CanOkError::try_from(code) {
164            Ok(CanOkError::Ok) => Ok(data[0]),
165            Ok(CanOkError::Err(err)) => Err(err),
166            Err(_) => Err(CanError::Unknown),
167        }
168    }
169}
170
171pub(crate) trait HasSetTraceSize {}
172
173pub trait SetTraceSize {
174    fn set_trace_size(&self, size_mb: u8) -> Result<(), CanError>;
175}
176
177impl<T: HasSetTraceSize + Channel> SetTraceSize for T {
178    fn set_trace_size(&self, size_mb: u8) -> Result<(), CanError> {
179        let mut data = [size_mb];
180        let code = unsafe {
181            peak_lib()?.CAN_SetValue(
182                self.channel(),
183                peak_can::PEAK_TRACE_SIZE as u8,
184                data.as_mut_ptr() as *mut c_void,
185                data.len() as u32,
186            )
187        };
188
189        match CanOkError::try_from(code) {
190            Ok(CanOkError::Ok) => Ok(()),
191            Ok(CanOkError::Err(err)) => Err(err),
192            Err(_) => Err(CanError::Unknown),
193        }
194    }
195}
196
197pub fn set_default_trace_size<T: SetTraceSize>(value: &T) -> Result<(), CanError> {
198    value.set_trace_size(0)
199}
200
201/* TRACE CONFIGURE traits */
202
203#[derive(PartialEq, Debug)]
204pub enum TraceFile {
205    Single,
206    Segmented,
207    Date,
208    Time,
209    Overwrite,
210}
211
212impl TryFrom<u32> for TraceFile {
213    type Error = ();
214
215    fn try_from(value: u32) -> Result<Self, Self::Error> {
216        match value {
217            peak_can::TRACE_FILE_SINGLE => Ok(TraceFile::Single),
218            peak_can::TRACE_FILE_SEGMENTED => Ok(TraceFile::Segmented),
219            peak_can::TRACE_FILE_DATE => Ok(TraceFile::Date),
220            peak_can::TRACE_FILE_TIME => Ok(TraceFile::Time),
221            peak_can::TRACE_FILE_OVERWRITE => Ok(TraceFile::Overwrite),
222            _ => Err(()),
223        }
224    }
225}
226
227impl From<TraceFile> for u32 {
228    fn from(value: TraceFile) -> Self {
229        match value {
230            TraceFile::Single => peak_can::TRACE_FILE_SINGLE,
231            TraceFile::Segmented => peak_can::TRACE_FILE_SEGMENTED,
232            TraceFile::Date => peak_can::TRACE_FILE_DATE,
233            TraceFile::Time => peak_can::TRACE_FILE_TIME,
234            TraceFile::Overwrite => peak_can::TRACE_FILE_OVERWRITE,
235        }
236    }
237}
238
239pub(crate) trait HasTraceConfigure {}
240
241pub trait TraceConfigure {
242    fn trace_configuration(&self) -> Result<TraceFile, CanError>;
243}
244
245impl<T: HasTraceConfigure + Channel> TraceConfigure for T {
246    fn trace_configuration(&self) -> Result<TraceFile, CanError> {
247        let mut data = [0u8; 4];
248        let code = unsafe {
249            peak_lib()?.CAN_GetValue(
250                self.channel(),
251                peak_can::PEAK_TRACE_CONFIGURE as u8,
252                data.as_mut_ptr() as *mut c_void,
253                data.len() as u32,
254            )
255        };
256
257        match CanOkError::try_from(code) {
258            Ok(CanOkError::Ok) => {
259                let code = u32::from_le_bytes(data);
260                match TraceFile::try_from(code) {
261                    Ok(log_config) => Ok(log_config),
262                    Err(_) => Err(CanError::Unknown),
263                }
264            }
265            Ok(CanOkError::Err(err)) => Err(err),
266            Err(_) => Err(CanError::Unknown),
267        }
268    }
269}
270
271pub(crate) trait HasSetTraceConfigure {}
272
273pub trait SetTraceConfigure {
274    fn configure_trace(&self, config: TraceFile) -> Result<(), CanError>;
275}
276
277impl<T: HasSetTraceConfigure + Channel> SetTraceConfigure for T {
278    fn configure_trace(&self, config: TraceFile) -> Result<(), CanError> {
279        let mut data = u32::from(config).to_le_bytes();
280        let code = unsafe {
281            peak_lib()?.CAN_SetValue(
282                self.channel(),
283                peak_can::PEAK_TRACE_CONFIGURE as u8,
284                data.as_mut_ptr() as *mut c_void,
285                data.len() as u32,
286            )
287        };
288
289        match CanOkError::try_from(code) {
290            Ok(CanOkError::Ok) => Ok(()),
291            Ok(CanOkError::Err(err)) => Err(err),
292            Err(_) => Err(CanError::Unknown),
293        }
294    }
295}