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 /** 80 * @typedef mgmt_cb 81 * @brief Function to be called on MGMT notification/event. 82 * 83 * This callback function is used to notify an application or system about a MCUmgr mgmt event. 84 * 85 * @param event #mcumgr_op_t. 86 * @param prev_status #mgmt_cb_return of the previous handler calls, if it is an error then it 87 * will be the first error that was returned by a handler (i.e. this handler 88 * is being called for a notification only, the return code will be ignored). 89 * @param rc If ``prev_status`` is #MGMT_CB_ERROR_RC then this is the SMP error that 90 * was returned by the first handler that failed. If ``prev_status`` is 91 * #MGMT_CB_ERROR_ERR then this will be the group error rc code returned by 92 * the first handler that failed. If the handler wishes to raise an SMP 93 * error, this must be set to the #mcumgr_err_t status and #MGMT_CB_ERROR_RC 94 * must be returned by the function, if the handler wishes to raise a ret 95 * error, this must be set to the group ret status and #MGMT_CB_ERROR_ERR 96 * must be returned by the function. 97 * @param group If ``prev_status`` is #MGMT_CB_ERROR_ERR then this is the group of the 98 * ret error that was returned by the first handler that failed. If the 99 * handler wishes to raise a ret error, this must be set to the group ret 100 * status and #MGMT_CB_ERROR_ERR must be returned by the function. 101 * @param abort_more Set to true to abort further processing by additional handlers. 102 * @param data Optional event argument. 103 * @param data_size Size of optional event argument (0 if no data is provided). 104 * 105 * @return #mgmt_cb_return indicating the status to return to the calling code (only 106 * checked when this is the first failure reported by a handler). 107 */ 108 typedef enum mgmt_cb_return (*mgmt_cb)(uint32_t event, enum mgmt_cb_return prev_status, 109 int32_t *rc, uint16_t *group, bool *abort_more, void *data, 110 size_t data_size); 111 112 /** 113 * MGMT event callback group IDs. Note that this is not a 1:1 mapping with #mcumgr_group_t values. 114 */ 115 enum mgmt_cb_groups { 116 MGMT_EVT_GRP_ALL = 0, 117 MGMT_EVT_GRP_SMP, 118 MGMT_EVT_GRP_OS, 119 MGMT_EVT_GRP_IMG, 120 MGMT_EVT_GRP_FS, 121 MGMT_EVT_GRP_SETTINGS, 122 MGMT_EVT_GRP_ENUM, 123 124 MGMT_EVT_GRP_USER_CUSTOM_START = MGMT_GROUP_ID_PERUSER, 125 }; 126 127 /** 128 * MGMT event opcodes for all command processing. 129 */ 130 enum smp_all_events { 131 /** Used to enable all events. */ 132 MGMT_EVT_OP_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_ALL), 133 }; 134 135 /** 136 * MGMT event opcodes for base SMP command processing. 137 */ 138 enum smp_group_events { 139 /** Callback when a command is received, data is mgmt_evt_op_cmd_arg(). */ 140 MGMT_EVT_OP_CMD_RECV = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_SMP, 0), 141 142 /** Callback when a status is updated, data is mgmt_evt_op_cmd_arg(). */ 143 MGMT_EVT_OP_CMD_STATUS = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_SMP, 1), 144 145 /** Callback when a command has been processed, data is mgmt_evt_op_cmd_arg(). */ 146 MGMT_EVT_OP_CMD_DONE = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_SMP, 2), 147 148 /** Used to enable all smp_group events. */ 149 MGMT_EVT_OP_CMD_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_SMP), 150 }; 151 152 /** 153 * MGMT event opcodes for filesystem management group. 154 */ 155 enum fs_mgmt_group_events { 156 /** Callback when a file has been accessed, data is fs_mgmt_file_access(). */ 157 MGMT_EVT_OP_FS_MGMT_FILE_ACCESS = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_FS, 0), 158 159 /** Used to enable all fs_mgmt_group events. */ 160 MGMT_EVT_OP_FS_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_FS), 161 }; 162 163 /** 164 * MGMT event opcodes for image management group. 165 */ 166 enum img_mgmt_group_events { 167 /** Callback when a client sends a file upload chunk, data is img_mgmt_upload_check(). */ 168 MGMT_EVT_OP_IMG_MGMT_DFU_CHUNK = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 0), 169 170 /** Callback when a DFU operation is stopped. */ 171 MGMT_EVT_OP_IMG_MGMT_DFU_STOPPED = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 1), 172 173 /** Callback when a DFU operation is started. */ 174 MGMT_EVT_OP_IMG_MGMT_DFU_STARTED = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 2), 175 176 /** Callback when a DFU operation has finished being transferred. */ 177 MGMT_EVT_OP_IMG_MGMT_DFU_PENDING = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 3), 178 179 /** Callback when an image has been confirmed. data is img_mgmt_image_confirmed(). */ 180 MGMT_EVT_OP_IMG_MGMT_DFU_CONFIRMED = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 4), 181 182 /** Callback when an image write command has finished writing to flash. */ 183 MGMT_EVT_OP_IMG_MGMT_DFU_CHUNK_WRITE_COMPLETE = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 5), 184 185 /** 186 * Callback when an image slot's state is encoded for a response, data is 187 * img_mgmt_state_slot_encode(). 188 */ 189 MGMT_EVT_OP_IMG_MGMT_IMAGE_SLOT_STATE = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 6), 190 191 /** 192 * Callback when a slot list command outputs fields for an image, data is 193 * img_mgmt_slot_info_image(). 194 */ 195 MGMT_EVT_OP_IMG_MGMT_SLOT_INFO_IMAGE = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 7), 196 197 /** 198 * Callback when a slot list command outputs fields for a slot of an image, data is 199 * img_mgmt_slot_info_slot(). 200 */ 201 MGMT_EVT_OP_IMG_MGMT_SLOT_INFO_SLOT = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_IMG, 8), 202 203 /** Used to enable all img_mgmt_group events. */ 204 MGMT_EVT_OP_IMG_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_IMG), 205 }; 206 207 /** 208 * MGMT event opcodes for operating system management group. 209 */ 210 enum os_mgmt_group_events { 211 /** Callback when a reset command has been received, data is os_mgmt_reset_data(). */ 212 MGMT_EVT_OP_OS_MGMT_RESET = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 0), 213 214 /** Callback when an info command is processed, data is os_mgmt_info_check(). */ 215 MGMT_EVT_OP_OS_MGMT_INFO_CHECK = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 1), 216 217 /** Callback when an info command needs to output data, data is os_mgmt_info_append(). */ 218 MGMT_EVT_OP_OS_MGMT_INFO_APPEND = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 2), 219 220 /** Callback when a datetime get command has been received. */ 221 MGMT_EVT_OP_OS_MGMT_DATETIME_GET = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 3), 222 223 /** Callback when a datetime set command has been received, data is struct rtc_time(). */ 224 MGMT_EVT_OP_OS_MGMT_DATETIME_SET = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 4), 225 226 /** 227 * Callback when a bootloader info command has been received, data is 228 * os_mgmt_bootloader_info_data(). 229 */ 230 MGMT_EVT_OP_OS_MGMT_BOOTLOADER_INFO = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_OS, 5), 231 232 /** Used to enable all os_mgmt_group events. */ 233 MGMT_EVT_OP_OS_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_OS), 234 }; 235 236 /** 237 * MGMT event opcodes for settings management group. 238 */ 239 enum settings_mgmt_group_events { 240 /** Callback when a setting is read/written/deleted. */ 241 MGMT_EVT_OP_SETTINGS_MGMT_ACCESS = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_SETTINGS, 0), 242 243 /** Used to enable all settings_mgmt_group events. */ 244 MGMT_EVT_OP_SETTINGS_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_SETTINGS), 245 }; 246 247 /** 248 * MGMT event opcodes for enumeration management group. 249 */ 250 enum enum_mgmt_group_events { 251 /** Callback when fetching details on supported command groups. */ 252 MGMT_EVT_OP_ENUM_MGMT_DETAILS = MGMT_DEF_EVT_OP_ID(MGMT_EVT_GRP_ENUM, 0), 253 254 /** Used to enable all enum_mgmt_group events. */ 255 MGMT_EVT_OP_ENUM_MGMT_ALL = MGMT_DEF_EVT_OP_ALL(MGMT_EVT_GRP_ENUM), 256 }; 257 258 /** 259 * MGMT callback struct 260 */ 261 struct mgmt_callback { 262 /** Entry list node. */ 263 sys_snode_t node; 264 265 /** Callback that will be called. */ 266 mgmt_cb callback; 267 268 /** 269 * MGMT_EVT_[...] Event ID for handler to be called on. This has special meaning if 270 * #MGMT_EVT_OP_ALL is used (which will cover all events for all groups), or 271 * MGMT_EVT_OP_*_MGMT_ALL (which will cover all events for a single group). For events 272 * that are part of a single group, they can be or'd together for this to have one 273 * registration trigger on multiple events, please note that this will only work for 274 * a single group, to register for events in different groups, they must be registered 275 * separately. 276 */ 277 uint32_t event_id; 278 }; 279 280 /** 281 * Arguments for #MGMT_EVT_OP_CMD_RECV, #MGMT_EVT_OP_CMD_STATUS and #MGMT_EVT_OP_CMD_DONE 282 */ 283 struct mgmt_evt_op_cmd_arg { 284 /** #mcumgr_group_t */ 285 uint16_t group; 286 287 /** Message ID within group */ 288 uint8_t id; 289 290 union { 291 /** #mcumgr_op_t used in #MGMT_EVT_OP_CMD_RECV */ 292 uint8_t op; 293 294 /** #mcumgr_err_t, used in #MGMT_EVT_OP_CMD_DONE */ 295 int err; 296 297 /** #img_mgmt_id_upload_t, used in #MGMT_EVT_OP_CMD_STATUS */ 298 int status; 299 }; 300 }; 301 302 /** 303 * @brief Get event ID index from event. 304 * 305 * @param event Event to get ID index from. 306 * 307 * @return Event index. 308 */ 309 uint8_t mgmt_evt_get_index(uint32_t event); 310 311 /** 312 * @brief This function is called to notify registered callbacks about mcumgr notifications/events. 313 * 314 * @param event #mcumgr_op_t. 315 * @param data Optional event argument. 316 * @param data_size Size of optional event argument (0 if none). 317 * @param err_rc Pointer to rc value. 318 * @param err_group Pointer to group value. 319 * 320 * @return #mgmt_cb_return either #MGMT_CB_OK if all handlers returned it, or 321 * #MGMT_CB_ERROR_RC if the first failed handler returned an SMP error (in 322 * which case ``err_rc`` will be updated with the SMP error) or 323 * #MGMT_CB_ERROR_ERR if the first failed handler returned a ret group and 324 * error (in which case ``err_group`` will be updated with the failed group 325 * ID and ``err_rc`` will be updated with the group-specific error code). 326 */ 327 enum mgmt_cb_return mgmt_callback_notify(uint32_t event, void *data, size_t data_size, 328 int32_t *err_rc, uint16_t *err_group); 329 330 /** 331 * @brief Register event callback function. 332 * 333 * @param callback Callback struct. 334 */ 335 void mgmt_callback_register(struct mgmt_callback *callback); 336 337 /** 338 * @brief Unregister event callback function. 339 * 340 * @param callback Callback struct. 341 */ 342 void mgmt_callback_unregister(struct mgmt_callback *callback); 343 344 /** 345 * @} 346 */ 347 348 #ifdef __cplusplus 349 } 350 #endif 351 352 #endif /* H_MCUMGR_CALLBACKS_ */ 353