3 * Copyright (C) 2012-2014 BMW AG
5 * This file is part of GENIVI Project Dlt - Diagnostic Log and Trace console apps.
7 * Contributions are licensed to the GENIVI Alliance under one or more
8 * Contribution License Agreements.
11 * This Source Code Form is subject to the terms of the
12 * Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with
13 * this file, You can obtain one at http://mozilla.org/MPL/2.0/.
17 * Alexander Wenzel <alexander.aw.wenzel@bmw.de>
18 * Markus Klein <Markus.Klein@esk.fraunhofer.de>
19 * Mikko Rapeli <mikko.rapeli@bmw.de>
22 * For further information see http://www.genivi.org/.
26 #include <stdlib.h> /* for getenv(), free(), atexit() */
27 #include <string.h> /* for strcmp(), strncmp(), strlen(), memset(), memcpy() */
28 #include <signal.h> /* for signal(), SIGPIPE, SIG_IGN */
30 #if !defined (__WIN32__)
31 #include <syslog.h> /* for LOG_... */
32 #include <semaphore.h>
33 #include <pthread.h> /* POSIX Threads */
43 #include <sys/uio.h> /* writev() */
47 #include <sys/prctl.h>
50 #include <sys/types.h> /* needed for getpid() */
55 #include "dlt_user_shared.h"
56 #include "dlt_user_shared_cfg.h"
57 #include "dlt_user_cfg.h"
59 static DltUser dlt_user;
60 static int dlt_user_initialised = 0;
61 static int dlt_user_freeing = 0;
63 static char str[DLT_USER_BUFFER_LENGTH];
65 static sem_t dlt_mutex;
66 static pthread_t dlt_receiverthread_handle;
67 static pthread_attr_t dlt_receiverthread_attr;
69 /* Segmented Network Trace */
70 #define DLT_MAX_TRACE_SEGMENT_SIZE 1024
71 #define DLT_MESSAGE_QUEUE_NAME "/dlt_message_queue"
72 #define DLT_DELAYED_RESEND_INDICATOR_PATTERN 0xFFFF
74 /* Mutex to wait on while message queue is not initialized */
75 pthread_mutex_t mq_mutex;
76 pthread_cond_t mq_init_condition;
78 /* Structure to pass data to segmented thread */
82 DltNetworkTraceType nw_trace_type;
89 /* Function prototypes for internally used functions */
90 static void dlt_user_receiverthread_function(void *ptr);
91 static void dlt_user_atexit_handler(void);
92 static int dlt_user_log_init(DltContext *handle, DltContextData *log);
93 static DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype);
94 static int dlt_user_log_send_register_application(void);
95 static int dlt_user_log_send_unregister_application(void);
96 static int dlt_user_log_send_register_context(DltContextData *log);
97 static int dlt_user_log_send_unregister_context(DltContextData *log);
98 static int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus);
99 static int dlt_user_log_send_log_mode(DltUserLogMode mode);
100 static int dlt_user_print_msg(DltMessage *msg, DltContextData *log);
101 static int dlt_user_log_check_user_message(void);
102 static void dlt_user_log_reattach_to_daemon(void);
103 static int dlt_user_log_send_overflow(void);
104 static void dlt_user_trace_network_segmented_thread(void *unused);
105 static void dlt_user_trace_network_segmented_thread_segmenter(s_segmented_data *data);
106 static int dlt_user_queue_resend(void);
108 int dlt_user_check_library_version(const char *user_major_version,const char *user_minor_version){
110 char str[DLT_USER_BUFFER_LENGTH];
111 char lib_major_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
112 char lib_minor_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
114 dlt_get_major_version( lib_major_version,DLT_USER_MAX_LIB_VERSION_LENGTH);
115 dlt_get_minor_version( lib_minor_version,DLT_USER_MAX_LIB_VERSION_LENGTH);
117 if( (strcmp(lib_major_version,user_major_version)!=0) || (strcmp(lib_minor_version,user_minor_version)!=0))
119 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);
120 dlt_log(LOG_WARNING, str);
128 char filename[DLT_USER_MAX_FILENAME_LENGTH];
131 // process is exiting. Do not allocate new resources.
132 if (dlt_user_freeing != 0)
134 // return negative value, to stop the current log
138 // WARNING: multithread unsafe !
139 // Another thread will check that dlt_user_initialised != 0, but the lib is not initialised !
140 dlt_user_initialised = 1;
142 /* Initialize common part of dlt_init()/dlt_init_file() */
143 if (dlt_init_common()==-1)
145 dlt_user_initialised = 0;
149 /* check environment variables */
152 dlt_user.dlt_is_file = 0;
153 dlt_user.overflow = 0;
154 dlt_user.overflow_counter = 0;
155 #ifdef DLT_SHM_ENABLE
156 memset(&(dlt_user.dlt_shm),0,sizeof(DltShm));
159 /* create dlt pipes directory */
160 ret=mkdir(DLT_USER_DIR, S_IRUSR | S_IWUSR | S_IXUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH | S_ISVTX );
161 if (ret==-1 && errno != EEXIST)
163 snprintf(str,DLT_USER_BUFFER_LENGTH,"FIFO user dir %s cannot be created!\n", DLT_USER_DIR);
164 dlt_log(LOG_ERR, str);
168 /* if dlt pipes directory is created by the application also chmod the directory */
171 // S_ISGID cannot be set by mkdir, let's reassign right bits
172 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 );
175 snprintf(str,DLT_USER_BUFFER_LENGTH,"FIFO user dir %s cannot be chmoded!\n", DLT_USER_DIR);
176 dlt_log(LOG_ERR, str);
181 /* create and open DLT user FIFO */
182 snprintf(filename,DLT_USER_MAX_FILENAME_LENGTH,"%s/dlt%d",DLT_USER_DIR,getpid());
184 /* Try to delete existing pipe, ignore result of unlink */
187 ret=mkfifo(filename, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP );
190 snprintf(str,DLT_USER_BUFFER_LENGTH,"Loging disabled, FIFO user %s cannot be created!\n",filename);
191 dlt_log(LOG_WARNING, str);
192 /* return 0; */ /* removed to prevent error, when FIFO already exists */
195 // S_IWGRP cannot be set by mkfifo (???), let's reassign right bits
196 ret=chmod(filename, S_IRUSR | S_IWUSR | S_IWGRP | S_IRGRP );
199 snprintf(str,DLT_USER_BUFFER_LENGTH,"FIFO user %s cannot be chmoded!\n", DLT_USER_DIR);
200 dlt_log(LOG_ERR, str);
204 dlt_user.dlt_user_handle = open(filename, O_RDWR | O_CLOEXEC);
205 if (dlt_user.dlt_user_handle == DLT_FD_INIT)
207 snprintf(str,DLT_USER_BUFFER_LENGTH,"Loging disabled, FIFO user %s cannot be opened!\n",filename);
208 dlt_log(LOG_WARNING, str);
213 /* open DLT output FIFO */
214 dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK | O_CLOEXEC );
215 if (dlt_user.dlt_log_handle==-1)
217 snprintf(str,DLT_USER_BUFFER_LENGTH,"Loging disabled, FIFO %s cannot be opened with open()!\n",DLT_USER_FIFO);
218 dlt_log(LOG_WARNING, str);
223 #ifdef DLT_SHM_ENABLE
224 /* init shared memory */
225 if (dlt_shm_init_client(&(dlt_user.dlt_shm),DLT_SHM_KEY) < 0)
227 snprintf(str,DLT_USER_BUFFER_LENGTH,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY);
228 dlt_log(LOG_WARNING, str);
235 if (dlt_receiver_init(&(dlt_user.receiver),dlt_user.dlt_user_handle, DLT_USER_RCVBUF_MAX_SIZE)==-1)
237 dlt_user_initialised = 0;
241 /* Start receiver thread */
242 if (pthread_create(&(dlt_receiverthread_handle),
244 (void *) &dlt_user_receiverthread_function,
247 if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0)
249 dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n");
252 dlt_log(LOG_CRIT, "Can't create receiver thread!\n");
253 dlt_user_initialised = 0;
257 if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0)
259 dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n");
262 /* These will be lazy initialized only when needed */
263 dlt_user.dlt_segmented_queue_read_handle = -1;
264 dlt_user.dlt_segmented_queue_write_handle = -1;
266 /* Wait mutext for segmented thread */
267 pthread_mutex_init(&mq_mutex, NULL);
268 pthread_cond_init(&mq_init_condition, NULL);
270 /* Start the segmented thread */
271 if(pthread_create(&(dlt_user.dlt_segmented_nwt_handle), NULL,
272 (void *)dlt_user_trace_network_segmented_thread, NULL))
274 dlt_log(LOG_CRIT, "Can't start segmented thread!\n");
281 int dlt_init_file(const char *name)
283 dlt_user_initialised = 1;
285 /* Initialize common part of dlt_init()/dlt_init_file() */
286 if (dlt_init_common()==-1)
288 dlt_user_initialised = 0;
292 dlt_user.dlt_is_file = 1;
294 /* open DLT output file */
295 dlt_user.dlt_log_handle = open(name,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */
296 if (dlt_user.dlt_log_handle == -1)
298 snprintf(str,DLT_USER_BUFFER_LENGTH,"Log file %s cannot be opened!\n",name);
299 dlt_log(LOG_ERR, str);
306 int dlt_init_message_queue(void)
308 pthread_mutex_lock(&mq_mutex);
309 if(dlt_user.dlt_segmented_queue_read_handle >= 0 &&
310 dlt_user.dlt_segmented_queue_write_handle >= 0)
312 // Already intialized
313 pthread_mutex_unlock(&mq_mutex);
317 /* Generate per process name for queue */
318 char queue_name[NAME_MAX];
319 snprintf(queue_name,NAME_MAX, "%s.%d", DLT_MESSAGE_QUEUE_NAME, getpid());
321 /* Maximum queue size is 10, limit to size of pointers */
322 struct mq_attr mqatr;
324 mqatr.mq_maxmsg = 10;
325 mqatr.mq_msgsize = sizeof(s_segmented_data *);
326 mqatr.mq_curmsgs = 0;
329 * Create the message queue. It must be newly created
330 * if old one was left by a crashing process.
332 dlt_user.dlt_segmented_queue_read_handle = mq_open(queue_name, O_CREAT| O_RDONLY | O_EXCL,
333 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, &mqatr);
334 if(dlt_user.dlt_segmented_queue_read_handle < 0)
338 dlt_log(LOG_WARNING, "Old message queue exists, trying to delete.\n");
339 if(mq_unlink(queue_name) < 0)
342 snprintf(str,255,"Could not delete existing message queue!: %s \n",strerror(errno));
343 dlt_log(LOG_CRIT, str);
347 dlt_user.dlt_segmented_queue_read_handle = mq_open(queue_name, O_CREAT| O_RDONLY | O_EXCL,
348 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, &mqatr);
351 if(dlt_user.dlt_segmented_queue_read_handle < 0)
354 snprintf(str,255,"Can't create message queue read handle!: %s \n",strerror(errno));
355 dlt_log(LOG_CRIT, str);
356 pthread_mutex_unlock(&mq_mutex);
361 dlt_user.dlt_segmented_queue_write_handle = mq_open(queue_name, O_WRONLY|O_NONBLOCK);
362 if(dlt_user.dlt_segmented_queue_write_handle < 0)
366 snprintf(str,255,"Can't open message queue write handle!: %s \n",strerror(errno));
367 dlt_log(LOG_CRIT, str);
368 pthread_mutex_unlock(&mq_mutex);
372 pthread_cond_signal(&mq_init_condition);
373 pthread_mutex_unlock(&mq_mutex);
377 int dlt_init_common(void)
379 char *env_local_print;
381 /* Binary semaphore for threads */
382 if (sem_init(&dlt_mutex, 0, 1)==-1)
384 dlt_user_initialised = 0;
388 /* set to unknown state of connected client */
389 dlt_user.log_state = -1;
391 dlt_user.dlt_log_handle=-1;
392 dlt_user.dlt_user_handle=DLT_FD_INIT;
394 dlt_set_id(dlt_user.ecuID,DLT_USER_DEFAULT_ECU_ID);
395 dlt_set_id(dlt_user.appID,"");
397 dlt_user.application_description = 0;
399 /* Verbose mode is enabled by default */
400 dlt_user.verbose_mode = 1;
402 /* Use extended header for non verbose is enabled by default */
403 dlt_user.use_extende_header_for_non_verbose = DLT_USER_USE_EXTENDED_HEADER_FOR_NONVERBOSE;
405 /* WIth session id is enabled by default */
406 dlt_user.with_session_id = DLT_USER_WITH_SESSION_ID;
408 /* With timestamp is enabled by default */
409 dlt_user.with_timestamp= DLT_USER_WITH_TIMESTAMP;
411 /* Local print is disabled by default */
412 dlt_user.enable_local_print = 0;
414 dlt_user.local_print_mode = DLT_PM_UNSET;
416 env_local_print = getenv(DLT_USER_ENV_LOCAL_PRINT_MODE);
419 if (strcmp(env_local_print,"AUTOMATIC")==0)
421 dlt_user.local_print_mode = DLT_PM_AUTOMATIC;
423 else if (strcmp(env_local_print,"FORCE_ON")==0)
425 dlt_user.local_print_mode = DLT_PM_FORCE_ON;
427 else if (strcmp(env_local_print,"FORCE_OFF")==0)
429 dlt_user.local_print_mode = DLT_PM_FORCE_OFF;
433 /* Initialize LogLevel/TraceStatus field */
435 dlt_user.dlt_ll_ts = 0;
436 dlt_user.dlt_ll_ts_max_num_entries = 0;
437 dlt_user.dlt_ll_ts_num_entries = 0;
439 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)
441 dlt_user_initialised = 0;
447 signal(SIGPIPE,SIG_IGN); /* ignore pipe signals */
449 atexit(dlt_user_atexit_handler);
451 #ifdef DLT_TEST_ENABLE
452 dlt_user.corrupt_user_header = 0;
453 dlt_user.corrupt_message_size = 0;
454 dlt_user.corrupt_message_size_size = 0;
460 void dlt_user_atexit_handler(void)
462 if (dlt_user_initialised==0)
464 dlt_log(LOG_WARNING, "dlt_user_atexit_handler dlt_user_initialised==0\n");
470 /* Try to resend potential log messages in the user buffer */
471 int count = dlt_user_atexit_blow_out_user_buffer();
475 snprintf(tmp,256,"Lost log messages in user buffer when exiting: %i\n",count);
476 dlt_log(LOG_ERR, tmp);
479 /* Unregister app (this also unregisters all contexts in daemon) */
480 /* Ignore return value */
481 dlt_unregister_app();
484 /* Ignore return value */
488 int dlt_user_atexit_blow_out_user_buffer(void){
492 uint32_t exitTime = dlt_uptime() + DLT_USER_ATEXIT_RESEND_BUFFER_EXIT_TIMEOUT;
494 while(dlt_uptime() < exitTime ){
496 ret = dlt_user_log_resend_buffer();
503 usleep(DLT_USER_ATEXIT_RESEND_BUFFER_SLEEP);
507 count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
516 char filename[DLT_USER_MAX_FILENAME_LENGTH];
518 if( dlt_user_freeing != 0 )
519 // resources are already being freed. Do nothing and return.
522 // library is freeing its resources. Avoid to allocate it in dlt_init()
523 dlt_user_freeing = 1;
525 if (dlt_user_initialised==0)
527 dlt_user_freeing = 0;
530 dlt_user_initialised = 0;
532 if (dlt_receiverthread_handle)
534 /* Ignore return value */
535 pthread_cancel(dlt_receiverthread_handle);
538 if (dlt_user.dlt_segmented_nwt_handle)
540 pthread_cancel(dlt_user.dlt_segmented_nwt_handle);
543 if (dlt_user.dlt_user_handle!=DLT_FD_INIT)
545 snprintf(filename,DLT_USER_MAX_FILENAME_LENGTH,"%s/dlt%d",DLT_USER_DIR,getpid());
547 close(dlt_user.dlt_user_handle);
548 dlt_user.dlt_user_handle=DLT_FD_INIT;
553 #ifdef DLT_SHM_ENABLE
554 /* free shared memory */
555 dlt_shm_free_client(&dlt_user.dlt_shm);
558 if (dlt_user.dlt_log_handle!=-1)
560 /* close log file/output fifo to daemon */
561 close(dlt_user.dlt_log_handle);
562 dlt_user.dlt_log_handle = -1;
565 /* Ignore return value */
567 dlt_receiver_free(&(dlt_user.receiver));
570 /* Ignore return value */
572 dlt_buffer_free_dynamic(&(dlt_user.startup_buffer));
576 if (dlt_user.dlt_ll_ts)
578 for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
580 if (dlt_user.dlt_ll_ts[i].injection_table!=0)
582 free(dlt_user.dlt_ll_ts[i].injection_table);
583 dlt_user.dlt_ll_ts[i].injection_table = 0;
585 dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
588 free(dlt_user.dlt_ll_ts);
589 dlt_user.dlt_ll_ts = 0;
590 dlt_user.dlt_ll_ts_max_num_entries = 0;
591 dlt_user.dlt_ll_ts_num_entries = 0;
595 char queue_name[NAME_MAX];
596 snprintf(queue_name,NAME_MAX, "%s.%d", DLT_MESSAGE_QUEUE_NAME, getpid());
599 * Ignore errors from these, to not to spam user if dlt_free
600 * is accidentally called multiple times.
602 mq_close(dlt_user.dlt_segmented_queue_write_handle);
603 mq_close(dlt_user.dlt_segmented_queue_read_handle);
604 mq_unlink(queue_name);
606 // allow the user app to do dlt_init() again.
607 // The flag is unset only to keep almost the same behaviour as before, on EntryNav
608 // This should be removed for other projects (see documentation of dlt_free()
609 dlt_user_freeing = 0;
614 int dlt_check_library_version(const char * user_major_version,const char * user_minor_version)
616 return dlt_user_check_library_version(user_major_version, user_minor_version);
619 int dlt_register_app(const char *appid, const char * description)
623 if (dlt_user_initialised==0)
631 if ((appid==0) || (appid[0]=='\0'))
636 /* check if application already registered */
637 /* if yes do not register again */
640 if(appid[0]==dlt_user.appID[0])
645 if(appid[0]==dlt_user.appID[0] &&
646 appid[1]==dlt_user.appID[1])
651 if(appid[0]==dlt_user.appID[0] &&
652 appid[1]==dlt_user.appID[1] &&
653 appid[2]==dlt_user.appID[2])
658 if(appid[0]==dlt_user.appID[0] &&
659 appid[1]==dlt_user.appID[1] &&
660 appid[2]==dlt_user.appID[2] &&
661 appid[3]==dlt_user.appID[3])
667 /* Store locally application id and application description */
668 dlt_set_id(dlt_user.appID, appid);
670 if (dlt_user.application_description!=0)
672 free(dlt_user.application_description);
675 dlt_user.application_description = 0;
679 size_t desc_len = strlen(description);
680 dlt_user.application_description= malloc(desc_len+1);
681 if (dlt_user.application_description){
682 strncpy(dlt_user.application_description, description, desc_len);
683 dlt_user.application_description[desc_len]='\0';
694 ret = dlt_user_log_send_register_application();
698 int dlt_register_context(DltContext *handle, const char *contextid, const char * description)
700 if (dlt_user_initialised==0)
710 if (dlt_user.appID[0]=='\0')
712 dlt_log(LOG_ERR, "no application registered!\n");
718 if ((contextid==0) || (contextid[0]=='\0'))
726 return dlt_register_context_ll_ts(handle, contextid, description, DLT_USER_LOG_LEVEL_NOT_SET, DLT_USER_TRACE_STATUS_NOT_SET);
729 int dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const char * description, int loglevel, int tracestatus)
734 if (dlt_user_initialised==0)
744 if (dlt_user.appID[0]=='\0')
746 dlt_log(LOG_ERR, "no application registered!\n");
754 if ((contextid==0) || (contextid[0]=='\0'))
759 if ((loglevel<DLT_USER_LOG_LEVEL_NOT_SET) || (loglevel>DLT_LOG_VERBOSE) || (loglevel==DLT_LOG_DEFAULT))
764 if ((tracestatus<DLT_USER_TRACE_STATUS_NOT_SET) || (tracestatus>DLT_TRACE_STATUS_ON) || (tracestatus==DLT_TRACE_STATUS_DEFAULT))
769 if (dlt_user_log_init(handle, &log)==-1)
774 /* Reset message counter */
777 /* Store context id in log level/trace status field */
779 /* Check if already registered, else register context */
782 /* Check of double context registration removed */
783 /* Double registration is already checked by daemon */
785 /* Allocate or expand context array */
786 if (dlt_user.dlt_ll_ts == 0)
788 dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*DLT_USER_CONTEXT_ALLOC_SIZE);
789 if (dlt_user.dlt_ll_ts==0)
795 dlt_user.dlt_ll_ts_max_num_entries = DLT_USER_CONTEXT_ALLOC_SIZE;
797 /* Initialize new entries */
798 for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
800 dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
802 /* At startup, logging and tracing is locally enabled */
803 /* the correct log level/status is set after received from daemon */
804 dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL;
805 dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
807 dlt_user.dlt_ll_ts[i].log_level_ptr = 0;
808 dlt_user.dlt_ll_ts[i].trace_status_ptr = 0;
810 dlt_user.dlt_ll_ts[i].context_description = 0;
812 dlt_user.dlt_ll_ts[i].injection_table = 0;
813 dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
818 if ((dlt_user.dlt_ll_ts_num_entries%DLT_USER_CONTEXT_ALLOC_SIZE)==0)
820 /* allocate memory in steps of DLT_USER_CONTEXT_ALLOC_SIZE, e.g. 500 */
821 dlt_ll_ts_type *old_ll_ts;
822 uint32_t old_max_entries;
824 old_ll_ts = dlt_user.dlt_ll_ts;
825 old_max_entries = dlt_user.dlt_ll_ts_max_num_entries;
827 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;
828 dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*
829 dlt_user.dlt_ll_ts_max_num_entries);
830 if (dlt_user.dlt_ll_ts==0)
832 dlt_user.dlt_ll_ts = old_ll_ts;
833 dlt_user.dlt_ll_ts_max_num_entries = old_max_entries;
838 memcpy(dlt_user.dlt_ll_ts,old_ll_ts,sizeof(dlt_ll_ts_type)*dlt_user.dlt_ll_ts_num_entries);
841 /* Initialize new entries */
842 for (i=dlt_user.dlt_ll_ts_num_entries;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
844 dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
846 /* At startup, logging and tracing is locally enabled */
847 /* the correct log level/status is set after received from daemon */
848 dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL;
849 dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
851 dlt_user.dlt_ll_ts[i].log_level_ptr = 0;
852 dlt_user.dlt_ll_ts[i].trace_status_ptr = 0;
854 dlt_user.dlt_ll_ts[i].context_description = 0;
856 dlt_user.dlt_ll_ts[i].injection_table = 0;
857 dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
862 /* Store locally context id and context description */
863 dlt_set_id(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].contextID, contextid);
865 if (dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description!=0)
867 free(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description);
870 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = 0;
874 size_t desc_len = strlen(description);
875 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = malloc(desc_len+1);
876 if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description == 0)
882 strncpy(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description, description, desc_len);
883 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description[desc_len]='\0';
886 if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level_ptr == 0)
888 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level_ptr = malloc(sizeof(int8_t));
889 if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level_ptr == 0)
895 if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status_ptr == 0)
897 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status_ptr = malloc(sizeof(int8_t));
898 if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status_ptr == 0)
905 if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
907 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level = loglevel;
910 if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
912 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status = tracestatus;
915 /* Prepare transfer struct */
916 //dlt_set_id(log->appID, dlt_user.appID);
917 dlt_set_id(handle->contextID, contextid);
918 handle->log_level_pos = dlt_user.dlt_ll_ts_num_entries;
920 handle->log_level_ptr = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level_ptr;
921 handle->trace_status_ptr = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status_ptr;
923 log.context_description = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description;
925 *(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;
926 *(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;
928 if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
930 log.log_level = loglevel;
934 log.log_level = DLT_USER_LOG_LEVEL_NOT_SET;
937 if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
939 log.trace_status = tracestatus;
943 log.trace_status = DLT_USER_TRACE_STATUS_NOT_SET;
946 dlt_user.dlt_ll_ts_num_entries++;
950 return dlt_user_log_send_register_context(&log);
953 int dlt_unregister_app(void)
957 if (dlt_user_initialised==0)
962 /* Inform daemon to unregister application and all of its contexts */
963 ret = dlt_user_log_send_unregister_application();
967 /* Clear and free local stored application information */
968 dlt_set_id(dlt_user.appID, "");
970 if (dlt_user.application_description!=0)
972 free(dlt_user.application_description);
975 dlt_user.application_description = 0;
982 int dlt_unregister_context(DltContext *handle)
987 if (dlt_user_initialised==0)
992 if (dlt_user_log_init(handle, &log) == -1)
999 handle->log_level_ptr = 0;
1000 handle->trace_status_ptr = 0;
1002 if (dlt_user.dlt_ll_ts)
1004 /* Clear and free local stored context information */
1005 dlt_set_id(dlt_user.dlt_ll_ts[handle->log_level_pos].contextID, "");
1007 dlt_user.dlt_ll_ts[handle->log_level_pos].log_level = DLT_USER_INITIAL_LOG_LEVEL;
1008 dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
1010 if (dlt_user.dlt_ll_ts[handle->log_level_pos].context_description!=0)
1012 free(dlt_user.dlt_ll_ts[handle->log_level_pos].context_description);
1015 if (dlt_user.dlt_ll_ts[handle->log_level_pos].log_level_ptr!=0)
1017 free(dlt_user.dlt_ll_ts[handle->log_level_pos].log_level_ptr);
1018 dlt_user.dlt_ll_ts[handle->log_level_pos].log_level_ptr = 0;
1021 if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status_ptr!=0)
1023 free(dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status_ptr);
1024 dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status_ptr = 0;
1027 dlt_user.dlt_ll_ts[handle->log_level_pos].context_description = 0;
1029 if (dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table)
1031 free(dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table);
1032 dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table = 0;
1035 dlt_user.dlt_ll_ts[handle->log_level_pos].nrcallbacks = 0;
1040 /* Inform daemon to unregister context */
1041 ret = dlt_user_log_send_unregister_context(&log);
1046 int dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTraceStatusType tracestatus)
1051 if (dlt_user_initialised==0)
1059 /* Removed because of DltLogLevelType and DltTraceStatusType
1061 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
1066 if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
1071 if (dlt_user.dlt_ll_ts==0)
1079 if (dlt_user.dlt_ll_ts==0)
1085 /* Update local structures */
1086 for (i=0; i<dlt_user.dlt_ll_ts_num_entries;i++)
1088 dlt_user.dlt_ll_ts[i].log_level = loglevel;
1089 dlt_user.dlt_ll_ts[i].trace_status = tracestatus;
1090 if(dlt_user.dlt_ll_ts[i].log_level_ptr)
1091 *(dlt_user.dlt_ll_ts[i].log_level_ptr) = loglevel;
1092 if(dlt_user.dlt_ll_ts[i].trace_status_ptr)
1093 *(dlt_user.dlt_ll_ts[i].trace_status_ptr) = tracestatus;
1098 /* Inform DLT server about update */
1099 ret = dlt_send_app_ll_ts_limit(dlt_user.appID, loglevel, tracestatus);
1104 int dlt_get_log_state()
1106 return dlt_user.log_state;
1109 int dlt_set_log_mode(DltUserLogMode mode)
1111 if (dlt_user_initialised==0)
1119 return dlt_user_log_send_log_mode(mode);
1122 int dlt_forward_msg(void *msgdata,size_t size)
1124 DltUserHeader userheader;
1127 if ((msgdata==0) || (size==0))
1132 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1)
1134 /* Type of internal user message; same value for Trace messages */
1138 if (dlt_user.dlt_is_file)
1141 ret = dlt_user_log_out2(dlt_user.dlt_log_handle, msgdata, size, 0, 0);
1142 return ((ret==DLT_RETURN_OK)?0:-1);
1146 /* Reattach to daemon if neccesary */
1147 dlt_user_log_reattach_to_daemon();
1149 if (dlt_user.overflow_counter)
1151 if (dlt_user_log_send_overflow()==0)
1153 snprintf(str,DLT_USER_BUFFER_LENGTH,"Buffer full! %u messages discarded!\n",dlt_user.overflow_counter);
1154 dlt_log(LOG_ERR, str);
1155 dlt_user.overflow_counter=0; }
1159 ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
1160 &(userheader), sizeof(DltUserHeader),
1161 msgdata, size, 0, 0);
1163 /* store message in ringbuffer, if an error has occured */
1164 if (ret!=DLT_RETURN_OK)
1168 if (dlt_buffer_push3(&(dlt_user.startup_buffer),
1169 (unsigned char *)&(userheader), sizeof(DltUserHeader),
1170 msgdata, size, 0, 0)==-1)
1172 if(dlt_user.overflow_counter==0)
1174 dlt_log(LOG_ERR,"Buffer full! First message discarded!\n");
1176 ret = DLT_RETURN_BUFFER_FULL;
1181 if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
1183 ;//dlt_log(LOG_WARNING, "dlt_forward_msg: Failed to queue resending.\n");
1189 case DLT_RETURN_BUFFER_FULL:
1192 dlt_user.overflow_counter += 1;
1195 case DLT_RETURN_PIPE_FULL:
1197 /* data could not be written */
1200 case DLT_RETURN_PIPE_ERROR:
1202 /* handle not open or pipe error */
1203 close(dlt_user.dlt_log_handle);
1204 dlt_user.dlt_log_handle = -1;
1208 case DLT_RETURN_ERROR:
1210 /* other error condition */
1219 /* This case should not occur */
1228 /* ********************************************************************************************* */
1230 inline int dlt_user_log_write_start(DltContext *handle, DltContextData *log,DltLogLevelType loglevel)
1232 return dlt_user_log_write_start_id(handle,log,loglevel,DLT_USER_DEFAULT_MSGID);
1235 int dlt_user_log_write_start_id(DltContext *handle, DltContextData *log,DltLogLevelType loglevel, uint32_t messageid)
1237 if(dlt_user_initialised==0)
1249 if (dlt_user_log_init(handle, log)==-1)
1254 if (dlt_user.dlt_ll_ts==0)
1259 if (handle->log_level_ptr && (loglevel<=(int)*(handle->log_level_ptr) ) && (loglevel!=0))
1262 log->log_level = loglevel;
1264 /* In non-verbose mode, insert message id */
1265 if (dlt_user.verbose_mode==0)
1267 if ((sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1271 /* Write message id */
1272 memcpy(log->buffer,&(messageid),sizeof(uint32_t));
1273 log->size = sizeof(uint32_t);
1275 /* as the message id is part of each message in non-verbose mode,
1276 it doesn't increment the argument counter in extended header (if used) */
1285 int dlt_user_log_write_finish(DltContextData *log)
1292 return dlt_user_log_send_log(log, DLT_TYPE_LOG) < 0 ? -1 : 0;
1295 int dlt_user_log_write_raw(DltContextData *log,void *data,uint16_t length)
1305 if ((log->size+length+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1310 if (dlt_user.verbose_mode)
1312 if ((log->size+length+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1317 /* Transmit type information */
1318 type_info = DLT_TYPE_INFO_RAWD;
1320 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1321 log->size += sizeof(uint32_t);
1325 /* First transmit length of raw data, then the raw data itself */
1326 arg_size = (uint16_t)length;
1328 memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1329 log->size += sizeof(uint16_t);
1331 memcpy((log->buffer)+log->size,data,arg_size);
1332 log->size += arg_size;
1339 int dlt_user_log_write_float32(DltContextData *log, float32_t data)
1348 if (sizeof(float32_t)!=4)
1353 if ((log->size+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1358 if (dlt_user.verbose_mode)
1360 if ((log->size+sizeof(uint32_t)+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1365 type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_32BIT;
1367 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1368 log->size += sizeof(uint32_t);
1371 memcpy((log->buffer)+log->size,&data, sizeof(float32_t));
1372 log->size += sizeof(float32_t);
1379 int dlt_user_log_write_float64(DltContextData *log, float64_t data)
1388 if (sizeof(float64_t)!=8)
1393 if ((log->size+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1398 if (dlt_user.verbose_mode)
1400 if ((log->size+sizeof(uint32_t)+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1405 type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_64BIT;
1407 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1408 log->size += sizeof(uint32_t);
1411 memcpy((log->buffer)+log->size,&data, sizeof(float64_t));
1412 log->size += sizeof(float64_t);
1419 int dlt_user_log_write_uint( DltContextData *log, unsigned int data)
1426 switch (sizeof(unsigned int))
1430 return dlt_user_log_write_uint8(log, (uint8_t)data);
1435 return dlt_user_log_write_uint16(log, (uint16_t)data);
1440 return dlt_user_log_write_uint32(log, (uint32_t)data);
1445 return dlt_user_log_write_uint64(log, (uint64_t)data);
1458 int dlt_user_log_write_uint8(DltContextData *log, uint8_t data)
1467 if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1472 if (dlt_user.verbose_mode)
1474 if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1479 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_8BIT;
1481 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1482 log->size += sizeof(uint32_t);
1485 memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
1486 log->size += sizeof(uint8_t);
1493 int dlt_user_log_write_uint16(DltContextData *log, uint16_t data)
1502 if ((log->size+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1507 if (dlt_user.verbose_mode)
1509 if ((log->size+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1514 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_16BIT;
1516 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1517 log->size += sizeof(uint32_t);
1520 memcpy((log->buffer)+log->size,&data,sizeof(uint16_t));
1521 log->size += sizeof(uint16_t);
1528 int dlt_user_log_write_uint32(DltContextData *log, uint32_t data)
1537 if ((log->size+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1542 if (dlt_user.verbose_mode)
1544 if ((log->size+sizeof(uint32_t)+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1549 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_32BIT;
1551 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1552 log->size += sizeof(uint32_t);
1555 memcpy((log->buffer)+log->size,&data, sizeof(uint32_t));
1556 log->size += sizeof(uint32_t);
1563 int dlt_user_log_write_uint64(DltContextData *log, uint64_t data)
1572 if ((log->size+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1577 if (dlt_user.verbose_mode)
1579 if ((log->size+sizeof(uint32_t)+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1584 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_64BIT;
1586 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1587 log->size +=sizeof(uint32_t);
1590 memcpy((log->buffer)+log->size,&data,sizeof(uint64_t));
1591 log->size += sizeof(uint64_t);
1598 int dlt_user_log_write_int(DltContextData *log, int data)
1605 switch (sizeof(int))
1609 return dlt_user_log_write_int8(log, (int8_t)data);
1614 return dlt_user_log_write_int16(log, (int16_t)data);
1619 return dlt_user_log_write_int32(log, (int32_t)data);
1624 return dlt_user_log_write_int64(log, (int64_t)data);
1637 int dlt_user_log_write_int8(DltContextData *log, int8_t data)
1646 if ((log->size+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
1651 if (dlt_user.verbose_mode)
1653 if ((log->size+sizeof(uint32_t)+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
1658 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_8BIT;
1660 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1661 log->size += sizeof(uint32_t);
1664 memcpy((log->buffer)+log->size,&data,sizeof(int8_t));
1665 log->size += sizeof(int8_t);
1672 int dlt_user_log_write_int16(DltContextData *log, int16_t data)
1681 if ((log->size+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
1686 if (dlt_user.verbose_mode)
1688 if ((log->size+sizeof(uint32_t)+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
1693 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_16BIT;
1695 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1696 log->size += sizeof(uint32_t);
1699 memcpy((log->buffer)+log->size,&data,sizeof(int16_t));
1700 log->size += sizeof(int16_t);
1707 int dlt_user_log_write_int32(DltContextData *log, int32_t data)
1716 if ((log->size+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
1721 if (dlt_user.verbose_mode)
1723 if ((log->size+sizeof(uint32_t)+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
1728 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_32BIT;
1730 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1731 log->size += sizeof(uint32_t);
1734 memcpy((log->buffer)+log->size,&data, sizeof(int32_t));
1735 log->size += sizeof(int32_t);
1742 int dlt_user_log_write_int64(DltContextData *log, int64_t data)
1751 if ((log->size+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
1756 if (dlt_user.verbose_mode)
1758 if ((log->size+sizeof(uint32_t)+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
1763 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_64BIT;
1765 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1766 log->size += sizeof(uint32_t);
1769 memcpy((log->buffer)+log->size,&data,sizeof(int64_t));
1770 log->size += sizeof(int64_t);
1777 int dlt_user_log_write_bool(DltContextData *log, uint8_t data)
1786 if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1791 if (dlt_user.verbose_mode)
1793 if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1798 type_info = DLT_TYPE_INFO_BOOL;
1800 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1801 log->size += sizeof(uint32_t);
1804 memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
1805 log->size += sizeof(uint8_t);
1812 int dlt_user_log_write_string(DltContextData *log, const char *text)
1817 if ((log==0) || (text==0))
1822 if ((log->size+(strlen(text)+1)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1827 if (dlt_user.verbose_mode)
1829 if ((log->size+(strlen(text)+1)+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1834 type_info = DLT_TYPE_INFO_STRG | DLT_SCOD_ASCII;
1836 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1837 log->size += sizeof(uint32_t);
1840 arg_size = strlen(text) + 1;
1842 memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1843 log->size += sizeof(uint16_t);
1845 memcpy((log->buffer)+log->size,text,arg_size);
1846 log->size += arg_size;
1853 int dlt_user_log_write_utf8_string(DltContextData *log, const char *text)
1858 if ((log==0) || (text==0))
1863 arg_size = strlen(text)+1;
1865 if ((log->size+arg_size+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1870 if (dlt_user.verbose_mode)
1872 if ((log->size+arg_size+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1877 type_info = DLT_TYPE_INFO_STRG | DLT_SCOD_UTF8;
1879 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1880 log->size += sizeof(uint32_t);
1883 arg_size = strlen(text) + 1;
1885 memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1886 log->size += sizeof(uint16_t);
1888 memcpy((log->buffer)+log->size,text,arg_size);
1889 log->size += arg_size;
1896 int dlt_register_injection_callback(DltContext *handle, uint32_t service_id,
1897 int (*dlt_injection_callback)(uint32_t service_id, void *data, uint32_t length))
1903 DltUserInjectionCallback *old;
1910 if (dlt_user_log_init(handle, &log)==-1)
1915 if (service_id<DLT_USER_INJECTION_MIN)
1919 /* This function doesn't make sense storing to local file is choosen;
1920 so terminate this function */
1921 if (dlt_user.dlt_is_file)
1928 if (dlt_user.dlt_ll_ts==0)
1934 /* Insert callback in corresponding table */
1935 i=handle->log_level_pos;
1937 /* Insert each service_id only once */
1938 for (k=0;k<dlt_user.dlt_ll_ts[i].nrcallbacks;k++)
1940 if ((dlt_user.dlt_ll_ts[i].injection_table) &&
1941 (dlt_user.dlt_ll_ts[i].injection_table[k].service_id == service_id))
1954 j=dlt_user.dlt_ll_ts[i].nrcallbacks;
1956 /* Allocate or expand injection table */
1957 if (dlt_user.dlt_ll_ts[i].injection_table == 0)
1959 dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback));
1960 if(dlt_user.dlt_ll_ts[i].injection_table == 0)
1968 old = dlt_user.dlt_ll_ts[i].injection_table;
1969 dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback)*(j+1));
1970 if(dlt_user.dlt_ll_ts[i].injection_table == 0)
1972 dlt_user.dlt_ll_ts[i].injection_table = old;
1976 memcpy(dlt_user.dlt_ll_ts[i].injection_table,old,sizeof(DltUserInjectionCallback)*j);
1980 dlt_user.dlt_ll_ts[i].nrcallbacks++;
1983 /* Store service_id and corresponding function pointer for callback function */
1984 dlt_user.dlt_ll_ts[i].injection_table[j].service_id = service_id;
1985 dlt_user.dlt_ll_ts[i].injection_table[j].injection_callback = dlt_injection_callback;
1998 int total_size, used_size;
1999 dlt_user_check_buffer(&total_size, &used_size);
2001 if((total_size - used_size) < (total_size/2))
2009 * Send the start of a segment chain.
2010 * Returns -1 on failure
2012 int dlt_user_trace_network_segmented_start(uint16_t *id, DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len)
2023 if (dlt_user_log_init(handle, &log)==-1)
2029 if (dlt_user.dlt_ll_ts==0)
2034 if (handle->trace_status_ptr && *(handle->trace_status_ptr)==DLT_TRACE_STATUS_ON)
2038 log.trace_status = nw_trace_type;
2041 gettimeofday(&tv, NULL);
2044 /* Write identifier */
2045 if(dlt_user_log_write_string(&log, "NWST") < 0)
2050 /* Write stream handle */
2051 if(dlt_user_log_write_uint16(&log, *id) < 0)
2057 if(dlt_user_log_write_raw(&log, header, header_len) < 0)
2062 /* Write size of payload */
2063 if(dlt_user_log_write_uint16(&log, payload_len) < 0)
2068 /* Write expected segment count */
2069 uint16_t segment_count = payload_len/DLT_MAX_TRACE_SEGMENT_SIZE+1;
2071 /* If segments align perfectly with segment size, avoid sending empty segment */
2072 if((payload_len % DLT_MAX_TRACE_SEGMENT_SIZE) == 0)
2077 if(dlt_user_log_write_uint16(&log, segment_count) < 0)
2082 /* Write length of one segment */
2083 if(dlt_user_log_write_uint16(&log, DLT_MAX_TRACE_SEGMENT_SIZE) < 0)
2089 return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
2094 int dlt_user_trace_network_segmented_segment(uint16_t id, DltContext *handle, DltNetworkTraceType nw_trace_type, int sequence, uint16_t payload_len, void *payload)
2096 while(check_buffer() < 0)
2098 usleep(1000*50); // Wait 50ms
2099 dlt_user_log_resend_buffer();
2109 if (dlt_user_log_init(handle, &log)==-1)
2114 if (dlt_user.dlt_ll_ts==0)
2119 if (handle->trace_status_ptr && *(handle->trace_status_ptr)==DLT_TRACE_STATUS_ON)
2123 log.trace_status = nw_trace_type;
2126 /* Write identifier */
2127 if(dlt_user_log_write_string(&log, "NWCH") < 0)
2132 /* Write stream handle */
2133 if(dlt_user_log_write_uint16(&log, id) < 0)
2138 /* Write segment sequence number */
2139 if(dlt_user_log_write_uint16(&log, sequence) < 0)
2145 if(dlt_user_log_write_raw(&log, payload, payload_len) < 0)
2151 return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
2154 /* Allow other threads to log between chunks */
2159 int dlt_user_trace_network_segmented_end(uint16_t id, DltContext *handle, DltNetworkTraceType nw_trace_type)
2168 if (dlt_user_log_init(handle, &log)==-1)
2175 if (dlt_user.dlt_ll_ts==0)
2180 if (handle->trace_status_ptr && *(handle->trace_status_ptr)==DLT_TRACE_STATUS_ON)
2184 log.trace_status = nw_trace_type;
2187 /* Write identifier */
2188 if(dlt_user_log_write_string(&log, "NWEN") < 0)
2193 /* Write stream handle */
2194 if(dlt_user_log_write_uint(&log, id) < 0)
2200 return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
2206 void dlt_user_trace_network_segmented_thread(void *unused)
2208 /* Unused on purpose. */
2211 prctl(PR_SET_NAME, "dlt_segmented", 0, 0, 0);
2214 s_segmented_data *data;
2218 // Wait until message queue is initialized
2219 pthread_mutex_lock(&mq_mutex);
2220 if(dlt_user.dlt_segmented_queue_read_handle < 0)
2222 pthread_cond_wait(&mq_init_condition, &mq_mutex);
2224 pthread_mutex_unlock(&mq_mutex);
2226 ssize_t read = mq_receive(dlt_user.dlt_segmented_queue_read_handle, (char *)&data,
2227 sizeof(s_segmented_data * ), NULL);
2229 if(read != sizeof(s_segmented_data *))
2233 snprintf(str,254,"NWTSegmented: Error while reading queue: %s \n",strerror(errno));
2234 dlt_log(LOG_CRIT, str);
2238 /* Indicator just to try to flush the buffer */
2239 if(data->payload_len == DLT_DELAYED_RESEND_INDICATOR_PATTERN)
2241 // Sleep 100ms, to allow other process to read FIFO
2243 if(dlt_user_log_resend_buffer() < 0)
2245 // Requeue if still not empty
2246 if ( dlt_user_queue_resend() < 0 )
2248 //dlt_log(LOG_WARNING, "Failed to queue resending in dlt_user_trace_network_segmented_thread.\n");
2255 dlt_user_trace_network_segmented_thread_segmenter(data);
2257 /* Send the end message */
2258 DltReturnValue err = dlt_user_trace_network_segmented_end(data->id, data->handle, data->nw_trace_type);
2259 if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR)
2261 dlt_log(LOG_ERR,"NWTSegmented: Could not send end segment.\n");
2264 /* Free resources */
2266 free(data->payload);
2271 void dlt_user_trace_network_segmented_thread_segmenter(s_segmented_data *data)
2273 /* Segment the data and send the chunks */
2275 uint16_t offset = 0;
2276 uint16_t sequence = 0;
2280 if(offset + DLT_MAX_TRACE_SEGMENT_SIZE > data->payload_len)
2282 len = data->payload_len - offset;
2286 len = DLT_MAX_TRACE_SEGMENT_SIZE;
2288 /* If payload size aligns perfectly with segment size, avoid sending empty segment */
2294 ptr = data->payload + offset;
2295 DltReturnValue err = dlt_user_trace_network_segmented_segment(data->id, data->handle, data->nw_trace_type, sequence++, len, ptr);
2296 if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR)
2298 dlt_log(LOG_ERR,"NWTSegmented: Could not send segment. Aborting.\n");
2302 }while(ptr < data->payload + data->payload_len);
2306 int dlt_user_trace_network_segmented(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
2308 /* Send as normal trace if possible */
2309 if(header_len+payload_len+sizeof(uint16_t) < DLT_USER_BUF_MAX_SIZE) {
2310 return dlt_user_trace_network(handle, nw_trace_type, header_len, header, payload_len, payload);
2313 /* Allocate Memory */
2314 s_segmented_data *thread_data = malloc(sizeof(s_segmented_data));
2315 if(thread_data == NULL)
2319 thread_data->header = malloc(header_len);
2320 if(thread_data->header == NULL)
2325 thread_data->payload = malloc(payload_len);
2326 if(thread_data->payload == NULL)
2328 free(thread_data->header);
2334 thread_data->handle = handle;
2335 thread_data->nw_trace_type = nw_trace_type;
2336 thread_data->header_len = header_len;
2337 memcpy(thread_data->header, header, header_len);
2338 thread_data->payload_len = payload_len;
2339 memcpy(thread_data->payload, payload, payload_len);
2341 /* Send start message */
2342 DltReturnValue err = dlt_user_trace_network_segmented_start(&(thread_data->id),
2343 thread_data->handle, thread_data->nw_trace_type,
2344 thread_data->header_len, thread_data->header,
2345 thread_data->payload_len);
2346 if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR)
2348 dlt_log(LOG_ERR,"NWTSegmented: Could not send start segment. Aborting.\n");
2349 free(thread_data->header);
2350 free(thread_data->payload);
2355 /* Open queue if it is not open */
2356 if(dlt_init_message_queue() < 0)
2358 dlt_log(LOG_ERR, "NWTSegmented: Could not open queue.\n");
2359 free(thread_data->header);
2360 free(thread_data->payload);
2367 if(mq_send(dlt_user.dlt_segmented_queue_write_handle,
2368 (char *)&thread_data, sizeof(s_segmented_data *), 1) < 0)
2372 dlt_log(LOG_ERR, "NWTSegmented: Queue full. Message discarded.\n");
2374 free(thread_data->header);
2375 free(thread_data->payload);
2378 snprintf(str,255,"NWTSegmented: Could not write into queue: %s \n",strerror(errno));
2379 dlt_log(LOG_CRIT, str);
2383 //thread_data will be freed by the receiver function
2384 //coverity[leaked_storage]
2388 int dlt_user_trace_network(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
2390 return dlt_user_trace_network_truncated(handle, nw_trace_type, header_len, header, payload_len, payload, 1);
2393 int dlt_user_trace_network_truncated(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload, int allow_truncate)
2397 if (dlt_user_initialised==0)
2405 if (dlt_user_log_init(handle, &log)==-1)
2415 /* Commented out because of DltNetworkTraceType:
2417 if ((nw_trace_type<=0) || (nw_trace_type>0x15))
2424 if (dlt_user.dlt_ll_ts==0)
2429 if (handle->trace_status_ptr && *(handle->trace_status_ptr)==DLT_TRACE_STATUS_ON)
2433 log.trace_status = nw_trace_type;
2441 /* If truncation is allowed, check if we must do it */
2442 if(allow_truncate > 0 && (header_len+payload_len+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
2444 /* Identify as truncated */
2445 if(dlt_user_log_write_string(&log, "NWTR") < 0)
2450 /* Write header and its length */
2451 if (dlt_user_log_write_raw(&log, header, header_len) < 0)
2456 /* Write original size of payload */
2457 if(dlt_user_log_write_uint16(&log, payload_len) < 0)
2463 * Calculate maximum avaialble space in sending buffer after headers.
2466 int truncated_payload_len = DLT_USER_BUF_MAX_SIZE -
2467 log.size - sizeof(uint16_t) - sizeof(uint32_t);
2469 /* Write truncated payload */
2470 if (dlt_user_log_write_raw(&log, payload, truncated_payload_len) < 0)
2475 else /* Truncation not allowed or data short enough */
2477 /* Write header and its length */
2478 if (dlt_user_log_write_raw(&log, header, header_len)==-1)
2488 /* Write payload and its length */
2489 if (dlt_user_log_write_raw(&log, payload, payload_len)==-1)
2496 return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
2502 int dlt_log_string(DltContext *handle,DltLogLevelType loglevel, const char *text)
2506 if (dlt_user.verbose_mode==0)
2511 if ((handle==0) || (text==0))
2516 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2518 if (dlt_user_log_write_string(&log,text)==-1)
2522 if (dlt_user_log_write_finish(&log)==-1)
2531 int dlt_log_string_int(DltContext *handle,DltLogLevelType loglevel, const char *text, int data)
2535 if (dlt_user.verbose_mode==0)
2540 if ((handle==0) || (text==0))
2545 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2547 if (dlt_user_log_write_string(&log,text)==-1)
2551 if (dlt_user_log_write_int(&log,data)==-1)
2555 if (dlt_user_log_write_finish(&log)==-1)
2564 int dlt_log_string_uint(DltContext *handle,DltLogLevelType loglevel, const char *text, unsigned int data)
2568 if (dlt_user.verbose_mode==0)
2573 if ((handle==0) || (text==0))
2578 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2580 if (dlt_user_log_write_string(&log,text)==-1)
2584 if (dlt_user_log_write_uint(&log,data)==-1)
2588 if (dlt_user_log_write_finish(&log)==-1)
2597 int dlt_log_int(DltContext *handle,DltLogLevelType loglevel, int data)
2601 if (dlt_user.verbose_mode==0)
2611 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2613 if (dlt_user_log_write_int(&log,data)==-1)
2617 if (dlt_user_log_write_finish(&log)==-1)
2626 int dlt_log_uint(DltContext *handle,DltLogLevelType loglevel, unsigned int data)
2630 if (dlt_user.verbose_mode==0)
2640 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2642 if (dlt_user_log_write_uint(&log,data)==-1)
2646 if (dlt_user_log_write_finish(&log)==-1)
2655 int dlt_log_raw(DltContext *handle,DltLogLevelType loglevel, void *data,uint16_t length)
2659 if (dlt_user.verbose_mode==0)
2669 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2671 if (dlt_user_log_write_raw(&log,data,length)==-1)
2675 if (dlt_user_log_write_finish(&log)==-1)
2684 int dlt_verbose_mode(void)
2686 if (dlt_user_initialised==0)
2694 /* Switch to verbose mode */
2695 dlt_user.verbose_mode = 1;
2700 int dlt_nonverbose_mode(void)
2702 if (dlt_user_initialised==0)
2710 /* Switch to non-verbose mode */
2711 dlt_user.verbose_mode = 0;
2716 int dlt_use_extended_header_for_non_verbose(int8_t use_extende_header_for_non_verbose)
2718 if (dlt_user_initialised==0)
2726 /* Set use_extende_header_for_non_verbose */
2727 dlt_user.use_extende_header_for_non_verbose = use_extende_header_for_non_verbose;
2732 int dlt_with_session_id(int8_t with_session_id)
2734 if (dlt_user_initialised==0)
2742 /* Set use_extende_header_for_non_verbose */
2743 dlt_user.with_session_id = with_session_id;
2748 int dlt_with_timestamp(int8_t with_timestamp)
2750 if (dlt_user_initialised==0)
2758 /* Set with_timestamp */
2759 dlt_user.with_timestamp = with_timestamp;
2764 int dlt_enable_local_print(void)
2766 if (dlt_user_initialised==0)
2774 dlt_user.enable_local_print = 1;
2779 int dlt_disable_local_print(void)
2781 if (dlt_user_initialised==0)
2789 dlt_user.enable_local_print = 0;
2794 void dlt_user_receiverthread_function(__attribute__((unused)) void *ptr)
2797 prctl(PR_SET_NAME, "dlt_receiver", 0, 0, 0);
2801 /* Check for new messages from DLT daemon */
2802 if (dlt_user_log_check_user_message()==-1)
2804 /* Critical error */
2805 dlt_log(LOG_CRIT,"Receiver thread encountered error condition\n");
2808 usleep(DLT_USER_RECEIVE_DELAY); /* delay */
2812 /* Private functions of user library */
2814 int dlt_user_log_init(DltContext *handle, DltContextData *log)
2816 if (dlt_user_initialised==0)
2824 log->handle = handle;
2829 int dlt_user_queue_resend(void)
2831 static unsigned char dlt_user_queue_resend_error_counter = 0;
2833 if(dlt_user.dlt_log_handle < 0)
2835 // Fail silenty. FIFO is not open yet
2839 * Ask segmented thread to try emptying the buffer soon.
2840 * This will be freed in dlt_user_trace_network_segmented_thread
2842 s_segmented_data *resend_data = malloc(sizeof(s_segmented_data));
2844 if (NULL == resend_data)
2849 resend_data->payload_len = DLT_DELAYED_RESEND_INDICATOR_PATTERN;
2853 /* Open queue if it is not open */
2854 if(dlt_init_message_queue() < 0)
2856 if(!dlt_user_queue_resend_error_counter)
2858 // log error only when problem occurred first time
2859 dlt_log(LOG_ERR, "NWTSegmented: Could not open queue.\n");
2861 dlt_user_queue_resend_error_counter = 1;
2866 if(mq_send(dlt_user.dlt_segmented_queue_write_handle, (char *)&resend_data, sizeof(s_segmented_data *), 1) < 0)
2868 if(!dlt_user_queue_resend_error_counter)
2870 // log error only when problem occurred first time
2872 snprintf(str,254,"Could not request resending.: %s \n",strerror(errno));
2873 dlt_log(LOG_CRIT, str);
2875 dlt_user_queue_resend_error_counter = 1;
2880 dlt_user_queue_resend_error_counter = 0;
2882 //thread_data will be freed by the receiver function
2883 //coverity[leaked_storage]
2887 DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype)
2890 DltUserHeader userheader;
2893 DltReturnValue ret = DLT_RETURN_OK;
2897 return DLT_RETURN_ERROR;
2902 return DLT_RETURN_ERROR;
2905 if (dlt_user.appID[0]=='\0')
2907 return DLT_RETURN_ERROR;
2910 if (log->handle->contextID[0]=='\0')
2912 return DLT_RETURN_ERROR;
2915 if ((mtype<DLT_TYPE_LOG) || (mtype>DLT_TYPE_CONTROL))
2917 return DLT_RETURN_ERROR;
2920 /* also for Trace messages */
2921 #ifdef DLT_SHM_ENABLE
2922 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_SHM)==-1)
2924 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1)
2927 return DLT_RETURN_ERROR;
2930 if (dlt_message_init(&msg,0)==-1)
2932 return DLT_RETURN_ERROR;
2935 msg.storageheader = (DltStorageHeader*)msg.headerbuffer;
2937 if (dlt_set_storageheader(msg.storageheader,dlt_user.ecuID)==-1)
2939 return DLT_RETURN_ERROR;
2942 msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader));
2943 msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_PROTOCOL_VERSION1 ;
2945 /* send timestamp */
2946 if(dlt_user.with_timestamp)
2948 msg.standardheader->htyp |= DLT_HTYP_WTMS;
2951 /* send session id */
2952 if(dlt_user.with_session_id)
2954 msg.standardheader->htyp |= DLT_HTYP_WSID;
2955 msg.headerextra.seid = getpid();
2958 if (dlt_user.verbose_mode)
2960 /* In verbose mode, send extended header */
2961 msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
2965 /* In non-verbose, send extended header if desired */
2966 if(dlt_user.use_extende_header_for_non_verbose)
2967 msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
2970 #if (BYTE_ORDER==BIG_ENDIAN)
2971 msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF);
2974 msg.standardheader->mcnt = log->handle->mcnt++;
2976 /* Set header extra parameters */
2977 dlt_set_id(msg.headerextra.ecu,dlt_user.ecuID);
2978 //msg.headerextra.seid = 0;
2979 msg.headerextra.tmsp = dlt_uptime();
2981 if (dlt_message_set_extraparameters(&msg,0)==-1)
2983 return DLT_RETURN_ERROR;
2986 /* Fill out extended header, if extended header should be provided */
2987 if (DLT_IS_HTYP_UEH(msg.standardheader->htyp))
2989 /* with extended header */
2990 msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp) );
2996 msg.extendedheader->msin = (DLT_TYPE_LOG << DLT_MSIN_MSTP_SHIFT) | ((log->log_level << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
2999 case DLT_TYPE_NW_TRACE:
3001 msg.extendedheader->msin = (DLT_TYPE_NW_TRACE << DLT_MSIN_MSTP_SHIFT) | ((log->trace_status << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
3006 /* This case should not occur */
3007 return DLT_RETURN_ERROR;
3012 /* If in verbose mode, set flag in header for verbose mode */
3013 if (dlt_user.verbose_mode)
3015 msg.extendedheader->msin |= DLT_MSIN_VERB;
3018 msg.extendedheader->noar = log->args_num; /* number of arguments */
3019 dlt_set_id(msg.extendedheader->apid,dlt_user.appID); /* application id */
3020 dlt_set_id(msg.extendedheader->ctid,log->handle->contextID); /* context id */
3022 msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
3026 /* without extended header */
3027 msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
3030 len=msg.headersize - sizeof(DltStorageHeader) +log->size;
3033 dlt_log(LOG_CRIT,"Huge message discarded!\n");
3034 return DLT_RETURN_ERROR;
3037 msg.standardheader->len = DLT_HTOBE_16(len);
3039 /* print to std out, if enabled */
3040 if ((dlt_user.local_print_mode != DLT_PM_FORCE_OFF) &&
3041 (dlt_user.local_print_mode != DLT_PM_AUTOMATIC))
3043 if ((dlt_user.enable_local_print) || (dlt_user.local_print_mode == DLT_PM_FORCE_ON))
3045 if (dlt_user_print_msg(&msg, log)==-1)
3047 return DLT_RETURN_ERROR;
3052 if (dlt_user.dlt_is_file)
3055 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, msg.headerbuffer, msg.headersize, log->buffer, log->size);
3060 /* Reattach to daemon if neccesary */
3061 dlt_user_log_reattach_to_daemon();
3063 if (dlt_user.overflow_counter)
3065 if (dlt_user_log_send_overflow()==0)
3067 snprintf(str,DLT_USER_BUFFER_LENGTH,"%u messages discarded!\n",dlt_user.overflow_counter);
3068 dlt_log(LOG_ERR, str);
3069 dlt_user.overflow_counter=0;
3073 /* try to resent old data first */
3074 ret = DLT_RETURN_OK;
3075 if(dlt_user.dlt_log_handle!=-1)
3076 ret = dlt_user_log_resend_buffer();
3077 if(ret==DLT_RETURN_OK)
3079 /* resend ok or nothing to resent */
3080 #ifdef DLT_SHM_ENABLE
3081 if(dlt_user.dlt_log_handle!=-1)
3082 dlt_shm_push(&dlt_user.dlt_shm,msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
3083 log->buffer, log->size,0,0);
3086 ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
3087 &(userheader), sizeof(DltUserHeader),
3092 #ifdef DLT_TEST_ENABLE
3093 if(dlt_user.corrupt_user_header) {
3094 userheader.pattern[0]=0xff;
3095 userheader.pattern[1]=0xff;
3096 userheader.pattern[2]=0xff;
3097 userheader.pattern[3]=0xff;
3099 if(dlt_user.corrupt_message_size) {
3100 msg.standardheader->len = DLT_HTOBE_16(dlt_user.corrupt_message_size_size);
3103 ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
3104 &(userheader), sizeof(DltUserHeader),
3105 msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
3106 log->buffer, log->size);
3110 /* store message in ringbuffer, if an error has occured */
3111 if (ret!=DLT_RETURN_OK)
3115 if (dlt_buffer_push3(&(dlt_user.startup_buffer),
3116 (unsigned char *)&(userheader), sizeof(DltUserHeader),
3117 msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
3118 log->buffer, log->size)==-1)
3120 if(dlt_user.overflow_counter==0)
3123 dlt_log(LOG_ERR,"Buffer full! Messages will be discarded.\n");
3125 ret = DLT_RETURN_BUFFER_FULL;
3130 // Fail silenty if FIFO is not open
3131 if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
3133 ;//dlt_log(LOG_WARNING, "dlt_user_log_send_log: Failed to queue resending.\n");
3139 case DLT_RETURN_BUFFER_FULL:
3142 dlt_user.overflow_counter += 1;
3143 return DLT_RETURN_BUFFER_FULL;
3145 case DLT_RETURN_PIPE_FULL:
3147 /* data could not be written */
3148 return DLT_RETURN_PIPE_FULL;
3150 case DLT_RETURN_PIPE_ERROR:
3152 /* handle not open or pipe error */
3153 close(dlt_user.dlt_log_handle);
3154 dlt_user.dlt_log_handle = -1;
3156 #ifdef DLT_SHM_ENABLE
3157 /* free shared memory */
3158 dlt_shm_free_client(&dlt_user.dlt_shm);
3161 if (dlt_user.local_print_mode == DLT_PM_AUTOMATIC)
3163 dlt_user_print_msg(&msg, log);
3166 return DLT_RETURN_PIPE_ERROR;
3168 case DLT_RETURN_ERROR:
3170 /* other error condition */
3171 return DLT_RETURN_ERROR;
3175 return DLT_RETURN_OK;
3179 /* This case should never occur. */
3180 return DLT_RETURN_ERROR;
3185 return DLT_RETURN_OK;
3188 int dlt_user_log_send_register_application(void)
3190 DltUserHeader userheader;
3191 DltUserControlMsgRegisterApplication usercontext;
3195 if (dlt_user.appID[0]=='\0')
3200 /* set userheader */
3201 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_APPLICATION)==-1)
3206 /* set usercontext */
3207 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
3208 usercontext.pid = getpid();
3210 if (dlt_user.application_description!=0)
3212 usercontext.description_length = strlen(dlt_user.application_description);
3216 usercontext.description_length = 0;
3219 if (dlt_user.dlt_is_file)
3225 ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterApplication),dlt_user.application_description,usercontext.description_length);
3227 /* store message in ringbuffer, if an error has occured */
3228 if (ret!=DLT_RETURN_OK)
3232 if (dlt_buffer_push3(&(dlt_user.startup_buffer),
3233 (unsigned char *)&(userheader), sizeof(DltUserHeader),
3234 (const unsigned char*)&(usercontext), sizeof(DltUserControlMsgRegisterApplication),
3235 (const unsigned char*)dlt_user.application_description, usercontext.description_length)==-1)
3237 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
3244 if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
3246 ;//dlt_log(LOG_WARNING, "dlt_user_log_send_register_application: Failed to queue resending.\n");
3253 int dlt_user_log_send_unregister_application(void)
3255 DltUserHeader userheader;
3256 DltUserControlMsgUnregisterApplication usercontext;
3260 if (dlt_user.appID[0]=='\0')
3265 /* set userheader */
3266 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_APPLICATION)==-1)
3271 /* set usercontext */
3272 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
3273 usercontext.pid = getpid();
3275 if (dlt_user.dlt_is_file)
3281 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterApplication));
3282 return ((ret==DLT_RETURN_OK)?0:-1);
3285 int dlt_user_log_send_register_context(DltContextData *log)
3287 DltUserHeader userheader;
3288 DltUserControlMsgRegisterContext usercontext;
3301 if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0'))
3306 /* set userheader */
3307 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_CONTEXT)==-1)
3312 /* set usercontext */
3313 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
3314 dlt_set_id(usercontext.ctid,log->handle->contextID); /* context id */
3315 usercontext.log_level_pos = log->handle->log_level_pos;
3316 usercontext.pid = getpid();
3318 usercontext.log_level = (int8_t)log->log_level;
3319 usercontext.trace_status = (int8_t)log->trace_status;
3321 if (log->context_description!=0)
3323 usercontext.description_length = strlen(log->context_description);
3327 usercontext.description_length = 0;
3330 if (dlt_user.dlt_is_file)
3336 ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterContext),log->context_description,usercontext.description_length);
3338 /* store message in ringbuffer, if an error has occured */
3339 if (ret!=DLT_RETURN_OK)
3343 if (dlt_buffer_push3(&(dlt_user.startup_buffer),
3344 (unsigned char *)&(userheader), sizeof(DltUserHeader),
3345 (const unsigned char*)&(usercontext), sizeof(DltUserControlMsgRegisterContext),
3346 (const unsigned char*)log->context_description, usercontext.description_length)==-1)
3348 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
3355 if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
3357 ;//dlt_log(LOG_WARNING, "dlt_user_log_send_register_context: Failed to queue resending.\n");
3365 int dlt_user_log_send_unregister_context(DltContextData *log)
3367 DltUserHeader userheader;
3368 DltUserControlMsgUnregisterContext usercontext;
3381 if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0'))
3386 /* set userheader */
3387 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_CONTEXT)==-1)
3392 /* set usercontext */
3393 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
3394 dlt_set_id(usercontext.ctid,log->handle->contextID); /* context id */
3395 usercontext.pid = getpid();
3397 if (dlt_user.dlt_is_file)
3403 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterContext));
3404 return ((ret==DLT_RETURN_OK)?0:-1);
3407 int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus)
3409 DltUserHeader userheader;
3410 DltUserControlMsgAppLogLevelTraceStatus usercontext;
3413 if ((appid==0) || (appid[0]=='\0'))
3418 /* Removed because of DltLogLevelType and DltTraceStatusType
3420 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
3425 if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
3432 /* set userheader */
3433 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_APP_LL_TS)==-1)
3438 /* set usercontext */
3439 dlt_set_id(usercontext.apid,appid); /* application id */
3440 usercontext.log_level = loglevel;
3441 usercontext.trace_status = tracestatus;
3443 if (dlt_user.dlt_is_file)
3449 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgAppLogLevelTraceStatus));
3450 return ((ret==DLT_RETURN_OK)?0:-1);
3453 int dlt_user_log_send_log_mode(DltUserLogMode mode)
3455 DltUserHeader userheader;
3456 DltUserControlMsgLogMode logmode;
3460 /* set userheader */
3461 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_MODE)==-1)
3467 logmode.log_mode = (unsigned char) mode;
3469 if (dlt_user.dlt_is_file)
3475 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(logmode), sizeof(DltUserControlMsgLogMode));
3476 return ((ret==DLT_RETURN_OK)?0:-1);
3479 int dlt_user_print_msg(DltMessage *msg, DltContextData *log)
3481 uint8_t *databuffer_tmp;
3482 int32_t datasize_tmp;
3483 int32_t databuffersize_tmp;
3484 static char text[DLT_USER_TEXT_LENGTH];
3486 if ((msg==0) || (log==0))
3491 /* Save variables before print */
3492 databuffer_tmp = msg->databuffer;
3493 datasize_tmp = msg->datasize;
3494 databuffersize_tmp = msg->databuffersize;
3496 /* Act like a receiver, convert header back to host format */
3497 msg->standardheader->len = DLT_BETOH_16(msg->standardheader->len);
3498 dlt_message_get_extraparameters(msg,0);
3500 msg->databuffer = log->buffer;
3501 msg->datasize = log->size;
3502 msg->databuffersize = log->size;
3504 /* Print message as ASCII */
3505 if (dlt_message_print_ascii(msg,text,DLT_USER_TEXT_LENGTH,0)==-1)
3510 /* Restore variables and set len to BE*/
3511 msg->databuffer = databuffer_tmp;
3512 msg->databuffersize = databuffersize_tmp;
3513 msg->datasize = datasize_tmp;
3515 msg->standardheader->len = DLT_HTOBE_16(msg->standardheader->len);
3520 int dlt_user_log_check_user_message(void)
3527 DltUserHeader *userheader;
3528 DltReceiver *receiver = &(dlt_user.receiver);
3530 DltUserControlMsgLogLevel *usercontextll;
3531 DltUserControlMsgInjection *usercontextinj;
3532 DltUserControlMsgLogState *userlogstate;
3533 unsigned char *userbuffer;
3535 /* For delayed calling of injection callback, to avoid deadlock */
3536 DltUserInjectionCallback delayed_injection_callback;
3537 unsigned char *delayed_inject_buffer = 0;
3538 uint32_t delayed_inject_data_length = 0;
3540 /* Ensure that callback is null before searching for it */
3541 delayed_injection_callback.injection_callback = 0;
3542 delayed_injection_callback.service_id = 0;
3544 if (dlt_user.dlt_user_handle!=DLT_FD_INIT)
3548 if (dlt_receiver_receive_fd(receiver)<=0)
3550 /* No new message available */
3554 /* look through buffer as long as data is in there */
3557 if (receiver->bytesRcvd < (int32_t)sizeof(DltUserHeader))
3562 /* resync if necessary */
3566 userheader = (DltUserHeader*) (receiver->buf+offset);
3568 /* Check for user header pattern */
3569 if (dlt_user_check_userheader(userheader))
3576 while ((int32_t)(sizeof(DltUserHeader)+offset)<=receiver->bytesRcvd);
3578 /* Check for user header pattern */
3579 if (dlt_user_check_userheader(userheader)<0 ||
3580 dlt_user_check_userheader(userheader)==0)
3585 /* Set new start offset */
3588 receiver->buf+=offset;
3589 receiver->bytesRcvd-=offset;
3592 switch (userheader->message)
3594 case DLT_USER_MESSAGE_LOG_LEVEL:
3596 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel)))
3602 usercontextll = (DltUserControlMsgLogLevel*) (receiver->buf+sizeof(DltUserHeader));
3604 /* Update log level and trace status */
3605 if (usercontextll!=0)
3609 if ((usercontextll->log_level_pos >= 0) && (usercontextll->log_level_pos < (int32_t)dlt_user.dlt_ll_ts_num_entries))
3611 // printf("Store ll, ts\n");
3612 if (dlt_user.dlt_ll_ts)
3614 dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level = usercontextll->log_level;
3615 dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status = usercontextll->trace_status;
3616 if(dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level_ptr)
3617 *(dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level_ptr) = usercontextll->log_level;
3618 if(dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status_ptr)
3619 *(dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status_ptr) = usercontextll->trace_status;
3626 /* keep not read data in buffer */
3627 if (dlt_receiver_remove(receiver,sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel))==-1)
3633 case DLT_USER_MESSAGE_INJECTION:
3635 /* At least, user header, user context, and service id and data_length of injected message is available */
3636 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)))
3642 usercontextinj = (DltUserControlMsgInjection*) (receiver->buf+sizeof(DltUserHeader));
3643 userbuffer = (unsigned char*) (receiver->buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection));
3648 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))
3656 if ((usercontextinj->data_length_inject>0) && (dlt_user.dlt_ll_ts))
3658 /* Check if injection callback is registered for this context */
3659 for (i=0; i<dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].nrcallbacks;i++)
3661 if ((dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table) &&
3662 (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].service_id == usercontextinj->service_id))
3664 /* Prepare delayed injection callback call */
3665 if (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback!=0)
3667 delayed_injection_callback.injection_callback = dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback;
3668 delayed_injection_callback.service_id = usercontextinj->service_id;
3669 delayed_inject_data_length = usercontextinj->data_length_inject;
3670 delayed_inject_buffer = malloc(delayed_inject_data_length);
3671 if(delayed_inject_buffer != 0) {
3672 memcpy(delayed_inject_buffer, userbuffer, delayed_inject_data_length);
3683 /* Delayed injection callback call */
3684 if(delayed_inject_buffer != 0 && delayed_injection_callback.injection_callback != 0) {
3685 delayed_injection_callback.injection_callback(delayed_injection_callback.service_id, delayed_inject_buffer, delayed_inject_data_length);
3686 delayed_injection_callback.injection_callback = 0;
3687 free(delayed_inject_buffer);
3688 delayed_inject_buffer = NULL;
3692 /* keep not read data in buffer */
3693 if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))==-1)
3700 case DLT_USER_MESSAGE_LOG_STATE:
3702 /* At least, user header, user context, and service id and data_length of injected message is available */
3703 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))
3709 userlogstate = (DltUserControlMsgLogState*) (receiver->buf+sizeof(DltUserHeader));
3710 dlt_user.log_state = userlogstate->log_state;
3712 /* keep not read data in buffer */
3713 if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))==-1)
3721 dlt_log(LOG_ERR,"Invalid user message type received!\n");
3723 dlt_receiver_remove(receiver,sizeof(DltUserHeader));
3724 /* In next invocation of while loop, a resync will be triggered if additional data was received */
3737 if (dlt_receiver_move_to_begin(receiver)==-1)
3741 } /* while receive */
3744 return DLT_RETURN_OK;
3747 int dlt_user_log_resend_buffer(void)
3753 /* Send content of ringbuffer */
3755 count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
3758 for (num=0;num<count;num++)
3762 size = dlt_buffer_copy(&(dlt_user.startup_buffer),dlt_user.resend_buffer,sizeof(dlt_user.resend_buffer));
3766 #ifdef DLT_SHM_ENABLE
3767 dlt_shm_push(&dlt_user.dlt_shm,dlt_user.resend_buffer+sizeof(DltUserHeader),size-sizeof(DltUserHeader),0,0,0,0);
3770 ret = dlt_user_log_out3(dlt_user.dlt_log_handle, dlt_user.resend_buffer,sizeof(DltUserHeader),0,0,0,0);
3773 ret = dlt_user_log_out3(dlt_user.dlt_log_handle, dlt_user.resend_buffer,size,0,0,0,0);
3776 /* in case of error, keep message in ringbuffer */
3777 if (ret==DLT_RETURN_OK)
3779 dlt_buffer_remove(&(dlt_user.startup_buffer));
3783 /* keep message in ringbuffer */
3794 void dlt_user_log_reattach_to_daemon(void)
3796 uint32_t num,reregistered=0;
3799 DltContextData log_new;
3801 if (dlt_user.dlt_log_handle<0)
3803 dlt_user.dlt_log_handle=-1;
3805 /* try to open pipe to dlt daemon */
3806 dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK);
3807 if (dlt_user.dlt_log_handle > 0)
3809 if (dlt_user_log_init(&handle,&log_new)==-1)
3814 #ifdef DLT_SHM_ENABLE
3815 /* init shared memory */
3816 if (dlt_shm_init_client(&dlt_user.dlt_shm,DLT_SHM_KEY) < 0)
3818 snprintf(str,DLT_USER_BUFFER_LENGTH,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY);
3819 dlt_log(LOG_WARNING, str);
3824 dlt_log(LOG_NOTICE, "Logging re-enabled!\n");
3826 /* Re-register application */
3827 if (dlt_user_log_send_register_application()==-1)
3834 /* Re-register all stored contexts */
3835 for (num=0; num<dlt_user.dlt_ll_ts_num_entries; num++)
3837 /* Re-register stored context */
3838 if ((dlt_user.appID[0]!='\0') && (dlt_user.dlt_ll_ts) && (dlt_user.dlt_ll_ts[num].contextID[0]!='\0'))
3840 //dlt_set_id(log_new.appID, dlt_user.appID);
3841 dlt_set_id(handle.contextID, dlt_user.dlt_ll_ts[num].contextID);
3842 handle.log_level_pos = num;
3843 log_new.context_description = dlt_user.dlt_ll_ts[num].context_description;
3845 // Release the mutex for sending context registration:
3846 // function dlt_user_log_send_register_context() can take the mutex to write to the DLT buffer. => dead lock
3849 log_new.log_level = DLT_USER_LOG_LEVEL_NOT_SET;
3850 log_new.trace_status = DLT_USER_TRACE_STATUS_NOT_SET;
3852 if (dlt_user_log_send_register_context(&log_new)==-1)
3859 // Lock again the mutex
3860 // it is necessary in the for(;;) test, in order to have coherent dlt_user data all over the critical section.
3868 if (reregistered==1)
3870 dlt_user_log_resend_buffer();
3876 int dlt_user_log_send_overflow(void)
3878 DltUserHeader userheader;
3879 DltUserControlMsgBufferOverflow userpayload;
3882 /* set userheader */
3883 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_OVERFLOW)==-1)
3888 if (dlt_user.dlt_is_file)
3893 /* set user message parameters */
3894 userpayload.overflow_counter = dlt_user.overflow_counter;
3895 dlt_set_id(userpayload.apid,dlt_user.appID);
3898 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader),
3899 &(userpayload), sizeof(DltUserControlMsgBufferOverflow));
3900 return ((ret==DLT_RETURN_OK)?0:-1);
3903 int dlt_user_check_buffer(int *total_size, int *used_size)
3905 #ifdef DLT_SHM_ENABLE
3906 *total_size = dlt_shm_get_total_size(&(dlt_user.dlt_shm));
3907 *used_size = dlt_shm_get_used_size(&(dlt_user.dlt_shm));
3909 *total_size = dlt_buffer_get_total_size(&(dlt_user.startup_buffer));
3910 *used_size = dlt_buffer_get_used_size(&(dlt_user.startup_buffer));
3916 #ifdef DLT_TEST_ENABLE
3917 void dlt_user_test_corrupt_user_header(int enable)
3919 dlt_user.corrupt_user_header = enable;
3921 void dlt_user_test_corrupt_message_size(int enable,int16_t size)
3923 dlt_user.corrupt_message_size = enable;
3924 dlt_user.corrupt_message_size_size = size;