3 * Copyright (C) 2012 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/.
16 * \author Alexander Wenzel <alexander.aw.wenzel@bmw.de> BMW 2011-2012
19 * For further information see http://www.genivi.org/.
24 /*******************************************************************************
26 ** SRC-MODULE: dlt_user.c **
32 ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
39 ** PLATFORM DEPENDANT [yes/no]: yes **
41 ** TO BE CHANGED BY USER [yes/no]: no **
43 *******************************************************************************/
45 /*******************************************************************************
47 ********************************************************************************
49 ** Initials Name Company **
50 ** -------- ------------------------- ---------------------------------- **
51 ** aw Alexander Wenzel BMW **
52 ** mk Markus Klein Fraunhofer ESK **
53 *******************************************************************************/
55 /*******************************************************************************
56 ** Revision Control History **
57 *******************************************************************************/
60 * $LastChangedRevision: 1670 $
61 * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $
66 #include <stdlib.h> /* for getenv(), free(), atexit() */
67 #include <string.h> /* for strcmp(), strncmp(), strlen(), memset(), memcpy() */
68 #include <signal.h> /* for signal(), SIGPIPE, SIG_IGN */
70 #if !defined (__WIN32__)
71 #include <syslog.h> /* for LOG_... */
72 #include <semaphore.h>
73 #include <pthread.h> /* POSIX Threads */
83 #include <sys/uio.h> /* writev() */
88 #include "dlt_user_shared.h"
89 #include "dlt_user_shared_cfg.h"
90 #include "dlt_user_cfg.h"
92 static DltUser dlt_user;
93 static int dlt_user_initialised = 0;
95 static char str[DLT_USER_BUFFER_LENGTH];
97 static sem_t dlt_mutex;
98 static pthread_t dlt_receiverthread_handle;
99 static pthread_attr_t dlt_receiverthread_attr;
101 /* Segmented Network Trace */
102 #define DLT_MAX_TRACE_SEGMENT_SIZE 1024
103 #define DLT_MESSAGE_QUEUE_NAME "/dlt_message_queue"
104 #define DLT_DELAYED_RESEND_INDICATOR_PATTERN 0xFFFF
106 /* Mutex to wait on while message queue is not initialized */
107 pthread_mutex_t mq_mutex;
108 pthread_cond_t mq_init_condition;
110 /* Structure to pass data to segmented thread */
114 DltNetworkTraceType nw_trace_type;
117 uint16_t payload_len;
121 /* Function prototypes for internally used functions */
122 static void dlt_user_receiverthread_function(void *ptr);
123 static void dlt_user_atexit_handler(void);
124 static int dlt_user_log_init(DltContext *handle, DltContextData *log);
125 static DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype);
126 static int dlt_user_log_send_register_application(void);
127 static int dlt_user_log_send_unregister_application(void);
128 static int dlt_user_log_send_register_context(DltContextData *log);
129 static int dlt_user_log_send_unregister_context(DltContextData *log);
130 static int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus);
131 static int dlt_user_log_send_log_mode(DltUserLogMode mode);
132 static int dlt_user_print_msg(DltMessage *msg, DltContextData *log);
133 static int dlt_user_log_check_user_message(void);
134 static void dlt_user_log_reattach_to_daemon(void);
135 static int dlt_user_log_send_overflow(void);
136 static void dlt_user_trace_network_segmented_thread(void *unused);
137 static void dlt_user_trace_network_segmented_thread_segmenter(s_segmented_data *data);
138 static int dlt_user_queue_resend(void);
140 int dlt_user_check_library_version(const char *user_major_version,const char *user_minor_version){
143 char lib_major_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
144 char lib_minor_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
146 dlt_get_major_version( lib_major_version);
147 dlt_get_minor_version( lib_minor_version);
149 if( (strcmp(lib_major_version,user_major_version)!=0) || (strcmp(lib_minor_version,user_minor_version)!=0))
151 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);
152 dlt_log(LOG_WARNING, str);
160 char filename[DLT_USER_MAX_FILENAME_LENGTH];
163 dlt_user_initialised = 1;
165 /* Initialize common part of dlt_init()/dlt_init_file() */
166 if (dlt_init_common()==-1)
168 dlt_user_initialised = 0;
172 dlt_user.dlt_is_file = 0;
173 dlt_user.overflow = 0;
174 #ifdef DLT_SHM_ENABLE
175 memset(&(dlt_user.dlt_shm),0,sizeof(DltShm));
178 /* create and open DLT user FIFO */
179 sprintf(filename,"%s/dlt%d",DLT_USER_DIR,getpid());
181 /* Try to delete existing pipe, ignore result of unlink */
184 ret=mkfifo(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
187 sprintf(str,"Loging disabled, FIFO user %s cannot be created!\n",filename);
188 dlt_log(LOG_WARNING, str);
189 /* return 0; */ /* removed to prevent error, when FIFO already exists */
192 dlt_user.dlt_user_handle = open(filename, O_RDWR | O_CLOEXEC);
193 if (dlt_user.dlt_user_handle == DLT_FD_INIT)
195 sprintf(str,"Loging disabled, FIFO user %s cannot be opened!\n",filename);
196 dlt_log(LOG_WARNING, str);
201 /* open DLT output FIFO */
202 dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK | O_CLOEXEC );
203 if (dlt_user.dlt_log_handle==-1)
205 sprintf(str,"Loging disabled, FIFO %s cannot be opened with open()!\n",DLT_USER_FIFO);
206 dlt_log(LOG_WARNING, str);
211 #ifdef DLT_SHM_ENABLE
212 /* init shared memory */
213 if (dlt_shm_init_client(&(dlt_user.dlt_shm),DLT_SHM_KEY) < 0)
215 sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY);
216 dlt_log(LOG_WARNING, str);
223 if (dlt_receiver_init(&(dlt_user.receiver),dlt_user.dlt_user_handle, DLT_USER_RCVBUF_MAX_SIZE)==-1)
225 dlt_user_initialised = 0;
229 /* Start receiver thread */
230 if (pthread_create(&(dlt_receiverthread_handle),
232 (void *) &dlt_user_receiverthread_function,
235 if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0)
237 dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n");
240 dlt_log(LOG_CRIT, "Can't create receiver thread!\n");
241 dlt_user_initialised = 0;
245 if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0)
247 dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n");
250 /* These will be lazy initialized only when needed */
251 dlt_user.dlt_segmented_queue_read_handle = -1;
252 dlt_user.dlt_segmented_queue_write_handle = -1;
254 /* Wait mutext for segmented thread */
255 pthread_mutex_init(&mq_mutex, NULL);
256 pthread_cond_init(&mq_init_condition, NULL);
258 /* Start the segmented thread */
259 if(pthread_create(&(dlt_user.dlt_segmented_nwt_handle), NULL,
260 (void *)dlt_user_trace_network_segmented_thread, NULL))
262 dlt_log(LOG_CRIT, "Can't start segmented thread!\n");
269 int dlt_init_file(const char *name)
271 dlt_user_initialised = 1;
273 /* Initialize common part of dlt_init()/dlt_init_file() */
274 if (dlt_init_common()==-1)
276 dlt_user_initialised = 0;
280 dlt_user.dlt_is_file = 1;
282 /* open DLT output file */
283 dlt_user.dlt_log_handle = open(name,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */
284 if (dlt_user.dlt_log_handle == -1)
286 sprintf(str,"Log file %s cannot be opened!\n",name);
287 dlt_log(LOG_ERR, str);
294 int dlt_init_message_queue(void)
296 pthread_mutex_lock(&mq_mutex);
297 if(dlt_user.dlt_segmented_queue_read_handle >= 0 &&
298 dlt_user.dlt_segmented_queue_write_handle >= 0)
300 // Already intialized
301 pthread_mutex_unlock(&mq_mutex);
305 /* Generate per process name for queue */
306 char queue_name[NAME_MAX];
307 sprintf(queue_name, "%s.%d", DLT_MESSAGE_QUEUE_NAME, getpid());
309 /* Maximum queue size is 10, limit to size of pointers */
310 struct mq_attr mqatr;
312 mqatr.mq_maxmsg = 10;
313 mqatr.mq_msgsize = sizeof(s_segmented_data *);
314 mqatr.mq_curmsgs = 0;
317 * Create the message queue. It must be newly created
318 * if old one was left by a crashing process.
320 dlt_user.dlt_segmented_queue_read_handle = mq_open(queue_name, O_CREAT| O_RDONLY | O_EXCL,
321 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, &mqatr);
322 if(dlt_user.dlt_segmented_queue_read_handle < 0)
326 dlt_log(LOG_WARNING, "Old message queue exists, trying to delete.\n");
327 if(mq_unlink(queue_name) < 0)
330 snprintf(str,255,"Could not delete existing message queue!: %s \n",strerror(errno));
331 dlt_log(LOG_CRIT, str);
335 dlt_user.dlt_segmented_queue_read_handle = mq_open(queue_name, O_CREAT| O_RDONLY | O_EXCL,
336 S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH, &mqatr);
339 if(dlt_user.dlt_segmented_queue_read_handle < 0)
342 snprintf(str,255,"Can't create message queue read handle!: %s \n",strerror(errno));
343 dlt_log(LOG_CRIT, str);
344 pthread_mutex_unlock(&mq_mutex);
349 dlt_user.dlt_segmented_queue_write_handle = mq_open(queue_name, O_WRONLY|O_NONBLOCK);
350 if(dlt_user.dlt_segmented_queue_write_handle < 0)
354 snprintf(str,255,"Can't open message queue write handle!: %s \n",strerror(errno));
355 dlt_log(LOG_CRIT, str);
356 pthread_mutex_unlock(&mq_mutex);
360 pthread_cond_signal(&mq_init_condition);
361 pthread_mutex_unlock(&mq_mutex);
365 int dlt_init_common(void)
367 char *env_local_print;
369 /* Binary semaphore for threads */
370 if (sem_init(&dlt_mutex, 0, 1)==-1)
372 dlt_user_initialised = 0;
376 /* set to unknown state of connected client */
377 dlt_user.log_state = -1;
379 dlt_user.dlt_log_handle=-1;
380 dlt_user.dlt_user_handle=DLT_FD_INIT;
382 dlt_set_id(dlt_user.ecuID,DLT_USER_DEFAULT_ECU_ID);
383 dlt_set_id(dlt_user.appID,"");
385 dlt_user.application_description = 0;
387 /* Verbose mode is enabled by default */
388 dlt_user.verbose_mode = 1;
390 /* Local print is disabled by default */
391 dlt_user.enable_local_print = 0;
393 dlt_user.local_print_mode = DLT_PM_UNSET;
395 env_local_print = getenv(DLT_USER_ENV_LOCAL_PRINT_MODE);
398 if (strcmp(env_local_print,"AUTOMATIC")==0)
400 dlt_user.local_print_mode = DLT_PM_AUTOMATIC;
402 else if (strcmp(env_local_print,"FORCE_ON")==0)
404 dlt_user.local_print_mode = DLT_PM_FORCE_ON;
406 else if (strcmp(env_local_print,"FORCE_OFF")==0)
408 dlt_user.local_print_mode = DLT_PM_FORCE_OFF;
412 /* Initialize LogLevel/TraceStatus field */
414 dlt_user.dlt_ll_ts = 0;
415 dlt_user.dlt_ll_ts_max_num_entries = 0;
416 dlt_user.dlt_ll_ts_num_entries = 0;
418 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)
420 dlt_user_initialised = 0;
426 signal(SIGPIPE,SIG_IGN); /* ignore pipe signals */
428 atexit(dlt_user_atexit_handler);
430 #ifdef DLT_TEST_ENABLE
431 dlt_user.corrupt_user_header = 0;
432 dlt_user.corrupt_message_size = 0;
433 dlt_user.corrupt_message_size_size = 0;
439 void dlt_user_atexit_handler(void)
441 if (dlt_user_initialised==0)
446 /* Try to resend potential log messages in the user buffer */
447 int count = dlt_user_atexit_blow_out_user_buffer();
451 sprintf(tmp,"Lost log messages in user buffer when exiting: %i\n",count);
452 dlt_log(LOG_ERR, tmp);
455 /* Unregister app (this also unregisters all contexts in daemon) */
456 /* Ignore return value */
457 dlt_unregister_app();
460 /* Ignore return value */
464 int dlt_user_atexit_blow_out_user_buffer(void){
468 uint32_t exitTime = dlt_uptime() + DLT_USER_ATEXIT_RESEND_BUFFER_EXIT_TIMEOUT;
470 while(dlt_uptime() < exitTime ){
472 ret = dlt_user_log_resend_buffer();
479 usleep(DLT_USER_ATEXIT_RESEND_BUFFER_SLEEP);
483 count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
492 char filename[DLT_USER_MAX_FILENAME_LENGTH];
494 if (dlt_user_initialised==0)
499 if (dlt_receiverthread_handle)
501 /* Ignore return value */
502 pthread_cancel(dlt_receiverthread_handle);
505 if (dlt_user.dlt_user_handle!=DLT_FD_INIT)
507 sprintf(filename,"%s/dlt%d",DLT_USER_DIR,getpid());
509 close(dlt_user.dlt_user_handle);
510 dlt_user.dlt_user_handle=DLT_FD_INIT;
515 #ifdef DLT_SHM_ENABLE
516 /* free shared memory */
517 dlt_shm_free_client(&dlt_user.dlt_shm);
520 if (dlt_user.dlt_log_handle!=-1)
522 /* close log file/output fifo to daemon */
523 close(dlt_user.dlt_log_handle);
524 dlt_user.dlt_log_handle = -1;
527 /* Ignore return value */
528 dlt_receiver_free(&(dlt_user.receiver));
530 /* Ignore return value */
531 dlt_buffer_free_dynamic(&(dlt_user.startup_buffer));
534 if (dlt_user.dlt_ll_ts)
536 for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
538 if (dlt_user.dlt_ll_ts[i].injection_table!=0)
540 free(dlt_user.dlt_ll_ts[i].injection_table);
541 dlt_user.dlt_ll_ts[i].injection_table = 0;
543 dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
546 free(dlt_user.dlt_ll_ts);
547 dlt_user.dlt_ll_ts = 0;
548 dlt_user.dlt_ll_ts_max_num_entries = 0;
549 dlt_user.dlt_ll_ts_num_entries = 0;
553 if (dlt_user.dlt_segmented_nwt_handle)
555 pthread_cancel(dlt_user.dlt_segmented_nwt_handle);
558 char queue_name[NAME_MAX];
559 sprintf(queue_name, "%s.%d", DLT_MESSAGE_QUEUE_NAME, getpid());
562 * Ignore errors from these, to not to spam user if dlt_free
563 * is accidentally called multiple times.
565 mq_close(dlt_user.dlt_segmented_queue_write_handle);
566 mq_close(dlt_user.dlt_segmented_queue_read_handle);
567 mq_unlink(queue_name);
569 dlt_user_initialised = 0;
574 int dlt_check_library_version(const char * user_major_version,const char * user_minor_version)
576 return dlt_user_check_library_version(user_major_version, user_minor_version);
579 int dlt_register_app(const char *appid, const char * description)
583 if (dlt_user_initialised==0)
591 if ((appid==0) || (appid[0]=='\0'))
596 /* check if application already registered */
597 /* if yes do not register again */
600 if(appid[0]==dlt_user.appID[0])
605 if(appid[0]==dlt_user.appID[0] &&
606 appid[1]==dlt_user.appID[1])
611 if(appid[0]==dlt_user.appID[0] &&
612 appid[1]==dlt_user.appID[1] &&
613 appid[2]==dlt_user.appID[2])
618 if(appid[0]==dlt_user.appID[0] &&
619 appid[1]==dlt_user.appID[1] &&
620 appid[2]==dlt_user.appID[2] &&
621 appid[3]==dlt_user.appID[3])
627 /* Store locally application id and application description */
628 dlt_set_id(dlt_user.appID, appid);
630 if (dlt_user.application_description!=0)
632 free(dlt_user.application_description);
635 dlt_user.application_description = 0;
639 size_t desc_len = strlen(description);
640 dlt_user.application_description= malloc(desc_len+1);
641 if (dlt_user.application_description){
642 strncpy(dlt_user.application_description, description, desc_len);
644 /* Terminate transmitted string with 0 */
645 dlt_user.application_description[desc_len]='\0';
656 ret = dlt_user_log_send_register_application();
660 int dlt_register_context(DltContext *handle, const char *contextid, const char * description)
662 if (dlt_user_initialised==0)
672 if (dlt_user.appID[0]=='\0')
674 dlt_log(LOG_ERR, "no application registered!\n");
680 if ((contextid==0) || (contextid[0]=='\0'))
688 return dlt_register_context_ll_ts(handle, contextid, description, DLT_USER_LOG_LEVEL_NOT_SET, DLT_USER_TRACE_STATUS_NOT_SET);
691 int dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const char * description, int loglevel, int tracestatus)
696 char ctid[DLT_ID_SIZE+1];
698 if (dlt_user_initialised==0)
708 if (dlt_user.appID[0]=='\0')
710 dlt_log(LOG_ERR, "no application registered!\n");
718 if ((contextid==0) || (contextid[0]=='\0'))
723 if ((loglevel<DLT_USER_LOG_LEVEL_NOT_SET) || (loglevel>DLT_LOG_VERBOSE) || (loglevel==DLT_LOG_DEFAULT))
728 if ((tracestatus<DLT_USER_TRACE_STATUS_NOT_SET) || (tracestatus>DLT_TRACE_STATUS_ON) || (tracestatus==DLT_TRACE_STATUS_DEFAULT))
733 if (dlt_user_log_init(handle, &log)==-1)
738 /* Reset message counter */
741 /* Store context id in log level/trace status field */
743 /* Check if already registered, else register context */
747 for (i=0;i<dlt_user.dlt_ll_ts_num_entries;i++)
749 if (dlt_user.dlt_ll_ts)
751 if (memcmp(dlt_user.dlt_ll_ts[i].contextID, contextid,DLT_ID_SIZE)==0)
755 memset(ctid,0,(DLT_ID_SIZE+1));
756 dlt_print_id(ctid, contextid);
758 sprintf(str,"context '%s' already registered!\n",ctid);
759 dlt_log(LOG_WARNING, str);
768 /* Allocate or expand context array */
769 if (dlt_user.dlt_ll_ts == 0)
771 dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*DLT_USER_CONTEXT_ALLOC_SIZE);
772 if (dlt_user.dlt_ll_ts==0)
778 dlt_user.dlt_ll_ts_max_num_entries = DLT_USER_CONTEXT_ALLOC_SIZE;
780 /* Initialize new entries */
781 for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
783 dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
785 /* At startup, logging and tracing is locally enabled */
786 /* the correct log level/status is set after received from daemon */
787 dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL;
788 dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
790 dlt_user.dlt_ll_ts[i].context_description = 0;
792 dlt_user.dlt_ll_ts[i].injection_table = 0;
793 dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
798 if ((dlt_user.dlt_ll_ts_num_entries%DLT_USER_CONTEXT_ALLOC_SIZE)==0)
800 /* allocate memory in steps of DLT_USER_CONTEXT_ALLOC_SIZE, e.g. 500 */
801 dlt_ll_ts_type *old_ll_ts;
802 uint32_t old_max_entries;
804 old_ll_ts = dlt_user.dlt_ll_ts;
805 old_max_entries = dlt_user.dlt_ll_ts_max_num_entries;
807 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;
808 dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*
809 dlt_user.dlt_ll_ts_max_num_entries);
810 if (dlt_user.dlt_ll_ts==0)
812 dlt_user.dlt_ll_ts = old_ll_ts;
813 dlt_user.dlt_ll_ts_max_num_entries = old_max_entries;
818 memcpy(dlt_user.dlt_ll_ts,old_ll_ts,sizeof(dlt_ll_ts_type)*dlt_user.dlt_ll_ts_num_entries);
821 /* Initialize new entries */
822 for (i=dlt_user.dlt_ll_ts_num_entries;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
824 dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
826 /* At startup, logging and tracing is locally enabled */
827 /* the correct log level/status is set after received from daemon */
828 dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL;
829 dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
831 dlt_user.dlt_ll_ts[i].context_description = 0;
833 dlt_user.dlt_ll_ts[i].injection_table = 0;
834 dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
839 /* Store locally context id and context description */
840 dlt_set_id(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].contextID, contextid);
842 if (dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description!=0)
844 free(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description);
847 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = 0;
851 size_t desc_len = strlen(description);
852 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = malloc(desc_len+1);
853 if(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description == 0)
859 strncpy(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description, description, desc_len);
861 /* Terminate transmitted string with 0 */
862 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description[desc_len]='\0';
865 if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
867 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level = loglevel;
870 if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
872 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status = tracestatus;
875 /* Prepare transfer struct */
876 //dlt_set_id(log->appID, dlt_user.appID);
877 dlt_set_id(handle->contextID, contextid);
878 handle->log_level_pos = dlt_user.dlt_ll_ts_num_entries;
880 log.context_description = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description;
882 if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
884 log.log_level = loglevel;
888 log.log_level = DLT_USER_LOG_LEVEL_NOT_SET;
891 if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
893 log.trace_status = tracestatus;
897 log.trace_status = DLT_USER_TRACE_STATUS_NOT_SET;
900 dlt_user.dlt_ll_ts_num_entries++;
904 ret=dlt_user_log_send_register_context(&log);
916 int dlt_unregister_app(void)
920 if (dlt_user_initialised==0)
925 /* Inform daemon to unregister application and all of its contexts */
926 ret = dlt_user_log_send_unregister_application();
930 /* Clear and free local stored application information */
931 dlt_set_id(dlt_user.appID, "");
933 if (dlt_user.application_description!=0)
935 free(dlt_user.application_description);
938 dlt_user.application_description = 0;
945 int dlt_unregister_context(DltContext *handle)
950 if (dlt_user_initialised==0)
955 if (dlt_user_log_init(handle, &log) == -1)
962 if (dlt_user.dlt_ll_ts)
964 /* Clear and free local stored context information */
965 dlt_set_id(dlt_user.dlt_ll_ts[handle->log_level_pos].contextID, "");
967 dlt_user.dlt_ll_ts[handle->log_level_pos].log_level = DLT_USER_INITIAL_LOG_LEVEL;
968 dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
970 if (dlt_user.dlt_ll_ts[handle->log_level_pos].context_description!=0)
972 free(dlt_user.dlt_ll_ts[handle->log_level_pos].context_description);
975 dlt_user.dlt_ll_ts[handle->log_level_pos].context_description = 0;
977 if (dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table)
979 free(dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table);
980 dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table = 0;
983 dlt_user.dlt_ll_ts[handle->log_level_pos].nrcallbacks = 0;
988 /* Inform daemon to unregister context */
989 ret = dlt_user_log_send_unregister_context(&log);
994 int dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTraceStatusType tracestatus)
999 if (dlt_user_initialised==0)
1007 /* Removed because of DltLogLevelType and DltTraceStatusType
1009 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
1014 if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
1019 if (dlt_user.dlt_ll_ts==0)
1028 /* Update local structures */
1029 for (i=0; i<dlt_user.dlt_ll_ts_num_entries;i++)
1031 dlt_user.dlt_ll_ts[i].log_level = loglevel;
1032 dlt_user.dlt_ll_ts[i].trace_status = tracestatus;
1037 /* Inform DLT server about update */
1038 ret = dlt_send_app_ll_ts_limit(dlt_user.appID, loglevel, tracestatus);
1043 int dlt_get_log_state()
1045 return dlt_user.log_state;
1048 int dlt_set_log_mode(DltUserLogMode mode)
1050 if (dlt_user_initialised==0)
1058 return dlt_user_log_send_log_mode(mode);
1061 int dlt_forward_msg(void *msgdata,size_t size)
1063 DltUserHeader userheader;
1066 if ((msgdata==0) || (size==0))
1071 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1)
1073 /* Type of internal user message; same value for Trace messages */
1077 if (dlt_user.dlt_is_file)
1080 ret = dlt_user_log_out2(dlt_user.dlt_log_handle, msgdata, size, 0, 0);
1081 return ((ret==DLT_RETURN_OK)?0:-1);
1085 /* Reattach to daemon if neccesary */
1086 dlt_user_log_reattach_to_daemon();
1088 if (dlt_user.overflow)
1090 if (dlt_user_log_send_overflow()==0)
1092 dlt_user.overflow=0;
1097 ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
1098 &(userheader), sizeof(DltUserHeader),
1099 msgdata, size, 0, 0);
1101 /* store message in ringbuffer, if an error has occured */
1102 if (ret!=DLT_RETURN_OK)
1106 if (dlt_buffer_push3(&(dlt_user.startup_buffer),
1107 (unsigned char *)&(userheader), sizeof(DltUserHeader),
1108 msgdata, size, 0, 0)==-1)
1110 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
1115 if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
1117 dlt_log(LOG_WARNING, "dlt_forward_msg: Failed to queue resending.\n");
1123 case DLT_RETURN_PIPE_FULL:
1125 /* data could not be written */
1126 dlt_user.overflow = 1;
1129 case DLT_RETURN_PIPE_ERROR:
1131 /* handle not open or pipe error */
1132 close(dlt_user.dlt_log_handle);
1133 dlt_user.dlt_log_handle = -1;
1137 case DLT_RETURN_ERROR:
1139 /* other error condition */
1148 /* This case should not occur */
1157 /* ********************************************************************************************* */
1159 inline int dlt_user_log_write_start(DltContext *handle, DltContextData *log,DltLogLevelType loglevel)
1161 return dlt_user_log_write_start_id(handle,log,loglevel,DLT_USER_DEFAULT_MSGID);
1164 int dlt_user_log_write_start_id(DltContext *handle, DltContextData *log,DltLogLevelType loglevel, uint32_t messageid)
1166 if(dlt_user_initialised==0)
1178 if (dlt_user_log_init(handle, log)==-1)
1183 if (dlt_user.dlt_ll_ts==0)
1190 if ((loglevel<=(int)(dlt_user.dlt_ll_ts[handle->log_level_pos].log_level) ) && (loglevel!=0))
1194 log->log_level = loglevel;
1196 /* In non-verbose mode, insert message id */
1197 if (dlt_user.verbose_mode==0)
1199 if ((sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1203 /* Write message id */
1204 memcpy(log->buffer,&(messageid),sizeof(uint32_t));
1205 log->size = sizeof(uint32_t);
1207 /* as the message id is part of each message in non-verbose mode,
1208 it doesn't increment the argument counter in extended header (if used) */
1222 int dlt_user_log_write_finish(DltContextData *log)
1229 return dlt_user_log_send_log(log, DLT_TYPE_LOG) < 0 ? -1 : 0;
1232 int dlt_user_log_write_raw(DltContextData *log,void *data,uint16_t length)
1242 if ((log->size+length+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1247 if (dlt_user.verbose_mode)
1249 if ((log->size+length+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1254 /* Transmit type information */
1255 type_info = DLT_TYPE_INFO_RAWD;
1257 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1258 log->size += sizeof(uint32_t);
1262 /* First transmit length of raw data, then the raw data itself */
1263 arg_size = (uint16_t)length;
1265 memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1266 log->size += sizeof(uint16_t);
1268 memcpy((log->buffer)+log->size,data,arg_size);
1269 log->size += arg_size;
1276 int dlt_user_log_write_float32(DltContextData *log, float32_t data)
1285 if (sizeof(float32_t)!=4)
1290 if ((log->size+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1295 if (dlt_user.verbose_mode)
1297 if ((log->size+sizeof(uint32_t)+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1302 type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_32BIT;
1304 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1305 log->size += sizeof(uint32_t);
1308 memcpy((log->buffer)+log->size,&data, sizeof(float32_t));
1309 log->size += sizeof(float32_t);
1316 int dlt_user_log_write_float64(DltContextData *log, float64_t data)
1325 if (sizeof(float64_t)!=8)
1330 if ((log->size+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1335 if (dlt_user.verbose_mode)
1337 if ((log->size+sizeof(uint32_t)+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1342 type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_64BIT;
1344 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1345 log->size += sizeof(uint32_t);
1348 memcpy((log->buffer)+log->size,&data, sizeof(float64_t));
1349 log->size += sizeof(float64_t);
1356 int dlt_user_log_write_uint( DltContextData *log, unsigned int data)
1363 switch (sizeof(unsigned int))
1367 return dlt_user_log_write_uint8(log, (uint8_t)data);
1372 return dlt_user_log_write_uint16(log, (uint16_t)data);
1377 return dlt_user_log_write_uint32(log, (uint32_t)data);
1382 return dlt_user_log_write_uint64(log, (uint64_t)data);
1395 int dlt_user_log_write_uint8(DltContextData *log, uint8_t data)
1404 if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1409 if (dlt_user.verbose_mode)
1411 if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1416 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_8BIT;
1418 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1419 log->size += sizeof(uint32_t);
1422 memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
1423 log->size += sizeof(uint8_t);
1430 int dlt_user_log_write_uint16(DltContextData *log, uint16_t data)
1439 if ((log->size+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1444 if (dlt_user.verbose_mode)
1446 if ((log->size+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1451 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_16BIT;
1453 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1454 log->size += sizeof(uint32_t);
1457 memcpy((log->buffer)+log->size,&data,sizeof(uint16_t));
1458 log->size += sizeof(uint16_t);
1465 int dlt_user_log_write_uint32(DltContextData *log, uint32_t data)
1474 if ((log->size+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1479 if (dlt_user.verbose_mode)
1481 if ((log->size+sizeof(uint32_t)+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1486 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_32BIT;
1488 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1489 log->size += sizeof(uint32_t);
1492 memcpy((log->buffer)+log->size,&data, sizeof(uint32_t));
1493 log->size += sizeof(uint32_t);
1500 int dlt_user_log_write_uint64(DltContextData *log, uint64_t data)
1509 if ((log->size+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1514 if (dlt_user.verbose_mode)
1516 if ((log->size+sizeof(uint32_t)+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1521 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_64BIT;
1523 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1524 log->size +=sizeof(uint32_t);
1527 memcpy((log->buffer)+log->size,&data,sizeof(uint64_t));
1528 log->size += sizeof(uint64_t);
1535 int dlt_user_log_write_int(DltContextData *log, int data)
1542 switch (sizeof(int))
1546 return dlt_user_log_write_int8(log, (int8_t)data);
1551 return dlt_user_log_write_int16(log, (int16_t)data);
1556 return dlt_user_log_write_int32(log, (int32_t)data);
1561 return dlt_user_log_write_int64(log, (int64_t)data);
1574 int dlt_user_log_write_int8(DltContextData *log, int8_t data)
1583 if ((log->size+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
1588 if (dlt_user.verbose_mode)
1590 if ((log->size+sizeof(uint32_t)+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
1595 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_8BIT;
1597 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1598 log->size += sizeof(uint32_t);
1601 memcpy((log->buffer)+log->size,&data,sizeof(int8_t));
1602 log->size += sizeof(int8_t);
1609 int dlt_user_log_write_int16(DltContextData *log, int16_t data)
1618 if ((log->size+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
1623 if (dlt_user.verbose_mode)
1625 if ((log->size+sizeof(uint32_t)+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
1630 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_16BIT;
1632 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1633 log->size += sizeof(uint32_t);
1636 memcpy((log->buffer)+log->size,&data,sizeof(int16_t));
1637 log->size += sizeof(int16_t);
1644 int dlt_user_log_write_int32(DltContextData *log, int32_t data)
1653 if ((log->size+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
1658 if (dlt_user.verbose_mode)
1660 if ((log->size+sizeof(uint32_t)+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
1665 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_32BIT;
1667 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1668 log->size += sizeof(uint32_t);
1671 memcpy((log->buffer)+log->size,&data, sizeof(int32_t));
1672 log->size += sizeof(int32_t);
1679 int dlt_user_log_write_int64(DltContextData *log, int64_t data)
1688 if ((log->size+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
1693 if (dlt_user.verbose_mode)
1695 if ((log->size+sizeof(uint32_t)+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
1700 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_64BIT;
1702 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1703 log->size += sizeof(uint32_t);
1706 memcpy((log->buffer)+log->size,&data,sizeof(int64_t));
1707 log->size += sizeof(int64_t);
1714 int dlt_user_log_write_bool(DltContextData *log, uint8_t data)
1723 if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1728 if (dlt_user.verbose_mode)
1730 if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1735 type_info = DLT_TYPE_INFO_BOOL;
1737 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1738 log->size += sizeof(uint32_t);
1741 memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
1742 log->size += sizeof(uint8_t);
1749 int dlt_user_log_write_string(DltContextData *log, const char *text)
1754 if ((log==0) || (text==0))
1759 if ((log->size+(strlen(text)+1)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1764 if (dlt_user.verbose_mode)
1766 if ((log->size+(strlen(text)+1)+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1771 type_info = DLT_TYPE_INFO_STRG | DLT_SCOD_ASCII;
1773 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1774 log->size += sizeof(uint32_t);
1777 arg_size = strlen(text) + 1;
1779 memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1780 log->size += sizeof(uint16_t);
1782 memcpy((log->buffer)+log->size,text,arg_size);
1783 log->size += arg_size;
1790 int dlt_user_log_write_utf8_string(DltContextData *log, const char *text)
1795 if ((log==0) || (text==0))
1800 arg_size = strlen(text)+1;
1802 if ((log->size+arg_size+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1807 if (dlt_user.verbose_mode)
1809 if ((log->size+arg_size+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1814 type_info = DLT_TYPE_INFO_STRG | DLT_SCOD_UTF8;
1816 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1817 log->size += sizeof(uint32_t);
1820 arg_size = strlen(text) + 1;
1822 memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1823 log->size += sizeof(uint16_t);
1825 memcpy((log->buffer)+log->size,text,arg_size);
1826 log->size += arg_size;
1833 int dlt_register_injection_callback(DltContext *handle, uint32_t service_id,
1834 int (*dlt_injection_callback)(uint32_t service_id, void *data, uint32_t length))
1840 DltUserInjectionCallback *old;
1847 if (dlt_user_log_init(handle, &log)==-1)
1852 if (service_id<DLT_USER_INJECTION_MIN)
1856 /* This function doesn't make sense storing to local file is choosen;
1857 so terminate this function */
1858 if (dlt_user.dlt_is_file)
1865 if (dlt_user.dlt_ll_ts==0)
1871 /* Insert callback in corresponding table */
1872 i=handle->log_level_pos;
1874 /* Insert each service_id only once */
1875 for (k=0;k<dlt_user.dlt_ll_ts[i].nrcallbacks;k++)
1877 if ((dlt_user.dlt_ll_ts[i].injection_table) &&
1878 (dlt_user.dlt_ll_ts[i].injection_table[k].service_id == service_id))
1891 j=dlt_user.dlt_ll_ts[i].nrcallbacks;
1893 /* Allocate or expand injection table */
1894 if (dlt_user.dlt_ll_ts[i].injection_table == 0)
1896 dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback));
1897 if(dlt_user.dlt_ll_ts[i].injection_table == 0)
1905 old = dlt_user.dlt_ll_ts[i].injection_table;
1906 dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback)*(j+1));
1907 if(dlt_user.dlt_ll_ts[i].injection_table == 0)
1909 dlt_user.dlt_ll_ts[i].injection_table = old;
1913 memcpy(dlt_user.dlt_ll_ts[i].injection_table,old,sizeof(DltUserInjectionCallback)*j);
1917 dlt_user.dlt_ll_ts[i].nrcallbacks++;
1920 /* Store service_id and corresponding function pointer for callback function */
1921 dlt_user.dlt_ll_ts[i].injection_table[j].service_id = service_id;
1922 dlt_user.dlt_ll_ts[i].injection_table[j].injection_callback = dlt_injection_callback;
1935 int total_size, used_size;
1936 dlt_user_check_buffer(&total_size, &used_size);
1938 if((total_size - used_size) < (total_size/2))
1946 * Send the start of a segment chain.
1947 * Returns -1 on failure
1949 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)
1960 if (dlt_user_log_init(handle, &log)==-1)
1967 if (dlt_user.dlt_ll_ts==0)
1973 if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
1978 log.trace_status = nw_trace_type;
1981 gettimeofday(&tv, NULL);
1984 /* Write identifier */
1985 if(dlt_user_log_write_string(&log, "NWST") < 0)
1990 /* Write stream handle */
1991 if(dlt_user_log_write_uint16(&log, *id) < 0)
1997 if(dlt_user_log_write_raw(&log, header, header_len) < 0)
2002 /* Write size of payload */
2003 if(dlt_user_log_write_uint16(&log, payload_len) < 0)
2008 /* Write expected segment count */
2009 uint16_t segment_count = payload_len/DLT_MAX_TRACE_SEGMENT_SIZE+1;
2011 /* If segments align perfectly with segment size, avoid sending empty segment */
2012 if((payload_len % DLT_MAX_TRACE_SEGMENT_SIZE) == 0)
2017 if(dlt_user_log_write_uint16(&log, segment_count) < 0)
2022 /* Write length of one segment */
2023 if(dlt_user_log_write_uint16(&log, DLT_MAX_TRACE_SEGMENT_SIZE) < 0)
2029 return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
2038 int dlt_user_trace_network_segmented_segment(uint16_t id, DltContext *handle, DltNetworkTraceType nw_trace_type, int sequence, uint16_t payload_len, void *payload)
2040 while(check_buffer() < 0)
2042 usleep(1000*50); // Wait 50ms
2043 dlt_user_log_resend_buffer();
2053 if (dlt_user_log_init(handle, &log)==-1)
2060 if (dlt_user.dlt_ll_ts==0)
2066 if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
2071 log.trace_status = nw_trace_type;
2074 /* Write identifier */
2075 if(dlt_user_log_write_string(&log, "NWCH") < 0)
2080 /* Write stream handle */
2081 if(dlt_user_log_write_uint16(&log, id) < 0)
2086 /* Write segment sequence number */
2087 if(dlt_user_log_write_uint16(&log, sequence) < 0)
2093 if(dlt_user_log_write_raw(&log, payload, payload_len) < 0)
2099 return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
2106 /* Allow other threads to log between chunks */
2111 int dlt_user_trace_network_segmented_end(uint16_t id, DltContext *handle, DltNetworkTraceType nw_trace_type)
2120 if (dlt_user_log_init(handle, &log)==-1)
2129 if (dlt_user.dlt_ll_ts==0)
2135 if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
2140 log.trace_status = nw_trace_type;
2143 /* Write identifier */
2144 if(dlt_user_log_write_string(&log, "NWEN") < 0)
2149 /* Write stream handle */
2150 if(dlt_user_log_write_uint(&log, id) < 0)
2156 return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
2166 void dlt_user_trace_network_segmented_thread(void *unused)
2168 /* Unused on purpose. */
2171 s_segmented_data *data;
2175 // Wait until message queue is initialized
2176 pthread_mutex_lock(&mq_mutex);
2177 if(dlt_user.dlt_segmented_queue_read_handle < 0)
2179 pthread_cond_wait(&mq_init_condition, &mq_mutex);
2181 pthread_mutex_unlock(&mq_mutex);
2183 ssize_t read = mq_receive(dlt_user.dlt_segmented_queue_read_handle, (char *)&data,
2184 sizeof(s_segmented_data * ), NULL);
2186 if(read != sizeof(s_segmented_data *))
2190 snprintf(str,254,"NWTSegmented: Error while reading queue: %s \n",strerror(errno));
2191 dlt_log(LOG_CRIT, str);
2195 /* Indicator just to try to flush the buffer */
2196 if(data->payload_len == DLT_DELAYED_RESEND_INDICATOR_PATTERN)
2198 // Sleep 100ms, to allow other process to read FIFO
2200 if(dlt_user_log_resend_buffer() < 0)
2202 // Requeue if still not empty
2203 if ( dlt_user_queue_resend() < 0 )
2204 dlt_log(LOG_WARNING, "Failed to queue resending in dlt_user_trace_network_segmented_thread.\n");
2210 dlt_user_trace_network_segmented_thread_segmenter(data);
2212 /* Send the end message */
2213 DltReturnValue err = dlt_user_trace_network_segmented_end(data->id, data->handle, data->nw_trace_type);
2214 if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR)
2216 dlt_log(LOG_ERR,"NWTSegmented: Could not send end segment.\n");
2219 /* Free resources */
2221 free(data->payload);
2226 void dlt_user_trace_network_segmented_thread_segmenter(s_segmented_data *data)
2228 /* Segment the data and send the chunks */
2230 uint16_t offset = 0;
2231 uint16_t sequence = 0;
2235 if(offset + DLT_MAX_TRACE_SEGMENT_SIZE > data->payload_len)
2237 len = data->payload_len - offset;
2241 len = DLT_MAX_TRACE_SEGMENT_SIZE;
2243 /* If payload size aligns perfectly with segment size, avoid sending empty segment */
2249 ptr = data->payload + offset;
2250 DltReturnValue err = dlt_user_trace_network_segmented_segment(data->id, data->handle, data->nw_trace_type, sequence++, len, ptr);
2251 if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR)
2253 dlt_log(LOG_ERR,"NWTSegmented: Could not send segment. Aborting.\n");
2257 }while(ptr < data->payload + data->payload_len);
2261 int dlt_user_trace_network_segmented(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
2263 /* Send as normal trace if possible */
2264 if(header_len+payload_len+sizeof(uint16_t) < DLT_USER_BUF_MAX_SIZE) {
2265 return dlt_user_trace_network(handle, nw_trace_type, header_len, header, payload_len, payload);
2268 /* Allocate Memory */
2269 s_segmented_data *thread_data = malloc(sizeof(s_segmented_data));
2270 if(thread_data == NULL)
2274 thread_data->header = malloc(header_len);
2275 if(thread_data->header == NULL)
2280 thread_data->payload = malloc(payload_len);
2281 if(thread_data->payload == NULL)
2283 free(thread_data->header);
2289 thread_data->handle = handle;
2290 thread_data->nw_trace_type = nw_trace_type;
2291 thread_data->header_len = header_len;
2292 memcpy(thread_data->header, header, header_len);
2293 thread_data->payload_len = payload_len;
2294 memcpy(thread_data->payload, payload, payload_len);
2296 /* Send start message */
2297 DltReturnValue err = dlt_user_trace_network_segmented_start(&(thread_data->id),
2298 thread_data->handle, thread_data->nw_trace_type,
2299 thread_data->header_len, thread_data->header,
2300 thread_data->payload_len);
2301 if(err == DLT_RETURN_BUFFER_FULL || err == DLT_RETURN_ERROR)
2303 dlt_log(LOG_ERR,"NWTSegmented: Could not send start segment. Aborting.\n");
2304 free(thread_data->header);
2305 free(thread_data->payload);
2310 /* Open queue if it is not open */
2311 if(dlt_init_message_queue() < 0)
2313 dlt_log(LOG_ERR, "NWTSegmented: Could not open queue.\n");
2314 free(thread_data->header);
2315 free(thread_data->payload);
2322 if(mq_send(dlt_user.dlt_segmented_queue_write_handle,
2323 (char *)&thread_data, sizeof(s_segmented_data *), 1) < 0)
2327 dlt_log(LOG_ERR, "NWTSegmented: Queue full. Message discarded.\n");
2329 free(thread_data->header);
2330 free(thread_data->payload);
2333 snprintf(str,255,"NWTSegmented: Could not write into queue: %s \n",strerror(errno));
2334 dlt_log(LOG_CRIT, str);
2338 //thread_data will be freed by the receiver function
2339 //coverity[leaked_storage]
2343 int dlt_user_trace_network(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
2345 return dlt_user_trace_network_truncated(handle, nw_trace_type, header_len, header, payload_len, payload, 1);
2348 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)
2352 if (dlt_user_initialised==0)
2360 if (dlt_user_log_init(handle, &log)==-1)
2370 /* Commented out because of DltNetworkTraceType:
2372 if ((nw_trace_type<=0) || (nw_trace_type>0x15))
2381 if (dlt_user.dlt_ll_ts==0)
2387 if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
2392 log.trace_status = nw_trace_type;
2400 /* If truncation is allowed, check if we must do it */
2401 if(allow_truncate > 0 && (header_len+payload_len+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
2403 /* Identify as truncated */
2404 if(dlt_user_log_write_string(&log, "NWTR") < 0)
2409 /* Write header and its length */
2410 if (dlt_user_log_write_raw(&log, header, header_len) < 0)
2415 /* Write original size of payload */
2416 if(dlt_user_log_write_uint16(&log, payload_len) < 0)
2422 * Calculate maximum avaialble space in sending buffer after headers.
2425 int truncated_payload_len = DLT_USER_BUF_MAX_SIZE -
2426 log.size - sizeof(uint16_t) - sizeof(uint32_t);
2428 /* Write truncated payload */
2429 if (dlt_user_log_write_raw(&log, payload, truncated_payload_len) < 0)
2434 else /* Truncation not allowed or data short enough */
2436 /* Write header and its length */
2437 if (dlt_user_log_write_raw(&log, header, header_len)==-1)
2447 /* Write payload and its length */
2448 if (dlt_user_log_write_raw(&log, payload, payload_len)==-1)
2455 return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
2465 int dlt_log_string(DltContext *handle,DltLogLevelType loglevel, const char *text)
2469 if (dlt_user.verbose_mode==0)
2474 if ((handle==0) || (text==0))
2479 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2481 if (dlt_user_log_write_string(&log,text)==-1)
2485 if (dlt_user_log_write_finish(&log)==-1)
2494 int dlt_log_string_int(DltContext *handle,DltLogLevelType loglevel, const char *text, int data)
2498 if (dlt_user.verbose_mode==0)
2503 if ((handle==0) || (text==0))
2508 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2510 if (dlt_user_log_write_string(&log,text)==-1)
2514 if (dlt_user_log_write_int(&log,data)==-1)
2518 if (dlt_user_log_write_finish(&log)==-1)
2527 int dlt_log_string_uint(DltContext *handle,DltLogLevelType loglevel, const char *text, unsigned int data)
2531 if (dlt_user.verbose_mode==0)
2536 if ((handle==0) || (text==0))
2541 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2543 if (dlt_user_log_write_string(&log,text)==-1)
2547 if (dlt_user_log_write_uint(&log,data)==-1)
2551 if (dlt_user_log_write_finish(&log)==-1)
2560 int dlt_log_int(DltContext *handle,DltLogLevelType loglevel, int data)
2564 if (dlt_user.verbose_mode==0)
2574 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2576 if (dlt_user_log_write_int(&log,data)==-1)
2580 if (dlt_user_log_write_finish(&log)==-1)
2589 int dlt_log_uint(DltContext *handle,DltLogLevelType loglevel, unsigned int data)
2593 if (dlt_user.verbose_mode==0)
2603 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2605 if (dlt_user_log_write_uint(&log,data)==-1)
2609 if (dlt_user_log_write_finish(&log)==-1)
2618 int dlt_log_raw(DltContext *handle,DltLogLevelType loglevel, void *data,uint16_t length)
2622 if (dlt_user.verbose_mode==0)
2632 if (dlt_user_log_write_start(handle,&log,loglevel)>0)
2634 if (dlt_user_log_write_raw(&log,data,length)==-1)
2638 if (dlt_user_log_write_finish(&log)==-1)
2647 int dlt_verbose_mode(void)
2649 if (dlt_user_initialised==0)
2657 /* Switch to verbose mode */
2658 dlt_user.verbose_mode = 1;
2663 int dlt_nonverbose_mode(void)
2665 if (dlt_user_initialised==0)
2673 /* Switch to non-verbose mode */
2674 dlt_user.verbose_mode = 0;
2679 int dlt_enable_local_print(void)
2681 if (dlt_user_initialised==0)
2689 dlt_user.enable_local_print = 1;
2694 int dlt_disable_local_print(void)
2696 if (dlt_user_initialised==0)
2704 dlt_user.enable_local_print = 0;
2709 void dlt_user_receiverthread_function(__attribute__((unused)) void *ptr)
2713 /* Check for new messages from DLT daemon */
2714 if (dlt_user_log_check_user_message()==-1)
2716 /* Critical error */
2717 dlt_log(LOG_CRIT,"Receiver thread encountered error condition\n");
2720 usleep(DLT_USER_RECEIVE_DELAY); /* delay */
2724 /* Private functions of user library */
2726 int dlt_user_log_init(DltContext *handle, DltContextData *log)
2728 if (dlt_user_initialised==0)
2736 log->handle = handle;
2741 int dlt_user_queue_resend(void)
2743 if(dlt_user.dlt_log_handle < 0)
2745 // Fail silenty. FIFO is not open yet
2749 * Ask segmented thread to try emptying the buffer soon.
2750 * This will be freed in dlt_user_trace_network_segmented_thread
2752 s_segmented_data *resend_data = malloc(sizeof(s_segmented_data));
2754 if (NULL == resend_data)
2759 resend_data->payload_len = DLT_DELAYED_RESEND_INDICATOR_PATTERN;
2763 /* Open queue if it is not open */
2764 if(dlt_init_message_queue() < 0)
2766 dlt_log(LOG_ERR, "NWTSegmented: Could not open queue.\n");
2771 if(mq_send(dlt_user.dlt_segmented_queue_write_handle, (char *)&resend_data, sizeof(s_segmented_data *), 1) < 0)
2774 snprintf(str,254,"Could not request resending.: %s \n",strerror(errno));
2775 dlt_log(LOG_CRIT, str);
2779 //thread_data will be freed by the receiver function
2780 //coverity[leaked_storage]
2784 DltReturnValue dlt_user_log_send_log(DltContextData *log, int mtype)
2787 DltUserHeader userheader;
2790 DltReturnValue ret = DLT_RETURN_OK;
2794 return DLT_RETURN_ERROR;
2799 return DLT_RETURN_ERROR;
2802 if (dlt_user.appID[0]=='\0')
2804 return DLT_RETURN_ERROR;
2807 if (log->handle->contextID[0]=='\0')
2809 return DLT_RETURN_ERROR;
2812 if ((mtype<DLT_TYPE_LOG) || (mtype>DLT_TYPE_CONTROL))
2814 return DLT_RETURN_ERROR;
2817 /* also for Trace messages */
2818 #ifdef DLT_SHM_ENABLE
2819 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_SHM)==-1)
2821 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1)
2824 return DLT_RETURN_ERROR;
2827 if (dlt_message_init(&msg,0)==-1)
2829 return DLT_RETURN_ERROR;
2832 msg.storageheader = (DltStorageHeader*)msg.headerbuffer;
2834 if (dlt_set_storageheader(msg.storageheader,dlt_user.ecuID)==-1)
2836 return DLT_RETURN_ERROR;
2839 msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader));
2840 msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_PROTOCOL_VERSION1 ;
2842 if (dlt_user.verbose_mode)
2844 /* In verbose mode, send extended header */
2845 msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
2849 /* In non-verbose, send extended header if desired */
2850 #if (DLT_USER_USE_EXTENDED_HEADER_FOR_NONVERBOSE==1)
2851 msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
2855 #if (BYTE_ORDER==BIG_ENDIAN)
2856 msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF);
2859 msg.standardheader->mcnt = log->handle->mcnt++;
2861 /* Set header extra parameters */
2862 dlt_set_id(msg.headerextra.ecu,dlt_user.ecuID);
2863 //msg.headerextra.seid = 0;
2864 msg.headerextra.tmsp = dlt_uptime();
2866 if (dlt_message_set_extraparameters(&msg,0)==-1)
2868 return DLT_RETURN_ERROR;
2871 /* Fill out extended header, if extended header should be provided */
2872 if (DLT_IS_HTYP_UEH(msg.standardheader->htyp))
2874 /* with extended header */
2875 msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp) );
2881 msg.extendedheader->msin = (DLT_TYPE_LOG << DLT_MSIN_MSTP_SHIFT) | ((log->log_level << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
2884 case DLT_TYPE_NW_TRACE:
2886 msg.extendedheader->msin = (DLT_TYPE_NW_TRACE << DLT_MSIN_MSTP_SHIFT) | ((log->trace_status << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
2891 /* This case should not occur */
2892 return DLT_RETURN_ERROR;
2897 /* If in verbose mode, set flag in header for verbose mode */
2898 if (dlt_user.verbose_mode)
2900 msg.extendedheader->msin |= DLT_MSIN_VERB;
2903 msg.extendedheader->noar = log->args_num; /* number of arguments */
2904 dlt_set_id(msg.extendedheader->apid,dlt_user.appID); /* application id */
2905 dlt_set_id(msg.extendedheader->ctid,log->handle->contextID); /* context id */
2907 msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
2911 /* without extended header */
2912 msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
2915 len=msg.headersize - sizeof(DltStorageHeader) +log->size;
2918 dlt_log(LOG_CRIT,"Huge message discarded!\n");
2919 return DLT_RETURN_ERROR;
2922 msg.standardheader->len = DLT_HTOBE_16(len);
2924 /* print to std out, if enabled */
2925 if ((dlt_user.local_print_mode != DLT_PM_FORCE_OFF) &&
2926 (dlt_user.local_print_mode != DLT_PM_AUTOMATIC))
2928 if ((dlt_user.enable_local_print) || (dlt_user.local_print_mode == DLT_PM_FORCE_ON))
2930 if (dlt_user_print_msg(&msg, log)==-1)
2932 return DLT_RETURN_ERROR;
2937 if (dlt_user.dlt_is_file)
2940 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, msg.headerbuffer, msg.headersize, log->buffer, log->size);
2945 /* Reattach to daemon if neccesary */
2946 dlt_user_log_reattach_to_daemon();
2948 if (dlt_user.overflow)
2950 if (dlt_user_log_send_overflow()==0)
2952 dlt_user.overflow=0;
2956 /* try to resent old data first */
2957 ret = DLT_RETURN_OK;
2958 if(dlt_user.dlt_log_handle!=-1)
2959 ret = dlt_user_log_resend_buffer();
2960 if(ret==DLT_RETURN_OK)
2962 /* resend ok or nothing to resent */
2963 #ifdef DLT_SHM_ENABLE
2964 if(dlt_user.dlt_log_handle!=-1)
2965 dlt_shm_push(&dlt_user.dlt_shm,msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2966 log->buffer, log->size,0,0);
2969 ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
2970 &(userheader), sizeof(DltUserHeader),
2975 #ifdef DLT_TEST_ENABLE
2976 if(dlt_user.corrupt_user_header) {
2977 userheader.pattern[0]=0xff;
2978 userheader.pattern[1]=0xff;
2979 userheader.pattern[2]=0xff;
2980 userheader.pattern[3]=0xff;
2982 if(dlt_user.corrupt_message_size) {
2983 msg.standardheader->len = DLT_HTOBE_16(dlt_user.corrupt_message_size_size);
2986 ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
2987 &(userheader), sizeof(DltUserHeader),
2988 msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2989 log->buffer, log->size);
2993 /* store message in ringbuffer, if an error has occured */
2994 if (ret!=DLT_RETURN_OK)
2998 if (dlt_buffer_push3(&(dlt_user.startup_buffer),
2999 (unsigned char *)&(userheader), sizeof(DltUserHeader),
3000 msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
3001 log->buffer, log->size)==-1)
3003 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
3004 ret = DLT_RETURN_BUFFER_FULL;
3009 // Fail silenty if FIFO is not open
3010 if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
3012 dlt_log(LOG_WARNING, "dlt_user_log_send_log: Failed to queue resending.\n");
3018 case DLT_RETURN_BUFFER_FULL:
3021 return DLT_RETURN_BUFFER_FULL;
3023 case DLT_RETURN_PIPE_FULL:
3025 /* data could not be written */
3026 dlt_user.overflow = 1;
3027 return DLT_RETURN_PIPE_FULL;
3029 case DLT_RETURN_PIPE_ERROR:
3031 /* handle not open or pipe error */
3032 close(dlt_user.dlt_log_handle);
3033 dlt_user.dlt_log_handle = -1;
3035 #ifdef DLT_SHM_ENABLE
3036 /* free shared memory */
3037 dlt_shm_free_client(&dlt_user.dlt_shm);
3040 if (dlt_user.local_print_mode == DLT_PM_AUTOMATIC)
3042 dlt_user_print_msg(&msg, log);
3045 return DLT_RETURN_PIPE_ERROR;
3047 case DLT_RETURN_ERROR:
3049 /* other error condition */
3050 return DLT_RETURN_ERROR;
3054 return DLT_RETURN_OK;
3058 /* This case should never occur. */
3059 return DLT_RETURN_ERROR;
3064 return DLT_RETURN_OK;
3067 int dlt_user_log_send_register_application(void)
3069 DltUserHeader userheader;
3070 DltUserControlMsgRegisterApplication usercontext;
3074 if (dlt_user.appID[0]=='\0')
3079 /* set userheader */
3080 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_APPLICATION)==-1)
3085 /* set usercontext */
3086 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
3087 usercontext.pid = getpid();
3089 if (dlt_user.application_description!=0)
3091 usercontext.description_length = strlen(dlt_user.application_description);
3095 usercontext.description_length = 0;
3098 if (dlt_user.dlt_is_file)
3104 ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterApplication),dlt_user.application_description,usercontext.description_length);
3106 /* store message in ringbuffer, if an error has occured */
3107 if (ret!=DLT_RETURN_OK)
3111 if (dlt_buffer_push3(&(dlt_user.startup_buffer),
3112 (unsigned char *)&(userheader), sizeof(DltUserHeader),
3113 (const unsigned char*)&(usercontext), sizeof(DltUserControlMsgRegisterApplication),
3114 (const unsigned char*)dlt_user.application_description, usercontext.description_length)==-1)
3116 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
3123 if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
3125 dlt_log(LOG_WARNING, "dlt_user_log_send_register_application: Failed to queue resending.\n");
3132 int dlt_user_log_send_unregister_application(void)
3134 DltUserHeader userheader;
3135 DltUserControlMsgUnregisterApplication usercontext;
3139 if (dlt_user.appID[0]=='\0')
3144 /* set userheader */
3145 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_APPLICATION)==-1)
3150 /* set usercontext */
3151 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
3152 usercontext.pid = getpid();
3154 if (dlt_user.dlt_is_file)
3160 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterApplication));
3161 return ((ret==DLT_RETURN_OK)?0:-1);
3164 int dlt_user_log_send_register_context(DltContextData *log)
3166 DltUserHeader userheader;
3167 DltUserControlMsgRegisterContext usercontext;
3180 if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0'))
3185 /* set userheader */
3186 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_CONTEXT)==-1)
3191 /* set usercontext */
3192 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
3193 dlt_set_id(usercontext.ctid,log->handle->contextID); /* context id */
3194 usercontext.log_level_pos = log->handle->log_level_pos;
3195 usercontext.pid = getpid();
3197 usercontext.log_level = (int8_t)log->log_level;
3198 usercontext.trace_status = (int8_t)log->trace_status;
3200 if (log->context_description!=0)
3202 usercontext.description_length = strlen(log->context_description);
3206 usercontext.description_length = 0;
3209 if (dlt_user.dlt_is_file)
3215 ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterContext),log->context_description,usercontext.description_length);
3217 /* store message in ringbuffer, if an error has occured */
3218 if (ret!=DLT_RETURN_OK)
3222 if (dlt_buffer_push3(&(dlt_user.startup_buffer),
3223 (unsigned char *)&(userheader), sizeof(DltUserHeader),
3224 (const unsigned char*)&(usercontext), sizeof(DltUserControlMsgRegisterContext),
3225 (const unsigned char*)log->context_description, usercontext.description_length)==-1)
3227 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
3234 if(dlt_user_queue_resend() < 0 && dlt_user.dlt_log_handle >= 0)
3236 dlt_log(LOG_WARNING, "dlt_user_log_send_register_context: Failed to queue resending.\n");
3244 int dlt_user_log_send_unregister_context(DltContextData *log)
3246 DltUserHeader userheader;
3247 DltUserControlMsgUnregisterContext usercontext;
3260 if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0'))
3265 /* set userheader */
3266 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_CONTEXT)==-1)
3271 /* set usercontext */
3272 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
3273 dlt_set_id(usercontext.ctid,log->handle->contextID); /* context id */
3274 usercontext.pid = getpid();
3276 if (dlt_user.dlt_is_file)
3282 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterContext));
3283 return ((ret==DLT_RETURN_OK)?0:-1);
3286 int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus)
3288 DltUserHeader userheader;
3289 DltUserControlMsgAppLogLevelTraceStatus usercontext;
3292 if ((appid==0) || (appid[0]=='\0'))
3297 /* Removed because of DltLogLevelType and DltTraceStatusType
3299 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
3304 if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
3311 /* set userheader */
3312 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_APP_LL_TS)==-1)
3317 /* set usercontext */
3318 dlt_set_id(usercontext.apid,appid); /* application id */
3319 usercontext.log_level = loglevel;
3320 usercontext.trace_status = tracestatus;
3322 if (dlt_user.dlt_is_file)
3328 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgAppLogLevelTraceStatus));
3329 return ((ret==DLT_RETURN_OK)?0:-1);
3332 int dlt_user_log_send_log_mode(DltUserLogMode mode)
3334 DltUserHeader userheader;
3335 DltUserControlMsgLogMode logmode;
3339 /* set userheader */
3340 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_MODE)==-1)
3346 logmode.log_mode = (unsigned char) mode;
3348 if (dlt_user.dlt_is_file)
3354 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(logmode), sizeof(DltUserControlMsgLogMode));
3355 return ((ret==DLT_RETURN_OK)?0:-1);
3358 int dlt_user_print_msg(DltMessage *msg, DltContextData *log)
3360 uint8_t *databuffer_tmp;
3361 int32_t datasize_tmp;
3362 int32_t databuffersize_tmp;
3363 static char text[DLT_USER_TEXT_LENGTH];
3365 if ((msg==0) || (log==0))
3370 /* Save variables before print */
3371 databuffer_tmp = msg->databuffer;
3372 datasize_tmp = msg->datasize;
3373 databuffersize_tmp = msg->databuffersize;
3375 /* Act like a receiver, convert header back to host format */
3376 msg->standardheader->len = DLT_BETOH_16(msg->standardheader->len);
3377 dlt_message_get_extraparameters(msg,0);
3379 msg->databuffer = log->buffer;
3380 msg->datasize = log->size;
3381 msg->databuffersize = log->size;
3383 /* Print message as ASCII */
3384 if (dlt_message_print_ascii(msg,text,DLT_USER_TEXT_LENGTH,0)==-1)
3389 /* Restore variables and set len to BE*/
3390 msg->databuffer = databuffer_tmp;
3391 msg->databuffersize = databuffersize_tmp;
3392 msg->datasize = datasize_tmp;
3394 msg->standardheader->len = DLT_HTOBE_16(msg->standardheader->len);
3399 int dlt_user_log_check_user_message(void)
3406 DltUserHeader *userheader;
3407 DltReceiver *receiver = &(dlt_user.receiver);
3409 DltUserControlMsgLogLevel *usercontextll;
3410 DltUserControlMsgInjection *usercontextinj;
3411 DltUserControlMsgLogState *userlogstate;
3412 unsigned char *userbuffer;
3414 /* For delayed calling of injection callback, to avoid deadlock */
3415 DltUserInjectionCallback delayed_injection_callback;
3416 unsigned char *delayed_inject_buffer = 0;
3417 uint32_t delayed_inject_data_length = 0;
3419 /* Ensure that callback is null before searching for it */
3420 delayed_injection_callback.injection_callback = 0;
3421 delayed_injection_callback.service_id = 0;
3423 if (dlt_user.dlt_user_handle!=DLT_FD_INIT)
3427 if (dlt_receiver_receive_fd(receiver)<=0)
3429 /* No new message available */
3433 /* look through buffer as long as data is in there */
3436 if (receiver->bytesRcvd < (int32_t)sizeof(DltUserHeader))
3441 /* resync if necessary */
3445 userheader = (DltUserHeader*) (receiver->buf+offset);
3447 /* Check for user header pattern */
3448 if (dlt_user_check_userheader(userheader))
3455 while ((int32_t)(sizeof(DltUserHeader)+offset)<=receiver->bytesRcvd);
3457 /* Check for user header pattern */
3458 if (dlt_user_check_userheader(userheader)<0 ||
3459 dlt_user_check_userheader(userheader)==0)
3464 /* Set new start offset */
3467 receiver->buf+=offset;
3468 receiver->bytesRcvd-=offset;
3471 switch (userheader->message)
3473 case DLT_USER_MESSAGE_LOG_LEVEL:
3475 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel)))
3481 usercontextll = (DltUserControlMsgLogLevel*) (receiver->buf+sizeof(DltUserHeader));
3483 /* Update log level and trace status */
3484 if (usercontextll!=0)
3488 if ((usercontextll->log_level_pos >= 0) && (usercontextll->log_level_pos < (int32_t)dlt_user.dlt_ll_ts_num_entries))
3490 // printf("Store ll, ts\n");
3491 if (dlt_user.dlt_ll_ts)
3493 dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level = usercontextll->log_level;
3494 dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status = usercontextll->trace_status;
3501 /* keep not read data in buffer */
3502 if (dlt_receiver_remove(receiver,sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel))==-1)
3508 case DLT_USER_MESSAGE_INJECTION:
3510 /* At least, user header, user context, and service id and data_length of injected message is available */
3511 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)))
3517 usercontextinj = (DltUserControlMsgInjection*) (receiver->buf+sizeof(DltUserHeader));
3518 userbuffer = (unsigned char*) (receiver->buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection));
3523 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))
3531 if ((usercontextinj->data_length_inject>0) && (dlt_user.dlt_ll_ts))
3533 /* Check if injection callback is registered for this context */
3534 for (i=0; i<dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].nrcallbacks;i++)
3536 if ((dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table) &&
3537 (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].service_id == usercontextinj->service_id))
3539 /* Prepare delayed injection callback call */
3540 if (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback!=0)
3542 delayed_injection_callback.injection_callback = dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback;
3543 delayed_injection_callback.service_id = usercontextinj->service_id;
3544 delayed_inject_data_length = usercontextinj->data_length_inject;
3545 delayed_inject_buffer = malloc(delayed_inject_data_length);
3546 if(delayed_inject_buffer != 0) {
3547 memcpy(delayed_inject_buffer, userbuffer, delayed_inject_data_length);
3558 /* Delayed injection callback call */
3559 if(delayed_inject_buffer != 0 && delayed_injection_callback.injection_callback != 0) {
3560 delayed_injection_callback.injection_callback(delayed_injection_callback.service_id, delayed_inject_buffer, delayed_inject_data_length);
3561 delayed_injection_callback.injection_callback = 0;
3562 free(delayed_inject_buffer);
3563 delayed_inject_buffer = NULL;
3567 /* keep not read data in buffer */
3568 if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))==-1)
3575 case DLT_USER_MESSAGE_LOG_STATE:
3577 /* At least, user header, user context, and service id and data_length of injected message is available */
3578 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))
3584 userlogstate = (DltUserControlMsgLogState*) (receiver->buf+sizeof(DltUserHeader));
3585 dlt_user.log_state = userlogstate->log_state;
3587 /* keep not read data in buffer */
3588 if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))==-1)
3596 dlt_log(LOG_ERR,"Invalid user message type received!\n");
3598 dlt_receiver_remove(receiver,sizeof(DltUserHeader));
3599 /* In next invocation of while loop, a resync will be triggered if additional data was received */
3612 if (dlt_receiver_move_to_begin(receiver)==-1)
3616 } /* while receive */
3619 return DLT_RETURN_OK;
3622 int dlt_user_log_resend_buffer(void)
3628 /* Send content of ringbuffer */
3630 count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
3633 for (num=0;num<count;num++)
3637 size = dlt_buffer_copy(&(dlt_user.startup_buffer),dlt_user.resend_buffer,sizeof(dlt_user.resend_buffer));
3641 #ifdef DLT_SHM_ENABLE
3642 dlt_shm_push(&dlt_user.dlt_shm,dlt_user.resend_buffer+sizeof(DltUserHeader),size-sizeof(DltUserHeader),0,0,0,0);
3645 ret = dlt_user_log_out3(dlt_user.dlt_log_handle, dlt_user.resend_buffer,sizeof(DltUserHeader),0,0,0,0);
3648 ret = dlt_user_log_out3(dlt_user.dlt_log_handle, dlt_user.resend_buffer,size,0,0,0,0);
3651 /* in case of error, keep message in ringbuffer */
3652 if (ret==DLT_RETURN_OK)
3654 dlt_buffer_remove(&(dlt_user.startup_buffer));
3658 /* keep message in ringbuffer */
3669 void dlt_user_log_reattach_to_daemon(void)
3671 uint32_t num,reregistered=0;
3674 DltContextData log_new;
3676 if (dlt_user.dlt_log_handle<0)
3678 dlt_user.dlt_log_handle=-1;
3680 /* try to open pipe to dlt daemon */
3681 dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK);
3682 if (dlt_user.dlt_log_handle > 0)
3684 if (dlt_user_log_init(&handle,&log_new)==-1)
3689 #ifdef DLT_SHM_ENABLE
3690 /* init shared memory */
3691 if (dlt_shm_init_client(&dlt_user.dlt_shm,DLT_SHM_KEY) < 0)
3693 sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY);
3694 dlt_log(LOG_WARNING, str);
3699 dlt_log(LOG_NOTICE, "Logging re-enabled!\n");
3701 /* Re-register application */
3702 if (dlt_user_log_send_register_application()==-1)
3709 /* Re-register all stored contexts */
3710 for (num=0; num<dlt_user.dlt_ll_ts_num_entries; num++)
3712 /* Re-register stored context */
3713 if ((dlt_user.appID[0]!='\0') && (dlt_user.dlt_ll_ts) && (dlt_user.dlt_ll_ts[num].contextID[0]!='\0'))
3715 //dlt_set_id(log_new.appID, dlt_user.appID);
3716 dlt_set_id(handle.contextID, dlt_user.dlt_ll_ts[num].contextID);
3717 handle.log_level_pos = num;
3718 log_new.context_description = dlt_user.dlt_ll_ts[num].context_description;
3720 log_new.log_level = DLT_USER_LOG_LEVEL_NOT_SET;
3721 log_new.trace_status = DLT_USER_TRACE_STATUS_NOT_SET;
3723 if (dlt_user_log_send_register_context(&log_new)==-1)
3735 if (reregistered==1)
3737 dlt_user_log_resend_buffer();
3743 int dlt_user_log_send_overflow(void)
3745 DltUserHeader userheader;
3748 /* set userheader */
3749 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_OVERFLOW)==-1)
3754 if (dlt_user.dlt_is_file)
3760 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), 0, 0);
3761 return ((ret==DLT_RETURN_OK)?0:-1);
3764 int dlt_user_check_buffer(int *total_size, int *used_size)
3766 #ifdef DLT_SHM_ENABLE
3767 *total_size = dlt_shm_get_total_size(&(dlt_user.dlt_shm));
3768 *used_size = dlt_shm_get_used_size(&(dlt_user.dlt_shm));
3770 *total_size = dlt_buffer_get_total_size(&(dlt_user.startup_buffer));
3771 *used_size = dlt_buffer_get_used_size(&(dlt_user.startup_buffer));
3777 #ifdef DLT_TEST_ENABLE
3778 void dlt_user_test_corrupt_user_header(int enable)
3780 dlt_user.corrupt_user_header = enable;
3782 void dlt_user_test_corrupt_message_size(int enable,int16_t size)
3784 dlt_user.corrupt_message_size = enable;
3785 dlt_user.corrupt_message_size_size = size;