1 /* 2 * Copyright (c) 2022-2023 Nordic Semiconductor ASA 3 * 4 * SPDX-License-Identifier: Apache-2.0 5 */ 6 7 #ifndef H_MCUMGR_CALLBACKS_ 8 #define H_MCUMGR_CALLBACKS_ 9 10 #include <inttypes.h> 11 #include <zephyr/sys/slist.h> 12 #include <zephyr/mgmt/mcumgr/mgmt/mgmt.h> 13 14 #ifdef CONFIG_MCUMGR_GRP_FS 15 #include <zephyr/mgmt/mcumgr/grp/fs_mgmt/fs_mgmt_callbacks.h> 16 #endif 17 18 #ifdef CONFIG_MCUMGR_GRP_IMG 19 #include <zephyr/mgmt/mcumgr/grp/img_mgmt/img_mgmt_callbacks.h> 20 #endif 21 22 #ifdef CONFIG_MCUMGR_GRP_OS 23 #include <zephyr/mgmt/mcumgr/grp/os_mgmt/os_mgmt_callbacks.h> 24 #endif 25 26 #ifdef CONFIG_MCUMGR_GRP_SETTINGS 27 #include <zephyr/mgmt/mcumgr/grp/settings_mgmt/settings_mgmt_callbacks.h> 28 #endif 29 30 #ifdef CONFIG_MCUMGR_GRP_ENUM 31 #include <zephyr/mgmt/mcumgr/grp/enum_mgmt/enum_mgmt_callbacks.h> 32 #endif 33 34 #ifdef __cplusplus 35 extern "C" { 36 #endif 37 38 /** 39 * @brief MCUmgr callback API 40 * @defgroup mcumgr_callback_api MCUmgr callback API 41 * @ingroup mcumgr 42 * @{ 43 */ 44 45 /** @cond INTERNAL_HIDDEN */ 46 /** Event which signifies that all event IDs for a particular group should be enabled. */ 47 #define MGMT_EVT_OP_ID_ALL 0xffff 48 49 /** Get event for a particular group and event ID. */ 50 #define MGMT_DEF_EVT_OP_ID(group, event_id) ((group << 16) | BIT(event_id)) 51 52 /** Get event used for enabling all event IDs of a particular group. */ 53 #define MGMT_DEF_EVT_OP_ALL(group) ((group << 16) | MGMT_EVT_OP_ID_ALL) 54 /** @endcond */ 55 56 /** Get group from event. */ 57 #define MGMT_EVT_GET_GROUP(event) ((event >> 16) & MGMT_EVT_OP_ID_ALL) 58 59 /** Get event ID from event. */ 60 #define MGMT_EVT_GET_ID(event) (event & MGMT_EVT_OP_ID_ALL) 61 62 /** 63 * MGMT event callback return value. 64 */ 65 enum mgmt_cb_return { 66 /** No error. */ 67 MGMT_CB_OK, 68 69 /** SMP protocol error and ``err_rc`` contains the #mcumgr_err_t error code. */ 70 MGMT_CB_ERROR_RC, 71 72 /** 73 * Group (application-level) error and ``err_group`` contains the group ID that caused 74 * the error and ``err_rc`` contains the error code of that group to return. 75 */ 76 MGMT_CB_ERROR_ERR, 77 }; 78 79 /* Deprecated after Zephyr 3.4, use MGMT_CB_ERROR_ERR instead */ 80 #define MGMT_CB_ERROR_RET __DEPRECATED_MACRO MGMT_CB_ERROR_ERR 81 82 /** 83 * @typedef mgmt_cb 84 * @brief Function to be called on MGMT notification/event. 85 * 86 * This callback function is used to notify an application or system about a MCUmgr mgmt event. 87 * 88 * @param event #mcumgr_op_t. 89 * @param prev_status #mgmt_cb_return of the previous handler calls, if it is an error then it 90 * will be the first error that was returned by a handler (i.e. this handler 91 * is being called for a notification only, the return code will be ignored). 92 * @param rc If ``prev_status`` is #MGMT_CB_ERROR_RC then this is the SMP error that 93 * was returned by the first handler that failed. If ``prev_status`` is 94 * #MGMT_CB_ERROR_ERR then this will be the group error rc code returned by 95 * the first handler that failed. If the handler wishes to raise an SMP 96 * error, this must be set to the #mcumgr_err_t status and #MGMT_CB_ERROR_RC 97 * must be returned by the function, if the handler wishes to raise a ret 98 * error, this must be set to the group ret status and #MGMT_CB_ERROR_ERR 99 * must be returned by the function. 100 * @param group If ``prev_status`` is #MGMT_CB_ERROR_ERR then this is the group of the 101 * ret error that was returned by the first handler that failed. If the 102 * handler wishes to raise a ret error, this must be set to the group ret 103 * status and #MGMT_CB_ERROR_ERR must be returned by the function. 104 * @param abort_more Set to true to abort further processing by additional handlers. 105 * @param data Optional event argument. 106 * @param data_size Size of optional event argument (0 if no data is provided). 107 * 108 * @return #mgmt_cb_return indicating the status to return to the calling code (only 109 * checked when this is the first failure reported by a handler). 110 */ 111 typedef enum mgmt_cb_return (*mgmt_cb)(uint32_t event, enum mgmt_cb_return prev_status, 112 int32_t *rc, uint16_t *group, bool *abort_more, void *data, 113 size_t data_size); 114 115 /** 116 * MGMT event callback group IDs. Note that this is not a 1:1 mapping with #mcumgr_group_t values. 117 */ 118 enum mgmt_cb_groups { 119 MGMT_EVT_GRP_ALL = 0, 120 MGMT_EVT_GRP_SMP, 121 MGMT_EVT_GRP_OS, 122 MGMT_EVT_GRP_IMG, 123 MGMT_EVT_GRP_FS, 124 MGMT_EVT_GRP_SETTINGS, 125 MGMT_EVT_GRP_ENUM, 126 127 MGMT_EVT_GRP_USER_CUSTOM_START = MGMT_GROUP_ID_PERUSER, 128 }; 129 130 /** 131 * MGMT event opcodes for all command processing. 132 */ 133 enum smp_all_events { 134 /** Used to enable all events. */ 135 MGMT_EVT_OP_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_ALL), 136 }; 137 138 /** 139 * MGMT event opcodes for base SMP command processing. 140 */ 141 enum smp_group_events { 142 /** Callback when a command is received, data is mgmt_evt_op_cmd_arg(). */ 143 MGMT_EVT_OP_CMD_RECV = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_SMP, 0), 144 145 /** Callback when a status is updated, data is mgmt_evt_op_cmd_arg(). */ 146 MGMT_EVT_OP_CMD_STATUS = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_SMP, 1), 147 148 /** Callback when a command has been processed, data is mgmt_evt_op_cmd_arg(). */ 149 MGMT_EVT_OP_CMD_DONE = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_SMP, 2), 150 151 /** Used to enable all smp_group events. */ 152 MGMT_EVT_OP_CMD_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_SMP), 153 }; 154 155 /** 156 * MGMT event opcodes for filesystem management group. 157 */ 158 enum fs_mgmt_group_events { 159 /** Callback when a file has been accessed, data is fs_mgmt_file_access(). */ 160 MGMT_EVT_OP_FS_MGMT_FILE_ACCESS = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_FS, 0), 161 162 /** Used to enable all fs_mgmt_group events. */ 163 MGMT_EVT_OP_FS_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_FS), 164 }; 165 166 /** 167 * MGMT event opcodes for image management group. 168 */ 169 enum img_mgmt_group_events { 170 /** Callback when a client sends a file upload chunk, data is img_mgmt_upload_check(). */ 171 MGMT_EVT_OP_IMG_MGMT_DFU_CHUNK = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 0), 172 173 /** Callback when a DFU operation is stopped. */ 174 MGMT_EVT_OP_IMG_MGMT_DFU_STOPPED = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 1), 175 176 /** Callback when a DFU operation is started. */ 177 MGMT_EVT_OP_IMG_MGMT_DFU_STARTED = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 2), 178 179 /** Callback when a DFU operation has finished being transferred. */ 180 MGMT_EVT_OP_IMG_MGMT_DFU_PENDING = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 3), 181 182 /** Callback when an image has been confirmed. */ 183 MGMT_EVT_OP_IMG_MGMT_DFU_CONFIRMED = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 4), 184 185 /** Callback when an image write command has finished writing to flash. */ 186 MGMT_EVT_OP_IMG_MGMT_DFU_CHUNK_WRITE_COMPLETE = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 5), 187 188 /** Callback when an image slot's state is encoded for a response. */ 189 MGMT_EVT_OP_IMG_MGMT_IMAGE_SLOT_STATE = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 6), 190 191 /** Callback when an slot list command outputs fields for an image. */ 192 MGMT_EVT_OP_IMG_MGMT_SLOT_INFO_IMAGE = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 7), 193 194 /** Callback when an slot list command outputs fields for a slot of an image. */ 195 MGMT_EVT_OP_IMG_MGMT_SLOT_INFO_SLOT = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 8), 196 197 /** Used to enable all img_mgmt_group events. */ 198 MGMT_EVT_OP_IMG_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_IMG), 199 }; 200 201 /** 202 * MGMT event opcodes for operating system management group. 203 */ 204 enum os_mgmt_group_events { 205 /** Callback when a reset command has been received, data is os_mgmt_reset_data. */ 206 MGMT_EVT_OP_OS_MGMT_RESET = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 0), 207 208 /** Callback when an info command is processed, data is os_mgmt_info_check. */ 209 MGMT_EVT_OP_OS_MGMT_INFO_CHECK = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 1), 210 211 /** Callback when an info command needs to output data, data is os_mgmt_info_append. */ 212 MGMT_EVT_OP_OS_MGMT_INFO_APPEND = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 2), 213 214 /** Callback when a datetime get command has been received. */ 215 MGMT_EVT_OP_OS_MGMT_DATETIME_GET = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 3), 216 217 /** Callback when a datetime set command has been received, data is struct rtc_time(). */ 218 MGMT_EVT_OP_OS_MGMT_DATETIME_SET = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 4), 219 220 /** 221 * Callback when a bootloader info command has been received, data is 222 * os_mgmt_bootloader_info_data. 223 */ 224 MGMT_EVT_OP_OS_MGMT_BOOTLOADER_INFO = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 5), 225 226 /** Used to enable all os_mgmt_group events. */ 227 MGMT_EVT_OP_OS_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_OS), 228 }; 229 230 /** 231 * MGMT event opcodes for settings management group. 232 */ 233 enum settings_mgmt_group_events { 234 /** Callback when a setting is read/written/deleted. */ 235 MGMT_EVT_OP_SETTINGS_MGMT_ACCESS = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_SETTINGS, 0), 236 237 /** Used to enable all settings_mgmt_group events. */ 238 MGMT_EVT_OP_SETTINGS_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_SETTINGS), 239 }; 240 241 /** 242 * MGMT event opcodes for enumeration management group. 243 */ 244 enum enum_mgmt_group_events { 245 /** Callback when fetching details on supported command groups. */ 246 MGMT_EVT_OP_ENUM_MGMT_DETAILS = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_ENUM, 0), 247 248 /** Used to enable all enum_mgmt_group events. */ 249 MGMT_EVT_OP_ENUM_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_ENUM), 250 }; 251 252 /** 253 * MGMT callback struct 254 */ 255 struct mgmt_callback { 256 /** Entry list node. */ 257 sys_snode_t node; 258 259 /** Callback that will be called. */ 260 mgmt_cb callback; 261 262 /** 263 * MGMT_EVT_[...] Event ID for handler to be called on. This has special meaning if 264 * #MGMT_EVT_OP_ALL is used (which will cover all events for all groups), or 265 * MGMT_EVT_OP_*_MGMT_ALL (which will cover all events for a single group). For events 266 * that are part of a single group, they can be or'd together for this to have one 267 * registration trigger on multiple events, please note that this will only work for 268 * a single group, to register for events in different groups, they must be registered 269 * separately. 270 */ 271 uint32_t event_id; 272 }; 273 274 /** 275 * Arguments for #MGMT_EVT_OP_CMD_RECV, #MGMT_EVT_OP_CMD_STATUS and #MGMT_EVT_OP_CMD_DONE 276 */ 277 struct mgmt_evt_op_cmd_arg { 278 /** #mcumgr_group_t */ 279 uint16_t group; 280 281 /** Message ID within group */ 282 uint8_t id; 283 284 union { 285 /** #mcumgr_op_t used in #MGMT_EVT_OP_CMD_RECV */ 286 uint8_t op; 287 288 /** #mcumgr_err_t, used in #MGMT_EVT_OP_CMD_DONE */ 289 int err; 290 291 /** #img_mgmt_id_upload_t, used in #MGMT_EVT_OP_CMD_STATUS */ 292 int status; 293 }; 294 }; 295 296 /** 297 * @brief Get event ID index from event. 298 * 299 * @param event Event to get ID index from. 300 * 301 * @return Event index. 302 */ 303 uint8_t mgmt_evt_get_index(uint32_t event); 304 305 /** 306 * @brief This function is called to notify registered callbacks about mcumgr notifications/events. 307 * 308 * @param event #mcumgr_op_t. 309 * @param data Optional event argument. 310 * @param data_size Size of optional event argument (0 if none). 311 * @param err_rc Pointer to rc value. 312 * @param err_group Pointer to group value. 313 * 314 * @return #mgmt_cb_return either #MGMT_CB_OK if all handlers returned it, or 315 * #MGMT_CB_ERROR_RC if the first failed handler returned an SMP error (in 316 * which case ``err_rc`` will be updated with the SMP error) or 317 * #MGMT_CB_ERROR_ERR if the first failed handler returned a ret group and 318 * error (in which case ``err_group`` will be updated with the failed group 319 * ID and ``err_rc`` will be updated with the group-specific error code). 320 */ 321 enum mgmt_cb_return mgmt_callback_notify(uint32_t event, void *data, size_t data_size, 322 int32_t *err_rc, uint16_t *err_group); 323 324 /** 325 * @brief Register event callback function. 326 * 327 * @param callback Callback struct. 328 */ 329 void mgmt_callback_register(struct mgmt_callback *callback); 330 331 /** 332 * @brief Unregister event callback function. 333 * 334 * @param callback Callback struct. 335 */ 336 void mgmt_callback_unregister(struct mgmt_callback *callback); 337 338 /** 339 * @} 340 */ 341 342 #ifdef __cplusplus 343 } 344 #endif 345 346 #endif /* H_MCUMGR_CALLBACKS_ */ 347