From 680807e5b066d417f1f676c0e8d629daaa8adf70 Mon Sep 17 00:00:00 2001 From: Vipul Rahane Date: Mon, 18 Mar 2024 11:02:52 -0700 Subject: [PATCH] log_mgmt: Add support for number of log entries in mcumgr --- cmd/log_mgmt/include/log_mgmt/log_mgmt.h | 25 ++--- .../include/log_mgmt/log_mgmt_config.h | 1 + cmd/log_mgmt/include/log_mgmt/log_mgmt_impl.h | 11 +++ .../port/mynewt/src/mynewt_log_mgmt.c | 28 ++++++ cmd/log_mgmt/src/log_mgmt.c | 95 +++++++++++++++++++ 5 files changed, 149 insertions(+), 11 deletions(-) diff --git a/cmd/log_mgmt/include/log_mgmt/log_mgmt.h b/cmd/log_mgmt/include/log_mgmt/log_mgmt.h index 6d046cd9..84d99878 100644 --- a/cmd/log_mgmt/include/log_mgmt/log_mgmt.h +++ b/cmd/log_mgmt/include/log_mgmt/log_mgmt.h @@ -30,10 +30,10 @@ extern "C" { * LOG MGMT specific error codes, 0 -> 6, 8 are same as mcumgr, * 7 and 9 are different for backwards compatibility with newtmgr. */ -#define LOG_MGMT_ERR_EOK (0) -#define LOG_MGMT_ERR_EUNKNOWN (1) -#define LOG_MGMT_ERR_ENOMEM (2) -#define LOG_MGMT_ERR_EINVAL (3) +#define LOG_MGMT_ERR_EOK (0) +#define LOG_MGMT_ERR_EUNKNOWN (1) +#define LOG_MGMT_ERR_ENOMEM (2) +#define LOG_MGMT_ERR_EINVAL (3) #define LOG_MGMT_ERR_ETIMEOUT (4) #define LOG_MGMT_ERR_ENOENT (5) #define LOG_MGMT_ERR_EBADSTATE (6) /* Current state disallows command. */ @@ -45,12 +45,13 @@ extern "C" { /** * Command IDs for log management group. */ -#define LOG_MGMT_ID_SHOW 0 -#define LOG_MGMT_ID_CLEAR 1 -#define LOG_MGMT_ID_APPEND 2 -#define LOG_MGMT_ID_MODULE_LIST 3 -#define LOG_MGMT_ID_LEVEL_LIST 4 -#define LOG_MGMT_ID_LOGS_LIST 5 +#define LOG_MGMT_ID_SHOW 0 +#define LOG_MGMT_ID_CLEAR 1 +#define LOG_MGMT_ID_APPEND 2 +#define LOG_MGMT_ID_MODULE_LIST 3 +#define LOG_MGMT_ID_LEVEL_LIST 4 +#define LOG_MGMT_ID_LOGS_LIST 5 +#define LOG_MGMT_ID_NUM_ENTRIES 6 /** @brief Log output is streamed without retention (e.g., console). */ #define LOG_MGMT_TYPE_STREAM 0 @@ -62,7 +63,8 @@ extern "C" { #define LOG_MGMT_TYPE_STORAGE 2 /* @brief Flags used to indicate type of data in reserved payload. */ -#define LOG_MGMT_FLAGS_IMG_HASH (1 << 0) +#define LOG_MGMT_FLAGS_IMG_HASH (1 << 0) +#define LOG_MGMT_FLAGS_NUM_ENTRIES (1 << 1) /* @brief Log entry types. */ #define LOG_MGMT_ETYPE_STRING 0 @@ -90,6 +92,7 @@ struct log_mgmt_entry { uint8_t type:4; uint8_t flags:4; const uint8_t *imghash; + uint32_t num_entries; size_t offset; size_t chunklen; void *ctxt; diff --git a/cmd/log_mgmt/include/log_mgmt/log_mgmt_config.h b/cmd/log_mgmt/include/log_mgmt/log_mgmt_config.h index 37d02f9a..261f7615 100644 --- a/cmd/log_mgmt/include/log_mgmt/log_mgmt_config.h +++ b/cmd/log_mgmt/include/log_mgmt/log_mgmt_config.h @@ -29,6 +29,7 @@ #define LOG_MGMT_MAX_RSP_LEN MYNEWT_VAL(LOG_MGMT_MAX_RSP_LEN) #define LOG_MGMT_READ_WATERMARK_UPDATE MYNEWT_VAL(LOG_READ_WATERMARK_UPDATE) #define LOG_MGMT_GLOBAL_IDX MYNEWT_VAL(LOG_GLOBAL_IDX) +#define LOG_MGMT_NUM_ENTRIES MYNEWT_VAL(LOG_FLAGS_TLV_SUPPORT) #define LOG_MGMT_IMG_HASHLEN 4 #elif defined __ZEPHYR__ diff --git a/cmd/log_mgmt/include/log_mgmt/log_mgmt_impl.h b/cmd/log_mgmt/include/log_mgmt/log_mgmt_impl.h index 81b65d34..4013bf29 100644 --- a/cmd/log_mgmt/include/log_mgmt/log_mgmt_impl.h +++ b/cmd/log_mgmt/include/log_mgmt/log_mgmt_impl.h @@ -124,6 +124,17 @@ int log_mgmt_impl_clear(const char *log_name); int log_mgmt_impl_set_watermark(const struct log_mgmt_log *log, int index); +/** + * @brief Get number of log entries since a specified log index + * + * @param log Log pointer + * @param index Log ndex + * + * @return 0 on success, non-zero on failure + */ +int +log_mgmt_impl_get_num_entries(const struct log_mgmt_log *log, int index, uint32_t *entries); + #ifdef __cplusplus } #endif diff --git a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c index 6bdf6fba..0b800ff5 100644 --- a/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c +++ b/cmd/log_mgmt/port/mynewt/src/mynewt_log_mgmt.c @@ -74,6 +74,32 @@ log_mgmt_mynewt_err_map(int mynewt_os_err) } } +int +log_mgmt_impl_get_num_entries(const struct log_mgmt_log *log, int index, uint32_t *entries) +{ +#if MYNEWT_VAL(LOG_FLAGS_TLV_SUPPORT) + struct log *tmplog; + uint32_t tmp_entries = 0; + int rc = 0; + + tmplog = mynewt_log_mgmt_find_log(log->name); + if (tmplog) { + rc = log_mgmt_mynewt_err_map(log_get_entries(tmplog, index, &tmp_entries)); + } else { + *entries = tmp_entries; + rc = LOG_MGMT_ERR_ENOENT; + } + + if (!rc) { + *entries = tmp_entries; + } + + return rc; +#else + return LOG_MGMT_ERR_ENOTSUP; +#endif +} + int log_mgmt_impl_set_watermark(const struct log_mgmt_log *log, int index) { @@ -196,6 +222,8 @@ mynewt_log_mgmt_walk_cb(struct log *log, struct log_offset *log_offset, entry.flags = leh->ue_flags; entry.imghash = (leh->ue_flags & LOG_FLAGS_IMG_HASH) ? leh->ue_imghash : NULL; + entry.num_entries = (leh->ue_flags & LOG_FLAGS_TLV_SUPPORT) ? + leh->ue_num_entries : 0; entry.len = len; entry.data = mynewt_log_mgmt_walk_arg->chunk; diff --git a/cmd/log_mgmt/src/log_mgmt.c b/cmd/log_mgmt/src/log_mgmt.c index 9f24b728..ee286565 100644 --- a/cmd/log_mgmt/src/log_mgmt.c +++ b/cmd/log_mgmt/src/log_mgmt.c @@ -57,6 +57,7 @@ static mgmt_handler_fn log_mgmt_clear; static mgmt_handler_fn log_mgmt_module_list; static mgmt_handler_fn log_mgmt_level_list; static mgmt_handler_fn log_mgmt_logs_list; +static mgmt_handler_fn log_mgmt_num_entries; static struct mgmt_handler log_mgmt_handlers[] = { [LOG_MGMT_ID_SHOW] = { log_mgmt_show, NULL }, @@ -64,6 +65,7 @@ static struct mgmt_handler log_mgmt_handlers[] = { [LOG_MGMT_ID_MODULE_LIST] = { log_mgmt_module_list, NULL }, [LOG_MGMT_ID_LEVEL_LIST] = { log_mgmt_level_list, NULL }, [LOG_MGMT_ID_LOGS_LIST] = { log_mgmt_logs_list, NULL }, + [LOG_MGMT_ID_NUM_ENTRIES] = { log_mgmt_num_entries, NULL }, }; #define LOG_MGMT_HANDLER_CNT \ @@ -125,6 +127,11 @@ log_mgmt_encode_entry(CborEncoder *enc, const struct log_mgmt_entry *entry, LOG_MGMT_IMG_HASHLEN); } + if (entry->flags & LOG_MGMT_FLAGS_NUM_ENTRIES) { + err |= cbor_encode_text_stringz(&lmec->mapenc, "num_entries"); + err |= cbor_encode_uint(&lmec->mapenc, entry->num_entries); + } + err |= cbor_encode_text_stringz(&lmec->mapenc, "msg"); /* @@ -454,6 +461,94 @@ log_mgmt_show(struct mgmt_ctxt *ctxt) return 0; } +/** + * Command handler: log mgmt number of entries since index + */ +static int +log_mgmt_num_entries(struct mgmt_ctxt *ctxt) +{ + char name[LOG_MGMT_NAME_LEN]; + struct log_mgmt_log log; + CborError err; + uint64_t index; + int name_len; + int log_idx; + int rc; + uint32_t entries = 0; + + const struct cbor_attr_t attr[] = { + { + .attribute = "log_name", + .type = CborAttrTextStringType, + .addr.string = name, + .len = sizeof(name), + }, + { + .attribute = "index", + .type = CborAttrUnsignedIntegerType, + .addr.uinteger = &index, + }, + { + .attribute = NULL, + }, + }; + + name[0] = '\0'; + rc = cbor_read_object(&ctxt->it, attr); + if (rc != 0) { + return LOG_MGMT_ERR_EINVAL; + } + name_len = strlen(name); + + (void)err; + err = 0; + + /* Iterate list of logs, encoding number of entries for the one that matches + * the client request + */ + for (log_idx = 0; ; log_idx++) { + rc = log_mgmt_impl_get_log(log_idx, &log); + if (rc == LOG_MGMT_ERR_ENOENT) { + /* Log list fully iterated. */ + if (name_len != 0) { + /* Client specified log name, but the log wasn't found. */ + rc = LOG_MGMT_ERR_ENOENT; + goto err; + } else { + break; + } + } else if (rc != 0) { + goto err; + } + + /* Stream logs cannot be read. */ + if (log.type != LOG_MGMT_TYPE_STREAM) { + if (name_len == 0 || strcmp(name, log.name) == 0) { +#if LOG_MGMT_NUM_ENTRIES + /* Get the number of entries since a specific log index */ + rc = log_mgmt_impl_get_num_entries(&log, index, &entries); + err |= cbor_encode_text_stringz(&ctxt->encoder, "num_entries"); + err |= cbor_encode_uint(&ctxt->encoder, entries); +#else + (void)entries; + rc = LOG_MGMT_ERR_ENOTSUP; +#endif + goto err; + } + } + } + +err: + err |= cbor_encode_text_stringz(&ctxt->encoder, "rc"); + err |= cbor_encode_int(&ctxt->encoder, rc); + + if (err != 0) { + return LOG_MGMT_ERR_ENOMEM; + } + + return 0; +} + /** * Command handler: log module_list */