From 92109e1f628aa135c681deeba419da88dc0707cf Mon Sep 17 00:00:00 2001 From: Dominik Ermel Date: Thu, 25 Nov 2021 15:19:37 +0000 Subject: [PATCH] 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 --- CODEOWNERS | 2 + doc/guides/device_mgmt/index.rst | 1 + .../device_mgmt/smp_groups/smp_group_0.rst | 458 ++++++++++++++++++ .../device_mgmt/smp_groups/smp_group_1.rst | 419 ++++++++++++++++ .../device_mgmt/smp_groups/smp_group_2.rst | 170 +++++++ .../device_mgmt/smp_groups/smp_group_8.rst | 218 +++++++++ .../device_mgmt/smp_groups/smp_group_9.rst | 99 ++++ doc/guides/device_mgmt/smp_protocol.rst | 261 ++++++++++ 8 files changed, 1628 insertions(+) create mode 100644 doc/guides/device_mgmt/smp_groups/smp_group_0.rst create mode 100644 doc/guides/device_mgmt/smp_groups/smp_group_1.rst create mode 100644 doc/guides/device_mgmt/smp_groups/smp_group_2.rst create mode 100644 doc/guides/device_mgmt/smp_groups/smp_group_8.rst create mode 100644 doc/guides/device_mgmt/smp_groups/smp_group_9.rst create mode 100644 doc/guides/device_mgmt/smp_protocol.rst diff --git a/CODEOWNERS b/CODEOWNERS index 89f3c6c9be8..d483b0ba8ed 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -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 diff --git a/doc/guides/device_mgmt/index.rst b/doc/guides/device_mgmt/index.rst index e77f0b60444..4bcb8a24b57 100644 --- a/doc/guides/device_mgmt/index.rst +++ b/doc/guides/device_mgmt/index.rst @@ -8,5 +8,6 @@ Device Management mcumgr.rst mcumgr_backporting.rst + smp_protocol.rst dfu.rst ota.rst diff --git a/doc/guides/device_mgmt/smp_groups/smp_group_0.rst b/doc/guides/device_mgmt/smp_groups/smp_group_0.rst new file mode 100644 index 00000000000..ab72479c71a --- /dev/null +++ b/doc/guides/device_mgmt/smp_groups/smp_group_0.rst @@ -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) : { + (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 + + +-----------------------+---------------------------------------------------+ + | | 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) { + (str)"blksiz" : (int) + (str)"nblks" : (int) + (str)"nfree" : (int) + (str)"min' : (int) + } + ... + (str)"rc" : (int) + } + +where: + +.. table:: + :align: center + + +-----------------------+---------------------------------------------------+ + | | 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 | + +-----------------------+---------------------------------------------------+ diff --git a/doc/guides/device_mgmt/smp_groups/smp_group_1.rst b/doc/guides/device_mgmt/smp_groups/smp_group_1.rst new file mode 100644 index 00000000000..00496047616 --- /dev/null +++ b/doc/guides/device_mgmt/smp_groups/smp_group_1.rst @@ -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. diff --git a/doc/guides/device_mgmt/smp_groups/smp_group_2.rst b/doc/guides/device_mgmt/smp_groups/smp_group_2.rst new file mode 100644 index 00000000000..11dd3c848e9 --- /dev/null +++ b/doc/guides/device_mgmt/smp_groups/smp_group_2.rst @@ -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) : (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 | + +-----------------------+---------------------------------------------------+ + | | 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), ... + ] + (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` | + +-----------------------+---------------------------------------------------+ diff --git a/doc/guides/device_mgmt/smp_groups/smp_group_8.rst b/doc/guides/device_mgmt/smp_groups/smp_group_8.rst new file mode 100644 index 00000000000..1192beaf5f9 --- /dev/null +++ b/doc/guides/device_mgmt/smp_groups/smp_group_8.rst @@ -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` | + +-----------------------+---------------------------------------------------+ diff --git a/doc/guides/device_mgmt/smp_groups/smp_group_9.rst b/doc/guides/device_mgmt/smp_groups/smp_group_9.rst new file mode 100644 index 00000000000..6ea5ff10f1b --- /dev/null +++ b/doc/guides/device_mgmt/smp_groups/smp_group_9.rst @@ -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) + (str,opt) + ... + ] + } + +where: + +.. table:: + :align: center + + +-----------------------+---------------------------------------------------+ + | "argv" | is array consisting of strings representing | + | | command and its arguments | + +-----------------------+---------------------------------------------------+ + | | command to be executed | + +-----------------------+---------------------------------------------------+ + | | 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` | + +-----------------------+---------------------------------------------------+ diff --git a/doc/guides/device_mgmt/smp_protocol.rst b/doc/guides/device_mgmt/smp_protocol.rst new file mode 100644 index 00000000000..44a00fff708 --- /dev/null +++ b/doc/guides/device_mgmt/smp_protocol.rst @@ -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