1.. _mcumgr_handlers: 2 3MCUmgr handlers 4############### 5 6Overview 7******** 8 9MCUmgr functions by having group handlers which identify a group of functions relating to a 10specific management area, which is addressed with a 16-bit identification value, 11:c:enum:`mcumgr_group_t` contains the management groups available in Zephyr with their 12corresponding group ID values. The group ID is included in SMP headers to identify which 13group a command belongs to, there is also an 8-bit command ID which identifies the function of 14that group to execute - see :ref:`mcumgr_smp_protocol_specification` for details on the SMP 15protocol and header. There can only be one registered group per unique ID. 16 17Implementation 18************** 19 20MCUmgr handlers can be added externally by application code or by module code, they do not have 21to reside in the upstream Zephyr tree to be usable. The first step to creating a handler is to 22create the folder structure for it, the typical Zephyr MCUmgr group layout is as follows: 23 24.. code-block:: none 25 26 <dir>/grp/<grp_name>_mgmt/ 27 ├── CMakeLists.txt 28 ├── Kconfig 29 ├── include 30 ├──── <grp_name>_mgmt.h 31 ├──── <grp_name>_mgmt_callbacks.h 32 ├── src 33 └──── <grp_name>_mgmt.c 34 35Note that the header files in upstream Zephyr MCUmgr handlers reside in the 36``zephyr/include/zephyr/mgmt/mcumgr/grp/<grp_name>_mgmt`` directory to allow the files to be 37globally included by applications. 38 39Initial header <grp_name>_mgmt.h 40================================ 41 42The purpose of the header file is to provide defines which can be used by the MCUmgr handler 43itself and application code, e.g. to reference the command IDs for executing functions. An example 44file would look similar to: 45 46.. literalinclude:: ../../../tests/subsys/mgmt/mcumgr/handler_demo/example_as_module/include/example_mgmt.h 47 :language: c 48 :linenos: 49 50This provides the defines for 2 command ``test`` and ``other`` and sets up the SMP version 2 error 51responses (which have unique error codes per group as opposed to the legacy SMP version 1 error 52responses that return a :c:enum:`mcumgr_err_t` - there should always be an OK error code with the 53value 0 and an unknown error code with the value 1. The above example then adds an error code of 54``not wanted`` with value 2. In addition, the group ID is set to be 55:c:enumerator:`MGMT_GROUP_ID_PERUSER`, which is the start group ID for user-defined groups, note 56that group IDs need to be unique so other custom groups should use different values, a central index 57header file (as upstream Zephyr has) can be used to distribute group IDs more easily. 58 59Initial header <grp_name>_mgmt_callbacks.h 60========================================== 61 62The purpose of the header file is to provide defines which can be used by the MCUmgr handler 63itself and application code, e.g. to reference the command IDs for executing functions. An example 64file would look similar to: 65 66.. literalinclude:: ../../../tests/subsys/mgmt/mcumgr/handler_demo/example_as_module/include/example_mgmt_callbacks.h 67 :language: c 68 :linenos: 69 70This sets up a single event which application (or module) code can register for to receive a 71callback when the function handler is executed, which allows the flow of the handler to be 72changed (i.e. to return an error instead of continuing). The event group ID is set to 73:c:enumerator:`MGMT_EVT_GRP_USER_CUSTOM_START`, which is the start event ID for user-defined groups, 74note that event IDs need to be unique so other custom groups should use different values, a 75central index header file (as upstream Zephyr has) can be used to distribute event IDs more 76easily. 77 78Initial source <grp_name>_mgmt.c 79================================ 80 81The purpose of this source file is to handle the incoming MCUmgr commands, provide responses, and 82register the transport with MCUmgr so that commands will be sent to it. An example file would 83look similar to: 84 85.. literalinclude:: ../../../tests/subsys/mgmt/mcumgr/handler_demo/example_as_module/src/example_mgmt.c 86 :language: c 87 :linenos: 88 89The above code creates 2 function handlers, ``test`` which supports read requests and takes 2 90required parameters, and ``other`` which supports write requests and takes 1 optional parameter, 91this function handler has an optional notification callback feature that allows other parts of 92the code to listen for the event and take any required actions that are necessary or prevent 93further execution of the function by returning an error, further details on MCUmgr callback 94functionality can be found on :ref:`mcumgr_callbacks`. 95 96Note that other code referencing callbacks for custom MCUmgr handlers needs to include both the 97base Zephyr callback include file and the custom handler callback file, only in-tree Zephyr 98handler headers are included when including the upstream Zephyr callback header file. 99 100Initial Kconfig 101=============== 102 103The purpose of the Kconfig file is to provide options which users can enable or change relating 104to the functionality of the handler being implemented. An example file would look similar to: 105 106.. literalinclude:: ../../../tests/subsys/mgmt/mcumgr/handler_demo/Kconfig 107 :language: kconfig 108 109Initial CMakeLists.txt 110====================== 111 112The CMakeLists.txt file is used by the build system to setup files to compile, include 113directories to add and specify options that can be changed. A basic file only need to include the 114source files if the Kconfig options are enabled. An example file would look similar to: 115 116.. tabs:: 117 118 .. group-tab:: Zephyr module 119 120 .. literalinclude:: ../../../tests/subsys/mgmt/mcumgr/handler_demo/example_as_module/CMakeLists.txt 121 :language: cmake 122 123 .. group-tab:: Application 124 125 .. literalinclude:: ../../../tests/subsys/mgmt/mcumgr/handler_demo/CMakeLists.txt 126 :language: cmake 127 :start-after: Include handler files 128 129Including from application 130************************** 131 132Application-specific MCUmgr handlers can be added by creating/editing application build files. 133Example modifications are shown below. 134 135Example CMakeLists.txt 136====================== 137 138The application ``CMakeLists.txt`` file can load the CMake file for the example MCUmgr handler by 139adding the following: 140 141.. code-block:: cmake 142 143 add_subdirectory(mcumgr/grp/<grp_name>) 144 145Example Kconfig 146=============== 147 148The application Kconfig file can include the Kconfig file for the example MCUmgr handler by adding 149the following to the ``Kconfig`` file in the application directory (or creating it if it does not 150exist): 151 152.. code-block:: kconfig 153 154 rsource "mcumgr/grp/<grp_name>/Kconfig" 155 156 # Include Zephyr's Kconfig 157 source "Kconfig.zephyr" 158 159Including from Zephyr Module 160**************************** 161 162Zephyr :ref:`modules` can be used to add custom MCUmgr handlers to multiple different applications 163without needing to duplicate the code in each application's source tree, see :ref:`module-yml` for 164details on how to set up the module files. Example files are shown below. 165 166Example zephyr/module.yml 167========================= 168 169This is an example file which can be used to load the Kconfig and CMake files from the root of the 170module directory, and would be placed at ``zephyr/module.yml``: 171 172.. code-block:: yaml 173 174 build: 175 kconfig: Kconfig 176 cmake: . 177 178Example CMakeLists.txt 179====================== 180 181This is an example CMakeLists.txt file which loads the CMake file for the example MCUmgr handler, 182and would be placed at ``CMakeLists.txt``: 183 184.. code-block:: cmake 185 186 add_subdirectory(mcumgr/grp/<grp_name>) 187 188Example Kconfig 189=============== 190 191This is an example Kconfig file which loads the Kconfig file for the example MCUmgr handler, and 192would be placed at ``Kconfig``: 193 194.. code-block:: kconfig 195 196 rsource "mcumgr/grp/<grp_name>/Kconfig" 197 198Demonstration handler 199********************* 200 201There is a demonstration project which includes configuration for both application and zephyr 202module-MCUmgr handlers which can be used as a basis for created your own in 203:zephyr_file:`tests/subsys/mgmt/mcumgr/handler_demo/`. 204