1 /* 2 * Licensed to the Apache Software Foundation (ASF) under one 3 * or more contributor license agreements. See the NOTICE file 4 * distributed with this work for additional information 5 * regarding copyright ownership. The ASF licenses this file 6 * to you under the Apache License, Version 2.0 (the 7 * "License"); you may not use this file except in compliance 8 * with the License. You may obtain a copy of the License at 9 * 10 * http://www.apache.org/licenses/LICENSE-2.0 11 * 12 * Unless required by applicable law or agreed to in writing, 13 * software distributed under the License is distributed on an 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 15 * KIND, either express or implied. See the License for the 16 * specific language governing permissions and limitations 17 * under the License. 18 */ 19 20 #ifndef H_MGMT_MGMT_ 21 #define H_MGMT_MGMT_ 22 23 #include <inttypes.h> 24 #include "tinycbor/cbor.h" 25 26 #ifdef __cplusplus 27 extern "C" { 28 #endif 29 30 /* MTU for newtmgr responses */ 31 #define MGMT_MAX_MTU 1024 32 33 /** Opcodes; encoded in first byte of header. */ 34 #define MGMT_OP_READ 0 35 #define MGMT_OP_READ_RSP 1 36 #define MGMT_OP_WRITE 2 37 #define MGMT_OP_WRITE_RSP 3 38 39 /** 40 * The first 64 groups are reserved for system level mcumgr commands. 41 * Per-user commands are then defined after group 64. 42 */ 43 #define MGMT_GROUP_ID_OS 0 44 #define MGMT_GROUP_ID_IMAGE 1 45 #define MGMT_GROUP_ID_STAT 2 46 #define MGMT_GROUP_ID_CONFIG 3 47 #define MGMT_GROUP_ID_LOG 4 48 #define MGMT_GROUP_ID_CRASH 5 49 #define MGMT_GROUP_ID_SPLIT 6 50 #define MGMT_GROUP_ID_RUN 7 51 #define MGMT_GROUP_ID_FS 8 52 #define MGMT_GROUP_ID_SHELL 9 53 #define MGMT_GROUP_ID_PERUSER 64 54 55 /** 56 * mcumgr error codes. 57 */ 58 #define MGMT_ERR_EOK 0 59 #define MGMT_ERR_EUNKNOWN 1 60 #define MGMT_ERR_ENOMEM 2 61 #define MGMT_ERR_EINVAL 3 62 #define MGMT_ERR_ETIMEOUT 4 63 #define MGMT_ERR_ENOENT 5 64 #define MGMT_ERR_EBADSTATE 6 /* Current state disallows command. */ 65 #define MGMT_ERR_EMSGSIZE 7 /* Response too large. */ 66 #define MGMT_ERR_ENOTSUP 8 /* Command not supported. */ 67 #define MGMT_ERR_ECORRUPT 9 /* Corrupt */ 68 #define MGMT_ERR_EPERUSER 256 69 70 #define MGMT_HDR_SIZE 8 71 72 /* 73 * MGMT event opcodes. 74 */ 75 #define MGMT_EVT_OP_CMD_RECV 0x01 76 #define MGMT_EVT_OP_CMD_STATUS 0x02 77 #define MGMT_EVT_OP_CMD_DONE 0x03 78 79 struct mgmt_hdr { 80 #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ 81 uint8_t nh_op:3; /* MGMT_OP_[...] */ 82 uint8_t _res1:5; 83 #endif 84 #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ 85 uint8_t _res1:5; 86 uint8_t nh_op:3; /* MGMT_OP_[...] */ 87 #endif 88 uint8_t nh_flags; /* Reserved for future flags */ 89 uint16_t nh_len; /* Length of the payload */ 90 uint16_t nh_group; /* MGMT_GROUP_ID_[...] */ 91 uint8_t nh_seq; /* Sequence number */ 92 uint8_t nh_id; /* Message ID within group */ 93 }; 94 95 #define nmgr_hdr mgmt_hdr 96 97 /* 98 * MGMT_EVT_OP_CMD_STATUS argument 99 */ 100 struct mgmt_evt_op_cmd_status_arg { 101 int status; 102 }; 103 104 /* 105 * MGMT_EVT_OP_CMD_DONE argument 106 */ 107 struct mgmt_evt_op_cmd_done_arg { 108 int err; /* MGMT_ERR_[...] */ 109 }; 110 111 /** @typedef mgmt_on_evt_cb 112 * @brief Function to be called on MGMT event. 113 * 114 * This callback function is used to notify application about mgmt event. 115 * 116 * @param opcode MGMT_EVT_OP_[...]. 117 * @param group MGMT_GROUP_ID_[...]. 118 * @param id Message ID within group. 119 * @param arg Optional event argument. 120 */ 121 typedef void mgmt_on_evt_cb(uint8_t opcode, uint16_t group, uint8_t id, 122 void *arg); 123 124 /** @typedef mgmt_alloc_rsp_fn 125 * @brief Allocates a buffer suitable for holding a response. 126 * 127 * If a source buf is provided, its user data is copied into the new buffer. 128 * 129 * @param src_buf An optional source buffer to copy user data 130 * from. 131 * @param arg Optional streamer argument. 132 * 133 * @return Newly-allocated buffer on success 134 * NULL on failure. 135 */ 136 typedef void *mgmt_alloc_rsp_fn(const void *src_buf, void *arg); 137 138 /** @typedef mgmt_trim_front_fn 139 * @brief Trims data from the front of a buffer. 140 * 141 * If the amount to trim exceeds the size of the buffer, the buffer is 142 * truncated to a length of 0. 143 * 144 * @param buf The buffer to trim. 145 * @param len The number of bytes to remove. 146 * @param arg Optional streamer argument. 147 */ 148 typedef void mgmt_trim_front_fn(void *buf, size_t len, void *arg); 149 150 /** @typedef mgmt_reset_buf_fn 151 * @brief Resets a buffer to a length of 0. 152 * 153 * The buffer's user data remains, but its payload is cleared. 154 * 155 * @param buf The buffer to reset. 156 * @param arg Optional streamer argument. 157 */ 158 typedef void mgmt_reset_buf_fn(void *buf, void *arg); 159 160 /** @typedef mgmt_write_at_fn 161 * @brief Writes data to a CBOR encoder. 162 * 163 * Any existing data at the specified offset is overwritten by the new data. 164 * Any new data that extends past the buffer's current length is appended. 165 * 166 * @param writer The encoder to write to. 167 * @param offset The byte offset to write to, 168 * @param data The data to write. 169 * @param len The number of bytes to write. 170 * @param arg Optional streamer argument. 171 * 172 * @return 0 on success, MGMT_ERR_[...] code on failure. 173 */ 174 typedef int mgmt_write_at_fn(struct cbor_encoder_writer *writer, size_t offset, 175 const void *data, size_t len, void *arg); 176 177 /** @typedef mgmt_init_reader_fn 178 * @brief Initializes a CBOR reader with the specified buffer. 179 * 180 * @param reader The reader to initialize. 181 * @param buf The buffer to configure the reader with. 182 * @param arg Optional streamer argument. 183 * 184 * @return 0 on success, MGMT_ERR_[...] code on failure. 185 */ 186 typedef int mgmt_init_reader_fn(struct cbor_decoder_reader *reader, void *buf, 187 void *arg); 188 189 /** @typedef mgmt_init_writer_fn 190 * @brief Initializes a CBOR writer with the specified buffer. 191 * 192 * @param writer The writer to initialize. 193 * @param buf The buffer to configure the writer with. 194 * @param arg Optional streamer argument. 195 * 196 * @return 0 on success, MGMT_ERR_[...] code on failure. 197 */ 198 typedef int mgmt_init_writer_fn(struct cbor_encoder_writer *writer, void *buf, 199 void *arg); 200 201 /** @typedef mgmt_init_writer_fn 202 * @brief Frees the specified buffer. 203 * 204 * @param buf The buffer to free. 205 * @param arg Optional streamer argument. 206 */ 207 typedef void mgmt_free_buf_fn(void *buf, void *arg); 208 209 /** 210 * @brief Configuration for constructing a mgmt_streamer object. 211 */ 212 struct mgmt_streamer_cfg { 213 mgmt_alloc_rsp_fn *alloc_rsp; 214 mgmt_trim_front_fn *trim_front; 215 mgmt_reset_buf_fn *reset_buf; 216 mgmt_write_at_fn *write_at; 217 mgmt_init_reader_fn *init_reader; 218 mgmt_init_writer_fn *init_writer; 219 mgmt_free_buf_fn *free_buf; 220 }; 221 222 /** 223 * @brief Decodes requests and encodes responses for any mcumgr protocol. 224 */ 225 struct mgmt_streamer { 226 const struct mgmt_streamer_cfg *cfg; 227 void *cb_arg; 228 struct cbor_decoder_reader *reader; 229 struct cbor_encoder_writer *writer; 230 }; 231 232 /** 233 * @brief Context required by command handlers for parsing requests and writing 234 * responses. 235 */ 236 struct mgmt_ctxt { 237 struct CborEncoder encoder; 238 struct CborParser parser; 239 struct CborValue it; 240 }; 241 242 /** @typedef mgmt_handler_fn 243 * @brief Processes a request and writes the corresponding response. 244 * 245 * A separate handler is required for each supported op-ID pair. 246 * 247 * @param ctxt The mcumgr context to use. 248 * 249 * @return 0 if a response was successfully encoded, 250 * MGMT_ERR_[...] code on failure. 251 */ 252 typedef int mgmt_handler_fn(struct mgmt_ctxt *ctxt); 253 254 /** 255 * @brief Read handler and write handler for a single command ID. 256 */ 257 struct mgmt_handler { 258 mgmt_handler_fn *mh_read; 259 mgmt_handler_fn *mh_write; 260 }; 261 262 /** 263 * @brief A collection of handlers for an entire command group. 264 */ 265 struct mgmt_group { 266 /** Points to the next group in the list. */ 267 struct mgmt_group *mg_next; 268 269 /** Array of handlers; one entry per command ID. */ 270 const struct mgmt_handler *mg_handlers; 271 uint16_t mg_handlers_count; 272 273 /* The numeric ID of this group. */ 274 uint16_t mg_group_id; 275 }; 276 277 /** 278 * @brief Uses the specified streamer to allocates a response buffer. 279 * 280 * If a source buf is provided, its user data is copied into the new buffer. 281 * 282 * @param streamer The streamer providing the callback. 283 * @param src_buf An optional source buffer to copy user data 284 * from. 285 * 286 * @return Newly-allocated buffer on success 287 * NULL on failure. 288 */ 289 void *mgmt_streamer_alloc_rsp(struct mgmt_streamer *streamer, 290 const void *src_buf); 291 292 /** 293 * @brief Uses the specified streamer to trim data from the front of a buffer. 294 * 295 * If the amount to trim exceeds the size of the buffer, the buffer is 296 * truncated to a length of 0. 297 * 298 * @param streamer The streamer providing the callback. 299 * @param buf The buffer to trim. 300 * @param len The number of bytes to remove. 301 */ 302 void mgmt_streamer_trim_front(struct mgmt_streamer *streamer, void *buf, 303 size_t len); 304 305 /** 306 * @brief Uses the specified streamer to reset a buffer to a length of 0. 307 * 308 * The buffer's user data remains, but its payload is cleared. 309 * 310 * @param streamer The streamer providing the callback. 311 * @param buf The buffer to reset. 312 */ 313 void mgmt_streamer_reset_buf(struct mgmt_streamer *streamer, void *buf); 314 315 /** 316 * @brief Uses the specified streamer to write data to a CBOR encoder. 317 * 318 * Any existing data at the specified offset is overwritten by the new data. 319 * Any new data that extends past the buffer's current length is appended. 320 * 321 * @param streamer The streamer providing the callback. 322 * @param writer The encoder to write to. 323 * @param offset The byte offset to write to, 324 * @param data The data to write. 325 * @param len The number of bytes to write. 326 * 327 * @return 0 on success, MGMT_ERR_[...] code on failure. 328 */ 329 int mgmt_streamer_write_at(struct mgmt_streamer *streamer, size_t offset, 330 const void *data, int len); 331 332 /** 333 * @brief Uses the specified streamer to initialize a CBOR reader. 334 * 335 * @param streamer The streamer providing the callback. 336 * @param reader The reader to initialize. 337 * @param buf The buffer to configure the reader with. 338 * 339 * @return 0 on success, MGMT_ERR_[...] code on failure. 340 */ 341 int mgmt_streamer_init_reader(struct mgmt_streamer *streamer, void *buf); 342 343 /** 344 * @brief Uses the specified streamer to initializes a CBOR writer. 345 * 346 * @param streamer The streamer providing the callback. 347 * @param writer The writer to initialize. 348 * @param buf The buffer to configure the writer with. 349 * 350 * @return 0 on success, MGMT_ERR_[...] code on failure. 351 */ 352 int mgmt_streamer_init_writer(struct mgmt_streamer *streamer, void *buf); 353 354 /** 355 * @brief Uses the specified streamer to free a buffer. 356 * 357 * @param streamer The streamer providing the callback. 358 * @param buf The buffer to free. 359 */ 360 void mgmt_streamer_free_buf(struct mgmt_streamer *streamer, void *buf); 361 362 /** 363 * @brief Registers a full command group. 364 * 365 * @param group The group to register. 366 */ 367 void mgmt_register_group(struct mgmt_group *group); 368 369 /** 370 * @brief Unregisters a full command group. 371 * 372 * @param group The group to register. 373 */ 374 void 375 mgmt_unregister_group(struct mgmt_group *group); 376 377 /** 378 * @brief Finds a registered command handler. 379 * 380 * @param group_id The group of the command to find. 381 * @param command_id The ID of the command to find. 382 * 383 * @return The requested command handler on success; 384 * NULL on failure. 385 */ 386 const struct mgmt_handler *mgmt_find_handler(uint16_t group_id, 387 uint16_t command_id); 388 389 /** 390 * @brief Encodes a response status into the specified management context. 391 * 392 * @param ctxt The management context to encode into. 393 * @param status The response status to write. 394 * 395 * @return 0 on success, MGMT_ERR_[...] code on failure. 396 */ 397 int mgmt_write_rsp_status(struct mgmt_ctxt *ctxt, int status); 398 399 /** 400 * @brief Initializes a management context object with the specified streamer. 401 * 402 * @param ctxt The context object to initialize. 403 * @param streamer The streamer that will be used with the 404 * context. 405 * 406 * @return 0 on success, MGMT_ERR_[...] code on failure. 407 */ 408 int mgmt_ctxt_init(struct mgmt_ctxt *ctxt, struct mgmt_streamer *streamer); 409 410 /** 411 * @brief Converts a CBOR status code to a MGMT_ERR_[...] code. 412 * 413 * @param cbor_status The CBOR status code to convert. 414 * 415 * @return The corresponding MGMT_ERR_[,,,] code. 416 */ 417 int mgmt_err_from_cbor(int cbor_status); 418 419 /** 420 * @brief Byte-swaps an mcumgr header from network to host byte order. 421 * 422 * @param hdr The mcumgr header to byte-swap. 423 */ 424 void mgmt_ntoh_hdr(struct mgmt_hdr *hdr); 425 426 /** 427 * @brief Byte-swaps an mcumgr header from host to network byte order. 428 * 429 * @param hdr The mcumgr header to byte-swap. 430 */ 431 void mgmt_hton_hdr(struct mgmt_hdr *hdr); 432 433 /** 434 * @brief Register event callback function. 435 * 436 * @param cb Callback function. 437 */ 438 void mgmt_register_evt_cb(mgmt_on_evt_cb *cb); 439 440 /** 441 * @brief This function is called to notify about mgmt event. 442 * 443 * @param opcode MGMT_EVT_OP_[...]. 444 * @param group MGMT_GROUP_ID_[...]. 445 * @param id Message ID within group. 446 * @param arg Optional event argument. 447 */ 448 void mgmt_evt(uint8_t opcode, uint16_t group, uint8_t id, void *arg); 449 450 #ifdef __cplusplus 451 } 452 #endif 453 454 #endif /* MGMT_MGMT_H_ */ 455