/**
* @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.
*
* this file, You can obtain one at http://mozilla.org/MPL/2.0/.
*
*
- * \author Alexander Wenzel <alexander.aw.wenzel@bmw.de> BMW 2011-2012
+ * \author
+ * Alexander Wenzel <alexander.aw.wenzel@bmw.de>
+ * Markus Klein <Markus.Klein@esk.fraunhofer.de>
+ * Mikko Rapeli <mikko.rapeli@bmw.de>
*
* \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 <stdlib.h> /* for getenv(), free(), atexit() */
#include <string.h> /* for strcmp(), strncmp(), strlen(), memset(), memcpy() */
#include <signal.h> /* for signal(), SIGPIPE, SIG_IGN */
#include <sys/uio.h> /* writev() */
#include <limits.h>
+#ifdef linux
+#include <sys/prctl.h>
+#endif
+
+#include <sys/types.h> /* needed for getpid() */
+#include <unistd.h>
+
#include "dlt_user.h"
#include "dlt_user_shared.h"
static DltUser dlt_user;
static int dlt_user_initialised = 0;
+static int dlt_user_freeing = 0;
static char str[DLT_USER_BUFFER_LENGTH];
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;
}
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() */
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;
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;
}
/* 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;
}
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;
}
/* Generate per process name for queue */
char queue_name[NAME_MAX];
- sprintf(queue_name, "%s.%d", DLT_MESSAGE_QUEUE_NAME, getpid());
+ 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;
/* 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;
{
if (dlt_user_initialised==0)
{
+ dlt_log(LOG_WARNING, "dlt_user_atexit_handler dlt_user_initialised==0\n");
+ // close file
+ dlt_log_free();
return;
}
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);
}
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)
{
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;
}
/* 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)
}
DLT_SEM_FREE();
- if (dlt_user.dlt_segmented_nwt_handle)
- {
- pthread_cancel(dlt_user.dlt_segmented_nwt_handle);
- }
-
char queue_name[NAME_MAX];
- sprintf(queue_name, "%s.%d", DLT_MESSAGE_QUEUE_NAME, getpid());
+ snprintf(queue_name,NAME_MAX, "%s.%d", DLT_MESSAGE_QUEUE_NAME, getpid());
/**
* Ignore errors from these, to not to spam user if dlt_free
mq_close(dlt_user.dlt_segmented_queue_read_handle);
mq_unlink(queue_name);
- dlt_user_initialised = 0;
+ // allow the user app to do dlt_init() again.
+ // The flag is unset only to keep almost the same behaviour as before, on EntryNav
+ // This should be removed for other projects (see documentation of dlt_free()
+ dlt_user_freeing = 0;
return 0;
}
dlt_user.application_description= malloc(desc_len+1);
if (dlt_user.application_description){
strncpy(dlt_user.application_description, description, desc_len);
-
- /* Terminate transmitted string with 0 */
dlt_user.application_description[desc_len]='\0';
}
else
{
DltContextData log;
uint32_t i;
- int registered,ret;
- char ctid[DLT_ID_SIZE+1];
if (dlt_user_initialised==0)
{
/* Check if already registered, else register context */
DLT_SEM_LOCK();
- registered=0;
- for (i=0;i<dlt_user.dlt_ll_ts_num_entries;i++)
- {
- if (dlt_user.dlt_ll_ts)
- {
- if (memcmp(dlt_user.dlt_ll_ts[i].contextID, contextid,DLT_ID_SIZE)==0)
- {
- registered=1;
+ /* Check of double context registration removed */
+ /* Double registration is already checked by daemon */
- memset(ctid,0,(DLT_ID_SIZE+1));
- dlt_print_id(ctid, contextid);
+ /* Allocate or expand context array */
+ if (dlt_user.dlt_ll_ts == 0)
+ {
+ dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*DLT_USER_CONTEXT_ALLOC_SIZE);
+ if (dlt_user.dlt_ll_ts==0)
+ {
+ DLT_SEM_FREE();
+ return -1;
+ }
- sprintf(str,"context '%s' already registered!\n",ctid);
- dlt_log(LOG_WARNING, str);
+ dlt_user.dlt_ll_ts_max_num_entries = DLT_USER_CONTEXT_ALLOC_SIZE;
- break;
- }
- }
- }
+ /* Initialize new entries */
+ for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
+ {
+ dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
- if (registered==0)
- {
- /* Allocate or expand context array */
- if (dlt_user.dlt_ll_ts == 0)
- {
- dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*DLT_USER_CONTEXT_ALLOC_SIZE);
- if (dlt_user.dlt_ll_ts==0)
- {
- DLT_SEM_FREE();
- return -1;
- }
+ /* At startup, logging and tracing is locally enabled */
+ /* the correct log level/status is set after received from daemon */
+ dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL;
+ dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
- dlt_user.dlt_ll_ts_max_num_entries = DLT_USER_CONTEXT_ALLOC_SIZE;
+ dlt_user.dlt_ll_ts[i].log_level_ptr = 0;
+ dlt_user.dlt_ll_ts[i].trace_status_ptr = 0;
- /* Initialize new entries */
- for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
- {
- dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
+ dlt_user.dlt_ll_ts[i].context_description = 0;
- /* At startup, logging and tracing is locally enabled */
- /* the correct log level/status is set after received from daemon */
- dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL;
- dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
+ dlt_user.dlt_ll_ts[i].injection_table = 0;
+ dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
+ }
+ }
+ else
+ {
+ if ((dlt_user.dlt_ll_ts_num_entries%DLT_USER_CONTEXT_ALLOC_SIZE)==0)
+ {
+ /* allocate memory in steps of DLT_USER_CONTEXT_ALLOC_SIZE, e.g. 500 */
+ dlt_ll_ts_type *old_ll_ts;
+ uint32_t old_max_entries;
- dlt_user.dlt_ll_ts[i].context_description = 0;
+ old_ll_ts = dlt_user.dlt_ll_ts;
+ old_max_entries = dlt_user.dlt_ll_ts_max_num_entries;
- dlt_user.dlt_ll_ts[i].injection_table = 0;
- dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
- }
- }
- else
- {
- if ((dlt_user.dlt_ll_ts_num_entries%DLT_USER_CONTEXT_ALLOC_SIZE)==0)
- {
- /* allocate memory in steps of DLT_USER_CONTEXT_ALLOC_SIZE, e.g. 500 */
- dlt_ll_ts_type *old_ll_ts;
- uint32_t old_max_entries;
-
- old_ll_ts = dlt_user.dlt_ll_ts;
- old_max_entries = dlt_user.dlt_ll_ts_max_num_entries;
+ dlt_user.dlt_ll_ts_max_num_entries = ((dlt_user.dlt_ll_ts_num_entries/DLT_USER_CONTEXT_ALLOC_SIZE)+1)*DLT_USER_CONTEXT_ALLOC_SIZE;
+ dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*
+ dlt_user.dlt_ll_ts_max_num_entries);
+ if (dlt_user.dlt_ll_ts==0)
+ {
+ dlt_user.dlt_ll_ts = old_ll_ts;
+ dlt_user.dlt_ll_ts_max_num_entries = old_max_entries;
+ DLT_SEM_FREE();
+ return -1;
+ }
- dlt_user.dlt_ll_ts_max_num_entries = ((dlt_user.dlt_ll_ts_num_entries/DLT_USER_CONTEXT_ALLOC_SIZE)+1)*DLT_USER_CONTEXT_ALLOC_SIZE;
- dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*
- dlt_user.dlt_ll_ts_max_num_entries);
- if (dlt_user.dlt_ll_ts==0)
- {
- dlt_user.dlt_ll_ts = old_ll_ts;
- dlt_user.dlt_ll_ts_max_num_entries = old_max_entries;
- DLT_SEM_FREE();
- return -1;
- }
+ memcpy(dlt_user.dlt_ll_ts,old_ll_ts,sizeof(dlt_ll_ts_type)*dlt_user.dlt_ll_ts_num_entries);
+ free(old_ll_ts);
- memcpy(dlt_user.dlt_ll_ts,old_ll_ts,sizeof(dlt_ll_ts_type)*dlt_user.dlt_ll_ts_num_entries);
- free(old_ll_ts);
+ /* Initialize new entries */
+ for (i=dlt_user.dlt_ll_ts_num_entries;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
+ {
+ dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
- /* Initialize new entries */
- for (i=dlt_user.dlt_ll_ts_num_entries;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
- {
- dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
+ /* At startup, logging and tracing is locally enabled */
+ /* the correct log level/status is set after received from daemon */
+ dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL;
+ dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
- /* At startup, logging and tracing is locally enabled */
- /* the correct log level/status is set after received from daemon */
- dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL;
- dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
+ dlt_user.dlt_ll_ts[i].log_level_ptr = 0;
+ dlt_user.dlt_ll_ts[i].trace_status_ptr = 0;
- dlt_user.dlt_ll_ts[i].context_description = 0;
+ dlt_user.dlt_ll_ts[i].context_description = 0;
- dlt_user.dlt_ll_ts[i].injection_table = 0;
- dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
- }
- }
- }
+ dlt_user.dlt_ll_ts[i].injection_table = 0;
+ dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
+ }
+ }
+ }
- /* Store locally context id and context description */
- dlt_set_id(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].contextID, contextid);
+ /* Store locally context id and context description */
+ dlt_set_id(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].contextID, contextid);
- if (dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description!=0)
- {
- free(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description);
- }
+ if (dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description!=0)
+ {
+ free(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description);
+ }
- dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = 0;
+ dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = 0;
- if (description!=0)
- {
- size_t desc_len = strlen(description);
- dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = malloc(desc_len+1);
- if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description == 0)
- {
- DLT_SEM_FREE();
- return -1;
- }
+ if (description!=0)
+ {
+ size_t desc_len = strlen(description);
+ dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = malloc(desc_len+1);
+ if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description == 0)
+ {
+ DLT_SEM_FREE();
+ return -1;
+ }
- strncpy(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description, description, desc_len);
+ strncpy(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description, description, desc_len);
+ dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description[desc_len]='\0';
+ }
- /* Terminate transmitted string with 0 */
- dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description[desc_len]='\0';
- }
+ if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level_ptr == 0)
+ {
+ dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level_ptr = malloc(sizeof(int8_t));
+ if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level_ptr == 0)
+ {
+ DLT_SEM_FREE();
+ return -1;
+ }
+ }
+ if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status_ptr == 0)
+ {
+ dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status_ptr = malloc(sizeof(int8_t));
+ if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status_ptr == 0)
+ {
+ DLT_SEM_FREE();
+ return -1;
+ }
+ }
- if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
- {
- dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level = loglevel;
- }
+ if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
+ {
+ dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level = loglevel;
+ }
- if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
- {
- dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status = tracestatus;
- }
+ if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
+ {
+ dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status = tracestatus;
+ }
- /* 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;
+ /* 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)
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 */
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)
*/
DLT_SEM_LOCK();
+ if (dlt_user.dlt_ll_ts==0)
+ {
+ DLT_SEM_FREE();
+ return -1;
+ }
/* Update local structures */
for (i=0; i<dlt_user.dlt_ll_ts_num_entries;i++)
{
dlt_user.dlt_ll_ts[i].log_level = loglevel;
dlt_user.dlt_ll_ts[i].trace_status = tracestatus;
+ if(dlt_user.dlt_ll_ts[i].log_level_ptr)
+ *(dlt_user.dlt_ll_ts[i].log_level_ptr) = loglevel;
+ if(dlt_user.dlt_ll_ts[i].trace_status_ptr)
+ *(dlt_user.dlt_ll_ts[i].trace_status_ptr) = tracestatus;
}
DLT_SEM_FREE();
/* 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,"Buffer full! %u messages discarded!\n",dlt_user.overflow_counter);
+ dlt_log(LOG_ERR, str);
+ dlt_user.overflow_counter=0; }
}
/* log to FIFO */
(unsigned char *)&(userheader), sizeof(DltUserHeader),
msgdata, size, 0, 0)==-1)
{
- dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
+ if(dlt_user.overflow_counter==0)
+ {
+ dlt_log(LOG_ERR,"Buffer full! First message discarded!\n");
+ }
+ ret = DLT_RETURN_BUFFER_FULL;
}
DLT_SEM_FREE();
if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
{
- dlt_log(LOG_WARNING, "dlt_forward_msg: Failed to queue resending.\n");
+ ;//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:
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;
else log->size=0;
return 1;
}
- else
- {
- DLT_SEM_FREE();
- return 0;
- }
return -1;
}
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;
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;
/* Send log */
return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
}
- else
- {
- DLT_SEM_FREE();
- }
return 0;
}
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;
/* 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();
- 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;
/* Send log */
return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
}
- else
- {
- DLT_SEM_FREE();
- }
return 0;
}
{
/* Unused on purpose. */
(void) unused;
+#ifdef linux
+ prctl(PR_SET_NAME, "dlt_segmented", 0, 0, 0);
+#endif
s_segmented_data *data;
{
// 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");
+ {
+ //dlt_log(LOG_WARNING, "Failed to queue resending in dlt_user_trace_network_segmented_thread.\n");
+ }
}
free(data);
continue;
*/
- 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;
/* Send log */
return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
}
- else
- {
- DLT_SEM_FREE();
- }
return 0;
}
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)
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 */
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
/* Open queue if it is not open */
if(dlt_init_message_queue() < 0)
{
- dlt_log(LOG_ERR, "NWTSegmented: Could not open queue.\n");
- free(resend_data);
+ 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)
{
- char str[255];
- snprintf(str,254,"Could not request resending.: %s \n",strerror(errno));
- dlt_log(LOG_CRIT, str);
+ 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;
}
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)
{
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)
/* 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;
}
}
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();
// Fail silenty if FIFO is not open
if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
{
- dlt_log(LOG_WARNING, "dlt_user_log_send_log: Failed to queue resending.\n");
+ ;//dlt_log(LOG_WARNING, "dlt_user_log_send_log: Failed to queue resending.\n");
}
}
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:
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");
+ ;//dlt_log(LOG_WARNING, "dlt_user_log_send_register_application: Failed to queue resending.\n");
}
}
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");
+ ;//dlt_log(LOG_WARNING, "dlt_user_log_send_register_context: Failed to queue resending.\n");
}
}
{
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;
}
}
/* 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;
}
handle.log_level_pos = num;
log_new.context_description = dlt_user.dlt_ll_ts[num].context_description;
+ // Release the mutex for sending context registration:
+ // function dlt_user_log_send_register_context() can take the mutex to write to the DLT buffer. => 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();
+
}
}
int dlt_user_log_send_overflow(void)
{
DltUserHeader userheader;
+ DltUserControlMsgBufferOverflow userpayload;
DltReturnValue ret;
/* set userheader */
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);
}