| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| #ifndef H_MGMT_MGMT_ |
| #define H_MGMT_MGMT_ |
| |
| #include <inttypes.h> |
| #include "tinycbor/cbor.h" |
| |
| #ifdef __cplusplus |
| extern "C" { |
| #endif |
| |
| /* MTU for newtmgr responses */ |
| #define MGMT_MAX_MTU 1024 |
| |
| /** Opcodes; encoded in first byte of header. */ |
| #define MGMT_OP_READ 0 |
| #define MGMT_OP_READ_RSP 1 |
| #define MGMT_OP_WRITE 2 |
| #define MGMT_OP_WRITE_RSP 3 |
| |
| /** |
| * The first 64 groups are reserved for system level mcumgr commands. |
| * Per-user commands are then defined after group 64. |
| */ |
| #define MGMT_GROUP_ID_OS 0 |
| #define MGMT_GROUP_ID_IMAGE 1 |
| #define MGMT_GROUP_ID_STAT 2 |
| #define MGMT_GROUP_ID_CONFIG 3 |
| #define MGMT_GROUP_ID_LOG 4 |
| #define MGMT_GROUP_ID_CRASH 5 |
| #define MGMT_GROUP_ID_SPLIT 6 |
| #define MGMT_GROUP_ID_RUN 7 |
| #define MGMT_GROUP_ID_FS 8 |
| #define MGMT_GROUP_ID_SHELL 9 |
| #define MGMT_GROUP_ID_PERUSER 64 |
| |
| /** |
| * mcumgr error codes. |
| */ |
| #define MGMT_ERR_EOK 0 |
| #define MGMT_ERR_EUNKNOWN 1 |
| #define MGMT_ERR_ENOMEM 2 |
| #define MGMT_ERR_EINVAL 3 |
| #define MGMT_ERR_ETIMEOUT 4 |
| #define MGMT_ERR_ENOENT 5 |
| #define MGMT_ERR_EBADSTATE 6 /* Current state disallows command. */ |
| #define MGMT_ERR_EMSGSIZE 7 /* Response too large. */ |
| #define MGMT_ERR_ENOTSUP 8 /* Command not supported. */ |
| #define MGMT_ERR_ECORRUPT 9 /* Corrupt */ |
| #define MGMT_ERR_EPERUSER 256 |
| |
| #define MGMT_HDR_SIZE 8 |
| |
| /* |
| * MGMT event opcodes. |
| */ |
| #define MGMT_EVT_OP_CMD_RECV 0x01 |
| #define MGMT_EVT_OP_CMD_STATUS 0x02 |
| #define MGMT_EVT_OP_CMD_DONE 0x03 |
| |
| struct mgmt_hdr { |
| #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ |
| uint8_t nh_op:3; /* MGMT_OP_[...] */ |
| uint8_t _res1:5; |
| #endif |
| #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ |
| uint8_t _res1:5; |
| uint8_t nh_op:3; /* MGMT_OP_[...] */ |
| #endif |
| uint8_t nh_flags; /* Reserved for future flags */ |
| uint16_t nh_len; /* Length of the payload */ |
| uint16_t nh_group; /* MGMT_GROUP_ID_[...] */ |
| uint8_t nh_seq; /* Sequence number */ |
| uint8_t nh_id; /* Message ID within group */ |
| }; |
| |
| #define nmgr_hdr mgmt_hdr |
| |
| /* |
| * MGMT_EVT_OP_CMD_STATUS argument |
| */ |
| struct mgmt_evt_op_cmd_status_arg { |
| int status; |
| }; |
| |
| /* |
| * MGMT_EVT_OP_CMD_DONE argument |
| */ |
| struct mgmt_evt_op_cmd_done_arg { |
| int err; /* MGMT_ERR_[...] */ |
| }; |
| |
| /** @typedef mgmt_on_evt_cb |
| * @brief Function to be called on MGMT event. |
| * |
| * This callback function is used to notify application about mgmt event. |
| * |
| * @param opcode MGMT_EVT_OP_[...]. |
| * @param group MGMT_GROUP_ID_[...]. |
| * @param id Message ID within group. |
| * @param arg Optional event argument. |
| */ |
| typedef void mgmt_on_evt_cb(uint8_t opcode, uint16_t group, uint8_t id, |
| void *arg); |
| |
| /** @typedef mgmt_alloc_rsp_fn |
| * @brief Allocates a buffer suitable for holding a response. |
| * |
| * If a source buf is provided, its user data is copied into the new buffer. |
| * |
| * @param src_buf An optional source buffer to copy user data |
| * from. |
| * @param arg Optional streamer argument. |
| * |
| * @return Newly-allocated buffer on success |
| * NULL on failure. |
| */ |
| typedef void *mgmt_alloc_rsp_fn(const void *src_buf, void *arg); |
| |
| /** @typedef mgmt_trim_front_fn |
| * @brief Trims data from the front of a buffer. |
| * |
| * If the amount to trim exceeds the size of the buffer, the buffer is |
| * truncated to a length of 0. |
| * |
| * @param buf The buffer to trim. |
| * @param len The number of bytes to remove. |
| * @param arg Optional streamer argument. |
| */ |
| typedef void mgmt_trim_front_fn(void *buf, size_t len, void *arg); |
| |
| /** @typedef mgmt_reset_buf_fn |
| * @brief Resets a buffer to a length of 0. |
| * |
| * The buffer's user data remains, but its payload is cleared. |
| * |
| * @param buf The buffer to reset. |
| * @param arg Optional streamer argument. |
| */ |
| typedef void mgmt_reset_buf_fn(void *buf, void *arg); |
| |
| /** @typedef mgmt_write_at_fn |
| * @brief Writes data to a CBOR encoder. |
| * |
| * Any existing data at the specified offset is overwritten by the new data. |
| * Any new data that extends past the buffer's current length is appended. |
| * |
| * @param writer The encoder to write to. |
| * @param offset The byte offset to write to, |
| * @param data The data to write. |
| * @param len The number of bytes to write. |
| * @param arg Optional streamer argument. |
| * |
| * @return 0 on success, MGMT_ERR_[...] code on failure. |
| */ |
| typedef int mgmt_write_at_fn(struct cbor_encoder_writer *writer, size_t offset, |
| const void *data, size_t len, void *arg); |
| |
| /** @typedef mgmt_init_reader_fn |
| * @brief Initializes a CBOR reader with the specified buffer. |
| * |
| * @param reader The reader to initialize. |
| * @param buf The buffer to configure the reader with. |
| * @param arg Optional streamer argument. |
| * |
| * @return 0 on success, MGMT_ERR_[...] code on failure. |
| */ |
| typedef int mgmt_init_reader_fn(struct cbor_decoder_reader *reader, void *buf, |
| void *arg); |
| |
| /** @typedef mgmt_init_writer_fn |
| * @brief Initializes a CBOR writer with the specified buffer. |
| * |
| * @param writer The writer to initialize. |
| * @param buf The buffer to configure the writer with. |
| * @param arg Optional streamer argument. |
| * |
| * @return 0 on success, MGMT_ERR_[...] code on failure. |
| */ |
| typedef int mgmt_init_writer_fn(struct cbor_encoder_writer *writer, void *buf, |
| void *arg); |
| |
| /** @typedef mgmt_init_writer_fn |
| * @brief Frees the specified buffer. |
| * |
| * @param buf The buffer to free. |
| * @param arg Optional streamer argument. |
| */ |
| typedef void mgmt_free_buf_fn(void *buf, void *arg); |
| |
| /** |
| * @brief Configuration for constructing a mgmt_streamer object. |
| */ |
| struct mgmt_streamer_cfg { |
| mgmt_alloc_rsp_fn *alloc_rsp; |
| mgmt_trim_front_fn *trim_front; |
| mgmt_reset_buf_fn *reset_buf; |
| mgmt_write_at_fn *write_at; |
| mgmt_init_reader_fn *init_reader; |
| mgmt_init_writer_fn *init_writer; |
| mgmt_free_buf_fn *free_buf; |
| }; |
| |
| /** |
| * @brief Decodes requests and encodes responses for any mcumgr protocol. |
| */ |
| struct mgmt_streamer { |
| const struct mgmt_streamer_cfg *cfg; |
| void *cb_arg; |
| struct cbor_decoder_reader *reader; |
| struct cbor_encoder_writer *writer; |
| }; |
| |
| /** |
| * @brief Context required by command handlers for parsing requests and writing |
| * responses. |
| */ |
| struct mgmt_ctxt { |
| struct CborEncoder encoder; |
| struct CborParser parser; |
| struct CborValue it; |
| }; |
| |
| /** @typedef mgmt_handler_fn |
| * @brief Processes a request and writes the corresponding response. |
| * |
| * A separate handler is required for each supported op-ID pair. |
| * |
| * @param ctxt The mcumgr context to use. |
| * |
| * @return 0 if a response was successfully encoded, |
| * MGMT_ERR_[...] code on failure. |
| */ |
| typedef int mgmt_handler_fn(struct mgmt_ctxt *ctxt); |
| |
| /** |
| * @brief Read handler and write handler for a single command ID. |
| */ |
| struct mgmt_handler { |
| mgmt_handler_fn *mh_read; |
| mgmt_handler_fn *mh_write; |
| }; |
| |
| /** |
| * @brief A collection of handlers for an entire command group. |
| */ |
| struct mgmt_group { |
| /** Points to the next group in the list. */ |
| struct mgmt_group *mg_next; |
| |
| /** Array of handlers; one entry per command ID. */ |
| const struct mgmt_handler *mg_handlers; |
| uint16_t mg_handlers_count; |
| |
| /* The numeric ID of this group. */ |
| uint16_t mg_group_id; |
| }; |
| |
| /** |
| * @brief Uses the specified streamer to allocates a response buffer. |
| * |
| * If a source buf is provided, its user data is copied into the new buffer. |
| * |
| * @param streamer The streamer providing the callback. |
| * @param src_buf An optional source buffer to copy user data |
| * from. |
| * |
| * @return Newly-allocated buffer on success |
| * NULL on failure. |
| */ |
| void *mgmt_streamer_alloc_rsp(struct mgmt_streamer *streamer, |
| const void *src_buf); |
| |
| /** |
| * @brief Uses the specified streamer to trim data from the front of a buffer. |
| * |
| * If the amount to trim exceeds the size of the buffer, the buffer is |
| * truncated to a length of 0. |
| * |
| * @param streamer The streamer providing the callback. |
| * @param buf The buffer to trim. |
| * @param len The number of bytes to remove. |
| */ |
| void mgmt_streamer_trim_front(struct mgmt_streamer *streamer, void *buf, |
| size_t len); |
| |
| /** |
| * @brief Uses the specified streamer to reset a buffer to a length of 0. |
| * |
| * The buffer's user data remains, but its payload is cleared. |
| * |
| * @param streamer The streamer providing the callback. |
| * @param buf The buffer to reset. |
| */ |
| void mgmt_streamer_reset_buf(struct mgmt_streamer *streamer, void *buf); |
| |
| /** |
| * @brief Uses the specified streamer to write data to a CBOR encoder. |
| * |
| * Any existing data at the specified offset is overwritten by the new data. |
| * Any new data that extends past the buffer's current length is appended. |
| * |
| * @param streamer The streamer providing the callback. |
| * @param writer The encoder to write to. |
| * @param offset The byte offset to write to, |
| * @param data The data to write. |
| * @param len The number of bytes to write. |
| * |
| * @return 0 on success, MGMT_ERR_[...] code on failure. |
| */ |
| int mgmt_streamer_write_at(struct mgmt_streamer *streamer, size_t offset, |
| const void *data, int len); |
| |
| /** |
| * @brief Uses the specified streamer to initialize a CBOR reader. |
| * |
| * @param streamer The streamer providing the callback. |
| * @param reader The reader to initialize. |
| * @param buf The buffer to configure the reader with. |
| * |
| * @return 0 on success, MGMT_ERR_[...] code on failure. |
| */ |
| int mgmt_streamer_init_reader(struct mgmt_streamer *streamer, void *buf); |
| |
| /** |
| * @brief Uses the specified streamer to initializes a CBOR writer. |
| * |
| * @param streamer The streamer providing the callback. |
| * @param writer The writer to initialize. |
| * @param buf The buffer to configure the writer with. |
| * |
| * @return 0 on success, MGMT_ERR_[...] code on failure. |
| */ |
| int mgmt_streamer_init_writer(struct mgmt_streamer *streamer, void *buf); |
| |
| /** |
| * @brief Uses the specified streamer to free a buffer. |
| * |
| * @param streamer The streamer providing the callback. |
| * @param buf The buffer to free. |
| */ |
| void mgmt_streamer_free_buf(struct mgmt_streamer *streamer, void *buf); |
| |
| /** |
| * @brief Registers a full command group. |
| * |
| * @param group The group to register. |
| */ |
| void mgmt_register_group(struct mgmt_group *group); |
| |
| /** |
| * @brief Unregisters a full command group. |
| * |
| * @param group The group to register. |
| */ |
| void |
| mgmt_unregister_group(struct mgmt_group *group); |
| |
| /** |
| * @brief Finds a registered command handler. |
| * |
| * @param group_id The group of the command to find. |
| * @param command_id The ID of the command to find. |
| * |
| * @return The requested command handler on success; |
| * NULL on failure. |
| */ |
| const struct mgmt_handler *mgmt_find_handler(uint16_t group_id, |
| uint16_t command_id); |
| |
| /** |
| * @brief Encodes a response status into the specified management context. |
| * |
| * @param ctxt The management context to encode into. |
| * @param status The response status to write. |
| * |
| * @return 0 on success, MGMT_ERR_[...] code on failure. |
| */ |
| int mgmt_write_rsp_status(struct mgmt_ctxt *ctxt, int status); |
| |
| /** |
| * @brief Initializes a management context object with the specified streamer. |
| * |
| * @param ctxt The context object to initialize. |
| * @param streamer The streamer that will be used with the |
| * context. |
| * |
| * @return 0 on success, MGMT_ERR_[...] code on failure. |
| */ |
| int mgmt_ctxt_init(struct mgmt_ctxt *ctxt, struct mgmt_streamer *streamer); |
| |
| /** |
| * @brief Converts a CBOR status code to a MGMT_ERR_[...] code. |
| * |
| * @param cbor_status The CBOR status code to convert. |
| * |
| * @return The corresponding MGMT_ERR_[,,,] code. |
| */ |
| int mgmt_err_from_cbor(int cbor_status); |
| |
| /** |
| * @brief Byte-swaps an mcumgr header from network to host byte order. |
| * |
| * @param hdr The mcumgr header to byte-swap. |
| */ |
| void mgmt_ntoh_hdr(struct mgmt_hdr *hdr); |
| |
| /** |
| * @brief Byte-swaps an mcumgr header from host to network byte order. |
| * |
| * @param hdr The mcumgr header to byte-swap. |
| */ |
| void mgmt_hton_hdr(struct mgmt_hdr *hdr); |
| |
| /** |
| * @brief Register event callback function. |
| * |
| * @param cb Callback function. |
| */ |
| void mgmt_register_evt_cb(mgmt_on_evt_cb *cb); |
| |
| /** |
| * @brief This function is called to notify about mgmt event. |
| * |
| * @param opcode MGMT_EVT_OP_[...]. |
| * @param group MGMT_GROUP_ID_[...]. |
| * @param id Message ID within group. |
| * @param arg Optional event argument. |
| */ |
| void mgmt_evt(uint8_t opcode, uint16_t group, uint8_t id, void *arg); |
| |
| #ifdef __cplusplus |
| } |
| #endif |
| |
| #endif /* MGMT_MGMT_H_ */ |