mcumgr_toolkit/smp_errors.rs
1use strum::{Display, FromRepr};
2
3use crate::MCUmgrGroup;
4
5/// Errors the device can respond with when trying to execute an SMP command.
6///
7/// More information can be found [here](https://docs.zephyrproject.org/latest/services/device_mgmt/smp_protocol.html#minimal-response-smp-data).
8#[derive(Debug, Clone, Eq, PartialEq)]
9pub enum DeviceError {
10 /// MCUmgr SMP v1 error codes
11 V1 {
12 /// Error code
13 rc: i32,
14 /// Optional string that clarifies reason for an error
15 rsn: Option<String>,
16 },
17 /// MCUmgr SMP v2 error codes
18 V2 {
19 /// Group id
20 group: u16,
21 /// Group based error code
22 rc: i32,
23 },
24}
25
26fn v2_err_to_string(group: u16, rc: i32) -> Option<String> {
27 match MCUmgrGroup::from_repr(group)? {
28 MCUmgrGroup::MGMT_GROUP_ID_ENUM => EnumMgmtErrCode::from_repr(rc).map(|x| x.to_string()),
29 MCUmgrGroup::MGMT_GROUP_ID_FS => FsMgmtErrCode::from_repr(rc).map(|x| x.to_string()),
30 MCUmgrGroup::MGMT_GROUP_ID_IMAGE => ImgMgmtErrCode::from_repr(rc).map(|x| x.to_string()),
31 MCUmgrGroup::MGMT_GROUP_ID_OS => OsMgmtErrCode::from_repr(rc).map(|x| x.to_string()),
32 MCUmgrGroup::MGMT_GROUP_ID_SETTINGS => {
33 SettingsMgmtRetCode::from_repr(rc).map(|x| x.to_string())
34 }
35 MCUmgrGroup::MGMT_GROUP_ID_SHELL => ShellMgmtErrCode::from_repr(rc).map(|x| x.to_string()),
36 MCUmgrGroup::MGMT_GROUP_ID_STAT => StatMgmtErrCode::from_repr(rc).map(|x| x.to_string()),
37 MCUmgrGroup::ZEPHYR_MGMT_GRP_BASIC => {
38 ZephyrBasicGroupErrCode::from_repr(rc).map(|x| x.to_string())
39 }
40 _ => None,
41 }
42}
43
44impl std::fmt::Display for DeviceError {
45 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
46 match self {
47 DeviceError::V1 { rc, rsn } => {
48 if let Some(rsn) = rsn {
49 write!(f, "{}: {}", MCUmgrErr::err_to_string(*rc), rsn)
50 } else {
51 write!(f, "{}", MCUmgrErr::err_to_string(*rc))
52 }
53 }
54 DeviceError::V2 { group, rc } => match v2_err_to_string(*group, *rc) {
55 Some(msg) => f.write_str(&msg),
56 None => write!(f, "group={group},rc={rc}"),
57 },
58 }
59 }
60}
61
62/// See [`enum mcumgr_err_t`](https://docs.zephyrproject.org/latest/doxygen/html/mgmt__defines_8h.html).
63#[derive(FromRepr, Display, Debug, Copy, Clone, PartialEq, Eq)]
64#[repr(i32)]
65#[allow(non_camel_case_types)]
66pub enum MCUmgrErr {
67 /** No error (success). */
68 MGMT_ERR_EOK = 0,
69
70 /** Unknown error. */
71 MGMT_ERR_EUNKNOWN,
72
73 /** Insufficient memory (likely not enough space for CBOR object). */
74 MGMT_ERR_ENOMEM,
75
76 /** Error in input value. */
77 MGMT_ERR_EINVAL,
78
79 /** Operation timed out. */
80 MGMT_ERR_ETIMEOUT,
81
82 /** No such file/entry. */
83 MGMT_ERR_ENOENT,
84
85 /** Current state disallows command. */
86 MGMT_ERR_EBADSTATE,
87
88 /** Response too large. */
89 MGMT_ERR_EMSGSIZE,
90
91 /** Command not supported. */
92 MGMT_ERR_ENOTSUP,
93
94 /** Corrupt */
95 MGMT_ERR_ECORRUPT,
96
97 /** Command blocked by processing of other command */
98 MGMT_ERR_EBUSY,
99
100 /** Access to specific function, command or resource denied */
101 MGMT_ERR_EACCESSDENIED,
102
103 /** Requested SMP MCUmgr protocol version is not supported (too old) */
104 MGMT_ERR_UNSUPPORTED_TOO_OLD,
105
106 /** Requested SMP MCUmgr protocol version is not supported (too new) */
107 MGMT_ERR_UNSUPPORTED_TOO_NEW,
108
109 /** User errors defined from 256 onwards */
110 MGMT_ERR_EPERUSER = 256,
111}
112impl MCUmgrErr {
113 /// Converts a raw error code to a string
114 pub fn err_to_string(err: i32) -> String {
115 const PERUSER: MCUmgrErr = MCUmgrErr::MGMT_ERR_EPERUSER;
116 if err < PERUSER as i32 {
117 if let Some(err_enum) = Self::from_repr(err) {
118 format!("{err_enum}")
119 } else {
120 format!("MGMT_ERR_UNKNOWN({err})")
121 }
122 } else {
123 format!("{PERUSER}({err})")
124 }
125 }
126}
127
128/// See `enum settings_mgmt_ret_code_t`.
129#[derive(FromRepr, Display, Debug, Copy, Clone, PartialEq, Eq)]
130#[repr(i32)]
131#[allow(non_camel_case_types)]
132pub enum SettingsMgmtRetCode {
133 /** No error, this is implied if there is no ret value in the response. */
134 SETTINGS_MGMT_ERR_OK = 0,
135
136 /** Unknown error occurred. */
137 SETTINGS_MGMT_ERR_UNKNOWN,
138
139 /** The provided key name is too long to be used. */
140 SETTINGS_MGMT_ERR_KEY_TOO_LONG,
141
142 /** The provided key name does not exist. */
143 SETTINGS_MGMT_ERR_KEY_NOT_FOUND,
144
145 /** The provided key name does not support being read. */
146 SETTINGS_MGMT_ERR_READ_NOT_SUPPORTED,
147
148 /** The provided root key name does not exist. */
149 SETTINGS_MGMT_ERR_ROOT_KEY_NOT_FOUND,
150
151 /** The provided key name does not support being written. */
152 SETTINGS_MGMT_ERR_WRITE_NOT_SUPPORTED,
153
154 /** The provided key name does not support being deleted. */
155 SETTINGS_MGMT_ERR_DELETE_NOT_SUPPORTED,
156
157 /** The provided key name does not support being saved. */
158 SETTINGS_MGMT_ERR_SAVE_NOT_SUPPORTED,
159}
160
161/// See `enum fs_mgmt_err_code_t`.
162#[derive(FromRepr, Display, Debug, Copy, Clone, PartialEq, Eq)]
163#[repr(i32)]
164#[allow(non_camel_case_types)]
165pub enum FsMgmtErrCode {
166 /** No error (success). */
167 FS_MGMT_ERR_OK = 0,
168
169 /** Unknown error occurred. */
170 FS_MGMT_ERR_UNKNOWN,
171
172 /** The specified file name is not valid. */
173 FS_MGMT_ERR_FILE_INVALID_NAME,
174
175 /** The specified file does not exist. */
176 FS_MGMT_ERR_FILE_NOT_FOUND,
177
178 /** The specified file is a directory, not a file. */
179 FS_MGMT_ERR_FILE_IS_DIRECTORY,
180
181 /** Error occurred whilst attempting to open a file. */
182 FS_MGMT_ERR_FILE_OPEN_FAILED,
183
184 /** Error occurred whilst attempting to seek to an offset in a file. */
185 FS_MGMT_ERR_FILE_SEEK_FAILED,
186
187 /** Error occurred whilst attempting to read data from a file. */
188 FS_MGMT_ERR_FILE_READ_FAILED,
189
190 /** Error occurred whilst trying to truncate file. */
191 FS_MGMT_ERR_FILE_TRUNCATE_FAILED,
192
193 /** Error occurred whilst trying to delete file. */
194 FS_MGMT_ERR_FILE_DELETE_FAILED,
195
196 /** Error occurred whilst attempting to write data to a file. */
197 FS_MGMT_ERR_FILE_WRITE_FAILED,
198
199 /**
200 * The specified data offset is not valid, this could indicate that the file on the device
201 * has changed since the previous command. The length of the current file on the device is
202 * returned as "len", the user application needs to decide how to handle this (e.g. the
203 * hash of the file could be requested and compared with the hash of the length of the
204 * file being uploaded to see if they match or not).
205 */
206 FS_MGMT_ERR_FILE_OFFSET_NOT_VALID,
207
208 /** The requested offset is larger than the size of the file on the device. */
209 FS_MGMT_ERR_FILE_OFFSET_LARGER_THAN_FILE,
210
211 /** The requested checksum or hash type was not found or is not supported by this build. */
212 FS_MGMT_ERR_CHECKSUM_HASH_NOT_FOUND,
213
214 /** The specified mount point was not found or is not mounted. */
215 FS_MGMT_ERR_MOUNT_POINT_NOT_FOUND,
216
217 /** The specified mount point is that of a read-only filesystem. */
218 FS_MGMT_ERR_READ_ONLY_FILESYSTEM,
219
220 /** The operation cannot be performed because the file is empty with no contents. */
221 FS_MGMT_ERR_FILE_EMPTY,
222}
223
224/// See `enum img_mgmt_err_code_t`.
225#[derive(FromRepr, Display, Debug, Copy, Clone, PartialEq, Eq)]
226#[repr(i32)]
227#[allow(non_camel_case_types)]
228pub enum ImgMgmtErrCode {
229 /** No error, this is implied if there is no ret value in the response */
230 IMG_MGMT_ERR_OK = 0,
231
232 /** Unknown error occurred. */
233 IMG_MGMT_ERR_UNKNOWN,
234
235 /** Failed to query flash area configuration. */
236 IMG_MGMT_ERR_FLASH_CONFIG_QUERY_FAIL,
237
238 /** There is no image in the slot. */
239 IMG_MGMT_ERR_NO_IMAGE,
240
241 /** The image in the slot has no TLVs (tag, length, value). */
242 IMG_MGMT_ERR_NO_TLVS,
243
244 /** The image in the slot has an invalid TLV type and/or length. */
245 IMG_MGMT_ERR_INVALID_TLV,
246
247 /** The image in the slot has multiple hash TLVs, which is invalid. */
248 IMG_MGMT_ERR_TLV_MULTIPLE_HASHES_FOUND,
249
250 /** The image in the slot has an invalid TLV size. */
251 IMG_MGMT_ERR_TLV_INVALID_SIZE,
252
253 /** The image in the slot does not have a hash TLV, which is required. */
254 IMG_MGMT_ERR_HASH_NOT_FOUND,
255
256 /** There is no free slot to place the image. */
257 IMG_MGMT_ERR_NO_FREE_SLOT,
258
259 /** Flash area opening failed. */
260 IMG_MGMT_ERR_FLASH_OPEN_FAILED,
261
262 /** Flash area reading failed. */
263 IMG_MGMT_ERR_FLASH_READ_FAILED,
264
265 /** Flash area writing failed. */
266 IMG_MGMT_ERR_FLASH_WRITE_FAILED,
267
268 /** Flash area erase failed. */
269 IMG_MGMT_ERR_FLASH_ERASE_FAILED,
270
271 /** The provided slot is not valid. */
272 IMG_MGMT_ERR_INVALID_SLOT,
273
274 /** Insufficient heap memory (malloc failed). */
275 IMG_MGMT_ERR_NO_FREE_MEMORY,
276
277 /** The flash context is already set. */
278 IMG_MGMT_ERR_FLASH_CONTEXT_ALREADY_SET,
279
280 /** The flash context is not set. */
281 IMG_MGMT_ERR_FLASH_CONTEXT_NOT_SET,
282
283 /** The device for the flash area is NULL. */
284 IMG_MGMT_ERR_FLASH_AREA_DEVICE_NULL,
285
286 /** The offset for a page number is invalid. */
287 IMG_MGMT_ERR_INVALID_PAGE_OFFSET,
288
289 /** The offset parameter was not provided and is required. */
290 IMG_MGMT_ERR_INVALID_OFFSET,
291
292 /** The length parameter was not provided and is required. */
293 IMG_MGMT_ERR_INVALID_LENGTH,
294
295 /** The image length is smaller than the size of an image header. */
296 IMG_MGMT_ERR_INVALID_IMAGE_HEADER,
297
298 /** The image header magic value does not match the expected value. */
299 IMG_MGMT_ERR_INVALID_IMAGE_HEADER_MAGIC,
300
301 /** The hash parameter provided is not valid. */
302 IMG_MGMT_ERR_INVALID_HASH,
303
304 /** The image load address does not match the address of the flash area. */
305 IMG_MGMT_ERR_INVALID_FLASH_ADDRESS,
306
307 /** Failed to get version of currently running application. */
308 IMG_MGMT_ERR_VERSION_GET_FAILED,
309
310 /** The currently running application is newer than the version being uploaded. */
311 IMG_MGMT_ERR_CURRENT_VERSION_IS_NEWER,
312
313 /** There is already an image operating pending. */
314 IMG_MGMT_ERR_IMAGE_ALREADY_PENDING,
315
316 /** The image vector table is invalid. */
317 IMG_MGMT_ERR_INVALID_IMAGE_VECTOR_TABLE,
318
319 /** The image it too large to fit. */
320 IMG_MGMT_ERR_INVALID_IMAGE_TOO_LARGE,
321
322 /** The amount of data sent is larger than the provided image size. */
323 IMG_MGMT_ERR_INVALID_IMAGE_DATA_OVERRUN,
324
325 /** Confirmation of image has been denied */
326 IMG_MGMT_ERR_IMAGE_CONFIRMATION_DENIED,
327
328 /** Setting test to active slot is not allowed */
329 IMG_MGMT_ERR_IMAGE_SETTING_TEST_TO_ACTIVE_DENIED,
330
331 /** Current active slot for image cannot be determined */
332 IMG_MGMT_ERR_ACTIVE_SLOT_NOT_KNOWN,
333}
334
335/// See `enum os_mgmt_err_code_t`.
336#[derive(FromRepr, Display, Debug, Copy, Clone, PartialEq, Eq)]
337#[repr(i32)]
338#[allow(non_camel_case_types)]
339pub enum OsMgmtErrCode {
340 /** No error, this is implied if there is no ret value in the response */
341 OS_MGMT_ERR_OK = 0,
342
343 /** Unknown error occurred. */
344 OS_MGMT_ERR_UNKNOWN,
345
346 /** The provided format value is not valid. */
347 OS_MGMT_ERR_INVALID_FORMAT,
348
349 /** Query was not recognized. */
350 OS_MGMT_ERR_QUERY_YIELDS_NO_ANSWER,
351
352 /** RTC is not set */
353 OS_MGMT_ERR_RTC_NOT_SET,
354
355 /** RTC command failed */
356 OS_MGMT_ERR_RTC_COMMAND_FAILED,
357
358 /** Query was recognized but there is no valid value for the response. */
359 OS_MGMT_ERR_QUERY_RESPONSE_VALUE_NOT_VALID,
360}
361
362/// See `enum shell_mgmt_err_code_t`.
363#[derive(FromRepr, Display, Debug, Copy, Clone, PartialEq, Eq)]
364#[repr(i32)]
365#[allow(non_camel_case_types)]
366pub enum ShellMgmtErrCode {
367 /** No error, this is implied if there is no ret value in the response */
368 SHELL_MGMT_ERR_OK = 0,
369
370 /** Unknown error occurred. */
371 SHELL_MGMT_ERR_UNKNOWN,
372
373 /** The provided command to execute is too long. */
374 SHELL_MGMT_ERR_COMMAND_TOO_LONG,
375
376 /** No command to execute was provided. */
377 SHELL_MGMT_ERR_EMPTY_COMMAND,
378}
379
380/// See `enum stat_mgmt_err_code_t`.
381#[derive(FromRepr, Display, Debug, Copy, Clone, PartialEq, Eq)]
382#[repr(i32)]
383#[allow(non_camel_case_types)]
384pub enum StatMgmtErrCode {
385 /** No error, this is implied if there is no ret value in the response */
386 STAT_MGMT_ERR_OK = 0,
387
388 /** Unknown error occurred. */
389 STAT_MGMT_ERR_UNKNOWN,
390
391 /** The provided statistic group name was not found. */
392 STAT_MGMT_ERR_INVALID_GROUP,
393
394 /** The provided statistic name was not found. */
395 STAT_MGMT_ERR_INVALID_STAT_NAME,
396
397 /** The size of the statistic cannot be handled. */
398 STAT_MGMT_ERR_INVALID_STAT_SIZE,
399
400 /** Walk through of statistics was aborted. */
401 STAT_MGMT_ERR_WALK_ABORTED,
402}
403
404/// See `enum enum_mgmt_err_code_t`.
405#[derive(FromRepr, Display, Debug, Copy, Clone, PartialEq, Eq)]
406#[repr(i32)]
407#[allow(non_camel_case_types)]
408pub enum EnumMgmtErrCode {
409 /** No error, this is implied if there is no ret value in the response */
410 ENUM_MGMT_ERR_OK = 0,
411
412 /** Unknown error occurred. */
413 ENUM_MGMT_ERR_UNKNOWN,
414
415 /** Too many entries were provided. */
416 ENUM_MGMT_ERR_TOO_MANY_GROUP_ENTRIES,
417
418 /** Insufficient heap memory to store entry data. */
419 ENUM_MGMT_ERR_INSUFFICIENT_HEAP_FOR_ENTRIES,
420
421 /** Provided index is larger than the number of supported grouped. */
422 ENUM_MGMT_ERR_INDEX_TOO_LARGE,
423}
424
425/// See `enum zephyr_basic_group_err_code_t`.
426#[derive(FromRepr, Display, Debug, Copy, Clone, PartialEq, Eq)]
427#[repr(i32)]
428#[allow(non_camel_case_types)]
429pub enum ZephyrBasicGroupErrCode {
430 /** No error, this is implied if there is no ret value in the response */
431 ZEPHYRBASIC_MGMT_ERR_OK = 0,
432
433 /** Unknown error occurred. */
434 ZEPHYRBASIC_MGMT_ERR_UNKNOWN,
435
436 /** Opening of the flash area has failed. */
437 ZEPHYRBASIC_MGMT_ERR_FLASH_OPEN_FAILED,
438
439 /** Querying the flash area parameters has failed. */
440 ZEPHYRBASIC_MGMT_ERR_FLASH_CONFIG_QUERY_FAIL,
441
442 /** Erasing the flash area has failed. */
443 ZEPHYRBASIC_MGMT_ERR_FLASH_ERASE_FAILED,
444}