/* * 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 #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_ */