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 void dlt_user_log_reattach_to_daemon(void);
126 static int dlt_user_log_send_overflow(void);
128 int dlt_user_check_library_version(const char *user_major_version,const char *user_minor_version){
131 char lib_major_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
132 char lib_minor_version[DLT_USER_MAX_LIB_VERSION_LENGTH];
134 dlt_get_major_version( lib_major_version);
135 dlt_get_minor_version( lib_minor_version);
137 if( (strcmp(lib_major_version,user_major_version)!=0) || (strcmp(lib_minor_version,user_minor_version)!=0))
139 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);
140 dlt_log(LOG_WARNING, str);
148 char filename[DLT_USER_MAX_FILENAME_LENGTH];
151 dlt_user_initialised = 1;
153 /* Initialize common part of dlt_init()/dlt_init_file() */
154 if (dlt_init_common()==-1)
156 dlt_user_initialised = 0;
160 dlt_user.dlt_is_file = 0;
161 dlt_user.overflow = 0;
163 /* init shared memory */
164 if (dlt_shm_init_client(&dlt_user.dlt_shm,DLT_SHM_KEY) < 0)
166 sprintf(str,"Loging disabled, Shared memory %d cannot be created!\n",DLT_SHM_KEY);
167 dlt_log(LOG_WARNING, str);
171 /* create and open DLT user FIFO */
172 sprintf(filename,"%s/dlt%d",DLT_USER_DIR,getpid());
174 /* Try to delete existing pipe, ignore result of unlink */
177 ret=mkfifo(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH );
180 sprintf(str,"Loging disabled, FIFO user %s cannot be created!\n",filename);
181 dlt_log(LOG_WARNING, str);
182 /* return 0; */ /* removed to prevent error, when FIFO already exists */
185 dlt_user.dlt_user_handle = open(filename, O_RDWR);
186 if (dlt_user.dlt_user_handle == -1)
188 sprintf(str,"Loging disabled, FIFO user %s cannot be opened!\n",filename);
189 dlt_log(LOG_WARNING, str);
194 /* open DLT output FIFO */
195 dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK);
196 if (dlt_user.dlt_log_handle==-1)
198 sprintf(str,"Loging disabled, FIFO %s cannot be opened with open()!\n",DLT_USER_FIFO);
199 dlt_log(LOG_WARNING, str);
203 if (dlt_receiver_init(&(dlt_user.receiver),dlt_user.dlt_user_handle, DLT_USER_RCVBUF_MAX_SIZE)==-1)
205 dlt_user_initialised = 0;
209 /* Start receiver thread */
210 if (pthread_create(&(dlt_receiverthread_handle),
212 (void *) &dlt_user_receiverthread_function,
215 if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0)
217 dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n");
220 dlt_log(LOG_CRIT, "Can't create receiver thread!\n");
221 dlt_user_initialised = 0;
225 if (pthread_attr_destroy(&dlt_receiverthread_attr)!=0)
227 dlt_log(LOG_WARNING, "Can't destroy thread attributes!\n");
233 int dlt_init_file(const char *name)
235 dlt_user_initialised = 1;
237 /* Initialize common part of dlt_init()/dlt_init_file() */
238 if (dlt_init_common()==-1)
240 dlt_user_initialised = 0;
244 dlt_user.dlt_is_file = 1;
246 /* open DLT output file */
247 dlt_user.dlt_log_handle = open(name,O_WRONLY|O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); /* mode: wb */
248 if (dlt_user.dlt_log_handle == -1)
250 sprintf(str,"Log file %s cannot be opened!\n",name);
251 dlt_log(LOG_ERR, str);
258 int dlt_init_common(void)
260 char *env_local_print;
262 /* Binary semaphore for threads */
263 if (sem_init(&dlt_mutex, 0, 1)==-1)
265 dlt_user_initialised = 0;
269 /* set to unknown state of connected client */
270 dlt_user.log_state = -1;
272 dlt_user.dlt_log_handle=-1;
273 dlt_user.dlt_user_handle=-1;
275 dlt_set_id(dlt_user.ecuID,DLT_USER_DEFAULT_ECU_ID);
276 dlt_set_id(dlt_user.appID,"");
278 dlt_user.application_description = 0;
280 /* Verbose mode is enabled by default */
281 dlt_user.verbose_mode = 1;
283 /* Local print is disabled by default */
284 dlt_user.enable_local_print = 0;
286 dlt_user.local_print_mode = DLT_PM_UNSET;
288 env_local_print = getenv(DLT_USER_ENV_LOCAL_PRINT_MODE);
291 if (strcmp(env_local_print,"AUTOMATIC")==0)
293 dlt_user.local_print_mode = DLT_PM_AUTOMATIC;
295 else if (strcmp(env_local_print,"FORCE_ON")==0)
297 dlt_user.local_print_mode = DLT_PM_FORCE_ON;
299 else if (strcmp(env_local_print,"FORCE_OFF")==0)
301 dlt_user.local_print_mode = DLT_PM_FORCE_OFF;
305 /* Initialize LogLevel/TraceStatus field */
306 dlt_user.dlt_ll_ts = 0;
307 dlt_user.dlt_ll_ts_max_num_entries = 0;
308 dlt_user.dlt_ll_ts_num_entries = 0;
310 if (dlt_ringbuffer_init(&(dlt_user.rbuf), DLT_USER_RINGBUFFER_SIZE)==-1)
312 dlt_user_initialised = 0;
316 signal(SIGPIPE,SIG_IGN); /* ignore pipe signals */
318 atexit(dlt_user_atexit_handler);
323 void dlt_user_atexit_handler(void)
325 /* Unregister app (this also unregisters all contexts in daemon) */
326 /* Ignore return value */
327 dlt_unregister_app();
330 /* Ignore return value */
337 char filename[DLT_USER_MAX_FILENAME_LENGTH];
339 if (dlt_user_initialised==0)
344 if (dlt_receiverthread_handle)
346 /* Ignore return value */
347 pthread_cancel(dlt_receiverthread_handle);
350 if (dlt_user.dlt_user_handle!=-1)
352 sprintf(filename,"/tmp/dlt%d",getpid());
354 close(dlt_user.dlt_user_handle);
355 dlt_user.dlt_user_handle=-1;
360 /* free shared memory */
361 dlt_shm_free_client(&dlt_user.dlt_shm);
363 if (dlt_user.dlt_log_handle!=-1)
365 /* close log file/output fifo to daemon */
366 close(dlt_user.dlt_log_handle);
367 dlt_user.dlt_log_handle = -1;
370 /* Ignore return value */
371 dlt_receiver_free(&(dlt_user.receiver));
373 /* Ignore return value */
374 dlt_ringbuffer_free(&(dlt_user.rbuf));
376 if (dlt_user.dlt_ll_ts)
378 for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
380 if (dlt_user.dlt_ll_ts[i].injection_table!=0)
382 free(dlt_user.dlt_ll_ts[i].injection_table);
383 dlt_user.dlt_ll_ts[i].injection_table = 0;
385 dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
388 free(dlt_user.dlt_ll_ts);
389 dlt_user.dlt_ll_ts = 0;
390 dlt_user.dlt_ll_ts_max_num_entries = 0;
391 dlt_user.dlt_ll_ts_num_entries = 0;
394 dlt_user_initialised = 0;
399 int dlt_check_library_version(const char * user_major_version,const char * user_minor_version)
401 return dlt_user_check_library_version(user_major_version, user_minor_version);
404 int dlt_register_app(const char *appid, const char * description)
408 if (dlt_user_initialised==0)
416 if ((appid==0) || (appid[0]=='\0'))
423 /* Store locally application id and application description */
424 dlt_set_id(dlt_user.appID, appid);
426 if (dlt_user.application_description!=0)
428 free(dlt_user.application_description);
431 dlt_user.application_description = 0;
435 dlt_user.application_description= malloc(strlen(description)+1);
436 strncpy(dlt_user.application_description, description, strlen(description));
438 /* Terminate transmitted string with 0 */
439 dlt_user.application_description[strlen(description)]='\0';
444 ret = dlt_user_log_send_register_application();
448 int dlt_register_context(DltContext *handle, const char *contextid, const char * description)
450 if (dlt_user_initialised==0)
460 if (dlt_user.appID[0]=='\0')
462 dlt_log(LOG_ERR, "no application registered!\n");
468 if ((contextid==0) || (contextid[0]=='\0'))
476 return dlt_register_context_ll_ts(handle, contextid, description, DLT_USER_LOG_LEVEL_NOT_SET, DLT_USER_TRACE_STATUS_NOT_SET);
479 int dlt_register_context_ll_ts(DltContext *handle, const char *contextid, const char * description, int loglevel, int tracestatus)
484 char ctid[DLT_ID_SIZE+1];
486 if (dlt_user_initialised==0)
496 if (dlt_user.appID[0]=='\0')
498 dlt_log(LOG_ERR, "no application registered!\n");
506 if ((contextid==0) || (contextid[0]=='\0'))
511 if ((loglevel<DLT_USER_LOG_LEVEL_NOT_SET) || (loglevel>DLT_LOG_VERBOSE) || (loglevel==DLT_LOG_DEFAULT))
516 if ((tracestatus<DLT_USER_TRACE_STATUS_NOT_SET) || (tracestatus>DLT_TRACE_STATUS_ON) || (tracestatus==DLT_TRACE_STATUS_DEFAULT))
521 if (dlt_user_log_init(handle, &log)==-1)
526 /* Store context id in log level/trace status field */
528 /* Check if already registered, else register context */
532 for (i=0;i<dlt_user.dlt_ll_ts_num_entries;i++)
534 if (dlt_user.dlt_ll_ts)
536 if (memcmp(dlt_user.dlt_ll_ts[i].contextID, contextid,DLT_ID_SIZE)==0)
540 memset(ctid,0,(DLT_ID_SIZE+1));
541 dlt_print_id(ctid, contextid);
543 sprintf(str,"context '%s' already registered!\n",ctid);
544 dlt_log(LOG_WARNING, str);
553 /* Allocate or expand context array */
554 if (dlt_user.dlt_ll_ts == 0)
556 dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*DLT_USER_CONTEXT_ALLOC_SIZE);
557 if (dlt_user.dlt_ll_ts==0)
563 dlt_user.dlt_ll_ts_max_num_entries = DLT_USER_CONTEXT_ALLOC_SIZE;
565 /* Initialize new entries */
566 for (i=0;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
568 dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
570 /* At startup, logging and tracing is locally enabled */
571 /* the correct log level/status is set after received from daemon */
572 dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL;
573 dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
575 dlt_user.dlt_ll_ts[i].context_description = 0;
577 dlt_user.dlt_ll_ts[i].injection_table = 0;
578 dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
583 if ((dlt_user.dlt_ll_ts_num_entries%DLT_USER_CONTEXT_ALLOC_SIZE)==0)
585 /* allocate memory in steps of DLT_USER_CONTEXT_ALLOC_SIZE, e.g. 500 */
587 old = dlt_user.dlt_ll_ts;
588 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;
589 dlt_user.dlt_ll_ts = (dlt_ll_ts_type*) malloc(sizeof(dlt_ll_ts_type)*
590 dlt_user.dlt_ll_ts_max_num_entries);
591 if (dlt_user.dlt_ll_ts==0)
597 memcpy(dlt_user.dlt_ll_ts,old,sizeof(dlt_ll_ts_type)*dlt_user.dlt_ll_ts_num_entries);
600 /* Initialize new entries */
601 for (i=dlt_user.dlt_ll_ts_num_entries;i<dlt_user.dlt_ll_ts_max_num_entries;i++)
603 dlt_set_id(dlt_user.dlt_ll_ts[i].contextID,"");
605 /* At startup, logging and tracing is locally enabled */
606 /* the correct log level/status is set after received from daemon */
607 dlt_user.dlt_ll_ts[i].log_level = DLT_USER_INITIAL_LOG_LEVEL;
608 dlt_user.dlt_ll_ts[i].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
610 dlt_user.dlt_ll_ts[i].context_description = 0;
612 dlt_user.dlt_ll_ts[i].injection_table = 0;
613 dlt_user.dlt_ll_ts[i].nrcallbacks = 0;
618 /* Store locally context id and context description */
619 dlt_set_id(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].contextID, contextid);
621 if (dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description!=0)
623 free(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description);
626 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = 0;
630 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description = malloc(strlen(description)+1);
631 strncpy(dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description, description, strlen(description));
633 /* Terminate transmitted string with 0 */
634 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description[strlen(description)]='\0';
637 if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
639 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].log_level = loglevel;
642 if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
644 dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].trace_status = tracestatus;
647 /* Prepare transfer struct */
648 //dlt_set_id(log->appID, dlt_user.appID);
649 dlt_set_id(handle->contextID, contextid);
650 handle->log_level_pos = dlt_user.dlt_ll_ts_num_entries;
652 log.context_description = dlt_user.dlt_ll_ts[dlt_user.dlt_ll_ts_num_entries].context_description;
654 if (loglevel!=DLT_USER_LOG_LEVEL_NOT_SET)
656 log.log_level = loglevel;
660 log.log_level = DLT_USER_LOG_LEVEL_NOT_SET;
663 if (tracestatus!=DLT_USER_TRACE_STATUS_NOT_SET)
665 log.trace_status = tracestatus;
669 log.trace_status = DLT_USER_TRACE_STATUS_NOT_SET;
672 dlt_user.dlt_ll_ts_num_entries++;
676 ret=dlt_user_log_send_register_context(&log);
688 int dlt_unregister_app(void)
692 if (dlt_user_initialised==0)
697 /* Inform daemon to unregister application and all of its contexts */
698 ret = dlt_user_log_send_unregister_application();
702 /* Clear and free local stored application information */
703 dlt_set_id(dlt_user.appID, "");
705 if (dlt_user.application_description!=0)
707 free(dlt_user.application_description);
710 dlt_user.application_description = 0;
717 int dlt_unregister_context(DltContext *handle)
722 if (dlt_user_initialised==0)
727 if (dlt_user_log_init(handle, &log) == -1)
734 if (dlt_user.dlt_ll_ts)
736 /* Clear and free local stored context information */
737 dlt_set_id(dlt_user.dlt_ll_ts[handle->log_level_pos].contextID, "");
739 dlt_user.dlt_ll_ts[handle->log_level_pos].log_level = DLT_USER_INITIAL_LOG_LEVEL;
740 dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status = DLT_USER_INITIAL_TRACE_STATUS;
742 if (dlt_user.dlt_ll_ts[handle->log_level_pos].context_description!=0)
744 free(dlt_user.dlt_ll_ts[handle->log_level_pos].context_description);
747 dlt_user.dlt_ll_ts[handle->log_level_pos].context_description = 0;
749 if (dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table)
751 free(dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table);
752 dlt_user.dlt_ll_ts[handle->log_level_pos].injection_table = 0;
755 dlt_user.dlt_ll_ts[handle->log_level_pos].nrcallbacks = 0;
760 /* Inform daemon to unregister context */
761 ret = dlt_user_log_send_unregister_context(&log);
766 int dlt_set_application_ll_ts_limit(DltLogLevelType loglevel, DltTraceStatusType tracestatus)
771 if (dlt_user_initialised==0)
779 /* Removed because of DltLogLevelType and DltTraceStatusType
781 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
786 if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
791 if (dlt_user.dlt_ll_ts==0)
800 /* Update local structures */
801 for (i=0; i<dlt_user.dlt_ll_ts_num_entries;i++)
803 dlt_user.dlt_ll_ts[i].log_level = loglevel;
804 dlt_user.dlt_ll_ts[i].trace_status = tracestatus;
809 /* Inform DLT server about update */
810 ret = dlt_send_app_ll_ts_limit(dlt_user.appID, loglevel, tracestatus);
815 int dlt_get_log_state()
817 return dlt_user.log_state;
820 int dlt_set_log_mode(DltUserLogMode mode)
822 if (dlt_user_initialised==0)
830 return dlt_user_log_send_log_mode(mode);
833 int dlt_forward_msg(void *msgdata,size_t size)
835 DltUserHeader userheader;
838 if ((msgdata==0) || (size==0))
843 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG)==-1)
845 /* Type of internal user message; same value for Trace messages */
849 if (dlt_user.dlt_is_file)
852 ret = dlt_user_log_out2(dlt_user.dlt_log_handle, msgdata, size, 0, 0);
853 return ((ret==DLT_RETURN_OK)?0:-1);
857 /* Reattach to daemon if neccesary */
858 dlt_user_log_reattach_to_daemon();
860 if (dlt_user.overflow)
862 if (dlt_user_log_send_overflow()==0)
869 ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
870 &(userheader), sizeof(DltUserHeader),
871 msgdata, size, 0, 0);
873 /* store message in ringbuffer, if an error has occured */
874 if (ret!=DLT_RETURN_OK)
878 if (dlt_ringbuffer_put3(&(dlt_user.rbuf),
879 &(userheader), sizeof(DltUserHeader),
880 msgdata, size, 0, 0)==-1)
882 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
890 case DLT_RETURN_PIPE_FULL:
892 /* data could not be written */
893 dlt_user.overflow = 1;
896 case DLT_RETURN_PIPE_ERROR:
898 /* handle not open or pipe error */
899 close(dlt_user.dlt_log_handle);
900 dlt_user.dlt_log_handle = -1;
904 case DLT_RETURN_ERROR:
906 /* other error condition */
915 /* This case should not occur */
924 /* ********************************************************************************************* */
926 int dlt_user_log_write_start(DltContext *handle, DltContextData *log,DltLogLevelType loglevel)
928 return dlt_user_log_write_start_id(handle,log,loglevel,DLT_USER_DEFAULT_MSGID);
931 int dlt_user_log_write_start_id(DltContext *handle, DltContextData *log,DltLogLevelType loglevel, uint32_t messageid)
935 if (dlt_user_initialised==0)
943 if (dlt_user_log_init(handle, log)==-1)
953 /* Removed because of DltLogLevelType
955 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
965 log->log_level = loglevel;
968 if (dlt_user.dlt_ll_ts==0)
975 if ((log->log_level<=(int)(dlt_user.dlt_ll_ts[handle->log_level_pos].log_level) ) && (log->log_level!=0))
979 /* In non-verbose mode, insert message id */
980 if (dlt_user.verbose_mode==0)
982 if ((sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
986 /* Write message id */
987 memcpy(log->buffer,&(mid),sizeof(uint32_t));
988 log->size = sizeof(uint32_t);
990 /* as the message id is part of each message in non-verbose mode,
991 it doesn't increment the argument counter in extended header (if used) */
1004 int dlt_user_log_write_finish(DltContextData *log)
1011 return dlt_user_log_send_log(log, DLT_TYPE_LOG);
1014 int dlt_user_log_write_raw(DltContextData *log,void *data,uint16_t length)
1024 if ((log->size+length+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1029 if (dlt_user.verbose_mode)
1031 if ((log->size+length+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1036 /* Transmit type information */
1037 type_info = DLT_TYPE_INFO_RAWD;
1039 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1040 log->size += sizeof(uint32_t);
1044 /* First transmit length of raw data, then the raw data itself */
1045 arg_size = (uint16_t)length;
1047 memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1048 log->size += sizeof(uint16_t);
1050 memcpy((log->buffer)+log->size,data,arg_size);
1051 log->size += arg_size;
1058 int dlt_user_log_write_float32(DltContextData *log, float32_t data)
1067 if (sizeof(float32_t)!=4)
1072 if ((log->size+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1077 if (dlt_user.verbose_mode)
1079 if ((log->size+sizeof(uint32_t)+sizeof(float32_t))>DLT_USER_BUF_MAX_SIZE)
1084 type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_32BIT;
1086 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1087 log->size += sizeof(uint32_t);
1090 memcpy((log->buffer)+log->size,&data, sizeof(float32_t));
1091 log->size += sizeof(float32_t);
1098 int dlt_user_log_write_float64(DltContextData *log, float64_t data)
1107 if (sizeof(float64_t)!=8)
1112 if ((log->size+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1117 if (dlt_user.verbose_mode)
1119 if ((log->size+sizeof(uint32_t)+sizeof(float64_t))>DLT_USER_BUF_MAX_SIZE)
1124 type_info = DLT_TYPE_INFO_FLOA | DLT_TYLE_64BIT;
1126 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1127 log->size += sizeof(uint32_t);
1130 memcpy((log->buffer)+log->size,&data, sizeof(float64_t));
1131 log->size += sizeof(float64_t);
1138 int dlt_user_log_write_uint( DltContextData *log, unsigned int data)
1145 switch (sizeof(unsigned int))
1149 return dlt_user_log_write_uint8(log, (uint8_t)data);
1154 return dlt_user_log_write_uint16(log, (uint16_t)data);
1159 return dlt_user_log_write_uint32(log, (uint32_t)data);
1164 return dlt_user_log_write_uint64(log, (uint64_t)data);
1177 int dlt_user_log_write_uint8(DltContextData *log, uint8_t data)
1186 if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1191 if (dlt_user.verbose_mode)
1193 if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1198 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_8BIT;
1200 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1201 log->size += sizeof(uint32_t);
1204 memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
1205 log->size += sizeof(uint8_t);
1212 int dlt_user_log_write_uint16(DltContextData *log, uint16_t data)
1221 if ((log->size+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1226 if (dlt_user.verbose_mode)
1228 if ((log->size+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1233 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_16BIT;
1235 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1236 log->size += sizeof(uint32_t);
1239 memcpy((log->buffer)+log->size,&data,sizeof(uint16_t));
1240 log->size += sizeof(uint16_t);
1247 int dlt_user_log_write_uint32(DltContextData *log, uint32_t data)
1256 if ((log->size+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1261 if (dlt_user.verbose_mode)
1263 if ((log->size+sizeof(uint32_t)+sizeof(uint32_t))>DLT_USER_BUF_MAX_SIZE)
1268 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_32BIT;
1270 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1271 log->size += sizeof(uint32_t);
1274 memcpy((log->buffer)+log->size,&data, sizeof(uint32_t));
1275 log->size += sizeof(uint32_t);
1282 int dlt_user_log_write_uint64(DltContextData *log, uint64_t data)
1291 if ((log->size+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1296 if (dlt_user.verbose_mode)
1298 if ((log->size+sizeof(uint32_t)+sizeof(uint64_t))>DLT_USER_BUF_MAX_SIZE)
1303 type_info = DLT_TYPE_INFO_UINT | DLT_TYLE_64BIT;
1305 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1306 log->size +=sizeof(uint32_t);
1309 memcpy((log->buffer)+log->size,&data,sizeof(uint64_t));
1310 log->size += sizeof(uint64_t);
1317 int dlt_user_log_write_int(DltContextData *log, int data)
1324 switch (sizeof(int))
1328 return dlt_user_log_write_int8(log, (int8_t)data);
1333 return dlt_user_log_write_int16(log, (int16_t)data);
1338 return dlt_user_log_write_int32(log, (int32_t)data);
1343 return dlt_user_log_write_int64(log, (int64_t)data);
1356 int dlt_user_log_write_int8(DltContextData *log, int8_t data)
1365 if ((log->size+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
1370 if (dlt_user.verbose_mode)
1372 if ((log->size+sizeof(uint32_t)+sizeof(int8_t))>DLT_USER_BUF_MAX_SIZE)
1377 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_8BIT;
1379 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1380 log->size += sizeof(uint32_t);
1383 memcpy((log->buffer)+log->size,&data,sizeof(int8_t));
1384 log->size += sizeof(int8_t);
1391 int dlt_user_log_write_int16(DltContextData *log, int16_t data)
1400 if ((log->size+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
1405 if (dlt_user.verbose_mode)
1407 if ((log->size+sizeof(uint32_t)+sizeof(int16_t))>DLT_USER_BUF_MAX_SIZE)
1412 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_16BIT;
1414 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1415 log->size += sizeof(uint32_t);
1418 memcpy((log->buffer)+log->size,&data,sizeof(int16_t));
1419 log->size += sizeof(int16_t);
1426 int dlt_user_log_write_int32(DltContextData *log, int32_t data)
1435 if ((log->size+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
1440 if (dlt_user.verbose_mode)
1442 if ((log->size+sizeof(uint32_t)+sizeof(int32_t))>DLT_USER_BUF_MAX_SIZE)
1447 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_32BIT;
1449 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1450 log->size += sizeof(uint32_t);
1453 memcpy((log->buffer)+log->size,&data, sizeof(int32_t));
1454 log->size += sizeof(int32_t);
1461 int dlt_user_log_write_int64(DltContextData *log, int64_t data)
1470 if ((log->size+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
1475 if (dlt_user.verbose_mode)
1477 if ((log->size+sizeof(uint32_t)+sizeof(int64_t))>DLT_USER_BUF_MAX_SIZE)
1482 type_info = DLT_TYPE_INFO_SINT | DLT_TYLE_64BIT;
1484 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1485 log->size += sizeof(uint32_t);
1488 memcpy((log->buffer)+log->size,&data,sizeof(int64_t));
1489 log->size += sizeof(int64_t);
1496 int dlt_user_log_write_bool(DltContextData *log, uint8_t data)
1505 if ((log->size+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1510 if (dlt_user.verbose_mode)
1512 if ((log->size+sizeof(uint32_t)+sizeof(uint8_t))>DLT_USER_BUF_MAX_SIZE)
1517 type_info = DLT_TYPE_INFO_BOOL;
1519 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1520 log->size += sizeof(uint32_t);
1523 memcpy((log->buffer)+log->size,&data,sizeof(uint8_t));
1524 log->size += sizeof(uint8_t);
1531 int dlt_user_log_write_string(DltContextData *log, const char *text)
1536 if ((log==0) || (text==0))
1541 if ((log->size+(strlen(text)+1)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1546 if (dlt_user.verbose_mode)
1548 if ((log->size+(strlen(text)+1)+sizeof(uint32_t)+sizeof(uint16_t))>DLT_USER_BUF_MAX_SIZE)
1553 type_info = DLT_TYPE_INFO_STRG;
1555 memcpy((log->buffer)+log->size,&(type_info),sizeof(uint32_t));
1556 log->size += sizeof(uint32_t);
1559 arg_size = strlen(text) + 1;
1561 memcpy((log->buffer)+log->size,&(arg_size),sizeof(uint16_t));
1562 log->size += sizeof(uint16_t);
1564 memcpy((log->buffer)+log->size,text,arg_size);
1565 log->size += arg_size;
1572 int dlt_register_injection_callback(DltContext *handle, uint32_t service_id,
1573 int (*dlt_injection_callback)(uint32_t service_id, void *data, uint32_t length))
1579 DltUserInjectionCallback *old;
1586 if (dlt_user_log_init(handle, &log)==-1)
1591 if (service_id<DLT_USER_INJECTION_MIN)
1595 /* This function doesn't make sense storing to local file is choosen;
1596 so terminate this function */
1597 if (dlt_user.dlt_is_file)
1604 if (dlt_user.dlt_ll_ts==0)
1610 /* Insert callback in corresponding table */
1611 i=handle->log_level_pos;
1613 /* Insert each service_id only once */
1614 for (k=0;k<dlt_user.dlt_ll_ts[i].nrcallbacks;k++)
1616 if ((dlt_user.dlt_ll_ts[i].injection_table) &&
1617 (dlt_user.dlt_ll_ts[i].injection_table[k].service_id == service_id))
1630 j=dlt_user.dlt_ll_ts[i].nrcallbacks;
1632 /* Allocate or expand injection table */
1633 if (dlt_user.dlt_ll_ts[i].injection_table == 0)
1635 dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback));
1639 old = dlt_user.dlt_ll_ts[i].injection_table;
1640 dlt_user.dlt_ll_ts[i].injection_table = (DltUserInjectionCallback*) malloc(sizeof(DltUserInjectionCallback)*(j+1));
1641 memcpy(dlt_user.dlt_ll_ts[i].injection_table,old,sizeof(DltUserInjectionCallback)*j);
1645 dlt_user.dlt_ll_ts[i].nrcallbacks++;
1648 /* Store service_id and corresponding function pointer for callback function */
1649 dlt_user.dlt_ll_ts[i].injection_table[j].service_id = service_id;
1650 dlt_user.dlt_ll_ts[i].injection_table[j].injection_callback = dlt_injection_callback;
1656 int dlt_user_trace_network(DltContext *handle, DltNetworkTraceType nw_trace_type, uint16_t header_len, void *header, uint16_t payload_len, void *payload)
1660 if (dlt_user_initialised==0)
1668 if (dlt_user_log_init(handle, &log)==-1)
1678 /* Commented out because of DltNetworkTraceType:
1680 if ((nw_trace_type<=0) || (nw_trace_type>0x15))
1689 if (dlt_user.dlt_ll_ts==0)
1695 if (dlt_user.dlt_ll_ts[handle->log_level_pos].trace_status==DLT_TRACE_STATUS_ON)
1700 log.trace_status = nw_trace_type;
1708 /* Write header and its length */
1709 if (dlt_user_log_write_raw(&log, header, header_len)==-1)
1719 /* Write payload and its length */
1720 if (dlt_user_log_write_raw(&log, payload, payload_len)==-1)
1726 return dlt_user_log_send_log(&log, DLT_TYPE_NW_TRACE);
1736 int dlt_log_string(DltContext *handle,DltLogLevelType loglevel, const char *text)
1740 if (dlt_user.verbose_mode==0)
1745 if ((handle==0) || (text==0))
1750 if (dlt_user_log_write_start(handle,&log,loglevel))
1752 if (dlt_user_log_write_string(&log,text)==-1)
1756 if (dlt_user_log_write_finish(&log)==-1)
1765 int dlt_log_string_int(DltContext *handle,DltLogLevelType loglevel, const char *text, int data)
1769 if (dlt_user.verbose_mode==0)
1774 if ((handle==0) || (text==0))
1779 if (dlt_user_log_write_start(handle,&log,loglevel))
1781 if (dlt_user_log_write_string(&log,text)==-1)
1785 if (dlt_user_log_write_int(&log,data)==-1)
1789 if (dlt_user_log_write_finish(&log)==-1)
1798 int dlt_log_string_uint(DltContext *handle,DltLogLevelType loglevel, const char *text, unsigned int data)
1802 if (dlt_user.verbose_mode==0)
1807 if ((handle==0) || (text==0))
1812 if (dlt_user_log_write_start(handle,&log,loglevel))
1814 if (dlt_user_log_write_string(&log,text)==-1)
1818 if (dlt_user_log_write_uint(&log,data)==-1)
1822 if (dlt_user_log_write_finish(&log)==-1)
1831 int dlt_log_int(DltContext *handle,DltLogLevelType loglevel, int data)
1835 if (dlt_user.verbose_mode==0)
1845 if (dlt_user_log_write_start(handle,&log,loglevel))
1847 if (dlt_user_log_write_int(&log,data)==-1)
1851 if (dlt_user_log_write_finish(&log)==-1)
1860 int dlt_log_uint(DltContext *handle,DltLogLevelType loglevel, unsigned int data)
1864 if (dlt_user.verbose_mode==0)
1874 if (dlt_user_log_write_start(handle,&log,loglevel))
1876 if (dlt_user_log_write_uint(&log,data)==-1)
1880 if (dlt_user_log_write_finish(&log)==-1)
1889 int dlt_log_raw(DltContext *handle,DltLogLevelType loglevel, void *data,uint16_t length)
1893 if (dlt_user.verbose_mode==0)
1903 if (dlt_user_log_write_start(handle,&log,loglevel))
1905 if (dlt_user_log_write_raw(&log,data,length)==-1)
1909 if (dlt_user_log_write_finish(&log)==-1)
1918 int dlt_verbose_mode(void)
1920 if (dlt_user_initialised==0)
1928 /* Switch to verbose mode */
1929 dlt_user.verbose_mode = 1;
1934 int dlt_nonverbose_mode(void)
1936 if (dlt_user_initialised==0)
1944 /* Switch to non-verbose mode */
1945 dlt_user.verbose_mode = 0;
1950 int dlt_enable_local_print(void)
1952 if (dlt_user_initialised==0)
1960 dlt_user.enable_local_print = 1;
1965 int dlt_disable_local_print(void)
1967 if (dlt_user_initialised==0)
1975 dlt_user.enable_local_print = 0;
1980 void dlt_user_receiverthread_function(void *ptr)
1984 /* Check for new messages from DLT daemon */
1985 if (dlt_user_log_check_user_message()==-1)
1987 /* Critical error */
1988 dlt_log(LOG_CRIT,"Receiver thread encountered error condition\n");
1991 usleep(DLT_USER_RECEIVE_DELAY); /* delay */
1995 /* Private functions of user library */
1997 int dlt_user_log_init(DltContext *handle, DltContextData *log)
1999 if (dlt_user_initialised==0)
2007 log->handle = handle;
2013 int dlt_user_log_send_log(DltContextData *log, int mtype)
2016 DltUserHeader userheader;
2031 if (dlt_user.appID[0]=='\0')
2036 if (log->handle->contextID[0]=='\0')
2041 if ((mtype<DLT_TYPE_LOG) || (mtype>DLT_TYPE_CONTROL))
2046 /* also for Trace messages */
2047 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_SHM)==-1)
2052 if (dlt_message_init(&msg,0)==-1)
2057 msg.storageheader = (DltStorageHeader*)msg.headerbuffer;
2059 if (dlt_set_storageheader(msg.storageheader,dlt_user.ecuID)==-1)
2064 msg.standardheader = (DltStandardHeader*)(msg.headerbuffer + sizeof(DltStorageHeader));
2065 msg.standardheader->htyp = DLT_HTYP_WEID | DLT_HTYP_WTMS | DLT_HTYP_PROTOCOL_VERSION1 ;
2067 if (dlt_user.verbose_mode)
2069 /* In verbose mode, send extended header */
2070 msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
2074 /* In non-verbose, send extended header if desired */
2075 #if (DLT_USER_USE_EXTENDED_HEADER_FOR_NONVERBOSE==1)
2076 msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_UEH );
2080 #if (BYTE_ORDER==BIG_ENDIAN)
2081 msg.standardheader->htyp = (msg.standardheader->htyp | DLT_HTYP_MSBF);
2084 msg.standardheader->mcnt = log->mcnt++;
2086 /* Set header extra parameters */
2087 dlt_set_id(msg.headerextra.ecu,dlt_user.ecuID);
2088 //msg.headerextra.seid = 0;
2089 msg.headerextra.tmsp = dlt_uptime();
2091 if (dlt_message_set_extraparameters(&msg,0)==-1)
2096 /* Fill out extended header, if extended header should be provided */
2097 if (DLT_IS_HTYP_UEH(msg.standardheader->htyp))
2099 /* with extended header */
2100 msg.extendedheader = (DltExtendedHeader*)(msg.headerbuffer + sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp) );
2106 msg.extendedheader->msin = (DLT_TYPE_LOG << DLT_MSIN_MSTP_SHIFT) | ((log->log_level << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
2109 case DLT_TYPE_NW_TRACE:
2111 msg.extendedheader->msin = (DLT_TYPE_NW_TRACE << DLT_MSIN_MSTP_SHIFT) | ((log->trace_status << DLT_MSIN_MTIN_SHIFT) & DLT_MSIN_MTIN) ; /* messsage info */
2116 /* This case should not occur */
2122 /* If in verbose mode, set flag in header for verbose mode */
2123 if (dlt_user.verbose_mode)
2125 msg.extendedheader->msin |= DLT_MSIN_VERB;
2128 msg.extendedheader->noar = log->args_num; /* number of arguments */
2129 dlt_set_id(msg.extendedheader->apid,dlt_user.appID); /* application id */
2130 dlt_set_id(msg.extendedheader->ctid,log->handle->contextID); /* context id */
2132 msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + sizeof(DltExtendedHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
2136 /* without extended header */
2137 msg.headersize = sizeof(DltStorageHeader) + sizeof(DltStandardHeader) + DLT_STANDARD_HEADER_EXTRA_SIZE(msg.standardheader->htyp);
2140 len=msg.headersize - sizeof(DltStorageHeader) +log->size;
2143 dlt_log(LOG_CRIT,"Huge message discarded!\n");
2147 msg.standardheader->len = DLT_HTOBE_16(len);
2149 /* print to std out, if enabled */
2150 if ((dlt_user.local_print_mode != DLT_PM_FORCE_OFF) &&
2151 (dlt_user.local_print_mode != DLT_PM_AUTOMATIC))
2153 if ((dlt_user.enable_local_print) || (dlt_user.local_print_mode == DLT_PM_FORCE_ON))
2155 if (dlt_user_print_msg(&msg, log)==-1)
2162 if (dlt_user.dlt_is_file)
2165 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, msg.headerbuffer, msg.headersize, log->buffer, log->size);
2166 return ((ret==DLT_RETURN_OK)?0:-1);
2170 /* Reattach to daemon if neccesary */
2171 dlt_user_log_reattach_to_daemon();
2173 if (dlt_user.overflow)
2175 if (dlt_user_log_send_overflow()==0)
2177 dlt_user.overflow=0;
2181 dlt_shm_push(&dlt_user.dlt_shm,msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2182 log->buffer, log->size,0,0);
2185 ret = dlt_user_log_out3(dlt_user.dlt_log_handle,
2186 &(userheader), sizeof(DltUserHeader),
2190 /* store message in ringbuffer, if an error has occured */
2191 if (ret!=DLT_RETURN_OK)
2195 if (dlt_ringbuffer_put3(&(dlt_user.rbuf),
2196 &(userheader), sizeof(DltUserHeader),
2197 msg.headerbuffer+sizeof(DltStorageHeader), msg.headersize-sizeof(DltStorageHeader),
2198 log->buffer, log->size)==-1)
2200 dlt_log(LOG_ERR,"Storing message to history buffer failed! Message discarded.\n");
2208 case DLT_RETURN_PIPE_FULL:
2210 /* data could not be written */
2211 dlt_user.overflow = 1;
2214 case DLT_RETURN_PIPE_ERROR:
2216 /* handle not open or pipe error */
2217 close(dlt_user.dlt_log_handle);
2218 dlt_user.dlt_log_handle = -1;
2220 if (dlt_user.local_print_mode == DLT_PM_AUTOMATIC)
2222 dlt_user_print_msg(&msg, log);
2227 case DLT_RETURN_ERROR:
2229 /* other error condition */
2238 /* This case should never occur. */
2247 int dlt_user_log_send_register_application(void)
2249 DltUserHeader userheader;
2250 DltUserControlMsgRegisterApplication usercontext;
2254 if (dlt_user.appID[0]=='\0')
2259 /* set userheader */
2260 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_APPLICATION)==-1)
2265 /* set usercontext */
2266 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
2267 usercontext.pid = getpid();
2269 if (dlt_user.application_description!=0)
2271 usercontext.description_length = strlen(dlt_user.application_description);
2275 usercontext.description_length = 0;
2278 if (dlt_user.dlt_is_file)
2284 ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterApplication),dlt_user.application_description,usercontext.description_length);
2285 return ((ret==DLT_RETURN_OK)?0:-1);
2288 int dlt_user_log_send_unregister_application(void)
2290 DltUserHeader userheader;
2291 DltUserControlMsgUnregisterApplication usercontext;
2295 if (dlt_user.appID[0]=='\0')
2300 /* set userheader */
2301 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_APPLICATION)==-1)
2306 /* set usercontext */
2307 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
2308 usercontext.pid = getpid();
2310 if (dlt_user.dlt_is_file)
2316 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterApplication));
2317 return ((ret==DLT_RETURN_OK)?0:-1);
2320 int dlt_user_log_send_register_context(DltContextData *log)
2322 DltUserHeader userheader;
2323 DltUserControlMsgRegisterContext usercontext;
2336 if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0'))
2341 /* set userheader */
2342 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_REGISTER_CONTEXT)==-1)
2347 /* set usercontext */
2348 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
2349 dlt_set_id(usercontext.ctid,log->handle->contextID); /* context id */
2350 usercontext.log_level_pos = log->handle->log_level_pos;
2351 usercontext.pid = getpid();
2353 usercontext.log_level = (int8_t)log->log_level;
2354 usercontext.trace_status = (int8_t)log->trace_status;
2356 if (log->context_description!=0)
2358 usercontext.description_length = strlen(log->context_description);
2362 usercontext.description_length = 0;
2365 if (dlt_user.dlt_is_file)
2371 ret=dlt_user_log_out3(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgRegisterContext),log->context_description,usercontext.description_length);
2372 return ((ret==DLT_RETURN_OK)?0:-1);
2375 int dlt_user_log_send_unregister_context(DltContextData *log)
2377 DltUserHeader userheader;
2378 DltUserControlMsgUnregisterContext usercontext;
2391 if ((dlt_user.appID[0]=='\0') || (log->handle->contextID=='\0'))
2396 /* set userheader */
2397 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_UNREGISTER_CONTEXT)==-1)
2402 /* set usercontext */
2403 dlt_set_id(usercontext.apid,dlt_user.appID); /* application id */
2404 dlt_set_id(usercontext.ctid,log->handle->contextID); /* context id */
2405 usercontext.pid = getpid();
2407 if (dlt_user.dlt_is_file)
2413 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgUnregisterContext));
2414 return ((ret==DLT_RETURN_OK)?0:-1);
2417 int dlt_send_app_ll_ts_limit(const char *appid, DltLogLevelType loglevel, DltTraceStatusType tracestatus)
2419 DltUserHeader userheader;
2420 DltUserControlMsgAppLogLevelTraceStatus usercontext;
2423 if ((appid==0) || (appid[0]=='\0'))
2428 /* Removed because of DltLogLevelType and DltTraceStatusType
2430 if ((loglevel<DLT_LOG_DEFAULT) || (loglevel>DLT_LOG_VERBOSE))
2435 if ((tracestatus<DLT_TRACE_STATUS_DEFAULT) || (tracestatus>DLT_TRACE_STATUS_ON))
2442 /* set userheader */
2443 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_APP_LL_TS)==-1)
2448 /* set usercontext */
2449 dlt_set_id(usercontext.apid,appid); /* application id */
2450 usercontext.log_level = loglevel;
2451 usercontext.trace_status = tracestatus;
2453 if (dlt_user.dlt_is_file)
2459 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(usercontext), sizeof(DltUserControlMsgAppLogLevelTraceStatus));
2460 return ((ret==DLT_RETURN_OK)?0:-1);
2463 int dlt_user_log_send_log_mode(DltUserLogMode mode)
2465 DltUserHeader userheader;
2466 DltUserControlMsgLogMode logmode;
2470 /* set userheader */
2471 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_LOG_MODE)==-1)
2477 logmode.log_mode = (unsigned char) mode;
2479 if (dlt_user.dlt_is_file)
2485 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), &(logmode), sizeof(DltUserControlMsgLogMode));
2486 return ((ret==DLT_RETURN_OK)?0:-1);
2489 int dlt_user_print_msg(DltMessage *msg, DltContextData *log)
2491 uint8_t *databuffer_tmp;
2492 int32_t datasize_tmp;
2493 static char text[DLT_USER_TEXT_LENGTH];
2495 if ((msg==0) || (log==0))
2500 /* Save variables before print */
2501 databuffer_tmp = msg->databuffer;
2502 datasize_tmp = msg->datasize;
2504 /* Act like a receiver, convert header back to host format */
2505 msg->standardheader->len = DLT_BETOH_16(msg->standardheader->len);
2506 dlt_message_get_extraparameters(msg,0);
2508 msg->databuffer = log->buffer;
2509 msg->datasize = log->size;
2511 /* Print message as ASCII */
2512 if (dlt_message_print_ascii(msg,text,DLT_USER_TEXT_LENGTH,0)==-1)
2517 /* Restore variables and set len to BE*/
2518 msg->databuffer = databuffer_tmp;
2519 msg->datasize = datasize_tmp;
2521 msg->standardheader->len = DLT_HTOBE_16(msg->standardheader->len);
2526 int dlt_user_log_check_user_message(void)
2533 DltUserHeader *userheader;
2534 DltReceiver *receiver = &(dlt_user.receiver);
2536 DltUserControlMsgLogLevel *usercontextll;
2537 DltUserControlMsgInjection *usercontextinj;
2538 DltUserControlMsgLogState *userlogstate;
2539 unsigned char *userbuffer;
2540 unsigned char *inject_buffer;
2542 if (dlt_user.dlt_user_handle!=-1)
2546 if (dlt_receiver_receive_fd(receiver)<=0)
2548 /* No new message available */
2552 /* look through buffer as long as data is in there */
2555 if (receiver->bytesRcvd < sizeof(DltUserHeader))
2560 /* resync if necessary */
2564 userheader = (DltUserHeader*) (receiver->buf+offset);
2566 /* Check for user header pattern */
2567 if (dlt_user_check_userheader(userheader))
2574 while ((sizeof(DltUserHeader)+offset)<=receiver->bytesRcvd);
2576 /* Check for user header pattern */
2577 if (dlt_user_check_userheader(userheader)==0)
2582 /* Set new start offset */
2585 receiver->buf+=offset;
2586 receiver->bytesRcvd-=offset;
2589 switch (userheader->message)
2591 case DLT_USER_MESSAGE_LOG_LEVEL:
2593 if (receiver->bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel)))
2599 usercontextll = (DltUserControlMsgLogLevel*) (receiver->buf+sizeof(DltUserHeader));
2601 /* Update log level and trace status */
2602 if (usercontextll!=0)
2606 if ((usercontextll->log_level_pos>=0) && (usercontextll->log_level_pos<dlt_user.dlt_ll_ts_num_entries))
2608 // printf("Store ll, ts\n");
2609 if (dlt_user.dlt_ll_ts)
2611 dlt_user.dlt_ll_ts[usercontextll->log_level_pos].log_level = usercontextll->log_level;
2612 dlt_user.dlt_ll_ts[usercontextll->log_level_pos].trace_status = usercontextll->trace_status;
2619 /* keep not read data in buffer */
2620 if (dlt_receiver_remove(receiver,sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogLevel))==-1)
2626 case DLT_USER_MESSAGE_INJECTION:
2628 /* At least, user header, user context, and service id and data_length of injected message is available */
2629 if (receiver->bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)))
2635 usercontextinj = (DltUserControlMsgInjection*) (receiver->buf+sizeof(DltUserHeader));
2636 userbuffer = (unsigned char*) (receiver->buf+sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection));
2642 if (receiver->bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))
2650 if ((usercontextinj->data_length_inject>0) && (dlt_user.dlt_ll_ts))
2652 /* Check if injection callback is registered for this context */
2653 for (i=0; i<dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].nrcallbacks;i++)
2655 if ((dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table) &&
2656 (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].service_id == usercontextinj->service_id))
2658 /* callback available, so prepare data, then call it */
2659 inject_buffer = malloc(usercontextinj->data_length_inject);
2660 if (inject_buffer!=0)
2662 /* copy from receiver to inject_buffer */
2663 memcpy(inject_buffer, userbuffer, usercontextinj->data_length_inject);
2666 if (dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback!=0)
2668 // printf("Got injection(%d), length=%d, '%s' \n", usercontext->service_id, usercontext->data_length_inject, inject_buffer);
2669 dlt_user.dlt_ll_ts[usercontextinj->log_level_pos].injection_table[i].injection_callback(
2670 usercontextinj->service_id, inject_buffer, usercontextinj->data_length_inject);
2673 if (inject_buffer!=0)
2675 free(inject_buffer);
2687 /* keep not read data in buffer */
2688 if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgInjection)+usercontextinj->data_length_inject))==-1)
2695 case DLT_USER_MESSAGE_LOG_STATE:
2697 /* At least, user header, user context, and service id and data_length of injected message is available */
2698 if (receiver->bytesRcvd < (sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))
2704 userlogstate = (DltUserControlMsgLogState*) (receiver->buf+sizeof(DltUserHeader));
2705 dlt_user.log_state = userlogstate->log_state;
2707 /* keep not read data in buffer */
2708 if (dlt_receiver_remove(receiver,(sizeof(DltUserHeader)+sizeof(DltUserControlMsgLogState)))==-1)
2716 dlt_log(LOG_ERR,"Invalid user message type received!\n");
2718 dlt_receiver_remove(receiver,sizeof(DltUserHeader));
2719 /* In next invocation of while loop, a resync will be triggered if additional data was received */
2732 if (dlt_receiver_move_to_begin(receiver)==-1)
2736 } /* while receive */
2742 void dlt_user_log_reattach_to_daemon(void)
2744 int num, count, reregistered=0;
2746 uint8_t buf[DLT_USER_RINGBUFFER_SIZE];
2750 DltContextData log_new;
2753 if (dlt_user.dlt_log_handle<0)
2755 dlt_user.dlt_log_handle=-1;
2757 /* try to open pipe to dlt daemon */
2758 dlt_user.dlt_log_handle = open(DLT_USER_FIFO, O_WRONLY | O_NONBLOCK);
2759 if (dlt_user.dlt_log_handle > 0)
2761 if (dlt_user_log_init(&handle,&log_new)==-1)
2766 dlt_log(LOG_NOTICE, "Logging re-enabled!\n");
2768 /* Re-register application */
2769 if (dlt_user_log_send_register_application()==-1)
2776 /* Re-register all stored contexts */
2777 for (num=0; num<dlt_user.dlt_ll_ts_num_entries; num++)
2779 /* Re-register stored context */
2780 if ((dlt_user.appID[0]!='\0') && (dlt_user.dlt_ll_ts[num].contextID[0]!='\0') && (dlt_user.dlt_ll_ts))
2782 //dlt_set_id(log_new.appID, dlt_user.appID);
2783 dlt_set_id(handle.contextID, dlt_user.dlt_ll_ts[num].contextID);
2784 handle.log_level_pos = num;
2785 log_new.context_description = dlt_user.dlt_ll_ts[num].context_description;
2787 log_new.log_level = DLT_USER_LOG_LEVEL_NOT_SET;
2788 log_new.trace_status = DLT_USER_TRACE_STATUS_NOT_SET;
2790 if (dlt_user_log_send_register_context(&log_new)==-1)
2802 if (reregistered==1)
2804 /* Send content of ringbuffer */
2806 count = dlt_user.rbuf.count;
2809 for (num=0;num<count;num++)
2813 dlt_ringbuffer_get(&(dlt_user.rbuf),buf,&size);
2818 dlt_shm_push(&dlt_user.dlt_shm,buf+sizeof(DltUserHeader),size-sizeof(DltUserHeader),0,0,0,0);
2821 ret = dlt_user_log_out3(dlt_user.dlt_log_handle, buf,sizeof(DltUserHeader),0,0,0,0);
2823 /* in case of error, push message back to ringbuffer */
2824 if (ret!=DLT_RETURN_OK)
2827 if (dlt_ringbuffer_put(&(dlt_user.rbuf), buf, size)==-1)
2829 dlt_log(LOG_ERR,"Error pushing back message to history buffer. Message discarded.\n");
2833 /* In case of: data could not be written, set overflow flag */
2834 if (ret==DLT_RETURN_PIPE_FULL)
2836 dlt_user.overflow = 1;
2847 int dlt_user_log_send_overflow(void)
2849 DltUserHeader userheader;
2852 /* set userheader */
2853 if (dlt_user_set_userheader(&userheader, DLT_USER_MESSAGE_OVERFLOW)==-1)
2858 if (dlt_user.dlt_is_file)
2864 ret=dlt_user_log_out2(dlt_user.dlt_log_handle, &(userheader), sizeof(DltUserHeader), 0, 0);
2865 return ((ret==DLT_RETURN_OK)?0:-1);
2868 int dlt_user_check_buffer(int *total_size, int *used_size)
2870 *total_size = dlt_shm_get_total_size(&(dlt_user.dlt_shm));
2871 *used_size = dlt_shm_get_used_size(&(dlt_user.dlt_shm));