at_cryptoauth/
error.rs

1use core::convert::TryFrom;
2
3/// An error type representing ATECC608's erroneous conditions.
4#[derive(Copy, Clone, Debug)]
5pub struct Error {
6    repr: Repr,
7}
8
9#[derive(Copy, Clone, Debug)]
10enum Repr {
11    Device(Status),
12    Simple(ErrorKind),
13}
14
15impl From<ErrorKind> for Error {
16    fn from(kind: ErrorKind) -> Error {
17        Error {
18            repr: Repr::Simple(kind),
19        }
20    }
21}
22
23impl From<Status> for Error {
24    fn from(status: Status) -> Error {
25        Error {
26            repr: Repr::Device(status),
27        }
28    }
29}
30
31impl core::fmt::Display for Error {
32    fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
33        match &self.repr {
34            Repr::Device(status) => write!(fmt, "{}", status),
35            Repr::Simple(kind) => write!(fmt, "{}", kind),
36        }
37    }
38}
39
40#[derive(Copy, Clone, Debug)]
41pub enum Status {
42    /// response status byte indicates CheckMac failure (status byte = 0x01)
43    CheckmacVerifyFailed = 0x01,
44    /// chip was in a state where it could not execute the command, response
45    /// status byte indicates command execution error (status byte = 0x0F)
46    Execution = 0x0F,
47    /// response status byte indicates parsing error (status byte = 0x03)
48    Parse = 0x03,
49    /// response status byte indicates Device did not receive data properly
50    /// (status byte = 0xFF)
51    Crc = 0xFF,
52    /// response status byte is unknown
53    Unknown = 0xD5,
54    /// response status byte is Ecc fault (status byte = 0x05)
55    Ecc = 0x05,
56    /// response status byte is Self Test Error, chip in failure mode (status
57    /// byte = 0x07)
58    SelfTest = 0x07,
59    /// random number generator health test error
60    HealthTest = 0x08,
61}
62
63impl TryFrom<u8> for Status {
64    type Error = ();
65
66    fn try_from(value: u8) -> Result<Self, Self::Error> {
67        match value {
68            0x00 => Err(()),
69            0x01 => Ok(Self::CheckmacVerifyFailed),
70            0x0F => Ok(Self::Execution),
71            0x03 => Ok(Self::Parse),
72            0xFF => Ok(Self::Crc),
73            0x05 => Ok(Self::Ecc),
74            0x07 => Ok(Self::SelfTest),
75            0x08 => Ok(Self::HealthTest),
76            _ => Ok(Self::Unknown),
77        }
78    }
79}
80
81impl core::fmt::Display for Status {
82    fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
83        match self {
84            Self::CheckmacVerifyFailed => write!(fmt, "checkmac or verify failed"),
85            Self::Crc => write!(
86                fmt,
87                "bad crc found (command not properly received by device) or other comm error"
88            ),
89            Self::Ecc => write!(
90                fmt,
91                "computation error during ECC processing causing invalid results"
92            ),
93            Self::Execution => write!(fmt, "chip can't execute the command"),
94            Self::HealthTest => write!(fmt, "random number generator health test error"),
95            Self::Parse => write!(
96                fmt,
97                "command received byte length, opcode or parameter was illegal"
98            ),
99            Self::SelfTest => write!(fmt, "chip is in self test failure mode"),
100            Self::Unknown => write!(fmt, "response contains unknown non-zero status byte"),
101        }
102    }
103}
104
105/// A list of specific error causes. Each kind is converted into `Error` type.
106#[derive(Copy, Clone, Debug)]
107pub enum ErrorKind {
108    /// Code failed run-time consistency check
109    AssertFailure = 0xF6,
110    /// opcode is not supported by the device
111    BadOpcode = 0xF2,
112    /// bad argument (out of range, null pointer, etc.)
113    BadParam = 0xE2,
114    /// Communication with device failed. Same as in hardware dependent modules.
115    CommFail = 0xF0,
116    ConfigZoneLocked = 0x01,
117    DataZoneLocked = 0x04,
118    /// Function could not execute due to incorrect condition / state.
119    FuncFail = 0xE0,
120    /// invalid device id, id not set
121    InvalidId = 0xE3,
122    /// Count value is out of range or greater than buffer size.
123    InvalidSize = 0xE4,
124    /// required zone was not locked
125    NotLocked = 0xF8,
126    /// Re-synchronization succeeded, but only after generating a Wake-up
127    ResyncWithWakeup = 0xE8,
128    /// Crc error in data received from device
129    RxCrcError = 0xE5,
130    /// Timed out while waiting for response. Number of bytes received is > 0.
131    RxFail = 0xE6,
132    /// Supplied buffer is too small for data required
133    SmallBuffer = 0xED,
134    /// Timed out while waiting for response. Number of bytes received is 0.
135    Timeout = 0xF1,
136    /// Device did not respond too many times during a transmission. Could
137    /// indicate no device present.
138    TooManyCommRetries = 0xEC,
139    /// Failed to write
140    TxFail = 0xF7,
141    /// Function or some element of it hasn't been implemented yet
142    Unimplemented = 0xF5,
143    /// Use flags on the device indicates its consumed fully
144    UseFlagsConsumed = 0xFC,
145    /// Device did not respond to wake call as expected
146    WakeFailed = 0xD0,
147}
148
149impl core::fmt::Display for ErrorKind {
150    fn fmt(&self, fmt: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
151        match self {
152            Self::AssertFailure => write!(fmt, "failed run-time consistency check"),
153            Self::BadOpcode => write!(fmt, "opcode is not supported by the device"),
154            Self::BadParam => write!(fmt, "bad argument (out of range, null pointer, etc.)"),
155            Self::CommFail => write!(fmt, "communication with device failed"),
156            Self::ConfigZoneLocked => write!(fmt, "config zone is locked"),
157            Self::DataZoneLocked => write!(fmt, "data zone is locked"),
158            Self::FuncFail => write!(
159                fmt,
160                "function could not execute due to incorrect condition / state"
161            ),
162            Self::InvalidId => write!(fmt, "invalid device id, id not set"),
163            Self::InvalidSize => write!(
164                fmt,
165                "count value is out of range or greater than buffer size"
166            ),
167            Self::NotLocked => write!(fmt, "required zone was not locked"),
168            Self::ResyncWithWakeup => write!(
169                fmt,
170                "re-synchronization succeeded, but only after generating a Wake-up"
171            ),
172            Self::RxCrcError => write!(fmt, "crc error in data received from device"),
173            Self::RxFail => write!(
174                fmt,
175                "timed out while waiting for response. Number of bytes received is > 0"
176            ),
177            Self::SmallBuffer => write!(fmt, "supplied buffer is too small for data required"),
178            Self::Timeout => write!(fmt, "timed out while waiting for response"),
179            Self::TooManyCommRetries => {
180                write!(
181                    fmt,
182                    "device did not respond too many times, indicating no device present"
183                )
184            }
185            Self::TxFail => write!(fmt, "failed to write"),
186            Self::Unimplemented => write!(
187                fmt,
188                "function or some element of it hasn't been implemented yet"
189            ),
190            Self::UseFlagsConsumed => {
191                write!(fmt, "use flags on the device indicates its consumed fully")
192            }
193            Self::WakeFailed => write!(fmt, "device did not respond to wake call as expected"),
194        }
195    }
196}