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