X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=src%2Flib%2Fdlt_user.c;h=2d044676d83e09d5bdcd46d87f1a64ebc109ed1e;hb=9a91fe28c05c54f7428325b0290a29c28966ae56;hp=0edea8c45d33f02f30a94593b32b468e47f00937;hpb=aa1033cbf49615f46cf2d46f22cbad547ab216ae;p=profile%2Fivi%2Fdlt-daemon.git diff --git a/src/lib/dlt_user.c b/src/lib/dlt_user.c index 0edea8c..2d04467 100644 --- a/src/lib/dlt_user.c +++ b/src/lib/dlt_user.c @@ -1,6 +1,6 @@ /** * @licence app begin@ - * Copyright (C) 2012 BMW AG + * Copyright (C) 2012-2014 BMW AG * * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps. * @@ -13,56 +13,16 @@ * this file, You can obtain one at http://mozilla.org/MPL/2.0/. * * - * \author Alexander Wenzel BMW 2011-2012 + * \author + * Alexander Wenzel + * Markus Klein + * Mikko Rapeli * * \file dlt_user.c * For further information see http://www.genivi.org/. * @licence end@ */ - -/******************************************************************************* -** ** -** SRC-MODULE: dlt_user.c ** -** ** -** TARGET : linux ** -** ** -** PROJECT : DLT ** -** ** -** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de ** -** Markus Klein ** -** ** -** PURPOSE : ** -** ** -** REMARKS : ** -** ** -** PLATFORM DEPENDANT [yes/no]: yes ** -** ** -** TO BE CHANGED BY USER [yes/no]: no ** -** ** -*******************************************************************************/ - -/******************************************************************************* -** Author Identity ** -******************************************************************************** -** ** -** Initials Name Company ** -** -------- ------------------------- ---------------------------------- ** -** aw Alexander Wenzel BMW ** -** mk Markus Klein Fraunhofer ESK ** -*******************************************************************************/ - -/******************************************************************************* -** Revision Control History ** -*******************************************************************************/ - -/* - * $LastChangedRevision: 1670 $ - * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $ - * $LastChangedBy$ - Initials Date Comment - aw 13.01.2010 initial - */ #include /* for getenv(), free(), atexit() */ #include /* for strcmp(), strncmp(), strlen(), memset(), memcpy() */ #include /* for signal(), SIGPIPE, SIG_IGN */ @@ -83,6 +43,13 @@ #include /* writev() */ #include +#ifdef linux +#include +#endif + +#include /* needed for getpid() */ +#include + #include "dlt_user.h" #include "dlt_user_shared.h" @@ -91,6 +58,7 @@ static DltUser dlt_user; static int dlt_user_initialised = 0; +static int dlt_user_freeing = 0; static char str[DLT_USER_BUFFER_LENGTH]; @@ -101,8 +69,13 @@ static pthread_attr_t dlt_receiverthread_attr; /* Segmented Network Trace */ #define DLT_MAX_TRACE_SEGMENT_SIZE 1024 #define DLT_MESSAGE_QUEUE_NAME "/dlt_message_queue" -#define DLT_DELAYED_RESEND_INDICATOR_PATTERN 0xFFFFFFFF +#define DLT_DELAYED_RESEND_INDICATOR_PATTERN 0xFFFF + +/* Mutex to wait on while message queue is not initialized */ +pthread_mutex_t mq_mutex; +pthread_cond_t mq_init_condition; +/* Structure to pass data to segmented thread */ typedef struct { DltContext *handle; uint16_t id; @@ -129,19 +102,21 @@ static int dlt_user_log_check_user_message(void); static void dlt_user_log_reattach_to_daemon(void); static int dlt_user_log_send_overflow(void); static void dlt_user_trace_network_segmented_thread(void *unused); +static void dlt_user_trace_network_segmented_thread_segmenter(s_segmented_data *data); +static int dlt_user_queue_resend(void); int dlt_user_check_library_version(const char *user_major_version,const char *user_minor_version){ - char str[200]; + char str[DLT_USER_BUFFER_LENGTH]; char lib_major_version[DLT_USER_MAX_LIB_VERSION_LENGTH]; char lib_minor_version[DLT_USER_MAX_LIB_VERSION_LENGTH]; - dlt_get_major_version( lib_major_version); - dlt_get_minor_version( lib_minor_version); + dlt_get_major_version( lib_major_version,DLT_USER_MAX_LIB_VERSION_LENGTH); + dlt_get_minor_version( lib_minor_version,DLT_USER_MAX_LIB_VERSION_LENGTH); if( (strcmp(lib_major_version,user_major_version)!=0) || (strcmp(lib_minor_version,user_minor_version)!=0)) { - sprintf(str,"DLT Library version check failed! Installed DLT library version is %s.%s - Application using DLT library version %s.%s\n",lib_major_version,lib_minor_version,user_major_version,user_minor_version); + snprintf(str,DLT_USER_BUFFER_LENGTH,"DLT Library version check failed! Installed DLT library version is %s.%s - Application using DLT library version %s.%s\n",lib_major_version,lib_minor_version,user_major_version,user_minor_version); dlt_log(LOG_WARNING, str); return -1; } @@ -153,6 +128,15 @@ int dlt_init(void) char filename[DLT_USER_MAX_FILENAME_LENGTH]; int ret; + // process is exiting. Do not allocate new resources. + if (dlt_user_freeing != 0) + { + // return negative value, to stop the current log + return -1; + } + + // WARNING: multithread unsafe ! + // Another thread will check that dlt_user_initialised != 0, but the lib is not initialised ! dlt_user_initialised = 1; /* Initialize common part of dlt_init()/dlt_init_file() */ @@ -162,30 +146,65 @@ int dlt_init(void) return -1; } + /* check environment variables */ + dlt_check_envvar(); + dlt_user.dlt_is_file = 0; dlt_user.overflow = 0; + dlt_user.overflow_counter = 0; #ifdef DLT_SHM_ENABLE memset(&(dlt_user.dlt_shm),0,sizeof(DltShm)); #endif + /* create dlt pipes directory */ + ret=mkdir(DLT_USER_DIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | S_ISVTX ); + if (ret==-1 && errno != EEXIST) + { + snprintf(str,DLT_USER_BUFFER_LENGTH,"FIFO user dir %s cannot be created!\n", DLT_USER_DIR); + dlt_log(LOG_ERR, str); + return -1; + } + + /* if dlt pipes directory is created by the application also chmod the directory */ + if(ret == 0) + { + // S_ISGID cannot be set by mkdir, let's reassign right bits + ret=chmod(DLT_USER_DIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IXGRP | S_IROTH | S_IWOTH | S_IXOTH | S_ISGID | S_ISVTX ); + if (ret==-1) + { + snprintf(str,DLT_USER_BUFFER_LENGTH,"FIFO user dir %s cannot be chmoded!\n", DLT_USER_DIR); + dlt_log(LOG_ERR, str); + return -1; + } + } + /* create and open DLT user FIFO */ - sprintf(filename,"%s/dlt%d",DLT_USER_DIR,getpid()); + snprintf(filename,DLT_USER_MAX_FILENAME_LENGTH,"%s/dlt%d",DLT_USER_DIR,getpid()); /* Try to delete existing pipe, ignore result of unlink */ unlink(filename); - ret=mkfifo(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH ); + ret=mkfifo(filename, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP ); if (ret==-1) { - sprintf(str,"Loging disabled, FIFO user %s cannot be created!\n",filename); + snprintf(str,DLT_USER_BUFFER_LENGTH,"Loging disabled, FIFO user %s cannot be created!\n",filename); dlt_log(LOG_WARNING, str); /* return 0; */ /* removed to prevent error, when FIFO already exists */ } + // S_IWGRP cannot be set by mkfifo (???), let's reassign right bits + ret=chmod(filename, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP ); + if (ret==-1) + { + snprintf(str,DLT_USER_BUFFER_LENGTH,"FIFO user %s cannot be chmoded!\n", DLT_USER_DIR); + dlt_log(LOG_ERR, str); + return -1; + } + dlt_user.dlt_user_handle = open(filename, O_RDWR | O_CLOEXEC); if (dlt_user.dlt_user_handle == DLT_FD_INIT) { - sprintf(str,"Loging disabled, FIFO user %s cannot be opened!\n",filename); + snprintf(str,DLT_USER_BUFFER_LENGTH,"Loging disabled, FIFO user %s cannot be opened!\n",filename); dlt_log(LOG_WARNING, str); unlink(filename); return 0; @@ -195,7 +214,7 @@ int dlt_init(void) dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK | O_CLOEXEC ); if (dlt_user.dlt_log_handle==-1) { - sprintf(str,"Loging disabled, FIFO %s cannot be opened with open()!\n",DLT_USER_FIFO); + snprintf(str,DLT_USER_BUFFER_LENGTH,"Loging disabled, FIFO %s cannot be opened with open()!\n",DLT_USER_FIFO); dlt_log(LOG_WARNING, str); //return 0; } @@ -205,7 +224,7 @@ int dlt_init(void) /* init shared memory */ if (dlt_shm_init_client(&(dlt_user.dlt_shm),DLT_SHM_KEY) < 0) { - sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY); + snprintf(str,DLT_USER_BUFFER_LENGTH,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY); dlt_log(LOG_WARNING, str); //return 0; } @@ -240,35 +259,15 @@ int dlt_init(void) dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n"); } - /* Generate per process name for queue */ - char queue_name[NAME_MAX]; - sprintf(queue_name, "%s.%d", DLT_MESSAGE_QUEUE_NAME, getpid()); + /* These will be lazy initialized only when needed */ + dlt_user.dlt_segmented_queue_read_handle = -1; + dlt_user.dlt_segmented_queue_write_handle = -1; - /* Maximum queue size is 10, limit to size of pointers */ - struct mq_attr mqatr; - mqatr.mq_flags = 0; - mqatr.mq_maxmsg = 10; - mqatr.mq_msgsize = sizeof(s_segmented_data *); - mqatr.mq_curmsgs = 0; - - /* Separate handles for reading and writing */ - dlt_user.dlt_segmented_queue_read_handle = mq_open(queue_name, O_CREAT| O_RDONLY, - S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, &mqatr); - if(dlt_user.dlt_segmented_queue_read_handle < 0) - { - dlt_log(LOG_CRIT, "Can't create message queue read handle!\n"); - dlt_log(LOG_CRIT, strerror(errno)); - return -1; - } - - dlt_user.dlt_segmented_queue_write_handle = mq_open(queue_name, O_WRONLY); - if(dlt_user.dlt_segmented_queue_write_handle < 0) - { - dlt_log(LOG_CRIT, "Can't open message queue write handle!\n"); - dlt_log(LOG_CRIT, strerror(errno)); - return -1; - } + /* Wait mutext for segmented thread */ + pthread_mutex_init(&mq_mutex, NULL); + pthread_cond_init(&mq_init_condition, NULL); + /* Start the segmented thread */ if(pthread_create(&(dlt_user.dlt_segmented_nwt_handle), NULL, (void *)dlt_user_trace_network_segmented_thread, NULL)) { @@ -296,7 +295,7 @@ int dlt_init_file(const char *name) dlt_user.dlt_log_handle = open(name,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */ if (dlt_user.dlt_log_handle == -1) { - sprintf(str,"Log file %s cannot be opened!\n",name); + snprintf(str,DLT_USER_BUFFER_LENGTH,"Log file %s cannot be opened!\n",name); dlt_log(LOG_ERR, str); return -1; } @@ -304,6 +303,77 @@ int dlt_init_file(const char *name) return 0; } +int dlt_init_message_queue(void) +{ + pthread_mutex_lock(&mq_mutex); + if(dlt_user.dlt_segmented_queue_read_handle >= 0 && + dlt_user.dlt_segmented_queue_write_handle >= 0) + { + // Already intialized + pthread_mutex_unlock(&mq_mutex); + return 0; + } + + /* Generate per process name for queue */ + char queue_name[NAME_MAX]; + snprintf(queue_name,NAME_MAX, "%s.%d", DLT_MESSAGE_QUEUE_NAME, getpid()); + + /* Maximum queue size is 10, limit to size of pointers */ + struct mq_attr mqatr; + mqatr.mq_flags = 0; + mqatr.mq_maxmsg = 10; + mqatr.mq_msgsize = sizeof(s_segmented_data *); + mqatr.mq_curmsgs = 0; + + /** + * Create the message queue. It must be newly created + * if old one was left by a crashing process. + * */ + dlt_user.dlt_segmented_queue_read_handle = mq_open(queue_name, O_CREAT| O_RDONLY | O_EXCL, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, &mqatr); + if(dlt_user.dlt_segmented_queue_read_handle < 0) + { + if(errno == EEXIST) + { + dlt_log(LOG_WARNING, "Old message queue exists, trying to delete.\n"); + if(mq_unlink(queue_name) < 0) + { + char str[256]; + snprintf(str,255,"Could not delete existing message queue!: %s \n",strerror(errno)); + dlt_log(LOG_CRIT, str); + } + else // Retry + { + dlt_user.dlt_segmented_queue_read_handle = mq_open(queue_name, O_CREAT| O_RDONLY | O_EXCL, + S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, &mqatr); + } + } + if(dlt_user.dlt_segmented_queue_read_handle < 0) + { + char str[256]; + snprintf(str,255,"Can't create message queue read handle!: %s \n",strerror(errno)); + dlt_log(LOG_CRIT, str); + pthread_mutex_unlock(&mq_mutex); + return -1; + } + } + + dlt_user.dlt_segmented_queue_write_handle = mq_open(queue_name, O_WRONLY|O_NONBLOCK); + if(dlt_user.dlt_segmented_queue_write_handle < 0) + { + + char str[256]; + snprintf(str,255,"Can't open message queue write handle!: %s \n",strerror(errno)); + dlt_log(LOG_CRIT, str); + pthread_mutex_unlock(&mq_mutex); + return -1; + } + + pthread_cond_signal(&mq_init_condition); + pthread_mutex_unlock(&mq_mutex); + return 0; +} + int dlt_init_common(void) { char *env_local_print; @@ -329,6 +399,18 @@ int dlt_init_common(void) /* Verbose mode is enabled by default */ dlt_user.verbose_mode = 1; + /* Use extended header for non verbose is enabled by default */ + dlt_user.use_extende_header_for_non_verbose = DLT_USER_USE_EXTENDED_HEADER_FOR_NONVERBOSE; + + /* WIth session id is enabled by default */ + dlt_user.with_session_id = DLT_USER_WITH_SESSION_ID; + + /* With timestamp is enabled by default */ + dlt_user.with_timestamp= DLT_USER_WITH_TIMESTAMP; + + /* With timestamp is enabled by default */ + dlt_user.with_ecu_id= DLT_USER_WITH_ECU_ID; + /* Local print is disabled by default */ dlt_user.enable_local_print = 0; @@ -352,6 +434,7 @@ int dlt_init_common(void) } /* Initialize LogLevel/TraceStatus field */ + DLT_SEM_LOCK(); dlt_user.dlt_ll_ts = 0; dlt_user.dlt_ll_ts_max_num_entries = 0; dlt_user.dlt_ll_ts_num_entries = 0; @@ -359,8 +442,10 @@ int dlt_init_common(void) if (dlt_buffer_init_dynamic(&(dlt_user.startup_buffer), DLT_USER_RINGBUFFER_MIN_SIZE, DLT_USER_RINGBUFFER_MAX_SIZE, DLT_USER_RINGBUFFER_STEP_SIZE)==-1) { dlt_user_initialised = 0; + DLT_SEM_FREE(); return -1; } + DLT_SEM_FREE(); signal(SIGPIPE,SIG_IGN); /* ignore pipe signals */ @@ -377,13 +462,20 @@ int dlt_init_common(void) void dlt_user_atexit_handler(void) { + if (dlt_user_initialised==0) + { + dlt_log(LOG_WARNING, "dlt_user_atexit_handler dlt_user_initialised==0\n"); + // close file + dlt_log_free(); + return; + } /* Try to resend potential log messages in the user buffer */ int count = dlt_user_atexit_blow_out_user_buffer(); if(count != 0){ char tmp[256]; - sprintf(tmp,"Lost log messages in user buffer when exiting: %i\n",count); + snprintf(tmp,256,"Lost log messages in user buffer when exiting: %i\n",count); dlt_log(LOG_ERR, tmp); } @@ -426,10 +518,19 @@ int dlt_free(void) uint32_t i; char filename[DLT_USER_MAX_FILENAME_LENGTH]; + if( dlt_user_freeing != 0 ) + // resources are already being freed. Do nothing and return. + return -1; + + // library is freeing its resources. Avoid to allocate it in dlt_init() + dlt_user_freeing = 1; + if (dlt_user_initialised==0) { + dlt_user_freeing = 0; return -1; } + dlt_user_initialised = 0; if (dlt_receiverthread_handle) { @@ -437,9 +538,14 @@ int dlt_free(void) pthread_cancel(dlt_receiverthread_handle); } + if (dlt_user.dlt_segmented_nwt_handle) + { + pthread_cancel(dlt_user.dlt_segmented_nwt_handle); + } + if (dlt_user.dlt_user_handle!=DLT_FD_INIT) { - sprintf(filename,"%s/dlt%d",DLT_USER_DIR,getpid()); + snprintf(filename,DLT_USER_MAX_FILENAME_LENGTH,"%s/dlt%d",DLT_USER_DIR,getpid()); close(dlt_user.dlt_user_handle); dlt_user.dlt_user_handle=DLT_FD_INIT; @@ -460,11 +566,16 @@ int dlt_free(void) } /* Ignore return value */ + DLT_SEM_LOCK(); dlt_receiver_free(&(dlt_user.receiver)); + DLT_SEM_FREE(); /* Ignore return value */ + DLT_SEM_LOCK(); dlt_buffer_free_dynamic(&(dlt_user.startup_buffer)); + DLT_SEM_FREE(); + DLT_SEM_LOCK(); if (dlt_user.dlt_ll_ts) { for (i=0;iappID, dlt_user.appID); - dlt_set_id(handle->contextID, contextid); - handle->log_level_pos = dlt_user.dlt_ll_ts_num_entries; + /* Prepare transfer struct */ + //dlt_set_id(log->appID, dlt_user.appID); + dlt_set_id(handle->contextID, contextid); + handle->log_level_pos = dlt_user.dlt_ll_ts_num_entries; - log.context_description = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description; + handle->log_level_ptr = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level_ptr; + handle->trace_status_ptr = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status_ptr; - if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET) - { - log.log_level = loglevel; - } - else - { - log.log_level = DLT_USER_LOG_LEVEL_NOT_SET; - } + log.context_description = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description; - if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET) - { - log.trace_status = tracestatus; - } - else - { - log.trace_status = DLT_USER_TRACE_STATUS_NOT_SET; - } + *(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level_ptr) = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level; + *(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status_ptr) = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status = tracestatus; - dlt_user.dlt_ll_ts_num_entries++; + if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET) + { + log.log_level = loglevel; + } + else + { + log.log_level = DLT_USER_LOG_LEVEL_NOT_SET; + } - DLT_SEM_FREE(); + if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET) + { + log.trace_status = tracestatus; + } + else + { + log.trace_status = DLT_USER_TRACE_STATUS_NOT_SET; + } - ret=dlt_user_log_send_register_context(&log); - } - else - { - DLT_SEM_FREE(); + dlt_user.dlt_ll_ts_num_entries++; - ret=-1; - } + DLT_SEM_FREE(); - return ret; + return dlt_user_log_send_register_context(&log); } int dlt_unregister_app(void) @@ -897,6 +999,9 @@ int dlt_unregister_context(DltContext *handle) DLT_SEM_LOCK(); + handle->log_level_ptr = 0; + handle->trace_status_ptr = 0; + if (dlt_user.dlt_ll_ts) { /* Clear and free local stored context information */ @@ -910,6 +1015,18 @@ int dlt_unregister_context(DltContext *handle) free(dlt_user.dlt_ll_ts[handle->log_level_pos].context_description); } + if (dlt_user.dlt_ll_ts[handle->log_level_pos].log_level_ptr!=0) + { + free(dlt_user.dlt_ll_ts[handle->log_level_pos].log_level_ptr); + dlt_user.dlt_ll_ts[handle->log_level_pos].log_level_ptr = 0; + } + + if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status_ptr!=0) + { + free(dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status_ptr); + dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status_ptr = 0; + } + dlt_user.dlt_ll_ts[handle->log_level_pos].context_description = 0; if (dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table) @@ -962,12 +1079,21 @@ int dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTraceStatusType */ DLT_SEM_LOCK(); + if (dlt_user.dlt_ll_ts==0) + { + DLT_SEM_FREE(); + return -1; + } /* Update local structures */ for (i=0; i= 0) + { + ;//dlt_log(LOG_WARNING, "dlt_forward_msg: Failed to queue resending.\n"); + } } switch (ret) { + case DLT_RETURN_BUFFER_FULL: + { + /* Buffer full */ + dlt_user.overflow_counter += 1; + return -1; + } case DLT_RETURN_PIPE_FULL: { /* data could not be written */ - dlt_user.overflow = 1; return -1; } case DLT_RETURN_PIPE_ERROR: @@ -1118,11 +1259,8 @@ int dlt_user_log_write_start_id(DltContext *handle, DltContextData *log,DltLogLe return -1; } - DLT_SEM_LOCK(); - - if ((loglevel<=(int)(dlt_user.dlt_ll_ts[handle->log_level_pos].log_level) ) && (loglevel!=0)) + if (handle->log_level_ptr && (loglevel<=(int)*(handle->log_level_ptr) ) && (loglevel!=0)) { - DLT_SEM_FREE(); log->args_num = 0; log->log_level = loglevel; @@ -1143,11 +1281,6 @@ int dlt_user_log_write_start_id(DltContext *handle, DltContextData *log,DltLogLe else log->size=0; return 1; } - else - { - DLT_SEM_FREE(); - return 0; - } return -1; } @@ -1701,7 +1834,61 @@ int dlt_user_log_write_string(DltContextData *log, const char *text) return -1; } - type_info = DLT_TYPE_INFO_STRG; + type_info = DLT_TYPE_INFO_STRG | DLT_SCOD_ASCII; + + memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t)); + log->size += sizeof(uint32_t); + } + + arg_size = strlen(text) + 1; + + memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t)); + log->size += sizeof(uint16_t); + + memcpy((log->buffer)+log->size,text,arg_size); + log->size += arg_size; + + log->args_num ++; + + return 0; +} + +int dlt_user_log_write_constant_string(DltContextData *log, const char *text) +{ + /* Send parameter only in verbose mode */ + if (dlt_user.verbose_mode) + { + return dlt_user_log_write_string(log,text); + } + + return 0; +} + +int dlt_user_log_write_utf8_string(DltContextData *log, const char *text) +{ + uint16_t arg_size; + uint32_t type_info; + + if ((log==0) || (text==0)) + { + return -1; + } + + arg_size = strlen(text)+1; + + if ((log->size+arg_size+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + if (dlt_user.verbose_mode) + { + if ((log->size+arg_size+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE) + { + return -1; + } + + type_info = DLT_TYPE_INFO_STRG | DLT_SCOD_UTF8; memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t)); log->size += sizeof(uint32_t); @@ -1852,17 +2039,14 @@ int dlt_user_trace_network_segmented_start(uint16_t *id, DltContext *handle, Dlt return -1; } - DLT_SEM_LOCK(); if (dlt_user.dlt_ll_ts==0) { - DLT_SEM_FREE(); return -1; } - if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON) + if (handle->trace_status_ptr && *(handle->trace_status_ptr)==DLT_TRACE_STATUS_ON) { - DLT_SEM_FREE(); log.args_num = 0; log.trace_status = nw_trace_type; @@ -1918,10 +2102,6 @@ int dlt_user_trace_network_segmented_start(uint16_t *id, DltContext *handle, Dlt /* Send log */ return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE); } - else - { - DLT_SEM_FREE(); - } return 0; } @@ -1945,17 +2125,13 @@ int dlt_user_trace_network_segmented_segment(uint16_t id, DltContext *handle, Dl return -1; } - DLT_SEM_LOCK(); - if (dlt_user.dlt_ll_ts==0) { - DLT_SEM_FREE(); return -1; } - if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON) + if (handle->trace_status_ptr && *(handle->trace_status_ptr)==DLT_TRACE_STATUS_ON) { - DLT_SEM_FREE(); log.args_num = 0; log.trace_status = nw_trace_type; @@ -1988,10 +2164,6 @@ int dlt_user_trace_network_segmented_segment(uint16_t id, DltContext *handle, Dl /* Send log */ return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE); } - else - { - DLT_SEM_FREE(); - } /* Allow other threads to log between chunks */ pthread_yield(); @@ -2014,17 +2186,13 @@ int dlt_user_trace_network_segmented_end(uint16_t id, DltContext *handle, DltNet - DLT_SEM_LOCK(); - if (dlt_user.dlt_ll_ts==0) { - DLT_SEM_FREE(); return -1; } - if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON) + if (handle->trace_status_ptr && *(handle->trace_status_ptr)==DLT_TRACE_STATUS_ON) { - DLT_SEM_FREE(); log.args_num = 0; log.trace_status = nw_trace_type; @@ -2045,84 +2213,110 @@ int dlt_user_trace_network_segmented_end(uint16_t id, DltContext *handle, DltNet /* Send log */ return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE); } - else - { - DLT_SEM_FREE(); - } return 0; } + void dlt_user_trace_network_segmented_thread(void *unused) { /* Unused on purpose. */ (void) unused; +#ifdef linux + prctl(PR_SET_NAME, "dlt_segmented", 0, 0, 0); +#endif s_segmented_data *data; - while(1) - { - ssize_t read = mq_receive(dlt_user.dlt_segmented_queue_read_handle, (char *)&data, - sizeof(s_segmented_data * ), NULL); - if(read != sizeof(s_segmented_data *)) - { - dlt_log(LOG_ERR, "NWTSegmented: Error while reading queue.\n"); - dlt_log(LOG_ERR, strerror(errno)); - continue; - } + while(1) + { + // Wait until message queue is initialized + pthread_mutex_lock(&mq_mutex); + if(dlt_user.dlt_segmented_queue_read_handle < 0) + { + pthread_cond_wait(&mq_init_condition, &mq_mutex); + } + pthread_mutex_unlock(&mq_mutex); - /* Indicator just to try to flush the buffer */ - if(data->payload == (void *)DLT_DELAYED_RESEND_INDICATOR_PATTERN) - { - dlt_user_log_resend_buffer(); - free(data); - continue; - } + ssize_t read = mq_receive(dlt_user.dlt_segmented_queue_read_handle, (char *)&data, + sizeof(s_segmented_data * ), NULL); - /* Segment the data and send the chunks */ - void *ptr = NULL; - uint16_t offset = 0; - uint16_t sequence = 0; - do - { - uint16_t len = 0; - if(offset + DLT_MAX_TRACE_SEGMENT_SIZE > data->payload_len) - { - len = data->payload_len - offset; - } - else - { - len = DLT_MAX_TRACE_SEGMENT_SIZE; - } - /* If payload size aligns perfectly with segment size, avoid sendind empty segment */ - if(len == 0) - { - break; - } + if(read != sizeof(s_segmented_data *)) + { - ptr = data->payload + offset; - DltReturnValue err = dlt_user_trace_network_segmented_segment(data->id, data->handle, data->nw_trace_type, sequence++, len, ptr); - if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR) - { - dlt_log(LOG_ERR,"NWTSegmented: Could not send segment. Aborting.\n"); - break; // Inner loop - } - offset += len; - }while(ptr < data->payload + data->payload_len); + char str[255]; + snprintf(str,254,"NWTSegmented: Error while reading queue: %s \n",strerror(errno)); + dlt_log(LOG_CRIT, str); + continue; + } - /* Send the end message */ - DltReturnValue err = dlt_user_trace_network_segmented_end(data->id, data->handle, data->nw_trace_type); - if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR) - { - dlt_log(LOG_ERR,"NWTSegmented: Could not send end segment.\n"); - } + /* Indicator just to try to flush the buffer */ + if(data->payload_len == DLT_DELAYED_RESEND_INDICATOR_PATTERN) + { + // Sleep 100ms, to allow other process to read FIFO + usleep(100*1000); + if(dlt_user_log_resend_buffer() < 0) + { + // Requeue if still not empty + if ( dlt_user_queue_resend() < 0 ) + { + //dlt_log(LOG_WARNING, "Failed to queue resending in dlt_user_trace_network_segmented_thread.\n"); + } + } + free(data); + continue; + } - /* Free resources */ - free(data->header); - free(data->payload); - free(data); - } + dlt_user_trace_network_segmented_thread_segmenter(data); + + /* Send the end message */ + DltReturnValue err = dlt_user_trace_network_segmented_end(data->id, data->handle, data->nw_trace_type); + if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR) + { + dlt_log(LOG_ERR,"NWTSegmented: Could not send end segment.\n"); + } + + /* Free resources */ + free(data->header); + free(data->payload); + free(data); + } +} + +void dlt_user_trace_network_segmented_thread_segmenter(s_segmented_data *data) +{ + /* Segment the data and send the chunks */ + void *ptr = NULL; + uint16_t offset = 0; + uint16_t sequence = 0; + do + { + uint16_t len = 0; + if(offset + DLT_MAX_TRACE_SEGMENT_SIZE > data->payload_len) + { + len = data->payload_len - offset; + } + else + { + len = DLT_MAX_TRACE_SEGMENT_SIZE; + } + /* If payload size aligns perfectly with segment size, avoid sending empty segment */ + if(len == 0) + { + break; + } + + ptr = data->payload + offset; + DltReturnValue err = dlt_user_trace_network_segmented_segment(data->id, data->handle, data->nw_trace_type, sequence++, len, ptr); + if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR) + { + dlt_log(LOG_ERR,"NWTSegmented: Could not send segment. Aborting.\n"); + break; // loop + } + offset += len; + }while(ptr < data->payload + data->payload_len); } + int dlt_user_trace_network_segmented(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload) { /* Send as normal trace if possible */ @@ -2172,17 +2366,36 @@ int dlt_user_trace_network_segmented(DltContext *handle, DltNetworkTraceType nw_ return -1; } + /* Open queue if it is not open */ + if(dlt_init_message_queue() < 0) + { + dlt_log(LOG_ERR, "NWTSegmented: Could not open queue.\n"); + free(thread_data->header); + free(thread_data->payload); + free(thread_data); + + return -1; + } + /* Add to queue */ if(mq_send(dlt_user.dlt_segmented_queue_write_handle, (char *)&thread_data, sizeof(s_segmented_data *), 1) < 0) { + if(errno == EAGAIN) + { + dlt_log(LOG_ERR, "NWTSegmented: Queue full. Message discarded.\n"); + } free(thread_data->header); free(thread_data->payload); - free(thread_data); - dlt_log(LOG_ERR, "NWTSegmented: Could not write into queue.\n"); - dlt_log(LOG_ERR, strerror(errno)); + free(thread_data); + char str[256]; + snprintf(str,255,"NWTSegmented: Could not write into queue: %s \n",strerror(errno)); + dlt_log(LOG_CRIT, str); return -1; } + + //thread_data will be freed by the receiver function + //coverity[leaked_storage] return 0; } @@ -2222,17 +2435,13 @@ int dlt_user_trace_network_truncated(DltContext *handle, DltNetworkTraceType nw_ */ - DLT_SEM_LOCK(); - if (dlt_user.dlt_ll_ts==0) { - DLT_SEM_FREE(); return -1; } - if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON) + if (handle->trace_status_ptr && *(handle->trace_status_ptr)==DLT_TRACE_STATUS_ON) { - DLT_SEM_FREE(); log.args_num = 0; log.trace_status = nw_trace_type; @@ -2300,10 +2509,6 @@ int dlt_user_trace_network_truncated(DltContext *handle, DltNetworkTraceType nw_ /* Send log */ return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE); } - else - { - DLT_SEM_FREE(); - } return 0; } @@ -2522,6 +2727,70 @@ int dlt_nonverbose_mode(void) return 0; } +int dlt_use_extended_header_for_non_verbose(int8_t use_extende_header_for_non_verbose) +{ + if (dlt_user_initialised==0) + { + if (dlt_init()<0) + { + return -1; + } + } + + /* Set use_extende_header_for_non_verbose */ + dlt_user.use_extende_header_for_non_verbose = use_extende_header_for_non_verbose; + + return 0; +} + +int dlt_with_session_id(int8_t with_session_id) +{ + if (dlt_user_initialised==0) + { + if (dlt_init()<0) + { + return -1; + } + } + + /* Set use_extende_header_for_non_verbose */ + dlt_user.with_session_id = with_session_id; + + return 0; +} + +int dlt_with_timestamp(int8_t with_timestamp) +{ + if (dlt_user_initialised==0) + { + if (dlt_init()<0) + { + return -1; + } + } + + /* Set with_timestamp */ + dlt_user.with_timestamp = with_timestamp; + + return 0; +} + +int dlt_with_ecu_id(int8_t with_ecu_id) +{ + if (dlt_user_initialised==0) + { + if (dlt_init()<0) + { + return -1; + } + } + + /* Set with_timestamp */ + dlt_user.with_ecu_id = with_ecu_id; + + return 0; +} + int dlt_enable_local_print(void) { if (dlt_user_initialised==0) @@ -2554,6 +2823,9 @@ int dlt_disable_local_print(void) void dlt_user_receiverthread_function(__attribute__((unused)) void *ptr) { +#ifdef linux + prctl(PR_SET_NAME, "dlt_receiver", 0, 0, 0); +#endif while (1) { /* Check for new messages from DLT daemon */ @@ -2584,6 +2856,64 @@ int dlt_user_log_init(DltContext *handle, DltContextData *log) return 0; } +int dlt_user_queue_resend(void) +{ + static unsigned char dlt_user_queue_resend_error_counter = 0; + + if(dlt_user.dlt_log_handle < 0) + { + // Fail silenty. FIFO is not open yet + return -1; + } + /** + * Ask segmented thread to try emptying the buffer soon. + * This will be freed in dlt_user_trace_network_segmented_thread + * */ + s_segmented_data *resend_data = malloc(sizeof(s_segmented_data)); + + if (NULL == resend_data) + { + return -1; + } + + resend_data->payload_len = DLT_DELAYED_RESEND_INDICATOR_PATTERN; + + + + /* Open queue if it is not open */ + if(dlt_init_message_queue() < 0) + { + if(!dlt_user_queue_resend_error_counter) + { + // log error only when problem occurred first time + dlt_log(LOG_ERR, "NWTSegmented: Could not open queue.\n"); + } + dlt_user_queue_resend_error_counter = 1; + free(resend_data); + return -1; + } + + if(mq_send(dlt_user.dlt_segmented_queue_write_handle, (char *)&resend_data, sizeof(s_segmented_data *), 1) < 0) + { + if(!dlt_user_queue_resend_error_counter) + { + // log error only when problem occurred first time + char str[255]; + snprintf(str,254,"Could not request resending.: %s \n",strerror(errno)); + dlt_log(LOG_CRIT, str); + } + dlt_user_queue_resend_error_counter = 1; + free(resend_data); + return -1; + } + + dlt_user_queue_resend_error_counter = 0; + + //thread_data will be freed by the receiver function + //coverity[leaked_storage] + return 0; +} + DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype) { DltMessage msg; @@ -2640,7 +2970,26 @@ DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype) } msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader)); - msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_PROTOCOL_VERSION1 ; + msg.standardheader->htyp = DLT_HTYP_PROTOCOL_VERSION1 ; + + /* send ecu id */ + if(dlt_user.with_ecu_id) + { + msg.standardheader->htyp |= DLT_HTYP_WEID; + } + + /* send timestamp */ + if(dlt_user.with_timestamp) + { + msg.standardheader->htyp |= DLT_HTYP_WTMS; + } + + /* send session id */ + if(dlt_user.with_session_id) + { + msg.standardheader->htyp |= DLT_HTYP_WSID; + msg.headerextra.seid = getpid(); + } if (dlt_user.verbose_mode) { @@ -2650,9 +2999,8 @@ DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype) else { /* In non-verbose, send extended header if desired */ -#if (DLT_USER_USE_EXTENDED_HEADER_FOR_NONVERBOSE==1) - msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH ); -#endif + if(dlt_user.use_extende_header_for_non_verbose) + msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH ); } #if (BYTE_ORDER==BIG_ENDIAN) @@ -2748,11 +3096,13 @@ DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype) /* Reattach to daemon if neccesary */ dlt_user_log_reattach_to_daemon(); - if (dlt_user.overflow) + if (dlt_user.overflow_counter) { if (dlt_user_log_send_overflow()==0) { - dlt_user.overflow=0; + snprintf(str,DLT_USER_BUFFER_LENGTH,"%u messages discarded!\n",dlt_user.overflow_counter); + dlt_log(LOG_ERR, str); + dlt_user.overflow_counter=0; } } @@ -2803,23 +3153,20 @@ DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype) msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader), log->buffer, log->size)==-1) { - dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n"); - ret = DLT_RETURN_BUFFER_FULL; + if(dlt_user.overflow_counter==0) + { + + dlt_log(LOG_ERR,"Buffer full! Messages will be discarded.\n"); + } + ret = DLT_RETURN_BUFFER_FULL; } DLT_SEM_FREE(); - /** - * Ask segmented thread to try emptying the buffer soon. - * This will be freed in dlt_user_trace_network_segmented_thread - * */ - s_segmented_data *resend_data = malloc(sizeof(s_segmented_data)); - resend_data->payload = (void *)DLT_DELAYED_RESEND_INDICATOR_PATTERN; - if(mq_send(dlt_user.dlt_segmented_queue_write_handle, (char *)&resend_data, sizeof(s_segmented_data *), 1) < 0) + // Fail silenty if FIFO is not open + if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0) { - dlt_log(LOG_ERR,"Could not request resending.\n"); - dlt_log(LOG_ERR, strerror(errno)); - free(resend_data); + ;//dlt_log(LOG_WARNING, "dlt_user_log_send_log: Failed to queue resending.\n"); } } @@ -2828,12 +3175,12 @@ DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype) case DLT_RETURN_BUFFER_FULL: { /* Buffer full */ + dlt_user.overflow_counter += 1; return DLT_RETURN_BUFFER_FULL; } case DLT_RETURN_PIPE_FULL: { /* data could not be written */ - dlt_user.overflow = 1; return DLT_RETURN_PIPE_FULL; } case DLT_RETURN_PIPE_ERROR: @@ -2929,6 +3276,11 @@ int dlt_user_log_send_register_application(void) } DLT_SEM_FREE(); + + if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0) + { + ;//dlt_log(LOG_WARNING, "dlt_user_log_send_register_application: Failed to queue resending.\n"); + } } return 0; @@ -3035,6 +3387,11 @@ int dlt_user_log_send_register_context(DltContextData *log) } DLT_SEM_FREE(); + + if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0) + { + ;//dlt_log(LOG_WARNING, "dlt_user_log_send_register_context: Failed to queue resending.\n"); + } } return 0; @@ -3255,7 +3612,8 @@ int dlt_user_log_check_user_message(void) while ((int32_t)(sizeof(DltUserHeader)+offset)<=receiver->bytesRcvd); /* Check for user header pattern */ - if (dlt_user_check_userheader(userheader)==0) + if (dlt_user_check_userheader(userheader)<0 || + dlt_user_check_userheader(userheader)==0) { break; } @@ -3291,6 +3649,10 @@ int dlt_user_log_check_user_message(void) { dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level = usercontextll->log_level; dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status = usercontextll->trace_status; + if(dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level_ptr) + *(dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level_ptr) = usercontextll->log_level; + if(dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status_ptr) + *(dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status_ptr) = usercontextll->trace_status; } } @@ -3357,7 +3719,10 @@ int dlt_user_log_check_user_message(void) /* Delayed injection callback call */ if(delayed_inject_buffer != 0 && delayed_injection_callback.injection_callback != 0) { delayed_injection_callback.injection_callback(delayed_injection_callback.service_id, delayed_inject_buffer, delayed_inject_data_length); - free(delayed_inject_buffer); + delayed_injection_callback.injection_callback = 0; + free(delayed_inject_buffer); + delayed_inject_buffer = NULL; + } /* keep not read data in buffer */ @@ -3418,7 +3783,6 @@ int dlt_user_log_check_user_message(void) int dlt_user_log_resend_buffer(void) { int num,count; - uint8_t buf[DLT_USER_RCVBUF_MAX_SIZE]; int size; DltReturnValue ret; @@ -3431,18 +3795,18 @@ int dlt_user_log_resend_buffer(void) { DLT_SEM_LOCK(); - size = dlt_buffer_copy(&(dlt_user.startup_buffer),buf,sizeof(buf)); + size = dlt_buffer_copy(&(dlt_user.startup_buffer),dlt_user.resend_buffer,sizeof(dlt_user.resend_buffer)); if (size>0) { #ifdef DLT_SHM_ENABLE - dlt_shm_push(&dlt_user.dlt_shm,buf+sizeof(DltUserHeader),size-sizeof(DltUserHeader),0,0,0,0); + dlt_shm_push(&dlt_user.dlt_shm,dlt_user.resend_buffer+sizeof(DltUserHeader),size-sizeof(DltUserHeader),0,0,0,0); /* log to FIFO */ - ret = dlt_user_log_out3(dlt_user.dlt_log_handle, buf,sizeof(DltUserHeader),0,0,0,0); + ret = dlt_user_log_out3(dlt_user.dlt_log_handle, dlt_user.resend_buffer,sizeof(DltUserHeader),0,0,0,0); #else /* log to FIFO */ - ret = dlt_user_log_out3(dlt_user.dlt_log_handle, buf,size,0,0,0,0); + ret = dlt_user_log_out3(dlt_user.dlt_log_handle, dlt_user.resend_buffer,size,0,0,0,0); #endif /* in case of error, keep message in ringbuffer */ @@ -3487,7 +3851,7 @@ void dlt_user_log_reattach_to_daemon(void) /* init shared memory */ if (dlt_shm_init_client(&dlt_user.dlt_shm,DLT_SHM_KEY) < 0) { - sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY); + snprintf(str,DLT_USER_BUFFER_LENGTH,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY); dlt_log(LOG_WARNING, str); //return 0; } @@ -3507,23 +3871,31 @@ void dlt_user_log_reattach_to_daemon(void) for (num=0; num dead lock + DLT_SEM_FREE(); + log_new.log_level = DLT_USER_LOG_LEVEL_NOT_SET; log_new.trace_status = DLT_USER_TRACE_STATUS_NOT_SET; if (dlt_user_log_send_register_context(&log_new)==-1) { - DLT_SEM_FREE(); return; } reregistered=1; + + // Lock again the mutex + // it is necessary in the for(;;) test, in order to have coherent dlt_user data all over the critical section. + DLT_SEM_LOCK(); + } } @@ -3540,6 +3912,7 @@ void dlt_user_log_reattach_to_daemon(void) int dlt_user_log_send_overflow(void) { DltUserHeader userheader; + DltUserControlMsgBufferOverflow userpayload; DltReturnValue ret; /* set userheader */ @@ -3553,8 +3926,13 @@ int dlt_user_log_send_overflow(void) return 0; } + /* set user message parameters */ + userpayload.overflow_counter = dlt_user.overflow_counter; + dlt_set_id(userpayload.apid,dlt_user.appID); + /* log to FIFO */ - ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), 0, 0); + ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), + &(userpayload), sizeof(DltUserControlMsgBufferOverflow)); return ((ret==DLT_RETURN_OK)?0:-1); }