mcumgr-toolkit 0.11.4

Core library of the software suite for Zephyr's MCUmgr protocol
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
use strum::{Display, FromRepr};

use crate::MCUmgrGroup;

/// Errors the device can respond with when trying to execute an SMP command.
///
/// More information can be found [here](https://docs.zephyrproject.org/latest/services/device_mgmt/smp_protocol.html#minimal-response-smp-data).
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum DeviceError {
    /// MCUmgr SMP v1 error codes
    V1 {
        /// Error code
        rc: i32,
        /// Optional string that clarifies reason for an error
        rsn: Option<String>,
    },
    /// MCUmgr SMP v2 error codes
    V2 {
        /// Group id
        group: u16,
        /// Group based error code
        rc: i32,
    },
}

fn v2_err_to_string(group: u16, rc: i32) -> Option<String> {
    match MCUmgrGroup::from_repr(group)? {
        MCUmgrGroup::MGMT_GROUP_ID_ENUM => EnumMgmtErrCode::from_repr(rc).map(|x| x.to_string()),
        MCUmgrGroup::MGMT_GROUP_ID_FS => FsMgmtErrCode::from_repr(rc).map(|x| x.to_string()),
        MCUmgrGroup::MGMT_GROUP_ID_IMAGE => ImgMgmtErrCode::from_repr(rc).map(|x| x.to_string()),
        MCUmgrGroup::MGMT_GROUP_ID_OS => OsMgmtErrCode::from_repr(rc).map(|x| x.to_string()),
        MCUmgrGroup::MGMT_GROUP_ID_SETTINGS => {
            SettingsMgmtRetCode::from_repr(rc).map(|x| x.to_string())
        }
        MCUmgrGroup::MGMT_GROUP_ID_SHELL => ShellMgmtErrCode::from_repr(rc).map(|x| x.to_string()),
        MCUmgrGroup::MGMT_GROUP_ID_STAT => StatMgmtErrCode::from_repr(rc).map(|x| x.to_string()),
        MCUmgrGroup::ZEPHYR_MGMT_GRP_BASIC => {
            ZephyrBasicGroupErrCode::from_repr(rc).map(|x| x.to_string())
        }
        _ => None,
    }
}

impl std::fmt::Display for DeviceError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        match self {
            DeviceError::V1 { rc, rsn } => {
                if let Some(rsn) = rsn {
                    write!(f, "{}: {}", MCUmgrErr::err_to_string(*rc), rsn)
                } else {
                    write!(f, "{}", MCUmgrErr::err_to_string(*rc))
                }
            }
            DeviceError::V2 { group, rc } => match v2_err_to_string(*group, *rc) {
                Some(msg) => f.write_str(&msg),
                None => write!(f, "group={group},rc={rc}"),
            },
        }
    }
}

/// See [`enum mcumgr_err_t`](https://docs.zephyrproject.org/latest/doxygen/html/mgmt__defines_8h.html).
#[derive(FromRepr, Display, Debug, Copy, Clone, PartialEq, Eq)]
#[repr(i32)]
#[allow(non_camel_case_types)]
pub enum MCUmgrErr {
    /** No error (success). */
    MGMT_ERR_EOK = 0,

    /** Unknown error. */
    MGMT_ERR_EUNKNOWN,

    /** Insufficient memory (likely not enough space for CBOR object). */
    MGMT_ERR_ENOMEM,

    /** Error in input value. */
    MGMT_ERR_EINVAL,

    /** Operation timed out. */
    MGMT_ERR_ETIMEOUT,

    /** No such file/entry. */
    MGMT_ERR_ENOENT,

    /** Current state disallows command. */
    MGMT_ERR_EBADSTATE,

    /** Response too large. */
    MGMT_ERR_EMSGSIZE,

    /** Command not supported. */
    MGMT_ERR_ENOTSUP,

    /** Corrupt */
    MGMT_ERR_ECORRUPT,

    /** Command blocked by processing of other command */
    MGMT_ERR_EBUSY,

    /** Access to specific function, command or resource denied */
    MGMT_ERR_EACCESSDENIED,

    /** Requested SMP MCUmgr protocol version is not supported (too old) */
    MGMT_ERR_UNSUPPORTED_TOO_OLD,

    /** Requested SMP MCUmgr protocol version is not supported (too new) */
    MGMT_ERR_UNSUPPORTED_TOO_NEW,

    /** User errors defined from 256 onwards */
    MGMT_ERR_EPERUSER = 256,
}
impl MCUmgrErr {
    /// Converts a raw error code to a string
    pub fn err_to_string(err: i32) -> String {
        const PERUSER: MCUmgrErr = MCUmgrErr::MGMT_ERR_EPERUSER;
        if err < PERUSER as i32 {
            if let Some(err_enum) = Self::from_repr(err) {
                format!("{err_enum}")
            } else {
                format!("MGMT_ERR_UNKNOWN({err})")
            }
        } else {
            format!("{PERUSER}({err})")
        }
    }
}

/// See `enum settings_mgmt_ret_code_t`.
#[derive(FromRepr, Display, Debug, Copy, Clone, PartialEq, Eq)]
#[repr(i32)]
#[allow(non_camel_case_types)]
pub enum SettingsMgmtRetCode {
    /** No error, this is implied if there is no ret value in the response. */
    SETTINGS_MGMT_ERR_OK = 0,

    /** Unknown error occurred. */
    SETTINGS_MGMT_ERR_UNKNOWN,

    /** The provided key name is too long to be used. */
    SETTINGS_MGMT_ERR_KEY_TOO_LONG,

    /** The provided key name does not exist. */
    SETTINGS_MGMT_ERR_KEY_NOT_FOUND,

    /** The provided key name does not support being read. */
    SETTINGS_MGMT_ERR_READ_NOT_SUPPORTED,

    /** The provided root key name does not exist. */
    SETTINGS_MGMT_ERR_ROOT_KEY_NOT_FOUND,

    /** The provided key name does not support being written. */
    SETTINGS_MGMT_ERR_WRITE_NOT_SUPPORTED,

    /** The provided key name does not support being deleted. */
    SETTINGS_MGMT_ERR_DELETE_NOT_SUPPORTED,

    /** The provided key name does not support being saved. */
    SETTINGS_MGMT_ERR_SAVE_NOT_SUPPORTED,
}

/// See `enum fs_mgmt_err_code_t`.
#[derive(FromRepr, Display, Debug, Copy, Clone, PartialEq, Eq)]
#[repr(i32)]
#[allow(non_camel_case_types)]
pub enum FsMgmtErrCode {
    /** No error (success). */
    FS_MGMT_ERR_OK = 0,

    /** Unknown error occurred. */
    FS_MGMT_ERR_UNKNOWN,

    /** The specified file name is not valid. */
    FS_MGMT_ERR_FILE_INVALID_NAME,

    /** The specified file does not exist. */
    FS_MGMT_ERR_FILE_NOT_FOUND,

    /** The specified file is a directory, not a file. */
    FS_MGMT_ERR_FILE_IS_DIRECTORY,

    /** Error occurred whilst attempting to open a file. */
    FS_MGMT_ERR_FILE_OPEN_FAILED,

    /** Error occurred whilst attempting to seek to an offset in a file. */
    FS_MGMT_ERR_FILE_SEEK_FAILED,

    /** Error occurred whilst attempting to read data from a file. */
    FS_MGMT_ERR_FILE_READ_FAILED,

    /** Error occurred whilst trying to truncate file. */
    FS_MGMT_ERR_FILE_TRUNCATE_FAILED,

    /** Error occurred whilst trying to delete file. */
    FS_MGMT_ERR_FILE_DELETE_FAILED,

    /** Error occurred whilst attempting to write data to a file. */
    FS_MGMT_ERR_FILE_WRITE_FAILED,

    /**
     * The specified data offset is not valid, this could indicate that the file on the device
     * has changed since the previous command. The length of the current file on the device is
     * returned as "len", the user application needs to decide how to handle this (e.g. the
     * hash of the file could be requested and compared with the hash of the length of the
     * file being uploaded to see if they match or not).
     */
    FS_MGMT_ERR_FILE_OFFSET_NOT_VALID,

    /** The requested offset is larger than the size of the file on the device. */
    FS_MGMT_ERR_FILE_OFFSET_LARGER_THAN_FILE,

    /** The requested checksum or hash type was not found or is not supported by this build. */
    FS_MGMT_ERR_CHECKSUM_HASH_NOT_FOUND,

    /** The specified mount point was not found or is not mounted. */
    FS_MGMT_ERR_MOUNT_POINT_NOT_FOUND,

    /** The specified mount point is that of a read-only filesystem. */
    FS_MGMT_ERR_READ_ONLY_FILESYSTEM,

    /** The operation cannot be performed because the file is empty with no contents. */
    FS_MGMT_ERR_FILE_EMPTY,
}

/// See `enum img_mgmt_err_code_t`.
#[derive(FromRepr, Display, Debug, Copy, Clone, PartialEq, Eq)]
#[repr(i32)]
#[allow(non_camel_case_types)]
pub enum ImgMgmtErrCode {
    /** No error, this is implied if there is no ret value in the response */
    IMG_MGMT_ERR_OK = 0,

    /** Unknown error occurred. */
    IMG_MGMT_ERR_UNKNOWN,

    /** Failed to query flash area configuration. */
    IMG_MGMT_ERR_FLASH_CONFIG_QUERY_FAIL,

    /** There is no image in the slot. */
    IMG_MGMT_ERR_NO_IMAGE,

    /** The image in the slot has no TLVs (tag, length, value). */
    IMG_MGMT_ERR_NO_TLVS,

    /** The image in the slot has an invalid TLV type and/or length. */
    IMG_MGMT_ERR_INVALID_TLV,

    /** The image in the slot has multiple hash TLVs, which is invalid. */
    IMG_MGMT_ERR_TLV_MULTIPLE_HASHES_FOUND,

    /** The image in the slot has an invalid TLV size. */
    IMG_MGMT_ERR_TLV_INVALID_SIZE,

    /** The image in the slot does not have a hash TLV, which is required.  */
    IMG_MGMT_ERR_HASH_NOT_FOUND,

    /** There is no free slot to place the image. */
    IMG_MGMT_ERR_NO_FREE_SLOT,

    /** Flash area opening failed. */
    IMG_MGMT_ERR_FLASH_OPEN_FAILED,

    /** Flash area reading failed. */
    IMG_MGMT_ERR_FLASH_READ_FAILED,

    /** Flash area writing failed. */
    IMG_MGMT_ERR_FLASH_WRITE_FAILED,

    /** Flash area erase failed. */
    IMG_MGMT_ERR_FLASH_ERASE_FAILED,

    /** The provided slot is not valid. */
    IMG_MGMT_ERR_INVALID_SLOT,

    /** Insufficient heap memory (malloc failed). */
    IMG_MGMT_ERR_NO_FREE_MEMORY,

    /** The flash context is already set. */
    IMG_MGMT_ERR_FLASH_CONTEXT_ALREADY_SET,

    /** The flash context is not set. */
    IMG_MGMT_ERR_FLASH_CONTEXT_NOT_SET,

    /** The device for the flash area is NULL. */
    IMG_MGMT_ERR_FLASH_AREA_DEVICE_NULL,

    /** The offset for a page number is invalid. */
    IMG_MGMT_ERR_INVALID_PAGE_OFFSET,

    /** The offset parameter was not provided and is required. */
    IMG_MGMT_ERR_INVALID_OFFSET,

    /** The length parameter was not provided and is required. */
    IMG_MGMT_ERR_INVALID_LENGTH,

    /** The image length is smaller than the size of an image header. */
    IMG_MGMT_ERR_INVALID_IMAGE_HEADER,

    /** The image header magic value does not match the expected value. */
    IMG_MGMT_ERR_INVALID_IMAGE_HEADER_MAGIC,

    /** The hash parameter provided is not valid. */
    IMG_MGMT_ERR_INVALID_HASH,

    /** The image load address does not match the address of the flash area. */
    IMG_MGMT_ERR_INVALID_FLASH_ADDRESS,

    /** Failed to get version of currently running application. */
    IMG_MGMT_ERR_VERSION_GET_FAILED,

    /** The currently running application is newer than the version being uploaded. */
    IMG_MGMT_ERR_CURRENT_VERSION_IS_NEWER,

    /** There is already an image operating pending. */
    IMG_MGMT_ERR_IMAGE_ALREADY_PENDING,

    /** The image vector table is invalid. */
    IMG_MGMT_ERR_INVALID_IMAGE_VECTOR_TABLE,

    /** The image it too large to fit. */
    IMG_MGMT_ERR_INVALID_IMAGE_TOO_LARGE,

    /** The amount of data sent is larger than the provided image size. */
    IMG_MGMT_ERR_INVALID_IMAGE_DATA_OVERRUN,

    /** Confirmation of image has been denied */
    IMG_MGMT_ERR_IMAGE_CONFIRMATION_DENIED,

    /** Setting test to active slot is not allowed */
    IMG_MGMT_ERR_IMAGE_SETTING_TEST_TO_ACTIVE_DENIED,

    /** Current active slot for image cannot be determined */
    IMG_MGMT_ERR_ACTIVE_SLOT_NOT_KNOWN,
}

/// See `enum os_mgmt_err_code_t`.
#[derive(FromRepr, Display, Debug, Copy, Clone, PartialEq, Eq)]
#[repr(i32)]
#[allow(non_camel_case_types)]
pub enum OsMgmtErrCode {
    /** No error, this is implied if there is no ret value in the response */
    OS_MGMT_ERR_OK = 0,

    /** Unknown error occurred. */
    OS_MGMT_ERR_UNKNOWN,

    /** The provided format value is not valid. */
    OS_MGMT_ERR_INVALID_FORMAT,

    /** Query was not recognized. */
    OS_MGMT_ERR_QUERY_YIELDS_NO_ANSWER,

    /** RTC is not set */
    OS_MGMT_ERR_RTC_NOT_SET,

    /** RTC command failed */
    OS_MGMT_ERR_RTC_COMMAND_FAILED,

    /** Query was recognized but there is no valid value for the response. */
    OS_MGMT_ERR_QUERY_RESPONSE_VALUE_NOT_VALID,
}

/// See `enum shell_mgmt_err_code_t`.
#[derive(FromRepr, Display, Debug, Copy, Clone, PartialEq, Eq)]
#[repr(i32)]
#[allow(non_camel_case_types)]
pub enum ShellMgmtErrCode {
    /** No error, this is implied if there is no ret value in the response */
    SHELL_MGMT_ERR_OK = 0,

    /** Unknown error occurred. */
    SHELL_MGMT_ERR_UNKNOWN,

    /** The provided command to execute is too long. */
    SHELL_MGMT_ERR_COMMAND_TOO_LONG,

    /** No command to execute was provided. */
    SHELL_MGMT_ERR_EMPTY_COMMAND,
}

/// See `enum stat_mgmt_err_code_t`.
#[derive(FromRepr, Display, Debug, Copy, Clone, PartialEq, Eq)]
#[repr(i32)]
#[allow(non_camel_case_types)]
pub enum StatMgmtErrCode {
    /** No error, this is implied if there is no ret value in the response */
    STAT_MGMT_ERR_OK = 0,

    /** Unknown error occurred. */
    STAT_MGMT_ERR_UNKNOWN,

    /** The provided statistic group name was not found. */
    STAT_MGMT_ERR_INVALID_GROUP,

    /** The provided statistic name was not found. */
    STAT_MGMT_ERR_INVALID_STAT_NAME,

    /** The size of the statistic cannot be handled. */
    STAT_MGMT_ERR_INVALID_STAT_SIZE,

    /** Walk through of statistics was aborted. */
    STAT_MGMT_ERR_WALK_ABORTED,
}

/// See `enum enum_mgmt_err_code_t`.
#[derive(FromRepr, Display, Debug, Copy, Clone, PartialEq, Eq)]
#[repr(i32)]
#[allow(non_camel_case_types)]
pub enum EnumMgmtErrCode {
    /** No error, this is implied if there is no ret value in the response */
    ENUM_MGMT_ERR_OK = 0,

    /** Unknown error occurred. */
    ENUM_MGMT_ERR_UNKNOWN,

    /** Too many entries were provided. */
    ENUM_MGMT_ERR_TOO_MANY_GROUP_ENTRIES,

    /** Insufficient heap memory to store entry data. */
    ENUM_MGMT_ERR_INSUFFICIENT_HEAP_FOR_ENTRIES,

    /** Provided index is larger than the number of supported grouped. */
    ENUM_MGMT_ERR_INDEX_TOO_LARGE,
}

/// See `enum zephyr_basic_group_err_code_t`.
#[derive(FromRepr, Display, Debug, Copy, Clone, PartialEq, Eq)]
#[repr(i32)]
#[allow(non_camel_case_types)]
pub enum ZephyrBasicGroupErrCode {
    /** No error, this is implied if there is no ret value in the response */
    ZEPHYRBASIC_MGMT_ERR_OK = 0,

    /** Unknown error occurred. */
    ZEPHYRBASIC_MGMT_ERR_UNKNOWN,

    /** Opening of the flash area has failed. */
    ZEPHYRBASIC_MGMT_ERR_FLASH_OPEN_FAILED,

    /** Querying the flash area parameters has failed. */
    ZEPHYRBASIC_MGMT_ERR_FLASH_CONFIG_QUERY_FAIL,

    /** Erasing the flash area has failed. */
    ZEPHYRBASIC_MGMT_ERR_FLASH_ERASE_FAILED,
}