2 * Dlt- Diagnostic Log and Trace user library
5 * Copyright (C) 2011, BMW AG - Alexander Wenzel <alexander.wenzel@bmw.de>
7 * This program is free software; you can redistribute it and/or modify it under the terms of the
8 * GNU Lesser General Public License, version 2.1, as published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
10 * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General
11 * Public License, version 2.1, for more details.
13 * You should have received a copy of the GNU Lesser General Public License, version 2.1, along
14 * with this program; if not, see <http://www.gnu.org/licenses/lgpl-2.1.html>.
16 * Note that the copyright holders assume that the GNU Lesser General Public License, version 2.1, may
17 * also be applicable to programs even in cases in which the program is not a library in the technical sense.
19 * Linking DLT statically or dynamically with other modules is making a combined work based on DLT. You may
20 * license such other modules under the GNU Lesser General Public License, version 2.1. If you do not want to
21 * license your linked modules under the GNU Lesser General Public License, version 2.1, you
22 * may use the program under the following exception.
24 * As a special exception, the copyright holders of DLT give you permission to combine DLT
25 * with software programs or libraries that are released under any license unless such a combination is not
26 * permitted by the license of such a software program or library. You may copy and distribute such a
27 * system following the terms of the GNU Lesser General Public License, version 2.1, including this
28 * special exception, for DLT and the licenses of the other code concerned.
30 * Note that people who make modified versions of DLT are not obligated to grant this special exception
31 * for their modified versions; it is their choice whether to do so. The GNU Lesser General Public License,
32 * version 2.1, gives permission to release a modified version without this exception; this exception
33 * also makes it possible to release a modified version which carries forward this exception.
39 /*******************************************************************************
41 ** SRC-MODULE: dlt_user.c **
47 ** AUTHOR : Alexander Wenzel Alexander.AW.Wenzel@bmw.de **
54 ** PLATFORM DEPENDANT [yes/no]: yes **
56 ** TO BE CHANGED BY USER [yes/no]: no **
58 *******************************************************************************/
60 /*******************************************************************************
62 ********************************************************************************
64 ** Initials Name Company **
65 ** -------- ------------------------- ---------------------------------- **
66 ** aw Alexander Wenzel BMW **
67 ** mk Markus Klein Fraunhofer ESK **
68 *******************************************************************************/
70 /*******************************************************************************
71 ** Revision Control History **
72 *******************************************************************************/
75 * $LastChangedRevision: 1670 $
76 * $LastChangedDate: 2011-04-08 15:12:06 +0200 (Fr, 08. Apr 2011) $
82 #include <stdlib.h> /* for getenv(), free(), atexit() */
83 #include <string.h> /* for strcmp(), strncmp(), strlen(), memset(), memcpy() */
84 #include <signal.h> /* for signal(), SIGPIPE, SIG_IGN */
86 #if !defined (__WIN32__)
87 #include <syslog.h> /* for LOG_... */
88 #include <semaphore.h>
89 #include <pthread.h> /* POSIX Threads */
96 #include <sys/uio.h> /* writev() */
99 #include "dlt_user_shared.h"
100 #include "dlt_user_shared_cfg.h"
101 #include "dlt_user_cfg.h"
103 static DltUser dlt_user;
104 static int dlt_user_initialised = 0;
106 static char str[DLT_USER_BUFFER_LENGTH];
108 static sem_t dlt_mutex;
109 static pthread_t dlt_receiverthread_handle;
110 static pthread_attr_t dlt_receiverthread_attr;
112 /* Function prototypes for internally used functions */
113 static void dlt_user_receiverthread_function(void *ptr);
114 static void dlt_user_atexit_handler(void);
115 static int dlt_user_log_init(DltContext *handle, DltContextData *log);
116 static int dlt_user_log_send_log(DltContextData *log, int mtype);
117 static int dlt_user_log_send_register_application(void);
118 static int dlt_user_log_send_unregister_application(void);
119 static int dlt_user_log_send_register_context(DltContextData *log);
120 static int dlt_user_log_send_unregister_context(DltContextData *log);
121 static int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus);
122 static int dlt_user_log_send_log_mode(DltUserLogMode mode);
123 static int dlt_user_print_msg(DltMessage *msg, DltContextData *log);
124 static int dlt_user_log_check_user_message(void);
125 static int dlt_user_log_resend_buffer(void);
126 static void dlt_user_log_reattach_to_daemon(void);
127 static int dlt_user_log_send_overflow(void);
129 int dlt_user_check_library_version(const char *user_major_version,const char *user_minor_version){
132 char lib_major_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
133 char lib_minor_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
135 dlt_get_major_version( lib_major_version);
136 dlt_get_minor_version( lib_minor_version);
138 if( (strcmp(lib_major_version,user_major_version)!=0) || (strcmp(lib_minor_version,user_minor_version)!=0))
140 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);
141 dlt_log(LOG_WARNING, str);
149 char filename[DLT_USER_MAX_FILENAME_LENGTH];
152 dlt_user_initialised = 1;
154 /* Initialize common part of dlt_init()/dlt_init_file() */
155 if (dlt_init_common()==-1)
157 dlt_user_initialised = 0;
161 dlt_user.dlt_is_file = 0;
162 dlt_user.overflow = 0;
163 #ifdef DLT_SHM_ENABLE
164 memset(&(dlt_user.dlt_shm),0,sizeof(DltShm));
167 /* create and open DLT user FIFO */
168 sprintf(filename,"%s/dlt%d",DLT_USER_DIR,getpid());
170 /* Try to delete existing pipe, ignore result of unlink */
173 ret=mkfifo(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
176 sprintf(str,"Loging disabled, FIFO user %s cannot be created!\n",filename);
177 dlt_log(LOG_WARNING, str);
178 /* return 0; */ /* removed to prevent error, when FIFO already exists */
181 dlt_user.dlt_user_handle = open(filename, O_RDWR);
182 if (dlt_user.dlt_user_handle == -1)
184 sprintf(str,"Loging disabled, FIFO user %s cannot be opened!\n",filename);
185 dlt_log(LOG_WARNING, str);
190 /* open DLT output FIFO */
191 dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK);
192 if (dlt_user.dlt_log_handle==-1)
194 sprintf(str,"Loging disabled, FIFO %s cannot be opened with open()!\n",DLT_USER_FIFO);
195 dlt_log(LOG_WARNING, str);
200 #ifdef DLT_SHM_ENABLE
201 /* init shared memory */
202 if (dlt_shm_init_client(&(dlt_user.dlt_shm),DLT_SHM_KEY) < 0)
204 sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY);
205 dlt_log(LOG_WARNING, str);
212 if (dlt_receiver_init(&(dlt_user.receiver),dlt_user.dlt_user_handle, DLT_USER_RCVBUF_MAX_SIZE)==-1)
214 dlt_user_initialised = 0;
218 /* Start receiver thread */
219 if (pthread_create(&(dlt_receiverthread_handle),
221 (void *) &dlt_user_receiverthread_function,
224 if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0)
226 dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n");
229 dlt_log(LOG_CRIT, "Can't create receiver thread!\n");
230 dlt_user_initialised = 0;
234 if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0)
236 dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n");
242 int dlt_init_file(const char *name)
244 dlt_user_initialised = 1;
246 /* Initialize common part of dlt_init()/dlt_init_file() */
247 if (dlt_init_common()==-1)
249 dlt_user_initialised = 0;
253 dlt_user.dlt_is_file = 1;
255 /* open DLT output file */
256 dlt_user.dlt_log_handle = open(name,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */
257 if (dlt_user.dlt_log_handle == -1)
259 sprintf(str,"Log file %s cannot be opened!\n",name);
260 dlt_log(LOG_ERR, str);
267 int dlt_init_common(void)
269 char *env_local_print;
271 /* Binary semaphore for threads */
272 if (sem_init(&dlt_mutex, 0, 1)==-1)
274 dlt_user_initialised = 0;
278 /* set to unknown state of connected client */
279 dlt_user.log_state = -1;
281 dlt_user.dlt_log_handle=-1;
282 dlt_user.dlt_user_handle=-1;
284 dlt_set_id(dlt_user.ecuID,DLT_USER_DEFAULT_ECU_ID);
285 dlt_set_id(dlt_user.appID,"");
287 dlt_user.application_description = 0;
289 /* Verbose mode is enabled by default */
290 dlt_user.verbose_mode = 1;
292 /* Local print is disabled by default */
293 dlt_user.enable_local_print = 0;
295 dlt_user.local_print_mode = DLT_PM_UNSET;
297 env_local_print = getenv(DLT_USER_ENV_LOCAL_PRINT_MODE);
300 if (strcmp(env_local_print,"AUTOMATIC")==0)
302 dlt_user.local_print_mode = DLT_PM_AUTOMATIC;
304 else if (strcmp(env_local_print,"FORCE_ON")==0)
306 dlt_user.local_print_mode = DLT_PM_FORCE_ON;
308 else if (strcmp(env_local_print,"FORCE_OFF")==0)
310 dlt_user.local_print_mode = DLT_PM_FORCE_OFF;
314 /* Initialize LogLevel/TraceStatus field */
315 dlt_user.dlt_ll_ts = 0;
316 dlt_user.dlt_ll_ts_max_num_entries = 0;
317 dlt_user.dlt_ll_ts_num_entries = 0;
319 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)
321 dlt_user_initialised = 0;
325 signal(SIGPIPE,SIG_IGN); /* ignore pipe signals */
327 atexit(dlt_user_atexit_handler);
329 #ifdef DLT_TEST_ENABLE
330 dlt_user.corrupt_user_header = 0;
331 dlt_user.corrupt_message_size = 0;
332 dlt_user.corrupt_message_size_size = 0;
338 void dlt_user_atexit_handler(void)
341 /* Try to resend potential log messages in the user buffer */
342 int count = dlt_user_atexit_blow_out_user_buffer();
346 sprintf(tmp,"Lost log messages in user buffer when exiting: %i\n",count);
347 dlt_log(LOG_ERR, tmp);
350 /* Unregister app (this also unregisters all contexts in daemon) */
351 /* Ignore return value */
352 dlt_unregister_app();
355 /* Ignore return value */
359 int dlt_user_atexit_blow_out_user_buffer(void){
363 uint32_t exitTime = dlt_uptime() + DLT_USER_ATEXIT_RESEND_BUFFER_EXIT_TIMEOUT;
365 while(dlt_uptime() < exitTime ){
367 ret = dlt_user_log_resend_buffer();
374 usleep(DLT_USER_ATEXIT_RESEND_BUFFER_SLEEP);
378 count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
387 char filename[DLT_USER_MAX_FILENAME_LENGTH];
389 if (dlt_user_initialised==0)
394 if (dlt_receiverthread_handle)
396 /* Ignore return value */
397 pthread_cancel(dlt_receiverthread_handle);
400 if (dlt_user.dlt_user_handle!=-1)
402 sprintf(filename,"/tmp/dlt%d",getpid());
404 close(dlt_user.dlt_user_handle);
405 dlt_user.dlt_user_handle=-1;
410 #ifdef DLT_SHM_ENABLE
411 /* free shared memory */
412 dlt_shm_free_client(&dlt_user.dlt_shm);
415 if (dlt_user.dlt_log_handle!=-1)
417 /* close log file/output fifo to daemon */
418 close(dlt_user.dlt_log_handle);
419 dlt_user.dlt_log_handle = -1;
422 /* Ignore return value */
423 dlt_receiver_free(&(dlt_user.receiver));
425 /* Ignore return value */
426 dlt_buffer_free_dynamic(&(dlt_user.startup_buffer));
428 if (dlt_user.dlt_ll_ts)
430 for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
432 if (dlt_user.dlt_ll_ts[i].injection_table!=0)
434 free(dlt_user.dlt_ll_ts[i].injection_table);
435 dlt_user.dlt_ll_ts[i].injection_table = 0;
437 dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
440 free(dlt_user.dlt_ll_ts);
441 dlt_user.dlt_ll_ts = 0;
442 dlt_user.dlt_ll_ts_max_num_entries = 0;
443 dlt_user.dlt_ll_ts_num_entries = 0;
446 dlt_user_initialised = 0;
451 int dlt_check_library_version(const char * user_major_version,const char * user_minor_version)
453 return dlt_user_check_library_version(user_major_version, user_minor_version);
456 int dlt_register_app(const char *appid, const char * description)
460 if (dlt_user_initialised==0)
468 if ((appid==0) || (appid[0]=='\0'))
475 /* Store locally application id and application description */
476 dlt_set_id(dlt_user.appID, appid);
478 if (dlt_user.application_description!=0)
480 free(dlt_user.application_description);
483 dlt_user.application_description = 0;
487 dlt_user.application_description= malloc(strlen(description)+1);
488 strncpy(dlt_user.application_description, description, strlen(description));
490 /* Terminate transmitted string with 0 */
491 dlt_user.application_description[strlen(description)]='\0';
496 ret = dlt_user_log_send_register_application();
500 int dlt_register_context(DltContext *handle, const char *contextid, const char * description)
502 if (dlt_user_initialised==0)
512 if (dlt_user.appID[0]=='\0')
514 dlt_log(LOG_ERR, "no application registered!\n");
520 if ((contextid==0) || (contextid[0]=='\0'))
528 return dlt_register_context_ll_ts(handle, contextid, description, DLT_USER_LOG_LEVEL_NOT_SET, DLT_USER_TRACE_STATUS_NOT_SET);
531 int dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const char * description, int loglevel, int tracestatus)
536 char ctid[DLT_ID_SIZE+1];
538 if (dlt_user_initialised==0)
548 if (dlt_user.appID[0]=='\0')
550 dlt_log(LOG_ERR, "no application registered!\n");
558 if ((contextid==0) || (contextid[0]=='\0'))
563 if ((loglevel<DLT_USER_LOG_LEVEL_NOT_SET) || (loglevel>DLT_LOG_VERBOSE) || (loglevel==DLT_LOG_DEFAULT))
568 if ((tracestatus<DLT_USER_TRACE_STATUS_NOT_SET) || (tracestatus>DLT_TRACE_STATUS_ON) || (tracestatus==DLT_TRACE_STATUS_DEFAULT))
573 if (dlt_user_log_init(handle, &log)==-1)
578 /* Reset message counter */
581 /* Store context id in log level/trace status field */
583 /* Check if already registered, else register context */
587 for (i=0;i<dlt_user.dlt_ll_ts_num_entries;i++)
589 if (dlt_user.dlt_ll_ts)
591 if (memcmp(dlt_user.dlt_ll_ts[i].contextID, contextid,DLT_ID_SIZE)==0)
595 memset(ctid,0,(DLT_ID_SIZE+1));
596 dlt_print_id(ctid, contextid);
598 sprintf(str,"context '%s' already registered!\n",ctid);
599 dlt_log(LOG_WARNING, str);
608 /* Allocate or expand context array */
609 if (dlt_user.dlt_ll_ts == 0)
611 dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*DLT_USER_CONTEXT_ALLOC_SIZE);
612 if (dlt_user.dlt_ll_ts==0)
618 dlt_user.dlt_ll_ts_max_num_entries = DLT_USER_CONTEXT_ALLOC_SIZE;
620 /* Initialize new entries */
621 for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
623 dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
625 /* At startup, logging and tracing is locally enabled */
626 /* the correct log level/status is set after received from daemon */
627 dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL;
628 dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
630 dlt_user.dlt_ll_ts[i].context_description = 0;
632 dlt_user.dlt_ll_ts[i].injection_table = 0;
633 dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
638 if ((dlt_user.dlt_ll_ts_num_entries%DLT_USER_CONTEXT_ALLOC_SIZE)==0)
640 /* allocate memory in steps of DLT_USER_CONTEXT_ALLOC_SIZE, e.g. 500 */
642 old = dlt_user.dlt_ll_ts;
643 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;
644 dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*
645 dlt_user.dlt_ll_ts_max_num_entries);
646 if (dlt_user.dlt_ll_ts==0)
652 memcpy(dlt_user.dlt_ll_ts,old,sizeof(dlt_ll_ts_type)*dlt_user.dlt_ll_ts_num_entries);
655 /* Initialize new entries */
656 for (i=dlt_user.dlt_ll_ts_num_entries;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
658 dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
660 /* At startup, logging and tracing is locally enabled */
661 /* the correct log level/status is set after received from daemon */
662 dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL;
663 dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
665 dlt_user.dlt_ll_ts[i].context_description = 0;
667 dlt_user.dlt_ll_ts[i].injection_table = 0;
668 dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
673 /* Store locally context id and context description */
674 dlt_set_id(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].contextID, contextid);
676 if (dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description!=0)
678 free(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description);
681 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = 0;
685 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = malloc(strlen(description)+1);
686 strncpy(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description, description, strlen(description));
688 /* Terminate transmitted string with 0 */
689 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description[strlen(description)]='\0';
692 if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
694 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level = loglevel;
697 if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
699 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status = tracestatus;
702 /* Prepare transfer struct */
703 //dlt_set_id(log->appID, dlt_user.appID);
704 dlt_set_id(handle->contextID, contextid);
705 handle->log_level_pos = dlt_user.dlt_ll_ts_num_entries;
707 log.context_description = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description;
709 if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
711 log.log_level = loglevel;
715 log.log_level = DLT_USER_LOG_LEVEL_NOT_SET;
718 if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
720 log.trace_status = tracestatus;
724 log.trace_status = DLT_USER_TRACE_STATUS_NOT_SET;
727 dlt_user.dlt_ll_ts_num_entries++;
731 ret=dlt_user_log_send_register_context(&log);
743 int dlt_unregister_app(void)
747 if (dlt_user_initialised==0)
752 /* Inform daemon to unregister application and all of its contexts */
753 ret = dlt_user_log_send_unregister_application();
757 /* Clear and free local stored application information */
758 dlt_set_id(dlt_user.appID, "");
760 if (dlt_user.application_description!=0)
762 free(dlt_user.application_description);
765 dlt_user.application_description = 0;
772 int dlt_unregister_context(DltContext *handle)
777 if (dlt_user_initialised==0)
782 if (dlt_user_log_init(handle, &log) == -1)
789 if (dlt_user.dlt_ll_ts)
791 /* Clear and free local stored context information */
792 dlt_set_id(dlt_user.dlt_ll_ts[handle->log_level_pos].contextID, "");
794 dlt_user.dlt_ll_ts[handle->log_level_pos].log_level = DLT_USER_INITIAL_LOG_LEVEL;
795 dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
797 if (dlt_user.dlt_ll_ts[handle->log_level_pos].context_description!=0)
799 free(dlt_user.dlt_ll_ts[handle->log_level_pos].context_description);
802 dlt_user.dlt_ll_ts[handle->log_level_pos].context_description = 0;
804 if (dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table)
806 free(dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table);
807 dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table = 0;
810 dlt_user.dlt_ll_ts[handle->log_level_pos].nrcallbacks = 0;
815 /* Inform daemon to unregister context */
816 ret = dlt_user_log_send_unregister_context(&log);
821 int dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTraceStatusType tracestatus)
826 if (dlt_user_initialised==0)
834 /* Removed because of DltLogLevelType and DltTraceStatusType
836 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
841 if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
846 if (dlt_user.dlt_ll_ts==0)
855 /* Update local structures */
856 for (i=0; i<dlt_user.dlt_ll_ts_num_entries;i++)
858 dlt_user.dlt_ll_ts[i].log_level = loglevel;
859 dlt_user.dlt_ll_ts[i].trace_status = tracestatus;
864 /* Inform DLT server about update */
865 ret = dlt_send_app_ll_ts_limit(dlt_user.appID, loglevel, tracestatus);
870 int dlt_get_log_state()
872 return dlt_user.log_state;
875 int dlt_set_log_mode(DltUserLogMode mode)
877 if (dlt_user_initialised==0)
885 return dlt_user_log_send_log_mode(mode);
888 int dlt_forward_msg(void *msgdata,size_t size)
890 DltUserHeader userheader;
893 if ((msgdata==0) || (size==0))
898 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1)
900 /* Type of internal user message; same value for Trace messages */
904 if (dlt_user.dlt_is_file)
907 ret = dlt_user_log_out2(dlt_user.dlt_log_handle, msgdata, size, 0, 0);
908 return ((ret==DLT_RETURN_OK)?0:-1);
912 /* Reattach to daemon if neccesary */
913 dlt_user_log_reattach_to_daemon();
915 if (dlt_user.overflow)
917 if (dlt_user_log_send_overflow()==0)
924 ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
925 &(userheader), sizeof(DltUserHeader),
926 msgdata, size, 0, 0);
928 /* store message in ringbuffer, if an error has occured */
929 if (ret!=DLT_RETURN_OK)
933 if (dlt_buffer_push3(&(dlt_user.startup_buffer),
934 (unsigned char *)&(userheader), sizeof(DltUserHeader),
935 msgdata, size, 0, 0)==-1)
937 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
945 case DLT_RETURN_PIPE_FULL:
947 /* data could not be written */
948 dlt_user.overflow = 1;
951 case DLT_RETURN_PIPE_ERROR:
953 /* handle not open or pipe error */
954 close(dlt_user.dlt_log_handle);
955 dlt_user.dlt_log_handle = -1;
959 case DLT_RETURN_ERROR:
961 /* other error condition */
970 /* This case should not occur */
979 /* ********************************************************************************************* */
981 int dlt_user_log_write_start(DltContext *handle, DltContextData *log,DltLogLevelType loglevel)
983 return dlt_user_log_write_start_id(handle,log,loglevel,DLT_USER_DEFAULT_MSGID);
986 int dlt_user_log_write_start_id(DltContext *handle, DltContextData *log,DltLogLevelType loglevel, uint32_t messageid)
990 if (dlt_user_initialised==0)
998 if (dlt_user_log_init(handle, log)==-1)
1008 /* Removed because of DltLogLevelType
1010 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
1020 log->log_level = loglevel;
1023 if (dlt_user.dlt_ll_ts==0)
1030 if ((log->log_level<=(int)(dlt_user.dlt_ll_ts[handle->log_level_pos].log_level) ) && (log->log_level!=0))
1034 /* In non-verbose mode, insert message id */
1035 if (dlt_user.verbose_mode==0)
1037 if ((sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1041 /* Write message id */
1042 memcpy(log->buffer,&(mid),sizeof(uint32_t));
1043 log->size = sizeof(uint32_t);
1045 /* as the message id is part of each message in non-verbose mode,
1046 it doesn't increment the argument counter in extended header (if used) */
1059 int dlt_user_log_write_finish(DltContextData *log)
1066 return dlt_user_log_send_log(log, DLT_TYPE_LOG);
1069 int dlt_user_log_write_raw(DltContextData *log,void *data,uint16_t length)
1079 if ((log->size+length+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1084 if (dlt_user.verbose_mode)
1086 if ((log->size+length+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1091 /* Transmit type information */
1092 type_info = DLT_TYPE_INFO_RAWD;
1094 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1095 log->size += sizeof(uint32_t);
1099 /* First transmit length of raw data, then the raw data itself */
1100 arg_size = (uint16_t)length;
1102 memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1103 log->size += sizeof(uint16_t);
1105 memcpy((log->buffer)+log->size,data,arg_size);
1106 log->size += arg_size;
1113 int dlt_user_log_write_float32(DltContextData *log, float32_t data)
1122 if (sizeof(float32_t)!=4)
1127 if ((log->size+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1132 if (dlt_user.verbose_mode)
1134 if ((log->size+sizeof(uint32_t)+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1139 type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_32BIT;
1141 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1142 log->size += sizeof(uint32_t);
1145 memcpy((log->buffer)+log->size,&data, sizeof(float32_t));
1146 log->size += sizeof(float32_t);
1153 int dlt_user_log_write_float64(DltContextData *log, float64_t data)
1162 if (sizeof(float64_t)!=8)
1167 if ((log->size+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1172 if (dlt_user.verbose_mode)
1174 if ((log->size+sizeof(uint32_t)+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1179 type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_64BIT;
1181 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1182 log->size += sizeof(uint32_t);
1185 memcpy((log->buffer)+log->size,&data, sizeof(float64_t));
1186 log->size += sizeof(float64_t);
1193 int dlt_user_log_write_uint( DltContextData *log, unsigned int data)
1200 switch (sizeof(unsigned int))
1204 return dlt_user_log_write_uint8(log, (uint8_t)data);
1209 return dlt_user_log_write_uint16(log, (uint16_t)data);
1214 return dlt_user_log_write_uint32(log, (uint32_t)data);
1219 return dlt_user_log_write_uint64(log, (uint64_t)data);
1232 int dlt_user_log_write_uint8(DltContextData *log, uint8_t data)
1241 if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1246 if (dlt_user.verbose_mode)
1248 if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1253 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_8BIT;
1255 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1256 log->size += sizeof(uint32_t);
1259 memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
1260 log->size += sizeof(uint8_t);
1267 int dlt_user_log_write_uint16(DltContextData *log, uint16_t data)
1276 if ((log->size+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1281 if (dlt_user.verbose_mode)
1283 if ((log->size+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1288 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_16BIT;
1290 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1291 log->size += sizeof(uint32_t);
1294 memcpy((log->buffer)+log->size,&data,sizeof(uint16_t));
1295 log->size += sizeof(uint16_t);
1302 int dlt_user_log_write_uint32(DltContextData *log, uint32_t data)
1311 if ((log->size+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1316 if (dlt_user.verbose_mode)
1318 if ((log->size+sizeof(uint32_t)+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1323 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_32BIT;
1325 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1326 log->size += sizeof(uint32_t);
1329 memcpy((log->buffer)+log->size,&data, sizeof(uint32_t));
1330 log->size += sizeof(uint32_t);
1337 int dlt_user_log_write_uint64(DltContextData *log, uint64_t data)
1346 if ((log->size+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1351 if (dlt_user.verbose_mode)
1353 if ((log->size+sizeof(uint32_t)+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1358 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_64BIT;
1360 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1361 log->size +=sizeof(uint32_t);
1364 memcpy((log->buffer)+log->size,&data,sizeof(uint64_t));
1365 log->size += sizeof(uint64_t);
1372 int dlt_user_log_write_int(DltContextData *log, int data)
1379 switch (sizeof(int))
1383 return dlt_user_log_write_int8(log, (int8_t)data);
1388 return dlt_user_log_write_int16(log, (int16_t)data);
1393 return dlt_user_log_write_int32(log, (int32_t)data);
1398 return dlt_user_log_write_int64(log, (int64_t)data);
1411 int dlt_user_log_write_int8(DltContextData *log, int8_t data)
1420 if ((log->size+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
1425 if (dlt_user.verbose_mode)
1427 if ((log->size+sizeof(uint32_t)+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
1432 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_8BIT;
1434 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1435 log->size += sizeof(uint32_t);
1438 memcpy((log->buffer)+log->size,&data,sizeof(int8_t));
1439 log->size += sizeof(int8_t);
1446 int dlt_user_log_write_int16(DltContextData *log, int16_t data)
1455 if ((log->size+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
1460 if (dlt_user.verbose_mode)
1462 if ((log->size+sizeof(uint32_t)+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
1467 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_16BIT;
1469 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1470 log->size += sizeof(uint32_t);
1473 memcpy((log->buffer)+log->size,&data,sizeof(int16_t));
1474 log->size += sizeof(int16_t);
1481 int dlt_user_log_write_int32(DltContextData *log, int32_t data)
1490 if ((log->size+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
1495 if (dlt_user.verbose_mode)
1497 if ((log->size+sizeof(uint32_t)+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
1502 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_32BIT;
1504 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1505 log->size += sizeof(uint32_t);
1508 memcpy((log->buffer)+log->size,&data, sizeof(int32_t));
1509 log->size += sizeof(int32_t);
1516 int dlt_user_log_write_int64(DltContextData *log, int64_t data)
1525 if ((log->size+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
1530 if (dlt_user.verbose_mode)
1532 if ((log->size+sizeof(uint32_t)+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
1537 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_64BIT;
1539 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1540 log->size += sizeof(uint32_t);
1543 memcpy((log->buffer)+log->size,&data,sizeof(int64_t));
1544 log->size += sizeof(int64_t);
1551 int dlt_user_log_write_bool(DltContextData *log, uint8_t data)
1560 if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1565 if (dlt_user.verbose_mode)
1567 if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1572 type_info = DLT_TYPE_INFO_BOOL;
1574 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1575 log->size += sizeof(uint32_t);
1578 memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
1579 log->size += sizeof(uint8_t);
1586 int dlt_user_log_write_string(DltContextData *log, const char *text)
1591 if ((log==0) || (text==0))
1596 if ((log->size+(strlen(text)+1)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1601 if (dlt_user.verbose_mode)
1603 if ((log->size+(strlen(text)+1)+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1608 type_info = DLT_TYPE_INFO_STRG;
1610 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1611 log->size += sizeof(uint32_t);
1614 arg_size = strlen(text) + 1;
1616 memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1617 log->size += sizeof(uint16_t);
1619 memcpy((log->buffer)+log->size,text,arg_size);
1620 log->size += arg_size;
1627 int dlt_register_injection_callback(DltContext *handle, uint32_t service_id,
1628 int (*dlt_injection_callback)(uint32_t service_id, void *data, uint32_t length))
1634 DltUserInjectionCallback *old;
1641 if (dlt_user_log_init(handle, &log)==-1)
1646 if (service_id<DLT_USER_INJECTION_MIN)
1650 /* This function doesn't make sense storing to local file is choosen;
1651 so terminate this function */
1652 if (dlt_user.dlt_is_file)
1659 if (dlt_user.dlt_ll_ts==0)
1665 /* Insert callback in corresponding table */
1666 i=handle->log_level_pos;
1668 /* Insert each service_id only once */
1669 for (k=0;k<dlt_user.dlt_ll_ts[i].nrcallbacks;k++)
1671 if ((dlt_user.dlt_ll_ts[i].injection_table) &&
1672 (dlt_user.dlt_ll_ts[i].injection_table[k].service_id == service_id))
1685 j=dlt_user.dlt_ll_ts[i].nrcallbacks;
1687 /* Allocate or expand injection table */
1688 if (dlt_user.dlt_ll_ts[i].injection_table == 0)
1690 dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback));
1694 old = dlt_user.dlt_ll_ts[i].injection_table;
1695 dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback)*(j+1));
1696 memcpy(dlt_user.dlt_ll_ts[i].injection_table,old,sizeof(DltUserInjectionCallback)*j);
1700 dlt_user.dlt_ll_ts[i].nrcallbacks++;
1703 /* Store service_id and corresponding function pointer for callback function */
1704 dlt_user.dlt_ll_ts[i].injection_table[j].service_id = service_id;
1705 dlt_user.dlt_ll_ts[i].injection_table[j].injection_callback = dlt_injection_callback;
1711 int dlt_user_trace_network(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
1715 if (dlt_user_initialised==0)
1723 if (dlt_user_log_init(handle, &log)==-1)
1733 /* Commented out because of DltNetworkTraceType:
1735 if ((nw_trace_type<=0) || (nw_trace_type>0x15))
1744 if (dlt_user.dlt_ll_ts==0)
1750 if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
1755 log.trace_status = nw_trace_type;
1763 /* Write header and its length */
1764 if (dlt_user_log_write_raw(&log, header, header_len)==-1)
1774 /* Write payload and its length */
1775 if (dlt_user_log_write_raw(&log, payload, payload_len)==-1)
1781 return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
1791 int dlt_log_string(DltContext *handle,DltLogLevelType loglevel, const char *text)
1795 if (dlt_user.verbose_mode==0)
1800 if ((handle==0) || (text==0))
1805 if (dlt_user_log_write_start(handle,&log,loglevel))
1807 if (dlt_user_log_write_string(&log,text)==-1)
1811 if (dlt_user_log_write_finish(&log)==-1)
1820 int dlt_log_string_int(DltContext *handle,DltLogLevelType loglevel, const char *text, int data)
1824 if (dlt_user.verbose_mode==0)
1829 if ((handle==0) || (text==0))
1834 if (dlt_user_log_write_start(handle,&log,loglevel))
1836 if (dlt_user_log_write_string(&log,text)==-1)
1840 if (dlt_user_log_write_int(&log,data)==-1)
1844 if (dlt_user_log_write_finish(&log)==-1)
1853 int dlt_log_string_uint(DltContext *handle,DltLogLevelType loglevel, const char *text, unsigned int data)
1857 if (dlt_user.verbose_mode==0)
1862 if ((handle==0) || (text==0))
1867 if (dlt_user_log_write_start(handle,&log,loglevel))
1869 if (dlt_user_log_write_string(&log,text)==-1)
1873 if (dlt_user_log_write_uint(&log,data)==-1)
1877 if (dlt_user_log_write_finish(&log)==-1)
1886 int dlt_log_int(DltContext *handle,DltLogLevelType loglevel, int data)
1890 if (dlt_user.verbose_mode==0)
1900 if (dlt_user_log_write_start(handle,&log,loglevel))
1902 if (dlt_user_log_write_int(&log,data)==-1)
1906 if (dlt_user_log_write_finish(&log)==-1)
1915 int dlt_log_uint(DltContext *handle,DltLogLevelType loglevel, unsigned int data)
1919 if (dlt_user.verbose_mode==0)
1929 if (dlt_user_log_write_start(handle,&log,loglevel))
1931 if (dlt_user_log_write_uint(&log,data)==-1)
1935 if (dlt_user_log_write_finish(&log)==-1)
1944 int dlt_log_raw(DltContext *handle,DltLogLevelType loglevel, void *data,uint16_t length)
1948 if (dlt_user.verbose_mode==0)
1958 if (dlt_user_log_write_start(handle,&log,loglevel))
1960 if (dlt_user_log_write_raw(&log,data,length)==-1)
1964 if (dlt_user_log_write_finish(&log)==-1)
1973 int dlt_verbose_mode(void)
1975 if (dlt_user_initialised==0)
1983 /* Switch to verbose mode */
1984 dlt_user.verbose_mode = 1;
1989 int dlt_nonverbose_mode(void)
1991 if (dlt_user_initialised==0)
1999 /* Switch to non-verbose mode */
2000 dlt_user.verbose_mode = 0;
2005 int dlt_enable_local_print(void)
2007 if (dlt_user_initialised==0)
2015 dlt_user.enable_local_print = 1;
2020 int dlt_disable_local_print(void)
2022 if (dlt_user_initialised==0)
2030 dlt_user.enable_local_print = 0;
2035 void dlt_user_receiverthread_function(void *ptr)
2039 /* Check for new messages from DLT daemon */
2040 if (dlt_user_log_check_user_message()==-1)
2042 /* Critical error */
2043 dlt_log(LOG_CRIT,"Receiver thread encountered error condition\n");
2046 usleep(DLT_USER_RECEIVE_DELAY); /* delay */
2050 /* Private functions of user library */
2052 int dlt_user_log_init(DltContext *handle, DltContextData *log)
2054 if (dlt_user_initialised==0)
2062 log->handle = handle;
2067 int dlt_user_log_send_log(DltContextData *log, int mtype)
2070 DltUserHeader userheader;
2073 DltReturnValue ret = 0;
2085 if (dlt_user.appID[0]=='\0')
2090 if (log->handle->contextID[0]=='\0')
2095 if ((mtype<DLT_TYPE_LOG) || (mtype>DLT_TYPE_CONTROL))
2100 /* also for Trace messages */
2101 #ifdef DLT_SHM_ENABLE
2102 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_SHM)==-1)
2104 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1)
2110 if (dlt_message_init(&msg,0)==-1)
2115 msg.storageheader = (DltStorageHeader*)msg.headerbuffer;
2117 if (dlt_set_storageheader(msg.storageheader,dlt_user.ecuID)==-1)
2122 msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader));
2123 msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_PROTOCOL_VERSION1 ;
2125 if (dlt_user.verbose_mode)
2127 /* In verbose mode, send extended header */
2128 msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
2132 /* In non-verbose, send extended header if desired */
2133 #if (DLT_USER_USE_EXTENDED_HEADER_FOR_NONVERBOSE==1)
2134 msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
2138 #if (BYTE_ORDER==BIG_ENDIAN)
2139 msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF);
2142 msg.standardheader->mcnt = log->handle->mcnt++;
2144 /* Set header extra parameters */
2145 dlt_set_id(msg.headerextra.ecu,dlt_user.ecuID);
2146 //msg.headerextra.seid = 0;
2147 msg.headerextra.tmsp = dlt_uptime();
2149 if (dlt_message_set_extraparameters(&msg,0)==-1)
2154 /* Fill out extended header, if extended header should be provided */
2155 if (DLT_IS_HTYP_UEH(msg.standardheader->htyp))
2157 /* with extended header */
2158 msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp) );
2164 msg.extendedheader->msin = (DLT_TYPE_LOG << DLT_MSIN_MSTP_SHIFT) | ((log->log_level << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
2167 case DLT_TYPE_NW_TRACE:
2169 msg.extendedheader->msin = (DLT_TYPE_NW_TRACE << DLT_MSIN_MSTP_SHIFT) | ((log->trace_status << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
2174 /* This case should not occur */
2180 /* If in verbose mode, set flag in header for verbose mode */
2181 if (dlt_user.verbose_mode)
2183 msg.extendedheader->msin |= DLT_MSIN_VERB;
2186 msg.extendedheader->noar = log->args_num; /* number of arguments */
2187 dlt_set_id(msg.extendedheader->apid,dlt_user.appID); /* application id */
2188 dlt_set_id(msg.extendedheader->ctid,log->handle->contextID); /* context id */
2190 msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
2194 /* without extended header */
2195 msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
2198 len=msg.headersize - sizeof(DltStorageHeader) +log->size;
2201 dlt_log(LOG_CRIT,"Huge message discarded!\n");
2205 msg.standardheader->len = DLT_HTOBE_16(len);
2207 /* print to std out, if enabled */
2208 if ((dlt_user.local_print_mode != DLT_PM_FORCE_OFF) &&
2209 (dlt_user.local_print_mode != DLT_PM_AUTOMATIC))
2211 if ((dlt_user.enable_local_print) || (dlt_user.local_print_mode == DLT_PM_FORCE_ON))
2213 if (dlt_user_print_msg(&msg, log)==-1)
2220 if (dlt_user.dlt_is_file)
2223 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, msg.headerbuffer, msg.headersize, log->buffer, log->size);
2224 return ((ret==DLT_RETURN_OK)?0:-1);
2228 /* Reattach to daemon if neccesary */
2229 dlt_user_log_reattach_to_daemon();
2231 if (dlt_user.overflow)
2233 if (dlt_user_log_send_overflow()==0)
2235 dlt_user.overflow=0;
2239 /* try to resent old data first */
2241 if(dlt_user.dlt_log_handle!=-1)
2242 ret = dlt_user_log_resend_buffer();
2245 /* resend ok or nothing to resent */
2246 #ifdef DLT_SHM_ENABLE
2247 if(dlt_user.dlt_log_handle!=-1)
2248 dlt_shm_push(&dlt_user.dlt_shm,msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2249 log->buffer, log->size,0,0);
2252 ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
2253 &(userheader), sizeof(DltUserHeader),
2258 #ifdef DLT_TEST_ENABLE
2259 if(dlt_user.corrupt_user_header) {
2260 userheader.pattern[0]=0xff;
2261 userheader.pattern[1]=0xff;
2262 userheader.pattern[2]=0xff;
2263 userheader.pattern[3]=0xff;
2265 if(dlt_user.corrupt_message_size) {
2266 msg.standardheader->len = DLT_HTOBE_16(dlt_user.corrupt_message_size_size);
2269 ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
2270 &(userheader), sizeof(DltUserHeader),
2271 msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2272 log->buffer, log->size);
2276 /* store message in ringbuffer, if an error has occured */
2277 if (ret!=DLT_RETURN_OK)
2281 if (dlt_buffer_push3(&(dlt_user.startup_buffer),
2282 (unsigned char *)&(userheader), sizeof(DltUserHeader),
2283 msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2284 log->buffer, log->size)==-1)
2286 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
2294 case DLT_RETURN_PIPE_FULL:
2296 /* data could not be written */
2297 dlt_user.overflow = 1;
2300 case DLT_RETURN_PIPE_ERROR:
2302 /* handle not open or pipe error */
2303 close(dlt_user.dlt_log_handle);
2304 dlt_user.dlt_log_handle = -1;
2306 #ifdef DLT_SHM_ENABLE
2307 /* free shared memory */
2308 dlt_shm_free_client(&dlt_user.dlt_shm);
2311 if (dlt_user.local_print_mode == DLT_PM_AUTOMATIC)
2313 dlt_user_print_msg(&msg, log);
2318 case DLT_RETURN_ERROR:
2320 /* other error condition */
2329 /* This case should never occur. */
2338 int dlt_user_log_send_register_application(void)
2340 DltUserHeader userheader;
2341 DltUserControlMsgRegisterApplication usercontext;
2345 if (dlt_user.appID[0]=='\0')
2350 /* set userheader */
2351 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_APPLICATION)==-1)
2356 /* set usercontext */
2357 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
2358 usercontext.pid = getpid();
2360 if (dlt_user.application_description!=0)
2362 usercontext.description_length = strlen(dlt_user.application_description);
2366 usercontext.description_length = 0;
2369 if (dlt_user.dlt_is_file)
2375 ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterApplication),dlt_user.application_description,usercontext.description_length);
2376 return ((ret==DLT_RETURN_OK)?0:-1);
2379 int dlt_user_log_send_unregister_application(void)
2381 DltUserHeader userheader;
2382 DltUserControlMsgUnregisterApplication usercontext;
2386 if (dlt_user.appID[0]=='\0')
2391 /* set userheader */
2392 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_APPLICATION)==-1)
2397 /* set usercontext */
2398 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
2399 usercontext.pid = getpid();
2401 if (dlt_user.dlt_is_file)
2407 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterApplication));
2408 return ((ret==DLT_RETURN_OK)?0:-1);
2411 int dlt_user_log_send_register_context(DltContextData *log)
2413 DltUserHeader userheader;
2414 DltUserControlMsgRegisterContext usercontext;
2427 if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0'))
2432 /* set userheader */
2433 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_CONTEXT)==-1)
2438 /* set usercontext */
2439 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
2440 dlt_set_id(usercontext.ctid,log->handle->contextID); /* context id */
2441 usercontext.log_level_pos = log->handle->log_level_pos;
2442 usercontext.pid = getpid();
2444 usercontext.log_level = (int8_t)log->log_level;
2445 usercontext.trace_status = (int8_t)log->trace_status;
2447 if (log->context_description!=0)
2449 usercontext.description_length = strlen(log->context_description);
2453 usercontext.description_length = 0;
2456 if (dlt_user.dlt_is_file)
2462 ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterContext),log->context_description,usercontext.description_length);
2463 return ((ret==DLT_RETURN_OK)?0:-1);
2466 int dlt_user_log_send_unregister_context(DltContextData *log)
2468 DltUserHeader userheader;
2469 DltUserControlMsgUnregisterContext usercontext;
2482 if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0'))
2487 /* set userheader */
2488 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_CONTEXT)==-1)
2493 /* set usercontext */
2494 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
2495 dlt_set_id(usercontext.ctid,log->handle->contextID); /* context id */
2496 usercontext.pid = getpid();
2498 if (dlt_user.dlt_is_file)
2504 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterContext));
2505 return ((ret==DLT_RETURN_OK)?0:-1);
2508 int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus)
2510 DltUserHeader userheader;
2511 DltUserControlMsgAppLogLevelTraceStatus usercontext;
2514 if ((appid==0) || (appid[0]=='\0'))
2519 /* Removed because of DltLogLevelType and DltTraceStatusType
2521 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
2526 if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
2533 /* set userheader */
2534 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_APP_LL_TS)==-1)
2539 /* set usercontext */
2540 dlt_set_id(usercontext.apid,appid); /* application id */
2541 usercontext.log_level = loglevel;
2542 usercontext.trace_status = tracestatus;
2544 if (dlt_user.dlt_is_file)
2550 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgAppLogLevelTraceStatus));
2551 return ((ret==DLT_RETURN_OK)?0:-1);
2554 int dlt_user_log_send_log_mode(DltUserLogMode mode)
2556 DltUserHeader userheader;
2557 DltUserControlMsgLogMode logmode;
2561 /* set userheader */
2562 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_MODE)==-1)
2568 logmode.log_mode = (unsigned char) mode;
2570 if (dlt_user.dlt_is_file)
2576 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(logmode), sizeof(DltUserControlMsgLogMode));
2577 return ((ret==DLT_RETURN_OK)?0:-1);
2580 int dlt_user_print_msg(DltMessage *msg, DltContextData *log)
2582 uint8_t *databuffer_tmp;
2583 int32_t datasize_tmp;
2584 static char text[DLT_USER_TEXT_LENGTH];
2586 if ((msg==0) || (log==0))
2591 /* Save variables before print */
2592 databuffer_tmp = msg->databuffer;
2593 datasize_tmp = msg->datasize;
2595 /* Act like a receiver, convert header back to host format */
2596 msg->standardheader->len = DLT_BETOH_16(msg->standardheader->len);
2597 dlt_message_get_extraparameters(msg,0);
2599 msg->databuffer = log->buffer;
2600 msg->datasize = log->size;
2602 /* Print message as ASCII */
2603 if (dlt_message_print_ascii(msg,text,DLT_USER_TEXT_LENGTH,0)==-1)
2608 /* Restore variables and set len to BE*/
2609 msg->databuffer = databuffer_tmp;
2610 msg->datasize = datasize_tmp;
2612 msg->standardheader->len = DLT_HTOBE_16(msg->standardheader->len);
2617 int dlt_user_log_check_user_message(void)
2624 DltUserHeader *userheader;
2625 DltReceiver *receiver = &(dlt_user.receiver);
2627 DltUserControlMsgLogLevel *usercontextll;
2628 DltUserControlMsgInjection *usercontextinj;
2629 DltUserControlMsgLogState *userlogstate;
2630 unsigned char *userbuffer;
2631 unsigned char *inject_buffer;
2633 if (dlt_user.dlt_user_handle!=-1)
2637 if (dlt_receiver_receive_fd(receiver)<=0)
2639 /* No new message available */
2643 /* look through buffer as long as data is in there */
2646 if (receiver->bytesRcvd < (int32_t)sizeof(DltUserHeader))
2651 /* resync if necessary */
2655 userheader = (DltUserHeader*) (receiver->buf+offset);
2657 /* Check for user header pattern */
2658 if (dlt_user_check_userheader(userheader))
2665 while ((int32_t)(sizeof(DltUserHeader)+offset)<=receiver->bytesRcvd);
2667 /* Check for user header pattern */
2668 if (dlt_user_check_userheader(userheader)==0)
2673 /* Set new start offset */
2676 receiver->buf+=offset;
2677 receiver->bytesRcvd-=offset;
2680 switch (userheader->message)
2682 case DLT_USER_MESSAGE_LOG_LEVEL:
2684 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel)))
2690 usercontextll = (DltUserControlMsgLogLevel*) (receiver->buf+sizeof(DltUserHeader));
2692 /* Update log level and trace status */
2693 if (usercontextll!=0)
2697 if ((usercontextll->log_level_pos >= 0) && (usercontextll->log_level_pos < (int32_t)dlt_user.dlt_ll_ts_num_entries))
2699 // printf("Store ll, ts\n");
2700 if (dlt_user.dlt_ll_ts)
2702 dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level = usercontextll->log_level;
2703 dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status = usercontextll->trace_status;
2710 /* keep not read data in buffer */
2711 if (dlt_receiver_remove(receiver,sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel))==-1)
2717 case DLT_USER_MESSAGE_INJECTION:
2719 /* At least, user header, user context, and service id and data_length of injected message is available */
2720 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)))
2726 usercontextinj = (DltUserControlMsgInjection*) (receiver->buf+sizeof(DltUserHeader));
2727 userbuffer = (unsigned char*) (receiver->buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection));
2733 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))
2741 if ((usercontextinj->data_length_inject>0) && (dlt_user.dlt_ll_ts))
2743 /* Check if injection callback is registered for this context */
2744 for (i=0; i<dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].nrcallbacks;i++)
2746 if ((dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table) &&
2747 (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].service_id == usercontextinj->service_id))
2749 /* callback available, so prepare data, then call it */
2750 inject_buffer = malloc(usercontextinj->data_length_inject);
2751 if (inject_buffer!=0)
2753 /* copy from receiver to inject_buffer */
2754 memcpy(inject_buffer, userbuffer, usercontextinj->data_length_inject);
2757 if (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback!=0)
2759 // printf("Got injection(%d), length=%d, '%s' \n", usercontext->service_id, usercontext->data_length_inject, inject_buffer);
2760 dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback(
2761 usercontextinj->service_id, inject_buffer, usercontextinj->data_length_inject);
2764 if (inject_buffer!=0)
2766 free(inject_buffer);
2778 /* keep not read data in buffer */
2779 if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))==-1)
2786 case DLT_USER_MESSAGE_LOG_STATE:
2788 /* At least, user header, user context, and service id and data_length of injected message is available */
2789 if (receiver->bytesRcvd < (int32_t)(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))
2795 userlogstate = (DltUserControlMsgLogState*) (receiver->buf+sizeof(DltUserHeader));
2796 dlt_user.log_state = userlogstate->log_state;
2798 /* keep not read data in buffer */
2799 if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))==-1)
2807 dlt_log(LOG_ERR,"Invalid user message type received!\n");
2809 dlt_receiver_remove(receiver,sizeof(DltUserHeader));
2810 /* In next invocation of while loop, a resync will be triggered if additional data was received */
2823 if (dlt_receiver_move_to_begin(receiver)==-1)
2827 } /* while receive */
2830 return DLT_RETURN_OK;
2833 int dlt_user_log_resend_buffer(void)
2836 uint8_t buf[DLT_USER_RCVBUF_MAX_SIZE];
2840 /* Send content of ringbuffer */
2842 count = dlt_buffer_get_message_count(&(dlt_user.startup_buffer));
2845 for (num=0;num<count;num++)
2849 size = dlt_buffer_copy(&(dlt_user.startup_buffer),buf,sizeof(buf));
2853 #ifdef DLT_SHM_ENABLE
2854 dlt_shm_push(&dlt_user.dlt_shm,buf+sizeof(DltUserHeader),size-sizeof(DltUserHeader),0,0,0,0);
2857 ret = dlt_user_log_out3(dlt_user.dlt_log_handle, buf,sizeof(DltUserHeader),0,0,0,0);
2860 ret = dlt_user_log_out3(dlt_user.dlt_log_handle, buf,size,0,0,0,0);
2863 /* in case of error, keep message in ringbuffer */
2864 if (ret==DLT_RETURN_OK)
2866 dlt_buffer_remove(&(dlt_user.startup_buffer));
2869 if (dlt_buffer_push(&(dlt_user.startup_buffer), buf, size)==-1)
2871 dlt_log(LOG_ERR,"Error pushing back message to history buffer. Message discarded.\n");
2875 // In case of: data could not be written, set overflow flag
2876 if (ret==DLT_RETURN_PIPE_FULL)
2878 dlt_user.overflow = 1;
2884 /* keep message in ringbuffer */
2895 void dlt_user_log_reattach_to_daemon(void)
2897 uint32_t num,reregistered=0;
2900 DltContextData log_new;
2902 if (dlt_user.dlt_log_handle<0)
2904 dlt_user.dlt_log_handle=-1;
2906 /* try to open pipe to dlt daemon */
2907 dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK);
2908 if (dlt_user.dlt_log_handle > 0)
2910 if (dlt_user_log_init(&handle,&log_new)==-1)
2915 #ifdef DLT_SHM_ENABLE
2916 /* init shared memory */
2917 if (dlt_shm_init_client(&dlt_user.dlt_shm,DLT_SHM_KEY) < 0)
2919 sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY);
2920 dlt_log(LOG_WARNING, str);
2925 dlt_log(LOG_NOTICE, "Logging re-enabled!\n");
2927 /* Re-register application */
2928 if (dlt_user_log_send_register_application()==-1)
2935 /* Re-register all stored contexts */
2936 for (num=0; num<dlt_user.dlt_ll_ts_num_entries; num++)
2938 /* Re-register stored context */
2939 if ((dlt_user.appID[0]!='\0') && (dlt_user.dlt_ll_ts[num].contextID[0]!='\0') && (dlt_user.dlt_ll_ts))
2941 //dlt_set_id(log_new.appID, dlt_user.appID);
2942 dlt_set_id(handle.contextID, dlt_user.dlt_ll_ts[num].contextID);
2943 handle.log_level_pos = num;
2944 log_new.context_description = dlt_user.dlt_ll_ts[num].context_description;
2946 log_new.log_level = DLT_USER_LOG_LEVEL_NOT_SET;
2947 log_new.trace_status = DLT_USER_TRACE_STATUS_NOT_SET;
2949 if (dlt_user_log_send_register_context(&log_new)==-1)
2961 if (reregistered==1)
2963 dlt_user_log_resend_buffer();
2969 int dlt_user_log_send_overflow(void)
2971 DltUserHeader userheader;
2974 /* set userheader */
2975 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_OVERFLOW)==-1)
2980 if (dlt_user.dlt_is_file)
2986 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), 0, 0);
2987 return ((ret==DLT_RETURN_OK)?0:-1);
2990 int dlt_user_check_buffer(int *total_size, int *used_size)
2992 #ifdef DLT_SHM_ENABLE
2993 *total_size = dlt_shm_get_total_size(&(dlt_user.dlt_shm));
2994 *used_size = dlt_shm_get_used_size(&(dlt_user.dlt_shm));
2996 *total_size = dlt_buffer_get_total_size(&(dlt_user.startup_buffer));
2997 *used_size = dlt_buffer_get_used_size(&(dlt_user.startup_buffer));
3003 #ifdef DLT_TEST_ENABLE
3004 void dlt_user_test_corrupt_user_header(int enable)
3006 dlt_user.corrupt_user_header = enable;
3008 void dlt_user_test_corrupt_message_size(int enable,int16_t size)
3010 dlt_user.corrupt_message_size = enable;
3011 dlt_user.corrupt_message_size_size = size;