1use std::{fmt, sync::PoisonError};
21
22use num_enum::{FromPrimitive, IntoPrimitive};
23
24use crate::raw;
25
26pub type Result<T> = std::result::Result<T, Error>;
28
29#[derive(Clone)]
31pub struct Error {
32 kind: ErrorKind,
33 origin: Option<ErrorOrigin>,
34}
35
36#[derive(
38 Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, FromPrimitive, IntoPrimitive,
39)]
40#[repr(u32)]
41pub enum ErrorKind {
42 Generic = raw::TEEC_ERROR_GENERIC,
44 AccessDenied = raw::TEEC_ERROR_ACCESS_DENIED,
46 Cancel = raw::TEEC_ERROR_CANCEL,
48 AccessConflict = raw::TEEC_ERROR_ACCESS_CONFLICT,
50 ExcessData = raw::TEEC_ERROR_EXCESS_DATA,
52 BadFormat = raw::TEEC_ERROR_BAD_FORMAT,
54 BadParameters = raw::TEEC_ERROR_BAD_PARAMETERS,
56 BadState = raw::TEEC_ERROR_BAD_STATE,
58 ItemNotFound = raw::TEEC_ERROR_ITEM_NOT_FOUND,
60 NotImplemented = raw::TEEC_ERROR_NOT_IMPLEMENTED,
62 NotSupported = raw::TEEC_ERROR_NOT_SUPPORTED,
64 NoData = raw::TEEC_ERROR_NO_DATA,
66 OutOfMemory = raw::TEEC_ERROR_OUT_OF_MEMORY,
68 Busy = raw::TEEC_ERROR_BUSY,
70 Communication = raw::TEEC_ERROR_COMMUNICATION,
72 Security = raw::TEEC_ERROR_SECURITY,
74 ShortBuffer = raw::TEEC_ERROR_SHORT_BUFFER,
76 ExternalCancel = raw::TEEC_ERROR_EXTERNAL_CANCEL,
78 TargetDead = raw::TEEC_ERROR_TARGET_DEAD,
80 #[default]
82 Unknown,
83}
84
85impl ErrorKind {
86 pub(crate) fn as_str(&self) -> &'static str {
87 match self {
88 ErrorKind::Generic => "Non-specific cause.",
89 ErrorKind::AccessDenied => "Access privileges are not sufficient.",
90 ErrorKind::Cancel => "The operation was canceled.",
91 ErrorKind::AccessConflict => "Concurrent accesses caused conflict.",
92 ErrorKind::ExcessData => "Too much data for the requested operation was passed.",
93 ErrorKind::BadFormat => "Input data was of invalid format.",
94 ErrorKind::BadParameters => "Input parameters were invalid.",
95 ErrorKind::BadState => "Operation is not valid in the current state.",
96 ErrorKind::ItemNotFound => "The requested data item is not found.",
97 ErrorKind::NotImplemented => {
98 "The requested operation should exist but is not yet implemented."
99 }
100 ErrorKind::NotSupported => {
101 "The requested operation is valid but is not supported in this implementation."
102 }
103 ErrorKind::NoData => "Expected data was missing.",
104 ErrorKind::OutOfMemory => "System ran out of resources.",
105 ErrorKind::Busy => "The system is busy working on something else.",
106 ErrorKind::Communication => "Communication with a remote party failed.",
107 ErrorKind::Security => "A security fault was detected.",
108 ErrorKind::ShortBuffer => "The supplied buffer is too short for the generated output.",
109 ErrorKind::ExternalCancel => "Undocumented.",
110 ErrorKind::TargetDead => "Trusted Application has panicked during the operation.",
111 ErrorKind::Unknown => "Unknown error.",
112 }
113 }
114}
115
116impl Error {
117 pub fn new(kind: ErrorKind) -> Error {
118 Error { kind, origin: None }
119 }
120 pub fn from_raw_error(code: u32) -> Error {
122 Error {
123 kind: ErrorKind::from(code),
124 origin: None,
125 }
126 }
127
128 pub fn with_origin(mut self, origin: ErrorOrigin) -> Self {
129 self.origin = Some(origin);
130 self
131 }
132
133 pub fn kind(&self) -> ErrorKind {
135 self.kind
136 }
137
138 pub fn origin(&self) -> Option<ErrorOrigin> {
140 self.origin.clone()
141 }
142
143 pub fn raw_code(&self) -> u32 {
145 self.kind.into()
146 }
147
148 pub fn message(&self) -> &str {
150 self.kind().as_str()
151 }
152}
153
154impl<T> From<PoisonError<T>> for Error {
155 fn from(_: PoisonError<T>) -> Self {
156 Error::new(ErrorKind::Generic).with_origin(ErrorOrigin::API)
157 }
158}
159
160impl fmt::Debug for Error {
161 fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
162 write!(
163 fmt,
164 "{} (错误代码 0x{:x}, 来源 0x{:x})",
165 self.message(),
166 self.raw_code(),
167 self.origin().map(|v| v.into()).unwrap_or(0_u32),
168 )
169 }
170}
171
172impl fmt::Display for Error {
173 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
174 fmt::Debug::fmt(self, f)
175 }
176}
177
178impl std::error::Error for Error {
179 fn description(&self) -> &str {
180 self.message()
181 }
182}
183
184impl From<ErrorKind> for Error {
185 #[inline]
186 fn from(kind: ErrorKind) -> Error {
187 Error { kind, origin: None }
188 }
189}
190
191#[derive(Clone, Debug, Eq, PartialEq, FromPrimitive, IntoPrimitive)]
192#[repr(u32)]
193pub enum ErrorOrigin {
194 API = raw::TEEC_ORIGIN_API,
195 COMMS = raw::TEEC_ORIGIN_COMMS,
196 TEE = raw::TEEC_ORIGIN_TEE,
197 TA = raw::TEEC_ORIGIN_TRUSTED_APP,
198 #[default]
199 UNKNOWN,
200}
201
202#[cfg(test)]
203mod teec_error_tests {
204 use super::*;
205
206 #[test]
207 fn test_error_types_and_methods() {
208 assert_eq!(ErrorKind::Generic.as_str(), "Non-specific cause.");
210 assert_eq!(
211 ErrorKind::AccessDenied.as_str(),
212 "Access privileges are not sufficient."
213 );
214 assert_eq!(ErrorKind::Cancel.as_str(), "The operation was canceled.");
215 assert_eq!(
216 ErrorKind::AccessConflict.as_str(),
217 "Concurrent accesses caused conflict."
218 );
219 assert_eq!(
220 ErrorKind::ExcessData.as_str(),
221 "Too much data for the requested operation was passed."
222 );
223 assert_eq!(
224 ErrorKind::BadFormat.as_str(),
225 "Input data was of invalid format."
226 );
227 assert_eq!(
228 ErrorKind::BadParameters.as_str(),
229 "Input parameters were invalid."
230 );
231 assert_eq!(
232 ErrorKind::BadState.as_str(),
233 "Operation is not valid in the current state."
234 );
235 assert_eq!(
236 ErrorKind::ItemNotFound.as_str(),
237 "The requested data item is not found."
238 );
239 assert_eq!(
240 ErrorKind::NotImplemented.as_str(),
241 "The requested operation should exist but is not yet implemented."
242 );
243 assert_eq!(
244 ErrorKind::NotSupported.as_str(),
245 "The requested operation is valid but is not supported in this implementation."
246 );
247 assert_eq!(ErrorKind::NoData.as_str(), "Expected data was missing.");
248 assert_eq!(
249 ErrorKind::OutOfMemory.as_str(),
250 "System ran out of resources."
251 );
252 assert_eq!(
253 ErrorKind::Busy.as_str(),
254 "The system is busy working on something else."
255 );
256 assert_eq!(
257 ErrorKind::Communication.as_str(),
258 "Communication with a remote party failed."
259 );
260 assert_eq!(
261 ErrorKind::Security.as_str(),
262 "A security fault was detected."
263 );
264 assert_eq!(
265 ErrorKind::ShortBuffer.as_str(),
266 "The supplied buffer is too short for the generated output."
267 );
268 assert_eq!(ErrorKind::ExternalCancel.as_str(), "Undocumented.");
269 assert_eq!(
270 ErrorKind::TargetDead.as_str(),
271 "Trusted Application has panicked during the operation."
272 );
273 assert_eq!(ErrorKind::Unknown.as_str(), "Unknown error.");
274
275 let error = Error::new(ErrorKind::BadParameters);
277 assert_eq!(error.kind(), ErrorKind::BadParameters);
278 assert_eq!(error.origin(), None);
279
280 let raw_error = Error::from_raw_error(ErrorKind::Generic.into());
282 assert_eq!(raw_error.kind(), ErrorKind::Generic);
283
284 let error_with_origin = Error::new(ErrorKind::Generic).with_origin(ErrorOrigin::API);
286 assert_eq!(error_with_origin.origin(), Some(ErrorOrigin::API));
287
288 assert_eq!(error.raw_code(), ErrorKind::BadParameters.into());
290
291 assert_eq!(error.message(), "Input parameters were invalid.");
293
294 let debug_str = format!("{:?}", error);
296 assert!(debug_str.contains("错误代码"));
297
298 let display_str = format!("{}", error);
300 assert!(display_str.contains("错误代码"));
301
302 let from_kind: Error = ErrorKind::OutOfMemory.into();
304 assert_eq!(from_kind.kind(), ErrorKind::OutOfMemory);
305
306 assert_eq!(u32::from(ErrorOrigin::API), raw::TEEC_ORIGIN_API);
308 assert_eq!(u32::from(ErrorOrigin::COMMS), raw::TEEC_ORIGIN_COMMS);
309 assert_eq!(u32::from(ErrorOrigin::TEE), raw::TEEC_ORIGIN_TEE);
310 assert_eq!(u32::from(ErrorOrigin::TA), raw::TEEC_ORIGIN_TRUSTED_APP);
311 }
312
313 #[test]
314 fn test_error_kind_all_variants_as_str() {
315 let error_kinds = vec![
317 ErrorKind::Generic,
318 ErrorKind::AccessDenied,
319 ErrorKind::Cancel,
320 ErrorKind::AccessConflict,
321 ErrorKind::ExcessData,
322 ErrorKind::BadFormat,
323 ErrorKind::BadParameters,
324 ErrorKind::BadState,
325 ErrorKind::ItemNotFound,
326 ErrorKind::NotImplemented,
327 ErrorKind::NotSupported,
328 ErrorKind::NoData,
329 ErrorKind::OutOfMemory,
330 ErrorKind::Busy,
331 ErrorKind::Communication,
332 ErrorKind::Security,
333 ErrorKind::ShortBuffer,
334 ErrorKind::ExternalCancel,
335 ErrorKind::TargetDead,
336 ErrorKind::Unknown,
337 ];
338
339 for kind in error_kinds {
340 let error = Error::new(kind);
341 let _ = error.kind();
343 }
344 }
345
346 #[test]
348 fn test_error_origin_to_u32() {
349 assert_eq!(u32::from(ErrorOrigin::API), raw::TEEC_ORIGIN_API);
350 assert_eq!(u32::from(ErrorOrigin::COMMS), raw::TEEC_ORIGIN_COMMS);
351 assert_eq!(u32::from(ErrorOrigin::TEE), raw::TEEC_ORIGIN_TEE);
352 assert_eq!(u32::from(ErrorOrigin::TA), raw::TEEC_ORIGIN_TRUSTED_APP);
353 }
354}