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