From fff5caa73977e8a6f2537a5a459fb13af5397385 Mon Sep 17 00:00:00 2001 From: Martin Willers Date: Tue, 16 Mar 2021 00:53:55 +0100 Subject: Add verbose mode attribute handling (#292) dlt_user_log_write_*_attr() enables to writing these types, but also support adding "attributes" for them, i.e. a "name" and a "unit". Signed-off-by: Martin Willers --- src/lib/dlt_user.c | 859 ++++++++++++++++++++---------------------------- src/shared/dlt_common.c | 135 ++++++-- 2 files changed, 464 insertions(+), 530 deletions(-) (limited to 'src') diff --git a/src/lib/dlt_user.c b/src/lib/dlt_user.c index ae6eb55..4dc8d42 100644 --- a/src/lib/dlt_user.c +++ b/src/lib/dlt_user.c @@ -115,6 +115,16 @@ enum StringType UTF8_STRING = 1 }; +/* Data type holding "Variable Info" (VARI) properties + * Some of the supported data types (eg. bool, string, raw) have only "name", but not "unit". + */ +typedef struct VarInfo +{ + const char *name; // the "name" attribute (can be NULL) + const char *unit; // the "unit" attribute (can be NULL) + bool with_unit; // true if the "unit" field is to be considered +} VarInfo; + #define DLT_UNUSED(x) (void)(x) /* Network trace */ @@ -191,10 +201,8 @@ static void dlt_user_trace_network_segmented_thread(void *unused); static void dlt_user_trace_network_segmented_thread_segmenter(s_segmented_data *data); #endif -static DltReturnValue dlt_user_log_write_string_utils(DltContextData *log, const char *text, - const enum StringType type); -static DltReturnValue dlt_user_log_write_sized_string_utils(DltContextData *log, const char *text, - uint16_t text_len, const enum StringType type); +static DltReturnValue dlt_user_log_write_string_utils_attr(DltContextData *log, const char *text, const enum StringType type, const char *name, bool with_var_info); +static DltReturnValue dlt_user_log_write_sized_string_utils_attr(DltContextData *log, const char *text, uint16_t length, const enum StringType type, const char *name, bool with_var_info); static DltReturnValue dlt_unregister_app_util(bool force_sending_messages); @@ -1756,16 +1764,8 @@ DltReturnValue dlt_user_log_write_finish(DltContextData *log) return ret; } -DltReturnValue dlt_user_log_write_raw(DltContextData *log, void *data, uint16_t length) -{ - return dlt_user_log_write_raw_formatted(log, data, length, DLT_FORMAT_DEFAULT); -} - -DltReturnValue dlt_user_log_write_raw_formatted(DltContextData *log, void *data, uint16_t length, DltFormatType type) +static DltReturnValue dlt_user_log_write_raw_internal(DltContextData *log, const void *data, uint16_t length, DltFormatType type, const char *name, bool with_var_info) { - size_t new_log_size = 0; - uint32_t type_info = 0; - /* check nullpointer */ if ((log == NULL) || ((data == NULL) && (length != 0))) return DLT_RETURN_WRONG_PARAMETER; @@ -1781,20 +1781,27 @@ DltReturnValue dlt_user_log_write_raw_formatted(DltContextData *log, void *data, return DLT_RETURN_ERROR; } - new_log_size = log->size + length + sizeof(uint16_t); + const uint16_t name_size = (name != NULL) ? strlen(name)+1 : 0; - if (new_log_size > dlt_user.log_buf_len) + size_t needed_size = length + sizeof(uint16_t); + if ((log->size + needed_size) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; if (dlt_user.verbose_mode) { - new_log_size = log->size + length + sizeof(uint32_t) + sizeof(uint16_t); + uint32_t type_info = DLT_TYPE_INFO_RAWD; - if (new_log_size > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; + needed_size += sizeof(uint32_t); // Type Info field + if (with_var_info) { + needed_size += sizeof(uint16_t); // length of name + needed_size += name_size; // the name itself - /* Transmit type information */ - type_info = DLT_TYPE_INFO_RAWD; + type_info |= DLT_TYPE_INFO_VARI; + } + if ((log->size + needed_size) > dlt_user.log_buf_len) + return DLT_RETURN_USER_BUFFER_FULL; + // Genivi extension: put formatting hints into the unused (for RAWD) TYLE + SCOD fields. + // The SCOD field holds the base (hex or bin); the TYLE field holds the column width (8bit..64bit). if ((type >= DLT_FORMAT_HEX8) && (type <= DLT_FORMAT_HEX64)) { type_info |= DLT_SCOD_HEX; type_info += type; @@ -1805,15 +1812,31 @@ DltReturnValue dlt_user_log_write_raw_formatted(DltContextData *log, void *data, type_info += type - DLT_FORMAT_BIN8 + 1; } - memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); + memcpy(log->buffer + log->size, &type_info, sizeof(uint32_t)); log->size += sizeof(uint32_t); } - /* First transmit length of raw data, then the raw data itself */ - memcpy((log->buffer) + log->size, &(length), sizeof(uint16_t)); + memcpy(log->buffer + log->size, &length, sizeof(uint16_t)); log->size += sizeof(uint16_t); - memcpy((log->buffer) + log->size, data, length); + if (dlt_user.verbose_mode) { + if (with_var_info) { + // Write length of "name" attribute. + // We assume that the protocol allows zero-sized strings here (which this code will create + // when the input pointer is NULL). + memcpy(log->buffer + log->size, &name_size, sizeof(uint16_t)); + log->size += sizeof(uint16_t); + + // Write name string itself. + // Must not use NULL as source pointer for memcpy. This check assures that. + if (name_size != 0) { + memcpy(log->buffer + log->size, name, name_size); + log->size += name_size; + } + } + } + + memcpy(log->buffer + log->size, data, length); log->size += length; log->args_num++; @@ -1821,10 +1844,29 @@ DltReturnValue dlt_user_log_write_raw_formatted(DltContextData *log, void *data, return DLT_RETURN_OK; } -DltReturnValue dlt_user_log_write_float32(DltContextData *log, float32_t data) +DltReturnValue dlt_user_log_write_raw(DltContextData *log, void *data, uint16_t length) +{ + return dlt_user_log_write_raw_internal(log, data, length, DLT_FORMAT_DEFAULT, NULL, false); +} + +DltReturnValue dlt_user_log_write_raw_formatted(DltContextData *log, void *data, uint16_t length, DltFormatType type) { - uint32_t type_info; + return dlt_user_log_write_raw_internal(log, data, length, type, NULL, false); +} + +DltReturnValue dlt_user_log_write_raw_attr(DltContextData *log, const void *data, uint16_t length, const char *name) +{ + return dlt_user_log_write_raw_internal(log, data, length, DLT_FORMAT_DEFAULT, name, true); +} + +DltReturnValue dlt_user_log_write_raw_formatted_attr(DltContextData *log, const void *data, uint16_t length, DltFormatType type, const char *name) +{ + return dlt_user_log_write_raw_internal(log, data, length, type, name, true); +} +// Generic implementation for all "simple" types, possibly with attributes +static DltReturnValue dlt_user_log_write_generic_attr(DltContextData *log, const void *datap, size_t datalen, uint32_t type_info, const VarInfo *varinfo) +{ if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; @@ -1833,67 +1875,152 @@ DltReturnValue dlt_user_log_write_float32(DltContextData *log, float32_t data) return DLT_RETURN_ERROR; } - if (sizeof(float32_t) != 4) - return DLT_RETURN_ERROR; - - if ((log->size + sizeof(float32_t)) > dlt_user.log_buf_len) + size_t needed_size = datalen; + if ((log->size + needed_size) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; if (dlt_user.verbose_mode) { - if ((log->size + sizeof(uint32_t) + sizeof(float32_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; + bool with_var_info = (varinfo != NULL); + + uint16_t name_size; + uint16_t unit_size; + + needed_size += sizeof(uint32_t); // Type Info field + if (with_var_info) { + name_size = (varinfo->name != NULL) ? strlen(varinfo->name)+1 : 0; + unit_size = (varinfo->unit != NULL) ? strlen(varinfo->unit)+1 : 0; + + needed_size += sizeof(uint16_t); // length of name + needed_size += name_size; // the name itself + if (varinfo->with_unit) { + needed_size += sizeof(uint16_t); // length of unit + needed_size += unit_size; // the unit itself + } - type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_32BIT; + type_info |= DLT_TYPE_INFO_VARI; + } + if ((log->size + needed_size) > dlt_user.log_buf_len) + return DLT_RETURN_USER_BUFFER_FULL; - memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); + memcpy(log->buffer + log->size, &type_info, sizeof(uint32_t)); log->size += sizeof(uint32_t); + + if (with_var_info) { + // Write lengths of name/unit strings + // We assume here that the protocol allows zero-sized strings here (which occur + // when the input pointers are NULL). + memcpy(log->buffer + log->size, &name_size, sizeof(uint16_t)); + log->size += sizeof(uint16_t); + if (varinfo->with_unit) { + memcpy(log->buffer + log->size, &unit_size, sizeof(uint16_t)); + log->size += sizeof(uint16_t); + } + + // Write name/unit strings themselves + // Must not use NULL as source pointer for memcpy. + if (name_size != 0) { + memcpy(log->buffer + log->size, varinfo->name, name_size); + log->size += name_size; + } + if (unit_size != 0) { + memcpy(log->buffer + log->size, varinfo->unit, unit_size); + log->size += unit_size; + } + } } - memcpy((log->buffer) + log->size, &data, sizeof(float32_t)); - log->size += sizeof(float32_t); + memcpy(log->buffer + log->size, datap, datalen); + log->size += datalen; log->args_num++; return DLT_RETURN_OK; } -DltReturnValue dlt_user_log_write_float64(DltContextData *log, float64_t data) +// Generic implementation for all "simple" types +static DltReturnValue dlt_user_log_write_generic_formatted(DltContextData *log, const void *datap, size_t datalen, uint32_t type_info, DltFormatType type) { - uint32_t type_info; - if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; + /* Have to cast type to signed type because some compilers assume that DltFormatType is unsigned and issue a warning */ + if (((int16_t)type < DLT_FORMAT_DEFAULT) || (type >= DLT_FORMAT_MAX)) { + dlt_vlog(LOG_ERR, "Format type %d is outside valid range", type); + return DLT_RETURN_WRONG_PARAMETER; + } + if (!dlt_user_initialised) { dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); return DLT_RETURN_ERROR; } - if (sizeof(float64_t) != 8) - return DLT_RETURN_ERROR; - - if ((log->size + sizeof(float64_t)) > dlt_user.log_buf_len) + size_t needed_size = datalen; + if ((log->size + needed_size) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; if (dlt_user.verbose_mode) { - if ((log->size + sizeof(uint32_t) + sizeof(float64_t)) > dlt_user.log_buf_len) + needed_size += sizeof(uint32_t); // Type Info field + if ((log->size + needed_size) > dlt_user.log_buf_len) return DLT_RETURN_USER_BUFFER_FULL; - type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_64BIT; + // Genivi extension: put formatting hints into the unused (for SINT/UINT/FLOA) SCOD field. + if ((type >= DLT_FORMAT_HEX8) && (type <= DLT_FORMAT_HEX64)) + type_info |= DLT_SCOD_HEX; - memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); + else if ((type >= DLT_FORMAT_BIN8) && (type <= DLT_FORMAT_BIN16)) + type_info |= DLT_SCOD_BIN; + + memcpy(log->buffer + log->size, &type_info, sizeof(uint32_t)); log->size += sizeof(uint32_t); } - memcpy((log->buffer) + log->size, &data, sizeof(float64_t)); - log->size += sizeof(float64_t); + memcpy(log->buffer + log->size, datap, datalen); + log->size += datalen; log->args_num++; return DLT_RETURN_OK; } -DltReturnValue dlt_user_log_write_uint(DltContextData *log, unsigned int data) +DltReturnValue dlt_user_log_write_float32(DltContextData *log, float32_t data) +{ + if (sizeof(float32_t) != 4) + return DLT_RETURN_ERROR; + + uint32_t type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_32BIT; + return dlt_user_log_write_generic_attr(log, &data, sizeof(float32_t), type_info, NULL); +} + +DltReturnValue dlt_user_log_write_float64(DltContextData *log, float64_t data) +{ + if (sizeof(float64_t) != 8) + return DLT_RETURN_ERROR; + + uint32_t type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_64BIT; + return dlt_user_log_write_generic_attr(log, &data, sizeof(float64_t), type_info, NULL); +} + +DltReturnValue dlt_user_log_write_float32_attr(DltContextData *log, float32_t data, const char *name, const char *unit) +{ + if (sizeof(float32_t) != 4) + return DLT_RETURN_ERROR; + + uint32_t type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_32BIT; + const VarInfo var_info = { name, unit, true }; + return dlt_user_log_write_generic_attr(log, &data, sizeof(float32_t), type_info, &var_info); +} + +DltReturnValue dlt_user_log_write_float64_attr(DltContextData *log, float64_t data, const char *name, const char *unit) +{ + if (sizeof(float64_t) != 8) + return DLT_RETURN_ERROR; + + uint32_t type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_64BIT; + const VarInfo var_info = { name, unit, true }; + return dlt_user_log_write_generic_attr(log, &data, sizeof(float64_t), type_info, &var_info); +} + +DltReturnValue dlt_user_log_write_uint_attr(DltContextData *log, unsigned int data, const char *name, const char *unit) { if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; @@ -1906,22 +2033,22 @@ DltReturnValue dlt_user_log_write_uint(DltContextData *log, unsigned int data) switch (sizeof(unsigned int)) { case 1: { - return dlt_user_log_write_uint8(log, (uint8_t)data); + return dlt_user_log_write_uint8_attr(log, (uint8_t)data, name, unit); break; } case 2: { - return dlt_user_log_write_uint16(log, (uint16_t)data); + return dlt_user_log_write_uint16_attr(log, (uint16_t)data, name, unit); break; } case 4: { - return dlt_user_log_write_uint32(log, (uint32_t)data); + return dlt_user_log_write_uint32_attr(log, (uint32_t)data, name, unit); break; } case 8: { - return dlt_user_log_write_uint64(log, (uint64_t)data); + return dlt_user_log_write_uint64_attr(log, (uint64_t)data, name, unit); break; } default: @@ -1936,314 +2063,83 @@ DltReturnValue dlt_user_log_write_uint(DltContextData *log, unsigned int data) DltReturnValue dlt_user_log_write_uint8(DltContextData *log, uint8_t data) { - uint32_t type_info; - - if (log == NULL) - return DLT_RETURN_WRONG_PARAMETER; - - if (!dlt_user_initialised) { - dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); - return DLT_RETURN_ERROR; - } - - if ((log->size + sizeof(uint8_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - if (dlt_user.verbose_mode) { - if ((log->size + sizeof(uint32_t) + sizeof(uint8_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_8BIT; - - memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); - log->size += sizeof(uint32_t); - } - - memcpy((log->buffer) + log->size, &data, sizeof(uint8_t)); - log->size += sizeof(uint8_t); - - log->args_num++; - - return DLT_RETURN_OK; + uint32_t type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_8BIT; + return dlt_user_log_write_generic_attr(log, &data, sizeof(uint8_t), type_info, NULL); } DltReturnValue dlt_user_log_write_uint16(DltContextData *log, uint16_t data) { - uint32_t type_info; - - if (log == NULL) - return DLT_RETURN_WRONG_PARAMETER; - - if (!dlt_user_initialised) { - dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); - return DLT_RETURN_ERROR; - } - - if ((log->size + sizeof(uint16_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - if (dlt_user.verbose_mode) { - if ((log->size + sizeof(uint32_t) + sizeof(uint16_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_16BIT; - - memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); - log->size += sizeof(uint32_t); - } - - memcpy((log->buffer) + log->size, &data, sizeof(uint16_t)); - log->size += sizeof(uint16_t); - - log->args_num++; - - return DLT_RETURN_OK; + uint32_t type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_16BIT; + return dlt_user_log_write_generic_attr(log, &data, sizeof(uint16_t), type_info, NULL); } DltReturnValue dlt_user_log_write_uint32(DltContextData *log, uint32_t data) { - uint32_t type_info; - - if (log == NULL) - return DLT_RETURN_WRONG_PARAMETER; - - if (!dlt_user_initialised) { - dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); - return DLT_RETURN_ERROR; - } - - if ((log->size + sizeof(uint32_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - if (dlt_user.verbose_mode) { - if ((log->size + sizeof(uint32_t) + sizeof(uint32_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_32BIT; - - memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); - log->size += sizeof(uint32_t); - } - - memcpy((log->buffer) + log->size, &data, sizeof(uint32_t)); - log->size += sizeof(uint32_t); - - log->args_num++; - - return DLT_RETURN_OK; + uint32_t type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_32BIT; + return dlt_user_log_write_generic_attr(log, &data, sizeof(uint32_t), type_info, NULL); } DltReturnValue dlt_user_log_write_uint64(DltContextData *log, uint64_t data) { - uint32_t type_info; - - if (log == NULL) - return DLT_RETURN_WRONG_PARAMETER; - - if (!dlt_user_initialised) { - dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); - return DLT_RETURN_ERROR; - } - - if ((log->size + sizeof(uint64_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - if (dlt_user.verbose_mode) { - if ((log->size + sizeof(uint32_t) + sizeof(uint64_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; + uint32_t type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_64BIT; + return dlt_user_log_write_generic_attr(log, &data, sizeof(uint64_t), type_info, NULL); +} - type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_64BIT; +DltReturnValue dlt_user_log_write_uint(DltContextData *log, unsigned int data) +{ + return dlt_user_log_write_uint_attr(log, data, NULL, NULL); +} - memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); - log->size += sizeof(uint32_t); - } +DltReturnValue dlt_user_log_write_uint8_attr(DltContextData *log, uint8_t data, const char *name, const char *unit) +{ + uint32_t type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_8BIT; + const VarInfo var_info = { name, unit, true }; + return dlt_user_log_write_generic_attr(log, &data, sizeof(uint8_t), type_info, &var_info); +} - memcpy((log->buffer) + log->size, &data, sizeof(uint64_t)); - log->size += sizeof(uint64_t); +DltReturnValue dlt_user_log_write_uint16_attr(DltContextData *log, uint16_t data, const char *name, const char *unit) +{ + uint32_t type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_16BIT; + const VarInfo var_info = { name, unit, true }; + return dlt_user_log_write_generic_attr(log, &data, sizeof(uint16_t), type_info, &var_info); +} - log->args_num++; +DltReturnValue dlt_user_log_write_uint32_attr(DltContextData *log, uint32_t data, const char *name, const char *unit) +{ + uint32_t type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_32BIT; + const VarInfo var_info = { name, unit, true }; + return dlt_user_log_write_generic_attr(log, &data, sizeof(uint32_t), type_info, &var_info); +} - return DLT_RETURN_OK; +DltReturnValue dlt_user_log_write_uint64_attr(DltContextData *log, uint64_t data, const char *name, const char *unit) +{ + uint32_t type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_64BIT; + const VarInfo var_info = { name, unit, true }; + return dlt_user_log_write_generic_attr(log, &data, sizeof(uint64_t), type_info, &var_info); } DltReturnValue dlt_user_log_write_uint8_formatted(DltContextData *log, uint8_t data, DltFormatType type) { - uint32_t type_info; - - if (log == NULL) - return DLT_RETURN_WRONG_PARAMETER; - - /* Have to cast type to signed type because some compilers assume that DltFormatType is unsigned and issue a warning */ - if (((int16_t)type < DLT_FORMAT_DEFAULT) || (type >= DLT_FORMAT_MAX)) { - dlt_vlog(LOG_ERR, "Format type %d is outside valid range", type); - return DLT_RETURN_WRONG_PARAMETER; - } - - if (!dlt_user_initialised) { - dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); - return DLT_RETURN_ERROR; - } - - if ((log->size + sizeof(uint16_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - if (dlt_user.verbose_mode) { - if ((log->size + sizeof(uint32_t) + sizeof(uint16_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_8BIT; - - if ((type >= DLT_FORMAT_HEX8) && (type <= DLT_FORMAT_HEX64)) - type_info |= DLT_SCOD_HEX; - - else if ((type >= DLT_FORMAT_BIN8) && (type <= DLT_FORMAT_BIN16)) - type_info |= DLT_SCOD_BIN; - - memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); - log->size += sizeof(uint32_t); - } - - memcpy((log->buffer) + log->size, &data, sizeof(uint8_t)); - log->size += sizeof(uint8_t); - - log->args_num++; - - return DLT_RETURN_OK; + uint32_t type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_8BIT; + return dlt_user_log_write_generic_formatted(log, &data, sizeof(uint8_t), type_info, type); } DltReturnValue dlt_user_log_write_uint16_formatted(DltContextData *log, uint16_t data, DltFormatType type) { - uint32_t type_info; - - if (log == NULL) - return DLT_RETURN_WRONG_PARAMETER; - - /* Have to cast type to signed type because some compilers assume that DltFormatType is unsigned and issue a warning */ - if (((int16_t)type < DLT_FORMAT_DEFAULT) || (type >= DLT_FORMAT_MAX)) { - dlt_vlog(LOG_ERR, "Format type %d is outside valid range", type); - return DLT_RETURN_WRONG_PARAMETER; - } - - if (!dlt_user_initialised) { - dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); - return DLT_RETURN_ERROR; - } - - if ((log->size + sizeof(uint16_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - if (dlt_user.verbose_mode) { - if ((log->size + sizeof(uint32_t) + sizeof(uint16_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_16BIT; - - if ((type >= DLT_FORMAT_HEX8) && (type <= DLT_FORMAT_HEX64)) - type_info |= DLT_SCOD_HEX; - - else if ((type >= DLT_FORMAT_BIN8) && (type <= DLT_FORMAT_BIN16)) - type_info |= DLT_SCOD_BIN; - - memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); - log->size += sizeof(uint32_t); - } - - memcpy((log->buffer) + log->size, &data, sizeof(uint16_t)); - log->size += sizeof(uint16_t); - - log->args_num++; - - return DLT_RETURN_OK; + uint32_t type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_16BIT; + return dlt_user_log_write_generic_formatted(log, &data, sizeof(uint16_t), type_info, type); } DltReturnValue dlt_user_log_write_uint32_formatted(DltContextData *log, uint32_t data, DltFormatType type) { - uint32_t type_info; - - if (log == NULL) - return DLT_RETURN_WRONG_PARAMETER; - - /* Have to cast type to signed type because some compilers assume that DltFormatType is unsigned and issue a warning */ - if (((int16_t)type < DLT_FORMAT_DEFAULT) || (type >= DLT_FORMAT_MAX)) { - dlt_vlog(LOG_ERR, "Format type %d is outside valid range", type); - return DLT_RETURN_WRONG_PARAMETER; - } - - if (!dlt_user_initialised) { - dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); - return DLT_RETURN_ERROR; - } - - if ((log->size + sizeof(uint16_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - if (dlt_user.verbose_mode) { - if ((log->size + sizeof(uint32_t) + sizeof(uint16_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_32BIT; - - if ((type >= DLT_FORMAT_HEX8) && (type <= DLT_FORMAT_HEX64)) - type_info |= DLT_SCOD_HEX; - - else if ((type >= DLT_FORMAT_BIN8) && (type <= DLT_FORMAT_BIN16)) - type_info |= DLT_SCOD_BIN; - - memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); - log->size += sizeof(uint32_t); - } - - memcpy((log->buffer) + log->size, &data, sizeof(uint32_t)); - log->size += sizeof(uint32_t); - - log->args_num++; - - return DLT_RETURN_OK; + uint32_t type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_32BIT; + return dlt_user_log_write_generic_formatted(log, &data, sizeof(uint32_t), type_info, type); } DltReturnValue dlt_user_log_write_uint64_formatted(DltContextData *log, uint64_t data, DltFormatType type) { - uint32_t type_info; - - if (log == NULL) - return DLT_RETURN_WRONG_PARAMETER; - - /* Have to cast type to signed type because some compilers assume that DltFormatType is unsigned and issue a warning */ - if (((int16_t)type < DLT_FORMAT_DEFAULT) || (type >= DLT_FORMAT_MAX)) { - dlt_vlog(LOG_ERR, "Format type %d is outside valid range", type); - return DLT_RETURN_WRONG_PARAMETER; - } - - if (!dlt_user_initialised) { - dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); - return DLT_RETURN_ERROR; - } - - if ((log->size + sizeof(uint16_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - if (dlt_user.verbose_mode) { - if ((log->size + sizeof(uint32_t) + sizeof(uint16_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_64BIT; - - if ((type >= DLT_FORMAT_HEX8) && (type <= DLT_FORMAT_HEX64)) - type_info |= DLT_SCOD_HEX; - - else if ((type >= DLT_FORMAT_BIN8) && (type <= DLT_FORMAT_BIN16)) - type_info |= DLT_SCOD_BIN; - - memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); - log->size += sizeof(uint32_t); - } - - memcpy((log->buffer) + log->size, &data, sizeof(uint64_t)); - log->size += sizeof(uint64_t); - - log->args_num++; - - return DLT_RETURN_OK; + uint32_t type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_64BIT; + return dlt_user_log_write_generic_formatted(log, &data, sizeof(uint64_t), type_info, type); } DltReturnValue dlt_user_log_write_ptr(DltContextData *log, void *data) @@ -2274,7 +2170,7 @@ DltReturnValue dlt_user_log_write_ptr(DltContextData *log, void *data) return DLT_RETURN_OK; } -DltReturnValue dlt_user_log_write_int(DltContextData *log, int data) +DltReturnValue dlt_user_log_write_int_attr(DltContextData *log, int data, const char *name, const char *unit) { if (log == NULL) return DLT_RETURN_WRONG_PARAMETER; @@ -2287,22 +2183,22 @@ DltReturnValue dlt_user_log_write_int(DltContextData *log, int data) switch (sizeof(int)) { case 1: { - return dlt_user_log_write_int8(log, (int8_t)data); + return dlt_user_log_write_int8_attr(log, (int8_t)data, name, unit); break; } case 2: { - return dlt_user_log_write_int16(log, (int16_t)data); + return dlt_user_log_write_int16_attr(log, (int16_t)data, name, unit); break; } case 4: { - return dlt_user_log_write_int32(log, (int32_t)data); + return dlt_user_log_write_int32_attr(log, (int32_t)data, name, unit); break; } case 8: { - return dlt_user_log_write_int64(log, (int64_t)data); + return dlt_user_log_write_int64_attr(log, (int64_t)data, name, unit); break; } default: @@ -2317,177 +2213,92 @@ DltReturnValue dlt_user_log_write_int(DltContextData *log, int data) DltReturnValue dlt_user_log_write_int8(DltContextData *log, int8_t data) { - uint32_t type_info; - - if (log == NULL) - return DLT_RETURN_WRONG_PARAMETER; - - if (!dlt_user_initialised) { - dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); - return DLT_RETURN_ERROR; - } - - if ((log->size + sizeof(int8_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - if (dlt_user.verbose_mode) { - if ((log->size + sizeof(uint32_t) + sizeof(int8_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_8BIT; - - memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); - log->size += sizeof(uint32_t); - } - - memcpy((log->buffer) + log->size, &data, sizeof(int8_t)); - log->size += sizeof(int8_t); - - log->args_num++; - - return DLT_RETURN_OK; + uint32_t type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_8BIT; + return dlt_user_log_write_generic_attr(log, &data, sizeof(int8_t), type_info, NULL); } DltReturnValue dlt_user_log_write_int16(DltContextData *log, int16_t data) { - uint32_t type_info; - - if (log == NULL) - return DLT_RETURN_WRONG_PARAMETER; - - if (!dlt_user_initialised) { - dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); - return DLT_RETURN_ERROR; - } - - if ((log->size + sizeof(int16_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - if (dlt_user.verbose_mode) { - if ((log->size + sizeof(uint32_t) + sizeof(int16_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_16BIT; - - memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); - log->size += sizeof(uint32_t); - } - - memcpy((log->buffer) + log->size, &data, sizeof(int16_t)); - log->size += sizeof(int16_t); - - log->args_num++; - - return DLT_RETURN_OK; + uint32_t type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_16BIT; + return dlt_user_log_write_generic_attr(log, &data, sizeof(int16_t), type_info, NULL); } DltReturnValue dlt_user_log_write_int32(DltContextData *log, int32_t data) { - uint32_t type_info; - - if (log == NULL) - return DLT_RETURN_WRONG_PARAMETER; - - if (!dlt_user_initialised) { - dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); - return DLT_RETURN_ERROR; - } - - if ((log->size + sizeof(int32_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - if (dlt_user.verbose_mode) { - if ((log->size + sizeof(uint32_t) + sizeof(int32_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_32BIT; - - memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); - log->size += sizeof(uint32_t); - } - - memcpy((log->buffer) + log->size, &data, sizeof(int32_t)); - log->size += sizeof(int32_t); - - log->args_num++; - - return DLT_RETURN_OK; + uint32_t type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_32BIT; + return dlt_user_log_write_generic_attr(log, &data, sizeof(int32_t), type_info, NULL); } DltReturnValue dlt_user_log_write_int64(DltContextData *log, int64_t data) { - uint32_t type_info; - - if (log == NULL) - return DLT_RETURN_WRONG_PARAMETER; - - if (!dlt_user_initialised) { - dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); - return DLT_RETURN_ERROR; - } - - if ((log->size + sizeof(int64_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - if (dlt_user.verbose_mode) { - if ((log->size + sizeof(uint32_t) + sizeof(int64_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; + uint32_t type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_64BIT; + return dlt_user_log_write_generic_attr(log, &data, sizeof(int64_t), type_info, NULL); +} - type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_64BIT; +DltReturnValue dlt_user_log_write_int(DltContextData *log, int data) +{ + return dlt_user_log_write_int_attr(log, data, NULL, NULL); +} - memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); - log->size += sizeof(uint32_t); - } +DltReturnValue dlt_user_log_write_int8_attr(DltContextData *log, int8_t data, const char *name, const char *unit) +{ + uint32_t type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_8BIT; + const VarInfo var_info = { name, unit, true }; + return dlt_user_log_write_generic_attr(log, &data, sizeof(int8_t), type_info, &var_info); +} - memcpy((log->buffer) + log->size, &data, sizeof(int64_t)); - log->size += sizeof(int64_t); +DltReturnValue dlt_user_log_write_int16_attr(DltContextData *log, int16_t data, const char *name, const char *unit) +{ + uint32_t type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_16BIT; + const VarInfo var_info = { name, unit, true }; + return dlt_user_log_write_generic_attr(log, &data, sizeof(int16_t), type_info, &var_info); +} - log->args_num++; +DltReturnValue dlt_user_log_write_int32_attr(DltContextData *log, int32_t data, const char *name, const char *unit) +{ + uint32_t type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_32BIT; + const VarInfo var_info = { name, unit, true }; + return dlt_user_log_write_generic_attr(log, &data, sizeof(int32_t), type_info, &var_info); +} - return DLT_RETURN_OK; +DltReturnValue dlt_user_log_write_int64_attr(DltContextData *log, int64_t data, const char *name, const char *unit) +{ + uint32_t type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_64BIT; + const VarInfo var_info = { name, unit, true }; + return dlt_user_log_write_generic_attr(log, &data, sizeof(int64_t), type_info, &var_info); } DltReturnValue dlt_user_log_write_bool(DltContextData *log, uint8_t data) { - uint32_t type_info; - - if (log == NULL) - return DLT_RETURN_WRONG_PARAMETER; - - if (!dlt_user_initialised) { - dlt_vlog(LOG_WARNING, "%s dlt_user_initialised false\n", __FUNCTION__); - return DLT_RETURN_ERROR; - } - - if ((log->size + sizeof(uint8_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - if (dlt_user.verbose_mode) { - if ((log->size + sizeof(uint32_t) + sizeof(uint8_t)) > dlt_user.log_buf_len) - return DLT_RETURN_USER_BUFFER_FULL; - - type_info = DLT_TYPE_INFO_BOOL; - - memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); - log->size += sizeof(uint32_t); - } - - memcpy((log->buffer) + log->size, &data, sizeof(uint8_t)); - log->size += sizeof(uint8_t); - - log->args_num++; + uint32_t type_info = DLT_TYPE_INFO_BOOL; + return dlt_user_log_write_generic_attr(log, &data, sizeof(uint8_t), type_info, NULL); +} - return DLT_RETURN_OK; +DltReturnValue dlt_user_log_write_bool_attr(DltContextData *log, uint8_t data, const char *name) +{ + uint32_t type_info = DLT_TYPE_INFO_BOOL; + const VarInfo var_info = { name, NULL, false }; + return dlt_user_log_write_generic_attr(log, &data, sizeof(uint8_t), type_info, &var_info); } DltReturnValue dlt_user_log_write_string(DltContextData *log, const char *text) { - return dlt_user_log_write_string_utils(log, text, ASCII_STRING); + return dlt_user_log_write_string_utils_attr(log, text, ASCII_STRING, NULL, false); +} + +DltReturnValue dlt_user_log_write_string_attr(DltContextData *log, const char *text, const char *name) +{ + return dlt_user_log_write_string_utils_attr(log, text, ASCII_STRING, name, true); } DltReturnValue dlt_user_log_write_sized_string(DltContextData *log, const char *text, uint16_t length) { - return dlt_user_log_write_sized_string_utils(log, text, length, ASCII_STRING); + return dlt_user_log_write_sized_string_utils_attr(log, text, length, ASCII_STRING, NULL, false); +} + +DltReturnValue dlt_user_log_write_sized_string_attr(DltContextData *log, const char *text, uint16_t length, const char *name) +{ + return dlt_user_log_write_sized_string_utils_attr(log, text, length, ASCII_STRING, name, true); } DltReturnValue dlt_user_log_write_constant_string(DltContextData *log, const char *text) @@ -2496,32 +2307,46 @@ DltReturnValue dlt_user_log_write_constant_string(DltContextData *log, const cha return dlt_user.verbose_mode ? 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; +} + 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; } +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; +} + DltReturnValue dlt_user_log_write_utf8_string(DltContextData *log, const char *text) { - return dlt_user_log_write_string_utils(log, text, UTF8_STRING); + return dlt_user_log_write_string_utils_attr(log, text, UTF8_STRING, NULL, false); } -DltReturnValue dlt_user_log_write_sized_utf8_string(DltContextData *log, const char *text, uint16_t length) +DltReturnValue dlt_user_log_write_utf8_string_attr(DltContextData *log, const char *text, const char *name) { - return dlt_user_log_write_sized_string_utils(log, text, length, UTF8_STRING); + return dlt_user_log_write_string_utils_attr(log, text, UTF8_STRING, name, true); } -DltReturnValue dlt_user_log_write_sized_string_utils(DltContextData *log, const char *text, uint16_t length, const enum StringType type) +DltReturnValue dlt_user_log_write_sized_utf8_string(DltContextData *log, const char *text, uint16_t length) { - uint16_t arg_size = 0; - uint32_t type_info = 0; - size_t new_log_size = 0; - DltReturnValue ret = DLT_RETURN_OK; + return dlt_user_log_write_sized_string_utils_attr(log, text, length, UTF8_STRING, NULL, false); +} - size_t str_truncate_message_length = strlen(STR_TRUNCATED_MESSAGE) + 1; - size_t max_payload_str_msg; +DltReturnValue dlt_user_log_write_sized_utf8_string_attr(DltContextData *log, const char *text, uint16_t length, const char *name) +{ + return dlt_user_log_write_sized_string_utils_attr(log, text, length, UTF8_STRING, name, true); +} +static DltReturnValue dlt_user_log_write_sized_string_utils_attr(DltContextData *log, const char *text, uint16_t length, const enum StringType type, const char *name, bool with_var_info) +{ if ((log == NULL) || (text == NULL)) return DLT_RETURN_WRONG_PARAMETER; @@ -2530,12 +2355,27 @@ DltReturnValue dlt_user_log_write_sized_string_utils(DltContextData *log, const return DLT_RETURN_ERROR; } - arg_size = (uint16_t) (length + 1); + const uint16_t name_size = (name != NULL) ? strlen(name)+1 : 0; - new_log_size = log->size + arg_size + sizeof(uint16_t); + uint16_t arg_size = (uint16_t) (length + 1); - if (dlt_user.verbose_mode) + size_t new_log_size = log->size + arg_size + sizeof(uint16_t); + + uint32_t type_info = 0; + + if (dlt_user.verbose_mode) { new_log_size += sizeof(uint32_t); + if (with_var_info) { + new_log_size += sizeof(uint16_t); // length of "name" attribute + new_log_size += name_size; // the "name" attribute itself + + type_info |= DLT_TYPE_INFO_VARI; + } + } + + size_t str_truncate_message_length = strlen(STR_TRUNCATED_MESSAGE) + 1; + size_t max_payload_str_msg; + DltReturnValue ret = DLT_RETURN_OK; /* Check log size condition */ if (new_log_size > dlt_user.log_buf_len) { @@ -2549,6 +2389,10 @@ DltReturnValue dlt_user_log_write_sized_string_utils(DltContextData *log, const if (dlt_user.verbose_mode) { min_payload_str_truncate_msg += sizeof(uint32_t); arg_size -= (uint16_t) sizeof(uint32_t); + if (with_var_info) { + min_payload_str_truncate_msg += sizeof(uint16_t) + name_size; + arg_size -= sizeof(uint16_t) + name_size; + } } /* Return when dlt_user.log_buf_len does not have enough space for min_payload_str_truncate_msg */ @@ -2589,34 +2433,45 @@ DltReturnValue dlt_user_log_write_sized_string_utils(DltContextData *log, const if (dlt_user.verbose_mode) { switch (type) { case ASCII_STRING: - { - type_info = DLT_TYPE_INFO_STRG | DLT_SCOD_ASCII; + type_info |= DLT_TYPE_INFO_STRG | DLT_SCOD_ASCII; break; - } case UTF8_STRING: - { - type_info = DLT_TYPE_INFO_STRG | DLT_SCOD_UTF8; + type_info |= DLT_TYPE_INFO_STRG | DLT_SCOD_UTF8; break; - } default: - { /* Do nothing */ break; } - } - memcpy((log->buffer) + log->size, &(type_info), sizeof(uint32_t)); + memcpy(log->buffer + log->size, &type_info, sizeof(uint32_t)); log->size += sizeof(uint32_t); } - memcpy((log->buffer) + log->size, &(arg_size), sizeof(uint16_t)); + memcpy(log->buffer + log->size, &arg_size, sizeof(uint16_t)); log->size += sizeof(uint16_t); + if (dlt_user.verbose_mode) { + if (with_var_info) { + // Write length of "name" attribute. + // We assume that the protocol allows zero-sized strings here (which this code will create + // when the input pointer is NULL). + memcpy(log->buffer + log->size, &name_size, sizeof(uint16_t)); + log->size += sizeof(uint16_t); + + // Write name string itself. + // Must not use NULL as source pointer for memcpy. This check assures that. + if (name_size != 0) { + memcpy(log->buffer + log->size, name, name_size); + log->size += name_size; + } + } + } + switch (ret) { case DLT_RETURN_OK: { /* Whole string will be copied */ - memcpy((log->buffer) + log->size, text, length); + memcpy(log->buffer + log->size, text, length); /* The input string might not be null-terminated, so we're doing that by ourselves */ log->buffer[log->size + length] = '\0'; log->size += arg_size; @@ -2625,11 +2480,11 @@ DltReturnValue dlt_user_log_write_sized_string_utils(DltContextData *log, const case DLT_RETURN_USER_BUFFER_FULL: { /* Only copy partial string */ - memcpy((log->buffer) + log->size, text, max_payload_str_msg); + memcpy(log->buffer + log->size, text, max_payload_str_msg); log->size += max_payload_str_msg; /* Append string truncate the input string */ - memcpy((log->buffer) + log->size, STR_TRUNCATED_MESSAGE, str_truncate_message_length); + memcpy(log->buffer + log->size, STR_TRUNCATED_MESSAGE, str_truncate_message_length); log->size += str_truncate_message_length; break; } @@ -2645,13 +2500,13 @@ DltReturnValue dlt_user_log_write_sized_string_utils(DltContextData *log, const return ret; } -DltReturnValue dlt_user_log_write_string_utils(DltContextData *log, const char *text, const enum StringType type) +static DltReturnValue dlt_user_log_write_string_utils_attr(DltContextData *log, const char *text, const enum StringType type, const char *name, bool with_var_info) { if ((log == NULL) || (text == NULL)) return DLT_RETURN_WRONG_PARAMETER; uint16_t length = (uint16_t) strlen(text); - return dlt_user_log_write_sized_string_utils(log, text, length, type); + return dlt_user_log_write_sized_string_utils_attr(log, text, length, type, name, with_var_info); } DltReturnValue dlt_register_injection_callback_with_id(DltContext *handle, uint32_t service_id, diff --git a/src/shared/dlt_common.c b/src/shared/dlt_common.c index 5c28113..af7a373 100644 --- a/src/shared/dlt_common.c +++ b/src/shared/dlt_common.c @@ -31,6 +31,7 @@ #include /* for localtime_r(), strftime() */ #include /* for NAME_MAX */ #include /* for PRI formatting macro */ +#include #include #include @@ -81,6 +82,7 @@ static int logging_mode = DLT_LOG_TO_CONSOLE; static int logging_level = LOG_INFO; static char logging_filename[NAME_MAX + 1] = ""; static FILE *logging_handle = NULL; +static bool print_with_attributes = false; char *message_type[] = { "log", "app_trace", "nw_trace", "control", "", "", "", "" }; char *log_info[] = { "", "fatal", "error", "warn", "info", "debug", "verbose", "", "", "", "", "", "", "", "", "" }; @@ -1778,6 +1780,11 @@ void dlt_log_set_shm_name(const char * env_shm_name) } #endif +void dlt_print_with_attributes(bool state) +{ + print_with_attributes = state; +} + void dlt_log_init(int mode) { if ((mode < DLT_LOG_TO_CONSOLE) || (mode > DLT_LOG_DROPPED)) { @@ -3297,6 +3304,13 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, uint32_t quantisation_tmp = 0; + // pointer to the value string + char* value_text = text; + // pointer to the "unit" attribute string, if there is one (only for *INT and FLOAT*) + const uint8_t* unit_text_src = NULL; + // length of the "unit" attribute string, if there is one (only for *INT and FLOAT*) + size_t unit_text_len = 0; + /* apparently this makes no sense but needs to be done to prevent compiler warning. * This variable is only written by DLT_MSG_READ_VALUE macro in if (type_info & DLT_TYPE_INFO_FIXP) * case but never read anywhere */ @@ -3328,11 +3342,20 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, if ((*datalength) < length2) return DLT_RETURN_ERROR; + if (print_with_attributes) { + // Print "name" attribute, if we have one with non-zero size. + if (length2 > 1) { + snprintf(text, textlength, "%s:", *ptr); + value_text += length2+1-1; // +1 for ":" and -1 for NUL + textlength -= length2+1-1; + } + } + *ptr += length2; *datalength -= length2; } - DLT_MSG_READ_STRING(text, *ptr, *datalength, textlength, length); + DLT_MSG_READ_STRING(value_text, *ptr, *datalength, textlength, length); if ((*datalength) < 0) return DLT_RETURN_ERROR; @@ -3351,6 +3374,15 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, if ((*datalength) < length2) return DLT_RETURN_ERROR; + if (print_with_attributes) { + // Print "name" attribute, if we have one with non-zero size. + if (length2 > 1) { + snprintf(text, textlength, "%s:", *ptr); + value_text += length2+1-1; // +1 for ":" and -1 for NUL + textlength -= length2+1-2; + } + } + *ptr += length2; *datalength -= length2; } @@ -3361,7 +3393,7 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, if ((*datalength) < 0) return DLT_RETURN_ERROR; - snprintf(text, textlength, "%d", value8u); + snprintf(value_text, textlength, "%d", value8u); } else if ((type_info & DLT_TYPE_INFO_UINT) && (DLT_SCOD_BIN == (type_info & DLT_TYPE_INFO_SCOD))) { @@ -3381,7 +3413,7 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, strcat(binary, (i == (value8u & i)) ? "1" : "0"); } - snprintf(text, textlength, "0b%s", binary); + snprintf(value_text, textlength, "0b%s", binary); } if (DLT_TYLE_16BIT == (type_info & DLT_TYPE_INFO_TYLE)) { @@ -3400,7 +3432,7 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, strcat(binary, (i == (value16u & i)) ? "1" : "0"); } - snprintf(text, textlength, "0b%s", binary); + snprintf(value_text, textlength, "0b%s", binary); } } else if ((type_info & DLT_TYPE_INFO_UINT) && (DLT_SCOD_HEX == (type_info & DLT_TYPE_INFO_SCOD))) @@ -3411,7 +3443,7 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, if ((*datalength) < 0) return DLT_RETURN_ERROR; - snprintf(text, textlength, "0x%02x", value8u); + snprintf(value_text, textlength, "0x%02x", value8u); } if (DLT_TYLE_16BIT == (type_info & DLT_TYPE_INFO_TYLE)) { @@ -3420,7 +3452,7 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, if ((*datalength) < 0) return DLT_RETURN_ERROR; - snprintf(text, textlength, "0x%04x", value16u); + snprintf(value_text, textlength, "0x%04x", value16u); } if (DLT_TYLE_32BIT == (type_info & DLT_TYPE_INFO_TYLE)) { @@ -3429,7 +3461,7 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, if ((*datalength) < 0) return DLT_RETURN_ERROR; - snprintf(text, textlength, "0x%08x", value32u); + snprintf(value_text, textlength, "0x%08x", value32u); } if (DLT_TYLE_64BIT == (type_info & DLT_TYPE_INFO_TYLE)) { @@ -3439,14 +3471,14 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, if ((*datalength) < 0) return DLT_RETURN_ERROR; - snprintf(text, textlength, "0x%08x", value32u); + snprintf(value_text, textlength, "0x%08x", value32u); *ptr -= 8; DLT_MSG_READ_VALUE(value32u, *ptr, *datalength, uint32_t); if ((*datalength) < 0) return DLT_RETURN_ERROR; - snprintf(text + strlen(text), textlength - strlen(text), "%08x", value32u); + snprintf(value_text + strlen(value_text), textlength - strlen(value_text), "%08x", value32u); *ptr += 4; } } @@ -3470,12 +3502,25 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, if ((*datalength) < length2) return DLT_RETURN_ERROR; + if (print_with_attributes) { + // Print "name" attribute, if we have one with non-zero size. + if (length2 > 1) { + snprintf(text, textlength, "%s:", *ptr); + value_text += length2+1-1; // +1 for the ":", and -1 for nul + textlength -= length2+1-1; + } + } + *ptr += length2; *datalength -= length2; if ((*datalength) < length3) return DLT_RETURN_ERROR; + // We want to add the "unit" attribute only after the value, so remember its pointer and length here. + unit_text_src = *ptr; + unit_text_len = length3; + *ptr += length3; *datalength -= length3; } @@ -3533,7 +3578,7 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, if ((*datalength) < 0) return DLT_RETURN_ERROR; - snprintf(text, textlength, "%d", value8i); + snprintf(value_text, textlength, "%d", value8i); } else { value8u = 0; @@ -3542,7 +3587,7 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, if ((*datalength) < 0) return DLT_RETURN_ERROR; - snprintf(text, textlength, "%d", value8u); + snprintf(value_text, textlength, "%d", value8u); } break; @@ -3558,7 +3603,7 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, return DLT_RETURN_ERROR; value16i = (int16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16i_tmp); - snprintf(text, textlength, "%hd", value16i); + snprintf(value_text, textlength, "%hd", value16i); } else { value16u = 0; @@ -3569,7 +3614,7 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, return DLT_RETURN_ERROR; value16u = (uint16_t) DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp); - snprintf(text, textlength, "%hu", value16u); + snprintf(value_text, textlength, "%hu", value16u); } break; @@ -3585,7 +3630,7 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, return DLT_RETURN_ERROR; value32i = (int32_t) DLT_ENDIAN_GET_32(msg->standardheader->htyp, (uint32_t)value32i_tmp); - snprintf(text, textlength, "%d", value32i); + snprintf(value_text, textlength, "%d", value32i); } else { value32u = 0; @@ -3596,7 +3641,7 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, return DLT_RETURN_ERROR; value32u = DLT_ENDIAN_GET_32(msg->standardheader->htyp, value32u_tmp); - snprintf(text, textlength, "%u", value32u); + snprintf(value_text, textlength, "%u", value32u); } break; @@ -3613,9 +3658,9 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, value64i = (int64_t) DLT_ENDIAN_GET_64(msg->standardheader->htyp, (uint64_t)value64i_tmp); #if defined (__WIN32__) && !defined(_MSC_VER) - snprintf(text, textlength, "%I64d", value64i); + snprintf(value_text, textlength, "%I64d", value64i); #else - snprintf(text, textlength, "%" PRId64, value64i); + snprintf(value_text, textlength, "%" PRId64, value64i); #endif } else { @@ -3628,9 +3673,9 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, value64u = DLT_ENDIAN_GET_64(msg->standardheader->htyp, value64u_tmp); #if defined (__WIN32__) && !defined(_MSC_VER) - snprintf(text, textlength, "%I64u", value64u); + snprintf(value_text, textlength, "%I64u", value64u); #else - snprintf(text, textlength, "%" PRIu64, value64u); + snprintf(value_text, textlength, "%" PRIu64, value64u); #endif } @@ -3639,7 +3684,7 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, case DLT_TYLE_128BIT: { if (*datalength >= 16) - dlt_print_hex_string(text, (int) textlength, *ptr, 16); + dlt_print_hex_string(value_text, (int) textlength, *ptr, 16); if ((*datalength) < 16) return DLT_RETURN_ERROR; @@ -3674,12 +3719,25 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, if ((*datalength) < length2) return DLT_RETURN_ERROR; + if (print_with_attributes) { + // Print "name" attribute, if we have one with non-zero size. + if (length2 > 1) { + snprintf(text, textlength, "%s:", *ptr); + value_text += length2+1-1; // +1 for ":" and -1 for NUL + textlength -= length2+1-1; + } + } + *ptr += length2; *datalength -= length2; if ((*datalength) < length3) return DLT_RETURN_ERROR; + // We want to add the "unit" attribute only after the value, so remember its pointer and length here. + unit_text_src = *ptr; + unit_text_len = length3; + *ptr += length3; *datalength -= length3; } @@ -3688,7 +3746,7 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, case DLT_TYLE_8BIT: { if (*datalength >= 1) - dlt_print_hex_string(text, (int) textlength, *ptr, 1); + dlt_print_hex_string(value_text, (int) textlength, *ptr, 1); if ((*datalength) < 1) return DLT_RETURN_ERROR; @@ -3700,7 +3758,7 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, case DLT_TYLE_16BIT: { if (*datalength >= 2) - dlt_print_hex_string(text, (int) textlength, *ptr, 2); + dlt_print_hex_string(value_text, (int) textlength, *ptr, 2); if ((*datalength) < 2) return DLT_RETURN_ERROR; @@ -3725,7 +3783,7 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, value32f_tmp_int32i_swaped = (int32_t) DLT_ENDIAN_GET_32(msg->standardheader->htyp, (uint32_t)value32f_tmp_int32i); memcpy(&value32f, &value32f_tmp_int32i_swaped, sizeof(float32_t)); - snprintf(text, textlength, "%g", value32f); + snprintf(value_text, textlength, "%g", value32f); } else { dlt_log(LOG_ERR, "Invalid size of float32_t\n"); @@ -3751,9 +3809,9 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, (int64_t) DLT_ENDIAN_GET_64(msg->standardheader->htyp, (uint64_t)value64f_tmp_int64i); memcpy(&value64f, &value64f_tmp_int64i_swaped, sizeof(float64_t)); #ifdef __arm__ - snprintf(text, textlength, "ILLEGAL"); + snprintf(value_text, textlength, "ILLEGAL"); #else - snprintf(text, textlength, "%g", value64f); + snprintf(value_text, textlength, "%g", value64f); #endif } else { @@ -3766,7 +3824,7 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, case DLT_TYLE_128BIT: { if (*datalength >= 16) - dlt_print_hex_string(text, textlength, *ptr, 16); + dlt_print_hex_string(value_text, textlength, *ptr, 16); if ((*datalength) < 16) return DLT_RETURN_ERROR; @@ -3802,6 +3860,15 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, if ((*datalength) < length2) return DLT_RETURN_ERROR; + if (print_with_attributes) { + // Print "name" attribute, if we have one with non-zero size. + if (length2 > 1) { + snprintf(text, textlength, "%s:", *ptr); + value_text += length2+1-1; // +1 for ":" and -1 for NUL + textlength -= length2+1-1; + } + } + *ptr += length2; *datalength -= length2; } @@ -3809,7 +3876,7 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, if ((*datalength) < length) return DLT_RETURN_ERROR; - dlt_print_hex_string(text, (int) textlength, *ptr, length); + dlt_print_hex_string(value_text, (int) textlength, *ptr, length); *ptr += length; *datalength -= length; } @@ -3823,7 +3890,7 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, length = DLT_ENDIAN_GET_16(msg->standardheader->htyp, value16u_tmp); - DLT_MSG_READ_STRING(text, *ptr, *datalength, textlength, length); + DLT_MSG_READ_STRING(value_text, *ptr, *datalength, textlength, length); if ((*datalength) < 0) return DLT_RETURN_ERROR; @@ -3837,6 +3904,18 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, return DLT_RETURN_ERROR; } + // Now write "unit" attribute, but only if it has more than only a nul-termination char. + if (print_with_attributes) { + if (unit_text_len > 1) { + // 'value_text' still points to the +start+ of the value text + size_t currLen = strlen(value_text); + + char* unitText = value_text + currLen; + textlength -= currLen; + snprintf(unitText, textlength, ":%s", unit_text_src); + } + } + return DLT_RETURN_OK; } -- cgit v1.2.1