From 49ef927f7d3e6c9be4e6a0b81ee3bea28960db11 Mon Sep 17 00:00:00 2001 From: Martin Willers Date: Mon, 17 May 2021 02:51:06 +0200 Subject: Make nonverbose mode non exclusive (#300) * Make Non-Verbose mode non-exclusive Switching to global Non-Verbose mode now does not force Verbose messages to also be sent as Non-Verbose ones anymore. That would not make any sense, because Verbose messages don't have a MessageId and thus are all getting the same MessageId of 65535. Instead, setting global "Non-Verbose" mode will allow both Verbose and Non-Verbose messages to be sent in a single session. The "Verbose-APIs" (e.g. dlt_user_log_write_start()) will then only write Verbose messages, whereas the "Non-Verbose APIs" (e.g. dlt_user_log_write_start_id()) will then only write Non-Verbose messages. Signed-off-by: Martin Willers --- doc/dlt_for_developers.md | 48 ++++++++++++++--------- include/dlt/dlt_user.h.in | 4 ++ src/lib/dlt_user.c | 98 +++++++++++++++++++++++++++++------------------ tests/gtest_dlt_user.cpp | 39 +++++++++++++++++++ 4 files changed, 133 insertions(+), 56 deletions(-) diff --git a/doc/dlt_for_developers.md b/doc/dlt_for_developers.md index 1b30f86..1c4ef53 100644 --- a/doc/dlt_for_developers.md +++ b/doc/dlt_for_developers.md @@ -560,9 +560,14 @@ int main(int argc, const char* argv[]) ### Logging command -DLT provides functions and macros for logging, whereas the interface for -Verbose and Non-Verbose differs. The following table shows an example of all 4 -types for logging using a constant string and an integer. +DLT provides functions that allow for flexible construction of messages +with an arbitrary number of arguments. Both Verbose and Non-Verbose +messages are supported, with different APIs. Sending a message using +these functions require multiple function calls, for starting message +construction, adding the arguments, and sending off the message. + +The following table shows an example of all 4 types for logging +using a constant string and an integer. #### Verbose vs. Non-Verbose API @@ -606,32 +611,39 @@ if (dlt_user_log_write_start_id(&ctx, &ctxdata, DLT_LOG_INFO, 42) > 0) { } ``` -Drawback of that solution is that the developer has to decide during -development if Verbose or Non-Verbose mode shall be used and the code most -likely ends up as written in the dlt-example-user application: +#### Statefulness of Verbose/Non-Verbose -``` -if (gflag) { - /* Non-verbose mode */ - DLT_LOG_ID(ctx, DLT_LOG_INFO, 42 /* unique msg ID */, DLT_INT(num), - DLT_STRING(text)); -} -else { - /* Verbose mode */ - DLT_LOG(ctx, DLT_LOG_INFO, DLT_INT(num), DLT_STRING(text)); -} -``` +The library uses a global state that applies to all logging commands being used. +If the library is in global "Verbose" mode, both the "Verbose" and the "Non-Verbose" +API calls shown above will always result in Verbose messages being sent. -##### Switching Verbose and Non-Verbose +However, if the library is in global "Non-Verbose" mode, it is possible to send +both Verbose and Non-Verbose messages in a single session; all "Verbose" APIs will +send Verbose messages, and all "Non-Verbose" APIs will send Non-Verbose messages. + +It does not make sense to send a Non-Verbose message via a Verbose API, as there +is then no sensible message ID, which is however mandatory when sending +Non-Verbose messages. + +#### Switching Verbose and Non-Verbose To switch Verbose/Non-Verbose mode (Verbose mode is default), the following APIs are available: +##### MACRO + ``` DLT_VERBOSE_MODE(); DLT_NONVERBOSE_MODE(); ``` +##### Function + +``` +dlt_verbose_mode(); +dlt_nonverbose_mode(); +``` + #### String arguments For string arguments, you can choose between ASCII and UTF-8 encoding. This diff --git a/include/dlt/dlt_user.h.in b/include/dlt/dlt_user.h.in index 817cf11..e4a1f06 100644 --- a/include/dlt/dlt_user.h.in +++ b/include/dlt/dlt_user.h.in @@ -136,6 +136,7 @@ typedef struct char *context_description; /**< description of context */ DltTimestampType use_timestamp; /**< whether to use user-supplied timestamps */ uint32_t user_timestamp; /**< user-supplied timestamp to use */ + int8_t verbose_mode; /**< verbose mode: 1 enabled, 0 disabled */ } DltContextData; typedef struct @@ -940,6 +941,9 @@ DltReturnValue dlt_user_check_library_version(const char *user_major_version, co /** * Switch to non-verbose mode * + * This does not force all messages to be sent as Non-Verbose ones, as that does not make much sense. + * Instead, it +allows+ the sending of both Verbose and Non-Verbose messages, depending on which APIs + * are being called. */ DltReturnValue dlt_nonverbose_mode(void); diff --git a/src/lib/dlt_user.c b/src/lib/dlt_user.c index 973361c..98c896e 100644 --- a/src/lib/dlt_user.c +++ b/src/lib/dlt_user.c @@ -623,6 +623,12 @@ DltReturnValue dlt_init_message_queue(void) } #endif /* DLT_NETWORK_TRACE_ENABLE */ +/* Return true if verbose mode is to be used for this DltContextData */ +static inline bool is_verbose_mode(int8_t dltuser_verbose_mode, const DltContextData* log) +{ + return (dltuser_verbose_mode == 1) || (log != NULL && log->verbose_mode); +} + DltReturnValue dlt_init_common(void) { char *env_local_print; @@ -1686,15 +1692,30 @@ int dlt_set_resend_timeout_atexit(uint32_t timeout_in_milliseconds) /* ********************************************************************************************* */ +static DltReturnValue dlt_user_log_write_start_internal(DltContext *handle, + DltContextData *log, + DltLogLevelType loglevel, + uint32_t messageid, + bool is_verbose); + inline DltReturnValue dlt_user_log_write_start(DltContext *handle, DltContextData *log, DltLogLevelType loglevel) { - return dlt_user_log_write_start_id(handle, log, loglevel, DLT_USER_DEFAULT_MSGID); + return dlt_user_log_write_start_internal(handle, log, loglevel, DLT_USER_DEFAULT_MSGID, true); } DltReturnValue dlt_user_log_write_start_id(DltContext *handle, DltContextData *log, DltLogLevelType loglevel, uint32_t messageid) +{ + return dlt_user_log_write_start_internal(handle, log, loglevel, messageid, false); +} + +DltReturnValue dlt_user_log_write_start_internal(DltContext *handle, + DltContextData *log, + DltLogLevelType loglevel, + uint32_t messageid, + bool is_verbose) { DLT_LOG_FATAL_RESET_TRAP(loglevel); DltReturnValue ret = DLT_RETURN_OK; @@ -1733,9 +1754,10 @@ DltReturnValue dlt_user_log_write_start_id(DltContext *handle, log->log_level = loglevel; log->size = 0; log->use_timestamp = DLT_AUTO_TIMESTAMP; + log->verbose_mode = is_verbose; /* In non-verbose mode, insert message id */ - if (dlt_user.verbose_mode == 0) { + if (!is_verbose_mode(dlt_user.verbose_mode, log)) { if ((sizeof(uint32_t)) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; @@ -1787,7 +1809,7 @@ static DltReturnValue dlt_user_log_write_raw_internal(DltContextData *log, const if ((log->size + needed_size) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; - if (dlt_user.verbose_mode) { + if (is_verbose_mode(dlt_user.verbose_mode, log)) { uint32_t type_info = DLT_TYPE_INFO_RAWD; needed_size += sizeof(uint32_t); // Type Info field @@ -1819,7 +1841,7 @@ static DltReturnValue dlt_user_log_write_raw_internal(DltContextData *log, const memcpy(log->buffer + log->size, &length, sizeof(uint16_t)); log->size += sizeof(uint16_t); - if (dlt_user.verbose_mode) { + if (is_verbose_mode(dlt_user.verbose_mode, log)) { if (with_var_info) { // Write length of "name" attribute. // We assume that the protocol allows zero-sized strings here (which this code will create @@ -1879,7 +1901,7 @@ static DltReturnValue dlt_user_log_write_generic_attr(DltContextData *log, const if ((log->size + needed_size) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; - if (dlt_user.verbose_mode) { + if (is_verbose_mode(dlt_user.verbose_mode, log)) { bool with_var_info = (varinfo != NULL); uint16_t name_size; @@ -1958,7 +1980,7 @@ static DltReturnValue dlt_user_log_write_generic_formatted(DltContextData *log, if ((log->size + needed_size) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; - if (dlt_user.verbose_mode) { + if (is_verbose_mode(dlt_user.verbose_mode, log)) { needed_size += sizeof(uint32_t); // Type Info field if ((log->size + needed_size) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; @@ -2304,25 +2326,25 @@ DltReturnValue dlt_user_log_write_sized_string_attr(DltContextData *log, const c DltReturnValue dlt_user_log_write_constant_string(DltContextData *log, const char *text) { /* Send parameter only in verbose mode */ - return dlt_user.verbose_mode ? dlt_user_log_write_string(log, text) : DLT_RETURN_OK; + return is_verbose_mode(dlt_user.verbose_mode, log) ? dlt_user_log_write_string(log, text) : DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_constant_string_attr(DltContextData *log, const char *text, const char *name) { /* Send parameter only in verbose mode */ - return dlt_user.verbose_mode ? dlt_user_log_write_string_attr(log, text, name) : DLT_RETURN_OK; + return is_verbose_mode(dlt_user.verbose_mode, log) ? dlt_user_log_write_string_attr(log, text, name) : DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_sized_constant_string(DltContextData *log, const char *text, uint16_t length) { /* Send parameter only in verbose mode */ - return dlt_user.verbose_mode ? dlt_user_log_write_sized_string(log, text, length) : DLT_RETURN_OK; + return is_verbose_mode(dlt_user.verbose_mode, log) ? dlt_user_log_write_sized_string(log, text, length) : DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_sized_constant_string_attr(DltContextData *log, const char *text, uint16_t length, const char *name) { /* Send parameter only in verbose mode */ - return dlt_user.verbose_mode ? dlt_user_log_write_sized_string_attr(log, text, length, name) : DLT_RETURN_OK; + return is_verbose_mode(dlt_user.verbose_mode, log) ? dlt_user_log_write_sized_string_attr(log, text, length, name) : DLT_RETURN_OK; } DltReturnValue dlt_user_log_write_utf8_string(DltContextData *log, const char *text) @@ -2363,7 +2385,7 @@ static DltReturnValue dlt_user_log_write_sized_string_utils_attr(DltContextData uint32_t type_info = 0; - if (dlt_user.verbose_mode) { + if (is_verbose_mode(dlt_user.verbose_mode, log)) { new_log_size += sizeof(uint32_t); if (with_var_info) { new_log_size += sizeof(uint16_t); // length of "name" attribute @@ -2386,7 +2408,7 @@ static DltReturnValue dlt_user_log_write_sized_string_utils_attr(DltContextData size_t min_payload_str_truncate_msg = log->size + str_truncate_message_length + sizeof(uint16_t); - if (dlt_user.verbose_mode) { + if (is_verbose_mode(dlt_user.verbose_mode, log)) { min_payload_str_truncate_msg += sizeof(uint32_t); arg_size -= (uint16_t) sizeof(uint32_t); if (with_var_info) { @@ -2430,7 +2452,7 @@ static DltReturnValue dlt_user_log_write_sized_string_utils_attr(DltContextData } } - if (dlt_user.verbose_mode) { + if (is_verbose_mode(dlt_user.verbose_mode, log)) { switch (type) { case ASCII_STRING: type_info |= DLT_TYPE_INFO_STRG | DLT_SCOD_ASCII; @@ -2450,7 +2472,7 @@ static DltReturnValue dlt_user_log_write_sized_string_utils_attr(DltContextData memcpy(log->buffer + log->size, &arg_size, sizeof(uint16_t)); log->size += sizeof(uint16_t); - if (dlt_user.verbose_mode) { + if (is_verbose_mode(dlt_user.verbose_mode, log)) { if (with_var_info) { // Write length of "name" attribute. // We assume that the protocol allows zero-sized strings here (which this code will create @@ -3204,15 +3226,15 @@ DltReturnValue dlt_user_trace_network_truncated(DltContext *handle, DltReturnValue dlt_log_string(DltContext *handle, DltLogLevelType loglevel, const char *text) { - DltReturnValue ret = DLT_RETURN_OK; - DltContextData log; - - if (dlt_user.verbose_mode == 0) + if (!is_verbose_mode(dlt_user.verbose_mode, NULL)) return DLT_RETURN_ERROR; if ((handle == NULL) || (text == NULL)) return DLT_RETURN_WRONG_PARAMETER; + DltReturnValue ret = DLT_RETURN_OK; + DltContextData log; + if (dlt_user_log_write_start(handle, &log, loglevel) == DLT_RETURN_TRUE) { ret = dlt_user_log_write_string(&log, text); @@ -3225,15 +3247,15 @@ DltReturnValue dlt_log_string(DltContext *handle, DltLogLevelType loglevel, cons DltReturnValue dlt_log_string_int(DltContext *handle, DltLogLevelType loglevel, const char *text, int data) { - DltReturnValue ret = DLT_RETURN_OK; - DltContextData log; - - if (dlt_user.verbose_mode == 0) + if (!is_verbose_mode(dlt_user.verbose_mode, NULL)) return DLT_RETURN_ERROR; if ((handle == NULL) || (text == NULL)) return DLT_RETURN_WRONG_PARAMETER; + DltReturnValue ret = DLT_RETURN_OK; + DltContextData log; + if (dlt_user_log_write_start(handle, &log, loglevel) == DLT_RETURN_TRUE) { ret = dlt_user_log_write_string(&log, text); dlt_user_log_write_int(&log, data); @@ -3247,15 +3269,15 @@ DltReturnValue dlt_log_string_int(DltContext *handle, DltLogLevelType loglevel, DltReturnValue dlt_log_string_uint(DltContext *handle, DltLogLevelType loglevel, const char *text, unsigned int data) { - DltReturnValue ret = DLT_RETURN_OK; - DltContextData log; - - if (dlt_user.verbose_mode == 0) + if (!is_verbose_mode(dlt_user.verbose_mode, NULL)) return DLT_RETURN_ERROR; if ((handle == NULL) || (text == NULL)) return DLT_RETURN_WRONG_PARAMETER; + DltReturnValue ret = DLT_RETURN_OK; + DltContextData log; + if (dlt_user_log_write_start(handle, &log, loglevel) == DLT_RETURN_TRUE) { ret = dlt_user_log_write_string(&log, text); dlt_user_log_write_uint(&log, data); @@ -3269,14 +3291,14 @@ DltReturnValue dlt_log_string_uint(DltContext *handle, DltLogLevelType loglevel, DltReturnValue dlt_log_int(DltContext *handle, DltLogLevelType loglevel, int data) { - DltContextData log; - - if (dlt_user.verbose_mode == 0) + if (!is_verbose_mode(dlt_user.verbose_mode, NULL)) return DLT_RETURN_ERROR; if (handle == NULL) return DLT_RETURN_ERROR; + DltContextData log; + if (dlt_user_log_write_start(handle, &log, loglevel) == DLT_RETURN_TRUE) { dlt_user_log_write_int(&log, data); @@ -3289,14 +3311,14 @@ DltReturnValue dlt_log_int(DltContext *handle, DltLogLevelType loglevel, int dat DltReturnValue dlt_log_uint(DltContext *handle, DltLogLevelType loglevel, unsigned int data) { - DltContextData log; - - if (dlt_user.verbose_mode == 0) + if (!is_verbose_mode(dlt_user.verbose_mode, NULL)) return DLT_RETURN_ERROR; if (handle == NULL) return DLT_RETURN_WRONG_PARAMETER; + DltContextData log; + if (dlt_user_log_write_start(handle, &log, loglevel) == DLT_RETURN_TRUE) { dlt_user_log_write_uint(&log, data); @@ -3309,15 +3331,15 @@ DltReturnValue dlt_log_uint(DltContext *handle, DltLogLevelType loglevel, unsign DltReturnValue dlt_log_raw(DltContext *handle, DltLogLevelType loglevel, void *data, uint16_t length) { - DltContextData log; - DltReturnValue ret = DLT_RETURN_OK; - - if (dlt_user.verbose_mode == 0) + if (!is_verbose_mode(dlt_user.verbose_mode, NULL)) return DLT_RETURN_ERROR; if (handle == NULL) return DLT_RETURN_WRONG_PARAMETER; + DltContextData log; + DltReturnValue ret = DLT_RETURN_OK; + if (dlt_user_log_write_start(handle, &log, loglevel) > 0) { if ((ret = dlt_user_log_write_raw(&log, data, length)) < DLT_RETURN_OK) { dlt_user_free_buffer(&(log.buffer)); @@ -3611,7 +3633,7 @@ DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype) msg.headerextra.seid = (uint32_t) getpid(); } - if (dlt_user.verbose_mode) + if (is_verbose_mode(dlt_user.verbose_mode, log)) /* In verbose mode, send extended header */ msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH); else @@ -3668,7 +3690,7 @@ DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype) } /* If in verbose mode, set flag in header for verbose mode */ - if (dlt_user.verbose_mode) + if (is_verbose_mode(dlt_user.verbose_mode, log)) msg.extendedheader->msin |= DLT_MSIN_VERB; msg.extendedheader->noar = (uint8_t) log->args_num; /* number of arguments */ diff --git a/tests/gtest_dlt_user.cpp b/tests/gtest_dlt_user.cpp index ca5117c..a66f7a4 100644 --- a/tests/gtest_dlt_user.cpp +++ b/tests/gtest_dlt_user.cpp @@ -3645,6 +3645,45 @@ TEST(t_dlt_user_log_write_raw_formatted_attr, normal) EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); } +/*/////////////////////////////////////// */ +/* + * Test sending Verbose and Non-Verbose messages in the same session. + */ + +/*/////////////////////////////////////// */ +/* t_dlt_user_nonverbose*/ +TEST(t_dlt_user_nonverbose, nonverbosemode) +{ + dlt_nonverbose_mode(); + dlt_use_extended_header_for_non_verbose(false); + + DltContext context; + DltContextData contextData; + + EXPECT_LE(DLT_RETURN_OK, dlt_register_app("TUSR", "dlt_user.c tests")); + EXPECT_LE(DLT_RETURN_OK, dlt_register_context(&context, "TEST", "dlt_user.c t_dlt_user_message_modes")); + + // Send a Verbose message + EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start(&context, &contextData, DLT_LOG_DEFAULT)); + EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_constant_string_attr(&contextData, "hello", "msg")); + EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_attr(&contextData, 0x01020304, "val1", "unit1")); + EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_attr(&contextData, 0x04030201, "val2", "unit2")); + EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); + + // Send a Non-Verbose message + EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_start_id(&context, &contextData, DLT_LOG_DEFAULT, 42)); + EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_constant_string_attr(&contextData, "hello", "msg")); + EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_attr(&contextData, 0x01020304, "val1", "unit1")); + EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_uint32_attr(&contextData, 0x04030201, "val2", "unit2")); + EXPECT_LE(DLT_RETURN_OK, dlt_user_log_write_finish(&contextData)); + + EXPECT_LE(DLT_RETURN_OK, dlt_unregister_context(&context)); + EXPECT_LE(DLT_RETURN_OK, dlt_unregister_app()); + + dlt_use_extended_header_for_non_verbose(true); + dlt_verbose_mode(); +} + /*/////////////////////////////////////// */ /* * int dlt_log_string(DltContext *handle,DltLogLevelType loglevel, const char *text); -- cgit v1.2.1