1.. _mcumgr_smp_group_1:
2
3Application/software image management group
4###########################################
5
6Application/software image management group defines following commands:
7
8.. table::
9    :align: center
10
11    +-------------------+-----------------------------------------------+
12    | ``Command ID``    | Command description                           |
13    +===================+===============================================+
14    | ``0``             | State of images                               |
15    +-------------------+-----------------------------------------------+
16    | ``1``             | Image upload                                  |
17    +-------------------+-----------------------------------------------+
18    | ``2``             | File                                          |
19    |                   | (reserved but not supported by Zephyr)        |
20    +-------------------+-----------------------------------------------+
21    | ``3``             | Corelist                                      |
22    |                   | (reserved but not supported by Zephyr)        |
23    +-------------------+-----------------------------------------------+
24    | ``4``             | Coreload                                      |
25    |                   | (reserved but not supported by Zephyr)        |
26    +-------------------+-----------------------------------------------+
27    | ``5``             | Image erase                                   |
28    +-------------------+-----------------------------------------------+
29
30Notion of "slots" and "images" in Zephyr
31****************************************
32
33The "slot" and "image" definition comes from mcuboot where "image" would
34consist of two "slots", further named "primary" and "secondary"; the application
35is supposed to run from the "primary slot" and update is supposed to be
36uploaded to the "secondary slot";  the mcuboot is responsible in swapping
37slots on boot.
38This means that pair of slots is dedicated to single upgradable application.
39In case of Zephyr this gets a little bit confusing because DTS will use
40"slot0_partition" and "slot1_partition", as label of ``fixed-partition`` dedicated
41to single application, but will name them as "image-0" and "image-1" respectively.
42
43Currently Zephyr supports at most two images, in which case mapping is as follows:
44
45.. table::
46    :align: center
47
48    +-------------+-------------------+---------------+
49    | Image       | Slot labels       | Slot  Names   |
50    +=============+===================+===============+
51    | 1           | "slot0_partition" |   "image-0"   |
52    |             | "slot1_partition" |   "image-1"   |
53    +-------------+-------------------+---------------+
54    | 2           | "slot2_partition" |   "image-2"   |
55    |             | "slot3_partition" |   "image-3"   |
56    +-------------+-------------------+---------------+
57
58State of images
59***************
60
61The command is used to set state of images and obtain list of images
62with their current state.
63
64Get state of images request
65===========================
66
67Get state of images request header fields:
68
69.. table::
70    :align: center
71
72    +--------+--------------+----------------+
73    | ``OP`` | ``Group ID`` | ``Command ID`` |
74    +========+==============+================+
75    | ``0``  | ``1``        |  ``0``         |
76    +--------+--------------+----------------+
77
78The command sends an empty CBOR map as data.
79
80.. _mcumgr_smp_protocol_op_1_grp_1_cmd_0:
81
82Get state of images response
83============================
84
85Get state of images response header fields:
86
87.. table::
88    :align: center
89
90    +--------+--------------+----------------+
91    | ``OP`` | ``Group ID`` | ``Command ID`` |
92    +========+==============+================+
93    | ``1``  | ``1``        |  ``0``         |
94    +--------+--------------+----------------+
95
96.. note::
97    Below definition of the response contains "image" field that has been marked
98    as optional(opt): the field may not appear in response when target application
99    does not support more than one image. The field is mandatory when application
100    supports more than one application image to allow identifying which image
101    information is listed.
102
103A response will only contain information for valid images, if an image can not
104be identified as valid it is simply skipped.
105
106CBOR data of successful response:
107
108.. code-block:: none
109
110    {
111        (str)"images" : [
112            {
113                (str,opt)"image"        : (uint)
114                (str)"slot"             : (uint)
115                (str)"version"          : (str)
116                (str,opt*)"hash"        : (byte str)
117                (str,opt)"bootable"     : (bool)
118                (str,opt)"pending"      : (bool)
119                (str,opt)"confirmed"    : (bool)
120                (str,opt)"active"       : (bool)
121                (str,opt)"permanent"    : (bool)
122            }
123            ...
124        ]
125        (str,opt)"splitStatus" : (int)
126    }
127
128In case of error the CBOR data takes the form:
129
130.. tabs::
131
132   .. group-tab:: SMP version 2
133
134      .. code-block:: none
135
136          {
137              (str)"err" : {
138                  (str)"group"    : (uint)
139                  (str)"rc"       : (uint)
140              }
141          }
142
143   .. group-tab:: SMP version 1 (and non-group SMP version 2)
144
145      .. code-block:: none
146
147          {
148              (str)"rc"       : (int)
149              (str,opt)"rsn"  : (str)
150          }
151
152where:
153
154.. table::
155    :align: center
156
157    +------------------+-------------------------------------------------------------------------+
158    | "image"          | semi-optional image number; the field is not required when only one     |
159    |                  | image is supported by the running application.                          |
160    +------------------+-------------------------------------------------------------------------+
161    | "slot"           | slot number within "image"; each image has two slots : primary (running |
162    |                  | one) = 0 and secondary (for DFU dual-bank purposes) = 1.                |
163    +------------------+-------------------------------------------------------------------------+
164    | "version"        | string representing image version, as set with ``imgtool``.             |
165    +------------------+-------------------------------------------------------------------------+
166    | "hash"           | SHA256 hash of the image header and body. Note that this will not be    |
167    |                  | the same as the SHA256 of the whole file, it is the field in the        |
168    |                  | MCUboot TLV section that contains a hash of the data which is used for  |
169    |                  | signature verification purposes. This field is optional but only        |
170    |                  | optional when using MCUboot's serial recovery feature with one pair of  |
171    |                  | image slots, Kconfig :kconfig:option:`CONFIG_BOOT_SERIAL_IMG_GRP_HASH`  |
172    |                  | can be disabled to remove support for hashes in this configuration.     |
173    |                  | MCUmgr in applications must support sending hashes.                     |
174    |                  |                                                                         |
175    |                  | .. note::                                                               |
176    |                  |    See ``IMAGE_TLV_SHA256`` in the MCUboot image format documentation   |
177    |                  |    link below.                                                          |
178    +------------------+-------------------------------------------------------------------------+
179    | "bootable"       | true if image has bootable flag set; this field does not have to be     |
180    |                  | present if false.                                                       |
181    +------------------+-------------------------------------------------------------------------+
182    | "pending"        | true if image is set for next swap; this field does not have to be      |
183    |                  | present if false.                                                       |
184    +------------------+-------------------------------------------------------------------------+
185    | "confirmed"      | true if image has been confirmed; this field does not have to be        |
186    |                  | present if false.                                                       |
187    +------------------+-------------------------------------------------------------------------+
188    | "active"         | true if image is currently active application; this field does not have |
189    |                  | to be present if false.                                                 |
190    +------------------+-------------------------------------------------------------------------+
191    | "permanent"      | true if image is to stay in primary slot after the next boot; this      |
192    |                  | does not have to be present if false.                                   |
193    +------------------+-------------------------------------------------------------------------+
194    | "splitStatus"    | states whether loader of split image is compatible with application     |
195    |                  | part; this is unused by Zephyr.                                         |
196    +------------------+-------------------------------------------------------------------------+
197    | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only      |
198    |                  | appears if an error is returned when using SMP version 2.               |
199    +------------------+-------------------------------------------------------------------------+
200    | "err" -> "rc"    | contains the index of the group-based error code. Only appears if       |
201    |                  | non-zero (error condition) when using SMP version 2.                    |
202    +------------------+-------------------------------------------------------------------------+
203    | "rc"             | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when  |
204    |                  | using SMP version 1 or for SMP errors when using SMP version 2.         |
205    +------------------+-------------------------------------------------------------------------+
206    | "rsn"            | optional string that clarifies reason for an error; specifically useful |
207    |                  | when ``rc`` is :c:enumerator:`MGMT_ERR_EUNKNOWN`.                       |
208    +------------------+-------------------------------------------------------------------------+
209
210.. note::
211    For more information on how does image/slots function, please refer to
212    the MCUBoot documentation
213    https://docs.mcuboot.com/design.html#image-slots
214    For information on MCUboot image format, please reset to the MCUboot
215    documentation https://docs.mcuboot.com/design.html#image-format
216
217
218Set state of image request
219==========================
220
221Set state of image request header fields:
222
223.. table::
224    :align: center
225
226    +--------+--------------+----------------+
227    | ``OP`` | ``Group ID`` | ``Command ID`` |
228    +========+==============+================+
229    | ``2``  | ``1``        |  ``0``         |
230    +--------+--------------+----------------+
231
232CBOR data of request:
233
234.. code-block:: none
235
236    {
237        (str,opt)"hash"     : (str)
238        (str)"confirm"      : (bool)
239    }
240
241If "confirm" is false or not provided, an image with the "hash" will be set for
242test, which means that it will not be marked as permanent and upon hard reset
243the previous application will be restored to the primary slot.
244In case when "confirm" is true, the "hash" is optional as the currently running
245application will be assumed as target for confirmation.
246
247Set state of image response
248============================
249
250The response takes the same format as :ref:`mcumgr_smp_protocol_op_1_grp_1_cmd_0`
251
252Image upload
253************
254
255The image upload command allows to update application image.
256
257Image upload request
258====================
259
260The image upload request is sent for each chunk of image that is uploaded, until
261complete image gets uploaded to a device.
262
263Image upload request header fields:
264
265.. table::
266    :align: center
267
268    +--------+--------------+----------------+
269    | ``OP`` | ``Group ID`` | ``Command ID`` |
270    +========+==============+================+
271    | ``2``  | ``1``        |  ``1``         |
272    +--------+--------------+----------------+
273
274CBOR data of request:
275
276.. code-block:: none
277
278    {
279        (str,opt)"image"    : (uint)
280        (str,opt)"len"      : (uint)
281        (str)"off"          : (uint)
282        (str,opt)"sha"      : (byte str)
283        (str)"data"         : (byte str)
284        (str,opt)"upgrade"  : (bool)
285    }
286
287where:
288
289.. table::
290    :align: center
291
292    +-----------+--------------------------------------------------------------------------------+
293    | "image"   | optional image number, it does not have to appear in request at all, in which  |
294    |           | case it is assumed to be 0. Should only be present when "off" is 0.            |
295    +-----------+--------------------------------------------------------------------------------+
296    | "len"     | optional length of an image. Must appear when "off" is 0.                      |
297    +-----------+--------------------------------------------------------------------------------+
298    | "off"     | offset of image chunk the request carries.                                     |
299    +-----------+--------------------------------------------------------------------------------+
300    | "sha"     | SHA256 hash of an upload; this is used to identify an upload session (e.g. to  |
301    |           | allow MCUmgr to continue a broken session), and for image verification         |
302    |           | purposes. This must be a full SHA256 hash of the whole image being uploaded,   |
303    |           | or not included if the hash is not available (in which  case, upload session   |
304    |           | continuation and image verification functionality will be unavailable). Should |
305    |           | only be present when "off" is 0.                                               |
306    +-----------+--------------------------------------------------------------------------------+
307    | "data"    | image data to write at provided offset.                                        |
308    +-----------+--------------------------------------------------------------------------------+
309    | "upgrade" | optional flag that states that only upgrade should be allowed, so if the       |
310    |           | version of uploaded software is not higher then already on a device, the image |
311    |           | upload will be rejected. Zephyr compares major, minor and revision (x.y.z) by  |
312    |           | default unless                                                                 |
313    |           | :kconfig:option:`CONFIG_MCUMGR_GRP_IMG_VERSION_CMP_USE_BUILD_NUMBER` is set,   |
314    |           | whereby it will compare build numbers too. Should only be present when "off"   |
315    |           | is 0.                                                                          |
316    +-----------+--------------------------------------------------------------------------------+
317
318.. note::
319    There is no field representing size of chunk that is carried as "data" because
320    that information is embedded within "data" field itself.
321
322.. note::
323    It is possible that a server will respond to an upload with "off" of 0, this
324    may happen if an upload on another transport (or outside of MCUmgr entirely)
325    is started, if the device has rebooted or if a packet has been lost. If this
326    happens, a client must re-send all the required and optional fields that it
327    sent in the original first packet so that the upload state can be re-created
328    by the server. If the original fields are not included, the upload will be
329    unable to continue.
330
331The MCUmgr library uses "sha" field to tag ongoing update session, to be able
332to continue it in case when it gets broken, and for upload verification
333purposes.
334If library gets request with "off" equal zero it checks stored "sha" within its
335state and if it matches it will respond to update client application with
336offset that it should continue with.
337If this hash is not available (e.g. because a file is being streamed) then it
338must not be provided, image verification and upload session continuation
339features will be unavailable in this case.
340
341Image upload response
342=====================
343
344Image upload response header fields:
345
346.. table::
347    :align: center
348
349    +--------+--------------+----------------+
350    | ``OP`` | ``Group ID`` | ``Command ID`` |
351    +========+==============+================+
352    | ``3``  | ``1``        |  ``1``         |
353    +--------+--------------+----------------+
354
355CBOR data of successful response:
356
357.. code-block:: none
358
359    {
360        (str,opt)"off"    : (uint)
361        (str,opt)"match"  : (bool)
362    }
363
364In case of error the CBOR data takes the form:
365
366.. tabs::
367
368   .. group-tab:: SMP version 2
369
370      .. code-block:: none
371
372          {
373              (str)"err" : {
374                  (str)"group"    : (uint)
375                  (str)"rc"       : (uint)
376              }
377          }
378
379   .. group-tab:: SMP version 1 (and non-group SMP version 2)
380
381      .. code-block:: none
382
383          {
384              (str)"rc"       : (int)
385              (str,opt)"rsn"  : (str)
386          }
387
388where:
389
390.. table::
391    :align: center
392
393    +------------------+-------------------------------------------------------------------------+
394    | "off"            | offset of last successfully written byte of update.                     |
395    +------------------+-------------------------------------------------------------------------+
396    | "match"          | indicates if the uploaded data successfully matches the provided SHA256 |
397    |                  | hash or not, only sent in the final packet if                           |
398    |                  | :kconfig:option:`CONFIG_IMG_ENABLE_IMAGE_CHECK` is enabled.             |
399    +------------------+-------------------------------------------------------------------------+
400    | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only      |
401    |                  | appears if an error is returned when using SMP version 2.               |
402    +------------------+-------------------------------------------------------------------------+
403    | "err" -> "rc"    | contains the index of the group-based error code. Only appears if       |
404    |                  | non-zero (error condition) when using SMP version 2.                    |
405    +------------------+-------------------------------------------------------------------------+
406    | "rc"             | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when  |
407    |                  | using SMP version 1 or for SMP errors when using SMP version 2.         |
408    +------------------+-------------------------------------------------------------------------+
409    | "rsn"            | optional string that clarifies reason for an error; specifically useful |
410    |                  | when ``rc`` is :c:enumerator:`MGMT_ERR_EUNKNOWN`.                       |
411    +------------------+-------------------------------------------------------------------------+
412
413The "off" field is only included in responses to successfully processed requests;
414if "rc" is negative then "off" may not appear.
415
416Image erase
417***********
418
419The command is used for erasing image slot on a target device.
420
421.. note::
422    This is synchronous command which means that a sender of request will not
423    receive response until the command completes, which can take a long time.
424
425Image erase request
426===================
427
428Image erase request header fields:
429
430.. table::
431    :align: center
432
433    +--------+--------------+----------------+
434    | ``OP`` | ``Group ID`` | ``Command ID`` |
435    +========+==============+================+
436    | ``2``  | ``1``        |  ``5``         |
437    +--------+--------------+----------------+
438
439CBOR data of request:
440
441.. code-block:: none
442
443    {
444        (str,opt)"slot"     : (uint)
445    }
446
447where:
448
449.. table::
450    :align: center
451
452    +---------+-----------------------------------------------------------------+
453    | "slot"  | optional slot number, it does not have to appear in the request |
454    |         | at all, in which case it is assumed to be 1.                    |
455    +---------+-----------------------------------------------------------------+
456
457Image erase response
458====================
459
460Image erase response header fields:
461
462.. table::
463    :align: center
464
465    +--------+--------------+----------------+
466    | ``OP`` | ``Group ID`` | ``Command ID`` |
467    +========+==============+================+
468    | ``3``  | ``1``        |  ``5``         |
469    +--------+--------------+----------------+
470
471The command sends an empty CBOR map as data if successful. In case of error the
472CBOR data takes the form:
473
474.. tabs::
475
476   .. group-tab:: SMP version 2
477
478      .. code-block:: none
479
480          {
481              (str)"err" : {
482                  (str)"group"    : (uint)
483                  (str)"rc"       : (uint)
484              }
485          }
486
487   .. group-tab:: SMP version 1 (and non-group SMP version 2)
488
489      .. code-block:: none
490
491          {
492              (str)"rc"       : (int)
493              (str,opt)"rsn"  : (str)
494          }
495
496where:
497
498.. table::
499    :align: center
500
501    +------------------+-------------------------------------------------------------------------+
502    | "err" -> "group" | :c:enum:`mcumgr_group_t` group of the group-based error code. Only      |
503    |                  | appears if an error is returned when using SMP version 2.               |
504    +------------------+-------------------------------------------------------------------------+
505    | "err" -> "rc"    | contains the index of the group-based error code. Only appears if       |
506    |                  | non-zero (error condition) when using SMP version 2.                    |
507    +------------------+-------------------------------------------------------------------------+
508    | "rc"             | :c:enum:`mcumgr_err_t` only appears if non-zero (error condition) when  |
509    |                  | using SMP version 1 or for SMP errors when using SMP version 2.         |
510    +------------------+-------------------------------------------------------------------------+
511    | "rsn"            | optional string that clarifies reason for an error; specifically useful |
512    |                  | when ``rc`` is :c:enumerator:`MGMT_ERR_EUNKNOWN`.                       |
513    +------------------+-------------------------------------------------------------------------+
514
515.. note::
516    Response from Zephyr running device may have "rc" value of
517    :c:enumerator:`MGMT_ERR_EBADSTATE`, which means that the secondary
518    image has been marked for next boot already and may not be erased.
519