diff options
Diffstat (limited to 'src/shared/dlt_common.c')
-rw-r--r-- | src/shared/dlt_common.c | 249 |
1 files changed, 213 insertions, 36 deletions
diff --git a/src/shared/dlt_common.c b/src/shared/dlt_common.c index 427044b..cbbe99a 100644 --- a/src/shared/dlt_common.c +++ b/src/shared/dlt_common.c @@ -31,6 +31,7 @@ #include <time.h> /* for localtime_r(), strftime() */ #include <limits.h> /* for NAME_MAX */ #include <inttypes.h> /* for PRI formatting macro */ +#include <libgen.h> /* dirname */ #include <stdarg.h> #include <err.h> @@ -41,6 +42,7 @@ #include "dlt_user_shared.h" #include "dlt_common.h" #include "dlt_common_cfg.h" +#include "dlt_multiple_files.h" #include "dlt_version.h" @@ -81,9 +83,20 @@ char dltShmName[NAME_MAX + 1] = "/dlt-shm"; static int logging_level = LOG_INFO; static char logging_filename[NAME_MAX + 1] = ""; static bool print_with_attributes = false; -int logging_mode = DLT_LOG_TO_CONSOLE; +int logging_mode = DLT_LOG_TO_STDERR; FILE *logging_handle = NULL; +//use ohandle as an indicator that multiple files logging is active +MultipleFilesRingBuffer multiple_files_ring_buffer = { + .directory={0}, + .filename={0}, + .fileSize=0, + .maxSize=0, + .filenameTimestampBased=false, + .filenameBase={0}, + .filenameExt={0}, + .ohandle=-1}; + char *message_type[] = { "log", "app_trace", "nw_trace", "control", "", "", "", "" }; char *log_info[] = { "", "fatal", "error", "warn", "info", "debug", "verbose", "", "", "", "", "", "", "", "", "" }; char *trace_type[] = { "", "variable", "func_in", "func_out", "state", "vfb", "", "", "", "", "", "", "", "", "", "" }; @@ -202,7 +215,10 @@ DltReturnValue dlt_print_mixed_string(char *text, int textlength, uint8_t *ptr, /* Hex-Output */ /* It is not required to decrement textlength, as it was already checked, that * there is enough space for the complete output */ - dlt_print_hex_string(text, textlength, (uint8_t *)(ptr + (lines * DLT_COMMON_HEX_CHARS)), DLT_COMMON_HEX_CHARS); + if (dlt_print_hex_string(text, textlength, + (uint8_t *)(ptr + (lines * DLT_COMMON_HEX_CHARS)), + DLT_COMMON_HEX_CHARS) < DLT_RETURN_OK) + return DLT_RETURN_ERROR; text += ((2 * DLT_COMMON_HEX_CHARS) + (DLT_COMMON_HEX_CHARS - 1)); /* 32 characters + 15 spaces */ snprintf(text, 2, " "); @@ -211,8 +227,10 @@ DltReturnValue dlt_print_mixed_string(char *text, int textlength, uint8_t *ptr, /* Char-Output */ /* It is not required to decrement textlength, as it was already checked, that * there is enough space for the complete output */ - dlt_print_char_string(&text, textlength, (uint8_t *)(ptr + (lines * DLT_COMMON_HEX_CHARS)), - DLT_COMMON_HEX_CHARS); + if (dlt_print_char_string(&text, textlength, + (uint8_t *)(ptr + (lines * DLT_COMMON_HEX_CHARS)), + DLT_COMMON_HEX_CHARS) < DLT_RETURN_OK) + return DLT_RETURN_ERROR; if (html == 0) { snprintf(text, 2, "\n"); @@ -240,10 +258,11 @@ DltReturnValue dlt_print_mixed_string(char *text, int textlength, uint8_t *ptr, /* Hex-Output */ /* It is not required to decrement textlength, as it was already checked, that * there is enough space for the complete output */ - dlt_print_hex_string(text, + if (dlt_print_hex_string(text, textlength, (uint8_t *)(ptr + ((size / DLT_COMMON_HEX_CHARS) * DLT_COMMON_HEX_CHARS)), - rest); + rest) < DLT_RETURN_OK) + return DLT_RETURN_ERROR; text += 2 * rest + (rest - 1); for (i = 0; i < (DLT_COMMON_HEX_CHARS - rest); i++) { @@ -257,8 +276,10 @@ DltReturnValue dlt_print_mixed_string(char *text, int textlength, uint8_t *ptr, /* Char-Output */ /* It is not required to decrement textlength, as it was already checked, that * there is enough space for the complete output */ - dlt_print_char_string(&text, textlength, - (uint8_t *)(ptr + ((size / DLT_COMMON_HEX_CHARS) * DLT_COMMON_HEX_CHARS)), rest); + if (dlt_print_char_string(&text, textlength, + (uint8_t *)(ptr + ((size / DLT_COMMON_HEX_CHARS) * DLT_COMMON_HEX_CHARS)), + rest) < DLT_RETURN_OK) + return DLT_RETURN_ERROR; } return DLT_RETURN_OK; @@ -672,6 +693,9 @@ DltReturnValue dlt_message_header_flags(DltMessage *msg, char *text, size_t text if ((msg == NULL) || (text == NULL) || (textlength <= 0)) return DLT_RETURN_WRONG_PARAMETER; + if ((DLT_IS_HTYP_UEH(msg->standardheader->htyp)) && (msg->extendedheader == NULL)) + return DLT_RETURN_WRONG_PARAMETER; + if ((flags < DLT_HEADER_SHOW_NONE) || (flags > DLT_HEADER_SHOW_ALL)) return DLT_RETURN_WRONG_PARAMETER; @@ -1707,7 +1731,7 @@ DltReturnValue dlt_file_message(DltFile *file, int index, int verbose) return DLT_RETURN_WRONG_PARAMETER; /* check if message is in range */ - if (index >= file->counter) { + if (index < 0 || index >= file->counter) { dlt_vlog(LOG_WARNING, "Message %d out of range!\r\n", index); return DLT_RETURN_WRONG_PARAMETER; } @@ -1803,34 +1827,116 @@ void dlt_print_with_attributes(bool state) print_with_attributes = state; } -void dlt_log_init(int mode) +DltReturnValue dlt_log_init(int mode) +{ + return dlt_log_init_multiple_logfiles_support((DltLoggingMode)mode, false, 0, 0); +} + +DltReturnValue dlt_log_init_multiple_logfiles_support(const DltLoggingMode mode, const bool enable_multiple_logfiles, + const int logging_file_size, const int logging_files_max_size) { if ((mode < DLT_LOG_TO_CONSOLE) || (mode > DLT_LOG_DROPPED)) { dlt_vlog(LOG_WARNING, "Wrong parameter for mode: %d\n", mode); - return; + return DLT_RETURN_WRONG_PARAMETER; } logging_mode = mode; - if (logging_mode == DLT_LOG_TO_FILE) { - /* internal logging to file */ - logging_handle = fopen(logging_filename, "a"); + if (logging_mode != DLT_LOG_TO_FILE) { + return DLT_RETURN_OK; + } - if (logging_handle == NULL) { - dlt_user_printf("Internal log file %s cannot be opened!\n", logging_filename); - return; + if (enable_multiple_logfiles) { + dlt_user_printf("configure dlt logging using file limits\n"); + int result = dlt_log_init_multiple_logfiles(logging_file_size, logging_files_max_size); + if (result == DLT_RETURN_OK) { + return DLT_RETURN_OK; } + dlt_user_printf("dlt logging for limits fails with error code=%d, use logging without limits as fallback\n", result); + return dlt_log_init_single_logfile(); + } else { + dlt_user_printf("configure dlt logging without file limits\n"); + return dlt_log_init_single_logfile(); + } +} + +DltReturnValue dlt_log_init_single_logfile() +{ + /* internal logging to file */ + errno = 0; + logging_handle = fopen(logging_filename, "a"); + + if (logging_handle == NULL) { + dlt_user_printf("Internal log file %s cannot be opened, error: %s\n", logging_filename, strerror(errno)); + return DLT_RETURN_ERROR; } + return DLT_RETURN_OK; +} + +DltReturnValue dlt_log_init_multiple_logfiles(const int logging_file_size, const int logging_files_max_size) +{ + char path_logging_filename[PATH_MAX + 1]; + strncpy(path_logging_filename, logging_filename, PATH_MAX); + path_logging_filename[PATH_MAX] = 0; + + const char *directory = dirname(path_logging_filename); + if (directory[0]) { + char basename_logging_filename[NAME_MAX + 1]; + strncpy(basename_logging_filename, logging_filename, NAME_MAX); + basename_logging_filename[NAME_MAX] = 0; + + const char *file_name = basename(basename_logging_filename); + char filename_base[NAME_MAX]; + if (!dlt_extract_base_name_without_ext(file_name, filename_base, sizeof(filename_base))) return DLT_RETURN_ERROR; + + const char *filename_ext = get_filename_ext(file_name); + if (!filename_ext) return DLT_RETURN_ERROR; + + DltReturnValue result = multiple_files_buffer_init( + &multiple_files_ring_buffer, + directory, + logging_file_size, + logging_files_max_size, + false, + true, + filename_base, + filename_ext); + + return result; + } + + return DLT_RETURN_ERROR; } void dlt_log_free(void) { - if (logging_mode == DLT_LOG_TO_FILE) + if (logging_mode == DLT_LOG_TO_FILE) { + if (dlt_is_log_in_multiple_files_active()) { + dlt_log_free_multiple_logfiles(); + } else { + dlt_log_free_single_logfile(); + } + } +} + +void dlt_log_free_single_logfile() +{ + if (logging_handle) fclose(logging_handle); } +void dlt_log_free_multiple_logfiles() +{ + if (DLT_RETURN_ERROR == multiple_files_buffer_free(&multiple_files_ring_buffer)) return; + + // reset indicator of multiple files usage + multiple_files_ring_buffer.ohandle = -1; +} + int dlt_user_printf(const char *format, ...) { + if (format == NULL) return -1; + va_list args; va_start(args, format); @@ -1909,9 +2015,13 @@ DltReturnValue dlt_log(int prio, char *s) #endif break; case DLT_LOG_TO_FILE: - /* log to file */ - if (logging_handle) { + + if (dlt_is_log_in_multiple_files_active()) { + dlt_log_multiple_files_write(sFormatString, (unsigned int)sTimeSpec.tv_sec, + (unsigned int)(sTimeSpec.tv_nsec / 1000), getpid(), asSeverity[prio], s); + } + else if (logging_handle) { fprintf(logging_handle, sFormatString, (unsigned int)sTimeSpec.tv_sec, (unsigned int)(sTimeSpec.tv_nsec / 1000), getpid(), asSeverity[prio], s); fflush(logging_handle); @@ -3239,7 +3349,8 @@ DltReturnValue dlt_message_print_header(DltMessage *message, char *text, uint32_ if ((message == NULL) || (text == NULL)) return DLT_RETURN_WRONG_PARAMETER; - dlt_message_header(message, text, size, verbose); + if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK) + return DLT_RETURN_ERROR; dlt_user_printf("%s\n", text); return DLT_RETURN_OK; @@ -3250,9 +3361,12 @@ DltReturnValue dlt_message_print_hex(DltMessage *message, char *text, uint32_t s if ((message == NULL) || (text == NULL)) return DLT_RETURN_WRONG_PARAMETER; - dlt_message_header(message, text, size, verbose); + if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK) + return DLT_RETURN_ERROR; dlt_user_printf("%s ", text); - dlt_message_payload(message, text, size, DLT_OUTPUT_HEX, verbose); + + if (dlt_message_payload(message, text, size, DLT_OUTPUT_HEX, verbose) < DLT_RETURN_OK) + return DLT_RETURN_ERROR; dlt_user_printf("[%s]\n", text); return DLT_RETURN_OK; @@ -3263,9 +3377,12 @@ DltReturnValue dlt_message_print_ascii(DltMessage *message, char *text, uint32_t if ((message == NULL) || (text == NULL)) return DLT_RETURN_WRONG_PARAMETER; - dlt_message_header(message, text, size, verbose); + if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK) + return DLT_RETURN_ERROR; dlt_user_printf("%s ", text); - dlt_message_payload(message, text, size, DLT_OUTPUT_ASCII, verbose); + + if (dlt_message_payload(message, text, size, DLT_OUTPUT_ASCII, verbose) < DLT_RETURN_OK) + return DLT_RETURN_ERROR; dlt_user_printf("[%s]\n", text); return DLT_RETURN_OK; @@ -3276,9 +3393,12 @@ DltReturnValue dlt_message_print_mixed_plain(DltMessage *message, char *text, ui if ((message == NULL) || (text == NULL)) return DLT_RETURN_WRONG_PARAMETER; - dlt_message_header(message, text, size, verbose); + if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK) + return DLT_RETURN_ERROR; dlt_user_printf("%s \n", text); - dlt_message_payload(message, text, size, DLT_OUTPUT_MIXED_FOR_PLAIN, verbose); + + if (dlt_message_payload(message, text, size, DLT_OUTPUT_MIXED_FOR_PLAIN, verbose) < DLT_RETURN_OK) + return DLT_RETURN_ERROR; dlt_user_printf("[%s]\n", text); return DLT_RETURN_OK; @@ -3289,9 +3409,13 @@ DltReturnValue dlt_message_print_mixed_html(DltMessage *message, char *text, uin if ((message == NULL) || (text == NULL)) return DLT_RETURN_WRONG_PARAMETER; - dlt_message_header(message, text, size, verbose); + if (dlt_message_header(message, text, size, verbose) < DLT_RETURN_OK) + return DLT_RETURN_ERROR; dlt_user_printf("%s \n", text); - dlt_message_payload(message, text, size, DLT_OUTPUT_MIXED_FOR_HTML, verbose); + + if (dlt_message_payload(message, text, size, DLT_OUTPUT_MIXED_FOR_HTML, verbose) < DLT_RETURN_OK) + return DLT_RETURN_ERROR; + dlt_user_printf("[%s]\n", text); return DLT_RETURN_OK; @@ -3901,7 +4025,8 @@ DltReturnValue dlt_message_argument_print(DltMessage *msg, if ((*datalength) < length) return DLT_RETURN_ERROR; - dlt_print_hex_string_delim(value_text, (int) textlength, *ptr, length, '\''); + if (dlt_print_hex_string_delim(value_text, (int) textlength, *ptr, length, '\'') < DLT_RETURN_OK) + return DLT_RETURN_ERROR; *ptr += length; *datalength -= length; } @@ -4034,7 +4159,7 @@ int16_t dlt_getloginfo_conv_ascii_to_uint16_t(char *rp, int *rp_count) num_work[4] = 0; *rp_count += 6; - return (unsigned char)strtol(num_work, &endptr, 16); + return (uint16_t)strtol(num_work, &endptr, 16); } int16_t dlt_getloginfo_conv_ascii_to_int16_t(char *rp, int *rp_count) @@ -4056,17 +4181,31 @@ int16_t dlt_getloginfo_conv_ascii_to_int16_t(char *rp, int *rp_count) return (signed char)strtol(num_work, &endptr, 16); } -void dlt_getloginfo_conv_ascii_to_id(char *rp, int *rp_count, char *wp, int len) +void dlt_getloginfo_conv_ascii_to_string(char *rp, int *rp_count, char *wp, int len) +{ + if ((rp == NULL ) || (rp_count == NULL ) || (wp == NULL )) + return; + /* ------------------------------------------------------ + * from: [72 65 6d 6f ] -> to: [0x72,0x65,0x6d,0x6f,0x00] + * ------------------------------------------------------ */ + + int count = dlt_getloginfo_conv_ascii_to_id(rp, rp_count, wp, len); + *(wp + count) = '\0'; + + return; +} + +int dlt_getloginfo_conv_ascii_to_id(char *rp, int *rp_count, char *wp, int len) { char number16[3] = { 0 }; char *endptr; int count; if ((rp == NULL) || (rp_count == NULL) || (wp == NULL)) - return; + return 0; /* ------------------------------------------------------ - * from: [72 65 6d 6f ] -> to: [0x72,0x65,0x6d,0x6f,0x00] + * from: [72 65 6d 6f ] -> to: [0x72,0x65,0x6d,0x6f] * ------------------------------------------------------ */ for (count = 0; count < len; count++) { number16[0] = *(rp + *rp_count + 0); @@ -4075,8 +4214,7 @@ void dlt_getloginfo_conv_ascii_to_id(char *rp, int *rp_count, char *wp, int len) *rp_count += 3; } - *(wp + count) = 0; - return; + return count; } void dlt_hex_ascii_to_binary(const char *ptr, uint8_t *binary, int *size) @@ -4267,3 +4405,42 @@ int dlt_execute_command(char *filename, char *command, ...) free(args); return ret; } + +char *get_filename_ext(const char *filename) +{ + if (filename == NULL) { + fprintf(stderr, "ERROR: %s: invalid arguments\n", __FUNCTION__); + return NULL; + } + + char *dot = strrchr(filename, '.'); + return (!dot || dot == filename) ? NULL : dot; +} + +bool dlt_extract_base_name_without_ext(const char* const abs_file_name, char* base_name, long base_name_len) { + if (abs_file_name == NULL || base_name == NULL) return false; + + const char* last_separator = strrchr(abs_file_name, '.'); + if (!last_separator) return false; + long length = last_separator - abs_file_name; + length = length > base_name_len ? base_name_len : length; + + strncpy(base_name, abs_file_name, length); + base_name[length] = '\0'; + return true; +} + +void dlt_log_multiple_files_write(const char* format, ...) +{ + char output_string[2048] = { 0 }; + va_list args; + va_start (args, format); + vsnprintf(output_string, 2047, format, args); + va_end (args); + multiple_files_buffer_write(&multiple_files_ring_buffer, (unsigned char*)output_string, strlen(output_string)); +} + +bool dlt_is_log_in_multiple_files_active() +{ + return multiple_files_ring_buffer.ohandle > -1; +} |