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
8pub(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
77pub(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
143pub(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#[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}