summaryrefslogtreecommitdiff
path: root/src/shared/dlt_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/shared/dlt_common.c')
-rw-r--r--src/shared/dlt_common.c249
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;
+}