doc/guides/device_mgmt: SMP protocol documentation

The commit adds guide that describes format of SMP reqests/responses
as issued by Zephyr implementation within mcumgr.

Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
This commit is contained in:
Dominik Ermel 2021-11-25 15:19:37 +00:00 committed by Carles Cufí
parent f96ee77c7c
commit 92109e1f62
8 changed files with 1628 additions and 0 deletions

View File

@ -188,6 +188,8 @@
/CMakeLists.txt @tejlmand @nashif
/doc/ @dbkinder
/doc/guides/coccinelle.rst @himanshujha199640 @JuliaLawall
/doc/guides/device_mgmt/smp_protocol.rst @de-nordic
/doc/guides/device_mgmt/smp_groups/ @de-nordic
/doc/CMakeLists.txt @carlescufi
/doc/_scripts/ @carlescufi
/doc/guides/bluetooth/ @alwa-nordic @jhedberg @Vudentz

View File

@ -8,5 +8,6 @@ Device Management
mcumgr.rst
mcumgr_backporting.rst
smp_protocol.rst
dfu.rst
ota.rst

View File

@ -0,0 +1,458 @@
.. _mcumgr_smp_group_0:
Default/OS Management Group
###########################
OS management group defines following commands:
.. table::
:align: center
+-------------------+-----------------------------------------------+
| ``Command ID`` | Command description |
+===================+===============================================+
| ``0`` | Echo |
+-------------------+-----------------------------------------------+
| ``1`` | Console/Terminal echo control; |
| | unimplemented by Zephyr |
+-------------------+-----------------------------------------------+
| ``2`` | Statistics |
+-------------------+-----------------------------------------------+
| ``3`` | Memory pool statistics |
+-------------------+-----------------------------------------------+
| ``4`` | Date-time string; unimplemented by Zephyr |
+-------------------+-----------------------------------------------+
| ``5`` | System reset |
+-------------------+-----------------------------------------------+
Echo command
************
Echo command responses by sending back string that it has received.
Echo request
============
Echo request header fields:
.. table::
:align: center
+--------------------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+====================+==============+================+
| ``0`` or ``2`` | ``0`` | ``0`` |
+--------------------+--------------+----------------+
CBOR data of request:
.. code-block:: none
{
(str)"d" : (str)
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| "d" | string to be replied by echo service |
+-----------------------+---------------------------------------------------+
Echo response
=============
Echo response header fields:
.. table::
:align: center
+--------+--------------+----------------+----------------------------------+
| ``OP`` | ``Group ID`` | ``Command ID`` | Note |
+========+==============+================+==================================+
| ``1`` | ``0`` | ``0`` | When request ``OP`` was ``0`` |
+--------+--------------+----------------+----------------------------------+
| ``3`` | ``0`` | ``0`` | When request ``OP`` was ``2`` |
+--------+--------------+----------------+----------------------------------+
CBOR data of successful response:
.. code-block:: none
{
(str)"r" : (str)
}
In case of error the CBOR data takes form:
.. code-block:: none
{
(str)"rc" : (int)
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| "r" | Replying echo string |
+-----------------------+---------------------------------------------------+
| "rc" | :ref:`mcumgr_smp_protocol_status_codes` |
+-----------------------+---------------------------------------------------+
Task statistics command
***********************
The command responds with some system statistics.
Task statistics request
=======================
Task statistics request header fields:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``0`` | ``0`` | ``2`` |
+--------+--------------+----------------+
The command sends empty CBOR map as data.
Task statistics response
========================
Task statistics response header fields:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``1`` | ``0`` | ``2`` |
+--------+--------------+----------------+
CBOR data of response:
.. code-block:: none
{
(str)"tasks" : {
(str)<task_name> : {
(str)"prio" : (uint)
(str)"tid" : (uint)
(str)"state" : (uint)
(str)"stkuse" : (uint)
(str)"stksiz" : (uint)
(str)"cswcnt" : (uint)
(str)"runtime" : (uint)
(str)"last_checkin" : (uint)
(str)"next_checkin" : (uint)
}
...
}
(str)"rc" : (int)
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| <task_name> | string identifying task |
+-----------------------+---------------------------------------------------+
| "prio" | task priority |
+-----------------------+---------------------------------------------------+
| "tid" | numeric task ID |
+-----------------------+---------------------------------------------------+
| "state" | numeric task state |
+-----------------------+---------------------------------------------------+
| "stkuse" | task's/thread's stack usage |
+-----------------------+---------------------------------------------------+
| "stksiz" | task's/thread's stack size |
+-----------------------+---------------------------------------------------+
| "cswcnt" | task's/thread's context switches |
+-----------------------+---------------------------------------------------+
| "runtime" | task's/thread's runtime in "ticks" |
+-----------------------+---------------------------------------------------+
| "last_checkin" | set to 0 by Zephyr |
+-----------------------+---------------------------------------------------+
| "next_checkin" | set to 0 by Zephyr |
+-----------------------+---------------------------------------------------+
| "rc" | :ref:`mcumgr_smp_protocol_status_codes` |
+-----------------------+---------------------------------------------------+
.. note::
The unit for "stkuse" and "stksiz" is system dependent and in case of Zephyr
this is number of 4 byte words.
Memory pool statistics
**********************
The command is used to obtain information on memory pools active in running
system.
Memory pool statistic request
=============================
Memory pool statistics request header fields:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``0`` | ``0`` | ``3`` |
+--------+--------------+----------------+
The command sends empty CBOR map as data.
Memory pool statistics response
===============================
Memory pool statistics response header fields:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``1`` | ``0`` | ``3`` |
+--------+--------------+----------------+
CBOR data of response:
.. code-block:: none
{
(str)<pool_name> {
(str)"blksiz" : (int)
(str)"nblks" : (int)
(str)"nfree" : (int)
(str)"min' : (int)
}
...
(str)"rc" : (int)
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| <pool_name> | string representing the pool name, used as a key |
| | for dictionary with pool statistics data |
+-----------------------+---------------------------------------------------+
| "blksiz" | size of the memory block in the pool |
+-----------------------+---------------------------------------------------+
| "nblks" | number of blocks in the pool |
+-----------------------+---------------------------------------------------+
| "nrfree" | number of free blocks |
+-----------------------+---------------------------------------------------+
| "min" | lowest number of free blocks the pool reached |
| | during run-time |
+-----------------------+---------------------------------------------------+
| "rc" | :ref:`mcumgr_smp_protocol_status_codes` |
+-----------------------+---------------------------------------------------+
Date-time command
*****************
The command allows to obtain string representing current time-date on a device
or set a new time to a device.
The time format used, by both set and get operations, is:
"yyyy-MM-dd'T'HH:mm:ss.SSSSSSZZZZZ"
Date-time get
=============
The command allows to obtain date-time from a device.
Date-time get request
---------------------
Date-time request header fields:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``0`` | ``0`` | ``4`` |
+--------+--------------+----------------+
The command sends empty CBOR map as data.
Data-time get response
----------------------
Date-time get response header fields:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``1`` | ``0`` | ``4`` |
+--------+--------------+----------------+
CBOR data of response:
.. code-block:: none
{
(str)"datetime" : (str)
(opt,str)"rc" : (int)
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| "datetime" | String in format |
| | yyyy-MM-dd'T'HH:mm:ss.SSSSSSZZZZZ |
+-----------------------+---------------------------------------------------+
| "rc" | :ref:`mcumgr_smp_protocol_status_codes`; |
| | may not appear if 0 |
+-----------------------+---------------------------------------------------+
Date-time set
=============
The command allows to set date-time to a device.
Date-time set request
---------------------
Date-time set request header fields:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``2`` | ``0`` | ``4`` |
+--------+--------------+----------------+
CBOR data of response:
.. code-block:: none
{
(str)"datetime" : (str)
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| "datetime" | String in format |
| | yyyy-MM-dd'T'HH:mm:ss.SSSSSSZZZZZ |
+-----------------------+---------------------------------------------------+
Data-time set response
----------------------
Date-time set response header fields:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``1`` | ``0`` | ``4`` |
+--------+--------------+----------------+
CBOR data of response:
.. code-block:: none
{
(str)"rc" : (int)
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| "rc" | :ref:`mcumgr_smp_protocol_status_codes` |
+-----------------------+---------------------------------------------------+
System reset
************
Performs reset of system. The device should issue response before resetting so that
the SMP client could receive information that the command has been accepted.
System reset request
====================
System reset request header fields:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``2`` | ``0`` | ``5`` |
+--------+--------------+----------------+
The command sends empty CBOR map as data.
System reset response
=====================
System reset response header fields
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``3`` | ``0`` | ``5`` |
+--------+--------------+----------------+
CBOR data of response:
.. code-block:: none
{
(opt,str)"rc" : (int)
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| "rc" | :ref:`mcumgr_smp_protocol_status_codes`; |
| | may not appear if 0 |
+-----------------------+---------------------------------------------------+

View File

@ -0,0 +1,419 @@
.. _mcumgr_smp_group_1:
Application/software image management group
###########################################
Application/software image management management group defines following commands:
.. table::
:align: center
+-------------------+-----------------------------------------------+
| ``Command ID`` | Command description |
+===================+===============================================+
| ``0`` | State of images |
+-------------------+-----------------------------------------------+
| ``1`` | Image upload |
+-------------------+-----------------------------------------------+
| ``2`` | File |
| | (reserved but not supported by Zephyr) |
+-------------------+-----------------------------------------------+
| ``3`` | Corelist |
| | (reserved but not supported by Zephyr) |
+-------------------+-----------------------------------------------+
| ``4`` | Coreload |
| | (reserved but not supported by Zephyr) |
+-------------------+-----------------------------------------------+
| ``5`` | Image erase |
+-------------------+-----------------------------------------------+
Notion of "slots" and "images" in Zephyr
****************************************
The "slot" and "image" definition comes from mcuboot where "image" would
consist of two "slots", further named "primary" and "secondary"; the application
is supposed to run from the "primary slot" and update is supposed to be
uploaded to the "secondary slot"; the mcuboot is responsible in swapping
slots on boot.
This means that pair of slots is dedicated to single upgradable application.
In case of Zephyr this gets a little bit confusing because DTS will use
"slot0_partition" and "slot1_partition", as label of ``fixed-partition`` dedicated
to single application, but will name them as "image-0" and "image-1" respectively.
Currently Zephyr supports at most two images, in which case mapping is as follows:
.. table::
:align: center
+-------------+-------------------+---------------+
| Image | Slot labels | Slot Names |
+=============+===================+===============+
| 1 | "slot0_partition" | "image-0" |
| | "slot1_partition" | "image-1" |
+-------------+-------------------+---------------+
| 2 | "slot2_partition" | "image-2" |
| | "slot3_partition" | "image-3" |
+-------------+-------------------+---------------+
State of images
***************
The command is used to set state of images and obtain list of images
with their current state.
Get state of images request
===========================
Get state of images request header fields:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``0`` | ``1`` | ``0`` |
+--------+--------------+----------------+
The command sends sends empty CBOR map as data.
.. _mcumgr_smp_protocol_op_1_grp_1_cmd_0:
Get state of images response
============================
Get state of images response header fields:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``1`` | ``1`` | ``0`` |
+--------+--------------+----------------+
.. note::
Below definition of the response contains "image" field that has been marked
as optional(opt): the field may not appear in response when target application
does not support more than one image. The field is mandatory when application
supports more than one application image to allow identifying which image
information is listed.
A response will only contain information for valid images, if an image can not
be identified as valid it is simply skipped.
CBOR data of successful response:
.. code-block:: none
{
(str)"images" : [
{
(str,opt)"image" : (int)
(str)"slot" : (int)
(str)"version" : (str)
(str)"hash" ; (str)
(str,opt)"bootable" : (bool)
(str,opt)"pending" : (bool)
(str,opt)"confirmed" : (bool)
(str,opt)"active" : (bool)
(str,opt)"permanent" : (bool)
}
...
]
(str,opt)"splitStatus" : (int)
}
In case of error the CBOR data takes form:
.. code-block:: none
{
(str)"rc" : (int)
(str,opt)"rsn" : (str)
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| "image" | semi-optional image number; the field is not |
| | required when only one image is supported by |
| | running application |
+-----------------------+---------------------------------------------------+
| "slot" | slot number within "image"; each image has two |
| | slots : primary (running one) = 0 and secondary |
| | (for DFU dual-bank purposes) = 1 |
+-----------------------+---------------------------------------------------+
| "version" | string representing image version, as set with |
| | ``imgtool`` |
+-----------------------+---------------------------------------------------+
| "hash" | hash of an upload; this is used to identify |
| | an upload session, for example to allow mcumgr |
| | library to continue broken session |
| | |
| | .. note:: |
| | By default mcumgr-cli uses here a few |
| | characters of sha256 of the first uploaded |
| | chunk. |
+-----------------------+---------------------------------------------------+
| "bootable" | true if image has bootable flag set; |
| | this field does not have to be present if false |
+-----------------------+---------------------------------------------------+
| "pending" | true if image is set for next swap |
| | this field does not have to be present if false |
+-----------------------+---------------------------------------------------+
| "confirmed" | true if image has been confirmed |
| | this field does not have to be present if false |
+-----------------------+---------------------------------------------------+
| "active" | true if image is currently active application |
| | this field does not have to be present if false |
+-----------------------+---------------------------------------------------+
| "permanent" | true if image is to stay in primary slot after |
| | next boot |
| | this field does not have to be present if false |
+-----------------------+---------------------------------------------------+
| "splitStatus" | states whether loader of split image is compatible|
| | with application part; this is unused by Zephyr |
+-----------------------+---------------------------------------------------+
| "rc" | :ref:`mcumgr_smp_protocol_status_codes` |
+-----------------------+---------------------------------------------------+
| "rsn" | optional string that clarifies reason for an |
| | error; specifically useful for error code ``1``, |
| | unknown error |
+-----------------------+---------------------------------------------------+
.. note::
For more information on how does image/slots function, please refer to
the MCUBoot documentation
https://www.mcuboot.com/documentation/design/#image-slots
Set state of image request
==========================
Set state of image request header fields:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``2`` | ``1`` | ``0`` |
+--------+--------------+----------------+
CBOR data of request:
.. code-block:: none
{
{
(str,opt)"hash" : (str)
(str)"confirm" : (bool)
}
}
If "confirm" is false an image with the "hash" will be set for test, which means
that it will not be marked as permanent and upon hard reset the previous
application will be restored to the primary slot.
In case when "confirm" is true, the "hash" is optional as the currently running
application will be assumed as target for confirmation.
Set state of image response
============================
The response takes the same format as :ref:`mcumgr_smp_protocol_op_1_grp_1_cmd_0`
Image upload
************
The image upload command allows to update application image.
Image upload request
====================
The image upload request is sent for each chunk of image that is uploaded, until
complete image gets uploaded to a device.
Set state of image request header fields:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``2`` | ``1`` | ``1`` |
+--------+--------------+----------------+
CBOR data of request:
.. code-block:: none
{
{
(str,opt)"image" : (uint)
(str,opt)"len" : (uint)
(str)"off" : (uint)
(str,opt)"sha" : (str)
(str,opt)"data" : (byte str)
(str,opt)"upgrade" : (bool)
}
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| "image" | optional image number, it does not have to appear |
| | in request at all, in which case it is assumed to |
| | be 0; only request with "off" 0 can contain |
| | image number |
+-----------------------+---------------------------------------------------+
| "len" | optional length of an image, it only appears in |
| | the first packet of request, where "off" is 0 |
+-----------------------+---------------------------------------------------+
| "off" | offset of image chunk the request carries |
+-----------------------+---------------------------------------------------+
| "sha" | string identifying update session; it should only |
| | be present if "off" is zero; although name |
| | suggests it might be SHA, it can actually be any |
| | string |
+-----------------------+---------------------------------------------------+
| "data" | optional image data |
+-----------------------+---------------------------------------------------+
| "upgrade" | optional flag that states that only upgrade |
| | should be allowed, so if version of uploaded |
| | software is lower then already on device, the |
| | image update should be rejected |
| | (unused by Zephyr at this time) |
+-----------------------+---------------------------------------------------+
.. note::
There is no field representing size of chunk that is carried as "data" because
that information is embedded within "data" field itself.
The mcumgr library uses "sha" field to tag ongoing update session, to be able
to continue it in case when it gets broken.
If library gets request with "off" equal zero it checks stored "sha" within its
state and if it matches it will respond to update client application with
offset that it should continue with.
Image upload response
=====================
Set state of image request header fields:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``3`` | ``1`` | ``1`` |
+--------+--------------+----------------+
CBOR data of response:
.. code-block:: none
{
(str,opt)"off" : (uint)
(str)"rc" : (int)
(str,opt)"rsn" : (str)
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| "off" | offset of last successfully written byte of update|
+-----------------------+---------------------------------------------------+
| "rc" | :ref:`mcumgr_smp_protocol_status_codes` |
+-----------------------+---------------------------------------------------+
| "rsn" | Optional string that clarifies reason for an |
| | error; specifically useful for error code ``1``, |
| | unknown error |
+-----------------------+---------------------------------------------------+
The "off" field is only included in responses to successfully processed requests;
if "rc" is negative the "off' may not appear.
Image erase
***********
The command is used for erasing image slot on a target device.
.. note::
Currently Zephyr version of mcumgr is hardcoded to always erase secondary slot
of the first image.
.. note::
This is synchronous command which means that a sender of request will not
receive response until the command completes.
Image erase request
===================
Image erase request header fields:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``2`` | ``1`` | ``5`` |
+--------+--------------+----------------+
The command sends sends empty CBOR map as data.
Image erase response
====================
Image erase response header fields:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``3`` | ``1`` | ``5`` |
+--------+--------------+----------------+
CBOR data of response:
.. code-block:: none
{
(str)"rc" : (int)
(str,opt)"rsn" : (str)
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| "rc" | :ref:`mcumgr_smp_protocol_status_codes` |
+-----------------------+---------------------------------------------------+
| "rsn" | Optional string that clarifies reason for an |
| | error; specifically useful for error code ``1``, |
| | unknown error |
+-----------------------+---------------------------------------------------+
.. note::
Response from Zephyr running device may have "rc" value of 6, bad state
(:ref:`mcumgr_smp_protocol_status_codes`), which means that the secondary
image has been marked for next boot already and may not be erased.

View File

@ -0,0 +1,170 @@
.. _mcumgr_smp_group_2:
Statistics management
#####################
Statistics management allows to obtain data gathered by Statistics subsystem
of Zephyr, enabled by ``CONFIG_STATS``.
Statistics management group defines commands:
.. table::
:align: center
+-------------------+-----------------------------------------------+
| ``Command ID`` | Command description |
+===================+===============================================+
| ``0`` | Group data |
+-------------------+-----------------------------------------------+
| ``1`` | List groups |
+-------------------+-----------------------------------------------+
Statistics: group data
**********************
The command is used to obtain data for group specified by a name.
The name is one of group names as registered, with ``STATS_INIT_AND_REG`` macro
or ``stats_init_and_reg(...)`` function call, within module that gathers
the statistics.
Statistics: group data request
==============================
Statistics group data request header:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``0`` | ``2`` | ``0`` |
+--------+--------------+----------------+
CBOR Payload of request:
.. code-block:: none
{
(str)"name" : (str)
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| "name" | is group name |
+-----------------------+---------------------------------------------------+
Statistics: group data response
===============================
Statistics group data response header:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``1`` | ``2`` | ``0`` |
+--------+--------------+----------------+
CBOR Payload of response:
.. code-block:: none
{
(str)"name" : (str)
(str)"fields" : {
(str)<entry_name> : (uint)
...
}
(str)"rc" : (int)
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| "name" | this is name of group the response contains data |
| | for |
+-----------------------+---------------------------------------------------+
| "fields" | this is map of entries within groups that consists|
| | of pairs where entry name is mapped to value it |
| | represents in statistics |
+-----------------------+---------------------------------------------------+
| <entry_name> | single entry to value mapping; value is hardcoded |
| | to unsigned integer type, in a CBOR meaning |
+-----------------------+---------------------------------------------------+
| "rc" | :ref:`mcumgr_smp_protocol_status_codes` |
+-----------------------+---------------------------------------------------+
Statistics: list of groups
**************************
The command is used to obtain list of groups of statistics that are gathered
on a device. This is a list of names as given to groups with
``STATS_INIT_AND_REG`` macro or ``stats_init_and_reg(...)`` function calls,
within module that gathers the statistics; this means that this command may
be considered optional as it is known during compilation what groups will
be included into build and listing them is not needed prior to issuing
a query.
Statistics: list of groups request
==================================
Statistics group list request header:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``0`` | ``2`` | ``1`` |
+--------+--------------+----------------+
The command sends empty CBOR map as data.
Statistics: list of groups response
===================================
Statistics group list request header:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``1`` | ``2`` | ``1`` |
+--------+--------------+----------------+
CBOR Payload of response:
.. code-block:: none
{
(str)"stat_list" : [
(str)<stat_group_name>, ...
]
(str)"rc" : (int)
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| "stat_list" | array of strings representing group names; this |
| | array may be empty if there are no groups |
+-----------------------+---------------------------------------------------+
| "rc" | :ref:`mcumgr_smp_protocol_status_codes` |
+-----------------------+---------------------------------------------------+

View File

@ -0,0 +1,218 @@
.. _mcumgr_smp_group_8:
File management
###############
The file management group provides commands that allow to upload and download files
to/from a device.
File management group defines following commands:
.. table::
:align: center
+-------------------+-----------------------------------------------+
| ``Command ID`` | Command description |
+===================+===============================================+
| ``0`` | File download/upload |
+-------------------+-----------------------------------------------+
File download
*************
Command allows to download contents of an existing file from specified path
of a target device. The command is stateless and mcumgr does not hold file
in open state after response to the command is issued, instead a client
application is supposed to keep track of data it has already downloaded,
and issue subsequent requests, with modified offset, to gather entire file.
Request does not carry size of requested chunk, the size is specified
by application itself.
Mcumgr server side re-opens a file for each subsequent request, and current
specification does not provide means to identify subsequent requests as
belonging to specified download session. This means that the file is not
locked in any way or exclusively owned by mcumgr, for the time of download
session, and may change between requests or even be removed.
File download request
=====================
File download request header:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``0`` | ``8`` | ``0`` |
+--------+--------------+----------------+
CBOR data of request:
.. code-block:: none
{
(str)"off" : (uint)
(str)"name" : (str)
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| "off" | offset to start download at |
+-----------------------+---------------------------------------------------+
| "name" | absolute path to a file |
+-----------------------+---------------------------------------------------+
File download response
======================
File download response header:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``1`` | ``8`` | ``0`` |
+--------+--------------+----------------+
CBOR data of successful response:
.. code-block:: none
{
(str)"off" : (uint)
(str)"data" : (byte str)
(str)"rc" : (int)
(str,opt)"len" : (uint)
}
In case of error the CBOR data takes form:
.. code-block:: none
{
(str)"rc" : (int)
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| "off" | offset the response is for |
+-----------------------+---------------------------------------------------+
| "data" | chunk of data read from file; it is CBOR encoded |
| | stream of bytes with embeeded size; |
| | "data" appears only in responses where "rc" is 0 |
+-----------------------+---------------------------------------------------+
| "len" | length of file, this field is only mandatory |
| | when "off" is 0 |
+-----------------------+---------------------------------------------------+
| "rc" | :ref:`mcumgr_smp_protocol_status_codes` |
+-----------------------+---------------------------------------------------+
In case when "rc" is not 0, success, the other fields will not appear.
File upload
***********
Allows to upload a file to a specified location. Command will automatically overwrite
existing file or create a new one if it does not exist at specified path.
The protocol supports stateless upload where each requests carries different chunk
of a file and it is client side responsibility to track progress of upload.
Mcumgr server side re-opens a file for each subsequent request, and current
specification does not provide means to identify subsequent requests as
belonging to specified upload session. This means that the file is not
locked in any way or exclusively owned by mcumgr, for the time of upload
session, and may change between requests or even be removed.
.. note::
Weirdly, the current Zephyr implementation is half-stateless as is able to hold
single upload context, holding information on ongoing upload, that consists
of bool flag indicating in-progress upload, last successfully uploaded offset
and total length only.
File upload request
===================
File upload request header:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``2`` | ``8`` | ``0`` |
+--------+--------------+----------------+
CBOR data of request:
.. code-block:: none
{
(str)"off" : (uint)
(str)"data" : (str)
(str)"name" : (str)
(str,opt)"len" : (uint)
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| "off" | offset to start/continue uplad at |
+-----------------------+---------------------------------------------------+
| "data" | chunk of data to write to the file; |
| | it is CBOR encoded with length embeeded |
+-----------------------+---------------------------------------------------+
| "name" | absolute path to a file |
+-----------------------+---------------------------------------------------+
| "len" | length of file, this field is only mandatory |
| | when "off" is 0 |
+-----------------------+---------------------------------------------------+
File upload response
====================
File upload response header:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``3`` | ``8`` | ``0`` |
+--------+--------------+----------------+
CBOR data of request:
.. code-block:: none
{
(str,opt)"off" : (uint)
(str)"rc" : (int)
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| "off" | offset of last successfully written data; |
| | appears only when "rc" is 0 |
+-----------------------+---------------------------------------------------+
| "rc" | :ref:`mcumgr_smp_protocol_status_codes` |
+-----------------------+---------------------------------------------------+

View File

@ -0,0 +1,99 @@
.. _mcumgr_smp_group_9:
Shell management
################
Shell management allows to pass commands to shell subsystem with use of SMP
protocol.
Shell management group defines following commands:
.. table::
:align: center
+-------------------+-----------------------------------------------+
| ``Command ID`` | Command description |
+===================+===============================================+
| ``0`` | Shell command line execute |
+-------------------+-----------------------------------------------+
Shell command line execute
**************************
The command allows to execute command line in a similar way to typing it into
a shell, but both a request and a response are transported with use of SMP.
Shell command line execute request
==================================
Execute command request header:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``2`` | ``9`` | ``0`` |
+--------+--------------+----------------+
CBOR data of request:
.. code-block:: none
{
(str)"argv" : [
(str)<cmd>
(str,opt)<arg>
...
]
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| "argv" | is array consisting of strings representing |
| | command and its arguments |
+-----------------------+---------------------------------------------------+
| <cmd> | command to be executed |
+-----------------------+---------------------------------------------------+
| <arg> | optional arguments to command |
+-----------------------+---------------------------------------------------+
Shell command line execute response
===================================
Command line execute response header fields:
.. table::
:align: center
+--------+--------------+----------------+
| ``OP`` | ``Group ID`` | ``Command ID`` |
+========+==============+================+
| ``3`` | ``9`` | ``0`` |
+--------+--------------+----------------+
CBOR data of response:
.. code-block:: none
{
(str)"o" : (str)
(str)"rc" : (int)
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| "o" | command output |
+-----------------------+---------------------------------------------------+
| "rc" | either return code from shell command execution |
| | or :ref:`mcumgr_smp_protocol_status_codes` |
+-----------------------+---------------------------------------------------+

View File

@ -0,0 +1,261 @@
.. _mcumgr_smp_protocol_specification:
SMP Protocol Specification
##########################
This is description of Simple Management Protocol, SMP, that is used by
mcumgr to pass requests to devices and receive responses from them.
SMP is an application layer protocol. The underlying transport layer is not
in scope of this documentation.
Frame: The envelope
*******************
Each frame consists of header and following it data. The ``Data Length``" field in
the header may be used for reassembly purposes if underlying transport layer supports
fragmentation.
Frame is encoded in "Big Endian" (Network endianness), where field is more than
one byte lone, and takes the following form:
.. _mcumgr_smp_protocol_frame:
.. table::
:align: center
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|3 |2 |1 |0 |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|7|6|5|4|3|2|1|0|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Res | OP | Flags | Data Length |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Group ID | Sequence Num | Command ID |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Data |
| ... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
.. note::
The original specification states that SMP should support receiving
both the "Little-endian" and "Big-endian" frames but in reality the
mcumgr library is hardcoded to always treat "Network" side as
"Big-endian".
The Data is optional and is not present when ``Data Length`` is zero.
The encoding of data depends on the target of group/ID.
Where meaning of fields is:
.. table::
:align: center
+-------------------+---------------------------------------------------+
| Field | Description |
+===================+===================================================+
| ``Res`` | This is reserved, not-used field and should be |
| | always set to 0. |
| | |
+-------------------+---------------------------------------------------+
| ``OP`` | :ref:`mcumgr_smp_protocol_op_code` |
+-------------------+---------------------------------------------------+
| ``Flags`` | Reserved for flags; there are no flags defined |
| | yet, the field should be set to 0 |
+-------------------+---------------------------------------------------+
| ``Data Length`` | Length of the ``Data`` field |
+-------------------+---------------------------------------------------+
| ``Group ID`` | :ref:`mcumgr_smp_protocol_group_ids` |
+-------------------+---------------------------------------------------+
| ``Seqence Num`` | This is a frame sequence number. |
| | The number is increased by one with each request |
| | frame. |
| | The Sequence Num of a response should match |
| | the one in the request. |
+-------------------+---------------------------------------------------+
| ``Command ID`` | This is a command, within ``Group``. |
+-------------------+---------------------------------------------------+
| ``Data`` | This is data payload of the ``Data Length`` |
| | size. It is optional as ``Data Length`` may be |
| | set to zero, which means that no data follows |
| | the header. |
+-------------------+---------------------------------------------------+
.. note::
Contents of a ``Data`` depends on a value of an ``OP``, a ``Group ID``,
and a ``Command ID``.
.. note::
The ``Res`` field may be repurposed by Zephyr for protocol version
in the future.
.. _mcumgr_smp_protocol_op_code:
Operation code
==============
The operation code determines whether an information is written to a device or
requested from it and whether a packet contains request to a SMP server or
response from it.
Following operation codes are defined.
.. table::
:align: center
+---------------+-----------------------------------------------+
| Decimal ID | Operation |
+===============+===============================================+
| ``0`` | read request |
+---------------+-----------------------------------------------+
| ``1`` | read response |
+---------------+-----------------------------------------------+
| ``2`` | write request |
+---------------+-----------------------------------------------+
| ``3`` | write response |
+---------------+-----------------------------------------------+
.. _mcumgr_smp_protocol_group_ids:
Management ``Group ID``'s
=========================
The SMP protocol supports predefined common groups and allows user defined
groups. Below table presents list of common groups:
.. table::
:align: center
+---------------+-----------------------------------------------+
| Decimal ID | Group description |
+===============+===============================================+
| ``0`` | :ref:`mcumgr_smp_group_0` |
+---------------+-----------------------------------------------+
| ``1`` | :ref:`mcumgr_smp_group_1` |
+---------------+-----------------------------------------------+
| ``2`` | :ref:`mcumgr_smp_group_2` |
+---------------+-----------------------------------------------+
| ``3`` | Application/system configuration |
| | (currently not used by Zephyr) |
+---------------+-----------------------------------------------+
| ``4`` | Application/system log management |
| | (currently not used by Zephyr) |
+---------------+-----------------------------------------------+
| ``5`` | Run-time tests |
| | (unused by Zephyr) |
+---------------+-----------------------------------------------+
| ``6`` | Split image management |
| | (unused by Zephyr) |
+---------------+-----------------------------------------------+
| ``7`` | Test crashing application |
| | (unused by Zephyr) |
+---------------+-----------------------------------------------+
| ``8`` | :ref:`mcumgr_smp_group_8` |
+---------------+-----------------------------------------------+
| ``9`` | :ref:`mcumgr_smp_group_9` |
+---------------+-----------------------------------------------+
| ``63`` | Zephyr specific basic commands group |
+---------------+-----------------------------------------------+
| ``64`` | This is the base group for defining |
| | an application specific management groups. |
+---------------+-----------------------------------------------+
The payload for above groups, except for ``64`` which is not defined,
is always CBOR encoded. The group ``64``, and above, are free to be defined
by application developers and are not defined within this documentation.
Minimal response
****************
Regardless of a command issued, as long as there is SMP client on the
other side of a request, a response should be issued containing header
followed by CBOR map container.
Lack of response is only allowed when there is no SMP service or device is
non-responsive.
Minimal response SMP data
=========================
Minimal response is CBOR directory:
.. code-block:: none
{
(str)"rc" : (int)
}
where:
.. table::
:align: center
+-----------------------+---------------------------------------------------+
| "rc" | :ref:`mcumgr_smp_protocol_status_codes` |
+-----------------------+---------------------------------------------------+
.. _mcumgr_smp_protocol_status_codes:
Status/error codes in responses
===============================
.. table::
:align: center
+---------------+-----------------------------------------------+
| Decimal ID | Meaning |
+===============+===============================================+
| ``0`` | No error, OK. |
+---------------+-----------------------------------------------+
| ``1`` | Unknown error. |
+---------------+-----------------------------------------------+
| ``2`` | Not enough memory; this error is reported |
| | when there is not enough memory to complete |
| | response. |
+---------------+-----------------------------------------------+
| ``3`` | Invalid value; a request contains an invalid |
| | value. |
+---------------+-----------------------------------------------+
| ``4`` | Timeout; the operation for some reason could |
| | not be completed in assumed time. |
+---------------+-----------------------------------------------+
| ``5`` | No entry; the error means that request frame |
| | has been missing some information that is |
| | required to perform action. |
| | It may also mean that requested information |
| | is not available. |
+---------------+-----------------------------------------------+
| ``6`` | Bad state; the error means that application |
| | or device is in a state that would not allow |
| | it to perform or complete a requested action. |
+---------------+-----------------------------------------------+
| ``7`` | Response too long; this error is issued when |
| | buffer assigned for gathering response is |
| | not big enough. |
+---------------+-----------------------------------------------+
| ``8`` | Not supported; usually issued when requested |
| | ``Group ID`` or ``Command ID`` is not |
| | supported by application. |
+---------------+-----------------------------------------------+
| ``9`` | Corrupted payload received. |
+---------------+-----------------------------------------------+
| ``256`` | This is base error number of user defined |
| | error codes. |
+---------------+-----------------------------------------------+
Zephyr uses ``MGMT_ERR_`` prefixed definitions gathered in this header file
:zephyr_file:`subsys/mgmt/mcumgr/lib/mgmt/include/mgmt/mgmt.h`
Specifications of management groups supported by Zephyr
*******************************************************
.. toctree::
:maxdepth: 1
smp_groups/smp_group_0.rst
smp_groups/smp_group_1.rst
smp_groups/smp_group_2.rst
smp_groups/smp_group_8.rst
smp_groups/smp_group_9.rst