1use crate::{CanErrorFrame, EmbeddedFrame, Frame};
42use std::{convert::TryFrom, error, fmt, io};
43use thiserror::Error;
44
45#[derive(Error, Debug)]
53pub enum Error {
54 #[error(transparent)]
56 Can(#[from] CanError),
57 #[error(transparent)]
59 Io(#[from] io::Error),
60}
61
62impl embedded_can::Error for Error {
63 fn kind(&self) -> embedded_can::ErrorKind {
64 match *self {
65 Error::Can(err) => err.kind(),
66 _ => embedded_can::ErrorKind::Other,
67 }
68 }
69}
70
71impl From<CanErrorFrame> for Error {
72 fn from(frame: CanErrorFrame) -> Self {
73 Error::Can(CanError::from(frame))
74 }
75}
76
77impl From<io::ErrorKind> for Error {
78 fn from(ek: io::ErrorKind) -> Self {
80 Self::from(io::Error::from(ek))
81 }
82}
83
84#[cfg(feature = "enumerate")]
85impl From<libudev::Error> for Error {
86 fn from(e: libudev::Error) -> Error {
88 match e.kind() {
89 libudev::ErrorKind::NoMem => Self::from(io::ErrorKind::OutOfMemory),
90 libudev::ErrorKind::InvalidInput => Self::from(io::ErrorKind::InvalidInput),
91 libudev::ErrorKind::Io(ek) => Self::from(ek),
92 }
93 }
94}
95
96pub type Result<T> = std::result::Result<T, Error>;
98
99pub type IoError = io::Error;
101
102pub type IoErrorKind = io::ErrorKind;
104
105pub type IoResult<T> = io::Result<T>;
107
108#[derive(Debug, Clone, Copy)]
125pub enum CanError {
126 TransmitTimeout,
128 LostArbitration(u8),
131 ControllerProblem(ControllerProblem),
133 ProtocolViolation {
135 vtype: ViolationType,
137 location: Location,
139 },
140 TransceiverError,
142 NoAck,
144 BusOff,
146 BusError,
148 Restarted,
150 DecodingFailure(CanErrorDecodingFailure),
152 Unknown(u32),
154}
155
156impl error::Error for CanError {}
157
158impl fmt::Display for CanError {
159 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
160 use CanError::*;
161 match *self {
162 TransmitTimeout => write!(f, "transmission timeout"),
163 LostArbitration(n) => write!(f, "arbitration lost after {} bits", n),
164 ControllerProblem(e) => write!(f, "controller problem: {}", e),
165 ProtocolViolation { vtype, location } => {
166 write!(f, "protocol violation at {}: {}", location, vtype)
167 }
168 TransceiverError => write!(f, "transceiver error"),
169 NoAck => write!(f, "no ack"),
170 BusOff => write!(f, "bus off"),
171 BusError => write!(f, "bus error"),
172 Restarted => write!(f, "restarted"),
173 DecodingFailure(err) => write!(f, "decoding failure: {}", err),
174 Unknown(err) => write!(f, "unknown error ({})", err),
175 }
176 }
177}
178
179impl embedded_can::Error for CanError {
180 fn kind(&self) -> embedded_can::ErrorKind {
181 match *self {
182 CanError::ControllerProblem(cp) => {
183 use ControllerProblem::*;
184 match cp {
185 ReceiveBufferOverflow | TransmitBufferOverflow => {
186 embedded_can::ErrorKind::Overrun
187 }
188 _ => embedded_can::ErrorKind::Other,
189 }
190 }
191 CanError::NoAck => embedded_can::ErrorKind::Acknowledge,
192 _ => embedded_can::ErrorKind::Other,
193 }
194 }
195}
196
197impl From<CanErrorFrame> for CanError {
198 fn from(frame: CanErrorFrame) -> Self {
200 match frame.error_bits() {
203 0x0001 => CanError::TransmitTimeout,
204 0x0002 => CanError::LostArbitration(frame.data()[0]),
205 0x0004 => match ControllerProblem::try_from(frame.data()[1]) {
206 Ok(err) => CanError::ControllerProblem(err),
207 Err(err) => CanError::DecodingFailure(err),
208 },
209 0x0008 => {
210 match (
211 ViolationType::try_from(frame.data()[2]),
212 Location::try_from(frame.data()[3]),
213 ) {
214 (Ok(vtype), Ok(location)) => CanError::ProtocolViolation { vtype, location },
215 (Err(err), _) | (_, Err(err)) => CanError::DecodingFailure(err),
216 }
217 }
218 0x0010 => CanError::TransceiverError,
219 0x0020 => CanError::NoAck,
220 0x0040 => CanError::BusOff,
221 0x0080 => CanError::BusError,
222 0x0100 => CanError::Restarted,
223 err => CanError::Unknown(err),
224 }
225 }
226}
227
228#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
234#[repr(u8)]
235pub enum ControllerProblem {
236 Unspecified = 0x00,
238 ReceiveBufferOverflow = 0x01,
240 TransmitBufferOverflow = 0x02,
242 ReceiveErrorWarning = 0x04,
244 TransmitErrorWarning = 0x08,
246 ReceiveErrorPassive = 0x10,
248 TransmitErrorPassive = 0x20,
250 Active = 0x40,
252}
253
254impl error::Error for ControllerProblem {}
255
256impl fmt::Display for ControllerProblem {
257 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
258 use ControllerProblem::*;
259 let msg = match *self {
260 Unspecified => "unspecified controller problem",
261 ReceiveBufferOverflow => "receive buffer overflow",
262 TransmitBufferOverflow => "transmit buffer overflow",
263 ReceiveErrorWarning => "ERROR WARNING (receive)",
264 TransmitErrorWarning => "ERROR WARNING (transmit)",
265 ReceiveErrorPassive => "ERROR PASSIVE (receive)",
266 TransmitErrorPassive => "ERROR PASSIVE (transmit)",
267 Active => "ERROR ACTIVE",
268 };
269 write!(f, "{}", msg)
270 }
271}
272
273impl TryFrom<u8> for ControllerProblem {
274 type Error = CanErrorDecodingFailure;
275
276 fn try_from(val: u8) -> std::result::Result<Self, Self::Error> {
277 use ControllerProblem::*;
278 Ok(match val {
279 0x00 => Unspecified,
280 0x01 => ReceiveBufferOverflow,
281 0x02 => TransmitBufferOverflow,
282 0x04 => ReceiveErrorWarning,
283 0x08 => TransmitErrorWarning,
284 0x10 => ReceiveErrorPassive,
285 0x20 => TransmitErrorPassive,
286 0x40 => Active,
287 _ => return Err(CanErrorDecodingFailure::InvalidControllerProblem),
288 })
289 }
290}
291
292#[derive(Debug, Clone, Copy, PartialEq, Eq)]
298#[repr(u8)]
299pub enum ViolationType {
300 Unspecified = 0x00,
302 SingleBitError = 0x01,
304 FrameFormatError = 0x02,
306 BitStuffingError = 0x04,
308 UnableToSendDominantBit = 0x08,
310 UnableToSendRecessiveBit = 0x10,
312 BusOverload = 0x20,
314 Active = 0x40,
316 TransmissionError = 0x80,
318}
319
320impl error::Error for ViolationType {}
321
322impl fmt::Display for ViolationType {
323 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
324 use ViolationType::*;
325 let msg = match *self {
326 Unspecified => "unspecified",
327 SingleBitError => "single bit error",
328 FrameFormatError => "frame format error",
329 BitStuffingError => "bit stuffing error",
330 UnableToSendDominantBit => "unable to send dominant bit",
331 UnableToSendRecessiveBit => "unable to send recessive bit",
332 BusOverload => "bus overload",
333 Active => "active",
334 TransmissionError => "transmission error",
335 };
336 write!(f, "{}", msg)
337 }
338}
339
340impl TryFrom<u8> for ViolationType {
341 type Error = CanErrorDecodingFailure;
342
343 fn try_from(val: u8) -> std::result::Result<Self, Self::Error> {
344 use ViolationType::*;
345 Ok(match val {
346 0x00 => Unspecified,
347 0x01 => SingleBitError,
348 0x02 => FrameFormatError,
349 0x04 => BitStuffingError,
350 0x08 => UnableToSendDominantBit,
351 0x10 => UnableToSendRecessiveBit,
352 0x20 => BusOverload,
353 0x40 => Active,
354 0x80 => TransmissionError,
355 _ => return Err(CanErrorDecodingFailure::InvalidViolationType),
356 })
357 }
358}
359
360#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
367#[repr(u8)]
368pub enum Location {
369 Unspecified = 0x00,
371 StartOfFrame = 0x03,
373 Id2821 = 0x02,
375 Id2018 = 0x06,
377 SubstituteRtr = 0x04,
379 IdentifierExtension = 0x05,
381 Id1713 = 0x07,
383 Id1205 = 0x0F,
385 Id0400 = 0x0E,
387 Rtr = 0x0C,
389 Reserved1 = 0x0D,
391 Reserved0 = 0x09,
393 DataLengthCode = 0x0B,
395 DataSection = 0x0A,
397 CrcSequence = 0x008,
399 CrcDelimiter = 0x18,
401 AckSlot = 0x19,
403 AckDelimiter = 0x1B,
405 EndOfFrame = 0x1A,
407 Intermission = 0x12,
409}
410
411impl fmt::Display for Location {
412 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
413 use Location::*;
414 let msg = match *self {
415 Unspecified => "unspecified location",
416 StartOfFrame => "start of frame",
417 Id2821 => "ID, bits 28-21",
418 Id2018 => "ID, bits 20-18",
419 SubstituteRtr => "substitute RTR bit",
420 IdentifierExtension => "ID, extension",
421 Id1713 => "ID, bits 17-13",
422 Id1205 => "ID, bits 12-05",
423 Id0400 => "ID, bits 04-00",
424 Rtr => "RTR bit",
425 Reserved1 => "reserved bit 1",
426 Reserved0 => "reserved bit 0",
427 DataLengthCode => "data length code",
428 DataSection => "data section",
429 CrcSequence => "CRC sequence",
430 CrcDelimiter => "CRC delimiter",
431 AckSlot => "ACK slot",
432 AckDelimiter => "ACK delimiter",
433 EndOfFrame => "end of frame",
434 Intermission => "intermission",
435 };
436 write!(f, "{}", msg)
437 }
438}
439impl TryFrom<u8> for Location {
440 type Error = CanErrorDecodingFailure;
441
442 fn try_from(val: u8) -> std::result::Result<Self, Self::Error> {
443 use Location::*;
444 Ok(match val {
445 0x00 => Unspecified,
446 0x03 => StartOfFrame,
447 0x02 => Id2821,
448 0x06 => Id2018,
449 0x04 => SubstituteRtr,
450 0x05 => IdentifierExtension,
451 0x07 => Id1713,
452 0x0F => Id1205,
453 0x0E => Id0400,
454 0x0C => Rtr,
455 0x0D => Reserved1,
456 0x09 => Reserved0,
457 0x0B => DataLengthCode,
458 0x0A => DataSection,
459 0x08 => CrcSequence,
460 0x18 => CrcDelimiter,
461 0x19 => AckSlot,
462 0x1B => AckDelimiter,
463 0x1A => EndOfFrame,
464 0x12 => Intermission,
465 _ => return Err(CanErrorDecodingFailure::InvalidLocation),
466 })
467 }
468}
469
470#[derive(Debug, Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
476#[repr(u8)]
477pub enum TransceiverError {
478 Unspecified = 0x00,
480 CanHighNoWire = 0x04,
482 CanHighShortToBat = 0x05,
484 CanHighShortToVcc = 0x06,
486 CanHighShortToGnd = 0x07,
488 CanLowNoWire = 0x40,
490 CanLowShortToBat = 0x50,
492 CanLowShortToVcc = 0x60,
494 CanLowShortToGnd = 0x70,
496 CanLowShortToCanHigh = 0x80,
498}
499
500impl TryFrom<u8> for TransceiverError {
501 type Error = CanErrorDecodingFailure;
502
503 fn try_from(val: u8) -> std::result::Result<Self, Self::Error> {
504 use TransceiverError::*;
505 Ok(match val {
506 0x00 => Unspecified,
507 0x04 => CanHighNoWire,
508 0x05 => CanHighShortToBat,
509 0x06 => CanHighShortToVcc,
510 0x07 => CanHighShortToGnd,
511 0x40 => CanLowNoWire,
512 0x50 => CanLowShortToBat,
513 0x60 => CanLowShortToVcc,
514 0x70 => CanLowShortToGnd,
515 0x80 => CanLowShortToCanHigh,
516 _ => return Err(CanErrorDecodingFailure::InvalidTransceiverError),
517 })
518 }
519}
520
521pub trait ControllerSpecificErrorInformation {
523 fn get_ctrl_err(&self) -> Option<&[u8]>;
525}
526
527impl<T: Frame> ControllerSpecificErrorInformation for T {
528 fn get_ctrl_err(&self) -> Option<&[u8]> {
530 let data = self.data();
531
532 if data.len() == 8 {
533 Some(&data[5..])
534 } else {
535 None
536 }
537 }
538}
539
540#[derive(Debug, Clone, Copy)]
544pub enum CanErrorDecodingFailure {
545 NotAnError,
547 UnknownErrorType(u32),
549 NotEnoughData(u8),
552 InvalidControllerProblem,
555 InvalidViolationType,
557 InvalidLocation,
560 InvalidTransceiverError,
562}
563
564impl error::Error for CanErrorDecodingFailure {}
565
566impl fmt::Display for CanErrorDecodingFailure {
567 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
568 use CanErrorDecodingFailure::*;
569 let msg = match *self {
570 NotAnError => "CAN frame is not an error",
571 UnknownErrorType(_) => "unknown error type",
572 NotEnoughData(_) => "not enough data",
573 InvalidControllerProblem => "not a valid controller problem",
574 InvalidViolationType => "not a valid violation type",
575 InvalidLocation => "not a valid location",
576 InvalidTransceiverError => "not a valid transceiver error",
577 };
578 write!(f, "{}", msg)
579 }
580}
581
582#[derive(Debug, Copy, Clone, PartialOrd, Ord, PartialEq, Eq)]
585pub enum ConstructionError {
587 WrongFrameType,
589 IDTooLarge,
591 TooMuchData,
593}
594
595impl error::Error for ConstructionError {}
596
597impl fmt::Display for ConstructionError {
598 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
599 use ConstructionError::*;
600 let msg = match *self {
601 WrongFrameType => "Incompatible frame type",
602 IDTooLarge => "CAN ID too large",
603 TooMuchData => "Payload is too large",
604 };
605 write!(f, "{}", msg)
606 }
607}
608
609#[cfg(test)]
612mod tests {
613 use crate::Error;
614 use std::io;
615
616 #[test]
617 fn test_errors() {
618 const KIND: io::ErrorKind = io::ErrorKind::TimedOut;
619
620 let err = Error::from(io::Error::from(KIND));
622 if let Error::Io(ioerr) = err {
623 assert_eq!(ioerr.kind(), KIND);
624 } else {
625 panic!("Wrong error conversion");
626 }
627
628 let err = Error::from(KIND);
630 if let Error::Io(ioerr) = err {
631 assert_eq!(ioerr.kind(), KIND);
632 } else {
633 panic!("Wrong error conversion");
634 }
635 }
636}